diff --git a/en/OpenHarmony-Overview.md b/en/OpenHarmony-Overview.md index d045073fa0c5f6e82f9824a18db1e18fd0cf59a7..2e90b1a038c02932edf499a66363f55a594f3e91 100644 --- a/en/OpenHarmony-Overview.md +++ b/en/OpenHarmony-Overview.md @@ -358,9 +358,9 @@ OpenHarmony archived projects: [https://gitee.com/openharmony-retired](https:// ## OpenHarmony Documentation -[Chinese version](https://gitee.com/openharmony/docs/blob/master/Readme-zh-cn.md) +[Chinese version](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme.md) -[English version](https://gitee.com/openharmony/docs/blob/master/Readme-en.md) +[English version](https://gitee.com/openharmony/docs/blob/master/en/readme.md) ## Source Code Downloading diff --git a/en/device-dev/bundles/Readme-EN.md b/en/device-dev/bundles/Readme-EN.md index 2ae8dc847c778c4cef4a191f56f5d3e107a2d1c7..b95e0adea8e0b365a0c1a7736a77c8a8a1643ac2 100644 --- a/en/device-dev/bundles/Readme-EN.md +++ b/en/device-dev/bundles/Readme-EN.md @@ -1,20 +1,11 @@ -# Bundle Development - -- [Development Specifications](development-specifications.md) - - [Overview](overview.md) - - [Bundle Composition](bundle-composition.md) - - [Bundle Management](bundle-management.md) - - [Bundle Version](bundle-version.md) - - [Distribution](distribution.md) - - [Environment Variables](environment-variables.md) - -- [Development Guidelines](development-guidelines.md) - - [Overview](overview-0.md) - - [Preparations](preparations.md) - - [Bundle Development](bundle-development.md) - -- [HPM User Guide](hpm-user-guide.md) - - [Introduction](introduction.md) - - [Preparations](preparations-1.md) - - [Development Example](development-example.md) - +# Bundle Development + +- [Development Specifications](bundles-standard-rules.md) +- [Development Guidelines](bundles-guide.md) + - [Bundle Development](bundles-guide-overview.md) + - [Preparations](bundles-guide-prepare.md) + - [Bundle Development](bundles-guide-develop.md) +- [HPM User Guide](bundles-demo.md) + - [Introduction](bundles-demo-hpmdescription.md) + - [Preparations](bundles-demo-environment.md) + - [Development Example](bundles-demo-devsample.md) \ No newline at end of file diff --git a/en/device-dev/bundles/bundle-composition.md b/en/device-dev/bundles/bundle-composition.md deleted file mode 100644 index 754f38a7c428547cacc97f55d0042e6eae62bb75..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/bundle-composition.md +++ /dev/null @@ -1,99 +0,0 @@ -# Bundle Composition - -- [Code files](#section101483489110) -- [README File](#section10519101221211) -- [Metadata Description File](#section45511827111211) - -A bundle contains the following contents: - -- **src** directory for storing code files or code library -- **ohos\_bundles** folder for storing dependent bundles \(It is automatically generated during bundle installation, without the need to submit to the code library.\) -- **README.md** file for describing the bundle -- **bundle.json** file for declaring metadata of the bundle -- **LICENSE** file for open-source code - - ``` - my-bundle - |_ohos_bundles - |_src - |_bundle.json - |_README.md - |_LICENSE - ``` - - -## Code files - -Bundle code files are the same as those in a common code directory. The only difference lies in the open APIs \(declared in header files\) of a bundle, which are likely to be referenced by other bundles and need to be declared in the **dirs** of **bundle.json**. - -## README File - -**README.md** is a bundle self-description file using the markdown syntax. For details, see [Syntax Reference](https://www.markdownguide.org/getting-started/). - -To help you easily find and use the desired bundle on the HarmonyOS Package Manager \(HPM\) platform, a **README** file is provided in the root directory of each bundle. - -The **README** file may include instructions on how to install, configure, and use the instance code in the bundle, as well as any other information helpful to you. - -The **README** file is available in the bundle details page of the HPM platform. - -## Metadata Description File - -A **bundle.json** file describes the metadata of a bundle. Each bundle has its own **bundle.json** file. - -``` -{ - "name": "@myorg/demo-bundle", - "version": "1.0.0", - "license": "MIT", - "description": "bundle description", - "keywords": ["hos"], - "tags": ["applications", "drivers"], - "author": {"name":"","email":"","url":""}, - "contributors":[{"name":"","email":"","url":""},{"name":"","email":"","url":""}], - "homepage": "http://www.foo.bar.com", - "repository": "https://git@gitee.com:foo/bar.git", - "publishAs": "source", - "dirs": { - "src": ["src/**/*.c"], - "headers": ["headers/**/*.h"], - "bin": ["bin/**/*.o"] - }, - "scripts": { - "build": "make" - }, - "envs": {}, - "ohos": { - "os": "2.0.0", - "board": "hi3516", - "kernel": "liteos-a" - }, - "rom": "10240", - "ram": "1024", - "dependencies": { - "@myorg/net":"1.0.0" - } -} -``` - -Each **bundle.json** file has the following fields: - -- **name**: a bundle name, which starts with @ and is separated by /, for example, **@myorg/mybundle** - -- **version**: a bundle version number, for example, 1.0.0. The version number must comply with the Semantic Versioning Specification \(SemVer\) standards. - -- **description**: a brief description of a bundle -- **dependencies**: bundles that a bundle depends on - -- **envs**: parameters required for bundle compilation, including global parameters and dependency parameters. - -- **scripts**: commands executable to a bundle, such as those for compiling, building, testing, and burning - -- **publishAs**: bundle publishing type, which can be **source**, **binary**, **distribution**, or **code-segment** - -- **dirs**: directory structure \(such as the header file\) generated for publishing - -- **ram&rom**: statistical information about the estimated read-only memory \(ROM\) and random access memory \(RAM\) usage -- **ohos**: mappings among OpenHarmony versions, development boards, and kernels, separated by commas \(,\). -- Extended information: author, home page, code repository, license, tags, and keywords -- **base** \(only for a distribution\): a base distribution which others inherit from. - diff --git a/en/device-dev/bundles/bundle-development.md b/en/device-dev/bundles/bundle-development.md deleted file mode 100644 index 09330f69915d1cc850b0125a3e198e4f1c8c163f..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/bundle-development.md +++ /dev/null @@ -1,241 +0,0 @@ -# Bundle Development - -- [Developing a OpenHarmony Bundle](#section1976410130540) -- [Creating a Bundle](#section717481119145) -- [Modifying a Bundle](#section102861955201410) -- [Using HPM-provided Template to Create a Bundle](#section15882846181510) -- [Building a Bundle](#section136732148541) -- [Defining the Building Script](#section10274147111610) -- [Executing the Building Script](#section879301916172) -- [Defining a Distribution](#section413216495619) -- [Defining Scripts](#section11503171219190) -- [Distributing](#section4694125521912) -- [Burning](#section1746331545413) -- [Debugging](#section6742131615549) - -## Developing a OpenHarmony Bundle - -You have an option to use any of the following methods to develop an OpenHarmony bundle: - -- Develop a brand new bundle from scratch. -- Rewrite code of an existing non-bundle to develop a bundle. - -- Use HPM-provided bundle templates to quickly develop a bundle. - -## Creating a Bundle - -Generally, you can find commonly used bundles on the [HPM](https://hpm.harmonyos.com/#/en/home) website. If they cannot meet your requirements, you can develop your own bundles. - -You can publish bundles in the HPM repository if you like, so that your peers have an option to use them. Assume that you want to create a bundle named **my-bundle** in the **D:/source** directory: - -Run the **hpm init** command to create the scaffold code for this bundle. For example, you can go to the **D:/source** directory and run the following command: - -``` -hpm init -t default -d demo my-bundle -``` - -The following files are generated in the **source** directory: - -``` -mybundle -├── bundle.json # Metadata description file of the bundle -├── example # Example of testing bundle functions -│ └── main.c -├── include # Internal header files of the bundle -│ └── mybundle.h -├── README.md # Brief description of the bundle -└── src # Source code of the bundle - └─ mybundle.c -``` - -Then, complete your coding based on service requirements. Finally, use **git** to commit your code \(including the **bundle.json** file\) to the code hosting repository, such as gitee. - -## Modifying a Bundle - -If you have code unqualified for the OpenHarmony bundle structure, modify your code to match an HPM bundle. In the code directory \(for example, **mybundle2**\) storing your code, run the following command with the bundle name and version specified: - -``` -hpm init -``` - -1. Enter a bundle name \(**mybundle2** as an example\) and press **Enter**. -2. Enter the bundle version \(**1.0.0** as an example\) and press **Enter**. A **bundle.json** file is generated in the current bundle directory. -3. Add other descriptions in **bundle.json**, which is publishable. - - ``` - $ hpm init - Your bundle will be created in dirname E:\demo\mybundle2 - ? bundle name mybundel2 - ? version 1.0.0 - Init finished! - ``` - - -1. Modify other information \(such as the author, code repository, code directory, command script, and dependent bundles\) in **bundle.json**. - - ``` - { - "name": "mybundle2", - "version": "1.0.0", - "publishAs": "source", - "dirs":{ - ".":[ - "README.md" - ], - "src":[ - "test.c" - ], - "header":[ - "header/test.h" - ], - "src/common":[ - "src/common/foobar.txt" - ] - }, - "scripts": { - "build": "make -${args}" - }, - "dependencies": { - "@ohos/cjson": "^1.0.0", - "@ohos/": "^1.2.0" - } - } - ``` - - -## Using HPM-provided Template to Create a Bundle - -The HPM provides **default** and **simple** templates as well as other templates that are stored on the server. - -You can run the **hpm search -t template** command to search for a template stored on the server. - -![](figures/en-us_image_0000001051452177.png) - -Then, select your desired template based on the information below **description**, use the selected template to quickly create the bundle scaffold, and run the following command with the **-t** and **-d** parameters specified: - -``` -hpm init -t {templatename} -d dir name -``` - -- **\{templatename\}** indicates the template name. -- **dir** indicates the path for storing the bundle to be created. -- **name** indicates the name of the bundle to be created. - -## Building a Bundle - -After completing code development, you need to build the bundle. The HPM supports command integration so that you can select any build tool \(such as **make**, **gcc**, and **gn**\) suitable for your project. You only need to define the **build** command in the **scripts** in the **bundle.json** file of your project, and then you run the hpm command **build** to perform building. - -## Defining the Building Script - -This section uses how to build an executable file **helloworld** in the **app** directory as an example. - -``` -app -├── BUILD.gn -├── include -│ └── helloworld.h -└── src - └── helloworld.c -``` - -Create a **BUILD.gn** file in the same directory as **helloworld.c**. - -``` -touch BUILD.gn -vim BUILD.gn -``` - -The following is an example of **BUILD.gn** for your reference: - -``` -executable("hello_world") { - sources = [ - "src/helloworld.c" - ] - - include_dirs = [ - "include" - ] -} -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->- **executable** is a built-in template of **gn**. You can run the **gn help executable** command to view how to use this template. ->- **sources** represents the source code path, and **include\_dirs** represents the header file path. - -## Executing the Building Script - -Run the following command: - -``` -hpm build -``` - -After all building operations are complete, the message "build succeed" is displayed. You need to check the building result. - -![](figures/en-us_image_0000001051770876.png) - -## Defining a Distribution - -A distribution refers to an image file of an executable OpenHarmony solution composed of a group of bundles. It contains many dependent bundles and provides scripts to illustrate how to compile and link these bundles. - -## Defining Scripts - -Define scripts in **bundle.json** as follows: - -``` -{ -"name": "my_dist", -"version": "1.0.0", -"publishAs": "distribution", -"scripts": { -"dist": "make -${args}" - }, -"base": { -"name": "dist-bundle", -"version": "1.0.0" - }, -"envs": { -"args": "x86" - }, -"dependencies": { -} -} -``` - -## Distributing - -Run the following command in the current distribution directory: - -``` -hpm dist -``` - -The **hpm-cli** tool automatically performs compiling and packing, and generates an image file of the **dist** script defined based on **scripts**. The following is an example: - -``` -out -|-xxdist.img -|-xx.file -``` - -## Burning - -The building result of the distribution can be burnt into devices, for example, by using the **hiburn** tool. You need to configure burning parameters in the **bundle.json** file of the distribution. - -``` -"scripts": { -"flash": "{$DEP_HIBURN}/hiburn" -}, -``` - -You should set burning parameters by referring to the specific guide on the burning tool you use. - -``` -hpm run flash -``` - -## Debugging - -Start debugging after you have burnt the image file of the distribution into devices. The debugging process varies according to specific development boards and IDE debugging tools. - diff --git a/en/device-dev/bundles/bundle-management.md b/en/device-dev/bundles/bundle-management.md deleted file mode 100644 index 4511f3427ca7e4ba140bc844e3c4450fd545daf8..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/bundle-management.md +++ /dev/null @@ -1,232 +0,0 @@ -# Bundle Management - -- [Dependency](#section12657593129) -- [HPM Command Reference](#section1258849181312) - -## Dependency - -A basic **bundle.json** file needs to be enriched by bundle dependencies to implement more complex features. Bundle names and version numbers should be defined in the **dependencies** field of **bundle.json**. - -``` -{ - "name": "my-bundle", - "version": "1.0.0", - "dependencies": { - "net": "1.0.0" - } -} -``` - -In this example, **my-bundle** depends on **net 1.0.0**. After you globally install the hpm-cli tool, run the following command to obtain bundle dependencies from the remote repository: - -``` -hpm install -``` - -Bundle dependencies are then stored in the **ohos\_bundles** folder in the root directory of the current bundle. A tree structure illustrating the bundle and its dependencies will be generated. You need to run the following command in the root directory of the bundle: - -``` -username@server MINGW64 /f/showcase/demo/demo -$ hpm list -+--demo@1.0.0 -| +--@huawei/media@1.0.2 -| +--@demo/sport_hi3518ev300_liteos_a@1.0.0 -| | +--@demo/app@4.0.1 -| | | +--@demo/build@4.0.1 -| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 -| | +--@demo/liteos_a@4.0.0 -| | | +--@demo/third_party_fatfs@4.0.0 -| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 -| | +--@demo/init@4.0.0 -| | +--@demo/dist_tools@4.0.0 -``` - -Alternatively, you can view the dependencies of the current bundle in a graph by running the following command: - -``` -hpm dependencies -``` - -A **deps\_visual** folder is generated in the current directory. The folder contains the **deps.html** and **deps-data.js** files. After you open the **deps.html** file via a browser, you can view bundle dependencies illustrated by a graph, as shown in the following figure. - -Each dependency type is indicated by a different color at the corresponding node. You can move the mouse pointer to a node to view the implied information. - -**Figure 1** Bundle dependencies -![](figures/bundle-dependencies.png "bundle-dependencies") - -## HPM Command Reference - -You can use the hpm-cli tool to manage the lifecycle of a bundle. The following table describes available HPM commands. \(You can run the **hpm -h** command to get the command details\). - -**Table 1** HPM commands - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Command

-

Description

-

Querying version information

-

hpm -V or hpm --version

-

Queries the hpm-cli version number.

-

Querying help information

-

hpm -h or hpm --version

-

Queries the command list and help information.

-

hpm -h

-

Queries command reference.

-

Creating a project

-

-

hpm init bundle

-

Creates a bundle project.

-

hpm init -t template

-

Creates a scaffolding project based on the template.

-

Installing bundles

-

-

hpm install or hpm i

-

Installs dependent bundles in the bundle.json file.

-

hpm install bundle@version

-

Installs bundles of a specified version.

-

Uninstalling bundles

-

-

hpm uninstall bundle

-

Removes dependent bundles.

-

hpm remove or hpm rm bundlename

-

Removes dependent bundles.

-

Viewing information

-

-

hpm list or hpm ls

-

Displays the bundle tree of available bundles and distributions.

-

hpm dependencies

-

Generates the dependency diagram (in HTML format) of available bundles and distributions.

-

Searching for bundles

-

hpm search name

-

Searches for bundles. --json is used to specify the search result in JSON format, and -type is used to set the target type, which can be bundle, distribution, or code-segment.

-

Setting HPM configuration items

-

hpm config set key value

-

Sets configuration items, such as the server address and network proxy.

-

hpm config delete key

-

Deletes configurations.

-

Updating bundle versions

-

-

hpm update

-

Updates the versions of dependent bundles.

-

hpm check-update

-

Checks whether version updates are available to dependent bundles.

-

Building

-

-

hpm build

-

Builds a bundle or distribution.

-

hpm dist

-

Packs a distribution, depending on the dist script in scripts of bundle.json.

-

Packing

-

hpm pack

-

Packs dependencies of local bundles.

-

Burning

-

hpm run flash

-

Burns the firmware, depending on the flash script in scripts of bundle.json.

-

Publishing

-

hpm publish

-

Publishes a bundle, which must be unique in the repository and has a unique version. (An account is required for login.)

-

Running extended commands

-

hpm run

-

Runs the commands in scripts defined in bundle.json. Multiple commands can be executed in batches by using &&.

-

Generating a key

-

hpm gen-keys

-

Generates a public-private key pair and configures the public key on the HPM server, achieving password-free hpm-cli login for bundle publishing.

-

Generating third-party open source notice

-

hpm gen-notice

-

Generates a joint file describing the notice on third-party open source based on the description of each bundle.

-
- diff --git a/en/device-dev/bundles/bundle-version.md b/en/device-dev/bundles/bundle-version.md deleted file mode 100644 index d07118d86a36d626e1ba8a04112560d4fb25d4ad..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/bundle-version.md +++ /dev/null @@ -1,23 +0,0 @@ -# Bundle Version - -- [Version Number Naming Specifications](#section16893854141310) -- [Version Publishing](#section43401320171420) - -## Version Number Naming Specifications - -Each version name allows only lowercase letters, which can be separated by hyphens \(-\) or underscores \(\_\). For example, **bundle** and **my\_bundle** are allowed. - -A bundle version number is in the format of _major version number_._minor version number_._revision version number_ or _major version number_._minor version number_._revision version number_-_pre-release version number_, for example, **1.0.0** and **1.0.0-beta**. For details, see [https://semver.org](https://semver.org/). - -## Version Publishing - -You should upload bundles to the remote repository so that your peers have an option to use them. You can run the following command to upload the bundles: - -``` -hpm publish -``` - -After this command is executed, the system checks the bundle dependencies and downloads the missing dependencies. If the bundles you uploaded are in binary, the system compiles the entire bundle, generates a binary file, packs the file, and uploads it. If the bundles you uploaded are in another format, the system packs the bundle file in compliance with the defined packing rules and then uploads the file. - -Note: To publish a bundle, you need an HPM account for login. After logging in to the HPM platform, register with an organization and apply for authentication. After successful authentication, you will have the permission to publish the bundle. - diff --git a/en/device-dev/bundles/bundles-demo-devsample.md b/en/device-dev/bundles/bundles-demo-devsample.md new file mode 100644 index 0000000000000000000000000000000000000000..4b896d4811456deb410fab4abbab7baac6e2493c --- /dev/null +++ b/en/device-dev/bundles/bundles-demo-devsample.md @@ -0,0 +1,54 @@ +# Development Example + +This following uses the Hi3861 platform as an example to describe how to install, compile, and package components by using HPM. + +1. Run the following commands to initialize the installation directory \(whose name can be customized\): + + ``` + mkdir test3861 + cd test3861 + hpm init -t dist + ``` + + If the following information is displayed, the initialization is successful: + + ``` + Initialization finished. + ``` + +2. Run the following command to install the **wifi\_iot** distribution: + + ``` + hpm install @ohos/wifi_iot + ``` + + If the following information is displayed, the installation is successful: + + ``` + Installed. + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Run the following command for the Hi3516 platform: + >``` + >hpm install @ohos/ip_camera_hi3516dv300 + >``` + >Run the following command for the Hi3518 platform: + >``` + >hpm install @ohos/ip_camera_hi3518ev300 + >``` + +3. Run the following command to build and package components: + + ``` + hpm dist + ``` + + If the building is successful, the following information is displayed: + + ``` + {{name}}: distribution building completed. + ``` + +4. Check the result in the **./out** directory. You can burn the distribution into the corresponding development board for testing. + diff --git a/en/device-dev/bundles/bundles-demo-environment.md b/en/device-dev/bundles/bundles-demo-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..6780aa705ee1b918dd9f6d748c286b0deae34476 --- /dev/null +++ b/en/device-dev/bundles/bundles-demo-environment.md @@ -0,0 +1,139 @@ +# Preparations + +- [Linux Server](#section20979554791) +- [Node.js](#section9954105413153) +- [HPM](#section15937194904819) +- [Python Environment](#section1621819180417) +- [File Packaging Tool](#section77617165913) +- [SCons](#section20558439191516) + +## Linux Server + +Prepare a 64-bit Linux server running Ubuntu 16.04 or later. HPM supports Windows Server, but the open-source Hi3861, Hi3516, and Hi3518 solutions support only Ubuntu. + +Configure Ubuntu to use bash as the Linux system shell, by performing the following: + +``` +ls -l $(which sh) +# If the file does not point to bash, modify the file using either of the provided methods. +# Method 1: Run the following command and select no: +dpkg-reconfigure dash +# Method 2: Run the following commands to delete /bin/sh and then create a new symbolic link to bash: +rm -f /bin/sh +ln -s bash /bin/sh +``` + +## Node.js + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>If the Node.js version of the source is outdated, run the following command before running **apt-get install**: +>``` +>curl -L https://deb.nodesource.com/setup_12.x | bash +>``` + +You are advised to install Node.js 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\). + +``` +sudo apt-get install nodejs +sudo apt-get install npm +``` + +Run the following commands to view Node.js and NPM versions: + +``` +node --version # Check the Node.js version. +npm --version # Check the NPM version. +``` + +## HPM + +Install the **hpm-cli** command line tool by using the NPM \(default source: https://registry.npmjs.org/\) provided by the Node.js. + +``` +npm install -g @ohos/hpm-cli +``` + +After **hpm-cli** is installed, run the following command to view default HPM configurations: + +``` +hpm config +``` + +You can modify the default configurations as required. The following lists common HPM configurations: + +``` +registry = https://hpm.harmonyos.com # Register with the HPM registration center. This is mandatory for downloading components. +strictSsl = true # Enable strict SSL verification as HTTPS is used for connection. +http_proxy = http://your-proxy-server:port # Configure the HTTP proxy. +https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy. +``` + +For details about **hpm-cli** commands, see [HPM Commands](bundles-standard-rules.md). + +## Python Environment + +Run the following commands to install Python later than 3.7: + +``` +sudo apt-get install python3.8 +sudo apt-get install python3-pip +sudo pip3 install setuptools +sudo pip3 install kconfiglib # Install kconfiglib 13.2.0 or later. +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The preceding method is applicable to Hi3518 and Hi3516 platforms. For Hi3861, run the following commands to install the Python environment: +>``` +>sudo apt-get install python3.8 +>sudo apt-get install python3-pip +>sudo pip3 install setuptools +>sudo pip3 install kconfiglib # Install kconfiglib 13.2.0 or later. +>sudo pip3 install pycryptodome +>sudo pip3 install six --upgrade --ignore-installed six +>sudo pip3 install ecdsa +>``` + +If both Python2 and Python3 have been installed in the current system, run the following commands to set the default Python to Python3: + +``` +ll `which python` +rm /usr/bin/python +ln -s python3.8 /usr/bin/python +``` + +## File Packaging Tool + +Run the following commands to install the tool: + +``` +which mkfs.vfat # If mkfs.vfat is not found, run the following command: +sudo apt-get install dosfstools +which mcopy # If mcopy is not found, run the following command: +sudo apt-get install mtools +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Both Hi3518 and Hi3516 platforms require the file packaging tool. For Hi3861, the tool is not required. + +## SCons + +1. Start a Linux server. +2. Run the following command to install the SCons installation package: + + ``` + python3 -m pip install scons + ``` + +3. Run the following command to check whether SCons is successfully installed. If the installation is successful, the query result as shown in [Figure 1](#fig235815252492) is displayed. + + ``` + scons -v + ``` + + **Figure 1** Successful installation \(SCons version requirement: 3.0.4 or later\) + ![](figure/successful-installation-(scons-version-requirement-3-0-4-or-later)-25.png "successful-installation-(scons-version-requirement-3-0-4-or-later)-25") + + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>SCons is required for the Hi3861 platform, but not for the Hi3518 or Hi3516 platform. + diff --git a/en/device-dev/bundles/introduction.md b/en/device-dev/bundles/bundles-demo-hpmdescription.md similarity index 100% rename from en/device-dev/bundles/introduction.md rename to en/device-dev/bundles/bundles-demo-hpmdescription.md diff --git a/en/device-dev/bundles/bundles-demo.md b/en/device-dev/bundles/bundles-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..846d6b1bde058051ef3212edb3596a2d7ec22396 --- /dev/null +++ b/en/device-dev/bundles/bundles-demo.md @@ -0,0 +1,9 @@ +# HPM User Guide + +- **[Introduction](bundles-demo-hpmdescription.md)** + +- **[Preparations](bundles-demo-environment.md)** + +- **[Development Example](bundles-demo-devsample.md)** + + diff --git a/en/device-dev/bundles/bundles-guide-develop.md b/en/device-dev/bundles/bundles-guide-develop.md new file mode 100644 index 0000000000000000000000000000000000000000..d7f0fdad1f664ab9f46ffbee7f40e07ae024dffb --- /dev/null +++ b/en/device-dev/bundles/bundles-guide-develop.md @@ -0,0 +1,240 @@ +# Bundle Development + +- [Developing OpenHarmony Bundles](#section1976410130540) +- [Creating a Bundle](#section717481119145) +- [Modifying a Bundle](#section102861955201410) +- [Using HPM-provided Template to Create a Bundle](#section15882846181510) +- [Building a Bundle](#section136732148541) +- [Defining the Building Script](#section10274147111610) +- [Executing the Building Script](#section879301916172) +- [Defining a Distribution](#section413216495619) +- [Defining Scripts](#section11503171219190) +- [Distributing](#section4694125521912) +- [Burning](#section1746331545413) +- [Debugging](#section6742131615549) + +## Developing OpenHarmony Bundles + +You have an option to use any of the following methods to develop OpenHarmony bundles: + +- Develop a brand new bundle from scratch. +- Rewrite code of an existing non-bundle to develop a bundle. +- Use HPM-provided bundle templates to quickly develop a bundle. + +## Creating a Bundle + +Generally, you can find commonly used bundles on the [HPM](https://hpm.harmonyos.com/#/en/home) website. If they cannot meet your requirements, you can develop your own bundles. + +You can publish bundles in the HPM repository if you like, so that your peers have an option to use them. Assume that you want to create a bundle named **my-bundle** in the **D:/source** directory: + +Run the **hpm init** command to create the scaffold code for this bundle. For example, you can go to the **D:/source** directory and run the following command: + +``` +hpm init -t default -d demo my-bundle +``` + +The following files are generated in the **source** directory: + +``` +mybundle +├── bundle.json # Metadata description file of the bundle +├── example # Example of testing bundle functions +│ └── main.c +├── include # Internal header files of the bundle +│ └── mybundle.h +├── README.md # Brief description of the bundle +└── src # Source code of the bundle + └─ mybundle.c +``` + +Then, complete your coding based on service requirements. Finally, use **git** to commit your code \(including the **bundle.json** file\) to the code hosting repository, such as gitee. + +## Modifying a Bundle + +If you have code unqualified for the OpenHarmony bundle structure, modify your code to match an HPM bundle. In the code directory \(for example, **mybundle2**\) storing your code, run the following command with the bundle name and version specified: + +``` +hpm init +``` + +1. Enter a bundle name \(**mybundle2** as an example\) and press **Enter**. +2. Enter the bundle version \(**1.0.0** as an example\) and press **Enter**. A **bundle.json** file is generated in the current bundle directory. +3. Add other descriptions in **bundle.json**, which is publishable. + + ``` + $ hpm init + Your bundle will be created in dirname E:\demo\mybundle2 + ? bundle name mybundel2 + ? version 1.0.0 + Init finished! + ``` + + +1. Modify other information \(such as the author, code repository, code directory, command script, and dependent bundles\) in **bundle.json**. + + ``` + { + "name": "mybundle2", + "version": "1.0.0", + "publishAs": "source", + "dirs":{ + ".":[ + "README.md" + ], + "src":[ + "test.c" + ], + "header":[ + "header/test.h" + ], + "src/common":[ + "src/common/foobar.txt" + ] + }, + "scripts": { + "build": "make -${args}" + }, + "dependencies": { + "@ohos/cjson": "^1.0.0", + "@ohos/": "^1.2.0" + } + } + ``` + + +## Using HPM-provided Template to Create a Bundle + +The HPM provides **default** and **simple** templates as well as other templates that are stored on the server. + +You can run the **hpm search -t template** command to search for a template stored on the server. + +![](figure/en-us_image_0000001051452177.png) + +Then, select your desired template based on the information below **description**, use the selected template to quickly create the bundle scaffold, and run the following command with the **-t** and **-d** parameters specified: + +``` +hpm init -t {templatename} -d dir name +``` + +- **\{templatename\}** indicates the template name. +- **dir** indicates the path for storing the bundle to be created. +- **name** indicates the name of the bundle to be created. + +## Building a Bundle + +After completing code development, you need to build the bundle. The HPM supports command integration so that you can select any build tool \(such as **make**, **gcc**, and **gn**\) suitable for your project. You only need to define the **build** command in the **scripts** in the **bundle.json** file of your project, and then you run the hpm command **build** to perform building. + +## Defining the Building Script + +This section uses how to build an executable file **helloworld** in the **app** directory as an example. + +``` +app +├── BUILD.gn +├── include +│ └── helloworld.h +└── src + └── helloworld.c +``` + +Create a **BUILD.gn** file in the same directory as **helloworld.c**. + +``` +touch BUILD.gn +vim BUILD.gn +``` + +The following is an example of **BUILD.gn** for your reference: + +``` +executable("hello_world") { + sources = [ + "src/helloworld.c" + ] + + include_dirs = [ + "include" + ] +} +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- **executable** is a built-in template of **gn**. You can run the **gn help executable** command to view how to use this template. +>- **sources** represents the source code path, and **include\_dirs** represents the header file path. + +## Executing the Building Script + +Run the following command: + +``` +hpm build +``` + +After all building operations are complete, the message "build succeed" is displayed. You need to check the building result. + +![](figure/en-us_image_0000001051770876.png) + +## Defining a Distribution + +A distribution refers to an image file of an executable OpenHarmony solution composed of a group of bundles. It contains many dependent bundles and provides scripts to illustrate how to compile and link these bundles. + +## Defining Scripts + +Define scripts in **bundle.json** as follows: + +``` +{ +"name": "my_dist", +"version": "1.0.0", +"publishAs": "distribution", +"scripts": { +"dist": "make -${args}" + }, +"base": { +"name": "dist-bundle", +"version": "1.0.0" + }, +"envs": { +"args": "x86" + }, +"dependencies": { +} +} +``` + +## Distributing + +Run the following command in the current distribution directory: + +``` +hpm dist +``` + +The **hpm-cli** tool automatically performs compiling and packing, and generates an image file of the **dist** script defined based on **scripts**. The following is an example: + +``` +out +|-xxdist.img +|-xx.file +``` + +## Burning + +The building result of the distribution can be burnt into devices, for example, by using the **hiburn** tool. You need to configure burning parameters in the **bundle.json** file of the distribution. + +``` +"scripts": { +"flash": "{$DEP_HIBURN}/hiburn" +}, +``` + +You should set burning parameters by referring to the specific guide on the burning tool you use. + +``` +hpm run flash +``` + +## Debugging + +Start debugging after you have burnt the image file of the distribution into devices. The debugging process varies according to specific development boards and IDE debugging tools. + diff --git a/en/device-dev/bundles/bundles-guide-overview.md b/en/device-dev/bundles/bundles-guide-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..a6d16e00da5e950294612bc72454fe531fa3bbdf --- /dev/null +++ b/en/device-dev/bundles/bundles-guide-overview.md @@ -0,0 +1,146 @@ +# Bundle Development + +- [Overview](#section112136415486) +- [Preparations](#section12731192104816) + - [Hardware Requirements](#section71851750144814) + - [Installing Node.js and the hpm-cli Tool](#section675199493) + - [\(Optional\) Modifying HPM Configurations](#section1940205015499) + - [Downloading OpenHarmony Code](#section42591118155217) + - [Installing Dependent Bundles](#section644212530524) + +- [Bundle Development](#section15640113715318) + +## Overview + +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. + +- 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. + +**Table 1** Differences between a bundle and a distribution + + + + + + + + + + + + + + + + + + + + + + + + +

Aspect

+

Bundle

+

Distribution

+

Application scenario

+

Feature-oriented

+

System-oriented

+

Content

+

Codes or a binary library for implementing features

+

List of dependent bundles as well as their compiling and building scripts

+

Integrity

+

A part of the operating system

+

An entire operating system

+

Compilation result

+

Bundles

+

System image

+
+ +**Figure 1** Composition of bundles and distributions + + +![](figure/组件0924.png) + +## Preparations + +### Hardware Requirements + +- Development boards \(examples: Hi3861, Hi3516D V300, and Hi3518E V300\) +- Host computer \(Windows workstation\) +- Linux server + +**Figure 2** Hardware connections +![](figure/hardware-connections-23.png "hardware-connections-23") + +### Installing **Node.js** and the **hpm-cli** Tool + +1. Install **Node.js**. + + Download **Node.js** from its official website and install it on your local PC. + + You are advised to install [Node.js](https://nodejs.org/) 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\). + +2. Install the **hpm-cli** tool using **npm** delivered with **Node.js**. Run the following command: + + ``` + npm install -g @ohos/hpm-cli + ``` + +3. Run the following command to check whether the installation is successful. If an HPM version is displayed, the installation is successful. + + ``` + hpm -V or hpm --version + ``` + +4. \(Optional\) Run the following command to upgrade the HPM version if needed: + + ``` + npm update -g @ohos/hpm-cli + ``` + + +### \(Optional\) Modifying HPM Configurations + +After the **hpm-cli** tool is installed, run the following command to view HPM configurations: + +``` +hpm config +``` + +Default HPM configurations are displayed upon the command execution. You can modify the default configurations as required. The following lists common HPM configurations: + +``` +registry = https://hpm.harmonyos.com/hpm/registry/api # Configure the address of the HPM registry (mandatory for downloading bundles). +login = https://hpm.harmonyos.com/hpm/auth/pk # Configure the address for HPM login (mandatory for publishing bundles). +loginUser = {your-account} # Configure the account for HPM login (mandatory for publishing bundles). +shellPath = C:\WINDOWS\System32\cmd.exe # Configure the shell for running HPM commands. +globalRepo = C:\Users\yourname\.global # Configure the path for storing bundles that are installed globally. +http_proxy = http://your-proxy-server:port # Configure the HTTP proxy. +https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy. +``` + +For details about **hpm-cli** commands, see [HPM Commands](bundles-guide-overview.md). + +### Downloading OpenHarmony Code + +For details, see [Source Code Acquisition](../get-code/sourcecode-acquire.md). + +### Installing Dependent Bundles + +The HPM publishes commonly used development tools \(such as those for burning, compiling, and compression\) as bundles. You can run the following command to install these tools. After the command is executed, the system automatically downloads and installs the tools, which need to be installed globally only once. + +``` +hpm i -g @ohos/llvm +hpm i -g @ohos/ninja +hpm i -g @ohos/gn +hpm i -g @ohos/hc_gen +hpm i -g @ohos/sysroot +``` + +These are a set of development tools \(such as **gn** and **ninja**\). With these tools, you can start your general bundle development based on source code. + +## Bundle Development + diff --git a/en/device-dev/bundles/bundles-guide-prepare.md b/en/device-dev/bundles/bundles-guide-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..f706e2c2f8ebf2c8307e60a5595d53eb9799d1c1 --- /dev/null +++ b/en/device-dev/bundles/bundles-guide-prepare.md @@ -0,0 +1,84 @@ +# Preparations + +- [Hardware Requirements](#section98535485518) +- [Installing Node.js and the hpm-cli Tool](#section106591616205311) +- [\(Optional\) Modifying HPM Configurations](#section71821165412) +- [Downloading OpenHarmony Code](#section102338221707) +- [Installing Dependent Bundles](#section19233183315020) + +## Hardware Requirements + +- Development boards \(examples: Hi3861, Hi3516D V300, and Hi3518E V300\) +- Host computer \(Windows workstation\) +- Linux server + +**Figure 1** Hardware connections +![](figure/hardware-connections-24.png "hardware-connections-24") + +## Installing **Node.js** and the **hpm-cli** Tool + +1. Install **Node.js**. + + Download **Node.js** from its official website and install it on your local PC. + + You are advised to install [Node.js](https://nodejs.org/) 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\). + +2. Install the **hpm-cli** tool using **npm** delivered with **Node.js**. Run the following command: + + ``` + npm install -g @ohos/hpm-cli + ``` + +3. Run the following command to check whether the installation is successful. If an HPM version is displayed, the installation is successful. + + ``` + hpm -V or hpm --version + ``` + +4. \(Optional\) Run the following command to upgrade the HPM version if needed: + + ``` + npm update -g @ohos/hpm-cli + ``` + + +## \(Optional\) Modifying HPM Configurations + +After the **hpm-cli** tool is installed, run the following command to view HPM configurations: + +``` +hpm config +``` + +Default HPM configurations are displayed upon the command execution. You can modify the default configurations as required. The following lists common HPM configurations: + +``` +registry = https://hpm.harmonyos.com/hpm/registry/api # Configure the address of the HPM registry, mandatory for downloading bundles. +login = https://hpm.harmonyos.com/hpm/auth/pk # Configure the address for HPM login, mandatory for publishing bundles. +loginUser = {your-account} # Configure the account for HPM login, mandatory for publishing bundles. +shellPath = C:\WINDOWS\System32\cmd.exe # Configure the shell for running HPM commands. +globalRepo = C:\Users\yourname\.global # Configure the path for storing bundles that are installed globally. +http_proxy = http://your-proxy-server:port # Configure the HTTP proxy. +https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy. +``` + +For details about **hpm-cli** commands, see [HPM Commands](bundles-guide-overview.md). + +## Downloading OpenHarmony Code + +For details, see [Source Code Acquisition](../get-code/sourcecode-acquire.md). + +## Installing Dependent Bundles + +The HPM publishes commonly used development tools \(such as those for burning, compiling, and compression\) as bundles. You can run the following command to install these tools. After the command is executed, the system automatically downloads and installs the tools, which need to be installed globally only once. + +``` +hpm i -g @ohos/llvm +hpm i -g @ohos/ninja +hpm i -g @ohos/gn +hpm i -g @ohos/hc_gen +hpm i -g @ohos/sysroot +``` + +These are a set of development tools \(such as **gn** and **ninja**\). With these tools, you can start your general bundle development based on source code. + diff --git a/en/device-dev/bundles/bundles-guide.md b/en/device-dev/bundles/bundles-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..162b7be93ab12c2b1da404fd0fca89f6a3b6e4d4 --- /dev/null +++ b/en/device-dev/bundles/bundles-guide.md @@ -0,0 +1,9 @@ +# Development Guidelines + +- **[Bundle Development](bundles-guide-overview.md)** + +- **[Preparations](bundles-guide-prepare.md)** + +- **[Bundle Development](bundles-guide-develop.md)** + + diff --git a/en/device-dev/bundles/bundles-standard-rules.md b/en/device-dev/bundles/bundles-standard-rules.md new file mode 100644 index 0000000000000000000000000000000000000000..8adaac0e618ca9b141d52d7a4683a8ba3fa086ae --- /dev/null +++ b/en/device-dev/bundles/bundles-standard-rules.md @@ -0,0 +1,549 @@ +# Development Specifications + +- [Overview](#section1725818533344) + - [Definition](#section4821219183514) + - [Bundle Division Principles](#section1089794263513) + - [Bundle Dependency](#section25701647163710) + +- [Bundle Composition](#section185538333914) + - [Code Files](#section8431268393) + - [README File](#section168121548173914) + - [Metadata Description File](#section7107181819406) + +- [Bundle Management](#section32061634104110) + - [Dependency](#section791115242423) + - [HPM Command Reference](#section1183205411429) + +- [Bundle Version](#section12612142864316) + - [Version Number Naming Specifications](#section1487612416432) + - [Version Publishing](#section1548171014440) + +- [Distribution](#section1264139114413) +- [Environment Variables](#section15352105174512) + +## Overview + +This document describes the basic concepts of a bundle and how to define it in compliance with specifications. + +### Definition + +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: + +- 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 +- Application-level bundles: applications that provide services to users, such as **wifi\_iot** and **ip\_camera** + +Bundles are designed for reuse purposes. Any reusable modules can be defined as bundles. They are classified into the following types based on their forms: + +- Source code +- Binary system +- Code snippet +- Distribution + +### Bundle Division Principles + +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: + +- Independence: Bundles provide relatively independent features and can be independently built. Each bundle is capable of providing its own APIs and services for external systems. +- Coupling: If a bundle must depend on another bundle to provide services, they can be coupled to one bundle. +- 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. + +### Bundle Dependency + +A bundle dependency can be mandatory or optional. + +- Mandatory dependency: If bundle A must depend on bundle B to implement a feature \(the APIs or services specific to bundle B must be invoked\), bundle B is a mandatory dependency of bundle A. +- Optional dependency: If bundle C or bundle D is required for bundle A to implement a feature and bundle C and bundle D are interchangeable, bundle C and bundle D are optional dependencies of bundle A. + +## Bundle Composition + +A bundle contains the following: + +- **src** directory for storing code files or code library +- **ohos\_bundles** folder for storing dependent bundles \(It is automatically generated during bundle installation, without the need to submit to the code library.\) +- **README.md** file for describing the bundle +- **bundle.json** file for declaring metadata of the bundle +- **LICENSE** file for open-source code + + ``` + my-bundle + |_ohos_bundles + |_src + |_bundle.json + |_README.md + |_LICENSE + ``` + + +### Code Files + +Bundle code files are the same as those in a common code directory. The only difference lies in the open APIs \(declared in header files\) of a bundle, which are likely to be referenced by other bundles and need to be declared in **dirs** of **bundle.json**. + +### README File + +**README.md** is a bundle self-description file using the markdown syntax. For details, see [Syntax Reference](https://www.markdownguide.org/getting-started/). + +To help you easily find and use the desired bundle on the HarmonyOS Package Manager \(HPM\) platform, a **README** file is provided in the root directory of each bundle. + +The **README** file may include instructions on how to install, configure, and use the instance code in the bundle, as well as any other information helpful to you. + +The **README** file is available in the bundle details page of the HPM platform. + +### Metadata Description File + +The **bundle.json** file describes the metadata of a bundle. Each bundle has its own **bundle.json** file. + +``` +{ + "name": "@myorg/demo-bundle", + "version": "1.0.0", + "license": "MIT", + "description": "bundle description", + "keywords": ["hos"], + "tags": ["applications", "drivers"], + "author": {"name":"","email":"","url":""}, + "contributors":[{"name":"","email":"","url":""},{"name":"","email":"","url":""}], + "homepage": "http://www.foo.bar.com", + "repository": "https://git@gitee.com:foo/bar.git", + "publishAs": "code-segment", + "segment":{ + "destPath":"/the/dest/path" + }, + "dirs": { + "src": ["src/**/*.c"], + "headers": ["headers/**/*.h"], + "bin": ["bin/**/*.o"] + }, + "scripts": { + "build": "make" + }, + "envs": {}, + "ohos": { + "os": "2.0.0", + "board": "hi3516", + "kernel": "liteos-a" + }, + "rom": "10240", + "ram": "1024", + "dependencies": { + "@myorg/net":"1.0.0" + } +} +``` + +Each **bundle.json** file has the following fields: + +- **name**: a bundle name, which starts with @ and is separated by /, for example, **@myorg/mybundle** + +- **version**: a bundle version number, for example, 1.0.0. The version number must comply with the Semantic Versioning Specification \(SemVer\) standards. + +- **description**: a brief description of a bundle +- **dependencies**: bundles that a bundle depends on + +- **envs**: parameters required for bundle compilation, including global parameters and dependency parameters. + +- **scripts**: commands executable to a bundle, such as commands for compiling, building, testing, and burning + +- **publishAs**: bundle publishing type, which can be **source**, **binary**, **distribution**, or **code-segment** + +- **segment**: destination path of the code-segment bundle. That is, the destination path of the files contained in the bundle package after the bundle is installed. +- **dirs**: directory structure \(such as the header file\) generated for publishing + +- **ram&rom**: statistical information about the estimated read-only memory \(ROM\) and random access memory \(RAM\) usage +- **ohos**: mappings among OpenHarmony versions, development boards, and kernels, separated by commas \(,\). +- Extended information: author, home page, code repository, license, tags, and keywords +- **base** \(only for a distribution\): a base distribution which others inherit from. + +## Bundle Management + +### Dependency + +A basic **bundle.json** file needs to be enriched by bundle dependencies to implement more complex features. Bundle names and version numbers should be defined in the **dependencies** field of **bundle.json**. + +``` +{ + "name": "my-bundle", + "version": "1.0.0", + "dependencies": { + "net": "1.0.0" + } +} +``` + +In this example, **my-bundle** depends on **net 1.0.0**. After you globally install the hpm-cli tool, run the following command to obtain bundle dependencies from the remote repository: + +``` +hpm install +``` + +Bundle dependencies are then stored in the **ohos\_bundles** folder in the root directory of the current bundle. A tree structure illustrating the bundle and its dependencies will be generated. You need to run the following command in the root directory of the bundle: + +``` +username@server MINGW64 /f/showcase/demo/demo +$ hpm list ++--demo@1.0.0 +| +--@huawei/media@1.0.2 +| +--@demo/sport_hi3518ev300_liteos_a@1.0.0 +| | +--@demo/app@4.0.1 +| | | +--@demo/build@4.0.1 +| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 +| | +--@demo/liteos_a@4.0.0 +| | | +--@demo/third_party_fatfs@4.0.0 +| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 +| | +--@demo/init@4.0.0 +| | +--@demo/dist_tools@4.0.0 +``` + +Alternatively, you can run the following command to view the dependencies of the current bundle in a visualized way: + +``` +hpm ui +``` + +A web service is started on the local host \(by default, the browser is open and the project page is displayed\). Click the project dependency icon on the sidebar. The list of dependent bundles is displayed. Click the button on the right to switch to the tree view. The bundle dependencies are displayed as shown in the following figure. + +**Figure 1** Bundle dependencies + + +![](figure/en-us_image_0000001173313501.png) + +### HPM Command Reference + +You can use the hpm-cli tool to manage the lifecycle of a bundle. The following table describes available HPM commands. \(You can run the **hpm -h** command to get the command details\). + +**Table 1** HPM commands + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Command Line

+

Description

+

Querying version information

+

hpm -V or hpm --version

+

Displays the hpm-cli version number.

+

Querying help information

+

hpm -h or hpm --version

+

Displays the command list and help information.

+

hpm -h

+

Displays command help information.

+

Creating a project

+

+

hpm init bundle

+

Creates a bundle project.

+

hpm init -t template

+

Creates a scaffolding project from a template.

+

Installing bundles

+

+

hpm install or hpm i

+

Installs dependent bundles in the bundle.json file.

+

hpm install bundle@version

+

Installs bundles of a specified version.

+

Uninstalling bundles

+

+

hpm uninstall bundle

+

Uninstalls dependent bundles.

+

hpm remove or hpm rm bundlename

+

Removes dependent bundles.

+

Viewing information

+

+

hpm list or hpm ls

+

Displays the bundle tree of available bundles and distributions.

+

hpm dependencies

+

Generates the dependency relationship data of a bundle or distribution. (This command is also integrated in the HPM UI to display the bundle dependencies intuitively.)

+

Searching for bundles

+

hpm search name

+

Searches for bundles. --json is used to specify the search result in JSON format, and -type is used to set the target type, which can be bundle, distribution, or code-segment.

+

Setting HPM configuration items

+

hpm config set key value

+

Sets configuration items, such as the server address and network proxy.

+

hpm config delete key

+

Deletes configurations.

+

Updating bundle versions

+

+

hpm update

+

Updates the versions of dependent bundles.

+

hpm check-update

+

Checks whether version updates are available to dependent bundles.

+

Building

+

+

hpm build

+

Builds a bundle or distribution.

+

hpm dist

+

Builds a distribution. The build depends on the dist script in scripts of bundle.json.

+

Packing

+

hpm pack

+

Packs dependencies of local bundles.

+

Burning

+

hpm run flash

+

Burns the firmware. The firmware burning depends on the flash script in scripts of bundle.json.

+

Publishing

+

hpm publish

+

Publishes a bundle, which must be unique in the repository and has a unique version. (An account is required for login.)

+

Running extended commands

+

hpm run

+

Runs the commands in scripts defined in bundle.json. Multiple commands can be executed at a time by using &&.

+

Decompressing

+

hpm extract

+

Decompresses files in zip, tar, tgz, or .tar.gz format.

+

Restarting GUI

+

hpm ui

+

Starts the HPM UI locally. You can use the -p parameter to specify a port. On the Windows platform, the default browser is used to open the HPM UI.

+

Changing language

+

hpm lang

+

Alternates between Chinese and English on the CLI and UI.

+

Converting to HPM format

+

hpm x2h

+

Converts a Maven or NPM package to an HPM package and publishes it to the HPM.

+

Code segment restoration or cleanup

+

hpm code clean|restore

+

Clears or restores the dependent code segment (code-segment). That is, copy or delete the code segment based on segment.destPath.

+

Generating a key

+

hpm gen-keys

+

Generates a public-private key pair and configures the public key on the HPM server, which enables password-free hpm-cli login for bundle publishing.

+

Generating third-party open source notice

+

hpm gen-notice

+

Generates a file providing the notice on third-party open source by combining the description of each bundle.

+
+ +## Bundle Version + +### Version Number Naming Specifications + +Each version name allows only lowercase letters, which can be separated by hyphens \(-\) or underscores \(\_\). For example, **bundle** and **my\_bundle** are allowed. + +A bundle version number is in the format of _major version number_._minor version number_._revision version number_ or _major version number_._minor version number_._revision version number_-_pre-release version number_, for example, **1.0.0** and **1.0.0-beta**. For details, see [https://semver.org](https://semver.org/). + +### Version Publishing + +You should upload bundles to the remote repository so that your peers have an option to use them. You can run the following command to upload the bundles: + +``` +hpm publish +``` + +After this command is executed, the system checks the bundle dependencies and downloads the missing dependencies. If the bundles you uploaded are in binary, the system compiles the entire bundle, generates a binary file, packs the file, and uploads it. If the bundles you uploaded are in another format, the system packs the bundle file in compliance with the defined packing rules and then uploads the file. + +Note: To publish a bundle, you need an HPM account for login. After logging in to the HPM platform, register with an organization and apply for authentication. After successful authentication, you will have the permission to publish the bundle. + +## Distribution + +A distribution refers to an image file of an executable OpenHarmony solution composed of a group of bundles. It contains many dependent bundles and provides scripts to illustrate how to compile and link these bundles. + +Generally, a distribution does not require code but contains only the **bundle.json** description \(**publishAs** set to **distribution**\) and some compilation scripts. + +As system-provided environment variables are required during distribution compiling, run the **dist** command in **scripts**. + +``` +{ + "publishAs":"distribution", + "scripts": { + "dist": "script compile command" + } +} +``` + +Run the following command: + +``` +hpm dist +``` + +As it is rather complex to redefine the functionality of a distribution, OpenHarmony allows inheritance from a distribution so that you can make a tailored distribution based on the existing functionality. To inherit from a distribution, you need to define the **base** field in **bundle.json**. + +``` +{ + "base": { + "name": "dist_wifi_iot", + "version": "1.0.0" + } +} +``` + +In this example, the current bundle inherits from the **dist-wifi-iot 1.0.0** bundle of the distribution. + +Each distribution consists of many dependent bundles, which are represented by the **dependencies** field in **bundle.json**. Some dependencies are mandatory, and others can be added or removed required. In the **bundle.json** file, bundle names prefixed with a question mark \(?\) represent optional dependent bundles. If you want to inherit from a distribution involving such bundles, you can remove them and then add other bundles. + +``` +{ + "dependencies": { + "?my_bundle": "1.0.0" + } +} +``` + +In this example, **my\_bundle** is an optional dependent bundle that can be removed by using the keyword **excludes**. + +``` +{ + "excludes": [ "my_bundle" ] +} +``` + +The removed **my-bundle** will not be involved in the build process. If you forcibly remove mandatory dependent bundles, an error message will be displayed. + +## Environment Variables + +During bundle compilation, system-provided environment variables are required to define the output and link the required binary files. These variables are injected into the context for executing scripts based on service requirements. Therefore, their values can be directly obtained from the scripts. The following environment variables are available: + +Global variables are defined by the **envs** attribute in **bundle.json**. All dependent bundles can obtain the values of global variables. + +``` +{ + "envs": { + "compileEnv": "arm" + } +} +``` + +Different parameters can be passed to bundles when introducing dependencies so that the compilation of dependent bundles can meet the requirements of the current bundle. The parameters defined in the dependencies can be obtained from the context for executing the corresponding scripts. + +``` +{ + "dependencies": { + "my-bundle": { + "version": "1.0.0", + "mode": "debug" + } + } +} +``` + +When linking to a binary file, the bundle needs to know the file path regarding the dependencies. Therefore, the path \(as an environment variable\) is passed to the bundle for compiling. + +The passed environment variable is in **DEP\__BundleName_** format, where **BundleName** indicates the name of the dependent bundle, for example, **DEP\_first\_bundle**. + +Tags can be defined to group dependent bundles. You can obtain the path of a group of dependent bundles based on their tag. A tag starts with a number sign \(\#\) and is defined as follows: + +``` +{ + "dependencies": { + "#tool": { + "first-bundle": "1.0.0", + "second-bundle": "1.0.0" + }, + "#drivers": { + "xx-bundle": "1.0.0", + "yy-bundle": "1.0.0" + } + } +} +``` + +There are two fixed environment variables: + +- **DEP\_OHOS\_BUNDLES**: path of the **ohos\_bundles** folder +- **DEP\_BUNDLE\_BASE**: path of the outermost bundle + diff --git a/en/device-dev/bundles/bundles.md b/en/device-dev/bundles/bundles.md new file mode 100644 index 0000000000000000000000000000000000000000..21586387bbddd35439986cadb9c812a6d0c58bc3 --- /dev/null +++ b/en/device-dev/bundles/bundles.md @@ -0,0 +1,9 @@ +# Bundle Development + +- **[Development Specifications](bundles-standard-rules.md)** + +- **[Development Guidelines](bundles-guide.md)** + +- **[HPM User Guide](bundles-demo.md)** + + diff --git a/en/device-dev/bundles/development-example.md b/en/device-dev/bundles/development-example.md deleted file mode 100644 index 159de560311c2fe03fd03c947fbfa669c060f3fa..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/development-example.md +++ /dev/null @@ -1,54 +0,0 @@ -# Development Example - -This following uses the Hi3861 platform as an example to describe how to install, compile, and package components by using HPM. - -1. Run the following commands to initialize the installation directory \(whose name can be customized\): - - ``` - mkdir test3861 - cd test3861 - hpm init -t dist - ``` - - If the following information is displayed, the initialization is successful: - - ``` - Initialization finished. - ``` - -2. Run the following command to install the **wifi\_iot** distribution: - - ``` - hpm install @ohos/wifi_iot - ``` - - If the following information is displayed, the installation is successful: - - ``` - Installed. - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >Run the following command for the Hi3516 platform: - >``` - >hpm install @ohos/ip_camera_hi3516dv300 - >``` - >Run the following command for the Hi3518 platform: - >``` - >hpm install @ohos/ip_camera_hi3518ev300 - >``` - -3. Run the following command to build and package components: - - ``` - hpm dist - ``` - - If the building is successful, the following information is displayed: - - ``` - {{name}}: distribution building completed. - ``` - -4. Check the result in the **./out** directory. You can burn the distribution into the corresponding development board for testing. - diff --git a/en/device-dev/bundles/development-guidelines.md b/en/device-dev/bundles/development-guidelines.md deleted file mode 100644 index 6ae82a8f668402df6a4b967fad4fb85af5f59eef..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/development-guidelines.md +++ /dev/null @@ -1,9 +0,0 @@ -# Development Guidelines - -- **[Overview](overview-0.md)** - -- **[Preparations](preparations.md)** - -- **[Bundle Development](bundle-development.md)** - - diff --git a/en/device-dev/bundles/development-specifications.md b/en/device-dev/bundles/development-specifications.md deleted file mode 100644 index 6f583016abacb71b7bee2f3d550924cac1025286..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/development-specifications.md +++ /dev/null @@ -1,15 +0,0 @@ -# Development Specifications - -- **[Overview](overview.md)** - -- **[Bundle Composition](bundle-composition.md)** - -- **[Bundle Management](bundle-management.md)** - -- **[Bundle Version](bundle-version.md)** - -- **[Distribution](distribution.md)** - -- **[Environment Variables](environment-variables.md)** - - diff --git a/en/device-dev/bundles/distribution.md b/en/device-dev/bundles/distribution.md deleted file mode 100644 index 426905862509138efe9d65a22ddd1c5bc5b3d3f7..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/distribution.md +++ /dev/null @@ -1,56 +0,0 @@ -# Distribution - -A distribution refers to an image file of an executable OpenHarmony solution composed of a group of bundles. It contains many dependent bundles and provides scripts to illustrate how to compile and link these bundles. - -Generally, a distribution does not require code but contains only the **bundle.json** description \(**publishAs** set to **distribution**\) and some compilation scripts. - -As system-provided environment variables are required during distribution compiling, run the **dist** command in **scripts**. - -``` -{ - "publishAs":"distribution", - "scripts": { - "dist": "script compile command" - } -} -``` - -Run the following command: - -``` -hpm dist -``` - -As it is rather complex to redefine the functionality of a distribution, OpenHarmony allows inheritance from a distribution so that you can make a tailored distribution based on the existing functionality. To inherit from a distribution, you need to define the **base** field in **bundle.json**. - -``` -{ - "base": { - "name": "dist_wifi_iot", - "version": "1.0.0" - } -} -``` - -In this example, the current bundle inherits from the **dist-wifi-iot 1.0.0** bundle of the distribution. - -Each distribution consists of many dependent bundles, which are represented by the **dependencies** field in **bundle.json**. Some dependencies are mandatory, and others can be added or removed required. In the **bundle.json** file, bundle names prefixed with a question mark \(?\) represent optional dependent bundles. If you want to inherit from a distribution involving such bundles, you can remove them and then add other bundles. - -``` -{ - "dependencies": { - "?my_bundle": "1.0.0" - } -} -``` - -In this example, **my\_bundle** is an optional dependent bundle that can be removed by using the keyword "excludes". - -``` -{ - "excludes": [ "my_bundle" ] -} -``` - -After **my-bundle** is removed, it will not be involved in the building process. If you forcibly remove mandatory dependent bundles, an error message will be displayed. - diff --git a/en/device-dev/bundles/environment-variables.md b/en/device-dev/bundles/environment-variables.md deleted file mode 100644 index 933994a6818205f1a7958390a67876048369f67e..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/environment-variables.md +++ /dev/null @@ -1,53 +0,0 @@ -# Environment Variables - -During bundle compilation, system-provided environment variables are required to define the output and link the required binary files. These variables are injected into the context for executing scripts based on service requirements. Therefore, their values can be directly obtained from the scripts. Currently, there are global and fixed environment variables in the system. - -Global variables are defined by the **envs** attribute in **bundle.json**. All dependent bundles can obtain the values of global variables. - -``` -{ - "envs": { - "compileEnv": "arm" - } -} -``` - -Different parameters can be passed to bundles when introducing dependencies so that the compilation of dependent bundles can meet the requirements of the current bundle. The parameters defined in the dependencies can be obtained from the context for executing the corresponding scripts. - -``` -{ - "dependencies": { - "my-bundle": { - "version": "1.0.0", - "mode": "debug" - } - } -} -``` - -When linking to a binary file, the bundle needs to know the file path regarding the dependencies. Therefore, the path \(as an environment variable\) is passed to the bundle for compiling. - -The passed environment variable is in **DEP\__BundleName_** format, where **BundleName** indicates the name of the dependent bundle, for example, **DEP\_first-bundle**. - -Tags can be defined to group dependent bundles. You can obtain the path of a group of dependent bundles based on their tag. A tag starts with a number sign \(\#\) and is defined as follows: - -``` -{ - "dependencies": { - "#tool": { - "first-bundle": "1.0.0", - "second-bundle": "1.0.0" - }, - "#drivers": { - "xx-bundle": "1.0.0", - "yy-bundle": "1.0.0" - } - } -} -``` - -There are two fixed environment variables: - -- **DEP\_OHOS\_BUNDLES**: path of the **ohos\_bundles** folder -- **DEP\_BUNDLE\_BASE**: path of the outermost bundle - diff --git a/en/device-dev/bundles/figures/en-us_image_0000001051452177.png b/en/device-dev/bundles/figure/en-us_image_0000001051452177.png similarity index 100% rename from en/device-dev/bundles/figures/en-us_image_0000001051452177.png rename to en/device-dev/bundles/figure/en-us_image_0000001051452177.png diff --git a/en/device-dev/bundles/figures/en-us_image_0000001051770876.png b/en/device-dev/bundles/figure/en-us_image_0000001051770876.png similarity index 100% rename from en/device-dev/bundles/figures/en-us_image_0000001051770876.png rename to en/device-dev/bundles/figure/en-us_image_0000001051770876.png diff --git a/en/device-dev/bundles/figure/en-us_image_0000001173313501.png b/en/device-dev/bundles/figure/en-us_image_0000001173313501.png new file mode 100644 index 0000000000000000000000000000000000000000..52f943be7f91caa887bff689f6c37040858fa8ce Binary files /dev/null and b/en/device-dev/bundles/figure/en-us_image_0000001173313501.png differ diff --git a/en/device-dev/bundles/figures/hardware-connections.png b/en/device-dev/bundles/figure/hardware-connections-23.png similarity index 100% rename from en/device-dev/bundles/figures/hardware-connections.png rename to en/device-dev/bundles/figure/hardware-connections-23.png diff --git "a/zh-cn/device-dev/bundles/figures/\347\241\254\344\273\266\347\216\257\345\242\203\350\277\236\346\216\245\345\205\263\347\263\273.png" b/en/device-dev/bundles/figure/hardware-connections-24.png old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/bundles/figures/\347\241\254\344\273\266\347\216\257\345\242\203\350\277\236\346\216\245\345\205\263\347\263\273.png" rename to en/device-dev/bundles/figure/hardware-connections-24.png diff --git a/en/device-dev/bundles/figures/successful-installation-(scons-version-requirement-3-0-4-or-later).png b/en/device-dev/bundles/figure/successful-installation-(scons-version-requirement-3-0-4-or-later)-25.png similarity index 100% rename from en/device-dev/bundles/figures/successful-installation-(scons-version-requirement-3-0-4-or-later).png rename to en/device-dev/bundles/figure/successful-installation-(scons-version-requirement-3-0-4-or-later)-25.png diff --git "a/en/device-dev/bundles/figures/\347\273\204\344\273\2660924.png" "b/en/device-dev/bundles/figure/\347\273\204\344\273\2660924.png" similarity index 100% rename from "en/device-dev/bundles/figures/\347\273\204\344\273\2660924.png" rename to "en/device-dev/bundles/figure/\347\273\204\344\273\2660924.png" diff --git a/en/device-dev/bundles/figures/bundle-dependencies.png b/en/device-dev/bundles/figures/bundle-dependencies.png deleted file mode 100644 index 1b936a2cbc95d3f9d7ddab0187305c3d0c486b0a..0000000000000000000000000000000000000000 Binary files a/en/device-dev/bundles/figures/bundle-dependencies.png and /dev/null differ diff --git a/en/device-dev/bundles/hpm-user-guide.md b/en/device-dev/bundles/hpm-user-guide.md deleted file mode 100644 index daaf5734779208bf468d896807d4ecdb3dfc6f6f..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/hpm-user-guide.md +++ /dev/null @@ -1,9 +0,0 @@ -# HPM User Guide - -- **[Introduction](introduction.md)** - -- **[Preparations](preparations-1.md)** - -- **[Development Example](development-example.md)** - - diff --git a/en/device-dev/bundles/overview-0.md b/en/device-dev/bundles/overview-0.md deleted file mode 100644 index 44fc41de4b49eaf811cc9b139d6751613452c21d..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/overview-0.md +++ /dev/null @@ -1,54 +0,0 @@ -# Overview - -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. - -- 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. - -**Table 1** Differences between a bundle and a distribution - - - - - - - - - - - - - - - - - - - - - - - - -

Aspect

-

Bundle

-

Distribution

-

Application scenario

-

Feature-oriented

-

System-oriented

-

Content

-

Codes or a binary library for implementing features

-

List of dependent bundles as well as their compiling and building scripts

-

Integrity

-

A part of the operating system

-

An entire operating system

-

Compilation result

-

Bundles

-

System image

-
- -**Figure 1** Composition of bundles and distributions - - -![](figures/组件0924.png) - diff --git a/en/device-dev/bundles/overview.md b/en/device-dev/bundles/overview.md deleted file mode 100644 index 3490dd84640d272e6c707c96d35fbee2c71b8da0..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/overview.md +++ /dev/null @@ -1,38 +0,0 @@ -# Overview - -- [Definition](#section177563344911) -- [Bundle Division Principles](#section2487162541016) -- [Bundle Dependency](#section185955409107) - -This document describes the basic concepts of a bundle and how to define it in compliance with specifications. - -## Definition - -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: - -- 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 -- Application-level bundles: applications that provide services to users, such as **wifi\_iot** and **ip\_camera** - -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: - -- Source code -- Binary system -- Code snippet -- Distribution - -## Bundle Division Principles - -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: - -- 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. -- Coupling: If a bundle must depend on another bundle to provide services, they can be coupled to one bundle. -- 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. - -## Bundle Dependency - -A bundle dependency can be mandatory or optional. - -- 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. -- 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. - diff --git a/en/device-dev/bundles/preparations-1.md b/en/device-dev/bundles/preparations-1.md deleted file mode 100644 index 6a0981f81bc1c1562946a9f1987eaabc30b50439..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/preparations-1.md +++ /dev/null @@ -1,139 +0,0 @@ -# Preparations - -- [Linux Server](#section20979554791) -- [Node.js](#section9954105413153) -- [HPM](#section15937194904819) -- [Python Environment](#section1621819180417) -- [File Packaging Tool](#section77617165913) -- [SCons](#section20558439191516) - -## Linux Server - -Prepare a 64-bit Linux server running Ubuntu 16.04 or later. HPM supports Windows Server, but the open-source Hi3861, Hi3516, and Hi3518 solutions support only Ubuntu. - -Configure Ubuntu to use bash as the Linux system shell, by performing the following: - -``` -ls -l $(which sh) -# If the file does not point to bash, modify the file using either of the provided methods. -# Method 1: Run the following command and select no: -dpkg-reconfigure dash -# Method 2: Run the following commands to delete /bin/sh and then create a new symbolic link to bash: -rm -f /bin/sh -ln -s bash /bin/sh -``` - -## Node.js - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If the Node.js version of the source is outdated, run the following command before running **apt-get install**: ->``` ->curl -L https://deb.nodesource.com/setup_12.x | bash ->``` - -You are advised to install Node.js 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\). - -``` -sudo apt-get install nodejs -sudo apt-get install npm -``` - -Run the following commands to view Node.js and NPM versions: - -``` -node --version # Check the Node.js version. -npm --version # Check the NPM version. -``` - -## HPM - -Install the **hpm-cli** command line tool by using the NPM \(default source: https://registry.npmjs.org/\) provided by the Node.js. - -``` -npm install -g @ohos/hpm-cli -``` - -After **hpm-cli** is installed, run the following command to view default HPM configurations: - -``` -hpm config -``` - -You can modify the default configurations as required. The following lists common HPM configurations: - -``` -registry = https://hpm.harmonyos.com # Register with the HPM registration center. This is mandatory for downloading components. -strictSsl = true # Enable strict SSL verification as HTTPS is used for connection. -http_proxy = http://your-proxy-server:port # Configure the HTTP proxy. -https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy. -``` - -For details about **hpm-cli** commands, see [HPM Commands](bundle-management.md). - -## Python Environment - -Run the following commands to install Python later than 3.7: - -``` -sudo apt-get install python3.8 -sudo apt-get install python3-pip -sudo pip3 install setuptools -sudo pip3 install kconfiglib # Install kconfiglib 13.2.0 or later. -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The preceding method is applicable to Hi3518 and Hi3516 platforms. For Hi3861, run the following commands to install the Python environment: ->``` ->sudo apt-get install python3.8 ->sudo apt-get install python3-pip ->sudo pip3 install setuptools ->sudo pip3 install kconfiglib # Install kconfiglib 13.2.0 or later. ->sudo pip3 install pycryptodome ->sudo pip3 install six --upgrade --ignore-installed six ->sudo pip3 install ecdsa ->``` - -If both Python2 and Python3 have been installed in the current system, run the following commands to set the default Python to Python3: - -``` -ll `which python` -rm /usr/bin/python -ln -s python3.8 /usr/bin/python -``` - -## File Packaging Tool - -Run the following commands to install the tool: - -``` -which mkfs.vfat # If mkfs.vfat is not found, run the following command: -sudo apt-get install dosfstools -which mcopy # If mcopy is not found, run the following command: -sudo apt-get install mtools -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Both Hi3518 and Hi3516 platforms require the file packaging tool. For Hi3861, the tool is not required. - -## SCons - -1. Start a Linux server. -2. Run the following command to install the SCons installation package: - - ``` - python3 -m pip install scons - ``` - -3. Run the following command to check whether SCons is successfully installed. If the installation is successful, the query result as shown in [Figure 1](#fig235815252492) is displayed. - - ``` - scons -v - ``` - - **Figure 1** Successful installation \(SCons version requirement: 3.0.4 or later\) - ![](figures/successful-installation-(scons-version-requirement-3-0-4-or-later).png "successful-installation-(scons-version-requirement-3-0-4-or-later)") - - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->SCons is required for the Hi3861 platform, but not for the Hi3518 or Hi3516 platform. - diff --git a/en/device-dev/bundles/preparations.md b/en/device-dev/bundles/preparations.md deleted file mode 100644 index dedd9b41f76f016fd1a33e1a407113feadabff7f..0000000000000000000000000000000000000000 --- a/en/device-dev/bundles/preparations.md +++ /dev/null @@ -1,84 +0,0 @@ -# Preparations - -- [Hardware Requirements](#section98535485518) -- [Installing Node.js and the hpm-cli Tool](#section106591616205311) -- [\(Optional\) Modifying HPM Configurations](#section71821165412) -- [Downloading OpenHarmony Code](#section102338221707) -- [Installing Dependent Bundles](#section19233183315020) - -## Hardware Requirements - -- Development boards \(examples: Hi3861, Hi3516DV300, and Hi3518EV300\) -- Host computer \(Windows workstation\) -- Linux server - -**Figure 1** Hardware connections -![](figures/hardware-connections.png "hardware-connections") - -## Installing **Node.js** and the **hpm-cli** Tool - -1. Install **Node.js**. - - Download **Node.js** from its official website and install it on your local PC. - - You are advised to install [Node.js](https://nodejs.org/) 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\). - -2. Install the **hpm-cli** tool using **npm** delivered with **Node.js**. Run the following command: - - ``` - npm install -g @ohos/hpm-cli - ``` - -3. Run the following command to check whether the installation is successful. If an HPM version is displayed, the installation is successful. - - ``` - hpm -V or hpm --version - ``` - -4. \(Optional\) Run the following command to upgrade the HPM version if needed: - - ``` - npm update -g @ohos/hpm-cli - ``` - - -## \(Optional\) Modifying HPM Configurations - -After the **hpm-cli** tool is installed, run the following command to view HPM configurations: - -``` -hpm config -``` - -Default HPM configurations are displayed upon the command execution. You can modify the default configurations as required. The following lists common HPM configurations: - -``` -registry = https://hpm.harmonyos.com/hpm/registry/api # Configure the address of the HPM registry, mandatory for downloading bundles. -login = https://hpm.harmonyos.com/hpm/auth/pk # Configure the address for HPM login, mandatory for publishing bundles. -loginUser = {your-account} # Configure the account for HPM login, mandatory for publishing bundles. -shellPath = C:\WINDOWS\System32\cmd.exe # Configure the shell for running HPM commands. -globalRepo = C:\Users\yourname\.global # Configure the path for storing bundles that are installed globally. -http_proxy = http://your-proxy-server:port # Configure the HTTP proxy. -https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy. -``` - -For details about **hpm-cli** commands, see [HPM Commands](bundle-management.md). - -## Downloading OpenHarmony Code - -For details, see [Source Code Acquisition](../get-code/source-code-acquisition.md). - -## Installing Dependent Bundles - -The HPM publishes commonly used development tools \(such as those for burning, compiling, and compression\) as bundles. You can run the following command to install these tools. After the command is executed, the system automatically downloads and installs the tools, which need to be installed globally only once. - -``` -hpm i -g @ohos/llvm -hpm i -g @ohos/ninja -hpm i -g @ohos/gn -hpm i -g @ohos/hc_gen -hpm i -g @ohos/sysroot -``` - -These are a set of development tools \(such as **gn** and **ninja**\). With these tools, you can start your general bundle development based on source code. - diff --git a/en/device-dev/driver/Readme-EN.md b/en/device-dev/driver/Readme-EN.md index 18678440ad06c989d251367330af5c65e8d93a59..c82515419fece430b91c9846b2c4ecba1df5f1fd 100644 --- a/en/device-dev/driver/Readme-EN.md +++ b/en/device-dev/driver/Readme-EN.md @@ -1,73 +1,23 @@ -# Drivers - -- [HDF](hdf.md) - - [HDF Overview](hdfoverview.md) - - [Driver Development](driver-development.md) - - [Driver Service Management](driver-service-management.md) - - [Driver Message Mechanism Management](driver-message-mechanism-management.md) - - [Driver Configuration Management](driver-configuration-management.md) - - [HDF Development Example](hdfdevelopment-example.md) - -- [Driver Platform](driver-platform.md) - - [GPIO](gpio.md) - - [GPIO Overview](gpiooverview.md) - - [GPIO Usage Guidelines](gpiousage-guidelines.md) - - [GPIO Usage Example](gpiousage-example.md) - - - [I2C](i2c.md) - - [I2C Overview](i2c-overview.md) - - [I2C Usage Guidelines](i2c-usage-guidelines.md) - - [I2C Usage Example](i2c-usage-example.md) - - - [RTC](rtc.md) - - [RTC Overview](rtc-overview.md) - - [RTC Usage Guidelines](rtc-usage-guidelines.md) - - [RTC Usage Example](rtc-usage-example.md) - - - [SDIO](sdio.md) - - [SDIO Overview](sdiooverview.md) - - [SDIO Usage Guidelines](sdiousage-guidelines.md) - - [SDIO Usage Example](sdiousage-example.md) - - - [SPI](spi.md) - - [SPI Overview](spioverview.md) - - [SPI Usage Guidelines](spiusage-guidelines.md) - - [SPI Usage Example](spiusage-example.md) - - - [UART](uart.md) - - [UART Overview](uartoverview.md) - - [UART Usage Guidelines](uartusage-guidelines.md) - - [UART Usage Example](uartusage-example.md) - - - [WATCHDOG](watchdog.md) - - [Watchdog Overview](watchdogoverview.md) - - [Watchdog Usage Guidelines](watchdogusage-guidelines.md) - - [Watchdog Usage Example](watchdogusage-example.md) - - - [MIPI DSI](mipi-dsi.md) - - [MIPI DSI Overview](mipi-dsi-overview.md) - - [Usage Guidelines](usage-guidelines.md) - - [Usage Example](usage-example.md) - -- [Peripherals](peripherals.md) - - [LCD](lcd.md) - - [LCD Overview](lcdoverview.md) - - [LCD Development Guidelines](lcddevelopment-guidelines.md) - - [LCD Development Example](lcddevelopment-example.md) - - - [TOUCHSCREEN](touchscreen.md) - - [Touchscreen Overview](touchscreenoverview.md) - - [Touchscreen Development Guidelines](touchscreendevelopment-guidelines.md) - - [Touchscreen Development Example](touchscreendevelopment-example.md) - - - [SENSOR](sensor.md) - - [Sensor Driver Overview](sensor-driver-overview.md) - - [Sensor Driver Development Guidelines](sensor-driver-development-guidelines.md) - - [Sensor Driver Development Example](sensor-driver-development-example.md) - - [Sensor Driver Test Guidelines](sensor-driver-test-guidelines.md) - - - [WLAN](wlan.md) - - [WLAN Overview](wlanoverview.md) - - [WLAN Development Guidelines](wlandevelopment-guidelines.md) - - [WLAN Development Example](wlandevelopment-example.md) - +# drivers + +- [HDF](driver-hdf.md) + - [HDF Overview](driver-hdf-overview.md) + - [driverr Development](driver-hdf-development.md) + - [driverr Service Management](driver-hdf-servicemanage.md) + - [driverr Message Mechanism Management](driver-hdf-news.md) + - [driverr Configuration Management](driver-hdf-manage.md) + - [HDF Development Example](driver-hdf-sample.md) +- [Platform driverrs](driver-platform.md) + - [GPIO](driver-platform-gpio-des.md) + - [I2C](driver-platform-i2c-des.md) + - [RTC](driver-platform-rtc-des.md) + - [SDIO](driver-platform-sdio-des.md) + - [SPI](driver-platform-spi-des.md) + - [UART](driver-platform-uart-des.md) + - [Watchdog](driver-platform-watchdog-des.md) + - [MIPI DSI](driver-platform-mipidsi-des.md) +- [Peripherals](driver-peripherals.md) + - [LCD](driver-peripherals-lcd-des.md) + - [TOUCHSCREEN](driver-peripherals-touch-des.md) + - [Sensor](driver-peripherals-sensor-des.md) + - [WLAN](driver-peripherals-external-des.md) \ No newline at end of file diff --git a/en/device-dev/driver/driver-configuration-management.md b/en/device-dev/driver/driver-configuration-management.md deleted file mode 100644 index ed33878be0b20585b044940e475784685e7e1c6a..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/driver-configuration-management.md +++ /dev/null @@ -1,437 +0,0 @@ -# Driver Configuration Management - -- [HDF Configuration Overview](#section59914284576) -- [Configuration Syntax](#section533713333580) -- [Keywords](#section1316625413586) -- [Basic Syntax](#section173481622115918) -- [Data Types](#section96521601302) -- [Pre-processing](#section8164295515) -- [Commenting](#section0338205819610) -- [Modifying a Reference](#section179799204716) -- [Replicating Node Configuration](#section382424014712) -- [Deleting a Node or Attribute](#section165211112586) -- [Referencing an Attribute](#section192841514490) -- [Keyword Template](#section520134294) -- [Configuration Generation](#section106152531919) -- [Introduction to HC-GEN](#section8260625101012) - -## HDF Configuration Overview - -HCS is the source code that describes the configuration of the HDF using key-value pairs. It decouples the configuration code from driver code, thereby facilitating configuration management. - -HDF Configuration Generator \(HC-GEN\) is a tool for converting a configuration file into a file that can be read by the target software. - -- In a low-performance system on a chip \(SoC\), this tool can convert a configuration file into the source code of the configuration tree so that the driver can obtain the configuration by directly calling the C library code. -- In a high-performance SoC, this tool can convert an HCS configuration file into the HDF Configuration Binary \(HCB\) file, allowing the driver to obtain the configuration through the APIs provided by the HDF. - -The following figure shows the typical application scenario of the HCB mode. - -**Figure 1** Process of using HCS - - -![](figures/en-us_image_0000001053405727.png) - -The HCS is compiled using the HC-GEN tool to generate an HCB file. The HCS Parser module in the HDF recreates a configuration tree using the HCB file. Then, the HDF driver modules obtain the configurations using the API provided by the HCS Paser. - -## Configuration Syntax - -The HCS syntax is described as follows: - -## Keywords - -The keywords listed in the following table below are reserved for HCS configuration files. - -**Table 1** Reserved keywords for HCS configuration files - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Keywords

-

Description

-

Remarks

-

root

-

Configures the root node.

-

-

-

include

-

References other HCS configuration files.

-

-

-

delete

-

Deletes a node or an attribute.

-

This keyword applies only to the configuration tree imported using the include keyword.

-

template

-

Defines a template node.

-

-

-

match_attr

-

Marks the node attribute for matching.

-

During configuration parsing, the keyword value can be used to find the corresponding node.

-
- -## Basic Syntax - -The HCS configuration file consists of configurations of attributes and nodes. - -**Attributes** - -An attribute, as the minimum configuration unit, is an independent configuration item. Its syntax is as follows: - -``` - attribute_name = value; -``` - -- The value of **attribute\_name** is a case-sensitive string of characters starting with a letter and consisting of letters, digits, and underscores \(\_\). - -- Available formats of **value** are as follows: - - - A binary, octal, decimal, or hexadecimal integer. For details, see [Data Types](#section96521601302). - - - A character string. The content should be enclosed in double quotation marks \(" "\). - - - A node reference - - -- An attribute key-value pair must end with a semicolon \(;\) and belong to a node. - - -**Nodes** - -A node is a set of attributes. Its syntax is as follows: - -``` - node_name { - module = "sample"; - ... - } -``` - -- The value of **node\_name** is a case-sensitive string of characters starting with a letter and consisting of letters, digits, and underscores \(\_\). - -- A semicolon \(;\) is not required after the curly brace \(\}\). - -- The reserved keyword **root** is used to declare the root node of a configuration table. - -- The root node must contain a **module** attribute that uses a string to represent the module to which the configuration belongs. - -- The **match\_attr** attribute can be added to a node. Its value is a globally unique character string. During configuration parsing, the query interface can be invoked to query the nodes with the attribute based on the attribute value. - -## Data Types - -Attributes automatically use built-in data types, including integers, strings, arrays, and booleans. You do not need to explicitly specify the data type for the attribute values. - -**Integer** - -An integer can be binary, octal, decimal, or hexadecimal. The minimum space is automatically allocated to the integer based on the actual data length. - -- Binary: prefixed with 0b, for example, 0b1010 - -- Octal: prefixed with 0, for example, 0664 -- Decimal: either signed or unsigned, without a prefix, for example, 1024 or +1024. Negative integers can be read only via signed interfaces. - -- Hexadecimal: prefixed with 0x, for example, 0xff00 and 0xFF - - -**String** - -A string is enclosed by double quotation marks \(" "\). - -**Array** - -The elements in an array can be integers or strings, but cannot be a combination of both. The combination of **uint32\_t** and **uint64\_t** in an integer array will enable up-casting to **uint64**. The following is an example of an integer array and a string array: - -``` -attr_foo = [0x01, 0x02, 0x03, 0x04]; -attr_bar = ["hello", "world"]; -``` - -**Boolean** - -A Boolean data type has two possible values: **true** and **false**. - -## Pre-processing - -**include** - -The **include** keyword is used to import other HCS files. The syntax is as follows: - -``` -#include "foo.hcs" -#include "../bar.hcs" -``` - -- The file names must be enclosed by double quotation marks \(" "\). Files in different directories can be referenced using relative paths. The file included must be a valid HCS file. -- In the scenario that multiple HCS files are imported using **include**, if the same nodes exist, the latter node will override the former one, and other nodes are listed in sequence. - -## Commenting - -Comments can be formatted as follows: - -- Single-line comment - - ``` - // comment - ``` - -- Multi-line comment - - ``` - /* - comment - */ - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >Multi-line comments cannot be nested. - - -## Modifying a Reference - -You can use the following syntax to modify the content of any other node: - -``` - node :& source_node -``` - -This syntax indicates that the node value is a modification of the source\_node value. Example: - -``` -root { - module = "sample"; - foo { - foo_ :& root.bar{ - attr = "foo"; - } - foo1 :& foo2 { - attr = 0x2; - } - foo2 { - attr = 0x1; - } - } - - bar { - attr = "bar"; - } -} -``` - -The following configuration tree is generated: - -``` -root { - module = "sample"; - foo { - foo2 { - attr = 0x2; - } - } - bar { - attr = "foo"; - } -} -``` - -In the preceding example, the **foo.foo\_** node changes the value of the referenced **bar.attr** to "**foo**", and the **foo.foo1** node changes the value of the referenced **foo.foo2.attr** to **0x2**. In the generated configuration tree, **foo.foo\_** and **foo.foo1** are not displayed, but their configuration modifications are presented by their referenced nodes. - -- A node of the same level can be referenced simply using the node name. A node of a different level must be referenced by the absolute path, and node names are separated using a period \(.\). **root** indicates the root node. The path format is the node path sequence starting with root. For example, **root.foo.bar** is a valid absolute path. -- If multiple modifications are made to the same attribute, only one uncertain modification can take effect, and a warning will be displayed. - -## Replicating Node Configuration - -The content of a node can be replicated to another node to define the node with similar content. The syntax is as follows: - -``` - node : source_node -``` - -The preceding statement indicates that the attributes of **source\_node** are replicated to **node**. Example: - -``` -root { - module = "sample"; - foo { - attr_0 = 0x0; - } - bar:foo { - attr_1 = 0x1; - } -} -``` - -The following configuration tree is generated: - -``` -root { - module = "sample"; - foo { - attr_0 = 0x0; - } - bar { - attr_1 = 0x1; - attr_0 = 0x0; - } -} -``` - -In the preceding example, the **bar** node configuration includes both the **attr\_0** and **attr\_1** values. The modification to **attr\_0** in the **bar** node does not affect the **foo** node. - -The path of the **foo** node is not required if the **foo** node and the **bar** node are of the same level. Otherwise, the absolute path must be used. For details, see [Modifying a Reference](#section179799204716). - -## Deleting a Node or Attribute - -You can use the keyword **delete** to delete unnecessary nodes or attributes in the base configuration tree imported by the **include** keyword. In the following example, **sample1.hcs** imports the configuration of **sample2.hcs** using **include**, and deletes the **attribute2** attribute and the **foo\_2** node using the **delete** keyword. - -``` -// sample2.hcs -root { - attr_1 = 0x1; - attr_2 = 0x2; - foo_2 { - t = 0x1; - } -} - -// sample1.hcs -#include "sample2.hcs" -root { - attr_2 = delete; - foo_2 : delete { - } -} -``` - -The following configuration tree is generated: - -``` -root { - attr_1 = 0x1; -} -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The **delete** keyword cannot be used in the same HCS file. It is recommended that you delete unnecessary attributes directly from the configuration source code. - -## Referencing an Attribute - -To quickly locate the associated node during configuration parsing, you can use the node as the value of the attribute and read the attribute to find the corresponding node. The syntax is as follows: - -``` - attribute = &node; -``` - -This syntax indicates that the **attribute** value is a reference to **node**. During code parsing, you can quickly locate the node using this attribute. Example: - -``` -node1 { - attributes; -} - -node2 { - attr_1 = &node1; -} -``` - -## Keyword Template - -The **template** keyword is used to generate nodes with strictly consistent syntax, thereby facilitating the traverse and management of nodes of the same type. - -If a node is defined using the keyword **template**, its child nodes inherit the node configuration through the double colon operator \(::\). The child nodes can modify but cannot add or delete attributes in **template**. The attributes not defined in the child nodes will use the attributes defined in **template** as the default values. Example: - -``` -root { - module = "sample"; - template foo { - attr_1 = 0x1; - attr_2 = 0x2; - } - - bar :: foo { - } - - bar_1 :: foo { - attr_1 = 0x2; - } -} -``` - -The following configuration tree is generated: - -``` -root { - module = "sample"; - bar { - attr_1 = 0x1; - attr_2 = 0x2; - } - bar_1 { - attr_1 = 0x2; - attr_2 = 0x2; - } -} -``` - -In the preceding example, the **bar** and **bar\_1** nodes inherit the **foo** node. The structures of the generated configuration tree nodes are the same as that of the **foo** node, but the attribute values are different. - -## Configuration Generation - -The HC-GEN tool is used to generate configurations. It checks the HCS configuration syntax and converts HCS source files into HCB files. - -## Introduction to HC-GEN - -Parameter description: - -``` -Usage: hc-gen [Options] [File] -options: - -o output file name, default same as input - -a hcb align with four bytes - -b output binary output, default enable - -t output config in C language source file style - -i output binary hex dump in C language source file style - -p prefix of generated symbol name - -d decompile hcb to hcs - -V show verbose info - -v show version - -h show this help message -``` - -Generate a **.c** or **.h** configuration file. - -``` -hc-gen -o [OutputCFileName] -t [SourceHcsFileName] -``` - -Generate an HCB file. - -``` -hc-gen -o [OutputHcbFileName] -b [SourceHcsFileName] -``` - -Compile an **HCB** file to an **HCS** file: - -``` -hc-gen -o [OutputHcsFileName] -d [SourceHcbFileName] -``` - diff --git a/en/device-dev/driver/driver-development.md b/en/device-dev/driver/driver-development.md deleted file mode 100644 index f9c14ec11f06e6f5c5448751c6967e3de0dac1fa..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/driver-development.md +++ /dev/null @@ -1,175 +0,0 @@ -# Driver Development - -- [Introduction](#section157425168112) -- [How to Develop](#section1969312275533) - -## Introduction - -The HDF is designed based on the component-based driver model. It provides more refined driver management to make driver development and deployment more standard. Device drivers of the same type are placed in the same host. You can develop and deploy the drivers separately. One driver can have multiple nodes. The following figure shows the HDF driver management model. - -**Figure 1** HDF driver management model - - -![](figures/en-us_image_0000001054564784.png) - -## How to Develop - -Driver development based on the HDF consists of two parts: driver implementation and driver configuration. The details are as follows: - -1. Implement driver. - - To implement a driver, compile driver service code and register a driver entry. - - - Driver service code - - ``` - #include "hdf_device_desc.h" // Header file that describes the APIs provided by the HDF to the driver. - #include "hdf_log.h" // Header file of the log interface provided by the HDF. - - #define HDF_LOG_TAG "sample_driver" // Tag contained in logs. If the tag is not specified, HDF_TAG is used by default. - - // The driver service interface must be bound to the HDF for you to use the service capability. - int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver bind success"); - return 0; - } - - // Initialize the driver service. - int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver Init success"); - return 0; - } - - // Release the driver resources. - void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver release success"); - return; - } - ``` - - - Registering the driver entry with the HDF - - ``` - // Define the object of the driver entry. The object must be a global variable of the HdfDriverEntry type (defined in hdf_device_desc.h). - struct HdfDriverEntry g_sampleDriverEntry = { - .moduleVersion = 1, - .moduleName = "sample_driver", - .Bind = HdfSampleDriverBind, - .Init = HdfSampleDriverInit, - .Release = HdfSampleDriverRelease, - }; - - // Call HDF_INIT to register the driver entry with the HDF framework. When loading the driver, call the Bind function and then the Init function. If the Init function fails to be called, the HDF will call Release to release the driver resource and exit. - HDF_INIT(g_sampleDriverEntry); - ``` - - -2. Compile the driver code. - - Use the **Makefile** template provided by the HDF to compile the driver code. - - ``` - include $(LITEOSTOPDIR)/../../drivers/adapter/lite/khdf/lite.mk # (Mandatory) Import the predefined content of the HDF. - MODULE_NAME := # Generated result file - LOCAL_INCLUDE: = # Header file directory of the driver - LOCAL_SRCS : = # Source code file of the driver - LOCAL_CFLAGS : = # Custom compilation options - include $(HDF_DRIVER) # Import the template Makefile to complete compilation. - ``` - - - Link the compilation result file to the kernel image by adding the result file to **hdf\_vendor.mk** in the **vendor** directory. The following is an example: - - ``` - LITEOS_BASELIB += -lxxx # Static library generated through linking - LIB_SUBDIRS += # Directory of Makefile - ``` - - -3. Configure the driver. - - HDF Configuration Source \(HCS\) is the source code that describes the configuration of the HDF. For details about the HCS, see [Driver Configuration Management](driver-configuration-management.md). - - The driver configuration consists of the driver device description defined by the HDF and private driver configuration information. - - - \(Mandatory\) Driver device description - - The information required for the HDF to load drivers comes from the driver device description defined by the HDF. Therefore, the device description must be added to the configuration file **device\_info.hcs** defined by the HDF for drivers developed based on the HDF. The following is an example: - - ``` - root { - device_info { - match_attr = "hdf_manager"; - template host { // Host template. If the node (for example, sample_host) that inherits the template uses default values in the template, the values of the node fields can be omitted. - hostName = ""; - priority = 100; - template device { - template deviceNode { - policy = 0; - priority = 100; - preload = 0; - permission = 0664; - moduleName = ""; - serviceName = ""; - deviceMatchAttr = ""; - } - } - } - sample_host :: host{ - hostName = "host0"; // Host name. The host node is used to store a certain type of drivers. - priority = 100; // Host startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the host loading sequence is random. - device_sample :: device { // Device node of sample - device0 :: deviceNode { // DeviceNode of the sample driver - policy = 1; // Driver service release policy. For details, see section Driver Service Management. - priority = 100; // Driver startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the device loading sequence is random. - preload = 0; // On-demand driver loading. For details, see "NOTE" at the end of this section. - permission = 0664; // Permission for the driver to create device nodes. - moduleName = "sample_driver"; // Driver name. The value of this field must be the same as the value of moduleName in the driver entry structure. - serviceName = "sample_service"; // Name of the service released by the driver. The name must be unique. - deviceMatchAttr = "sample_config"; // Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver. - } - } - } - } - } - ``` - - - \(Optional\) Private configuration information of the driver - - If the driver has private configurations, you can add a driver configuration file to fill in the default configuration information of the driver. When loading the driver, the HDF obtains the information and saves it in the **property** of **HdfDeviceObject**, and transfers it to the driver using **Bind** and **Init** \(see [1](#li35182436435)\). The following is an example of the driver configuration information: - - ``` - root { - SampleDriverConfig { - sample_version = 1; - sample_bus = "I2C_0"; - match_attr = "sample_config"; // The value of this field must be the same as that of deviceMatchAttr in device_info.hcs. - } - } - ``` - - After the configuration information is defined, you need to add the configuration file to the board-level configuration entry file **hdf.hcs**. \(You can use the DevEco to perform on-click configuration. For details, see the description about the driver development suite.\) The following is an example: - - ``` - #include "device_info/device_info.hcs" - #include "sample/sample_config.hcs" - ``` - - - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->On-demand loading and sequential loading are supported. The detailed usage is as follows: ->- On-demand loading -> ``` -> typedef enum { -> DEVICE_PRELOAD_ENABLE = 0, -> DEVICE_PRELOAD_ENABLE_STEP2, -> DEVICE_PRELOAD_DISABLE, -> DEVICE_PRELOAD_INVALID -> } DevicePreload; -> ``` -> When the **preload** field in the configuration file is set to **0** \(**DEVICE\_PRELOAD\_ENABLE**\), the driver is loaded by default during system startup. When this field is set to **1** \(**DEVICE\_PRELOAD\_ENABLE\_STEP2**\), the driver is loaded after system startup if quick start is enabled; it is loaded during system startup otherwise. When this field is set to **2** \(**DEVICE\_PRELOAD\_DISABLE**\), the driver is not loaded by default during system startup and can be dynamically loaded later. If the driver service does not exist when a user-level application obtains the driver service \(for details about how to obtain the driver service, see [Driver Message Mechanism Management](driver-message-mechanism-management.md)\), the HDF attempts to dynamically load the driver. ->- Sequential loading \(drivers must be loaded by default\) -> In the configuration file, the **priority** field \(the value is an integer ranging from 0 to 200\) indicates the priority of the host and driver. For drivers in different hosts, a smaller host priority value indicates a higher driver loading priority; for drivers in the same host, a smaller driver priority value indicates a higher driver loading priority. - diff --git a/en/device-dev/driver/driver-hdf-development.md b/en/device-dev/driver/driver-hdf-development.md new file mode 100644 index 0000000000000000000000000000000000000000..7d9e91390c07c54b069f1e396d245cb9381d3790 --- /dev/null +++ b/en/device-dev/driver/driver-hdf-development.md @@ -0,0 +1,175 @@ +# Driver Development + +- [Introduction](#section157425168112) +- [How to Develop](#section1969312275533) + +## Introduction + +The HDF is designed based on the component-based driver model. It provides more refined driver management to make driver development and deployment more standard. Device drivers of the same type are placed in the same host. You can develop and deploy the drivers separately. One driver can have multiple nodes. [Figure 1](#fig5487113011526) shows the HDF driver model. + +**Figure 1** HDF driver model + + +![](figure/en-us_image_0000001054564784.png) + +## How to Develop + +Driver development based on the HDF consists of two parts: driver implementation and driver configuration. The details are as follows: + +1. Implement driver. + + To implement a driver, compile driver service code and register a driver entry. + + - Driver service code + + ``` + #include "hdf_device_desc.h" // Header file that describes the APIs provided by the HDF to the driver. + #include "hdf_log.h" // Header file that describes the log APIs provided by the HDF. + + #define HDF_LOG_TAG "sample_driver" // Tag contained in logs. If no tag is not specified, the default HDF_TAG is used. + + // The driver service interface must be bound to the HDF for you to use the service capability. + int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver bind success"); + return 0; + } + + // Initialize the driver service. + int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver Init success"); + return 0; + } + + // Release the driver resources. + void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver release success"); + return; + } + ``` + + - Registering the driver entry with the HDF + + ``` + // Define the object of the driver entry. The object must be a global variable of the HdfDriverEntry type (defined in hdf_device_desc.h). + struct HdfDriverEntry g_sampleDriverEntry = { + .moduleVersion = 1, + .moduleName = "sample_driver", + .Bind = HdfSampleDriverBind, + .Init = HdfSampleDriverInit, + .Release = HdfSampleDriverRelease, + }; + + // Call HDF_INIT to register the driver entry with the HDF framework. When loading the driver, call the Bind function and then the Init function. If the Init function fails to be called, the HDF will call Release to release the driver resource and exit. + HDF_INIT(g_sampleDriverEntry); + ``` + + +2. Compile the driver code. + - Use the **Makefile** template provided by the HDF to compile the driver code. + + ``` + include $(LITEOSTOPDIR)/../../drivers/adapter/lite/khdf/lite.mk # (Mandatory) Import the predefined content of the HDF. + MODULE_NAME := # Generated result file + LOCAL_INCLUDE: = # Header file directory of the driver + LOCAL_SRCS : = # Source code file of the driver + LOCAL_CFLAGS : = # Custom compilation options + include $(HDF_DRIVER) # Import the template Makefile to complete compilation. + ``` + + - Link the compilation result file to the kernel image by adding the result file to **hdf\_vendor.mk** in the **vendor** directory. The following is an example: + + ``` + LITEOS_BASELIB += -lxxx # Static library generated through linking + LIB_SUBDIRS += # Directory of Makefile + ``` + + +3. Configure the driver. + + HDF Configuration Source \(HCS\) is the source code that describes the configuration of the HDF. For details about the HCS, see [Driver Configuration Management](driver-hdf-manage.md). + + The driver configuration consists of the driver device description defined by the HDF and private driver configuration information. + + - \(Mandatory\) Driver device description + + The information required for the HDF to load drivers comes from the driver device description defined by the HDF. Therefore, the device description must be added to the configuration file **device\_info.hcs** defined by the HDF for drivers developed based on the HDF. The following is an example: + + ``` + root { + device_info { + match_attr = "hdf_manager"; + template host { // Host template. If the node (for example, sample_host) that inherits the template uses default values in the template, the values of the node fields can be omitted. + hostName = ""; + priority = 100; + template device { + template deviceNode { + policy = 0; + priority = 100; + preload = 0; + permission = 0664; + moduleName = ""; + serviceName = ""; + deviceMatchAttr = ""; + } + } + } + sample_host :: host{ + hostName = "host0"; // Host name. The host node is used to store a certain type of drivers. + priority = 100; // Host startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the host loading sequence is random. + device_sample :: device { // Device node of sample + device0 :: deviceNode { // DeviceNode of the sample driver + policy = 1; // Driver service release policy. For details, see section Driver Service Management. + priority = 100; // Driver startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the device loading sequence is random. + preload = 0; // On-demand loading of the driver. For details, see "NOTE" at the end of this section. + permission = 0664; // Permission for the driver to create device nodes. + moduleName = "sample_driver"; // Driver name. The value of this field must be the same as the value of moduleName in the driver entry structure. + serviceName = "sample_service"; // Name of the service released by the driver. The name must be unique. + deviceMatchAttr = "sample_config"; // Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver. + } + } + } + } + } + ``` + + - \(Optional\) Private configuration information of the driver + + If the driver has private configurations, you can add a driver configuration file to fill in the default configuration information of the driver. When loading the driver, the HDF obtains the information and saves it in the **property** of **HdfDeviceObject**, and transfers it to the driver using **Bind** and **Init** \(see [1](#li35182436435)\). The following is an example of the driver configuration information: + + ``` + root { + SampleDriverConfig { + sample_version = 1; + sample_bus = "I2C_0"; + match_attr = "sample_config"; // The value of this field must be the same as that of deviceMatchAttr in device_info.hcs. + } + } + ``` + + After the configuration information is defined, you need to add the configuration file to the board-level configuration entry file **hdf.hcs**. \(You can use the DevEco to perform on-click configuration. For details, see the description about the driver development suite.\) The following is an example: + + ``` + #include "device_info/device_info.hcs" + #include "sample/sample_config.hcs" + ``` + + + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>On-demand loading and sequential loading are supported. The detailed usage is as follows: +>- On-demand loading +> ``` +> typedef enum { +> DEVICE_PRELOAD_ENABLE = 0, +> DEVICE_PRELOAD_ENABLE_STEP2, +> DEVICE_PRELOAD_DISABLE, +> DEVICE_PRELOAD_INVALID +> } DevicePreload; +> ``` +> When the **preload** field in the configuration file is set to **0** \(**DEVICE\_PRELOAD\_ENABLE**\), the driver is loaded by default during system startup. When this field is set to **1** \(**DEVICE\_PRELOAD\_ENABLE\_STEP2**\), the driver is loaded after system startup if quick start is enabled; it is loaded during system startup otherwise. When this field is set to **2** \(**DEVICE\_PRELOAD\_DISABLE**\), the driver is not loaded by default during system startup and can be dynamically loaded later. If the driver service does not exist when a user-level application obtains the driver service \(for details about how to obtain the driver service, see [Driver Message Mechanism Management](drive-hdf-news.md)\), the HDF attempts to dynamically load the driver. +>- Sequential loading \(drivers must be loaded by default\) +> In the configuration file, the **priority** field \(the value is an integer ranging from 0 to 200\) indicates the priority of the host and driver. For drivers in different hosts, a smaller host priority value indicates a higher driver loading priority; for drivers in the same host, a smaller driver priority value indicates a higher driver loading priority. + diff --git a/en/device-dev/driver/driver-hdf-manage.md b/en/device-dev/driver/driver-hdf-manage.md new file mode 100644 index 0000000000000000000000000000000000000000..08a88cae19f8c85942cfbe4fe6a6bf73585fda77 --- /dev/null +++ b/en/device-dev/driver/driver-hdf-manage.md @@ -0,0 +1,437 @@ +# Driver Configuration Management + +- [HDF Configuration Overview](#section59914284576) +- [Configuration Syntax](#section533713333580) +- [Keywords](#section1316625413586) +- [Basic Syntax](#section173481622115918) +- [Data Types](#section96521601302) +- [Pre-processing](#section8164295515) +- [Commenting](#section0338205819610) +- [Modifying a Reference](#section179799204716) +- [Replicating Node Configuration](#section382424014712) +- [Deleting a Node or Attribute](#section165211112586) +- [Referencing an Attribute](#section192841514490) +- [Keyword Template](#section520134294) +- [Configuration Generation](#section106152531919) +- [Introduction to HC-GEN](#section8260625101012) + +## HDF Configuration Overview + +HCS is the source code that describes the configuration of the HDF using key-value pairs. It decouples the configuration code from driver code, thereby facilitating configuration management. + +HDF Configuration Generator \(HC-GEN\) is a tool for converting a configuration file into a file that can be read by the target software. + +- In a low-performance system on a chip \(SoC\), this tool can convert a configuration file into the source code of the configuration tree so that the driver can obtain the configuration by directly calling the C library code. +- In a high-performance SoC, this tool can convert an HCS configuration file into the HDF Configuration Binary \(HCB\) file, allowing the driver to obtain the configuration through the APIs provided by the HDF. + +The following figure shows the typical application scenario of the HCB mode. + +**Figure 1** Process of using HCS + + +![](figure/en-us_image_0000001053405727.png) + +The HCS is compiled using the HC-GEN tool to generate an HCB file. The HCS Parser module in the HDF recreates a configuration tree using the HCB file. Then, the HDF driver modules obtain the configurations using the API provided by the HCS Paser. + +## Configuration Syntax + +The HCS syntax is described as follows: + +## Keywords + +The keywords listed in the following table below are reserved for HCS configuration files. + +**Table 1** Reserved keywords for HCS configuration files + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Keywords

+

Description

+

Remarks

+

root

+

Configures the root node.

+

-

+

include

+

References other HCS configuration files.

+

-

+

delete

+

Deletes a node or an attribute.

+

This keyword applies only to the configuration tree imported using the include keyword.

+

template

+

Defines a template node.

+

-

+

match_attr

+

Marks the node attribute for matching.

+

During configuration parsing, the keyword value can be used to find the corresponding node.

+
+ +## Basic Syntax + +The HCS configuration file consists of configurations of attributes and nodes. + +**Attributes** + +An attribute, as the minimum configuration unit, is an independent configuration item. Its syntax is as follows: + +``` + attribute_name = value; +``` + +- The value of **attribute\_name** is a case-sensitive string of characters starting with a letter and consisting of letters, digits, and underscores \(\_\). + +- Available formats of **value** are as follows: + + - A binary, octal, decimal, or hexadecimal integer. For details, see [Data Types](#section96521601302). + + - A character string. The content should be enclosed in double quotation marks \(" "\). + + - A node reference + + +- An attribute key-value pair must end with a semicolon \(;\) and belong to a node. + + +**Nodes** + +A node is a set of attributes. Its syntax is as follows: + +``` + node_name { + module = "sample"; + ... + } +``` + +- The value of **node\_name** is a case-sensitive string of characters starting with a letter and consisting of letters, digits, and underscores \(\_\). + +- A semicolon \(;\) is not required after the curly brace \(\}\). + +- The reserved keyword **root** is used to declare the root node of a configuration table. + +- The root node must contain a **module** attribute that uses a string to represent the module to which the configuration belongs. + +- The **match\_attr** attribute can be added to a node. Its value is a globally unique character string. During configuration parsing, the query interface can be invoked to query the nodes with the attribute based on the attribute value. + +## Data Types + +Attributes automatically use built-in data types, including integers, strings, arrays, and booleans. You do not need to explicitly specify the data type for the attribute values. + +**Integer** + +An integer can be binary, octal, decimal, or hexadecimal. The minimum space is automatically allocated to the integer based on the actual data length. + +- Binary: prefixed with 0b, for example, 0b1010 + +- Octal: prefixed with 0, for example, 0664 +- Decimal: either signed or unsigned, without a prefix, for example, 1024 or +1024. Negative integers can be read only via signed interfaces. + +- Hexadecimal: prefixed with 0x, for example, 0xff00 and 0xFF + + +**String** + +A string is enclosed by double quotation marks \(" "\). + +**Array** + +The elements in an array can be integers or strings, but cannot be a combination of both. The combination of **uint32\_t** and **uint64\_t** in an integer array will enable up-casting to **uint64**. The following is an example of an integer array and a string array: + +``` +attr_foo = [0x01, 0x02, 0x03, 0x04]; +attr_bar = ["hello", "world"]; +``` + +**Boolean** + +A Boolean data type has two possible values: **true** and **false**. + +## Pre-processing + +**include** + +The **include** keyword is used to import other HCS files. The syntax is as follows: + +``` +#include "foo.hcs" +#include "../bar.hcs" +``` + +- The file names must be enclosed by double quotation marks \(" "\). Files in different directories can be referenced using relative paths. The file included must be a valid HCS file. +- In the scenario that multiple HCS files are imported using **include**, if the same nodes exist, the latter node will override the former one, and other nodes are listed in sequence. + +## Commenting + +Comments can be formatted as follows: + +- Single-line comment + + ``` + // comment + ``` + +- Multi-line comment + + ``` + /* + comment + */ + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Multi-line comments cannot be nested. + + +## Modifying a Reference + +You can use the following syntax to modify the content of any other node: + +``` + node :& source_node +``` + +This syntax indicates that the node value is a modification of the source\_node value. Example: + +``` +root { + module = "sample"; + foo { + foo_ :& root.bar{ + attr = "foo"; + } + foo1 :& foo2 { + attr = 0x2; + } + foo2 { + attr = 0x1; + } + } + + bar { + attr = "bar"; + } +} +``` + +The following configuration tree is generated: + +``` +root { + module = "sample"; + foo { + foo2 { + attr = 0x2; + } + } + bar { + attr = "foo"; + } +} +``` + +In the preceding example, the **foo.foo\_** node changes the value of the referenced **bar.attr** to "**foo**", and the **foo.foo1** node changes the value of the referenced **foo.foo2.attr** to **0x2**. In the generated configuration tree, **foo.foo\_** and **foo.foo1** are not displayed, but their configuration modifications are presented by their referenced nodes. + +- A node of the same level can be referenced simply using the node name. A node of a different level must be referenced by the absolute path, and node names are separated using a period \(.\). **root** indicates the root node. The path format is the node path sequence starting with root. For example, **root.foo.bar** is a valid absolute path. +- If multiple modifications are made to the same attribute, only one uncertain modification can take effect, and a warning will be displayed. + +## Replicating Node Configuration + +The content of a node can be replicated to another node to define the node with similar content. The syntax is as follows: + +``` + node : source_node +``` + +The preceding statement indicates that the attributes of **source\_node** are replicated to **node**. Example: + +``` +root { + module = "sample"; + foo { + attr_0 = 0x0; + } + bar:foo { + attr_1 = 0x1; + } +} +``` + +The following configuration tree is generated: + +``` +root { + module = "sample"; + foo { + attr_0 = 0x0; + } + bar { + attr_1 = 0x1; + attr_0 = 0x0; + } +} +``` + +In the preceding example, the **bar** node configuration includes both the **attr\_0** and **attr\_1** values. The modification to **attr\_0** in the **bar** node does not affect the **foo** node. + +The path of the **foo** node is not required if the **foo** node and the **bar** node are of the same level. Otherwise, the absolute path must be used. For details, see [Modifying a Reference](#section179799204716). + +## Deleting a Node or Attribute + +You can use the keyword **delete** to delete unnecessary nodes or attributes in the base configuration tree imported by the **include** keyword. In the following example, **sample1.hcs** imports the configuration of **sample2.hcs** using **include**, and deletes the **attribute2** attribute and the **foo\_2** node using the **delete** keyword. + +``` +// sample2.hcs +root { + attr_1 = 0x1; + attr_2 = 0x2; + foo_2 { + t = 0x1; + } +} + +// sample1.hcs +#include "sample2.hcs" +root { + attr_2 = delete; + foo_2 : delete { + } +} +``` + +The following configuration tree is generated: + +``` +root { + attr_1 = 0x1; +} +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The **delete** keyword cannot be used in the same HCS file. It is recommended that you delete unnecessary attributes directly from the configuration source code. + +## Referencing an Attribute + +To quickly locate the associated node during configuration parsing, you can use the node as the value of the attribute and read the attribute to find the corresponding node. The syntax is as follows: + +``` + attribute = &node; +``` + +This syntax indicates that the **attribute** value is a reference to **node**. During code parsing, you can quickly locate the node using this attribute. Example: + +``` +node1 { + attributes; +} + +node2 { + attr_1 = &node1; +} +``` + +## Keyword Template + +The **template** keyword is used to generate nodes with strictly consistent syntax, thereby facilitating the traverse and management of nodes of the same type. + +If a node is defined using the keyword **template**, its child nodes inherit the node configuration through the double colon operator \(::\). The child nodes can modify but cannot add or delete attributes in **template**. The attributes not defined in the child nodes will use the attributes defined in **template** as the default values. Example: + +``` +root { + module = "sample"; + template foo { + attr_1 = 0x1; + attr_2 = 0x2; + } + + bar :: foo { + } + + bar_1 :: foo { + attr_1 = 0x2; + } +} +``` + +The following configuration tree is generated: + +``` +root { + module = "sample"; + bar { + attr_1 = 0x1; + attr_2 = 0x2; + } + bar_1 { + attr_1 = 0x2; + attr_2 = 0x2; + } +} +``` + +In the preceding example, the **bar** and **bar\_1** nodes inherit the **foo** node. The structures of the generated configuration tree nodes are the same as that of the **foo** node, but the attribute values are different. + +## Configuration Generation + +The HC-GEN tool is used to generate configurations. It checks the HCS configuration syntax and converts HCS source files into HCB files. + +## Introduction to HC-GEN + +Parameter description: + +``` +Usage: hc-gen [Options] [File] +options: + -o output file name, default same as input + -a hcb align with four bytes + -b output binary output, default enable + -t output config in C language source file style + -i output binary hex dump in C language source file style + -p prefix of generated symbol name + -d decompile hcb to hcs + -V show verbose info + -v show version + -h show this help message +``` + +Generate a **.c** or **.h** configuration file. + +``` +hc-gen -o [OutputCFileName] -t [SourceHcsFileName] +``` + +Generate an HCB file. + +``` +hc-gen -o [OutputHcbFileName] -b [SourceHcsFileName] +``` + +Compile an **HCB** file to an **HCS** file: + +``` +hc-gen -o [OutputHcsFileName] -d [SourceHcbFileName] +``` + diff --git a/en/device-dev/driver/driver-hdf-news.md b/en/device-dev/driver/driver-hdf-news.md new file mode 100644 index 0000000000000000000000000000000000000000..90f70d1aa93f3c0964e923e24b16c9b42c16171a --- /dev/null +++ b/en/device-dev/driver/driver-hdf-news.md @@ -0,0 +1,193 @@ +# Driver Message Mechanism Management + +- [When to Use](#section33014541954) +- [Available APIs](#section538852311616) +- [How to Develop](#section946912121153) + +## When to Use + +When user-level applications need to interact with kernel-level drivers, the driver message mechanism of the HDF can be used. + +## Available APIs + +The message mechanism provides the following features: + +1. User-level applications send messages to drivers. +2. User-level applications receive events sent by the drivers. + +**Table 1** APIs for the driver message mechanism + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

struct HdfIoService *HdfIoServiceBind(const char *serviceName)

+

Obtains a specified driver service. After the service is obtained, the Dispatch function of the service is used to send messages to the driver.

+

void HdfIoServiceRecycle(struct HdfIoService *service);

+

Releases a specified driver service.

+

int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);

+

Receives events sent by the drivers.

+

int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);

+

Sends events.

+
+ +## How to Develop + +1. Set the value of the **policy** field in the driver configuration information to **2** \(SERVICE\_POLICY\_CAPACITY, see [Driver Service Management](drive-hdf-servicemanage.md)\). + + ``` + device_sample :: Device { + policy = 2; + ... + } + ``` + +2. The **permission** field in the driver configuration information indicates the permission provided for the driver to create device nodes. The default value is **0666**. You can configure the value of this field based on the actual application scenario of the driver. +3. Implement the **Dispatch** function of the service base member **IDeviceIoService** during service implementation. + + ``` + // Process messages delivered by user-level applications. + int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) + { + HDF_LOGE("sample driver lite A dispatch"); + return 0; + } + int32_t SampleDriverBind(struct HdfDeviceObject *device) + { + HDF_LOGE("test for lite os sample driver A Open!"); + if (device == NULL) { + HDF_LOGE("test for lite os sample driver A Open failed!"); + return -1; + } + static struct ISampleDriverService sampleDriverA = { + .ioService.Dispatch = SampleDriverDispatch, + .ServiceA = SampleDriverServiceA, + .ServiceB = SampleDriverServiceB, + }; + device->service = (struct IDeviceIoService *)(&sampleDriverA); + return 0; + } + ``` + +4. Define the CMD type in the message processing function. + + ``` + #define SAMPLE_WRITE_READ 1 // Read and write operation 1 + ``` + +5. Enable the user-level application to obtain the service interface and send messages to the driver. + + ``` + int SendMsg(const char *testMsg) + { + if (testMsg == NULL) { + HDF_LOGE("test msg is null"); + return -1; + } + struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); + if (serv == NULL) { + HDF_LOGE("fail to get service"); + return -1; + } + struct HdfSBuf *data = HdfSBufObtainDefaultSize(); + if (data == NULL) { + HDF_LOGE("fail to obtain sbuf data"); + return -1; + } + struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); + if (reply == NULL) { + HDF_LOGE("fail to obtain sbuf reply"); + ret = HDF_DEV_ERR_NO_MEMORY; + goto out; + } + if (!HdfSbufWriteString(data, testMsg)) { + HDF_LOGE("fail to write sbuf"); + ret = HDF_FAILURE; + goto out; + } + int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("fail to send service call"); + goto out; + } + out: + HdfSBufRecycle(data); + HdfSBufRecycle(reply); + HdfIoServiceRecycle(serv); + return ret; + } + ``` + +6. Enable the user-level application to receive messages reported by the driver. + 1. Enable the user-level application to compile the function for processing messages reported by the driver. + + ``` + static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) + { + OsalTimespec time; + OsalGetTime(&time); + HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); + + const char *string = HdfSbufReadString(data); + if (string == NULL) { + HDF_LOGE("fail to read string in event data"); + return -1; + } + HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); + return 0; + } + ``` + + 2. Enable the user-level application to register the function for receiving messages reported by the driver. + + ``` + int RegisterListen() + { + struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); + if (serv == NULL) { + HDF_LOGE("fail to get service"); + return -1; + } + static struct HdfDevEventlistener listener = { + .callBack = OnDevEventReceived, + .priv ="Service0" + }; + if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { + HDF_LOGE("fail to register event listener"); + return -1; + } + ...... + HdfDeviceUnregisterEventListener(serv, &listener); + HdfIoServiceRecycle(serv); + return 0; + } + ``` + + 3. Enable the driver to report events. + + ``` + int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) + { + ... // process api call here + return HdfDeviceSendEvent(deviceObject, cmdCode, data); + } + ``` + + + diff --git a/en/device-dev/driver/hdfoverview.md b/en/device-dev/driver/driver-hdf-overview.md similarity index 100% rename from en/device-dev/driver/hdfoverview.md rename to en/device-dev/driver/driver-hdf-overview.md diff --git a/en/device-dev/driver/driver-hdf-sample.md b/en/device-dev/driver/driver-hdf-sample.md new file mode 100644 index 0000000000000000000000000000000000000000..722f9bb4e98bb5c14b30007e710ae3457020e80d --- /dev/null +++ b/en/device-dev/driver/driver-hdf-sample.md @@ -0,0 +1,238 @@ +# HDF Development Example + +- [Adding Configurations](#section27261067111) +- [Compiling the Driver Code](#section177988005) +- [Compiling the Code for Interaction](#section6205173816412) + +The following example shows how to add configurations, implement the driver code, and compile the code for interaction between the user-level applications and the driver. + +## Adding Configurations + +Add the driver configurations to the HDF configuration file \(for example, **vendor/hisilicon/xxx/config/device\_info**\). Example: + +``` +root { + device_info { + match_attr = "hdf_manager"; + template host { + hostName = ""; + priority = 100; + template device { + template deviceNode { + policy = 0; + priority = 100; + preload = 0; + permission = 0664; + moduleName = ""; + serviceName = ""; + deviceMatchAttr = ""; + } + } + } + sample_host :: host { + hostName = "sample_host"; + sample_device :: device { + device0 :: deviceNode { + policy = 2; + priority = 100; + preload = 1; + permission = 0664; + moduleName = "sample_driver"; + serviceName = "sample_service"; + } + } + } + } +} +``` + +## Compiling the Driver Code + +A sample of driver code compiled based on the HDF is as follows: + +``` +#include +#include +#include +#include "hdf_log.h" +#include "hdf_base.h" +#include "hdf_device_desc.h" + +#define HDF_LOG_TAG "sample_driver" + +#define SAMPLE_WRITE_READ 123 + +int32_t HdfSampleDriverDispatch( + struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + HDF_LOGE("%s: received cmd %d", __func__, id); + if (id == SAMPLE_WRITE_READ) { + const char *readData = HdfSbufReadString(data); + if (readData != NULL) { + HDF_LOGE("%s: read data is: %s", __func__, readData); + } + if (!HdfSbufWriteInt32(reply, INT32_MAX)) { + HDF_LOGE("%s: reply int32 fail", __func__); + } + return HdfDeviceSendEvent(deviceObject, id, data); + } + return HDF_FAILURE; +} + +void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) +{ + // Release resources here + return; +} + +int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) +{ + if (deviceObject == NULL) { + return HDF_FAILURE; + } + static struct IDeviceIoService testService = { + .Dispatch = HdfSampleDriverDispatch, + }; + deviceObject->service = &testService; + return HDF_SUCCESS; +} + +int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) +{ + if (deviceObject == NULL) { + HDF_LOGE("%s::ptr is null!", __func__); + return HDF_FAILURE; + } + HDF_LOGE("Sample driver Init success"); + return HDF_SUCCESS; +} + +struct HdfDriverEntry g_sampleDriverEntry = { + .moduleVersion = 1, + .moduleName = "sample_driver", + .Bind = HdfSampleDriverBind, + .Init = HdfSampleDriverInit, + .Release = HdfSampleDriverRelease, +}; + +HDF_INIT(g_sampleDriverEntry); +``` + +## Compiling the Code for Interaction + +A sample code for interaction between the user-level application and driver compiled based on the HDF is as follows: + +``` +#include +#include +#include +#include +#include "hdf_log.h" +#include "hdf_sbuf.h" +#include "hdf_io_service_if.h" + +#define HDF_LOG_TAG "sample_test" +#define SAMPLE_SERVICE_NAME "sample_service" + +#define SAMPLE_WRITE_READ 123 + +int g_replyFlag = 0; + +static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) +{ + const char *string = HdfSbufReadString(data); + if (string == NULL) { + HDF_LOGE("fail to read string in event data"); + g_replyFlag = 1; + return HDF_FAILURE; + } + HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string); + g_replyFlag = 1; + return HDF_SUCCESS; +} + +static int SendEvent(struct HdfIoService *serv, char *eventData) +{ + int ret = 0; + struct HdfSBuf *data = HdfSBufObtainDefaultSize(); + if (data == NULL) { + HDF_LOGE("fail to obtain sbuf data"); + return 1; + } + + struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); + if (reply == NULL) { + HDF_LOGE("fail to obtain sbuf reply"); + ret = HDF_DEV_ERR_NO_MEMORY; + goto out; + } + + if (!HdfSbufWriteString(data, eventData)) { + HDF_LOGE("fail to write sbuf"); + ret = HDF_FAILURE; + goto out; + } + + ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("fail to send service call"); + goto out; + } + + int replyData = 0; + if (!HdfSbufReadInt32(reply, &replyData)) { + HDF_LOGE("fail to get service call reply"); + ret = HDF_ERR_INVALID_OBJECT; + goto out; + } + HDF_LOGE("Get reply is: %d", replyData); +out: + HdfSBufRecycle(data); + HdfSBufRecycle(reply); + return ret; +} + +int main() +{ + char *sendData = "default event info"; + struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME); + if (serv == NULL) { + HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME); + return HDF_FAILURE; + } + + static struct HdfDevEventlistener listener = { + .callBack = OnDevEventReceived, + .priv ="Service0" + }; + + if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) { + HDF_LOGE("fail to register event listener"); + return HDF_FAILURE; + } + if (SendEvent(serv, sendData)) { + HDF_LOGE("fail to send event"); + return HDF_FAILURE; + } + + while (g_replyFlag == 0) { + sleep(1); + } + + if (HdfDeviceUnregisterEventListener(serv, &listener)) { + HDF_LOGE("fail to unregister listener"); + return HDF_FAILURE; + } + + HdfIoServiceRecycle(serv); + return HDF_SUCCESS; +} +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The code compilation of user-level applications depends on the dynamic libraries **hdf\_core** and **osal** provided by the HDF because user-level applications use the message sending interface of the HDF. In the GN compilation file, add the following dependency relationships: +>deps = \[ +>"//drivers/adapter/lite/uhdf/manager:hdf\_core", +>"//drivers/adapter/lite/uhdf/posix:hdf\_posix\_osal", +>\] + diff --git a/en/device-dev/driver/driver-service-management.md b/en/device-dev/driver/driver-hdf-servicemanage.md similarity index 100% rename from en/device-dev/driver/driver-service-management.md rename to en/device-dev/driver/driver-hdf-servicemanage.md diff --git a/en/device-dev/driver/driver-hdf.md b/en/device-dev/driver/driver-hdf.md new file mode 100644 index 0000000000000000000000000000000000000000..cc7e51c2b541100f6d1109886b19bc9b1d9beb63 --- /dev/null +++ b/en/device-dev/driver/driver-hdf.md @@ -0,0 +1,15 @@ +# HDF + +- **[HDF Overview](driver-hdf-overview.md)** + +- **[driverr Development](driver-hdf-development.md)** + +- **[driverr Service Management](driver-hdf-servicemanage.md)** + +- **[driverr Message Mechanism Management](driver-hdf-news.md)** + +- **[driverr Configuration Management](driver-hdf-manage.md)** + +- **[HDF Development Example](driver-hdf-sample.md)** + + diff --git a/en/device-dev/driver/driver-message-mechanism-management.md b/en/device-dev/driver/driver-message-mechanism-management.md deleted file mode 100644 index 3ea214d2ade48cb8955cd793fd84aadc2cc38d81..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/driver-message-mechanism-management.md +++ /dev/null @@ -1,193 +0,0 @@ -# Driver Message Mechanism Management - -- [When to Use](#section33014541954) -- [Available APIs](#section538852311616) -- [How to Develop](#section946912121153) - -## When to Use - -When user-level applications need to interact with kernel-level drivers, the driver message mechanism of the HDF can be used. - -## Available APIs - -The message mechanism provides the following features: - -1. User-level applications send messages to drivers. -2. User-level applications receive events sent by the drivers. - -**Table 1** APIs for the driver message mechanism - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

struct HdfIoService *HdfIoServiceBind(const char *serviceName)

-

Obtains a specified driver service. After the service is obtained, the Dispatch function of the service is used to send messages to the driver.

-

void HdfIoServiceRecycle(struct HdfIoService *service);

-

Releases a specified driver service.

-

int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);

-

Receives events sent by the drivers.

-

int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);

-

Sends events.

-
- -## How to Develop - -1. Set the value of the **policy** field in the driver configuration information to **2** \(SERVICE\_POLICY\_CAPACITY, see [Driver Service Management](driver-service-management.md)\). - - ``` - device_sample :: Device { - policy = 2; - ... - } - ``` - -2. The **permission** field in the driver configuration information indicates the permission provided for the driver to create device nodes. The default value is **0666**. You can configure the value of this field based on the actual application scenario of the driver. -3. Implement the **Dispatch** function of the service base member **IDeviceIoService** during service implementation. - - ``` - // Process messages delivered by user-level applications. - int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) - { - HDF_LOGE("sample driver lite A dispatch"); - return 0; - } - int32_t SampleDriverBind(struct HdfDeviceObject *device) - { - HDF_LOGE("test for lite os sample driver A Open!"); - if (device == NULL) { - HDF_LOGE("test for lite os sample driver A Open failed!"); - return -1; - } - static struct ISampleDriverService sampleDriverA = { - .ioService.Dispatch = SampleDriverDispatch, - .ServiceA = SampleDriverServiceA, - .ServiceB = SampleDriverServiceB, - }; - device->service = (struct IDeviceIoService *)(&sampleDriverA); - return 0; - } - ``` - -4. Define the CMD type in the message processing function. - - ``` - #define SAMPLE_WRITE_READ 1 // Read and write operation 1 - ``` - -5. Enable the user-level application to obtain the service interface and send messages to the driver. - - ``` - int SendMsg(const char *testMsg) - { - if (testMsg == NULL) { - HDF_LOGE("test msg is null"); - return -1; - } - struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); - if (serv == NULL) { - HDF_LOGE("fail to get service"); - return -1; - } - struct HdfSBuf *data = HdfSBufObtainDefaultSize(); - if (data == NULL) { - HDF_LOGE("fail to obtain sbuf data"); - return -1; - } - struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); - if (reply == NULL) { - HDF_LOGE("fail to obtain sbuf reply"); - ret = HDF_DEV_ERR_NO_MEMORY; - goto out; - } - if (!HdfSbufWriteString(data, testMsg)) { - HDF_LOGE("fail to write sbuf"); - ret = HDF_FAILURE; - goto out; - } - int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); - if (ret != HDF_SUCCESS) { - HDF_LOGE("fail to send service call"); - goto out; - } - out: - HdfSBufRecycle(data); - HdfSBufRecycle(reply); - HdfIoServiceRecycle(serv); - return ret; - } - ``` - -6. Enable the user-level application to receive messages reported by the driver. - 1. Enable the user-level application to compile the function for processing messages reported by the driver. - - ``` - static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) - { - OsalTimespec time; - OsalGetTime(&time); - HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); - - const char *string = HdfSbufReadString(data); - if (string == NULL) { - HDF_LOGE("fail to read string in event data"); - return -1; - } - HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); - return 0; - } - ``` - - 2. Enable the user-level application to register the function for receiving messages reported by the driver. - - ``` - int RegisterListen() - { - struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); - if (serv == NULL) { - HDF_LOGE("fail to get service"); - return -1; - } - static struct HdfDevEventlistener listener = { - .callBack = OnDevEventReceived, - .priv ="Service0" - }; - if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { - HDF_LOGE("fail to register event listener"); - return -1; - } - ...... - HdfDeviceUnregisterEventListener(serv, &listener); - HdfIoServiceRecycle(serv); - return 0; - } - ``` - - 3. Enable the driver to report events. - - ``` - int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) - { - ... // process api call here - return HdfDeviceSendEvent(deviceObject, cmdCode, data); - } - ``` - - - diff --git a/en/device-dev/driver/driver-peripherals-external-des.md b/en/device-dev/driver/driver-peripherals-external-des.md new file mode 100644 index 0000000000000000000000000000000000000000..8cb36a1068e3bef6baba7e9c1a8060b4fd9ae588 --- /dev/null +++ b/en/device-dev/driver/driver-peripherals-external-des.md @@ -0,0 +1,622 @@ +# WLAN + +- [Overview](#section729758162218) + - [WLAN Driver API Architecture](#section178022416377) + - [Available APIs](#section149681312202415) + +- [Development Guidelines](#section15957746172412) + - [How to Develop](#section11776186132513) + +- [Development Example](#section1395253612512) + +## Overview + +The WLAN module is developed based on the Hardware Driver Foundation \(HDF\). It supports cross-OS migration, component adaptation, and modular assembly and compilation. Based on the unified APIs provided by the WLAN module, driver developers of WLAN vendors can adapt their driver code and are capable of creating, disabling, scanning, and connecting to WLAN hotspots. The WLAN driver provides the Hardware Driver Interface \(HDI\) layer with the capabilities of setting and obtaining the device MAC address and setting the transmit power. The following figure shows the framework of the [WLAN module](#fig967034316227): + +**Figure 1** WLAN framework + + +![](figure/en-us_image_0000001170383063.png) + +### WLAN Driver API Architecture + +The WLAN module provides the following three types of APIs: + +1. Capability APIs for the HDI layer + +2. Capability APIs directly invoked by drivers + +3. Capability APIs for vendors + +**Figure 2** Available APIs of the WLAN module + + +![](figure/接口分布图4.png) + +### Available APIs + +The WLAN driver module provides APIs that can be directly called by driver developers, such as creating/releasing a **WifiModule**, connecting to/disconnecting from a WLAN hotspot, applying for/releasing a **NetBuf**, and converting between the **pbuf** structure of Lightweight IP \(lwIP\) and a **NetBuf**. [Table 1](#table1521573319472) describes some APIs. + +**Table 1** APIs that can be directly called by driver developers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File

+

Function

+

Description

+

wifi_module.h

+

+

struct WifiModule *WifiModuleCreate(const struct HdfConfigWifiModuleConfig *config);

+

Creates a WifiModule.

+

void WifiModuleDelete(struct WifiModule *module);

+

Deletes a WifiModule and releases its data.

+

int32_t DelFeature(struct WifiModule *module, uint16_t featureType);

+

Deletes a feature from a WifiModule.

+

int32_t AddFeature(struct WifiModule *module, uint16_t featureType, struct WifiFeature *featureData);

+

Adds a feature to a WifiModule.

+

wifi_mac80211_ops.h

+

int32_t (*startAp)(NetDevice *netDev);

+

Starts an AP.

+

int32_t (*stopAp)(NetDevice *netDev);

+

Stops an AP.

+

int32_t (*connect)(NetDevice *netDev, WifiConnectParams *param);

+

Connects to a hotspot.

+

int32_t (*disconnect)(NetDevice *netDev, uint16_t reasonCode);

+

Disconnects from a hotspot.

+

hdf_netbuf.h

+

static inline void NetBufQueueInit(struct NetBufQueue *q);

+

Initializes a NetBuf queue.

+

struct NetBuf *NetBufAlloc(uint32_t size);

+

Applies for a NetBuf.

+

void NetBufFree(struct NetBuf *nb);

+

Releases a NetBuf.

+

struct NetBuf *Pbuf2NetBuf(const struct NetDevice *netdev, struct pbuf *lwipBuf);

+

Converts the pbuf structure of lwIP to a NetBuf.

+

struct pbuf *NetBuf2Pbuf(const struct NetBuf *nb);

+

Converts a NetBuf to the pbuf structure of lwIP.

+
+ +The WLAN driver module provides APIs for driver developers, such as initializing/deregistering, opening/stopping a **NetDevice**, and obtaining the state of a **NetDevice**. [Table 2](#table74613501475) describes some APIs. + +**Table 2** APIs for driver developers of WLAN vendors to implement + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File

+

Function

+

Description

+

net_device.h

+

int32_t (*init)(struct NetDevice *netDev);

+

Initializes a NetDevice.

+

struct NetDevStats *(*getStats)(struct NetDevice *netDev);

+

Obtains the state of a NetDevice.

+

int32_t (*setMacAddr)(struct NetDevice *netDev, void *addr);

+

Sets the MAC address.

+

void (*deInit)(struct NetDevice *netDev);

+

Deinitializes a NetDevice.

+

int32_t (*open)(struct NetDevice *netDev);

+

Opens a NetDevice.

+

int32_t (*stop)(struct NetDevice *netDev);

+

Stops a NetDevice.

+
+ +The WLAN driver provides the HDI layer with the APIs for creating and destroying an **IWiFi** object and setting the MAC address. [Table 3](#table141076311618) describes some APIs. + +**Table 3** APIs provided by the WLAN HAL module + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Header File

+

Function

+

Description

+

wifi_hal.h

+

+

int32_t WifiConstruct(struct IWiFi **wifiInstance);

+

Creates an IWiFi object with basic capabilities.

+

int32_t WifiDestruct(struct IWiFi **wifiInstance);

+

Destroys an IWiFi object.

+

int32_t (*start)(struct IWiFi *);

+

Creates a channel between the HAL and the driver and obtains the NIC supported by the driver.

+

int32_t (*stop)(struct IWiFi *);

+

Stops the channel between the HAL and the driver.

+

wifi_hal_base_feature.h

+

int32_t (*getFeatureType)(const struct IWiFiBaseFeature *);

+

Obtains the feature type.

+

int32_t (*setMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

+

Sets the MAC address.

+

int32_t (*getDeviceMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

+

Obtains the device MAC address.

+

int32_t (*setTxPower)(const struct IWiFiBaseFeature *, int32_t);

+

Sets the transmit power.

+
+ +## Development Guidelines + +The WLAN driver is developed based on the HDF and PLATFORM. It provides a unified driver model for WLAN modules of different vendors regardless of the operating system \(OS\) and system on a chip \(SoC\). + +### How to Develop + +1. Set hardware parameters such as **module** \(different features\) and **chip** in the **wifi\_config.hcs** file. +2. Parse the **wifi\_config.hcs** file and generate a structure with the configured parameters. +3. Initialize and create a module. +4. Mount and initialize the chip. +5. Initialize the bus. +6. Mount the upper-layer WPA service. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Some of the above adaptation steps have been provided. For details, see [Development Example](#section1395253612512). The steps waiting to be performed by developers include setting configuration parameters based on hardware attributes, adapting and mounting a chip, and performing tests and verification. + +## Development Example + +This example describes how to initialize a WLAN module. The following uses the Hi3881 WLAN chip as an example: + +1. Set parameters for the WLAN module based on hardware attributes. + +``` +/* Set parameters in the wlan_platform.hcs file based on hardware attributes. The following is an example of the WLAN platform configuration. */ +hisi :& deviceList { + device0 :: deviceInst { + deviceInstId = 0; + powers { + power0 { + powerSeqDelay = 0; /* Power supply sequencing delay */ + powerType = 1; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through general-purpose input/output (GPIO). */ + gpioId = 1; /* GPIO pin ID */ + activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */ + } + power1 { + powerSeqDelay = 0; /* Power supply sequencing delay */ + powerType = 0; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through GPIO. */ + } + } + reset { + resetType = 0; /* Reset type. Value 0 indicates that reset is not supported, and value 1 indicates reset through GPIO. */ + gpioId = 2; /* GPIO pin ID */ + activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */ + resetHoldTime = 30; /* Hold time (ms) for a reset */ + } + bootUpTimeout = 30; /* Boot timeout duration (ms) */ + bus { + busType = 0; /* Bus type. Value 0 indicates secure digital input/output (SDIO). */ + busId = 2; /* Bus ID */ + funcNum = [1]; /* SDIO function number */ + timeout = 1000; /* Timeout duration for data read/write */ + blockSize = 512; /* Size of the data block to read or write */ + } + } +} +/* Add the configuration file wlan_chip_.hcs (for example, wlan_chip_hi3881.hcs) for each chip and set parameters. The following uses the Hi3881 chip as an example. */ +root { + wlan_config { + hi3881 :& chipList { + chipHi3881 :: chipInst { + match_attr = "hdf_wlan_chips_hi3881"; /* Match attribute */ + chipName = "hi3881"; /* WLAN chip name */ + sdio { + vendorId = 0x0296; /* Vendor ID */ + deviceId = [0x5347]; /* Device ID */ + } + } + } + } +} +``` + +2. Mount the **init** and **deinit** functions of the WLAN chip and WLAN chip driver. + +``` +/* WLAN module initialization and mount process */ +#include "hdf_device_desc.h" +#include "hdf_wifi_product.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "hdf_wlan_chipdriver_manager.h" +#include "securec.h" +#include "wifi_module.h" +#include "hi_wifi_api.h" +#include "hi_types_base.h" + +#define HDF_LOG_TAG Hi3881Driver + +/* Functions for initializing and deinitializing the WLAN chip */ +int32_t InitHi3881Chip(struct HdfWlanDevice *device); +int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); +/* Functions for initializing and deinitializing the WLAN chip driver */ +int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); +int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); + +/* Initialize mac80211 and mount functions of the chip. */ +hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); + +static const char* const HI3881_DRIVER_NAME = "hisi"; + +/* Mount the WLAN chip driver and the functions of mac80211 and the chip. */ +static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) +{ + struct HdfChipDriver *specificDriver = NULL; + if (device == NULL) { + HDF_LOGE("%s fail : channel is NULL", __func__); + return NULL; + } + (void)device; + (void)ifIndex; + specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); + if (specificDriver == NULL) { + HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); + return NULL; + } + if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { + HDF_LOGE("%s fail: memset_s fail!", __func__); + OsalMemFree(specificDriver); + return NULL; + } + + if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { + HDF_LOGE("%s fail : strcpy_s fail", __func__); + OsalMemFree(specificDriver); + return NULL; + } + specificDriver->init = Hi3881Init; + specificDriver->deinit = Hi3881Deinit; + + HiMac80211Init(specificDriver); + + return specificDriver; +} + +/* Release the WLAN chip driver. */ +static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) +{ + if (chipDriver == NULL) { + return; + } + if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { + HDF_LOGE("%s:Not my driver!", __func__); + return; + } + OsalMemFree(chipDriver); +} + +static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { + (void)factory; + return 1; +} + +/* Register functions related to the WLAN chip. */ +static int32_t HDFWlanRegHisiDriverFactory(void) +{ + static struct HdfChipDriverFactory tmpFactory = { 0 }; + struct HdfChipDriverManager *driverMgr = NULL; + driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + tmpFactory.driverName = HI3881_DRIVER_NAME; + tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; + tmpFactory.InitChip = InitHi3881Chip; + tmpFactory.DeinitChip = DeinitHi3881Chip; + tmpFactory.Build = BuildHi3881Driver; + tmpFactory.Release = ReleaseHi3881Driver; + tmpFactory.ReleaseFactory = NULL; + if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) +{ + (void)device; + return HDFWlanRegHisiDriverFactory(); +} + +struct HdfDriverEntry g_hdfHisiChipEntry = { + .moduleVersion = 1, + .Init = HdfWlanHisiChipDriverInit, + .moduleName = "HDF_WLAN_CHIPS" +}; + +HDF_INIT(g_hdfHisiChipEntry); +``` + +``` +#include "hdf_wifi_product.h" +#include "hi_wifi_api.h" +#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) +#include "oal_thread.h" +#include "osal_time.h" +#endif +#include "wifi_mac80211_ops.h" +#include "wal_cfg80211.h" +#include "net_adpater.h" +#include "hdf_wlan_utils.h" + +#define HDF_LOG_TAG Hi3881Driver + +/* Initialize the WLAN chip. */ +int32_t InitHi3881Chip(struct HdfWlanDevice *device) +{ + uint8_t maxPortCount = 1; + int32_t ret = HI_SUCCESS; + uint8_t maxRetryCount = 2; + if (device == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HI_FAIL; + } + + do { + if (ret != HI_SUCCESS) { + if (device->reset != NULL && device->reset->Reset != NULL) { + device->reset->Reset(device->reset); + } + HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); + } + ret = hi_wifi_init(maxPortCount); + } while (ret != 0 && --maxRetryCount > 0); + + if (ret != 0) { + HDF_LOGE("%s:Init hi3881 driver failed!", __func__); + return ret; + } + return HI_SUCCESS; +} + +/* Deinitialize the WLAN chip. */ +int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) +{ + (void)device; + int32_t ret = hi_wifi_deinit(); + if (ret != 0) { + HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); + } + return ret; +} + +/* Initialize the WLAN chip driver. */ +int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + HDF_LOGI("%s: start...", __func__); + hi_u16 mode = wal_get_vap_mode(); + int32_t ret; + nl80211_iftype_uint8 type; + (void)chipDriver; + + if (mode >= WAL_WIFI_MODE_BUTT) { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + + if (mode == WAL_WIFI_MODE_STA) { + type = NL80211_IFTYPE_STATION; + } else if (mode == WAL_WIFI_MODE_AP) { + type = NL80211_IFTYPE_AP; + } else { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + + ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); + if (ret != HI_SUCCESS) { + oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); + } + return ret; +} + +/* Deinitialize the WLAN chip driver. */ +int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + (void)chipDriver; + int32_t ret = wal_deinit_drv_wlan_netdev(netDevice); + if (ret != HDF_SUCCESS) { + return ret; + } + return ReleasePlatformNetDevice(netDevice); +} +``` + +3. During the chip initialization, call the **NetDeviceInit\(\)** function to initialize a network device, call the **NetDeviceAdd\(\)** function to add the network device to a protocol stack, and implement some function pointers of **netdev**. + +``` +hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len) +{ + oal_net_device_stru *netdev = HI_NULL; + + ...... + /* Initialize the network device and obtain the initialized instance. */ + netdev = NetDeviceInit(ifname, *len, LITE_OS); + oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); + ret = wal_init_netif(type, netdev, wdev); + + ...... + + return HI_SUCCESS; +} +/* Mount some function pointers of NetDeviceInterFace. */ +oal_net_device_ops_stru g_wal_net_dev_ops = +{ + .getStats = wal_netdev_get_stats, + .open = wal_netdev_open, + .stop = wal_netdev_stop, + .xmit = hmac_bridge_vap_xmit, + .ioctl = wal_net_device_ioctl, + .changeMtu = oal_net_device_change_mtu, + .init = oal_net_device_init, + .deInit = oal_net_free_netdev, +#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) + .selectQueue = wal_netdev_select_queue, +#endif + .setMacAddr = wal_netdev_set_mac_addr, +#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) + .netifNotify = HI_NULL, +#endif + .specialEtherTypeProcess = SpecialEtherTypeProcess, +}; + +hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) +{ + /* Add the network device to a protocol stack. */ + hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); + + ...... + + return HI_SUCCESS; +} +``` + +4. Implement functions of **WifiMac80211Ops**. + +``` +/* Mount some function pointers of mac80211. */ + +/* MAC-layer APIs for basic capabilities that need to be implemented by the driver */ +static struct HdfMac80211BaseOps g_baseOps = { + .SetMode = WalSetMode, + .AddKey = WalAddKey, + .DelKey = WalDelKey, + .SetDefaultKey = WalSetDefaultKey, + .GetDeviceMacAddr = WalGetDeviceMacAddr, + .SetMacAddr = WalSetMacAddr, + .SetTxPower = WalSetTxPower, + .GetValidFreqsWithBand = WalGetValidFreqsWithBand, + .GetHwCapability = WalGetHwCapability +}; + +/* MAC-layer APIs for station capabilities that need to be implemented by the driver */ +static struct HdfMac80211STAOps g_staOps = { + .Connect = WalConnect, + .Disconnect = WalDisconnect, + .StartScan = WalStartScan, + .AbortScan = WalAbortScan, + .SetScanningMacAddress = WalSetScanningMacAddress, +}; + +/* MAC-layer APIs for AP capabilities that need to be implemented by the driver */ +static struct HdfMac80211APOps g_apOps = { + .ConfigAp = WalConfigAp, + .StartAp = WalStartAp, + .StopAp = WalStopAp, + .ConfigBeacon = WalChangeBeacon, + .DelStation = WalDelStation, + .SetCountryCode = WalSetCountryCode, + .GetAssociatedStasCount = WalGetAssociatedStasCount, + .GetAssociatedStasInfo = WalGetAssociatedStasInfo +}; + +/* Initialize mac80211 and mount functions of the chip. */ +hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) +{ + if (chipDriver == NULL) { + oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__); + return; + } + chipDriver->ops = &g_baseOps; + chipDriver->staOps = &g_staOps; + chipDriver->apOps = &g_apOps; +} +``` + diff --git a/en/device-dev/driver/driver-peripherals-lcd-des.md b/en/device-dev/driver/driver-peripherals-lcd-des.md new file mode 100644 index 0000000000000000000000000000000000000000..2b8dd1543a584339b768c9bc929ea4287ea43ab4 --- /dev/null +++ b/en/device-dev/driver/driver-peripherals-lcd-des.md @@ -0,0 +1,363 @@ +# LCD + +- [Overview](#section141575391542) + - [API Description](#section14711163785519) + +- [Development Guidelines](#section12394223125615) + - [How to Develop](#section515923045814) + +- [Development Example](#section7441155155813) + +## Overview + +The Liquid Crystal Display \(LCD\) driver powers on the LCD and initializes internal LCD registers through APIs to enable the LCD to work properly. The display driver is developed based on the hardware driver foundation \([HDF](drive-hdf-overview.md)\). It provides power-on, power-off, and sending of the initialization sequence for LCD hardware across OSs and platforms. The display driver model is shown in [Figure 1](#fig69138814229). + +**Figure 1** Architecture of the display driver model +![](figure/architecture-of-the-display-driver-model.png "architecture-of-the-display-driver-model") + +- **Display driver model** + + The display driver model consists of the display common driver layer, SoC adapter layer, and third-party chip driver layer. The display driver model is developed based on the HDF and hides the differences between kernel forms through platform and OSAL APIs so the LCD driver can be migrated between different OSs and chip platforms. The display driver connects to the display common HAL, supports the implementation of Hardware Driver Interfaces \(HDIs\), and provides various driver interfaces for the graphics service through the display HDI. + + - Display common driver layer: connects to the display common HAL through the IOService data channel provided by the HDF to receive and process upper-layer calls in a centralized manner. + + - SoC adapter layer: decouples the display driver from the SoC driver, configures parameters related to the chip platform, and passes calls from the platform driver layer to the LCD driver layer. + + - Third-party chip driver layer: provides LCD-related APIs for sending the LCD initialization sequence, powering on or off the LCD device, and setting the backlight. + + The display driver model, capabilities, and APIs help you simplify the display driver development and improve the efficiency. + + +### API Description + +The LCD interfaces are classified into the Mobile Industry Processor Interface \(MIPI\) Display Serial Interface \(DSI\), Transistor-Transistor Logic \(TTL\) interfaces, and Low Voltage Differential Signaling \(LVDS\) interfaces. The MIPI DSI and TTL interfaces are commonly used. Here is a brief introduction to them. + +- MIPI DSI + + **Figure 2** MIPI DSI + ![](figure/mipi-dsi.png "mipi-dsi") + + The MIPI DSI is defined by MIPI Alliance. It is mainly used for mobile terminal display. The MIPI DSI is used to transmit image data, in compliance with the MIPI protocol. Generally, control information of the MIPI DSI is sent to the peer IC in the form of MIPI packets through the MIPI DSI. No additional interface is required. + +- TTL interface + + **Figure 3** TTL interface + ![](figure/ttl-interface.png "ttl-interface") + + TTL level signals are generated by TTL devices, which are a major type of digital integrated circuits. They are manufactured using the bipolar process and feature high speed, low power consumption, and multiple types. + + The TTL interface is used to transmit data in parallel mode under the control of control signals. It transmits data signals, clock signals, and control signals \(such as line synchronization signals, frame synchronization signals, and data validity signals\). Generally, the LCD of the TTL interface and the read/write of internal registers require additional peripheral interfaces, such as the Serial Peripheral Interface \(SPI\) and Inter-Integrated Circuit \(I2C\). + + +## Development Guidelines + +The display driver model is developed based on the HDF, platform APIs, and APIs at the OS abstraction layer \(OSAL\), and provides a unified driver model for the LCD regardless of the OS \(LiteOS or Linux OS\) and chip platforms \(such as Hi35xx, Hi38xx, and V3S\). + +### How to Develop + +1. Add the LCD driver-related hardware descriptions. +2. Add a driver that adapts to the chip at the SoC adapter layer. +3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for: + - Powering on/off the LCD device + + Based on the LCD hardware connection, use the GPIO interfaces provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier. + + - Sending the initialization sequence + + Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier. + + +4. Implement other HDF interfaces as required, for example, the **Release** interface. +5. Use the HDF to create other device nodes for implementing service logic or debugging as required. + +## Development Example + +Add the device description. + +``` +/* Description of the display driver */ +display :: host { + hostName = "display_host"; + /* Description of the HDF display driver */ + device_hdf_disp :: device { + device0 :: deviceNode { + policy = 2; + priority = 200; + permission = 0660; + moduleName = "HDF_DISP"; + serviceName = "hdf_disp"; + } + } + /* Description of the driver device at the SoC adapter layer */ + device_hi35xx_disp :: device { + device0 :: deviceNode { + policy = 0; + priority = 199; + moduleName = "HI351XX_DISP"; + } + } + /* Description of the LCD driver */ + device_lcd :: device { + device0 :: deviceNode { + policy = 0; + priority = 100; + preload = 0; + moduleName = "LCD_Sample"; + } + device1 :: deviceNode { + policy = 0; + priority = 100; + preload = 2; + moduleName = "LCD_SampleXX"; + } + } +} +``` + +The following example shows how to adapt to the MIPI device to the Hi35xx series chips at the SoC adapter layer: + +``` +static int32_t MipiDsiInit(struct PanelInfo *info) +{ + int32_t ret; + struct DevHandle *mipiHandle = NULL; + struct MipiCfg cfg; + + mipiHandle = MipiDsiOpen(0); + if (mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + cfg.lane = info->mipi.lane; + cfg.mode = info->mipi.mode; + cfg.format = info->mipi.format; + cfg.burstMode = info->mipi.burstMode; + cfg.timing.xPixels = info->width; + cfg.timing.hsaPixels = info->hsw; + cfg.timing.hbpPixels = info->hbp; + cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; + cfg.timing.vsaLines = info->vsw; + cfg.timing.vbpLines = info->vbp; + cfg.timing.vfpLines = info->vfp; + cfg.timing.ylines = info->height; + /* 0 : no care */ + cfg.timing.edpiCmdSize = 0; + cfg.pixelClk = CalcPixelClk(info); + cfg.phyDataRate = CalcDataRate(info); + /* config mipi device */ + ret = MipiDsiSetCfg(mipiHandle, &cfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); + } + MipiDsiClose(mipiHandle); + HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, + cfg.pixelClk, cfg.phyDataRate); + return ret; +} +``` + +The following example shows code for developing an LCD driver: + +``` +#define RESET_GPIO 5 +#define MIPI_DSI0 0 +#define BLK_PWM1 1 +#define PWM_MAX_PERIOD 100000 +/* backlight setting */ +#define MIN_LEVEL 0 +#define MAX_LEVEL 255 +#define DEFAULT_LEVEL 100 + +#define WIDTH 480 +#define HEIGHT 960 +#define HORIZONTAL_BACK_PORCH 20 +#define HORIZONTAL_FRONT_PORCH 20 +#define HORIZONTAL_SYNC_WIDTH 10 +#define VERTIACL_BACK_PORCH 14 +#define VERTIACL_FRONT_PORCH 16 +#define VERTIACL_SYNC_WIDTH 2 +#define FRAME_RATE 60 + +/* PanelInfo structure */ +struct PanelInfo { + uint32_t width; + uint32_t height; + uint32_t hbp; + uint32_t hfp; + uint32_t hsw; + uint32_t vbp; + uint32_t vfp; + uint32_t vsw; + uint32_t frameRate; + enum LcdIntfType intfType; + enum IntfSync intfSync; + struct MipiDsiDesc mipi; + struct BlkDesc blk; + struct PwmCfg pwm; +}; + +/* Initialization sequence of the LCD panel */ +static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; +static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; +static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; +static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; +static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; +static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; +static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; +static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; +static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; +static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; +static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; +static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; +static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; +static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; +static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; +static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; +static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; +static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; +static uint8_t g_payLoad18[] = { + 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, + 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, + 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 +}; +static uint8_t g_payLoad19[] = { 0x11 }; +static uint8_t g_payLoad20[] = { 0x29 }; + +struct DsiCmdDesc g_OnCmd[] = { + { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, + { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, + { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, + { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, + { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, + { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, + { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, + { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, + { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, + { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, + { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, + { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, + { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, + { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, + { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, + { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, + { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, + { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, + { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, + { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, + { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, +}; +static DevHandle g_mipiHandle = NULL; +static DevHandle g_pwmHandle = NULL; + +/* Set the status of the reset pin. */ +static int32_t LcdResetOn(void) +{ + int32_t ret; + ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioSetDir failure, ret:%d", ret); + return HDF_FAILURE; + } + ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioWrite failure, ret:%d", ret); + return HDF_FAILURE; + } + /* delay 20ms */ + OsalMSleep(20); + return HDF_SUCCESS; +} + +static int32_t SampleInit(void) +{ + /* Obtain the MIPI DSI device handle. */ + g_mipiHandle = MipiDsiOpen(MIPI_DSI0); + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t SampleOn(void) +{ + int32_t ret; + /* Power on the LCD. */ + ret = LcdResetOn(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: LcdResetOn failure", __func__); + return HDF_FAILURE; + } + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: g_mipiHandle is null", __func__); + return HDF_FAILURE; + } + /* Send the initialization sequence via MIPI. */ + int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); + int32_t i; + for (i = 0; i < count; i++) { + ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); + if (ret != HDF_SUCCESS) { + HDF_LOGE("MipiDsiTx failure"); + return HDF_FAILURE; + } + } + /* Set MIPI to the high speed (HS) mode. */ + MipiDsiSetHsMode(g_mipiHandle); + return HDF_SUCCESS; +} + +/* PanelInfo structure variables */ +static struct PanelInfo g_panelInfo = { + .width = WIDTH, /* width */ + .height = HEIGHT, /* height */ + .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ + .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ + .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ + .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ + .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ + .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ + .frameRate = FRAME_RATE, /* frame rate */ + .intfType = MIPI_DSI, /* panel interface type */ + .intfSync = OUTPUT_USER, /* output timming type */ + /* mipi config info */ + .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, + /* backlight config info */ + .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, + .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, +}; + +/* Basic APIs that need to be adapted for the chip driver */ +static struct PanelData g_panelData = { + .info = &g_panelInfo, + .init = SampleInit, + .on = SampleOn, + .off = SampleOff, + .setBacklight = SampleSetBacklight, +}; + +/* Entry function of the chip driver */ +int32_t SampleEntryInit(struct HdfDeviceObject *object) +{ + HDF_LOGI("%s: enter", __func__); + if (object == NULL) { + HDF_LOGE("%s: param is null!", __func__); + return HDF_FAILURE; + } + /* Register the chip driver APIs with the platform driver. */ + if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { + HDF_LOGE("%s: PanelDataRegister error!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +struct HdfDriverEntry g_sampleDevEntry = { + .moduleVersion = 1, + .moduleName = "LCD_SAMPLE", + .Init = SampleEntryInit, +}; + +HDF_INIT(g_sampleDevEntry); +``` + diff --git a/en/device-dev/driver/driver-peripherals-sensor-des.md b/en/device-dev/driver/driver-peripherals-sensor-des.md new file mode 100644 index 0000000000000000000000000000000000000000..5ad5682a94344b9bf86b6d679af80d31318900a6 --- /dev/null +++ b/en/device-dev/driver/driver-peripherals-sensor-des.md @@ -0,0 +1,929 @@ +# Sensor + +- [Overview](#section3634112111) + - [Available APIs](#section188213414114) + +- [Development Guidelines](#section1140943382) + - [How to Develop](#section7893102915819) + +- [Development Example](#section257750691) +- [Test Guidelines](#section106021256121219) + +## Overview + +The sensor driver module provides APIs for upper-layer sensor services to implement basic sensor capabilities, including querying the sensor list, enabling or disabling a sensor, subscribing to or unsubscribing from sensor data, and setting sensor options. The sensor driver model is developed based on the Hardware Driver Foundation \(HDF\) and supports functions such as cross-OS migration and differentiated device configuration. The following figure shows the architecture of the sensor driver model. + +**Figure 1** Architecture of the sensor driver model +![](figure/architecture-of-the-sensor-driver-model.png "architecture-of-the-sensor-driver-model") + +The sensor driver model offers the following APIs: + +- Hardware Driver Interfaces \(HDIs\) for sensors: These HDIs facilitate service development. +- APIs for implementing sensor driver model capabilities: These APIs implement the capabilities of registering, loading, and unregistering sensor drivers as well as detecting sensor devices depending on the HDF. The APIs include normalized APIs for sensor devices of the same type, APIs for parsing register configurations, abstract APIs for bus access, and abstract platform APIs. +- APIs to be implemented by developers: Based on the HDF Configuration Source \(HCS\), developers can implement differentiated configuration for sensors of the same type and serialized configuration of sensor device parameters. Some sensor device operations can be abstracted as APIs to simplify sensor driver development. + +### Available APIs + +The following table lists the APIs provided by the sensor driver model. + +**Table 1** External APIs provided by the sensor driver model + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Category

+

API

+

Description

+

Query

+

int32_t GetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)

+

Obtains information about all sensors in the system. The information about a sensor generally includes the sensor name, sensor vendor, firmware version, hardware version, sensor type ID, sensor ID, maximum measurement range, accuracy, and power.

+

Setting

+

int32_t Enable(int32_t sensorId)

+

Enables the sensor that has been subscribed to. The subscriber can obtain the sensor data only after the sensor is enabled.

+

int32_t Disable(int32_t sensorId)

+

Disables a sensor.

+

int32_t SetBatch(iint32_t sensorId, int64_t samplingInterval, int64_t reportInterval)

+

Sets the data sampling interval and data reporting interval for the specified sensor.

+

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

+

Sets the data reporting mode for the specified sensor.

+

int32_t SetOption(int32_t sensorId, uint32_t option)

+

Sets options for the specified sensor, including its measurement range and accuracy.

+

Data subscription and unsubscription

+

int32_t Register(RecordDataCallback cb)

+

Registers the callback for reporting sensor data to the subscriber.

+

int32_t Unregister(void)

+

Unregisters the callback for reporting sensor data.

+

Instance creation

+

const struct SensorInterface *NewSensorInterfaceInstance(void)

+

Creates a SensorInterface instance.

+

int32_t FreeSensorInterfaceInstance(void)

+

Releases the SensorInterface instance.

+
+ +The following table lists the APIs provided by the sensor driver model for driver developers. You can directly call these APIs without any implementations. + +**Table 2** APIs provided by the sensor driver model for driver developers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Category

+

API

+

Description

+

Device management

+

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

+

Adds a sensor of the current type to the sensor management module.

+

int32_t DeleteSensorDevice(int32_t sensorId)

+

Deletes a specified sensor from the sensor management module.

+

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

+

Reports data of a specified sensor type.

+

Abstract bus and platform operations

+

int32_t ReadSensor(struct SensorBusCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen)

+

Reads sensor configuration data from the sensor register based on the bus configuration.

+

int32_t WriteSensor(struct SensorBusCfg *busCfg, uint8_t *writeData, uint16_t len)

+

Writes sensor configuration data to the sensor register based on the bus configuration.

+

int32_t CreateSensorThread(struct OsalThread *thread, OsalThreadEntry threadEntry, char *name, void *entryPara)

+

Creates a scheduled thread for a specified sensor to process sensor data reporting.

+

void DestroySensorThread(struct OsalThread *thread, uint8_t *status);

+

Destroys the scheduled thread created for the sensor.

+

Common configuration

+

int32_t SetSensorRegCfgArray(struct SensorBusCfg *busCfg, const struct SensorRegCfgGroupNode *group);

+

Sets the sensor register group configuration based on the sensor bus type.

+

Configuration parsing

+

+

int32_t GetSensorBaseConfigData(const struct DeviceResourceNode *node, struct SensorCfgData *config)

+

Obtains basic configuration information such as sensor, bus, and attribute configurations based on the HCS resource configuration of the sensor device, and initializes the basic configuration data structure.

+

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

+

Parses the register group information based on the HCS resource configuration of the sensor device and initializes the configuration data structure.

+

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

+

Releases the resources allocated to the sensor configuration data structure.

+

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

+

Obtains the sensor bus handle information.

+

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

+

Releases the sensor bus handle information.

+
+ +The following table lists the APIs that need to be implemented by driver developers. + +**Table 3** APIs that need to be implemented by driver developers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Category

+

API

+

Description

+

Basic functions

+

int32_t init(void)

+

Initializes the configuration of a sensor device after it is detected.

+

int32_t GetInfo(struct SensorBasicInfo *info)

+

Obtains the basic information about the current sensor device from the HCS of sensor devices.

+

int32_t Enable(void)

+

Enables the current sensor device by delivering the register configuration in the operation group based on the HCS of the current sensor device.

+

int32_t Disable(void)

+

Disables the current sensor device by delivering the register configuration in the operation group based on the HCS of the current sensor device.

+

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

+

Sets the processing time of the data reporting thread for the current sensor device based on the data sampling interval and data reporting interval.

+

int32_t SetMode(int32_t mode)

+

Sets the data reporting mode of the current sensor device.

+

int32_t SetOption(uint32_t option)

+

Sets the register configuration such as the measurement range and accuracy based on sensor options.

+

void ReadSensorData(void)

+

Reads sensor data.

+
+ +For details about the API implementation, see [Development Example](#section257750691). + +## Development Guidelines + +Regardless of the OS and system on a chip \(SoC\), the sensor driver is developed based on the HDF, platform, and OSAL APIs to provide a unified driver model for sensor devices. This section uses the acceleration sensor as an example to describe how to develop a sensor driver. + +### How to Develop + +1. Register the acceleration sensor driver. The HDF provides a unified driver management model. The HDF identifies and loads the target module driver based on the configuration of the acceleration sensor module. +2. Initialize and deinitialize the acceleration sensor driver. Using the **init** function, the HDF starts loading the sensor device driver and allocating configuration resources for sensor device data, respectively. Using the **release** function, the HDF releases the resources and configurations loaded by the driver. +3. Parse the configurations of the acceleration sensor register group. For different types of sensors, you must configure their respective HCS configuration files in the HCS, check whether the sensor device is in position during the device driver startup, and then load the corresponding configuration file to generate the configuration structure object. +4. Implement APIs for acceleration sensor driver operations. The driver APIs for various types of sensors, such as **init**, **GetInfo**, **Enable**, **Disable**, **SetBatch**, **SetMode**, **SetOption**, and **ReadSensorData**, are normalized to deliver sensor driver configurations and report sensor data. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The sensor driver model provides a collection of APIs to implement sensor driver capabilities, including the driver device management, abstract bus and platform operation, general configuration, and configuration parsing capabilities. For details about the APIs, see [Table 2](#table1156812588320). You need to implement the following APIs: some operations to perform on sensors \([Table 3](#table1083014911336)\), differentiated data configuration of the sensor HCS, and verification of basic driver functions. + +## Development Example + +This section uses a code example to demonstrate how to load and start the acceleration sensor driver based on the HDF driver model. For details about the mechanism, see [Driver Development](driver-hdf-development.md). This example uses the Bosch BMI160 acceleration sensor that communicates over I2C. + +1. Register the driver entry of the acceleration sensor. + +- Implementation of the entry function + +``` +/* Register the entry structure object of the acceleration sensor. */ +struct HdfDriverEntry g_sensorAccelDevEntry = { + .moduleVersion = 1, /* Version of the acceleration sensor module */ + .moduleName = "HDF_SENSOR_ACCEL", /* Name of the acceleration sensor module. The value must be the same as that of moduleName in the device_info.hcs file. */ + .Bind = BindAccelDriver, /* Binding function of the acceleration sensor */ + .Init = InitAccelDriver, /* Initialization function of the acceleration sensor */ + .Release = ReleaseAccelDriver, /* Resource release function of the acceleration sensor */ +}; + +/* Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind function first and then the Init function. If the Init function fails to be called, the HDF will call Release to release the driver resource and exit. +HDF_INIT(g_sensorAccelDevEntry); +``` + +- Acceleration sensor configuration + +The acceleration sensor model uses the HCS as the configuration source code. For details about the HCS configuration fields, see [Driver Configuration Management](driver-hdf-manage.md). + +``` +/* HCS configuration of the acceleration sensor device */ +device_sensor_accel :: device { + device0 :: deviceNode { + policy = 1; /* Policy for providing the driver service */ + priority = 105; /* Driver startup priority (0–200). A larger value indicates a lower priority. The default value 100 is recommended. The sequence for loading devices with the same priority is random. */ + preload = 2; /* Field for specifying whether to load the driver. The value 0 means to load the driver, and 2 means the opposite. */ + permission = 0664; /* Permission for the driver to create device nodes */ + moduleName = "HDF_SENSOR_ACCEL"; /* Driver name. The value must be the same as that of moduleName in the driver entry structure. */ + serviceName = "sensor_accel"; /* Name of the service provided by the driver. The name must be unique. */ + deviceMatchAttr = "hdf_sensor_accel_driver"; /* Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver. */ + } +} +``` + +1. Initialize and deinitialize the acceleration sensor driver. + +- Initialization entry function **init** + +``` +/* Bind the service provided by the acceleration sensor driver to the HDF. */ +int32_t BindAccelDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + + static struct IDeviceIoService service = { + .object = {0}, + .Dispatch = DispatchAccel, + }; + device->service = &service; + + return HDF_SUCCESS; +} +/* After detecting that the device is in position, call RegisterAccelChipOps to register the differentiation adaptation function. */ +int32_t RegisterAccelChipOps(struct AccelOpsCall *ops) +{ + struct AccelDrvData *drvData = NULL; + + CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); + + drvData = AccelGetDrvData(); + drvData->ops.Init = ops->Init; + drvData->ops.ReadData = ops->ReadData; + return HDF_SUCCESS; +} +/* Hook the acceleration sensor driver normalization function. */ +static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo) +{ + struct AccelDrvData *drvData = AccelGetDrvData(); + + (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); + deviceInfo->ops.GetInfo = SetAccelInfo; + deviceInfo->ops.Enable = SetAccelEnable; + deviceInfo->ops.Disable = SetAccelDisable; + deviceInfo->ops.SetBatch = SetAccelBatch; + deviceInfo->ops.SetMode = SetAccelMode; + deviceInfo->ops.SetOption = SetAccelOption; + + if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), + &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) { + HDF_LOGE("%s: copy sensor info failed", __func__); + return HDF_FAILURE; + } + /* The sensor type ID can be configured in the HCS configuration file or here. */ + drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER; + drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER; + + return HDF_SUCCESS; +} +/* Initialize the sensor register. */ +static int32_t InitAccelAfterConfig(void) +{ + struct SensorDeviceInfo deviceInfo; + + if (InitAccelConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel config failed", __func__); + return HDF_FAILURE; + } + + if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: init accel ops failed", __func__); + return HDF_FAILURE; + } + + if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: add accel device failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} +/* Call the device detection function to hook the differentiated device function. */ +static int32_t DetectAccelChip(void) +{ + int32_t num; + int32_t ret; + int32_t loop; + struct AccelDrvData *drvData = AccelGetDrvData(); + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]); + for (loop = 0; loop < num; ++loop) { + if (g_accelDetectIfList[loop].DetectChip != NULL) { + ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg); + if (ret == HDF_SUCCESS) { + drvData->detectFlag = true; + break; + } + } + } + + if (loop == num) { + HDF_LOGE("%s: detect accel device failed", __func__); + drvData->detectFlag = false; + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +/* The entry function of the acceleration sensor driver is used to initialize the structure object of the sensor private data, allocate space for the HCS data configuration object of the sensor, invoke the entry function for initializing the sensor HCS data configuration, detect whether the sensor device is in position, create the sensor data reporting timer, implement the sensor normalization API, and register the sensor device. */ +int32_t InitAccelDriver(struct HdfDeviceObject *device) +{ + /* Obtain the private data structure object of the sensor. */ + struct AccelDrvData *drvData = AccelGetDrvData(); + + /* When detecting sensors of the same type from different vendors, the function checks whether this type of sensors is in position. If yes, it no longer detects the other sensors of this type and directly returns the result. */ + if (drvData->detectFlag) { + HDF_LOGE("%s: accel sensor have detected", __func__); + return HDF_SUCCESS; + } + + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + /* Allocate space for the private data structure objects for storing sensor data configurations. The allocated space needs to be released when the driver is released. */ + drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg)); + if (drvData->accelCfg == NULL) { + HDF_LOGE("%s: malloc sensor config data failed", __func__); + return HDF_FAILURE; + } + + drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; + /* Initializing the sensor configuration data aims to parse the configuration information of the sensor communication bus, basic sensor information, sensor attributes, whether the sensor is in position, and register group information. */ + if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: get sensor base config failed", __func__); + goto Base_CONFIG_EXIT; + } + + if (DetectAccelChip() != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor detect device no exist", __func__); + goto DETECT_CHIP_EXIT; + } + drvData->detectFlag = true; + if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: detect sensor device failed", __func__); + goto REG_CONFIG_EXIT; + } + + if (InitAccelAfterConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel after config failed", __func__); + goto INIT_EXIT; + } + + HDF_LOGI("%s: init accel driver success", __func__); + return HDF_SUCCESS; + +INIT_EXIT: + DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); +REG_CONFIG_EXIT: + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); +DETECT_CHIP_EXIT: + drvData->detectFlag = false; +BASE_CONFIG_EXIT: + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + return HDF_FAILURE; +} + +/* Release the resources allocated during driver initialization. */ +void ReleaseAccelDriver(struct HdfDeviceObject *device) +{ + (void)device; + struct AccelDrvData *drvData = NULL; + + drvData = AccelGetDrvData(); + (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); + drvData->detectFlag = false; + + if (drvData->accelCfg != NULL) { + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + } + + drvData->initStatus = false; +} +``` + +1. Configure the acceleration sensor register group. + +You only need to configure the acceleration sensor data according to the template. Template configuration parsing has been implemented via the **InitSensorConfigData** function and only needs to be called during initialization. If new configuration items are added, you need to modify this function accordingly. + +``` +Acceleration sensor data configuration template (accel_config.hcs) +root { + sensorAccelConfig { + accelChipConfig { + /* Sensor information template */ + template sensorInfo { + sensorName = "accelerometer"; /* Acceleration sensor name. The value contains a maximum of 16 bytes. */ + vendorName = "borsh_bmi160"; /* Sensor vendor name. The value contains a maximum of 16 bytes. */ + firmwareVersion = "1.0"; /* Sensor firmware version. The default value is 1.0. The value contains a maximum of 16 bytes. */ + hardwareVersion = "1.0"; /* Sensor hardware version. The default value is 1.0. The value contains a maximum of 16 bytes. */ + sensorTypeId = 1; /* Sensor type ID. For details, see SensorTypeTag. */ + sensorId = 1; /* Sensor ID, which is defined by the sensor driver developer. The SensorTypeTag enums are recommended. */ + maxRange = 8; /* Maximum measurement range of the sensor. Set this parameter based on your business requirements. */ + precision = 0; /* Sensor accuracy, which is used together with sensor data reporting. For details, see SensorEvents. */ + power = 230; /* Power consumption of the sensor */ + } + /* Template of the bus type and configuration information used by the sensor */ + template sensorBusConfig { + busType = 0; /* 0:i2c 1:spi */ + busNum = 6; /* Device ID allocated to the sensor on the chip */ + busAddr = 0; /* Address allocated to the sensor on the chip */ + regWidth = 1; /* Width of the sensor register address */ + regBigEndian = 0; /* Endian mode of the sensor register */ + } + /* Sensor attribute template */ + template sensorAttr { + chipName = ""; /* Sensor chip name */ + chipIdRegister = 0xf; /* Address of the register detecting whether the sensor is in position */ + chipIdValue = 0xd1; /* Value of the register detecting whether the sensor is in position */ + } + } + } +} + +/* You can modify the template configuration based on the differences of sensor devices. If no modification is made, the default template configuration is used. */ +root { + sensorAccelConfig { + accel_bmi160_chip_config : accelChipConfig { + match_attr = "hdf_sensor_accel_driver"; /* The value must be the same as the match_attr field configured for the acceleration sensor. */ + accelInfo :: sensorInfo { + vendorName = "borsh_bmi160"; + sensorTypeId = 1; + sensorId = 1; + } + accelBusConfig :: sensorBusConfig { + busType = 0; /* I2C communication mode */ + busNum = 6; + busAddr = 0x68; + regWidth = 1; /* 1-byte bit width */ + } + accelAttr :: sensorAttr { + chipName = "bmi160"; + chipIdRegister = 0x00; + chipIdValue = 0xd1; + } + accelRegConfig { + /* regAddr: Register address + value: Register value + mask: Mask of the register value + len: Length (in bytes) of the register value + delay: Register delay (in milliseconds) + opsType: Operation type. The options can be 0 (no operation), 1 (read), 2 (write), 3 (read and check), and 4 (bit update). + calType: Calculation type. The options can be 0 (none), 1 (write), 2 (negate), 3 (XOR) 4, (left shift), and 5 (right shift). + shiftNum: Number of shifts + debug: Debugging switch. The value can be 0 (disabled) or 1 (enabled). + save: Data saving switch. The value can be 0 (not save data) or 1 (save data). + */ + /* Groups of sensor register operations. Registers can be configured in sequence based on the groups. */ + /* Register address, register value, mask of the register value, data length of the register value, register delay, operation type, calculation type, number of shifts, debugging switch, data saving switch */ + /* Initialize the register groups. */ + initSeqConfig = [ + 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + /* Enable the register groups. */ + enableSeqConfig = [ + 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0, + 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0 + ]; + /* Disable the register groups. */ + disableSeqConfig = [ + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + } + } + } +} +``` + +1. Implement APIs for acceleration sensor driver operations. + +You need to implement normalized APIs based on sensor types. + +``` +/* Leave a function empty if it is not used. */ +static int32_t SetAccelInfo(struct SensorBasicInfo *info) +{ + (void)info; + + return HDF_ERR_NOT_SUPPORT; +} +/* Deliver the configuration of enabling the register groups. */ +static int32_t SetAccelEnable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_RUNNING; + + return HDF_SUCCESS; +} +/* Deliver the configuration of disabling the register groups. */ +static int32_t SetAccelDisable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_STOPPED; + + return HDF_SUCCESS; +} +/* Set the sampling interval and data reporting interval of the sensor. */ +static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval) +{ + (void)interval; + + struct AccelDrvData *drvData = AccelGetDrvData(); + drvData->interval = samplingInterval; + + return HDF_SUCCESS; +} +/* Set the data reporting mode of the sensor. Currently, the real-time mode is supported. */ +static int32_t SetAccelMode(int32_t mode) +{ + return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE; +} +/* Set the sensor options. */ +static int32_t SetAccelOption(uint32_t option) +{ + (void)option; + return HDF_ERR_NOT_SUPPORT; +} +``` + +- Differentiated processing APIs + + ``` + /* If a device is detected, register the differentiated processing function to the accel driver model. */ + int32_t DetectAccelBim160Chip(struct SensorCfgData *data) + { + int32_t ret; + struct AccelOpsCall ops; + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + + if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) { + return HDF_SUCCESS; + } + ret = InitAccelPreConfig(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: init BMI160 bus mux config", __func__); + return HDF_FAILURE; + } + if (DetectSensorDevice(data) != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* Differentiated processing function */ + ops.Init = InitBmi160; + ops.ReadData = ReadBmi160Data; + ret = RegisterAccelChipOps(&ops); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: register BMI160 accel failed", __func__); + (void)ReleaseSensorBusHandle(&data->busCfg); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* Initialization processing function */ + static int32_t InitBmi160(struct SensorCfgData *data) + { + int32_t ret; + + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: bmi160 sensor init config failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* Data processing function */ + int32_t ReadBmi160Data(struct SensorCfgData *data) + { + int32_t ret; + struct AccelData rawData = { 0, 0, 0 }; + int32_t tmp[ACCEL_AXIS_NUM]; + struct SensorReportEvent event; + + (void)memset_s(&event, sizeof(event), 0, sizeof(event)); + + ret = ReadBmi160RawData(data, &rawData, &event.timestamp); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + event.sensorId = SENSOR_TAG_ACCELEROMETER; + event.option = 0; + event.mode = SENSOR_WORK_MODE_REALTIME; + + rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G; + rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G; + rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G; + + tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + + event.dataLen = sizeof(tmp); + event.data = (uint8_t *)&tmp; + ret = ReportSensorEvent(&event); + return ret; + } + ``` + +- Data processing function + +Create a sensor timer to periodically sample data based on the configured sampling interval and report the data to the data subscriber. + +``` +/* Scheduled working thread of the sensor */ +static int32_t ReadAccelDataThreadWorker(void *arg) +{ + (void)arg; + int64_t interval; + struct AccelDrvData *drvData = AccelGetDrvData(); + + drvData->threadStatus = SENSOR_THREAD_START; + while (true) { + if (drvData->threadStatus == SENSOR_THREAD_RUNNING) { + if (drvData->ops.ReadData != NULL) { + (void)drvData->ops.ReadData(drvData->accelCfg); + } + interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT)); + OsalMSleep(interval); + } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) { + break; + } else { + OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT); + } + + if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) { + continue; + } + } + + return HDF_SUCCESS; +} +/* Create a sensor timer and initialize the sensor device. */ +static int32_t InitAccelConfig(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) { + HDF_LOGE("%s: accel thread have created", __func__); + return HDF_SUCCESS; + } + + ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + + CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM); + + ret = drvData->ops.Init(drvData->accelCfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + drvData->initStatus = true; + return HDF_SUCCESS; +} +``` + +- Major data structures + +``` +/* Sensor conversion units */ +#define SENSOR_CONVERT_UNIT 1000 +#define SENSOR_1K_UNIT 1024 +/* Sensitivity conversion value of the sensor with a 2g measurement range */ +#define BMI160_ACC_SENSITIVITY_2G 61 +/* Address of the sensor data sampling register */ +#define BMI160_ACCEL_X_LSB_ADDR 0X12 +#define BMI160_ACCEL_X_MSB_ADDR 0X13 +#define BMI160_ACCEL_Y_LSB_ADDR 0X14 +#define BMI160_ACCEL_Y_MSB_ADDR 0X15 +#define BMI160_ACCEL_Z_LSB_ADDR 0X16 +#define BMI160_ACCEL_Z_MSB_ADDR 0X17 +/* Data dimension of the sensor */ +enum AccelAxisNum { + ACCEL_X_AXIS = 0, + ACCEL_Y_AXIS = 1, + ACCEL_Z_AXIS = 2, + ACCEL_AXIS_NUM = 3, +}; +/* Each dimension of the sensor */ +struct AccelData { + int32_t x; + int32_t y; + int32_t z; +}; +/* Private data structure of the sensor */ +struct AccelDrvData { + bool detectFlag; + uint8_t threadStatus; + uint8_t initStatus; + int64_t interval; + struct SensorCfgData *accelCfg; + struct OsalThread thread; + struct AccelOpsCall ops; +}; +/* Differentiation adaptation function */ +struct AccelOpsCall { + int32_t (*Init)(struct SensorCfgData *data); + int32_t (*ReadData)(struct SensorCfgData *data); +}; +``` + +## Test Guidelines + +After the driver is developed, you can develop self-test cases in the sensor unit test to verify the basic functions of the driver. The developer self-test platform is used as the test environment. + +``` +/* Specify whether to report sensor data. */ +static int32_t g_sensorDataFlag = 0; +/* Retain the address of the sensor interface instance. */ +static const struct SensorInterface *g_sensorDev = nullptr; + +/* Register the data reporting function. */ +static int SensorTestDataCallback(struct SensorEvents *event) +{ + if (event == nullptr) { + return -1; + } + float *data = (float*)event->data; + printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, + event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); + if (*data > 1e-5) { + g_sensorDataFlag = 1; + } + return 0; +} +/* Initialize the sensor interface instance before executing the test cases. */ +void HdfSensorTest::SetUpTestCase() +{ + g_sensorDev = NewSensorInterfaceInstance(); + if (g_sensorDev == nullptr) { + printf("test sensorHdi get Module instace failed\n\r"); + } +} +/* Release case resources. */ +void HdfSensorTest::TearDownTestCase() +{ + if (g_sensorDev != nullptr) { + FreeSensorInterfaceInstance(); + g_sensorDev = nullptr; + } +} +/* Verify the sensor driver. */ +HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) +{ + int32_t sensorInterval = 1000000000; /* Data sampling interval, in nanoseconds */ + int32_t pollTime = 5; /* Data sampling duration, in seconds */ + int32_t accelSensorId = 1; /* Acceleration sensor type ID, which is 1 */ + int32_t count = 0; + int ret; + struct SensorInformation *sensorInfo = nullptr; + + ret = g_sensorDev->Register(SensorTestDataCallback) + EXPECT_EQ(SENSOR_NULL_PTR, ret); + + ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); + EXPECT_EQ(0, ret); + if (sensorInfo == nullptr) { + EXPECT_NE(nullptr, sensorInfo); + return; + } + /* Print the obtained sensor list. */ + for (int i = 0; i < count; i++) { + printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); + } + ret = g_sensorDev->Enable(accelSensorId); + EXPECT_EQ(0, ret); + g_sensorDataFlag = 0; + + ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); + EXPECT_EQ(0, ret); + /* Observe the printed data within the period specified by pollTime. */ + OsalSleep(pollTime); + EXPECT_EQ(1, g_sensorDataFlag); + + ret = g_sensorDev->Disable(accelSensorId); + g_sensorDataFlag = 0; + EXPECT_EQ(0, ret); + + ret = g_sensorDev->Unregister(); + EXPECT_EQ(0, ret); +} +``` + diff --git a/en/device-dev/driver/driver-peripherals-touch-des.md b/en/device-dev/driver/driver-peripherals-touch-des.md new file mode 100644 index 0000000000000000000000000000000000000000..f4bfd35be3cf06492694b92bf2b7711e703a409e --- /dev/null +++ b/en/device-dev/driver/driver-peripherals-touch-des.md @@ -0,0 +1,410 @@ +# TOUCHSCREEN + +- [Overview](#section175431838101617) + - [Available APIs](#section17667171301711) + +- [Development Guidelines](#section65745222184) + - [How to Develop](#section865734181916) + +- [Development Example](#section263714411191) + - [Add the touchscreen driver-related descriptions.](#section18249155619195) + - [Board-level Hardware Configuration and Private Data Configuration](#section3571192072014) + - [Adding the Touchscreen Driver](#section6356758162015) + + +## Overview + +- **Functions of the Touchscreen driver** + + The Touchscreen driver is used to power on its integrated circuit \(IC\), configure and initialize hardware pins, register interrupts, configure Inter-Integrated Circuit \(I2C\) or SPI APIs, set input-related configurations, and download and update firmware. + + +- **Layers of the Touchscreen driver** + + This section describes how to develop the touchscreen driver based on the input driver model. [Figure 1](#fig6251184817261) shows an overall architecture of the touchscreen driver. + + The input driver is developed based on the hardware driver foundation \(HDF\), platform APIs, and operating system abstraction layer \(OSAL\) APIs. It provides hardware driver capabilities through the input Hardware Driver Interfaces \(HDIs\) for upper-layer input services to control the touchscreen. + + +**Figure 1** Architecture of the input driver model +![](figure/architecture-of-the-input-driver-model.png "architecture-of-the-input-driver-model") + +- **Input driver model** + + The input driver model mainly consists of the device manager, common drivers, and chip drivers. The platform data channel provides capabilities for sending data generated by the touchscreen from the kernel to the user space. The driver model adapts to different touchscreen devices and hardware platforms via the configuration file, improving the efficiency of the touchscreen development. The description for each part of the input driver model is as follows: + + - Input device manager: provides input device drivers with the APIs for registering or unregistering input devices and manages the input device list. + + - Input common driver: provides common abstract drivers \(such as the touchscreen common driver\) of various input devices for initializing the board-level hardware, processing hardware interrupts, and registering input devices with the input device manager. + + - Input chip driver: provides different chip drivers of each vendor. You can minimize the workload for the input chip driver development by calling differentiated APIs reserved by the input platform driver. + + - Event hub: provides a unified data reporting channel, which enables input devices to report input events. + + - HDF input config: parses and manages the board-level configuration as well as the private configuration of input devices. + + +- **Advantages of developing drivers based on the HDF** + + The touchscreen driver is developed based on the [HDF](driver-hdf-development.md) and is implemented via calls to the OSAL and platform APIs, including bus APIs and OS native APIs \(such as memory, lock, thread, and timer\). The OSAL and platform APIs hide the differences of underlying hardware, so that the touchscreen driver can be migrated across platforms and OSs. In this regard, you can develop the touchscreen driver only once but deploy it on multiple devices. + + +### Available APIs + +Based on the attributes of the pins, interfaces on the touchscreens can be classified into the following types: + +- Power interfaces +- I/O control interfaces +- Communications interfaces + +**Figure 2** Common pins of the touchscreen +![](figure/common-pins-of-the-touchscreen.png "common-pins-of-the-touchscreen") + +The interfaces shown in the figure are described as follows: + +1. **Power interfaces** + - LDO\_1P8: 1.8 V digital circuits + - LDO\_3P3: 3.3 V analog circuits + + Generally, the touchscreen driver IC is separated from the LCD driver IC. In this case, the touchscreen driver IC requires both 1.8 V and 3.3 V power supplies. Nowadays, the touchscreen driver IC and LCD driver IC can be integrated. Therefore, the touchscreen, requires only the 1.8 V power supply, and the 3.3 V power required internally is supplied by the LCD VSP power \(typical value: 5.5 V\) in the driver IC. + + +2. **I/O control interfaces** + - RESET: reset pin, which is used to reset the driver IC on the host when suspending or resuming the system. + - INT: interrupt pin, which needs to be set to the input direction and pull-up status during driver initialization. After detecting an external touch signal, the driver triggers the interrupt by operating the interrupt pin. The driver reads the touch reporting data in the ISR function. + +3. **Communications interfaces** + - I2C: Since only a small amount of touch data is reported by the touchscreen, I2C is used to transmit the reported data. For details about the I2C protocol and interfaces, see [I2C](drive-platform-i2c-des.md#section1695201514281). + - SPI: In addition to touch reporting data coordinates, some vendors need to obtain basic capacitance data. Therefore, Serial Peripheral Interface \(SPI\) is used to transmit such huge amount of data. For details about the SPI protocol and interfaces, see [SPI](drive-platform-spi-des.md#section71363452477). + + +## Development Guidelines + +Regardless of the OS and system on a chip \(SoC\), the input driver is developed based on the HDF, platform, and OSAL APIs to provide a unified driver model for touchscreen devices. + +- The following uses the touchscreen driver as an example to describe the loading process of the input driver model: + + \(1\) Complete the device description configuration, such as the loading priority, board-level hardware information, and private data, by referring to the existing template. + + \(2\) Load the input device management driver. The input management driver is loaded automatically by the HDF to create and initialize the device manager. + + \(3\) Load the platform driver. The platform driver is loaded automatically by the HDF to parse the board-level configuration, initialize the hardware, and provide the API for registering the touchscreen. + + \(4\) Load the touchscreen driver. The touchscreen driver is loaded automatically by the HDF to instantiate the touchscreen device, parse the private data, and implement differentiated APIs provided by the platform. + + \(5\) Register the instantiated touchscreen device with the platform driver. Then bind this device to the platform driver, and complete touchscreen initialization such as interrupt registration and power-on and power-off. + + \(6\) Instantiate the input device and register it with the input manager after the touchscreen is initialized. + + +### How to Develop + +1. Add the touchscreen driver-related descriptions. + + Currently, the input driver is developed based on the HDF and is loaded and started by the HDF. Register the driver information, such as whether to load the driver and the loading priority in the configuration file. Then, the HDF starts the registered driver modules one by one. For details about the driver configuration, see [Driver Development](driver-hdf-development.md#section1969312275533). + +2. Complete the board-level configuration and private data configuration of the touchscreen. + + Configure the required I/O pins. For example, configure a register for the I2C pin reserved for the touchscreen to use I2C for transmitting data. + +3. Implement differentiated adaptation APIs of the touchscreen. + + Use the platform APIs to perform operations for the reset pins, interrupt pins, and power based on the communications interfaces designed for boards. For details about the GPIO-related operations, see [GPIO](drive-platform-gpio-des.md#section259614242196). + + +## Development Example + +This example describes how to develop the touchscreen driver. + +### Add the touchscreen driver-related descriptions. + +The information about modules of the input driver model is shown as follows and enables the HDF to load the modules in sequence. For details, see [Driver Development](driver-hdf-development.md). + +``` +input :: host { + hostName = "input_host"; + priority = 100; + device_input_manager :: device { + device0 :: deviceNode { + policy = 2; // Publish services externally. + priority = 100; // Loading priority. The input device manager in the input driver has the highest priority. + preload = 0; // Value 0 indicates that the driver is to be loaded, and value 1 indicates the opposite. + permission = 0660; + moduleName = "HDF_INPUT_MANAGER"; + serviceName = "input_dev_manager"; + deviceMatchAttr = ""; + } + } + device_hdf_touch :: device { + device0 :: deviceNode { + policy = 2; + priority = 120; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH"; + serviceName = "event1"; + deviceMatchAttr = "touch_device1"; + } + } + + device_touch_chip :: device { + device0 :: deviceNode { + policy = 0; + priority = 130; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH_SAMPLE"; + serviceName = "hdf_touch_sample_service"; + deviceMatchAttr = "zsj_sample_5p5"; + } + } +} +``` + +### Board-level Hardware Configuration and Private Data Configuration + +The following describes the configuration of the board-level hardware and private data of the touchscreen. You can modify the configuration based on service requirements. + +``` +root { + input_config { + touchConfig { + touch0 { + boardConfig { + match_attr = "touch_device1"; + inputAttr { + inputType = 0; // Value 0 indicates that the input device is a touchscreen. + solutionX = 480; + solutionY = 960; + devName = "main_touch"; // Device name + } + busConfig { + busType = 0; // Value 0 indicates the I2C bus. + busNum = 6; + clkGpio = 86; + dataGpio = 87; + i2cClkIomux = [0x114f0048, 0x403]; // Register configuration of the i2c_clk pin + i2cDataIomux = [0x114f004c, 0x403]; // Register configuration of the i2c_data pin + } + pinConfig { + rstGpio = 3; + intGpio = 4; + rstRegCfg = [0x112f0094, 0x400]; // Register configuration of the reset pin + intRegCfg = [0x112f0098, 0x400]; // Register configuration of the interrupt pin + } + powerConfig { + vccType = 2; // Values 1, 2, and 3 indicate the low-dropout regulator (LDO), GPIO, and PMIC, respectively. + vccNum = 20; // The GPIO number is 20. + vccValue = 1800; // The voltage amplitude is 1800 mV. + vciType = 1; + vciNum = 12; + vciValue = 3300; + } + featureConfig { + capacitanceTest = 0; + gestureMode = 0; + gloverMOde = 0; + coverMode = 0; + chargerMode = 0; + knuckleMode = 0; + } + } + chipConfig { + template touchChip { + match_attr = ""; + chipName = "sample"; + vendorName = "zsj"; + chipInfo = "AAAA11222"; // The first four characters indicate the product name. The fifth and sixth characters indicate the IC model. The last three characters indicate the chip model. + busType = 0; + deviceAddr = 0x5D; + irqFlag = 2; // Values 1 and 2 indicate that the interrupt is triggered on the rising and falling edges, respectively. Values 4 and 8 indicate that the interrupt is triggered by the high and low levels, respectively. + maxSpeed = 400; + chipVersion = 0; + powerSequence { + /* Power-on sequence is described as follows: + [Type, status, direction, delay] + Value 0 indicates the power or pin is empty. Values 1 and 2 indicate the VCC (1.8 V) and VCI (3.3 V) power, respectively. Values 3 and 4 indicate the reset and interrupt pins, respectively. + Values 0 and 1 indicate the power-off or pull-down, and the power-on or pull-up, respectively. Value 2 indicates that no operation is performed. + Values 0 and 1 indicate the input and output directions, respectively. Value 2 indicates that no operation is performed. + Delay time, in milliseconds. + */ + powerOnSeq = [4, 0, 1, 0, + 3, 0, 1, 10, + 3, 1, 2, 60, + 4, 2, 0, 0]; + suspendSeq = [3, 0, 2, 10]; + resumeSeq = [3, 1, 2, 10]; + powerOffSeq = [3, 0, 2, 10, + 1, 0, 2, 20]; + } + } + chip0 :: touchChip { + match_attr = "zsj_sample_5p5"; + chipInfo = "ZIDN45100"; + chipVersion = 0; + } + } + } + } + } +} +``` + +### Adding the Touchscreen Driver + +The following example shows how to implement the differentiated APIs provided by the platform driver to obtain and parse the touchscreen data. You can adjust the development process based on the board and touchscreen in use. + +``` +/* Parse the touch reporting data read from the touchscreen into coordinates. */ +static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) +{ + int32_t resX = device->driver->boardCfg->attr.resolutionX; + int32_t resY = device->driver->boardCfg->attr.resolutionY; + + for (int32_t i = 0; i < pointNum; i++) { + frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].valid = true; + } +} +/* Obtain the touch reporting data from the chip. */ +static int32_t ChipDataHandle(ChipDevice *device) +{ + int32_t ret; + uint8_t touchStatus = 0; + uint8_t pointNum; + uint8_t buf[GT_POINT_SIZE * MAX_SUPPORT_POINT] = {0}; + InputI2cClient *i2cClient = &device->driver->i2cClient; + uint8_t reg[GT_ADDR_LEN] = {0}; + FrameData *frame = &device->driver->frameData; + reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; + ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); + if (ret < 0 || touchStatus == GT_EVENT_INVALID) { + return HDF_FAILURE; + } + OsalMutexLock(&device->driver->mutex); + (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData)); + if (touchStatus == GT_EVENT_UP) { + frame->realPointNum = 0; + frame->definedEvent = TOUCH_UP; + goto exit; + } + reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; + pointNum = touchStatus & GT_FINGER_NUM_MASK; + if (pointNum <= 0 || pointNum > MAX_SUPPORT_POINT) { + HDF_LOGE("%s: pointNum is invalid, %d", __func__, pointNum); + (void)ChipCleanBuffer(i2cClient); + OsalMutexUnlock(&device->driver->mutex); + return HDF_FAILURE; + } + frame->realPointNum = pointNum; + frame->definedEvent = TOUCH_DOWN; + /* Read the touch reporting data from the register. */ + (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); + /* Parse the touch reporting data. */ + ParsePointData(device, frame, buf, pointNum); +exit: + OsalMutexUnlock(&device->driver->mutex); + if (ChipCleanBuffer(i2cClient) != HDF_SUCCESS) { + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static struct TouchChipOps g_sampleChipOps = { + .Init = ChipInit, + .Detect = ChipDetect, + .Resume = ChipResume, + .Suspend = ChipSuspend, + .DataHandle = ChipDataHandle, +}; + +static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device) +{ + TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg)); + if (chipCfg == NULL) { + HDF_LOGE("%s: instance chip config failed", __func__); + return NULL; + } + (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg)); + /* Parse the private configuration of the touchscreen. */ + if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: parse chip config failed", __func__); + OsalMemFree(chipCfg); + chipCfg = NULL; + } + return chipCfg; +} + +static ChipDevice *ChipDeviceInstance(void) +{ + ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice)); + if (chipDev == NULL) { + HDF_LOGE("%s: instance chip device failed", __func__); + return NULL; + } + (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice)); + return chipDev; +} + +static void FreeChipConfig(TouchChipCfg *config) +{ + if (config->pwrSeq.pwrOn.buf != NULL) { + OsalMemFree(config->pwrSeq.pwrOn.buf); + } + if (config->pwrSeq.pwrOff.buf != NULL) { + OsalMemFree(config->pwrSeq.pwrOff.buf); + } + OsalMemFree(config); +} + +static int32_t HdfSampleChipInit(struct HdfDeviceObject *device) +{ + TouchChipCfg *chipCfg = NULL; + ChipDevice *chipDev = NULL; + HDF_LOGE("%s: enter", __func__); + if (device == NULL) { + return HDF_ERR_INVALID_PARAM; + } + /* Parse the private configuration of the touchscreen. */ + chipCfg = ChipConfigInstance(device); + if (chipCfg == NULL) { + return HDF_ERR_MALLOC_FAIL; + } + /* Instantiate the touchscreen device. */ + chipDev = ChipDeviceInstance(); + if (chipDev == NULL) { + goto freeCfg; + } + chipDev->chipCfg = chipCfg; + chipDev->ops = &g_sampleChipOps; + chipDev->chipName = chipCfg->chipName; + chipDev->vendorName = chipCfg->vendorName; + + /* Register the touchscreen device with the platform driver. */ + if (RegisterChipDevice(chipDev) != HDF_SUCCESS) { + goto freeDev; + } + HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName); + return HDF_SUCCESS; + +freeDev: + OsalMemFree(chipDev); +freeCfg: + FreeChipConfig(chipCfg); + return HDF_FAILURE; +} + +struct HdfDriverEntry g_touchSampleChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_SAMPLE", + .Init = HdfSampleChipInit, +}; + +HDF_INIT(g_touchSampleChipEntry); +``` + diff --git a/en/device-dev/driver/driver-peripherals.md b/en/device-dev/driver/driver-peripherals.md new file mode 100644 index 0000000000000000000000000000000000000000..02e7a9e357a6eb7484f8a0eea5a486c3a90b396a --- /dev/null +++ b/en/device-dev/driver/driver-peripherals.md @@ -0,0 +1,11 @@ +# Peripherals + +- **[LCD](driver-peripherals-lcd-des.md)** + +- **[TOUCHSCREEN](driver-peripherals-touch-des.md)** + +- **[Sensor](driver-peripherals-sensor-des.md)** + +- **[WLAN](driver-peripherals-external-des.md)** + + diff --git a/en/device-dev/driver/driver-platform-gpio-des.md b/en/device-dev/driver/driver-platform-gpio-des.md new file mode 100644 index 0000000000000000000000000000000000000000..045a23db3e998a174fd191525fd04742b9ca86a8 --- /dev/null +++ b/en/device-dev/driver/driver-platform-gpio-des.md @@ -0,0 +1,560 @@ +# GPIO + +- [Overview](#section1635911016188) + - [Available APIs](#section17715915181611) + +- [Usage Guidelines](#section259614242196) + - [How to Use](#section103477714216) + - [Determining a GPIO Pin Number](#section370083272117) + - [Using APIs to Operate GPIO Pins](#section13604050132118) + +- [Usage Example](#section25941262111) + +## Overview + +Generally, a general-purpose input/output \(GPIO\) controller manages all GPIO pins by group. Each group of GPIO pins is associated with one or more registers. The GPIO pins are operated by reading data from and writing data to the registers. + +The GPIO APIs define a set of standard functions for performing operations on GPIO pins, including: + +- Setting the pin direction, which can be input or output \(High impedance is not supported currently.\) + +- Reading and writing level values, which can be low or high +- Setting an interrupt service routine \(ISR\) function and interrupt trigger mode for a pin +- Enabling or disabling a pin interrupt + +### Available APIs + +**Table 1** APIs available for the GPIO driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

GPIO read/write

+

GpioRead

+

Reads the level value of a GPIO pin.

+

GpioWrite

+

Writes the level value of a GPIO pin.

+

GPIO settings

+

GpioSetDir

+

Sets the direction for a GPIO pin.

+

GpioGetDir

+

Obtains the direction for a GPIO pin.

+

GPIO interrupt settings

+

GpioSetIrq

+

Sets the ISR function for a GPIO pin.

+

GpioUnSetIrq

+

Cancels the setting of the ISR function for a GPIO pin.

+

GpioEnableIrq

+

Enables a GPIO interrupt.

+

GpioDisableIrq

+

Disables a GPIO interrupt.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All functions provided in this document can be called only in kernel mode. + +## Usage Guidelines + +### How to Use + +The GPIO APIs use the GPIO pin number to specify a pin. [Figure 1](#fig1399416053717) shows the general process of using a GPIO. + +**Figure 1** Process of using a GPIO + + +![](figure/en-us_image_0000001170187071.png) + +### Determining a GPIO Pin Number + +The method for converting GPIO pin numbers varies according to the GPIO controller model, parameters, and controller driver of different system on chips \(SoCs\). + +- Hi3516DV300 + + A controller manages 12 groups of GPIO pins. Each group contains 8 GPIO pins. + + GPIO pin number = GPIO group index \(0-11\) x Number of GPIO pins in each group \(8\) + Offset in the group + + Example: GPIO number of GPIO10\_3 = 10 x 8 + 3 = 83 + +- Hi3518EV300 + + A controller manages 10 groups of GPIO pins. Each group contains 10 GPIO pins. + + GPIO pin number = GPIO group index \(0–9\) x Number of GPIO pins in each group \(10\) + Offset in the group + + Example: GPIO pin number of GPIO7\_3 = 7 x 10 + 3 = 73 + + +### Using APIs to Operate GPIO Pins + +- Set the direction for a GPIO pin. + + Before performing read/write operations on a GPIO pin, call the following function to set the direction: + + int32\_t GpioSetDir\(uint16\_t gpio, uint16\_t dir\); + + **Table 2** Description of GpioSetDir + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

dir

+

Direction to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the direction for a GPIO pin.

+

Negative value

+

Failed to set the direction for a GPIO pin.

+
+ + +- Read or write the level value for a GPIO pin. + + To read the level value of a GPIO pin, call the following function: + + int32\_t GpioRead\(uint16\_t gpio, uint16\_t \*val\); + + **Table 3** Description of GpioRead + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

val

+

Pointer to the level value.

+

Return Value

+

Description

+

0

+

Succeeded in reading the level value.

+

Negative value

+

Failed to read the level value.

+
+ + To write the level value for a GPIO pin, call the following function: + + int32\_t GpioWrite\(uint16\_t gpio, uint16\_t val\); + + **Table 4** Description of GpioWrite + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

val

+

Level value to write.

+

Return Value

+

Description

+

0

+

Succeeded in writing the level value.

+

Negative value

+

Failed to write the level value.

+
+ + Example: + + ``` + int32_t ret; + uint16_t val; + /* Set the output direction for GPIO3. */ + ret = GpioSetDir(3, GPIO_DIR_OUT); + if (ret != 0) { + HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); + return; + } + /* Write the low level GPIO_VAL_LOW for GPIO3. */ + ret = GpioWrite(3, GPIO_VAL_LOW); + if (ret != 0) { + HDF_LOGE("GpioWrite: failed, ret %d\n", ret); + return; + } + /* Set the input direction for GPIO6. */ + ret = GpioSetDir(6, GPIO_DIR_IN); + if (ret != 0) { + HDF_LOGE("GpioSetDir: failed, ret %d\n", ret); + return; + } + /* Read the level value of GPIO6. */ + ret = GpioRead(6, &val); + ``` + + +- Set the ISR function for a GPIO pin. + + To set the ISR function for a GPIO pin, call the following function: + + int32\_t GpioSetIrq\(uint16\_t gpio, uint16\_t mode, GpioIrqFunc func, void \*arg\); + + **Table 5** Description of GpioSetIrq + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

mode

+

Interrupt trigger mode.

+

func

+

ISR function to set.

+

arg

+

Pointer to the parameters passed to the ISR function.

+

Return Value

+

Description

+

0

+

Succeeded in setting the ISR function for a GPIO pin.

+

Negative value

+

Failed to set the ISR function for a GPIO pin.

+
+ + >![](../public_sys-resources/icon-caution.gif) **CAUTION:** + >Only one ISR function can be set for a GPIO pin at a time. If **GpioSetIrq** is called repeatedly, the previous IRS function will be replaced. + + If the ISR function is no longer required, call the following function to cancel the setting: + + int32\_t GpioUnSetIrq\(uint16\_t gpio\); + + **Table 6** Description of GpioUnSetIrq + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

Return Value

+

Description

+

0

+

Succeeded in canceling the ISR function.

+

Negative value

+

Failed to cancel the ISR function.

+
+ + After the ISR function is set, call the following function to enable a GPIO interrupt: + + int32\_t GpioEnableIrq\(uint16\_t gpio\); + + **Table 7** Description of GpioEnableIrq + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

Return Value

+

Description

+

0

+

Succeeded in enabling a GPIO interrupt.

+

Negative value

+

Failed to enable a GPIO interrupt.

+
+ + >![](../public_sys-resources/icon-caution.gif) **CAUTION:** + >The configured ISR function can be responded only after the GPIO interrupt is enabled. + + Use the following function to disable the GPIO interrupt: + + int32\_t GpioDisableIrq\(uint16\_t gpio\); + + **Table 8** Description of GpioDisableIrq + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

Return Value

+

Description

+

0

+

Succeeded in disabling a GPIO interrupt.

+

Negative value

+

Failed to disable a GPIO interrupt.

+
+ + Example: + + ``` + /* ISR function */ + */ + int32_t MyCallBackFunc(uint16_t gpio, void *data) + { + HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); + return 0; + } + + int32_t ret; + /* Set the ISR function to MyCallBackFunc, the parameter to NULL, and the interrupt trigger mode to rising edge. */ + ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); + if (ret != 0) { + HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); + return; + } + + /* Enable an interrupt for GPIO3. */ + ret = GpioEnableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); + return; + } + + /* Disable the interrupt for GPIO3. */ + ret = GpioDisableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); + return; + } + + /* Cancel the ISR function for GPIO3. */ + ret = GpioUnSetIrq(3); + if (ret != 0) { + HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); + return; + } + ``` + + +## Usage Example + +In this example, we test the interrupt trigger of a GPIO pin as follows: Set the ISR function for the pin, set the trigger mode to rising edge and failing edge, write high and low levels to the pin alternately to generate level fluctuation, and observe the execution of the ISR function. + +Select an idle GPIO pin. This example uses a Hi3516D V300 development board and GPIO pin GPIO10\_3, which is numbered GPIO83. + +You can select an idle GPIO pin based on the development board and schematic diagram. + +``` +#include "gpio_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +static uint32_t g_irqCnt; + +/* ISR function */ +static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) +{ + HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); + g_irqCnt++; /* If the ISR function is triggered, the number of global interrupts is incremented by 1. */ + return GpioDisableIrq(gpio); +} + +/* Test case function */ +static int32_t TestCaseGpioIrqEdge(void) +{ + int32_t ret; + uint16_t valRead; + uint16_t mode; + uint16_t gpio = 83; /* Number of the GPIO pin to test */ + uint32_t timeout; + + /* Set the output direction for the pin. */ + ret = GpioSetDir(gpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret); + return ret; + } + + /* Disable the interrupt of the pin. */ + ret = GpioDisableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* Set the ISR function for the pin. The trigger mode is both rising edge and falling edge. */ + mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING; + HDF_LOGE("%s: mode:%0x\n", __func__, mode); + ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* Enable the interrupt for this pin. */ + ret = GpioEnableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret); + (void)GpioUnSetIrq(gpio); + return ret; + } + + g_irqCnt = 0; /* Reset the global counter. */ + timeout = 0; /* Reset the waiting time. */ + /* Wait for the ISR function of this pin to trigger. The timeout duration is 1000 ms. */ + while (g_irqCnt <= 0 && timeout < 1000) { + (void)GpioRead(gpio, &valRead); + (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); + HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout); + OsalMDelay(200); /* wait for irq trigger */ + timeout += 200; + } + (void)GpioUnSetIrq(gpio); + return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; +} +``` + diff --git a/en/device-dev/driver/driver-platform-i2c-des.md b/en/device-dev/driver/driver-platform-i2c-des.md new file mode 100644 index 0000000000000000000000000000000000000000..7b70a9fbd022795d0bdbfd142626fdeecf61346d --- /dev/null +++ b/en/device-dev/driver/driver-platform-i2c-des.md @@ -0,0 +1,426 @@ +# I2C + +- [Overview](#section5361140416) + - [Available APIs](#section459052019177) + +- [Usage Guidelines](#section1695201514281) + - [How to Use](#section1338373417288) + - [Opening an I2C Controller](#section13751110132914) + - [Performing I2C Communication](#section9202183372916) + - [Closing an I2C Controller](#section19481164133018) + +- [Usage Example](#section5302202015300) + +## Overview + +- The Inter-Integrated Circuit \(I2C\) is a simple, bidirectional, and synchronous serial bus that uses merely two wires. +- In an I2C communication, one controller communicates with one or more devices through the serial data line \(SDA\) and serial clock line \(SCL\), as shown in [Figure 1](#fig1135561232714). + +- I2C data transfer must begin with a **START** condition and end with a **STOP** condition. Data is transmitted byte-by-byte from the most significant bit to the least significant bit. +- Each I2C node is recognized by a unique address and can serve as either a controller or a device. When the controller needs to communicate with a device, it writes the device address to the bus through broadcast. A device matching this address sends a response to set up a data transfer channel. + +- The I2C APIs define a set of common functions for I2C data transfer, including: + + - I2C controller management: opening or closing an I2C controller + - I2C message transfer: custom transfer by using a message array + + **Figure 1** Physical connection diagram for I2C + ![](figure/physical-connection-diagram-for-i2c.png "physical-connection-diagram-for-i2c") + + +### Available APIs + +**Table 1** APIs available for the I2C driver + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

I2C controller management

+

I2cOpen

+

Opens an I2C controller.

+

I2cClose

+

Closes an I2C controller.

+

I2C message transfer

+

I2cTransfer

+

Performs a custom transfer.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All functions provided in this document can be called only in kernel mode. + +## Usage Guidelines + +### How to Use + +[Figure 2](#fig166181128151112) illustrates the process of an I2C device. + +**Figure 2** Process of using an I2C device + + +![](figure/en-us_image_0000001123509750.png) + +### Opening an I2C Controller + +Call the following function to open an I2C controller: + +DevHandle I2cOpen\(int16\_t number\); + +**Table 2** Description of I2cOpen + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

number

+

I2C controller ID.

+

Return Value

+

Description

+

NULL

+

Failed to open the I2C controller.

+

Device handle

+

Handle of the I2C controller.

+
+ +This example assumes that the system has eight I2C controllers \(numbered from 0 to 7\) and I2C controller 3 is to open. + +``` +DevHandle i2cHandle = NULL; /* I2C controller handle */ + +/* Open an I2C controller. */ +i2cHandle = I2cOpen(3); +if (i2cHandle == NULL) { + HDF_LOGE("I2cOpen: failed\n"); + return; +} +``` + +### Performing I2C Communication + +Use the following function for message transfer: + +int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\); + +**Table 3** Description of I2cTransfer + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Handle of an I2C controller.

+

msgs

+

Message array of the data to transfer.

+

count

+

Length of the message array.

+

Return Value

+

Description

+

Positive integer

+

Number of message structures that are successfully transmitted.

+

Negative value

+

Failed to perform the message transfer.

+
+ +The type of an I2C message transfer is defined by **I2cMsg**. Each message structure indicates a read or write operation. Multiple read or write operations can be performed by using a message array. + +``` +int32_t ret; +uint8_t wbuff[2] = { 0x12, 0x13 }; +uint8_t rbuff[2] = { 0 }; +struct I2cMsg msgs[2]; /* Custom message array for transfer */ +msgs[0].buf = wbuff; /* Data to write */ +msgs[0].len = 2; /* The length of the data to write is 2. */ +msgs[0].addr = 0x5A; /* The address of the device to write the data is 0x5A. */ +msgs[0].flags = 0; /* The flag is 0, indicating the write operation. */ +msgs[1].buf = rbuff; /* Data to read */ +msgs[1].len = 2; /* The length of the data to read is 2. */ +msgs[1].addr = 0x5A; /* The address of the device to read is 0x5A. */ +msgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ is configured, indicating the read operation. */ +/* Perform a custom transfer to transfer two messages. */ +ret = I2cTransfer(i2cHandle, msgs, 2); +if (ret != 2) { + HDF_LOGE("I2cTransfer: failed, ret %d\n", ret); + return; +} +``` + +>![](../public_sys-resources/icon-caution.gif) **CAUTION:** +>- The device address in the **I2cMsg** structure does not contain the read/write flag bit. The read/write information is transferred by the read/write control bit in the member variable **flags**. +>- The **I2cTransfer** function does not limit the number of message structures, which is determined by the I2C controller. +>- The **I2cTransfer** function does not limit the data length of each message structure, which is determined by the I2C controller. +>- The **I2cTransfer** function may cause the system to sleep and therefore cannot be called in the interrupt context. + +### Closing an I2C Controller + +Call the following function to close the I2C controller after the communication is complete: + +void I2cClose\(DevHandle \*handle\); + +**Table 4** Description of I2cClose + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Handle of an I2C controller.

+
+ +``` +I2cClose(i2cHandle); /* Close the I2C controller. */ +``` + +## Usage Example + +This example describes how to use I2C APIs with an I2C device on a development board. + +This example shows a simple register read/write operation on TouchPad on a Hi3516D V300 development board. The basic hardware information is as follows: + +- SoC: hi3516dv300 + +- Touch IC: The I2C address is 0x38, and the bit width of Touch IC's internal register is 1 byte. + +- Schematic diagram: TouchPad is mounted to I2C controller 3. The reset pin of Touch IC is GPIO3. + +In this example, first we reset Touch IC. \(The development board supplies power to Touch IC by default after being powered on, and this use case does not consider the power supply\). Then, we perform a read/write operation on an internal register to test whether the I2C channel is normal. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The example focuses on I2C device access and verifies the I2C channel. The read and write values of the device register are not concerned. The behavior caused by the read and write operations on the register is determined by the device itself. + +Example: + +``` +#include "i2c_if.h" /* Header file of I2C APIs */ +#include "gpio_if.h" /* Header file of GPIO APIs */ +#include "hdf_log.h" /* Header file for log APIs */ +#include "osal_io.h" /* Header file of I/O read and write APIs */ +#include "osal_time.h" /* Header file of delay and sleep APIs */ + +/* Define a TP device structure to store I2C and GPIO hardware information. */ +struct TpI2cDevice { + uint16_t rstGpio; /* Reset pin */ + uint16_t busId; /* I2C bus ID */ + uint16_t addr; /* I2C device address */ + uint16_t regLen; /* Register bit width */ + DevHandle i2cHandle; /* I2C controller handle */ +}; + +/* I2C pin I/O configuration. For details, see the SoC register manual. */ +#define I2C3_DATA_REG_ADDR 0x112f008c /* Address of the SDA pin configuration register of I2C controller 3 +#define I2C3_CLK_REG_ADDR 0x112f0090 /* Address of the SCL pin configuration register of I2C controller 3 +#define I2C_REG_CFG 0x5f1 /* Configuration values of SDA and SCL pins of I2C controller 3 + +static void TpSocIoCfg(void) +{ + /* Set the I/O function of the two pins corresponding to I2C controller 3 to I2C. */ + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR)); + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR)); +} + +/* Initialize the reset pin of the TP. Pull up the pin for 20 ms, pull down the pin for 50 ms, and then pull up the pin for 20 ms to complete the resetting. */ +static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice) +{ + int32_t ret; + + /* Set the output direction for the reset pin. */ + ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret); + return ret; + } + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst low fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(50); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst high fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + return HDF_SUCCESS; +} + +/* Use I2cTransfer to encapsulate a register read/write auxiliary function. Use flag to indicate the read or write operation. */ +static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen, uint8_t flag) +{ + int index = 0; + unsigned char regBuf[4] = {0}; + struct I2cMsg msgs[2] = {0}; + + /* Perform length adaptation for the single- or dual-byte register. */ + if (tpDevice->regLen == 1) { + regBuf[index++] = regAddr & 0xFF; + } else { + regBuf[index++] = (regAddr >> 8) & 0xFF; + regBuf[index++] = regAddr & 0xFF; + } + + /* Fill in the I2cMsg message structure. */ + msgs[0].addr = tpDevice->addr; + msgs[0].flags = 0; /* The flag is 0, indicating the write operation. */ + msgs[0].len = tpDevice->regLen; + msgs[0].buf = regBuf; + + msgs[1].addr = tpDevice->addr; + msgs[1].flags = (flag == 1)? I2C_FLAG_READ: 0; /* Add the read flag. */ + msgs[1].len = dataLen; + msgs[1].buf = regData; + + if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) { + HDF_LOGE("%s: i2c read err", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +/* TP register read function */ +static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1); +} + +/* TP register write function */ +static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0); +} + +/* Main entry of I2C */ +static int32_t TestCaseI2c(void) +{ + int32_t i; + int32_t ret; + unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC }; + unsigned char bufRead[7] = {0}; + static struct TpI2cDevice tpDevice; + + /* I/O pin function configuration */ + TpSocIoCfg(); + + /* Initialize TP device information. */ + tpDevice.rstGpio = 3; + tpDevice.busId = 3; + tpDevice.addr = 0x38; + tpDevice.regLen = 1; + tpDevice.i2cHandle = NULL; + + /* Initialize the GPIO pin. */ + ret = TestCaseGpioInit(&tpDevice); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: gpio init fail!:%d", __func__, ret); + return ret; + } + + /* Open an I2C controller. */ + tpDevice.i2cHandle = I2cOpen(tpDevice.busId); + if (tpDevice.i2cHandle == NULL) { + HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId); + return -1; + } + + /* Continuously write 7-byte data to register 0xD5 of TP-IC. */ + ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + OsalMSleep(10); + + /* Continuously read 7-byte data from register 0xDO of TP-IC. */ + ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + + HDF_LOGE("%s: tp i2c write&read reg success!", __func__); + for (i = 0; i < 7; i++) { + HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]); + } + + /* Close the I2C controller. */ + I2cClose(tpDevice.i2cHandle); + return ret; +} +``` + diff --git a/en/device-dev/driver/driver-platform-mipidsi-des.md b/en/device-dev/driver/driver-platform-mipidsi-des.md new file mode 100644 index 0000000000000000000000000000000000000000..250a419f0ee64f2364f03478a247bb11c0ff6d90 --- /dev/null +++ b/en/device-dev/driver/driver-platform-mipidsi-des.md @@ -0,0 +1,554 @@ +# MIPI DSI + +- [Overview](#section16806142183217) + - [Available APIs](#section129611916132011) + +- [Usage Guidelines](#section037231715335) + - [How to Use](#section49299119344) + - [Obtains a MIPI DSI device handle.](#section5126155683811) + - [Setting MIPI DSI Configuration Parameters](#section201164274344) + - [Sending/Receiving the Pointer to a Command](#section199401342173415) + - [Releasing the MIPI DSI Device Handle](#section161011610357) + +- [Usage Example](#section17470126123520) + +## Overview + +- The Display Serial Interface \(DSI\) is a specification stipulated by the Mobile Industry Processor Interface \(MIPI\) Alliance, aiming to reduce the cost of display controllers in a mobile device. It defines a serial bus and communication protocol among the host, the source of image data, and the target device. In this way, the DSI can send pixel data or commands to peripherals \(usually LCDs or similar display devices\) in serial mode, or reads information such as status and pixel from the peripherals. + +- MIPI DSI is capable of working in both high speed \(HS\) mode and low power \(LP\) mode. All data lanes can only travel from the DSI host to a peripheral in HS mode, except the first data lane, which can also receive data such as status information and pixels from the peripheral in LP mode. The clock lane is dedicated to transmitting synchronization clock signals in HS mode. +- [Figure 1](#fig1122611461203) shows a simplified DSI interface. Conceptually, a DSI-compliant interface has the same features as interfaces complying with DBI-2 and DPI-2 standards. It sends pixels or commands to a peripheral and can read status or pixel information from the peripheral. The main difference is that the DSI serializes all pixel data, commands, and events that, in traditional interfaces, are conveyed to and from the peripheral on a parallel data bus with additional control signals. + + **Figure 1** DSI transmitting and receiving interface + ![](figure/dsi-transmitting-and-receiving-interface.png "dsi-transmitting-and-receiving-interface") + + +### Available APIs + +**Table 1** APIs for MIPI DSI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

Setting/Obtaining MIPI DSI configuration parameters

+

MipiDsiSetCfg

+

Sets configuration parameters for a MIPI DSI device.

+

MipiDsiGetCfg

+

Obtains configuration parameters of a MIPI DSI device.

+

Obtaining /Releasing device handles

+

MipiDsiOpen

+

Obtains a MIPI DSI device handle.

+

MipiDsiClose

+

Releases a specified MIPI DSI device handle.

+

Setting the LP or HS mode

+

MipiDsiSetLpMode

+

Sets LP mode for a MIPI DSI device.

+

MipiDsiSetHsMode

+

Sets HS mode for a MIPI DSI device.

+

Reading/Sending commands

+

MipiDsiTx

+

Sends a display command set (DCS) command for sending data.

+

MipiDsiRx

+

Receives a DCS command for reading data with the specified length.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All functions described in this document can be called only in kernel space. + +## Usage Guidelines + +### How to Use + +[Figure 2](#fig99821771782) shows the process of using a MIPI DSI device. + +**Figure 2** Process of using a MIPI DSI device + + +![](figure/en-us_image_0000001123514210.png) + +### Obtains a MIPI DSI device handle. + +Before performing MIPI DSI communication, obtain a MIPI DSI device handle by calling **MipiDsiOpen**. This function returns a MIPI DSI device handle with a specified channel ID. + +DevHandle MipiDsiOpen\(uint8\_t id\); + +**Table 2** Description of **MipiDsiOpen** + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

id

+

MIPI DSI channel ID.

+

Return Value

+

Description

+

NULL

+

Failed to receive the specified command.

+

Device handle

+

MIPI DSI device handle with a specified channel ID, whose data type is DevHandle.

+
+ +The following example shows how to obtain a MIPI DSI device handle with the channel ID **0**: + +``` +DevHandle mipiDsiHandle = NULL; /* Device handle */ +chnId = 0; /* MIPI DSI channel ID */ + +/* Obtain the MIPI DSI device handle based on a specified channel ID. */ +mipiDsiHandle = MipiDsiOpen(chnId); +if (mipiDsiHandle == NULL) { + HDF_LOGE("MipiDsiOpen: failed\n"); + return; +} +``` + +### Setting MIPI DSI Configuration Parameters + +- Set MIPI DSI configuration parameters by calling the following function: + +int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\); + +**Table 3** Description of **MipiDsiSetCfg** + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cfg

+

Pointer to MIPI DSI configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in setting MIPI DSI configuration parameters.

+

Negative value

+

Failed to set MIPI DSI configuration parameters.

+
+ +``` +int32_t ret; +struct MipiCfg cfg = {0}; + +/* Configuration parameters of the connected device are as follows: */ +cfg.lane = DSI_4_LANES; +cfg.mode = DSI_CMD_MODE; +cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; +cfg.format = FORMAT_RGB_24_BIT; +cfg.pixelClk = 174; +cfg.phyDataRate = 384; +cfg.timingInfo.hsaPixels = 50; +cfg.timingInfo.hbpPixels = 55; +cfg.timingInfo.hlinePixels = 1200; +cfg.timingInfo.yResLines = 1800; +cfg.timingInfo.vbpLines = 33; +cfg.timingInfo.vsaLines = 76; +cfg.timingInfo.vfpLines = 120; +cfg.timingInfo.xResPixels = 1342; +/* Set MIPI DSI configuration parameters. */ +ret = MipiDsiSetCfg(g_handle, &cfg); +if (ret != 0) { + HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); + return -1; +} +``` + +- Obtain MIPI DSI configuration parameters by calling the following function: + +int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); + +**Table 4** Description of **MipiDsiGetCfg** + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cfg

+

Pointer to MIPI DSI configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in receiving the specified command.

+

Negative value

+

Failed to receive the specified command.

+
+ +``` +int32_t ret; +struct MipiCfg cfg; +memset(&cfg, 0, sizeof(struct MipiCfg)); +ret = MipiDsiGetCfg(g_handle, &cfg); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); + return HDF_FAILURE; +} +``` + +### Sending/Receiving the Pointer to a Command + +- Send the pointer to a specified command by calling the following function: + +int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); + +**Table 5** Description of **MipiDsiTx** + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cmd

+

Pointer to the command to be sent.

+

Return Value

+

Description

+

0

+

Succeeded in sending the specified command.

+

Negative value

+

Failed to send the specified command.

+
+ +``` +int32_t ret; +struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); +if (cmd == NULL) { + return HDF_FAILURE; +} +cmd->dtype = DTYPE_DCS_WRITE; +cmd->dlen = 1; +cmd->payload = OsalMemCalloc(sizeof(uint8_t)); +if (cmd->payload == NULL) { + HdfFree(cmd); + return HDF_FAILURE; +} +*(cmd->payload) = DTYPE_GEN_LWRITE; +MipiDsiSetLpMode(mipiHandle); +ret = MipiDsiTx(mipiHandle, cmd); +MipiDsiSetHsMode(mipiHandle); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret); + HdfFree(cmd->payload); + HdfFree(cmd); + return HDF_FAILURE; +} +HdfFree(cmd->payload); +HdfFree(cmd); +``` + +- Receive a specified command by calling the following function: + +int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); + +**Table 6** Description of **MipiDsiRx** + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cmd

+

Pointer to the command to be received.

+

readLen

+

Length of the data to read.

+

out

+

Pointer to the read data.

+

Return Value

+

Description

+

0

+

Succeeded in receiving the specified command.

+

Negative value

+

Failed to receive the specified command.

+
+ +``` +int32_t ret; +uint8_t readVal = 0; + +struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); +if (cmdRead == NULL) { + return HDF_FAILURE; +} +cmdRead->dtype = DTYPE_DCS_READ; +cmdRead->dlen = 1; +cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); +if (cmdRead->payload == NULL) { + HdfFree(cmdRead); + return HDF_FAILURE; +} +*(cmdRead->payload) = DDIC_REG_STATUS; +MipiDsiSetLpMode(g_handle); +ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); +MipiDsiSetHsMode(g_handle); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + return HDF_FAILURE; +} +HdfFree(cmdRead->payload); +HdfFree(cmdRead); +``` + +### Releasing the MIPI DSI Device Handle + +After the MIPI DSI communication, release the MIPI DSI device handle by calling the following function: + +void MipiDsiClose\(DevHandle handle\); + +This function releases the resources requested by **MipiDsiOpen**. + +**Table 7** Description of **MipiDsiClose** + + + + + + + + + + +

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+
+ +``` +MipiDsiClose(mipiHandle); /* Release the MIPI DSI device handle */ +``` + +## Usage Example + +The following is an example of using a MIPI DSI device: + +``` +#include "hdf.h" +#include "mipi_dsi_if.h" + +void PalMipiDsiTestSample(void) +{ + uint8_t chnId; + int32_t ret; + DevHandle handle = NULL; + + /* Device channel ID */ + chnId = 0; + /* Obtain the MIPI DSI device handle based on a specified channel ID. */ + handle = MipiDsiOpen(chnId); + if (handle == NULL) { + HDF_LOGE("MipiDsiOpen: failed!\n"); + return; + } + /* MIPI DSI configuration parameters */ + struct MipiCfg cfg = {0}; + cfg.lane = DSI_4_LANES; + cfg.mode = DSI_CMD_MODE; + cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; + cfg.format = FORMAT_RGB_24_BIT; + cfg.pixelClk = 174; + cfg.phyDataRate = 384; + cfg.timingInfo.hsaPixels = 50; + cfg.timingInfo.hbpPixels = 55; + cfg.timingInfo.hlinePixels = 1200; + cfg.timingInfo.yResLines = 1800; + cfg.timingInfo.vbpLines = 33; + cfg.timingInfo.vsaLines = 76; + cfg.timingInfo.vfpLines = 120; + cfg.timingInfo.xResPixels = 1342; + /* Set MIPI DSI configuration parameters. */ + ret = MipiDsiSetCfg(g_handle, &cfg); + if (ret != 0) { + HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); + return; + } + /* Send the command for initializing the PANEL register. */ + struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmd == NULL) { + return; + } + cmd->dtype = DTYPE_DCS_WRITE; + cmd->dlen = 1; + cmd->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmd->payload == NULL) { + HdfFree(cmd); + return; + } + *(cmd->payload) = DTYPE_GEN_LWRITE; + MipiDsiSetLpMode(mipiHandle); + ret = MipiDsiTx(mipiHandle, cmd); + MipiDsiSetHsMode(mipiHandle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret); + HdfFree(cmd->payload); + HdfFree(cmd); + return; + } + HdfFree(cmd->payload); + HdfFree(cmd); + /* Pointer to the register that reads the PANEL status */ + uint8_t readVal = 0; + struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmdRead == NULL) { + return; + } + cmdRead->dtype = DTYPE_DCS_READ; + cmdRead->dlen = 1; + cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmdRead->payload == NULL) { + HdfFree(cmdRead); + return; + } + *(cmdRead->payload) = DDIC_REG_STATUS; + MipiDsiSetLpMode(g_handle); + ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); + MipiDsiSetHsMode(g_handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + return; + } + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + /* Release the MIPI DSI device handle. */ + MipiDsiClose(handle); +} +``` + diff --git a/en/device-dev/driver/driver-platform-rtc-des.md b/en/device-dev/driver/driver-platform-rtc-des.md new file mode 100644 index 0000000000000000000000000000000000000000..66e8a08cf14f76bd8e32165491c4387567db8f66 --- /dev/null +++ b/en/device-dev/driver/driver-platform-rtc-des.md @@ -0,0 +1,944 @@ +# RTC + +- [Overview](#section104842041574) + - [Available APIs](#section3373340142215) + +- [Usage Guidelines](#section20636145604113) + - [How to Use](#section16919828134215) + - [Creating an RTC Device Handle](#section1131212144310) + - [Releasing the RTC Device Handle](#section10744117144314) + - [Registering RtcAlarmCallback](#section14839440184320) + - [Performing RTC-related Operations](#section161927578433) + +- [Usage Example](#section1186111020456) + +## Overview + +The real-time clock \(RTC\) driver provides precise real time for the operating system \(OS\). If the OS is powered off, the RTC driver continues to keep track of the system time using an external battery. + +### Available APIs + +**Table 1** APIs provided by the RTC driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

RTC handle

+

RtcOpen

+

Opens the RTC device to obtain its handle.

+

RtcClose

+

Releases a specified handle of the RTC device.

+

RTC time

+

RtcReadTime

+

Reads time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.

+

RtcWriteTime

+

Writes time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.

+

RTC alarm

+

RtcReadAlarm

+

Reads the RTC alarm time that was set last time.

+

RtcWriteAlarm

+

Writes the RTC alarm time based on the alarm index.

+

RtcRegisterAlarmCallback

+

Registers RtcAlarmCallback that will be invoked when an alarm is generated at the specified time.

+

RtcAlarmInterruptEnable

+

Enables or disables RTC alarm interrupts.

+

RTC configuration

+

RtcGetFreq

+

Reads the frequency of the external crystal oscillator connected to the RTC driver.

+

RtcSetFreq

+

Sets the frequency of the external crystal oscillator connected to the RTC driver.

+

RtcReset

+

Resets the RTC.

+

Custom register

+

RtcReadReg

+

Reads the configuration of a custom RTC register based on the register index.

+

RtcWriteReg

+

Writes the configuration of a custom RTC register based on the register index.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All functions provided in this document can be called only in kernel mode. + +## Usage Guidelines + +### How to Use + +During the OS startup, the HDF loads the RTC driver based on the configuration file. The RTC driver detects the RTC component and initializes the driver. + +[Figure 1](#fig166181128151112) illustrates the process of using an RTC device. + +**Figure 1** Process of using an RTC device + + +![](figure/en-us_image_0000001123675706.png) + +### Creating an RTC Device Handle + +After the RTC driver is loaded, you can use the API provided by the HDF and call APIs of the RTC driver. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Currently, only one RTC device is supported in the OS. + +DevHandle RtcOpen\(void\); + +**Table 2** Description of RtcOpen + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

void

+

NA

+

Return Value

+

Description

+

handle

+

Returns the if the operation is successful.

+

NULL

+

The operation fails.

+
+ +``` +DevHandle handle = NULL; + +/* Obtain the RTC device handle. */ +handle = RtcOpen(); +if (handle == NULL) { + /* Process the error. */ +} +``` + +### Releasing the RTC Device Handle + +You can call the following function to release the RTC device handle, thereby releasing resources of the device: + +void RtcClose\(DevHandle handle\); + +**Table 3** Description of RtcClose + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+
+ +``` +/* Release the RTC device handle. */ +RtcClose(handle); +``` + +### Registering RtcAlarmCallback + +After the OS is started, call the following function to register **RtcAlarmCallback**, which will be invoked when an alarm is generated at the specified time: + +int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\); + +**Table 4** Description of RtcRegisterAlarmCallback + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

cb

+

Callback that will be invoked when an alarm is generated at the specified time.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +The following is an example of registering **RtcAlarmCallback** for processing alarm **RTC\_ALARM\_INDEX\_A**: + +``` +/* Register an RTC alarm callback. */ +int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) +{ + if (alarmIndex == RTC_ALARM_INDEX_A) { + /* Process alarm A. */ + } else if (alarmIndex == RTC_ALARM_INDEX_B) { + /* Process alarm B. */ + } else { + /* Process the error. */ + } + return 0; +} +int32_t ret; +/* Register RtcAlarmCallback for alarm A. */ +ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); +if (ret != 0) { + /* Process the error. */ +} +``` + +### Performing RTC-related Operations + +- Reading RTC time + +Call the following function to read time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond: + +int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\); + +**Table 5** Description of RtcReadTime + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

time

+

Pointer to the time information read from the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; +struct RtcTime tm; + +/* Read time information from the RTC driver. */ +ret = RtcReadTime(handle, &tm); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Setting RTC time + +Call the following function to set the RTC time: + +int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\); + +**Table 6** Description of RtcWriteTime + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

time

+

Pointer to the time information written into the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week. + +``` +int32_t ret; +struct RtcTime tm; + +/* Set the RTC time to UTC 2020/01/01 00:59:00 .000. */ +tm.year = 2020; +tm.month = 01; +tm.day = 01; +tm.hour= 00; +tm.minute = 59; +tm.second = 00; +tm.millisecond = 0; +/* Write the RTC time information. */ +ret = RtcWriteTime(handle, &tm); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Reading the RTC alarm time + +Call the following function to read the alarm time: + +int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); + +**Table 7** Description of RtcReadAlarm + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

time

+

Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; +struct RtcTime alarmTime; + +/* Read the RTC alarm time information of alarm RTC_ALARM_INDEX_A. */ +ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Setting RTC alarm time + +Call the following function to set the RTC alarm time based on the alarm index: + +int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); + +**Table 8** Description of RtcWriteAlarm + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

time

+

Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week. + +``` +int32_t ret; +struct RtcTime alarmTime; + +/* Set the RTC alarm time to 2020/01/01 00:59:59 .000. */ +alarmTime.year = 2020; +alarmTime.month = 01; +alarmTime.day = 01; +alarmTime.hour = 00; +alarmTime.minute = 59; +alarmTime.second = 59; +alarmTime.millisecond = 0; +/* Set the alarm time of alarm RTC_ALARM_INDEX_A. */ +ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Enabling or disabling alarm interrupts + +Before performing alarm operations, use the following function to enable alarm interrupts, so that **RtcAlarmCallback** will be called when the alarm is not generated upon a timeout: + +int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\); + +**Table 9** Description of RtcAlarmInterruptEnable + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

enable

+

Whether to enable RTC alarm interrupts. The value 1 means to enable alarm interrupts and 0 means to disable alarm interrupts.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; + +/* Enable the RTC alarm interrupts. */ +ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Reading RTC external frequency + +Call the following function to read the frequency of the external crystal oscillator connected to the RTC driver: + +int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\); + +**Table 10** Description of RtcGetFreq + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

freq

+

Pointer to the frequency to set for the external crystal oscillator, in Hz.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; +uint32_t freq = 0; + +/* Read frequency of the external crystal oscillator connected to the RTC driver */ +ret = RtcGetFreq(handle, &freq); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Setting the frequency of the external crystal oscillator connected to the RTC driver + +Call the following function to set the frequency of the external crystal oscillator connected to the RTC driver: + +int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\); + +**Table 11** Description of RtcSetFreq + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

freq

+

Frequency to set for the external crystal oscillator, in Hz

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; +uint32_t freq = 32768; /* 32768 Hz */ + +/* Set the frequency of the external crystal oscillator. Note that the frequency must be configured in accordance with the requirements specified in the product manual of the in-use component. */ +ret = RtcSetFreq(handle, freq); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Resetting the RTC driver + +Call the following function to perform a reset on the RTC driver \(after the reset, the registers are restored to the default values\): + +int32\_t RtcReset\(DevHandle handle\); + +**Table 12** Description of RtcReset + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; + +/* Reset the RTC driver. After the reset, the configuration registers are restored to the default values. */ +ret = RtcReset(handle); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Reading the configuration of a custom RTC register + +Call the following function to read the configuration of a custom RTC register based on the register index \(one index corresponds to one byte of the configuration value\): + +int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\); + +**Table 13** Description of RtcReadReg + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

usrDefIndex

+

Index of the custom register

+

value

+

Pointer to the register value

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; +uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ +uint8_t value = 0; + +/* Read the configuration of a custom RTC register based on the register index. One index corresponds to one byte of the configuration value. */ +ret = RtcReadReg(handle, usrDefIndex, &value); +if (ret != 0) { + /* Process the error. */ +} +``` + +- Setting the configuration of a custom RTC register + +Call the following function to configure a register based on the specified register index \(one index corresponds to one byte of the configuration value\): + +int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\); + +**Table 14** Description of RtcWriteReg + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

RTC device handle.

+

usrDefIndex

+

Index of the custom register

+

value

+

Register value

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

+
+ +``` +int32_t ret; +uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ +uint8_t value = 0x10; + +/* Configure a register based on the specified register index. One index corresponds to one byte of the configuration value. */ +ret = RtcWriteReg(handle, usrDefIndex, value); +if (ret != 0) { + /* Process the error. */ +} +``` + +## Usage Example + +This section describes the process of using RTC APIs: + +1. During the OS startup, the HDF identifies the RTC component in the system. +2. The HDF initializes and creates the RTC device. +3. You can perform operations on the RTC device by calling different APIs. +4. Call the **RtcClose** function to release the device handle and device resources. + +Example: + +``` +#include "rtc_if.h" +int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) +{ + if (alarmIndex == RTC_ALARM_INDEX_A) { + /* Process alarm A. */ + printf("RTC Alarm A callback function\n\r"); + } else if (alarmIndex == RTC_ALARM_INDEX_B) { + /* Process alarm B. */ + printf("RTC Alarm B callback function\n\r"); + } else { + /* Process the error. */ + } + return 0; +} + +void RtcTestSample(void) +{ + int32_t ret; + struct RtcTime tm; + struct RtcTime alarmTime; + uint32_t freq; + DevHandle handle = NULL; + + /* Obtain the RTC device handle. */ + handle = RtcOpen(); + if (handle == NULL) { + /* Process the error. */ + } + /* Register RtcAlarmCallback for alarm A. */ + ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); + if (ret != 0) { + /* Process the error. */ + } + /* Set the RTC external crystal frequency. Note that the frequency must be configured in accordance with the requirements specified in the product manual of the in-use component. */ + freq = 32768; /* 32768 Hz */ + ret = RtcSetFreq(handle, freq); + if (ret != 0) { + /* Process the error. */ + } + /* Enable the RTC alarm interrupts. */ + ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); + if (ret != 0) { + /* Process the error. */ + } + /* Set the RTC time to 2020/01/01 00:00:10 .990. */ + tm.year = 2020; + tm.month = 01; + tm.day = 01; + tm.hour= 0; + tm.minute = 0; + tm.second = 10; + tm.millisecond = 990; + /* Write the RTC time information. */ + ret = RtcWriteTime(handle, &tm); + if (ret != 0) { + /* Process the error. */ + } + /* Set the RTC alarm time to 2020/01/01 00:00:30 .100. */ + alarmTime.year = 2020; + alarmTime.month = 01; + alarmTime.day = 01; + alarmTime.hour = 0; + alarmTime.minute = 0; + alarmTime.second = 30; + alarmTime.millisecond = 100; + /* Set the alarm time information for RTC_ALARM_INDEX_A. When the specified time is reached, "RTC Alarm A callback function" is printed. */ + ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); + if (ret != 0) { + /* Process the error. */ + } + + /* Read the RTC real time. */ + ret = RtcReadTime(handle, &tm); + if (ret != 0) { + /* Process the error. */ + } + sleep(5) + printf("RTC read time:\n\r"); + printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", + tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); + /* Release the RTC device handle. */ + RtcClose(handle); +} +``` + diff --git a/en/device-dev/driver/driver-platform-sdio-des.md b/en/device-dev/driver/driver-platform-sdio-des.md new file mode 100644 index 0000000000000000000000000000000000000000..4b5a27d35334ab5e75cbf0ea3cddffd9fd9341d3 --- /dev/null +++ b/en/device-dev/driver/driver-platform-sdio-des.md @@ -0,0 +1,1068 @@ +# SDIO + +- [Overview](#section1155271783811) + - [Available APIs](#section08064247248) + +- [Usage Guidelines](#section1878939192515) + - [How to Use](#section1490685512255) + - [Opening an SDIO Controller](#section10782428132616) + - [Claiming a Host Exclusively](#section11263172312715) + - [Enabling the SDIO Device](#section17861486271) + - [Claiming an SDIO IRQ](#section521213262286) + - [Performing SDIO Communication](#section85661522153420) + - [Releasing the SDIO IRQ](#section1683449352) + - [Disabling the SDIO Device](#section15379324143611) + - [Releasing the Exclusively Claimed Host](#section536018263713) + - [Closing an SDIO Controller](#section4752739183716) + +- [Usage Example](#section376910122382) + +## Overview + +- Secure Digital Input/Output \(SDIO\) is a peripheral interface evolved from the Secure Digital \(SD\) memory card interface. The SDIO interface is compatible with SD memory cards and can be connected to devices that support the SDIO interface. +- SDIO is widely used. Currently, many smartphones support SDIO, and many SDIO peripherals are developed for connections to smartphones. Common SDIO peripherals include WLAN, GPS, cameras, and Bluetooth. +- The SDIO bus has two ends, named host and device. All communication starts when the host sends a command. The device can communicate with the host as long as it can parse the command of the host. An SDIO host can connect to multiple devices, as shown in the figure below. + + - CLK signal: clock signal sent from the host to the device + - VDD signal: power signal + - VSS signal: ground signal + - D0-3 signal: four data lines. The DAT1 signal cable is multiplexed as the interrupt line. In 1-bit mode, DAT0 is used to transmit data. In 4-bit mode, DAT0 to DAT3 are used to transmit data. + - CMD signal: used by the host to send commands and the device to respond to commands. + + **Figure 1** Connections between the host and devices in SDIO + + + ![](figure/en-us_image_0000001054280608.png) + +- The SDIO interface defines a set of common methods for operating an SDIO device, including opening and closing an SDIO controller, exclusively claiming and releasing the host, enabling and disabling devices, claiming and releasing an SDIO IRQ, reading and writing data based on SDIO, and obtaining and setting common information. + +### Available APIs + +**Table 1** APIs available for the SDIO driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

SDIO device opening/closing

+

SdioOpen

+

Opens an SDIO controller with a specified bus number.

+

SdioClose

+

Closes an SDIO controller.

+

SDIO reading/writing

+

SdioReadBytes

+

Incrementally reads a given length of data from a specified SDIO address.

+

SdioWriteBytes

+

Incrementally writes a given length of data into a specified SDIO address.

+

SdioReadBytesFromFixedAddr

+

Reads a given length of data from a fixed SDIO address.

+

SdioWriteBytesToFixedAddr

+

Writes a given length of data into a fixed SDIO address.

+

SdioReadBytesFromFunc0

+

Reads a given length of data from the address space of SDIO function 0.

+

SdioWriteBytesToFunc0

+

Writes a given length of data into the address space of SDIO function 0.

+

SDIO block size setting

+

SdioSetBlockSize

+

Sets the block size.

+

SDIO common information retrieval/setting

+

SdioGetCommonInfo

+

Obtains common information.

+

SdioSetCommonInfo

+

Sets common information.

+

SDIO data flushing

+

SdioFlushData

+

Flushes data.

+

SDIO host exclusively claiming or releasing

+

SdioClaimHost

+

Claims a host exclusively.

+

SdioReleaseHost

+

Releases the exclusively claimed host.

+

SDIO device enablement

+

SdioEnableFunc

+

Enables an SDIO device.

+

SdioDisableFunc

+

Disables an SDIO device.

+

SDIO IRQ claiming/releasing

+

SdioClaimIrq

+

Claims an SDIO IRQ.

+

SdioReleaseIrq

+

Releases an SDIO IRQ.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All functions provided in this document can be called only in kernel mode. + +## Usage Guidelines + +### How to Use + +[Figure 2](#fig1343742311264) illustrates the process of using an SDIO. + +**Figure 2** Process of using an SDIO + + +![](figure/en-us_image_0000001123540984.png) + +### Opening an SDIO Controller + +Before performing SDIO communication, obtain the device handle of an SDIO controller by calling **SdioOpen**. This function returns the device handle of the SDIO controller with a specified bus number. + +DevHandle SdioOpen\(int16\_t mmcBusNum, struct SdioFunctionConfig \*config\); + +**Table 2** Parameters and return values of SdioOpen + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

mmcBusNum

+

Bus number.

+

config

+

SDIO functionality configurations.

+

Return Value

+

Description

+

NULL

+

Failed to obtain the device handle of an SDIO controller.

+

Device handle

+

Device handle of an SDIO controller.

+
+ +The following example shows how to open an SDIO controller. + +``` +DevHandle handle = NULL; +struct SdioFunctionConfig config; +config.funcNr = 1; +config.vendorId = 0x123; +config.deviceId = 0x456; +/* Open an SDIO controller whose bus number is 1. */ +handle = SdioOpen(1, &config); +if (handle == NULL) { + HDF_LOGE("SdioOpen: failed!\n"); +} +``` + +### Claiming a Host Exclusively + +After obtaining the device handle of an SDIO controller, exclusively claim the host before performing subsequent operations on the SDIO device. + +void SdioClaimHost\(DevHandle handle\); + +**Table 3** Parameter description of SdioClaimHost + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+
+ +The following example shows how to exclusively claim a host. + +``` +SdioClaimHost(handle); /* Claim a host exclusively. */ +``` + +### Enabling the SDIO Device + +Before accessing a register, enable the SDIO device. + +int32\_t SdioEnableFunc\(DevHandle handle\); + +**Table 4** Parameters and return values of SdioEnableFunc + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

Return Value

+

Description

+

0

+

The SDIO device is enabled.

+

Negative value

+

Failed to enable the SDIO device.

+
+ +The following example shows how to enable the SDIO device. + +``` +int32_t ret; +/* Enable the SDIO device. */ +ret = SdioEnableFunc(handle); +if (ret != 0) { + HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); +} +``` + +### Claiming an SDIO IRQ + +Before SDIO communication, claim an SDIO IRQ. + +int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\); + +**Table 5** Parameters and return values of SdioClaimIrq + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

handler

+

Pointer to the SDIO IRQ function.

+

Return Value

+

Description

+

0

+

The SDIO IRQ is claimed.

+

Negative value

+

Failed to claim an SDIO IRQ.

+
+ +The following example shows how to claim an SDIO IRQ. + +``` +/* Implement the SDIO IRQ function based on the application. */ +static void SdioIrqFunc(void *data) +{ + if (data == NULL) { + HDF_LOGE("SdioIrqFunc: data is NULL.\n"); + return; + } + /* You need to add specific implementations. */ +} + +int32_t ret; +/* Claim an SDIO IRQ. */ +ret = SdioClaimIrq(handle, SdioIrqFunc); +if (ret != 0) { + HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); +} +``` + +### Performing SDIO Communication + +- Incrementally write a given length of data into the SDIO device. + +The corresponding function is as follows: + +int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**Table 6** Parameters and return values of SdioWriteBytes + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to write.

+

addr

+

Start address where the data is written into.

+

size

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Data is written into the SDIO device.

+

Negative value

+

Failed to write data into the SDIO device.

+
+ +The following example shows how to incrementally write a given length of data into the SDIO device. + +``` +int32_t ret; +uint8_t wbuff[] = {1,2,3,4,5}; +uint32_t addr = 0x100 + 0x09; +/* Incrementally write 5-byte data into the start address 0x109 of the SDIO device. */ +ret = SdioWriteBytes(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0])); +if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); +} +``` + +- Incrementally read a given length of data from the SDIO device. + +The corresponding function is as follows: + +int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**Table 7** Parameters and return values of SdioReadBytes + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to read.

+

addr

+

Start address where the data is read from.

+

size

+

Length of the data to read.

+

Return Value

+

Description

+

0

+

Data is read from the SDIO device.

+

Negative value

+

Failed to read data from the SDIO device.

+
+ +The following example shows how to incrementally read a given length of data from the SDIO device. + +``` +int32_t ret; +uint8_t rbuff[5] = {0}; +uint32_t addr = 0x100 + 0x09; +/* Incrementally read 5-byte data from the start address 0x109 of the SDIO device. */ +ret = SdioReadBytes(handle, rbuff, addr, 5); +if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); +} +``` + +- Write a given length of data into the fixed address of an SDIO device. + + The corresponding function is as follows: + + int32\_t SdioWriteBytesToFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); + + **Table 8** Parameters and return values of SdioWriteBytesToFixedAddr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to write.

+

addr

+

Fixed address where the data is written into.

+

size

+

Length of the data to write.

+

scatterLen

+

Length of the scatter list. If the value is not 0, the data is of the scatter list type.

+

Return Value

+

Description

+

0

+

Data is written into the SDIO device.

+

Negative value

+

Failed to write data into the SDIO device.

+
+ + The following example shows how to write a given length of data into the fixed address of an SDIO device. + + ``` + int32_t ret; + uint8_t wbuff[] = {1, 2, 3, 4, 5}; + uint32_t addr = 0x100 + 0x09; + /* Write 5-byte data into the fixed address 0x109 of the SDIO device. */ + ret = SdioWriteBytesToFixedAddr(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0]), 0); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); + } + ``` + +- Read a given length of data from the fixed address of an SDIO device. + + The corresponding function is as follows: + + int32\_t SdioReadBytesFromFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); + + **Table 9** Parameters and return values of SdioReadBytesFromFixedAddr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to read.

+

addr

+

Start address where the data is read from.

+

size

+

Length of the data to read.

+

scatterLen

+

Length of the scatter list. If the value is not 0, the data is of the scatter list type.

+

Return Value

+

Description

+

0

+

Data is read from the SDIO device.

+

Negative value

+

Failed to read data from the SDIO device.

+
+ + The following example shows how to read a given length of data from the fixed address of an SDIO device. + + ``` + int32_t ret; + uint8_t rbuff[5] = {0}; + uint32_t addr = 0x100 + 0x09; + /* Read 5-byte data from the fixed address 0x109 of the SDIO device. */ + ret = SdioReadBytesFromFixedAddr(handle, rbuff, addr, 5, 0); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); + } + ``` + + +- Writes a given length of data into the address space of SDIO function 0. + +Currently, only 1-byte data can be written. The corresponding function is as follows: + +int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**Table 10** Parameters and return values of SdioWriteBytesToFunc0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to write.

+

addr

+

Start address where the data is written into.

+

size

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Data is written into the SDIO device.

+

Negative value

+

Failed to write data into the SDIO device.

+
+ +The following example shows how to write a given length of data into the address space of SDIO function 0. + +``` +int32_t ret; +uint8_t wbuff = 1; +/* Write 1-byte data into the address 0x2 of SDIO function 0. */ +ret = SdioWriteBytesToFunc0(handle, &wbuff, 0x2, 1); +if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); +} +``` + +- Reads a given length of data from the address space of SDIO function 0. + +Currently, only 1-byte data can be read. The corresponding function is as follows: + +int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**Table 11** Parameters and return values of SdioReadBytesFromFunc0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to read.

+

addr

+

Start address where the data is read from.

+

size

+

Length of the data to read.

+

Return Value

+

Description

+

0

+

Data is read from the SDIO device.

+

Negative value

+

Failed to read data from the SDIO device.

+
+ +The following example shows how to read a given length of data from the address space of SDIO function 0. + +``` +int32_t ret; +uint8_t rbuff; +/* Read 1-byte data from the address 0x2 of SDIO function 0. */ +ret = SdioReadBytesFromFunc0(handle, &rbuff, 0x2, 1); +if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); +} +``` + +### Releasing the SDIO IRQ + +After the SDIO communication, release the SDIO IRQ. + +int32\_t SdioReleaseIrq\(DevHandle handle\); + +**Table 12** Parameters and return values of SdioReleaseIrq + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

Return Value

+

Description

+

0

+

The SDIO IRQ is released.

+

Negative value

+

Failed to release the SDIO IRQ.

+
+ +The following example shows how to release the SDIO IRQ. + +``` +int32_t ret; +/* Release the SDIO IRQ. */ +ret = SdioReleaseIrq(handle); +if (ret != 0) { + HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); +} +``` + +### Disabling the SDIO Device + +After the SDIO communication, disable the SDIO device. + +int32\_t SdioDisableFunc\(DevHandle handle\); + +**Table 13** Parameters and return values of SdioDisableFunc + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

Return Value

+

Description

+

0

+

The SDIO device is disabled.

+

Negative value

+

Failed to disable the SDIO device.

+
+ +The following example shows how to disable the SDIO device. + +``` +int32_t ret; +/* Disable the SDIO device. */ +ret = SdioDisableFunc(handle); +if (ret != 0) { + HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); +} +``` + +### Releasing the Exclusively Claimed Host + +After the SDIO communication, release the exclusively claimed host. + +void SdioReleaseHost\(DevHandle handle\); + +**Table 14** Parameter description of SdioReleaseHost + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+
+ +The following example shows how to release the exclusively claimed host. + +``` +SdioReleaseHost(handle); /* Release the exclusively claimed host. */ +``` + +### Closing an SDIO Controller + +After the SDIO communication, close the SDIO controller. + +void SdioClose\(DevHandle handle\); + +This function releases the resources requested. + +**Table 15** Parameter description of SdioClose + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+
+ +The following example shows how to close an SDIO controller. + +``` +SdioClose(handle); /* Close an SDIO controller. */ +``` + +## Usage Example + +The following example shows how to use an SDIO device. First, open an SDIO controller whose bus number is 1, exclusively claim a host, enable the SDIO device, claim an SDIO IRQ, and then perform SDIO communication \(such as reading and writing\). After the SDIO communication, release the SDIO IRQ, disable the SDIO device, release the host, and close the SDIO controller. + +``` +#include "hdf_log.h" +#include "sdio_if.h" + +#define TEST_FUNC_NUM 1 /* The I/O function whose ID is 1 is used. */ +#define TEST_FBR_BASE_ADDR 0x100 /* FBR base address of the I/O function whose ID is 1 */ +#define TEST_ADDR_OFFSET 9 /* Address offset of the register to read or write */ +#define TEST_DATA_LEN 3 /* Length of the data to read or write */ +#define TEST_BLOCKSIZE 2 /* Size of a data block, in bytes */ + +/* Implement the SDIO IRQ function based on the application. */ +static void SdioIrqFunc(void *data) +{ + if (data == NULL) { + HDF_LOGE("SdioIrqFunc: data is NULL.\n"); + return; + } + /* You need to add specific implementations. */ +} + +void SdioTestSample(void) +{ + int32_t ret; + DevHandle handle = NULL; + uint8_t data[TEST_DATA_LEN] = {0}; + struct SdioFunctionConfig config = {1, 0x123, 0x456}; + uint8_t val; + uint32_t addr; + + /* Open an SDIO controller whose bus number is 1. */ + handle = SdioOpen(1, &config); + if (handle == NULL) { + HDF_LOGE("SdioOpen: failed!\n"); + return; + } + /* Claim a host exclusively. */ + SdioClaimHost(handle); + /* Enable the SDIO device. */ + ret = SdioEnableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); + goto ENABLE_ERR; + } + /* Claim an SDIO IRQ. */ + ret = SdioClaimIrq(handle, SdioIrqFunc); + if (ret != 0) { + HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); + goto CLAIM_IRQ_ERR; + } + /* Set the block size to 2 bytes. */ + ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE); + if (ret != 0) { + HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 3-byte data from the incremental address of an SDIO device. */ + addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET; + ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 3-byte data into the incremental address of an SDIO device. */ + ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 1-byte data from the SDIO device. */ + ret = SdioReadBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 1-byte data into the SDIO device. */ + ret = SdioWriteBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 3-byte data from the fixed address of an SDIO device. */ + ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 1-byte data to the fixed address of an SDIO device. */ + ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 1-byte data from SDIO function 0. */ + addr = 0x02; + ret = SdioReadBytesFromFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 1-byte data into SDIO function 0. */ + ret = SdioWriteBytesToFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } +COMM_ERR: + /* Release the SDIO IRQ. */ + ret = SdioReleaseIrq(handle); + if (ret != 0) { + HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); + } +CLAIM_IRQ_ERR: + /* Disable the SDIO device. */ + ret = SdioDisableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); + } +ENABLE_ERR: + /* Release the exclusively claimed host. */ + SdioReleaseHost(handle); + /* Close an SDIO controller. */ + SdioClose(handle); +} +``` + diff --git a/en/device-dev/driver/driver-platform-spi-des.md b/en/device-dev/driver/driver-platform-spi-des.md new file mode 100644 index 0000000000000000000000000000000000000000..b2c1b31147091e2d28ff902727f8ec7c1abfef80 --- /dev/null +++ b/en/device-dev/driver/driver-platform-spi-des.md @@ -0,0 +1,566 @@ +# SPI + +- [Overview](#section193356154511) + - [Available APIs](#section232141411476) + +- [Usage Guidelines](#section71363452477) + - [How to Use](#section32846814820) + - [Obtaining an SPI Device Handle](#section1927265711481) + - [Obtaining SPI Device Configuration Parameters](#section541133418493) + - [Setting SPI Device Configuration Parameters](#section7870106145010) + - [Performing SPI Communication](#section13324155195013) + - [Destroying the SPI Device Handle](#section19661632135117) + +- [Usage Example](#section06541058155120) + +## Overview + +- Serial Peripheral Interface \(SPI\) is a serial bus specification used for high-speed, full-duplex, and synchronous communication. +- SPI is developed by Motorola. It is commonly used for communication with flash memory, real-time clocks, sensors, and analog-to-digital \(A/D\) converters. +- SPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires: + - SCLK: clock signals output from the SPI controller + - MOSI: data output from the SPI controller and input into an SPI device + - MISO: data output from an SPI device and input into the SPI controller + - CS: signals enabled by an SPI device and controlled by the SPI controller + + +- [Figure 1](#fig15227181812587) shows the connection between one SPI controller and two SPI devices \(device A and device B\). In this figure, device A and device B share three pins \(SCLK, MISO, and MOSI\) of the controller. CS0 of device A and CS1 of device B are connected to CS0 and CS1 of the controller, respectively. + +**Figure 1** SPI controller/device connection + + +![](figure/en-us_image_0000001123742254.png) + +- SPI communication is usually initiated by the SPI controller and is operated as follows: + +1. A single SPI device is selected at a time via the CS to communicate with the SPI controller. +2. Clock signals are provided for the selected SPI device via the SCLK. +3. The SPI controller sends data to SPI devices via the MOSI, and receives data from SPI devices via the MISO. + +- SPI can work in one of the following four modes, equivalent to one of the four possible states for Clock Polarity \(CPOL\) and Clock Phase \(CPHA\): + - If both CPOL and CPHA are **0**, the clock signal level is low in the idle state and data is sampled on the first clock edge. + - If CPOL is **0** and CPHA is **1**, the clock signal level is low in the idle state and data is sampled on the second clock edge. + - If CPOL is **1** and CPHA is **0**, the clock signal level is high in the idle state and data is sampled on the first clock edge. + - If both CPOL and CPHA are **1**, the clock signal level is high in the idle state and data is sampled on the second clock edge. + + +- SPI defines a set of common functions for operating an SPI device, including those for: + - Obtaining and releasing the handle of an SPI device. + - Reading or writing data of a specified length from or into an SPI device. + - Customizing data reading or writing via **SpiMsg**. + - Obtaining and setting SPI device configuration parameters. + + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Currently, these functions are only applicable in the communication initiated by the SPI controller. + +### Available APIs + +**Table 1** APIs for the SPI driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

SPI device handle obtaining/releasing

+

SpiOpen

+

Obtains an SPI device handle.

+

SpiClose

+

Releases an SPI device handle.

+

SPI reading/writing

+

SpiRead

+

Reads data of a specified length from an SPI device.

+

SpiWrite

+

Writes data of a specified length into an SPI device.

+

SpiTransfer

+

Transfers SPI data.

+

SPI device configuration

+

+

SpiSetCfg

+

Sets configuration parameters for an SPI device.

+

SpiGetCfg

+

Obtains configuration parameters of an SPI device.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All functions provided in this document can be called only in kernel space. + +## Usage Guidelines + +### How to Use + +[Figure 2](#fig23885455594) shows the process of using an SPI device. + +**Figure 2** Process of using an SPI device + + +![](figure/en-us_image_0000001123703482.png) + +### Obtaining an SPI Device Handle + +Before performing SPI communication, obtain an SPI device handle by calling **SpiOpen**. This function returns an SPI device handle with a specified bus number and CS number. + +DevHandle SpiOpen\(const struct SpiDevInfo \*info\); + +**Table 2** Description of **SpiOpen** + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

info

+

Pointer to the SPI device descriptor.

+

Return Value

+

Description

+

NULL

+

Failed to obtain an SPI device handle.

+

Device handle

+

Returns the pointer to the SPI device handle.

+
+ +The following example shows how to obtain an SPI device handle based on the assumption that both the bus number and CS number of the SPI device are **0**. + +``` +struct SpiDevInfo spiDevinfo; /* SPI device descriptor */ +DevHandle spiHandle = NULL; /* SPI device handle */ +spiDevinfo.busNum = 0; /* SPI device bus number */ +spiDevinfo.csNum = 0; /* SPI device CS number */ + +/* Obtain an SPI device handle. */ +spiHandle = SpiOpen(&spiDevinfo); +if (spiHandle == NULL) { + HDF_LOGE("SpiOpen: failed\n"); + return; +} +``` + +### Obtaining SPI Device Configuration Parameters + +After obtaining the SPI device handle, obtain the SPI device configuration parameters by calling the following function: + +int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\); + +**Table 3** Description of **SpiGetCfg** + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

SPI device handle.

+

cfg

+

Pointer to SPI device configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in obtaining SPI device configuration parameters.

+

Negative value

+

Failed to obtain SPI device configuration parameters.

+
+ +``` +int32_t ret; +struct SpiCfg cfg = {0}; /* SPI configuration information */ +ret = SpiGetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */ +if (ret != 0) { + HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); +} +``` + +### Setting SPI Device Configuration Parameters + +After obtaining the SPI device handle, set SPI device configuration parameters by calling the following function: + +int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\); + +**Table 4** Description of **SpiSetCfg** + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

SPI device handle.

+

cfg

+

Pointer to SPI device configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in setting SPI device configuration parameters.

+

Negative value

+

Failed to set SPI device configuration parameters.

+
+ +``` +int32_t ret; +struct SpiCfg cfg = {0}; /* SPI configuration information */ +cfg.mode = SPI_MODE_LOOP; /* Communication in loopback mode */ +cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* Communication in polling mode */ +cfg.maxSpeedHz = 115200; /* Maximum transmission frequency */ +cfg.bitsPerWord = 8; /* The width of per word to be read or written is 8 bits. */ +ret = SpiSetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */ +if (ret != 0) { + HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); +} +``` + +### Performing SPI Communication + +- Writing data of a specific length into an SPI device + +To write data into an SPI device only once, call the following function: + +int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); + +**Table 5** Description of **SpiWrite** + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

SPI device handle.

+

buf

+

Pointer to the data to write.

+

len

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Succeeded in writing data into an SPI device.

+

Negative value

+

Failed to write data into an SPI device.

+
+ +``` +int32_t ret; +uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78}; +/* Write data of a specific length into an SPI device. */ +ret = SpiWrite(spiHandle, wbuff, 4); +if (ret != 0) { + HDF_LOGE("SpiWrite: failed, ret %d\n", ret); +} +``` + +- Reading data of a specific length from an SPI device + +To read data from an SPI device only once, call the following function: + +int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); + +**Table 6** Description of **SpiRead** + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

SPI device handle.

+

buf

+

Pointer to the data to read.

+

len

+

Length of the data to read.

+

Return Value

+

Description

+

0

+

Succeeded in reading data from an SPI device.

+

Negative value

+

Failed to read data from an SPI device.

+
+ +``` +int32_t ret; +uint8_t rbuff[4] = {0}; +/* Read data of a specific length from an SPI device. */ +ret = SpiRead(spiHandle, rbuff, 4); +if (ret != 0) { + HDF_LOGE("SpiRead: failed, ret %d\n", ret); +} +``` + +- Launching a custom transfer + +To launch a custom transfer, call the following function: + +int32\_t SpiTransfer\(DevHandle handle, struct SpiMsg \*msgs, uint32\_t count\); + +**Table 7** Description of **SpiTransfer** + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

SPI device handle.

+

msgs

+

Pointer to the message array to be transferred.

+

count

+

Number of messages in the message array.

+

Return Value

+

Description

+

0

+

Succeeded in launching the custom transfer.

+

Negative value

+

Failed to launch the custom transfer.

+
+ +``` +int32_t ret; +uint8_t wbuff[1] = {0x12}; +uint8_t rbuff[1] = {0}; +struct SpiMsg msg; /* Custom message to be transferred */ +msg.wbuf = wbuff; /* Pointer to the data to write */ +msg.rbuf = rbuff; /* Pointer to the data to read */ +msg.len = 1; /* The length of the data to read or write is 1 bit. */ +msg.csChange = 1; /* Disable the CS before the next transfer. */ +msg.delayUs = 0; /* No delay before the next transfer */ +msg.speed = 115200; /* Speed of this transfer */ +/* Launch a custom transfer. The number of messages to be transferred is 1. */ +ret = SpiTransfer(spiHandle, &msg, 1); +if (ret != 0) { + HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); +} +``` + +### Destroying the SPI Device Handle + +After the SPI communication, destroy the SPI device handle by calling the following function: + +void SpiClose\(DevHandle handle\); + +This function will release the resources previously obtained. + +**Table 8** Description of **SpiClose** + + + + + + + + + +

Parameter

+

Description

+

handle

+

SPI device handle.

+
+ +``` +PalHandleDestroy(spiHandle); /* Destroy the SPI device handle. */ +``` + +## Usage Example + +The following example shows how to obtain an SPI device handle, set the configuration parameters, and then read or write data from or into the SPI device, and finally destroy the SPI device handle. + +``` +#include "hdf_log.h" +#include "spi_if.h" + +void SpiTestSample(void) +{ + int32_t ret; + struct SpiCfg cfg; /* SPI device configuration information */ + struct SpiDevInfo spiDevinfo; /* SPI device descriptor */ + DevHandle spiHandle = NULL; /* SPI device handle */ + struct SpiMsg msg; /* Custom message to be transferred */ + uint8_t rbuff[4] = { 0 }; + uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; + uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; + + spiDevinfo.busNum = 0; /* SPI device bus number */ + spiDevinfo.csNum = 0; /* SPI device CS number */ + spiHandle = SpiOpen(&spiDevinfo); /* Obtain an SPI device handle based on spiDevinfo. */ + if (spiHandle == NULL) { + HDF_LOGE("SpiOpen: failed\n"); + return; + } + /* Obtain configuration parameters of an SPI device. */ + ret = SpiGetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); + goto err; + } + cfg.maxSpeedHz = 115200; /* Change the maximum clock frequency to 115200. */ + cfg.bitsPerWord = 8; /* Change the word width to 8 bits. */ + /* Set configuration parameters for an SPI device. */ + ret = SpiSetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); + goto err; + } + /* Write specified length of data into an SPI device. */ + ret = SpiWrite(spiHandle, wbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiWrite: failed, ret %d\n", ret); + goto err; + } + /* Read data of a specified length from an SPI device. */ + ret = SpiRead(spiHandle, rbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiRead: failed, ret %d\n", ret); + goto err; + } + msg.wbuf = wbuff2; /* Pointer to the data to write */ + msg.rbuf = rbuff; /* Pointer to the data to read */ + msg.len = 4; /* The length of the data to read or write is 4 bits. */ + msg.csChange = 1; /* Disable the CS before the next transfer. */ + msg.delayUs = 0; /* No delay before the next transfer */ + msg.speed = 115200; /* Speed of this transfer */ + /* Launch a custom transfer. The number of messages to be transferred is 1. */ + ret = SpiTransfer(spiHandle, &msg, 1); + if (ret != 0) { + HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); + goto err; + } +err: + /* Destroy the SPI device handle. */ + SpiClose(spiHandle); +} +``` + diff --git a/en/device-dev/driver/driver-platform-uart-des.md b/en/device-dev/driver/driver-platform-uart-des.md new file mode 100644 index 0000000000000000000000000000000000000000..a789594525e5d6ebb9270dadd540a35e3d76f887 --- /dev/null +++ b/en/device-dev/driver/driver-platform-uart-des.md @@ -0,0 +1,682 @@ +# UART + +- [Overview](#section833012453535) + - [Available APIs](#section1680292311549) + +- [Usage Guidelines](#section12779050105412) + - [How to Use](#section1858116395510) + - [Obtaining a UART Device Handle](#section124512065617) + - [Setting the UART Baud Rate](#section86881004579) + - [Obtaining the UART Baud Rate](#section897032965712) + - [Setting the UART Device Attributes](#section129141884588) + - [Obtaining UART Device Attributes](#section18689637165812) + - [Setting the UART Transmission Mode](#section72713435918) + - [Writing Data of a Specified Length into a UART Device](#section128001736155919) + - [Reading Data of a Specified Length from a UART Device](#section92851601604) + - [Destroying the UART Device Handle](#section1477410521406) + +- [Usage Example](#section35404241311) + +## Overview + +- The Universal Asynchronous Receiver/Transmitter \(UART\) is a universal serial data bus used for asynchronous communication. It enables bi-directional communication between devices in full-duplex mode. +- UART is widely used to print information for debugging or to connect to various external modules such as GPS and Bluetooth. +- A UART is connected to other modules through two wires \(as shown in [Figure 1](#fig209936401896)\) or four wires \(as shown in [Figure 2](#fig1435614171015)\). + - TX: TX pin of the transmitting UART. It is connected to the RX pin of the peer UART. + - RX: RX pin of the receiving UART. It is connected to the TX pin of the peer UART. + - RTS: Request to Send signal pin. It is connected to the CTS pin of the peer UART and is used to indicate whether the local UART is ready to receive data. + - CTS: Clear to Send signal pin. It is connected to the RTS pin of the peer UART and is used to indicate whether the local UART is allowed to send data to the peer end. + + **Figure 1** 2-wire UART communication + + + ![](figure/en-us_image_0000001170262141.png) + + **Figure 2** 4-wire UART communication + + + ![](figure/en-us_image_0000001123582482.png) + + +- The transmitting and receiving UARTs must ensure that they have the same settings on particular attributes such as the baud rate and data format \(start bit, data bit, parity bit, and stop bit\) before they start to communicate. During data transmission, a UART sends data to the peer end over the TX pin and receives data from the peer end over the RX pin. When the size of the buffer used by a UART for storing received data reaches the preset threshold, the RTS signal of the UART changes to **1** \(data cannot be received\), and the peer UART stops sending data to it because its CTS signal does not allow it to send data. +- The UART interface defines a set of common functions for operating a UART port, including obtaining and releasing device handles, reading and writing data of a specified length, and obtaining and setting the baud rate, as well as the device attributes. + +### Available APIs + +**Table 1** APIs for the UART driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

Obtaining and releasing device handles

+

+

UartOpen

+

Obtains the UART device handle.

+

UartClose

+

Releases a specified UART device handle.

+

Reading and writing data

+

+

UartRead

+

Reads data of a specified length from a UART device.

+

UartWrite

+

Writes data of a specified length into a UART device.

+

Obtaining and setting the baud rate

+

UartGetBaud

+

Obtains the UART baud rate.

+

UartSetBaud

+

Sets the UART baud rate.

+

Obtaining and setting device attributes

+

+

UartGetAttribute

+

Obtains the UART device attributes.

+

UartSetAttribute

+

Sets the UART device attributes.

+

Setting the transmission mode

+

UartSetTransMode

+

Sets the UART transmission mode.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All functions provided in this document can be called only in kernel space. + +## Usage Guidelines + +### How to Use + +[Figure 3](#fig1852173020185) shows the process of using a UART device. + +**Figure 3** Process of using a UART device + + +![](figure/en-us_image_0000001170227689.png) + +### Obtaining a UART Device Handle + +Before performing UART communication, call **UartOpen** to obtain a UART device handle. This function returns the pointer to the UART device handle with a specified port number. + +DevHandle UartOpen\(uint32\_t port\); + +**Table 2** Description of UartOpen + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

port

+

UART port number.

+

Return Value

+

Description

+

NULL

+

Failed to obtain the UART device handle.

+

Device handle

+

UART device handle.

+
+ +The following example shows how to obtain a UART device handle based on the assumption that the UART port number is **3**: + +``` +DevHandle handle = NULL; /* The UART device handle */ +uint32_t port = 3; /* UART port number */ +handle = UartOpen(port); +if (handle == NULL) { + HDF_LOGE("UartOpen: failed!\n"); + return; +} +``` + +### Setting the UART Baud Rate + +After obtaining the UART device handle, set the UART baud rate by calling the following function: + +int32\_t UartSetBaud\(DevHandle handle, uint32\_t baudRate\); + +**Table 3** Description of UartSetBaud + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+

baudRate

+

Baud rate of the UART to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the UART baud rate.

+

Negative value

+

Failed to set the UART baud rate.

+
+ +The following example shows how to set the UART baud rate to **9600**: + +``` +int32_t ret; +/* Set the UART baud rate to 9600. */ +ret = UartSetBaud(handle, 9600); +if (ret != 0) { + HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); +} +``` + +### Obtaining the UART Baud Rate + +After setting the UART baud rate, obtain the current baud rate by calling the following function: + +int32\_t UartGetBaud\(DevHandle handle, uint32\_t \*baudRate\); + +**Table 4** Description of UartGetBaud + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+

baudRate

+

Pointer to the UART baud rate.

+

Return Value

+

Description

+

0

+

Succeeded in obtaining the UART baud rate.

+

Negative value

+

Failed to obtain the UART baud rate.

+
+ +The following example shows how to obtain the UART baud rate: + +``` +int32_t ret; +uint32_t baudRate; +/* Obtain the UART baud rate. */ +ret = UartGetBaud(handle, &baudRate); +if (ret != 0) { + HDF_LOGE("UartGetBaud: failed, ret %d\n", ret); +} +``` + +### Setting the UART Device Attributes + +Before performing UART communication, set the UART device attributes by calling the following function: + +int32\_t UartSetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); + +**Table 5** Description of UartSetAttribute + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+

attribute

+

Pointer to the UART device attributes to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the UART device attributes.

+

Negative value

+

Failed to set the UART device attributes.

+
+ +The following example shows how to set the UART device attributes: + +``` +int32_t ret; +struct UartAttribute attribute; +attribute.dataBits = UART_ATTR_DATABIT_7; /* Set the number of data bits to 7. */ +attribute.parity = UART_ATTR_PARITY_NONE; /* Set the parity bit to no parity. */ +attribute.stopBits = UART_ATTR_STOPBIT_1; /* Set the stop bit to 1. */ +attribute.rts = UART_ATTR_RTS_DIS; /* Disable the RTS signal. */ +attribute.cts = UART_ATTR_CTS_DIS; /* Disable the CTS signal. */ +attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* Enable RX FIFO. */ +attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* Enable TX FIFO. */ +/* Set the UART device attributes. */ +ret = UartSetAttribute(handle, &attribute); +if (ret != 0) { + HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); +} +``` + +### Obtaining UART Device Attributes + +After setting the UART device attributes, obtain the current device attributes by calling the following function: + +int32\_t UartGetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); + +**Table 6** Description of UartGetAttribute + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+

attribute

+

Pointer to the UART device attributes.

+

Return Value

+

Description

+

0

+

Succeeded in obtaining the UART device attributes.

+

Negative value

+

Failed to obtain the UART device attributes.

+
+ +The following example shows how to obtain the UART device attributes: + +``` +int32_t ret; +struct UartAttribute attribute; +/* Obtain the UART attributes. */ +ret = UartGetAttribute(handle, &attribute); +if (ret != 0) { + HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret); +} +``` + +### Setting the UART Transmission Mode + +Before performing UART communication, set the UART transmission mode by calling the following function: + +int32\_t UartSetTransMode\(DevHandle handle, enum UartTransMode mode\); + +**Table 7** Description of UartSetTransMode + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+

mode

+

UART transmission mode to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the UART transmission mode.

+

Negative value

+

Failed to set the UART transmission mode.

+
+ +The following example shows how to set the transmission mode to **UART\_MODE\_RD\_BLOCK**: + +``` +int32_t ret; +/* Set the UART transmission mode. */ +ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); +if (ret != 0) { + HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); +} +``` + +### Writing Data of a Specified Length into a UART Device + +To write data into a UART device, call the following function: + +int32\_t UartWrite\(DevHandle handle, uint8\_t \*data, uint32\_t size\); + +**Table 8** Description of UartWrite + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+

data

+

Pointer to the data to write.

+

size

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Succeeded in writing data into the UART device.

+

Negative value

+

Failed to write data into the UART device.

+
+ +The following example shows how to write data of a specified length into the UART device: + +``` +int32_t ret; +uint8_t wbuff[5] = {1, 2, 3, 4, 5}; +/* Write 5-byte data into the UART device. */ +ret = UartWrite(handle, wbuff, 5); +if (ret != 0) { + HDF_LOGE("UartWrite: failed, ret %d\n", ret); +} +``` + +### Reading Data of a Specified Length from a UART Device + +To write data into a UART device, call the following function: + +int32\_t UartRead\(DevHandle handle, uint8\_t \*data, uint32\_t size\); + +**Table 9** Description of UartRead + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+

data

+

Pointer to the buffer for receiving the data.

+

size

+

Length of the data to read.

+

Return Value

+

Description

+

Non-negative value

+

Length of the data read from the UART device.

+

Negative value

+

Failed to read data from the UART device.

+
+ +The following example shows how to read data of a specified length from the UART device: + +``` +int32_t ret; +uint8_t rbuff[5] = {0}; +/* Read 5-byte data from the UART device. */ +ret = UartRead(handle, rbuff, 5); +if (ret < 0) { + HDF_LOGE("UartRead: failed, ret %d\n", ret); +} +``` + +>![](../public_sys-resources/icon-caution.gif) **CAUTION:** +>Data is successfully read from the UART device if a non-negative value is returned. If the return value is **0**, no valid data can be read from the UART device. If the return value is greater than **0**, the return value is the length of the data actually read from the UART device. The length is less than or equal to the value of **size** and does not exceed the maximum length of data to read at a time specified by the UART controller in use. + +### Destroying the UART Device Handle + +After the UART communication, destroy the UART device handle by calling the following function: + +void UartClose\(DevHandle handle\); + +This function will release the resources previously obtained. + +**Table 10** Description of UartClose + + + + + + + + + + +

Parameter

+

Description

+

handle

+

UART device handle.

+
+ +The following example shows how to destroy the UART device handle: + +``` +UartClose(handle); /* Destroy the UART device handle. */ +``` + +## Usage Example + +The following is a usage example of a UART device, including how to obtain the UART device handle, set the baud rate, device attributes, and transmission mode, read data from or write data into the UART device, and then destroy the UART device handle. + +``` +#include "hdf_log.h" +#include "uart_if.h" + +void UartTestSample(void) +{ + int32_t ret; + uint32_t port; + DevHandle handle = NULL; + uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; + uint8_t rbuff[5] = { 0 }; + struct UartAttribute attribute; + attribute.dataBits = UART_ATTR_DATABIT_7; /* Set the number of data bits to 7. */ + attribute.parity = UART_ATTR_PARITY_NONE; /* Set the parity bit to no parity. */ + attribute.stopBits = UART_ATTR_STOPBIT_1; /* Set the stop bit to 1. */ + attribute.rts = UART_ATTR_RTS_DIS; /* Disable the RTS signal. */ + attribute.cts = UART_ATTR_CTS_DIS; /* Disable the CTS signal. */ + attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* Enable RX FIFO. */ + attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* Enable TX FIFO. */ + /* Set the UART port number actually used. */ + port = 1; + /* Obtain the UART device handle. */ + handle = UartOpen(port); + if (handle == NULL) { + HDF_LOGE("UartOpen: failed!\n"); + return; + } + /* Set the UART baud rate to 9600. */ + ret = UartSetBaud(handle, 9600); + if (ret != 0) { + HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); + goto _ERR; + } + /* Set the UART device attributes. */ + ret = UartSetAttribute(handle, &attribute); + if (ret != 0) { + HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); + goto _ERR; + } + /* Set the UART transmission mode to non-blocking mode. */ + ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); + if (ret != 0) { + HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); + goto _ERR; + } + /* Write 5-byte data into the UART device. */ + ret = UartWrite(handle, wbuff, 5); + if (ret != 0) { + HDF_LOGE("UartWrite: failed, ret %d\n", ret); + goto _ERR; + } + /* Read 5-byte data from the UART device. */ + ret = UartRead(handle, rbuff, 5); + if (ret < 0) { + HDF_LOGE("UartRead: failed, ret %d\n", ret); + goto _ERR; + } +_ERR: + /* Destroy the UART device handle. */ + UartClose(handle); +} +``` + diff --git a/en/device-dev/driver/driver-platform-watchdog-des.md b/en/device-dev/driver/driver-platform-watchdog-des.md new file mode 100644 index 0000000000000000000000000000000000000000..ddaddc1abe08efca457b46b26db353dc0df06f2e --- /dev/null +++ b/en/device-dev/driver/driver-platform-watchdog-des.md @@ -0,0 +1,557 @@ +# Watchdog + +- [Overview](#section14918241977) + - [Available APIs](#section20177131219818) + +- [Usage Guidelines](#section10103184312813) + - [How to Use](#section10181195910815) + - [Opening a Watchdog](#section66089201107) + - [Obtaining the Watchdog Status](#section786624341011) + - [Setting the Timeout Duration](#section182386137111) + - [Obtaining the Timeout Duration](#section1883310371114) + - [Starting a Watchdog](#section82501405123) + - [Feeding a Watchdog](#section3547530101211) + - [Stopping a Watchdog](#section944595841217) + - [Closing a Watchdog](#section96561824121311) + +- [Usage Example](#section1724514523135) + +## Overview + +A watchdog, also called a watchdog timer, is a hardware timing device. If an error occurs in the main program of the system and fails to reset the watchdog timer, the watchdog timer sends a reset signal to restore the system to a normal state. + +### Available APIs + +**Table 1** Watchdog APIs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

Open/Close

+

WatchdogOpen

+

Opens a watchdog.

+

WatchdogClose

+

Closes a watchdog.

+

Start/Stop

+

WatchdogStart

+

Starts a watchdog.

+

WatchdogStop

+

Stops a watchdog.

+

Timeout duration

+

WatchdogSetTimeout

+

Sets the watchdog timeout duration.

+

WatchdogGetTimeout

+

Obtains the watchdog timeout duration.

+

Status

+

WatchdogGetStatus

+

Obtains the watchdog status.

+

Feeding

+

WatchdogFeed

+

Feeds a watchdog, or resets a watchdog timer.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>All watchdog functions provided in this document can be called only in kernel mode. + +## Usage Guidelines + +### How to Use + +[Figure 1](#fig19134125410189) illustrates the process of using a watchdog. + +**Figure 1** Process of using a watchdog + + +![](figure/en-us_image_0000001170229891.png) + +### Opening a Watchdog + +Use **WatchdogOpen** to open a watchdog. A system may have multiple watchdogs. You can open the specified watchdog by using the ID. + +int32\_t WatchdogOpen\(int16\_t wdtId\); + +**Table 2** Description of WatchdogOpen + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

wdtId

+

Watchdog ID.

+

Return Value

+

Description

+

NULL

+

Failed to open the watchdog.

+

DevHandle pointer

+

Pointer to the watchdog handle.

+
+ +``` +DevHandle handle = NULL; +handle = WatchdogOpen(0); /* Open watchdog 0.*/ +if (handle == NULL) { + HDF_LOGE("WatchdogOpen: failed, ret %d\n", ret); + return; +} +``` + +### Obtaining the Watchdog Status + +int32\_t WatchdogGetStatus\(DevHandle handle, int32\_t \*status\); + +**Table 3** Description of WatchdogGetStatus + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Watchdog handle.

+

status

+

Pointer to the watchdog status.

+

Return Value

+

Description

+

0

+

The watchdog status is obtained.

+

Negative value

+

Failed to obtain the watchdog status.

+
+ +``` +int32_t ret; +int32_t status; +/* Obtain the watchdog status. */ +ret = WatchdogGetStatus(handle, &status); +if (ret != 0) { + HDF_LOGE("WatchdogGetStatus: failed, ret %d\n", ret); + return; +} +``` + +### Setting the Timeout Duration + +int32\_t WatchdogSetTimeout\(PalHandle \*handle, uint32\_t seconds\); + +**Table 4** Description of WatchdogSetTimeout + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Watchdog handle.

+

seconds

+

Timeout duration, in seconds.

+

Return Value

+

Description

+

0

+

The setting is successful.

+

Negative value

+

Setting failed.

+
+ +``` +int32_t ret; +uint32_t timeOut = 60; +/* Set the timeout duration, in seconds. */ +ret = WatchdogSetTimeout(handle, timeOut); +if (ret != 0) { + HDF_LOGE("WatchdogSetTimeout: failed, ret %d\n", ret); + return; +} +``` + +### Obtaining the Timeout Duration + +int32\_t WatchdogGetTimeout\(PalHandle \*handle, uint32\_t \*seconds\); + +**Table 5** Description of WatchdogGetTimeout + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Watchdog handle.

+

seconds

+

Pointer to the timeout duration, in seconds.

+

Return Value

+

Description

+

0

+

The watchdog status is obtained.

+

Negative value

+

Failed to obtain the watchdog status.

+
+ +``` +int32_t ret; +uint32_t timeOut; +/* Obtain the timeout duration, in seconds. */ +ret = WatchdogGetTimeout(handle, &timeOut); +if (ret != 0) { + HDF_LOGE("WatchdogGetTimeout: failed, ret %d\n", ret); + return; +} +``` + +### Starting a Watchdog + +int32\_t WatchdogStart\(DevHandle handle\); + +**Table 6** Description of WatchdogStart + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Watchdog handle.

+

Return Value

+

Description

+

0

+

The watchdog is started.

+

Negative value

+

Failed to start the watchdog.

+
+ +``` +int32_t ret; +/* Start the watchdog. */ +ret = WatchdogStart(handle); +if (ret != 0) { + HDF_LOGE("WatchdogStart: failed, ret %d\n", ret); + return; +} +``` + +### Feeding a Watchdog + +int32\_t WatchdogFeed\(DevHandle handle\); + +**Table 7** Description of WatchdogFeed + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Watchdog handle.

+

Return Value

+

Description

+

0

+

The watchdog is fed.

+

Negative value

+

Failed to feed the watchdog.

+
+ +``` +int32_t ret; +/* Feed the watchdog. */ +ret = WatchdogFeed(handle); +if (ret != 0) { + HDF_LOGE("WatchdogFeed: failed, ret %d\n", ret); + return; +} +``` + +### Stopping a Watchdog + +int32\_t WatchdogStop\(DevHandle handle\); + +**Table 8** Description of WatchdogStop + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Watchdog handle.

+

Return Value

+

Description

+

0

+

The watchdog is stopped.

+

Negative value

+

Stopping the watchdog failed.

+
+ +``` +int32_t ret; +/* Stop the watchdog. */ +ret = WatchdogStop(handle); +if (ret != 0) { + HDF_LOGE("WatchdogStop: failed, ret %d\n", ret); + return; +} +``` + +### Closing a Watchdog + +If the watchdog is no longer required, call **WatchdogClose** to close the watchdog handle. + +void WatchdogClose\(DevHandle handle\); + +**Table 9** Description of WatchdogClose + + + + + + + + + + +

Parameter

+

Description

+

handle

+

Watchdog handle.

+
+ +``` +/* Close the watchdog. */ +ret = WatchdogClose(handle); +``` + +## Usage Example + +This example provides a complete process for using a watchdog. + +In this example, open a watchdog, set the timeout duration, and start the watchdog. + +- Feed the watchdog periodically to ensure that the system is not reset due to timer expiry. +- Stop feeding the watchdog and check whether the system is reset after the timer expires. + +Example: + +``` +#include "watchdog_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +#define WATCHDOG_TEST_TIMEOUT 2 +#define WATCHDOG_TEST_FEED_TIME 6 + +static int32_t TestCaseWatchdog(void) +{ + int32_t i; + int32_t ret; + uint32_t timeout; + DevHandle handle = NULL; + + /* Open watchdog 0. */ + handle = WatchdogOpen(0); + if (handle == NULL) { + HDF_LOGE("Open watchdog fail!"); + return -1; + } + + /* Set the timeout duration. */ + ret = WatchdogSetTimeout(handle, WATCHDOG_TEST_TIMEOUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* Obtain the configured timeout duration. */ + ret = WatchdogGetTimeout(handle, &timeout); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); + + /* Start the watchdog. The timer starts. */ + ret = WatchdogStart(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* Feed the watchdog every 1s. */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); + ret = WatchdogFeed(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + OsalSleep(1); + } + /* Because the interval for feeding the watchdog is shorter than the timeout duration, the system does not reset, and logs can be printed normally. */ + HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); + + /* Enable the timer to expire by stopping feeding the watchdog. */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: watiting dog buck %d times... \n", __func__, i); + OsalSleep(1); + } + + /* The system resets when the timer expires. If the code is correct, the log below is not displayed. */ + HDF_LOGE("%s: dog has't buck!!! \n", __func__, i); + WatchdogClose(handle); + return -1; +} +``` + diff --git a/en/device-dev/driver/driver-platform.md b/en/device-dev/driver/driver-platform.md index d75727d7407e71e9088a907083d02278462474e3..c15f954770c9b49ba191a50de133f954d0c63bcd 100644 --- a/en/device-dev/driver/driver-platform.md +++ b/en/device-dev/driver/driver-platform.md @@ -1,19 +1,19 @@ -# Driver Platform +# Platform drivers -- **[GPIO](gpio.md)** +- **[GPIO](driver-platform-gpio-des.md)** -- **[I2C](i2c.md)** +- **[I2C](driver-platform-i2c-des.md)** -- **[RTC](rtc.md)** +- **[RTC](driver-platform-rtc-des.md)** -- **[SDIO](sdio.md)** +- **[SDIO](driver-platform-sdio-des.md)** -- **[SPI](spi.md)** +- **[SPI](driver-platform-spi-des.md)** -- **[UART](uart.md)** +- **[UART](driver-platform-uart-des.md)** -- **[WATCHDOG](watchdog.md)** +- **[Watchdog](driver-platform-watchdog-des.md)** -- **[MIPI DSI](mipi-dsi.md)** +- **[MIPI DSI](driver-platform-mipidsi-des.md)** diff --git a/en/device-dev/driver/driver.md b/en/device-dev/driver/driver.md new file mode 100644 index 0000000000000000000000000000000000000000..a046ce6e68b6b7ede4a835f772a75962b1fc870c --- /dev/null +++ b/en/device-dev/driver/driver.md @@ -0,0 +1,9 @@ +# Driver Usage Guidelines + +- **[HDF](driver-hdf.md)** + +- **[Platform Drivers](driver-platform.md)** + +- **[Peripherals](driver-peripherals.md)** + + diff --git a/en/device-dev/driver/figures/architecture-of-the-display-driver-model.png b/en/device-dev/driver/figure/architecture-of-the-display-driver-model.png similarity index 100% rename from en/device-dev/driver/figures/architecture-of-the-display-driver-model.png rename to en/device-dev/driver/figure/architecture-of-the-display-driver-model.png diff --git a/en/device-dev/driver/figures/architecture-of-the-input-driver-model.png b/en/device-dev/driver/figure/architecture-of-the-input-driver-model.png similarity index 100% rename from en/device-dev/driver/figures/architecture-of-the-input-driver-model.png rename to en/device-dev/driver/figure/architecture-of-the-input-driver-model.png diff --git a/en/device-dev/driver/figures/architecture-of-the-sensor-driver-model.png b/en/device-dev/driver/figure/architecture-of-the-sensor-driver-model.png similarity index 100% rename from en/device-dev/driver/figures/architecture-of-the-sensor-driver-model.png rename to en/device-dev/driver/figure/architecture-of-the-sensor-driver-model.png diff --git a/en/device-dev/driver/figures/common-pins-of-the-touchscreen.png b/en/device-dev/driver/figure/common-pins-of-the-touchscreen.png similarity index 100% rename from en/device-dev/driver/figures/common-pins-of-the-touchscreen.png rename to en/device-dev/driver/figure/common-pins-of-the-touchscreen.png diff --git a/en/device-dev/driver/figures/dsi-transmitting-and-receiving-interface.png b/en/device-dev/driver/figure/dsi-transmitting-and-receiving-interface.png similarity index 100% rename from en/device-dev/driver/figures/dsi-transmitting-and-receiving-interface.png rename to en/device-dev/driver/figure/dsi-transmitting-and-receiving-interface.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001053405727.png b/en/device-dev/driver/figure/en-us_image_0000001053405727.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001053405727.png rename to en/device-dev/driver/figure/en-us_image_0000001053405727.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054280608.png b/en/device-dev/driver/figure/en-us_image_0000001054280608.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054280608.png rename to en/device-dev/driver/figure/en-us_image_0000001054280608.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054564784.png b/en/device-dev/driver/figure/en-us_image_0000001054564784.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054564784.png rename to en/device-dev/driver/figure/en-us_image_0000001054564784.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001057902344.png b/en/device-dev/driver/figure/en-us_image_0000001123509750.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001057902344.png rename to en/device-dev/driver/figure/en-us_image_0000001123509750.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001072553354.png b/en/device-dev/driver/figure/en-us_image_0000001123514210.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001072553354.png rename to en/device-dev/driver/figure/en-us_image_0000001123514210.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054440624.png b/en/device-dev/driver/figure/en-us_image_0000001123540984.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054440624.png rename to en/device-dev/driver/figure/en-us_image_0000001123540984.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054007499.png b/en/device-dev/driver/figure/en-us_image_0000001123582482.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054007499.png rename to en/device-dev/driver/figure/en-us_image_0000001123582482.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054728498.png b/en/device-dev/driver/figure/en-us_image_0000001123675706.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054728498.png rename to en/device-dev/driver/figure/en-us_image_0000001123675706.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054726248.png b/en/device-dev/driver/figure/en-us_image_0000001123703482.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054726248.png rename to en/device-dev/driver/figure/en-us_image_0000001123703482.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054142582.png b/en/device-dev/driver/figure/en-us_image_0000001123742254.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054142582.png rename to en/device-dev/driver/figure/en-us_image_0000001123742254.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001057342245.png b/en/device-dev/driver/figure/en-us_image_0000001170187071.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001057342245.png rename to en/device-dev/driver/figure/en-us_image_0000001170187071.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054006983.png b/en/device-dev/driver/figure/en-us_image_0000001170227689.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054006983.png rename to en/device-dev/driver/figure/en-us_image_0000001170227689.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001057622716.png b/en/device-dev/driver/figure/en-us_image_0000001170229891.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001057622716.png rename to en/device-dev/driver/figure/en-us_image_0000001170229891.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001053926237.png b/en/device-dev/driver/figure/en-us_image_0000001170262141.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001053926237.png rename to en/device-dev/driver/figure/en-us_image_0000001170262141.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001055299108.png b/en/device-dev/driver/figure/en-us_image_0000001170383063.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001055299108.png rename to en/device-dev/driver/figure/en-us_image_0000001170383063.png diff --git a/en/device-dev/driver/figures/mipi-dsi.png b/en/device-dev/driver/figure/mipi-dsi.png similarity index 100% rename from en/device-dev/driver/figures/mipi-dsi.png rename to en/device-dev/driver/figure/mipi-dsi.png diff --git a/en/device-dev/driver/figures/physical-connection-diagram-for-i2c.png b/en/device-dev/driver/figure/physical-connection-diagram-for-i2c.png similarity index 100% rename from en/device-dev/driver/figures/physical-connection-diagram-for-i2c.png rename to en/device-dev/driver/figure/physical-connection-diagram-for-i2c.png diff --git a/en/device-dev/driver/figures/ttl-interface.png b/en/device-dev/driver/figure/ttl-interface.png similarity index 100% rename from en/device-dev/driver/figures/ttl-interface.png rename to en/device-dev/driver/figure/ttl-interface.png diff --git "a/en/device-dev/driver/figures/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" "b/en/device-dev/driver/figure/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" similarity index 100% rename from "en/device-dev/driver/figures/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" rename to "en/device-dev/driver/figure/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" diff --git a/en/device-dev/driver/gpio.md b/en/device-dev/driver/gpio.md deleted file mode 100644 index a35dc16408feb1ef8d9c6b7ad878a8d99d00fea6..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/gpio.md +++ /dev/null @@ -1,9 +0,0 @@ -# GPIO - -- **[GPIO Overview](gpiooverview.md)** - -- **[GPIO Usage Guidelines](gpiousage-guidelines.md)** - -- **[GPIO Usage Example](gpiousage-example.md)** - - diff --git a/en/device-dev/driver/gpiooverview.md b/en/device-dev/driver/gpiooverview.md deleted file mode 100644 index a05df150d2b1b166350337754bb024e4d58e7e67..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/gpiooverview.md +++ /dev/null @@ -1,85 +0,0 @@ -# GPIO Overview - -- [Introduction](#section15318165672215) -- [Available APIs](#section18977142162418) - -## Introduction - -GPIO is short for general-purpose input/output. Generally, a GPIO controller manages all GPIO pins by group. Each group of GPIO pins is associated with one or more registers. The GPIO pins are operated by reading data from and writing data to the registers. - -The GPIO APIs define a set of standard functions for performing operations on GPIO pins, including: - -- Setting the pin direction, which can be input or output \(High impedance is not supported currently.\) - -- Reading and writing level values, which can be low or high -- Setting an interrupt service routine \(ISR\) function and interrupt trigger mode for a pin -- Enabling or disabling a pin interrupt - -## Available APIs - -**Table 1** APIs available for the GPIO driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

GPIO read/write

-

GpioRead

-

Reads the level value of a GPIO pin.

-

GpioWrite

-

Writes the level value of a GPIO pin.

-

GPIO settings

-

GpioSetDir

-

Sets the direction for a GPIO pin.

-

GpioGetDir

-

Obtains the direction for a GPIO pin.

-

GPIO interrupt settings

-

-

-

-

GpioSetIrq

-

Sets the ISR function for a GPIO pin.

-

GpioUnSetIrq

-

Cancels the setting of the ISR function for a GPIO pin.

-

GpioEnableIrq

-

Enables a GPIO interrupt.

-

GpioDisableIrq

-

Disables a GPIO interrupt.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions provided in this document can be called only in kernel mode. - diff --git a/en/device-dev/driver/gpiousage-example.md b/en/device-dev/driver/gpiousage-example.md deleted file mode 100644 index bfdb21eed1d8feece2e48d130b8d0cea1ae17a58..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/gpiousage-example.md +++ /dev/null @@ -1,79 +0,0 @@ -# GPIO Usage Example - -In this example, we test the interrupt trigger of a GPIO pin as follows: Set the ISR function for the pin, set the trigger mode to rising edge and failing edge, write high and low levels to the pin alternately to generate level fluctuation, and observe the execution of the ISR function. - -Select an idle GPIO pin. This example uses a Hi3516D V300 development board and GPIO pin GPIO10\_3, which is numbered GPIO83. - -You can select an idle GPIO pin based on the development board and schematic diagram. - -``` -#include "gpio_if.h" -#include "hdf_log.h" -#include "osal_irq.h" -#include "osal_time.h" - -static uint32_t g_irqCnt; - -/* ISR function */ -static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) -{ - HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); - g_irqCnt++; /* If the ISR function is triggered, the number of global interrupts is incremented by 1. */ - return GpioDisableIrq(gpio); -} - -/* Test case function */ -static int32_t TestCaseGpioIrqEdge(void) -{ - int32_t ret; - uint16_t valRead; - uint16_t mode; - uint16_t gpio = 83; /* Number of the GPIO pin to test */ - uint32_t timeout; - - /* Set the output direction for the pin. */ - ret = GpioSetDir(gpio, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret); - return ret; - } - - /* Disable the interrupt of the pin. */ - ret = GpioDisableIrq(gpio); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret); - return ret; - } - - /* Set the ISR function for the pin. The trigger mode is both rising edge and falling edge. */ - mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING; - HDF_LOGE("%s: mode:%0x\n", __func__, mode); - ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret); - return ret; - } - - /* Enable the interrupt for this pin. */ - ret = GpioEnableIrq(gpio); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret); - (void)GpioUnSetIrq(gpio); - return ret; - } - - g_irqCnt = 0; /* Reset the global counter. */ - timeout = 0; /* Reset the waiting time. */ - /* Wait for the ISR function of this pin to trigger. The timeout duration is 1000 ms. */ - while (g_irqCnt <= 0 && timeout < 1000) { - (void)GpioRead(gpio, &valRead); - (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); - HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout); - OsalMDelay(200); /* wait for irq trigger */ - timeout += 200; - } - (void)GpioUnSetIrq(gpio); - return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; -} -``` - diff --git a/en/device-dev/driver/gpiousage-guidelines.md b/en/device-dev/driver/gpiousage-guidelines.md deleted file mode 100644 index 67c29e26454fde7b66ef285e993d01d08f09d8ba..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/gpiousage-guidelines.md +++ /dev/null @@ -1,395 +0,0 @@ -# GPIO Usage Guidelines - -- [How to Use](#section1583613406410) -- [Determining a GPIO Pin Number](#section135943361443) -- [Using APIs to Operate GPIO Pins](#section69151114115315) - -## How to Use - -The GPIO APIs use the GPIO pin number to specify a pin. [Figure 1](#fig1399416053717) shows the general process of using a GPIO. - -**Figure 1** Process of using a GPIO - - -![](figures/en-us_image_0000001057342245.png) - -## Determining a GPIO Pin Number - -The method for converting GPIO pin numbers varies according to the GPIO controller model, parameters, and controller driver of different system on chips \(SoCs\). - -- Hi3516D V300 - - A controller manages 12 groups of GPIO pins. Each group contains 8 GPIO pins. - - GPIO pin number = GPIO group index \(0-11\) x Number of GPIO pins in each group \(8\) + Offset in the group - - Example: GPIO number of GPIO10\_3 = 10 x 8 + 3 = 83 - -- Hi3518E V300 - - A controller manages 10 groups of GPIO pins. Each group contains 10 GPIO pins. - - GPIO pin number = GPIO group index \(0–9\) x Number of GPIO pins in each group \(10\) + Offset in the group - - Example: GPIO pin number of GPIO7\_3 = 7 x 10 + 3 = 73 - - -## Using APIs to Operate GPIO Pins - -- Set the direction for a GPIO pin. - - Before performing read/write operations on a GPIO pin, call the following function to set the direction: - - int32\_t GpioSetDir\(uint16\_t gpio, uint16\_t dir\); - - **Table 1** Description of GpioSetDir - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

dir

-

Direction to set.

-

Return Value

-

Description

-

0

-

The setting is successful.

-

Negative value

-

The setting failed.

-
- -- Read or write the level value for a GPIO pin. - - To read the level value of a GPIO pin, call the following function: - - int32\_t GpioRead\(uint16\_t gpio, uint16\_t \*val\); - - **Table 2** Description of GpioRead - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

val

-

Pointer to the level value.

-

Return Value

-

Description

-

0

-

Succeeded in reading the level value.

-

Negative value

-

Failed to read the level value.

-
- - To write the level value for a GPIO pin, call the following function: - - int32\_t GpioWrite\(uint16\_t gpio, uint16\_t val\); - - **Table 3** Description of GpioWrite - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

val

-

Level value to write.

-

Return Value

-

Description

-

0

-

Succeeded in writing the level value.

-

Negative value

-

Failed to write the level value.

-
- - Example: - - ``` - int32_t ret; - uint16_t val; - /* Set the output direction for GPIO3. */ - ret = GpioSetDir(3, GPIO_DIR_OUT); - if (ret != 0) { - HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); - return; - } - /* Write the low level GPIO_VAL_LOW for GPIO3. */ - ret = GpioWrite(3, GPIO_VAL_LOW); - if (ret != 0) { - HDF_LOGE("GpioWrite: failed, ret %d\n", ret); - return; - } - /* Set the input direction for GPIO6. */ - ret = GpioSetDir(6, GPIO_DIR_IN); - if (ret != 0) { - HDF_LOGE("GpioSetDir: failed, ret %d\n", ret); - return; - } - /* Read the level value of GPIO6. */ - ret = GpioRead(6, &val); - ``` - - -- Set the ISR function for a GPIO pin. - - To set the ISR function for a GPIO pin, call the following function: - - int32\_t GpioSetIrq\(uint16\_t gpio, uint16\_t mode, GpioIrqFunc func, void \*arg\); - - **Table 4** Description of GpioSetIrq - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

mode

-

Interrupt trigger mode.

-

func

-

ISR function to set.

-

arg

-

Pointer to the parameters passed to the ISR function.

-

Return Value

-

Description

-

0

-

The setting is successful.

-

Negative value

-

The setting failed.

-
- - >![](public_sys-resources/icon-caution.gif) **CAUTION:** - >Only one ISR function can be set for a GPIO pin at a time. If **GpioSetIrq** is called repeatedly, the previous IRS function will be replaced. - - If the ISR function is no longer required, call the following function to cancel the setting: - - int32\_t GpioUnSetIrq\(uint16\_t gpio\); - - **Table 5** Description of GpioUnSetIrq - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

Return Value

-

Description

-

0

-

The ISR function is canceled.

-

Negative value

-

Failed to cancel the ISR function.

-
- - After the ISR function is set, call the following function to enable a GPIO interrupt: - - int32\_t GpioEnableIrq\(uint16\_t gpio\); - - **Table 6** Description of GpioEnableIrq - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

Return Value

-

Description

-

0

-

The GPIO interrupt is enabled.

-

Negative value

-

Failed to enable a GPIO interrupt.

-
- - >![](public_sys-resources/icon-caution.gif) **CAUTION:** - >The configured ISR function can be responded only after the ISR function is enabled. - - Use the following function to disable the GPIO interrupt: - - int32\_t GpioDisableIrq\(uint16\_t gpio\); - - **Table 7** Description of GpioDisableIrq - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

Return Value

-

Description

-

0

-

The GPIO interrupt is disabled.

-

Negative value

-

Failed to disable the GPIO interrupt.

-
- - Example: - - ``` - /* ISR function */ - */ - int32_t MyCallBackFunc(uint16_t gpio, void *data) - { - HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); - return 0; - } - - int32_t ret; - /* Set the ISR function to MyCallBackFunc, the parameter to NULL, and the interrupt trigger mode to rising edge. */ - ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); - if (ret != 0) { - HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); - return; - } - - /* Enable an interrupt for GPIO3. */ - ret = GpioEnableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); - return; - } - - /* Disable the interrupt for GPIO3. */ - ret = GpioDisableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); - return; - } - - /* Cancel the ISR function for GPIO3. */ - ret = GpioUnSetIrq(3); - if (ret != 0) { - HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); - return; - } - ``` - - diff --git a/en/device-dev/driver/hdf.md b/en/device-dev/driver/hdf.md deleted file mode 100644 index 05183747d4acb2435125a02035725cedc28b5081..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/hdf.md +++ /dev/null @@ -1,15 +0,0 @@ -# HDF - -- **[HDF Overview](hdfoverview.md)** - -- **[Driver Development](driver-development.md)** - -- **[Driver Service Management](driver-service-management.md)** - -- **[Driver Message Mechanism Management](driver-message-mechanism-management.md)** - -- **[Driver Configuration Management](driver-configuration-management.md)** - -- **[HDF Development Example](hdfdevelopment-example.md)** - - diff --git a/en/device-dev/driver/hdfdevelopment-example.md b/en/device-dev/driver/hdfdevelopment-example.md deleted file mode 100644 index 815706650b3e69638f9310ace1bdd00b93f71e38..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/hdfdevelopment-example.md +++ /dev/null @@ -1,238 +0,0 @@ -# HDF Development Example - -- [Adding Configurations](#section27261067111) -- [Compiling the Driver Code](#section177988005) -- [Compiling the Code for Interaction](#section6205173816412) - -The following example shows how to add configurations, implement the driver code, and compile the code for interaction between the user-level applications and the driver. - -## Adding Configurations - -Add the driver configurations to the HDF configuration file \(for example, **vendor/hisilicon/xxx/config/device\_info**\). Example: - -``` -root { - device_info { - match_attr = "hdf_manager"; - template host { - hostName = ""; - priority = 100; - template device { - template deviceNode { - policy = 0; - priority = 100; - preload = 0; - permission = 0664; - moduleName = ""; - serviceName = ""; - deviceMatchAttr = ""; - } - } - } - sample_host :: host { - hostName = "sample_host"; - sample_device :: device { - device0 :: deviceNode { - policy = 2; - priority = 100; - preload = 1; - permission = 0664; - moduleName = "sample_driver"; - serviceName = "sample_service"; - } - } - } - } -} -``` - -## Compiling the Driver Code - -A sample of driver code compiled based on the HDF is as follows: - -``` -#include -#include -#include -#include "hdf_log.h" -#include "hdf_base.h" -#include "hdf_device_desc.h" - -#define HDF_LOG_TAG "sample_driver" - -#define SAMPLE_WRITE_READ 123 - -int32_t HdfSampleDriverDispatch( - struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply) -{ - HDF_LOGE("%s: received cmd %d", __func__, id); - if (id == SAMPLE_WRITE_READ) { - const char *readData = HdfSbufReadString(data); - if (readData != NULL) { - HDF_LOGE("%s: read data is: %s", __func__, readData); - } - if (!HdfSbufWriteInt32(reply, INT32_MAX)) { - HDF_LOGE("%s: reply int32 fail", __func__); - } - return HdfDeviceSendEvent(deviceObject, id, data); - } - return HDF_FAILURE; -} - -void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) -{ - // Release resources here - return; -} - -int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) -{ - if (deviceObject == NULL) { - return HDF_FAILURE; - } - static struct IDeviceIoService testService = { - .Dispatch = HdfSampleDriverDispatch, - }; - deviceObject->service = &testService; - return HDF_SUCCESS; -} - -int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) -{ - if (deviceObject == NULL) { - HDF_LOGE("%s::ptr is null!", __func__); - return HDF_FAILURE; - } - HDF_LOGE("Sample driver Init success"); - return HDF_SUCCESS; -} - -struct HdfDriverEntry g_sampleDriverEntry = { - .moduleVersion = 1, - .moduleName = "sample_driver", - .Bind = HdfSampleDriverBind, - .Init = HdfSampleDriverInit, - .Release = HdfSampleDriverRelease, -}; - -HDF_INIT(g_sampleDriverEntry); -``` - -## Compiling the Code for Interaction - -A sample code for interaction between the user-level application and driver compiled based on the HDF is as follows: - -``` -#include -#include -#include -#include -#include "hdf_log.h" -#include "hdf_sbuf.h" -#include "hdf_io_service_if.h" - -#define HDF_LOG_TAG "sample_test" -#define SAMPLE_SERVICE_NAME "sample_service" - -#define SAMPLE_WRITE_READ 123 - -int g_replyFlag = 0; - -static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) -{ - const char *string = HdfSbufReadString(data); - if (string == NULL) { - HDF_LOGE("fail to read string in event data"); - g_replyFlag = 1; - return HDF_FAILURE; - } - HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string); - g_replyFlag = 1; - return HDF_SUCCESS; -} - -static int SendEvent(struct HdfIoService *serv, char *eventData) -{ - int ret = 0; - struct HdfSBuf *data = HdfSBufObtainDefaultSize(); - if (data == NULL) { - HDF_LOGE("fail to obtain sbuf data"); - return 1; - } - - struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); - if (reply == NULL) { - HDF_LOGE("fail to obtain sbuf reply"); - ret = HDF_DEV_ERR_NO_MEMORY; - goto out; - } - - if (!HdfSbufWriteString(data, eventData)) { - HDF_LOGE("fail to write sbuf"); - ret = HDF_FAILURE; - goto out; - } - - ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); - if (ret != HDF_SUCCESS) { - HDF_LOGE("fail to send service call"); - goto out; - } - - int replyData = 0; - if (!HdfSbufReadInt32(reply, &replyData)) { - HDF_LOGE("fail to get service call reply"); - ret = HDF_ERR_INVALID_OBJECT; - goto out; - } - HDF_LOGE("Get reply is: %d", replyData); -out: - HdfSBufRecycle(data); - HdfSBufRecycle(reply); - return ret; -} - -int main() -{ - char *sendData = "default event info"; - struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME); - if (serv == NULL) { - HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME); - return HDF_FAILURE; - } - - static struct HdfDevEventlistener listener = { - .callBack = OnDevEventReceived, - .priv ="Service0" - }; - - if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) { - HDF_LOGE("fail to register event listener"); - return HDF_FAILURE; - } - if (SendEvent(serv, sendData)) { - HDF_LOGE("fail to send event"); - return HDF_FAILURE; - } - - while (g_replyFlag == 0) { - sleep(1); - } - - if (HdfDeviceUnregisterEventListener(serv, &listener)) { - HDF_LOGE("fail to unregister listener"); - return HDF_FAILURE; - } - - HdfIoServiceRecycle(serv); - return HDF_SUCCESS; -} -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The code compilation of user-level applications depends on the dynamic libraries **hdf\_core** and **osal** provided by the HDF because user-level applications use the message sending interface of the HDF. In the GN compilation file, add the following dependency relationships: ->deps = \[ ->"//drivers/adapter/lite/uhdf/manager:hdf\_core", ->"//drivers/adapter/lite/uhdf/posix:hdf\_posix\_osal", ->\] - diff --git a/en/device-dev/driver/i2c-overview.md b/en/device-dev/driver/i2c-overview.md deleted file mode 100644 index 407a149be21029b30d63559117a93b846ce70c00..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/i2c-overview.md +++ /dev/null @@ -1,60 +0,0 @@ -# I2C Overview - -- [Introduction](#section5361140416) -- [Available APIs](#section7606310210) - -## Introduction - -- The Inter-Integrated Circuit \(I2C\) is a simple, bidirectional, and synchronous serial bus that uses merely two wires. -- In an I2C communication, one controller communicates with one or more devices through the serial data line \(SDA\) and serial clock line \(SCL\), as shown in [Figure 1](#fig1135561232714). - -- I2C data transfer must begin with a **START** condition and end with a **STOP** condition. Data is transmitted byte-by-byte from the most significant bit to the least significant bit. -- Each I2C node is recognized by a unique address and can serve as either a controller or a device. When the controller needs to communicate with a device, it writes the device address to the bus through broadcast. A device matching this address sends a response to set up a data transfer channel. - -- The I2C APIs define a set of common functions for I2C data transfer, including: - - - I2C controller management: opening or closing an I2C controller - - I2C message transfer: custom transfer by using a message array - - **Figure 1** Physical connection diagram for I2C - ![](figures/physical-connection-diagram-for-i2c.png "physical-connection-diagram-for-i2c") - - -## Available APIs - -**Table 1** APIs available for the I2C driver - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

I2C controller management

-

I2cOpen

-

Opens an I2C controller.

-

I2cClose

-

Closes an I2C controller.

-

I2C message transfer

-

I2cTransfer

-

Performs a custom transfer.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions provided in this document can be called only in kernel mode. - diff --git a/en/device-dev/driver/i2c-usage-example.md b/en/device-dev/driver/i2c-usage-example.md deleted file mode 100644 index 438961611a6aba9bcb7e9a89617650a63e7dcd36..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/i2c-usage-example.md +++ /dev/null @@ -1,192 +0,0 @@ -# I2C Usage Example - -This example describes how to use I2C APIs by using an I2C device on a development board. - -This example shows a simple register read/write operation on TouchPad on a Hi3516D V300 development board. The basic hardware information is as follows: - -- SoC: hi3516dv300 - -- Touch IC: The I2C address is 0x38, and the bit width of Touch IC's internal register is 1 byte. - -- Schematic diagram: TouchPad is mounted to I2C controller 3. The reset pin of Touch IC is GPIO3. - -In this example, first we reset Touch IC. \(The development board supplies power to Touch IC by default after being powered on, and this use case does not consider the power supply\). Then, we perform a read/wirte operation on an internal register to test whether the I2C channel is normal. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The example focuses on I2C device access and verifies the I2C channel. The read and write values of the device register are not concerned. The behavior caused by the read and write operations on the register is determined by the device itself. - -Example: - -``` -#include "i2c_if.h" /* Header file of I2C APIs */ -#include "gpio_if.h" /* Header file of GPIO APIs */ -#include "hdf_log.h" /* Header file for log APIs */ -#include "osal_io.h" /* Header file of I/O read and write APIs */ -#include "osal_time.h" /* Header file of delay and sleep APIs */ - -/* Define a TP device structure to store I2C and GPIO hardware information. */ -struct TpI2cDevice { - uint16_t rstGpio; /* Reset pin */ - uint16_t busId; /* I2C bus ID */ - uint16_t addr; /* I2C device address */ - uint16_t regLen; /* Register bit width */ - DevHandle i2cHandle; /* I2C controller handle */ -}; - -/* I2C pin I/O configuration. For details, see the SoC register manual. */ -#define I2C3_DATA_REG_ADDR 0x112f008c /* Address of the SDA pin configuration register of I2C controller 3 -#define I2C3_CLK_REG_ADDR 0x112f0090 /* Address of the SCL pin configuration register of I2C controller 3 -#define I2C_REG_CFG 0x5f1 /* Configuration values of SDA and SCL pins of I2C controller 3 - -static void TpSocIoCfg(void) -{ - /* Set the I/O function of the two pins corresponding to I2C controller 3 to I2C. */ - OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR)); - OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR)); -} - -/* Initialize the reset pin of the TP. Pull up the pin for 20 ms, pull down the pin for 50 ms, and then pull up the pin for 20 ms to complete the resetting. */ -static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice) -{ - int32_t ret; - - /* Set the output direction for the reset pin. */ - ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret); - return ret; - } - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(20); - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst low fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(50); - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst high fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(20); - - return HDF_SUCCESS; -} - -/* Use I2cTransfer to encapsulate a register read/write auxiliary function. Use flag to indicate the read or write operation. */ -static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen, uint8_t flag) -{ - int index = 0; - unsigned char regBuf[4] = {0}; - struct I2cMsg msgs[2] = {0}; - - /* Perform length adaptation for the single- or dual-byte register. */ - if (tpDevice->regLen == 1) { - regBuf[index++] = regAddr & 0xFF; - } else { - regBuf[index++] = (regAddr >> 8) & 0xFF; - regBuf[index++] = regAddr & 0xFF; - } - - /* Fill in the I2cMsg message structure. */ - msgs[0].addr = tpDevice->addr; - msgs[0].flags = 0; /* The flag is 0, indicating the write operation. */ - msgs[0].len = tpDevice->regLen; - msgs[0].buf = regBuf; - - msgs[1].addr = tpDevice->addr; - msgs[1].flags = (flag == 1)? I2C_FLAG_READ: 0; /* Add the read flag. */ - msgs[1].len = dataLen; - msgs[1].buf = regData; - - if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) { - HDF_LOGE("%s: i2c read err", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -/* TP register read function */ -static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen) -{ - return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1); -} - -/* TP register write function */ -static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen) -{ - return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0); -} - -/* Main entry of I2C */ -static int32_t TestCaseI2c(void) -{ - int32_t i; - int32_t ret; - unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC }; - unsigned char bufRead[7] = {0}; - static struct TpI2cDevice tpDevice; - - /* I/O pin function configuration */ - TpSocIoCfg(); - - /* Initialize TP device information. */ - tpDevice.rstGpio = 3; - tpDevice.busId = 3; - tpDevice.addr = 0x38; - tpDevice.regLen = 1; - tpDevice.i2cHandle = NULL; - - /* Initialize the GPIO pin. */ - ret = TestCaseGpioInit(&tpDevice); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: gpio init fail!:%d", __func__, ret); - return ret; - } - - /* Open an I2C controller. */ - tpDevice.i2cHandle = I2cOpen(tpDevice.busId); - if (tpDevice.i2cHandle == NULL) { - HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId); - return -1; - } - - /* Continuously write 7-byte data to register 0xD5 of TP-IC. */ - ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret); - I2cClose(tpDevice.i2cHandle); - return -1; - } - OsalMSleep(10); - - /* Continuously read 7-byte data from register 0xDO of TP-IC. */ - ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); - I2cClose(tpDevice.i2cHandle); - return -1; - } - - HDF_LOGE("%s: tp i2c write&read reg success!", __func__); - for (i = 0; i < 7; i++) { - HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]); - } - - /* Close the I2C controller. */ - I2cClose(tpDevice.i2cHandle); - return ret; -} -``` - diff --git a/en/device-dev/driver/i2c-usage-guidelines.md b/en/device-dev/driver/i2c-usage-guidelines.md deleted file mode 100644 index 9a207bcc3878e779d7345ae5b14b18b0b4cdc46b..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/i2c-usage-guidelines.md +++ /dev/null @@ -1,171 +0,0 @@ -# I2C Usage Guidelines - -- [How to Use](#section333203315215) -- [Opening an I2C Controller](#section123631358135713) -- [Performing I2C Communication](#section11091522125812) -- [Closing an I2C Controller](#section13519505589) - -## How to Use - -[Figure 1](#fig166181128151112) illustrates the process of an I2C device. - -**Figure 1** Process of using an I2C device - - -![](figures/en-us_image_0000001057902344.png) - -## Opening an I2C Controller - -Call the following function to open an I2C controller: - -DevHandle I2cOpen\(int16\_t number\); - -**Table 1** Description of I2cOpen - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

number

-

I2C controller ID.

-

Return Value

-

Description

-

NULL

-

Failed to open the I2C controller.

-

Device handle

-

Handle of the I2C controller.

-
- -This example assumes that the system has eight I2C controllers \(numbered from 0 to 7\) and I2C controller 3 is to open. - -``` -DevHandle i2cHandle = NULL; /* I2C controller handle */ - -/* Open an I2C controller. */ -i2cHandle = I2cOpen(3); -if (i2cHandle == NULL) { - HDF_LOGE("I2cOpen: failed\n"); - return; -} -``` - -## Performing I2C Communication - -Use the following function for message transfer: - -int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\); - -**Table 2** Description of I2cTransfer - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Handle of an I2C controller.

-

msgs

-

Message array of the data to transfer.

-

count

-

Length of the message array.

-

Return Value

-

Description

-

Positive integer

-

Number of message structures that are successfully transmitted.

-

Negative value

-

Failed to perform the message transfer.

-
- -The type of an I2C message transfer is defined by **I2cMsg**. Each message structure indicates a read or write operation. Multiple read or write operations can be performed by using a message array. - -``` -int32_t ret; -uint8_t wbuff[2] = { 0x12, 0x13 }; -uint8_t rbuff[2] = { 0 }; -struct I2cMsg msgs[2]; /* Custom message array for transfer */ -msgs[0].buf = wbuff; /* Data to write */ -msgs[0].len = 2; /* The length of the data to write is 2. */ -msgs[0].addr = 0x5A; /* The address of the device to write the data is 0x5A. */ -msgs[0].flags = 0; /* The flag is 0, indicating the write operation. */ -msgs[1].buf = rbuff; /* Data to read */ -msgs[1].len = 2; /* The length of the data to read is 2. */ -msgs[1].addr = 0x5A; /* The address of the device to read the data is 0x5A. */ -msgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ is configured, indicating the read operation. */ -/* Perform a custom transfer to transfer two messages. */ -ret = I2cTransfer(i2cHandle, msgs, 2); -if (ret != 2) { - HDF_LOGE("I2cTransfer: failed, ret %d\n", ret); - return; -} -``` - ->![](public_sys-resources/icon-caution.gif) **CAUTION:** ->- The device address in the **I2cMsg** structure does not contain the read/write flag bit. The read/write information is transferred by the read/write control bit in the member variable **flags**. ->- The **I2cTransfer** function does not limit the number of message structures, which is determined by the I2C controller. ->- The **I2cTransfer** function does not limit the data length of each message structure, which is determined by the I2C controller. ->- The **I2cTransfer** function may cause the system to sleep and therefore cannot be invoked in the interrupt context. - -## Closing an I2C Controller - -Call the following function to close the I2C controller after the communication is complete: - -void I2cClose\(DevHandle handle\); - -**Table 3** Description of I2cClose - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Handle of an I2C controller.

-
- -``` -I2cClose(i2cHandle); /* Close the I2C controller. */ -``` - diff --git a/en/device-dev/driver/i2c.md b/en/device-dev/driver/i2c.md deleted file mode 100644 index 12167aeab9625b16e078335a504c96cf4cfe8422..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/i2c.md +++ /dev/null @@ -1,9 +0,0 @@ -# I2C - -- **[I2C Overview](i2c-overview.md)** - -- **[I2C Usage Guidelines](i2c-usage-guidelines.md)** - -- **[I2C Usage Example](i2c-usage-example.md)** - - diff --git a/en/device-dev/driver/lcd.md b/en/device-dev/driver/lcd.md deleted file mode 100644 index 9930511412c592f0dc36c9fe4b50ee9f206944a9..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/lcd.md +++ /dev/null @@ -1,9 +0,0 @@ -# LCD - -- **[LCD Overview](lcdoverview.md)** - -- **[LCD Development Guidelines](lcddevelopment-guidelines.md)** - -- **[LCD Development Example](lcddevelopment-example.md)** - - diff --git a/en/device-dev/driver/lcddevelopment-example.md b/en/device-dev/driver/lcddevelopment-example.md deleted file mode 100644 index 35122ca4fa69878a8c36e658da23082b0c0084e0..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/lcddevelopment-example.md +++ /dev/null @@ -1,291 +0,0 @@ -# LCD Development Example - -Add the device description. - -``` -/* Description of the display driver */ -display :: host { - hostName = "display_host"; - /* Description of the HDF display driver */ - device_hdf_disp :: device { - device0 :: deviceNode { - policy = 2; - priority = 200; - permission = 0660; - moduleName = "HDF_DISP"; - serviceName = "hdf_disp"; - } - } - /* Description of the driver device at the SoC adapter layer */ - device_hi35xx_disp :: device { - device0 :: deviceNode { - policy = 0; - priority = 199; - moduleName = "HI351XX_DISP"; - } - } - /* Description of the LCD driver */ - device_lcd :: device { - device0 :: deviceNode { - policy = 0; - priority = 100; - preload = 0; - moduleName = "LCD_Sample"; - } - device1 :: deviceNode { - policy = 0; - priority = 100; - preload = 2; - moduleName = "LCD_SampleXX"; - } - } -} -``` - -The following example shows how to adapt to the MIPI device to the Hi35xx series chips at the SoC adapter layer: - -``` -static int32_t MipiDsiInit(struct PanelInfo *info) -{ - int32_t ret; - struct DevHandle *mipiHandle = NULL; - struct MipiCfg cfg; - - mipiHandle = MipiDsiOpen(0); - if (mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - cfg.lane = info->mipi.lane; - cfg.mode = info->mipi.mode; - cfg.format = info->mipi.format; - cfg.burstMode = info->mipi.burstMode; - cfg.timing.xPixels = info->width; - cfg.timing.hsaPixels = info->hsw; - cfg.timing.hbpPixels = info->hbp; - cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; - cfg.timing.vsaLines = info->vsw; - cfg.timing.vbpLines = info->vbp; - cfg.timing.vfpLines = info->vfp; - cfg.timing.ylines = info->height; - /* 0 : no care */ - cfg.timing.edpiCmdSize = 0; - cfg.pixelClk = CalcPixelClk(info); - cfg.phyDataRate = CalcDataRate(info); - /* config mipi device */ - ret = MipiDsiSetCfg(mipiHandle, &cfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); - } - MipiDsiClose(mipiHandle); - HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, - cfg.pixelClk, cfg.phyDataRate); - return ret; -} -``` - -The following example shows code for developing an LCD driver: - -``` -#define RESET_GPIO 5 -#define MIPI_DSI0 0 -#define BLK_PWM1 1 -#define PWM_MAX_PERIOD 100000 -/* backlight setting */ -#define MIN_LEVEL 0 -#define MAX_LEVEL 255 -#define DEFAULT_LEVEL 100 - -#define WIDTH 480 -#define HEIGHT 960 -#define HORIZONTAL_BACK_PORCH 20 -#define HORIZONTAL_FRONT_PORCH 20 -#define HORIZONTAL_SYNC_WIDTH 10 -#define VERTIACL_BACK_PORCH 14 -#define VERTIACL_FRONT_PORCH 16 -#define VERTIACL_SYNC_WIDTH 2 -#define FRAME_RATE 60 - -/* Panel information structure */ -struct PanelInfo { - uint32_t width; - uint32_t height; - uint32_t hbp; - uint32_t hfp; - uint32_t hsw; - uint32_t vbp; - uint32_t vfp; - uint32_t vsw; - uint32_t frameRate; - enum LcdIntfType intfType; - enum IntfSync intfSync; - struct MipiDsiDesc mipi; - struct BlkDesc blk; - struct PwmCfg pwm; -}; - -/* Initialization sequence of the LCD panel */ -static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; -static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; -static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; -static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; -static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; -static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; -static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; -static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; -static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; -static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; -static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; -static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; -static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; -static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; -static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; -static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; -static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; -static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; -static uint8_t g_payLoad18[] = { - 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, - 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, - 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 -}; -static uint8_t g_payLoad19[] = { 0x11 }; -static uint8_t g_payLoad20[] = { 0x29 }; - -struct DsiCmdDesc g_OnCmd[] = { - { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, - { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, - { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, - { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, - { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, - { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, - { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, - { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, - { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, - { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, - { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, - { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, - { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, - { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, - { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, - { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, - { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, - { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, - { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, - { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, - { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, -}; -static DevHandle g_mipiHandle = NULL; -static DevHandle g_pwmHandle = NULL; - -/* Set the status of the reset pin. */ -static int32_t LcdResetOn(void) -{ - int32_t ret; - ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioSetDir failure, ret:%d", ret); - return HDF_FAILURE; - } - ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioWrite failure, ret:%d", ret); - return HDF_FAILURE; - } - /* delay 20ms */ - OsalMSleep(20); - return HDF_SUCCESS; -} - -static int32_t SampleInit(void) -{ - /* Obtain the MIPI DSI device handle. */ - g_mipiHandle = MipiDsiOpen(MIPI_DSI0); - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -static int32_t SampleOn(void) -{ - int32_t ret; - /* Power on the LCD. */ - ret = LcdResetOn(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: LcdResetOn failure", __func__); - return HDF_FAILURE; - } - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: g_mipiHandle is null", __func__); - return HDF_FAILURE; - } - /* Send the initialization sequence via MIPI. */ - int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); - int32_t i; - for (i = 0; i < count; i++) { - ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); - if (ret != HDF_SUCCESS) { - HDF_LOGE("MipiDsiTx failure"); - return HDF_FAILURE; - } - } - /* Set MIPI to the high speed (HS) mode. */ - MipiDsiSetHsMode(g_mipiHandle); - return HDF_SUCCESS; -} - -/* PanelInfo structure variables */ -static struct PanelInfo g_panelInfo = { - .width = WIDTH, /* width */ - .height = HEIGHT, /* height */ - .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ - .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ - .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ - .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ - .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ - .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ - .frameRate = FRAME_RATE, /* frame rate */ - .intfType = MIPI_DSI, /* panel interface type */ - .intfSync = OUTPUT_USER, /* output timming type */ - /* mipi config info */ - .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, - /* backlight config info */ - .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, - .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, -}; - -/* Basic APIs that need to be adapted for the chip driver */ -static struct PanelData g_panelData = { - .info = &g_panelInfo, - .init = SampleInit, - .on = SampleOn, - .off = SampleOff, - .setBacklight = SampleSetBacklight, -}; - -/* Entry function of the chip driver */ -int32_t SampleEntryInit(struct HdfDeviceObject *object) -{ - HDF_LOGI("%s: enter", __func__); - if (object == NULL) { - HDF_LOGE("%s: param is null!", __func__); - return HDF_FAILURE; - } - /* Register the chip driver APIs with the platform driver. */ - if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { - HDF_LOGE("%s: PanelDataRegister error!", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -struct HdfDriverEntry g_sampleDevEntry = { - .moduleVersion = 1, - .moduleName = "LCD_SAMPLE", - .Init = SampleEntryInit, -}; - -HDF_INIT(g_sampleDevEntry); -``` - diff --git a/en/device-dev/driver/lcddevelopment-guidelines.md b/en/device-dev/driver/lcddevelopment-guidelines.md deleted file mode 100644 index a7d0f9cb7453fe32c2c9448eba76bd2cac09ec45..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/lcddevelopment-guidelines.md +++ /dev/null @@ -1,23 +0,0 @@ -# LCD Development Guidelines - -- [How to Develop](#section3904154911218) - -The display driver model is developed based on the HDF, platform APIs, and APIs at the OS abstraction layer \(OSAL\), and provides a unified driver model for the LCD regardless of the OS \(LiteOS or Linux OS\) and chip platforms \(such as Hi35xx, Hi38xx, and V3S\). - -## How to Develop - -1. Add the LCD driver-related hardware descriptions. -2. Add a driver that adapts to the chip at the SoC adapter layer. -3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for: - - Powering on/off the LCD device - - Based on the LCD hardware connection, use the GPIO interfaces provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier. - - - Sending the initialization sequence - - Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier. - - -4. Implement other HDF interfaces as required, for example, the **Release** interface. -5. Use the HDF to create other device nodes for implementing service logic or debugging as required. - diff --git a/en/device-dev/driver/lcdoverview.md b/en/device-dev/driver/lcdoverview.md deleted file mode 100644 index 08ba05e1f409a702a3b4334ce7124a4e80f5af57..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/lcdoverview.md +++ /dev/null @@ -1,46 +0,0 @@ -# LCD Overview - -- [Introduction](#section3781515122118) -- [API Description](#section20280192712120) - -## Introduction - -The Liquid Crystal Display \(LCD\) driver powers on the LCD and initializes internal LCD registers APIs to enable the LCD to work properly. The display driver is developed based on the hardware driver foundation \([HDF](hdfoverview.md)\). It provides power-on, power-off, and sending of the initialization sequence for LCD hardware across OSs and platforms. The display driver model is shown in [Figure 1](#fig69138814229). - -**Figure 1** Architecture of the display driver model -![](figures/architecture-of-the-display-driver-model.png "architecture-of-the-display-driver-model") - -- **Display driver model** - - The display driver model consists of the display common driver layer, SoC adapter layer, and third-party chip driver layer. It is developed based on the HDF and hides the differences between kernel forms through platform and OSAL APIs so the LCD driver can be migrated to different OSs and chip platforms. The display driver connects to the display common HAL, supports the implementation of Hardware Driver Interfaces \(HDIs\), and provides various driver interfaces for the graphics service through the display HDI. - - - Display common driver layer: connects to the display common HAL through the IOService data channel provided by the HDF to receive and process various upper-layer calls in a centralized manner. - - - SoC adapter layer: decouples the display driver from the SoC driver, configures parameters related to the chip platform, and passes the calls at the platform driver layer to the LCD driver layer. - - - Third-party chip driver layer: provides LCD-related APIs for sending the LCD initialization sequence, powering on or off the LCD device, and setting the backlight. - - Based on the display driver model, various capabilities, and APIs, you can greatly simplify the display driver development and improve the efficiency. - - -## API Description - -The LCD interfaces are classified into the Mobile Industry Processor Interface \(MIPI\) Display Serial Interface \(DSI\), Transistor Transistor Logic \(TTL\) interfaces, and Low Voltage Differential Signaling \(LVDS\) interfaces. The MIPI DSI and TTL interfaces are commonly used. Here is a brief introduction to them. - -- MIPI DSI - - **Figure 2** MIPI DSI - ![](figures/mipi-dsi.png "mipi-dsi") - - The MIPI DSI is defined by MIPI Alliance. It is mainly used for mobile terminal display. The MIPI DSI is used to transmit image data, in compliance with the MIPI protocol. Generally, control information of the MIPI DSI is sent to the peer IC in the form of MIPI packets through the MIPI DSI. No additional interface is required. - -- TTL interface - - **Figure 3** TTL interface - ![](figures/ttl-interface.png "ttl-interface") - - TTL level signals are generated by TTL devices, which are a major type of digital integrated circuits. They are manufactured using the bipolar process and feature high speed, low power consumption, and multiple types. - - The TTL interface is used to transmit data in parallel mode. It transmits data signals, clock signals, and control signals \(such as line synchronization signals, frame synchronization signals, and data validity signals\) under the control of control signals. Generally, the LCD of the TTL interface and the read/write of internal registers require additional peripheral interfaces, such as the Serial Peripheral Interface \(SPI\) and Inter-Integrated Circuit \(I2C\). - - diff --git a/en/device-dev/driver/mipi-dsi-overview.md b/en/device-dev/driver/mipi-dsi-overview.md deleted file mode 100644 index ec579fba093ecad64f31fd5d00b429878829a652..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/mipi-dsi-overview.md +++ /dev/null @@ -1,84 +0,0 @@ -# MIPI DSI Overview - -- [Introduction](#section1369320102013) -- [Available APIs](#section6577545192317) - -## Introduction - -- The Display Serial Interface \(DSI\) is a specification stipulated by the Mobile Industry Processor Interface \(MIPI\) Alliance, aiming to reduce the cost of display controllers in a mobile device. It defines a serial bus and communication protocol among the host, the source of image data, and the target device. In this way, the DSI can send pixel data or commands to peripherals \(usually LCDs or similar display devices\) in serial mode, or reads information such as status and pixel from the peripherals. - -- MIPI DSI is capable of working in both high speed \(HS\) mode and low power \(LP\) mode. All data lanes can only travel from the DSI host to a peripheral in HS mode, except the first data lane, which can also receive data such as status information and pixels from the peripheral in LP mode. The clock lane is dedicated to transmitting synchronization clock signals in HS mode. - - [Figure 1](#fig1122611461203) shows a simplified DSI interface. Conceptually, a DSI-compliant interface has the same features as interfaces complying with DBI-2 and DPI-2 standards. It sends pixels or commands to a peripheral and can read status or pixel information from the peripheral. The main difference is that the DSI serializes all pixel data, commands, and events that, in traditional interfaces, are conveyed to and from the peripheral on a parallel data bus with additional control signals. - - **Figure 1** DSI transmitting and receiving Interface - ![](figures/dsi-transmitting-and-receiving-interface.png "dsi-transmitting-and-receiving-interface") - - - -## Available APIs - -**Table 1** APIs for MIPI DSI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

Setting/Obtaining MIPI DSI configuration parameters

-

MipiDsiSetCfg

-

Sets configuration parameters for a MIPI DSI device.

-

MipiDsiGetCfg

-

Obtains the configuration parameters of a MIPI DSI device.

-

Obtaining /Releasing device handles

-

MipiDsiOpen

-

Obtains a MIPI DSI device handle.

-

MipiDsiClose

-

Releases a specified MIPI DSI device handle.

-

Setting the LP or HS mode

-

MipiDsiSetLpMode

-

Sets LP mode for a MIPI DSI device.

-

MipiDsiSetHsMode

-

Sets HS mode for a MIPI DSI device.

-

Reading/Sending commands

-

MipiDsiTx

-

Sends a display command set (DCS) command for sending data.

-

MipiDsiRx

-

Receives a DCS command for reading data with the specified length.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions described in this document can be called only in kernel space. - diff --git a/en/device-dev/driver/mipi-dsi.md b/en/device-dev/driver/mipi-dsi.md deleted file mode 100644 index f50672962f5c2602a93f63821ac290de3271ad02..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/mipi-dsi.md +++ /dev/null @@ -1,9 +0,0 @@ -# MIPI DSI - -- **[MIPI DSI Overview](mipi-dsi-overview.md)** - -- **[Usage Guidelines](usage-guidelines.md)** - -- **[Usage Example](usage-example.md)** - - diff --git a/en/device-dev/driver/peripherals.md b/en/device-dev/driver/peripherals.md deleted file mode 100644 index 42016f572c98cb63bfd17d6994f67367f3c8bc5d..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/peripherals.md +++ /dev/null @@ -1,11 +0,0 @@ -# Peripherals - -- **[LCD](lcd.md)** - -- **[TOUCHSCREEN](touchscreen.md)** - -- **[SENSOR](sensor.md)** - -- **[WLAN](wlan.md)** - - diff --git a/en/device-dev/driver/rtc-overview.md b/en/device-dev/driver/rtc-overview.md deleted file mode 100644 index 97aa8a24369a26fed6689751accb5ab46ce7fa89..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/rtc-overview.md +++ /dev/null @@ -1,103 +0,0 @@ -# RTC Overview - -- [Introduction](#section104842041574) -- [Available APIs](#section16892932155715) - -## Introduction - -The real-time clock \(RTC\) driver provides precise real time for the operating system \(OS\). If the OS is powered off, the RTC driver continues to keep track of the system time using an external battery. - -## Available APIs - -**Table 1** APIs provided by the RTC driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

RTC handle

-

RtcOpen

-

Opens the RTC device to obtain its handle.

-

RtcClose

-

Releases a specified handle of the RTC device.

-

RTC time

-

RtcReadTime

-

Reads time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.

-

RtcWriteTime

-

Writes time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.

-

RTC alarm

-

RtcReadAlarm

-

Reads the RTC alarm time that was set last time.

-

RtcWriteAlarm

-

Writes the RTC alarm time based on the alarm index.

-

RtcRegisterAlarmCallback

-

Registers RtcAlarmCallback that will be invoked when an alarm is generated at the specified time.

-

RtcAlarmInterruptEnable

-

Enables or disables RTC alarm interrupts.

-

RTC configuration

-

RtcGetFreq

-

Reads the frequency of the external crystal oscillator connected to the RTC driver.

-

RtcSetFreq

-

Sets the frequency of the external crystal oscillator connected to the RTC driver.

-

RtcReset

-

Resets the RTC.

-

Custom register

-

RtcReadReg

-

Reads the configuration of a custom RTC register based on the register index.

-

RtcWriteReg

-

Writes the configuration of a custom RTC register based on the register index.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions provided in this document can be called only in kernel mode. - diff --git a/en/device-dev/driver/rtc-usage-example.md b/en/device-dev/driver/rtc-usage-example.md deleted file mode 100644 index e546c2f1433a2ce6810b93b43fd26f4c17f8e5a7..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/rtc-usage-example.md +++ /dev/null @@ -1,97 +0,0 @@ -# RTC Usage Example - -This section describes the process of using RTC APIs: - -1. During the OS startup, the HDF identifies the RTC component in the system. -2. The HDF initializes and creates the RTC device. -3. You can perform operations on the RTC device by calling different APIs. -4. Call the **RtcClose** function to release the device handle and device resources. - -Example: - -``` -#include "rtc_if.h" -int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) -{ - if (alarmIndex == RTC_ALARM_INDEX_A) { - /* Process alarm A. */ - printf("RTC Alarm A callback function\n\r"); - } else if (alarmIndex == RTC_ALARM_INDEX_B) { - /* Process alarm B. */ - printf("RTC Alarm B callback function\n\r"); - } else { - /* Process the error. */ - } - return 0; -} - -void RtcTestSample(void) -{ - int32_t ret; - struct RtcTime tm; - struct RtcTime alarmTime; - uint32_t freq; - DevHandle handle = NULL; - - /* Obtain the RTC device handle. */ - handle = RtcOpen(); - if (handle == NULL) { - /* Process the error. */ - } - /* Register RtcAlarmCallback for alarm A. */ - ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); - if (ret != 0) { - /* Process the error. */ - } - /* Set the RTC external crystal frequency. Note that the frequency must be configured in accordance with the requirements specified in the product manual of the in-use component. */ - freq = 32768; /* 32768 Hz */ - ret = RtcSetFreq(handle, freq); - if (ret != 0) { - /* Process the error. */ - } - /* Enable the RTC alarm interrupts. */ - ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); - if (ret != 0) { - /* Process the error. */ - } - /* Set the RTC time to 2020/01/01 00:00:10 .990. */ - tm.year = 2020; - tm.month = 01; - tm.day = 01; - tm.hour= 0; - tm.minute = 0; - tm.second = 10; - tm.millisecond = 990; - /* Write the RTC time information. */ - ret = RtcWriteTime(handle, &tm); - if (ret != 0) { - /* Process the error. */ - } - /* Set the RTC alarm time to 2020/01/01 00:00:30 .100. */ - alarmTime.year = 2020; - alarmTime.month = 01; - alarmTime.day = 01; - alarmTime.hour = 0; - alarmTime.minute = 0; - alarmTime.second = 30; - alarmTime.millisecond = 100; - /* Set the alarm time information for RTC_ALARM_INDEX_A. When the specified time is reached, "RTC Alarm A callback function" is printed. */ - ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); - if (ret != 0) { - /* Process the error. */ - } - - /* Read the RTC real time. */ - ret = RtcReadTime(handle, &tm); - if (ret != 0) { - /* Process the error. */ - } - sleep(5) - printf("RTC read time:\n\r"); - printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", - tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); - /* Release the RTC device handle. */ - RtcClose(handle); -} -``` - diff --git a/en/device-dev/driver/rtc-usage-guidelines.md b/en/device-dev/driver/rtc-usage-guidelines.md deleted file mode 100644 index 3d0a2f6638021e4ab54ec680a06b134a873685b8..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/rtc-usage-guidelines.md +++ /dev/null @@ -1,741 +0,0 @@ -# RTC Usage Guidelines - -- [How to Use](#section620515765714) -- [Creating an RTC Device Handle](#section0702183665711) -- [Releasing the RTC Device Handle](#section639962619542) -- [Registering RtcAlarmCallback](#section123631358135713) -- [Performing RTC-related Operations](#section11091522125812) - -## How to Use - -During the OS startup, the HDF loads the RTC driver based on the configuration file. The RTC driver detects the RTC component and initializes the driver. - -[Figure 1](#fig166181128151112) illustrates the process of an RTC device. - -**Figure 1** Process of using an RTC device - - -![](figures/en-us_image_0000001054728498.png) - -## Creating an RTC Device Handle - -After the RTC driver is loaded successfully, you can use the API provided by the HDF and call APIs of the RTC driver. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Currently, only one RTC device is supported in the OS. - -DevHandle RtcOpen\(void\); - -**Table 1** Description of **RtcOpen** - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

void

-

N/A

-

Return Value

-

Description

-

handle

-

Returns the pointer if the operation is successful.

-

NULL

-

The operation fails.

-
- -``` -DevHandle handle = NULL; - -/* Obtain the RTC device handle. */ -handle = RtcOpen(); -if (handle == NULL) { - /* Process the error. */ -} -``` - -## Releasing the RTC Device Handle - -You can call the following function to release the RTC device handle, thereby releasing resources of the device: - -void RtcClose\(DevHandle handle\); - -**Table 2** Description of **RtcClose** - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle

-
- -``` -/* Release the RTC device handle. */ -RtcClose(handle); -``` - -## Registering RtcAlarmCallback - -After the OS is started, call the following function to register **RtcAlarmCallback**, which will be invoked when an alarm is generated at the specified time: - -int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\); - -**Table 3** Description of **RtcRegisterAlarmCallback** - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

cb

-

Callback that will be invoked when an alarm is generated at the specified time.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -The following is an example of registering **RtcAlarmCallback** for processing alarm **RTC\_ALARM\_INDEX\_A**: - -``` -/* Register an RTC alarm callback. */ -int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) -{ - if (alarmIndex == RTC_ALARM_INDEX_A) { - /* Process alarm A. */ - } else if (alarmIndex == RTC_ALARM_INDEX_B) { - /* Process alarm B. */ - } else { - /* Process the error. */ - } - return 0; -} -int32_t ret; -/* Register RtcAlarmCallback for alarm A. */ -ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); -if (ret != 0) { - /* Process the error. */ -} -``` - -## Performing RTC-related Operations - -- Reading RTC time - -Call the following function to read time information from the RTC driver, including the year, month, the day fo the week, day, hour, minute, second, and millisecond: - -int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\); - -**Table 4** Description of **RtcReadTime** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

time

-

Pointer to the time information read from the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; -struct RtcTime tm; - -/* Read time information from the RTC driver. */ -ret = RtcReadTime(handle, &tm); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Setting RTC time - -Call the following function to set the RTC time: - -int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\); - -**Table 5** Description of **RtcWriteTime** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

time

-

Pointer to the time information written into the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week. - -``` -int32_t ret; -struct RtcTime tm; - -/* Set the RTC time to UTC 2020/01/01 00:59:00 .000. */ -tm.year = 2020; -tm.month = 01; -tm.day = 01; -tm.hour= 00; -tm.minute = 59; -tm.second = 00; -tm.millisecond = 0; -/* Write the RTC time information. */ -ret = RtcWriteTime(handle, &tm); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Reading the RTC alarm time - -Call the following function to read the alarm time: - -int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); - -**Table 6** Description of **RtcReadAlarm** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

time

-

Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; -struct RtcTime alarmTime; - -/* Read the RTC alarm time information of alarm RTC_ALARM_INDEX_A. */ -ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Setting RTC alarm time - -Call the following function to set the RTC alarm time based on the alarm index: - -int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); - -**Table 7** Description of **RtcWriteAlarm** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

time

-

Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week. - -``` -int32_t ret; -struct RtcTime alarmTime; - -/* Set the RTC alarm time to 2020/01/01 00:59:59 .000. */ -alarmTime.year = 2020; -alarmTime.month = 01; -alarmTime.day = 01; -alarmTime.hour = 00; -alarmTime.minute = 59; -alarmTime.second = 59; -alarmTime.millisecond = 0; -/* Set the alarm time of alarm RTC_ALARM_INDEX_A. */ -ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Enabling or disabling alarm interrupts - -Before performing alarm operations, use this function to enable alarm interrupts, so that **RtcAlarmCallback** will be called when the alarm is not generated upon a timeout. - -int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\); - -**Table 8** Description of **RtcAlarmInterruptEnable** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

enable

-

Whether to enable RTC alarm interrupts. Value 1 means to enable alarm interrupts and value 0 means to disable alarm interrupts.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; - -/* Enable the RTC alarm interrupts. */ -ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Reading RTC external frequency - -Call the following function to read the frequency of the external crystal oscillator connected to the RTC driver: - -int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\); - -**Table 9** Description of **RtcGetFreq** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

freq

-

Frequency to set for the external crystal oscillator, in Hz.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; -uint32_t freq = 0; - -/* Read frequency of the external crystal oscillator connected to the RTC driver */ -ret = RtcGetFreq(handle, &freq); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Setting the frequency of the external crystal oscillator connected to the RTC driver - -Call the following function to set the frequency of the external crystal oscillator connected to the RTC driver: - -int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\); - -**Table 10** Description of **RtcSetFreq** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

freq

-

Frequency to set for the external crystal oscillator, in Hz.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; -uint32_t freq = 32768; /* 32768 Hz */ - -/* Set the frequency of the external crystal oscillator. Note that the frequency must be configured in accordance with the requirements specified in the product manual of the in-use component. */ -ret = RtcSetFreq(handle, freq); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Resetting the RTC driver - -Call the following function to perform a reset on the RTC driver. After the reset, the registers are restored to the default values: - -int32\_t RtcReset\(DevHandle handle\); - -**Table 11** Description of **RtcReset** - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; - -/* Reset the RTC driver. After the reset, the configuration registers are restored to the default values. */ -ret = RtcReset(handle); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Reading the configuration of a custom RTC register - -Call the following function to read the configuration of a custom RTC register based on the register index \(one index corresponds to one byte of the configuration value\): - -int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\); - -**Table 12** Description of **RtcReadReg** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

usrDefIndex

-

Index of the custom register.

-

value

-

Register value.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; -uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ -uint8_t value = 0; - -/* Read the configuration of a custom RTC register based on the register index. One index corresponds to one byte of the configuration value. */ -ret = RtcReadReg(handle, usrDefIndex, &value); -if (ret != 0) { - /* Process the error. */ -} -``` - -- Setting the configuration of a custom RTC register - -Call the following function to configure a register based on the specified register index \(one index corresponds to one byte of the configuration value\): - -int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\); - -**Table 13** Description of **RtcWriteReg** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

usrDefIndex

-

Index of the custom register.

-

value

-

Register value.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; -uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ -uint8_t value = 0x10; - -/* Configure a register based on the specified register index. One index corresponds to one byte of the configuration value. */ -ret = RtcWriteReg(handle, usrDefIndex, value); -if (ret != 0) { - /* Process the error. */ -} -``` - diff --git a/en/device-dev/driver/rtc.md b/en/device-dev/driver/rtc.md deleted file mode 100644 index 50b89f7b7c1fb24aeac3e2922dce7da627864006..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/rtc.md +++ /dev/null @@ -1,9 +0,0 @@ -# RTC - -- **[RTC Overview](rtc-overview.md)** - -- **[RTC Usage Guidelines](rtc-usage-guidelines.md)** - -- **[RTC Usage Example](rtc-usage-example.md)** - - diff --git a/en/device-dev/driver/sdio.md b/en/device-dev/driver/sdio.md deleted file mode 100644 index 43fb762051920268c93821121065cd4ebec24ecb..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sdio.md +++ /dev/null @@ -1,9 +0,0 @@ -# SDIO - -- **[SDIO Overview](sdiooverview.md)** - -- **[SDIO Usage Guidelines](sdiousage-guidelines.md)** - -- **[SDIO Usage Example](sdiousage-example.md)** - - diff --git a/en/device-dev/driver/sdiooverview.md b/en/device-dev/driver/sdiooverview.md deleted file mode 100644 index 9890cf8f3c60999f90d41db98e8143600066308b..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sdiooverview.md +++ /dev/null @@ -1,149 +0,0 @@ -# SDIO Overview - -- [Introduction](#section1155271783811) -- [Available APIs](#section10204143763819) - -## Introduction - -- Secure Digital Input/Output \(SDIO\) is a peripheral interface evolved from the Secure Digital \(SD\) memory card interface. The SDIO interface is compatible with SD memory cards and can be connected to devices that support the SDIO interface. -- SDIO is widely used. Currently, many smartphones support SDIO, and many SDIO peripherals are developed for connections to smartphones. Common SDIO peripherals include WLAN, GPS, cameras, and Bluetooth. -- The SDIO bus has two ends, named host and device. All communication starts when the host sends a command. The device can communicate with the host as long as it can parse the command of the host. An SDIO host can connect to multiple devices, as shown in the figure below. - - - CLK signal: clock signal sent from the host to the device - - VDD signal: power signal - - VSS signal: ground signal - - D0-3 signal: four data lines. The DAT1 signal cable is multiplexed as the interrupt line. In 1-bit mode, DAT0 is used to transmit data. In 4-bit mode, DAT0 to DAT3 are used to transmit data. - - CMD signal: used by the host to send commands and the device to respond to commands. - - **Figure 1** Connections between the host and devices in SDIO - - - ![](figures/en-us_image_0000001054280608.png) - -- The SDIO interface defines a set of common methods for operating an SDIO device, including opening and closing an SDIO controller, exclusively claiming and releasing the host, enabling and disabling devices, claiming and releasing an SDIO IRQ, reading and writing data based on SDIO, and obtaining and setting common information. - -## Available APIs - -**Table 1** APIs available for the SDIO driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

SDIO device opening/closing

-

SdioOpen

-

Opens an SDIO controller with a specified bus number.

-

SdioClose

-

Closes an SDIO controller.

-

SDIO reading/writing

-

SdioReadBytes

-

Incrementally reads a given length of data from a specified SDIO address.

-

SdioWriteBytes

-

Incrementally writes a given length of data into a specified SDIO address.

-

SdioReadBytesFromFixedAddr

-

Reads a given length of data from a fixed SDIO address.

-

SdioWriteBytesToFixedAddr

-

Writes a given length of data into a fixed SDIO address.

-

SdioReadBytesFromFunc0

-

Reads a given length of data from the address space of SDIO function 0.

-

SdioWriteBytesToFunc0

-

Writes a given length of data into the address space of SDIO function 0.

-

SDIO block size setting

-

SdioSetBlockSize

-

Sets the block size.

-

SDIO common information retrieval/setting

-

SdioGetCommonInfo

-

Obtains common information.

-

SdioSetCommonInfo

-

Sets common information.

-

SDIO data flushing

-

SdioFlushData

-

Flushes data.

-

SDIO host exclusively claiming or releasing

-

SdioClaimHost

-

Claims a host exclusively.

-

SdioReleaseHost

-

Releases the exclusively claimed host.

-

SDIO device enablement

-

SdioEnableFunc

-

Enables an SDIO device.

-

SdioDisableFunc

-

Disables an SDIO device.

-

SDIO IRQ claiming/releasing

-

SdioClaimIrq

-

Claims an SDIO IRQ.

-

SdioReleaseIrq

-

Releases an SDIO IRQ.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions provided in this document can be called only in kernel mode. - diff --git a/en/device-dev/driver/sdiousage-example.md b/en/device-dev/driver/sdiousage-example.md deleted file mode 100644 index 558f4cf191206f4a01f28850d14d667208b592fc..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sdiousage-example.md +++ /dev/null @@ -1,129 +0,0 @@ -# SDIO Usage Example - -The following example shows how to use an SDIO device. First, open an SDIO controller whose bus number is 1, exclusively claim a host, enable the SDIO device, claim an SDIO IRQ, and then perform SDIO communication \(such as reading and writing\). After the SDIO communication, release the SDIO IRQ, disable the SDIO device, release the host, and close the SDIO controller. - -``` -#include "hdf_log.h" -#include "sdio_if.h" - -#define TEST_FUNC_NUM 1 /* The I/O function whose ID is 1 is used. */ -#define TEST_FBR_BASE_ADDR 0x100 /* FBR base address of the I/O function whose ID is 1 */ -#define TEST_ADDR_OFFSET 9 /* Address offset of the register to read or write */ -#define TEST_DATA_LEN 3 /* Length of the data to read or write */ -#define TEST_BLOCKSIZE 2 /* Size of a data block, in bytes */ - -/* Implement the SDIO IRQ function based on the application. */ -static void SdioIrqFunc(void *data) -{ - if (data == NULL) { - HDF_LOGE("SdioIrqFunc: data is NULL.\n"); - return; - } - /* You need to add specific implementations. */ -} - -void SdioTestSample(void) -{ - int32_t ret; - DevHandle handle = NULL; - uint8_t data[TEST_DATA_LEN] = {0}; - struct SdioFunctionConfig config = {1, 0x123, 0x456}; - uint8_t val; - uint32_t addr; - - /* Open an SDIO controller whose bus number is 1. */ - handle = SdioOpen(1, &config); - if (handle == NULL) { - HDF_LOGE("SdioOpen: failed!\n"); - return; - } - /* Claim a host exclusively. */ - SdioClaimHost(handle); - /* Enable the SDIO device. */ - ret = SdioEnableFunc(handle); - if (ret != 0) { - HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); - goto ENABLE_ERR; - } - /* Claim an SDIO IRQ. */ - ret = SdioClaimIrq(handle, SdioIrqFunc); - if (ret != 0) { - HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); - goto CLAIM_IRQ_ERR; - } - /* Set the block size to 2 bytes. */ - ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE); - if (ret != 0) { - HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Read 3-byte data from the incremental address of an SDIO device. */ - addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET; - ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN); - if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Write 3-byte data into the incremental address of an SDIO device. */ - ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN); - if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Read 1-byte data from the SDIO device. */ - ret = SdioReadBytes(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Write 1-byte data into the SDIO device. */ - ret = SdioWriteBytes(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Read 3-byte data from the fixed address of an SDIO device. */ - ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Write 1-byte data to the fixed address of an SDIO device. */ - ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Read 1-byte data from SDIO function 0. */ - addr = 0x02; - ret = SdioReadBytesFromFunc0(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* Write 1-byte data into SDIO function 0. */ - ret = SdioWriteBytesToFunc0(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); - goto COMM_ERR; - } -COMM_ERR: - /* Release the SDIO IRQ. */ - ret = SdioReleaseIrq(handle); - if (ret != 0) { - HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); - } -CLAIM_IRQ_ERR: - /* Disable the SDIO device. */ - ret = SdioDisableFunc(handle); - if (ret != 0) { - HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); - } -ENABLE_ERR: - /* Release the exclusively claimed host. */ - SdioReleaseHost(handle); - /* Close an SDIO controller. */ - SdioClose(handle); -} -``` - diff --git a/en/device-dev/driver/sdiousage-guidelines.md b/en/device-dev/driver/sdiousage-guidelines.md deleted file mode 100644 index 402cf305ebb98196a477530f749e0bc07f9710bd..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sdiousage-guidelines.md +++ /dev/null @@ -1,787 +0,0 @@ -# SDIO Usage Guidelines - -- [How to Use](#section1962415610383) -- [Opening an SDIO Controller](#section814751015461) -- [Claiming a Host Exclusively](#section49274582455) -- [Enabling the SDIO Device](#section1431520410489) -- [Claiming an SDIO IRQ](#section3662781537) -- [Performing SDIO Communication](#section391941913484) -- [Releasing the SDIO IRQ](#section56205204481) -- [Disabling the SDIO Device](#section181181621124815) -- [Releasing the Exclusively Claimed Host](#section657117215486) -- [Closing an SDIO Controller](#section1898172114818) - -## How to Use - -[Figure 1](spiusage-guidelines.md#fig23885455594) illustrates the process of using an SDIO. - -**Figure 1** Process of using an SDIO - - -![](figures/en-us_image_0000001054440624.png) - -## Opening an SDIO Controller - -Before performing SDIO communication, obtain the device handle of an SDIO controller by calling **SdioOpen**. This function returns the device handle of the SDIO controller with a specified bus number. - -DevHandle SdioOpen\(int16\_t mmcBusNum, struct SdioFunctionConfig \*config\); - -**Table 1** Parameters and return values of SdioOpen - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

mmcBusNum

-

Bus number.

-

config

-

SDIO functionality configurations.

-

Return Value

-

Description

-

NULL

-

Failed to obtain the device handle of an SDIO controller.

-

Device handle

-

Device handle of an SDIO controller.

-
- -The following example shows how to open an SDIO controller. - -``` -DevHandle handle = NULL; -struct SdioFunctionConfig config; -config.funcNr = 1; -config.vendorId = 0x123; -config.deviceId = 0x456; -/* Open an SDIO controller whose bus number is 1. */ -handle = SdioOpen(1, &config); -if (handle == NULL) { - HDF_LOGE("SdioOpen: failed!\n"); -} -``` - -## Claiming a Host Exclusively - -After obtaining the device handle of an SDIO controller, exclusively claim the host before performing subsequent operations on the SDIO device. - -void SdioClaimHost\(DevHandle handle\); - -**Table 2** Parameter description of SdioClaimHost - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-
- -The following example shows how to exclusively claim a host. - -``` -SdioClaimHost(handle); /* Claim a host exclusively. */ -``` - -## Enabling the SDIO Device - -Before accessing a register, enable the SDIO device. - -int32\_t SdioEnableFunc\(DevHandle handle\); - -**Table 3** Parameters and return values of SdioEnableFunc - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

Return Value

-

Description

-

0

-

The SDIO device is enabled.

-

Negative value

-

Failed to enable the SDIO device.

-
- -The following example shows how to enable the SDIO device. - -``` -int32_t ret; -/* Enable the SDIO device. */ -ret = SdioEnableFunc(handle); -if (ret != 0) { - HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); -} -``` - -## Claiming an SDIO IRQ - -Before SDIO communication, claim an SDIO IRQ. - -int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\); - -**Table 4** Parameters and return values of SdioClaimIrq - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

handler

-

Pointer to the SDIO IRQ function.

-

Return Value

-

Description

-

0

-

The SDIO IRQ is claimed.

-

Negative value

-

Failed to claim an SDIO IRQ.

-
- -The following example shows how to claim an SDIO IRQ. - -``` -/* Implement the SDIO IRQ function based on the application. */ -static void SdioIrqFunc(void *data) -{ - if (data == NULL) { - HDF_LOGE("SdioIrqFunc: data is NULL.\n"); - return; - } - /* You need to add specific implementations. */ -} - -int32_t ret; -/* Claim an SDIO IRQ. */ -ret = SdioClaimIrq(handle, SdioIrqFunc); -if (ret != 0) { - HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); -} -``` - -## Performing SDIO Communication - -- Incrementally write a given length of data into the SDIO device. - -The corresponding function is as follows: - -int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**Table 5** Parameters and return values of SdioWriteBytes - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to write.

-

addr

-

Start address where the data is written into.

-

size

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Data is written into the SDIO device.

-

Negative value

-

Failed to write data into the SDIO device.

-
- -The following example shows how to incrementally write a given length of data into the SDIO device. - -``` -int32_t ret; -uint8_t wbuff[] = {1,2,3,4,5}; -uint32_t addr = 0x100 + 0x09; -/* Incrementally write 5-byte data into the start address 0x109 of the SDIO device. */ -ret = SdioWriteBytes(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0])); -if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); -} -``` - -- Incrementally read a given length of data from the SDIO device. - -The corresponding function is as follows: - -int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**Table 6** Parameters and return values of SdioReadBytes - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to read.

-

addr

-

Start address where the data is read from.

-

size

-

Length of the data to read.

-

Return Value

-

Description

-

0

-

Data is read from the SDIO device.

-

Negative value

-

Failed to read data from the SDIO device.

-
- -The following example shows how to incrementally read a given length of data from the SDIO device. - -``` -int32_t ret; -uint8_t rbuff[5] = {0}; -uint32_t addr = 0x100 + 0x09; -/* Incrementally read 5-byte data from the start address 0x109 of the SDIO device. */ -ret = SdioReadBytes(handle, rbuff, addr, 5); -if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); -} -``` - -- Write a given length of data into the fixed address of an SDIO device. - - The corresponding function is as follows: - - int32\_t SdioWriteBytesToFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); - - **Table 7** Parameters and return values of SdioWriteBytesToFixedAddr - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to write.

-

addr

-

Fixed address where the data is written into.

-

size

-

Length of the data to write.

-

scatterLen

-

Length of the scatter list. If the value is not 0, the data is of the scatter list type.

-

Return Value

-

Description

-

0

-

Data is written into the SDIO device.

-

Negative value

-

Failed to write data into the SDIO device.

-
- - The following example shows how to write a given length of data into the fixed address of an SDIO device. - - ``` - int32_t ret; - uint8_t wbuff[] = {1, 2, 3, 4, 5}; - uint32_t addr = 0x100 + 0x09; - /* Write 5-byte data into the fixed address 0x109 of the SDIO device. */ - ret = SdioWriteBytesToFixedAddr(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0]), 0); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); - } - ``` - -- Read a given length of data from the fixed address of an SDIO device. - - The corresponding function is as follows: - - int32\_t SdioReadBytesFromFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); - - **Table 8** Parameters and return values of SdioReadBytesFromFixedAddr - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to read.

-

addr

-

Start address where the data is read from.

-

size

-

Length of the data to read.

-

scatterLen

-

Length of the scatter list. If the value is not 0, the data is of the scatter list type.

-

Return Value

-

Description

-

0

-

Data is read from the SDIO device.

-

Negative value

-

Failed to read data from the SDIO device.

-
- - The following example shows how to read a given length of data from the fixed address of an SDIO device. - - ``` - int32_t ret; - uint8_t rbuff[5] = {0}; - uint32_t addr = 0x100 + 0x09; - /* Read 5-byte data from the fixed address 0x109 of the SDIO device. */ - ret = SdioReadBytesFromFixedAddr(handle, rbuff, addr, 5, 0); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); - } - ``` - - -- Write a given length of data into the address space of SDIO function 0. - -Currently, only 1-byte data can be written. The corresponding function is as follows: - -int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**Table 9** Parameters and return values of SdioWriteBytesToFunc0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to write.

-

addr

-

Start address where the data is written into.

-

size

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Data is written into the SDIO device.

-

Negative value

-

Failed to write data into the SDIO device.

-
- -The following example shows how to write a given length of data into the address space of SDIO function 0. - -``` -int32_t ret; -uint8_t wbuff = 1; -/* Write 1-byte data into the address 0x2 of SDIO function 0. */ -ret = SdioWriteBytesToFunc0(handle, &wbuff, 0x2, 1); -if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); -} -``` - -- Read a given length of data from the address space of SDIO function 0. - -Currently, only 1-byte data can be read. The corresponding function is as follows: - -int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**Table 10** Parameters and return values of SdioReadBytesFromFunc0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to read.

-

addr

-

Start address where the data is read from.

-

size

-

Length of the data to read.

-

Return Value

-

Description

-

0

-

Data is read from the SDIO device.

-

Negative value

-

Failed to read data from the SDIO device.

-
- -The following example shows how to read a given length of data from the address space of SDIO function 0. - -``` -int32_t ret; -uint8_t rbuff; -/* Read 1-byte data from the address 0x2 of SDIO function 0. */ -ret = SdioReadBytesFromFunc0(handle, &rbuff, 0x2, 1); -if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); -} -``` - -## Releasing the SDIO IRQ - -After the SDIO communication, release the SDIO IRQ. - -int32\_t SdioReleaseIrq\(DevHandle handle\); - -**Table 11** Parameters and return values of SdioReleaseIrq - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

Return Value

-

Description

-

0

-

The SDIO IRQ is released.

-

Negative value

-

Failed to release the SDIO IRQ.

-
- -The following example shows how to release the SDIO IRQ. - -``` -int32_t ret; -/* Release the SDIO IRQ. */ -ret = SdioReleaseIrq(handle); -if (ret != 0) { - HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); -} -``` - -## Disabling the SDIO Device - -After the SDIO communication, disable the SDIO device. - -int32\_t SdioDisableFunc\(DevHandle handle\); - -**Table 12** Parameters and return values of SdioDisableFunc - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

Return Value

-

Description

-

0

-

The SDIO device is disabled.

-

Negative value

-

Failed to disable the SDIO device.

-
- -The following example shows how to disable the SDIO device. - -``` -int32_t ret; -/* Disable the SDIO device. */ -ret = SdioDisableFunc(handle); -if (ret != 0) { - HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); -} -``` - -## Releasing the Exclusively Claimed Host - -After the SDIO communication, release the exclusively claimed host. - -void SdioReleaseHost\(DevHandle handle\); - -**Table 13** Parameter description of SdioReleaseHost - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-
- -The following example shows how to release the exclusively claimed host. - -``` -SdioReleaseHost(handle); /* Release the exclusively claimed host. */ -``` - -## Closing an SDIO Controller - -After the SDIO communication, close the SDIO controller. - -void SdioClose\(DevHandle handle\); - -This function releases the resources requested. - -**Table 14** Parameter description of SdioClose - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-
- -The following example shows how to close an SDIO controller. - -``` -SdioClose(handle); /* Close an SDIO controller. */ -``` - diff --git a/en/device-dev/driver/sensor-driver-development-example.md b/en/device-dev/driver/sensor-driver-development-example.md deleted file mode 100644 index acab2c70f8f15eb2f313206a50e289af4ab759db..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sensor-driver-development-example.md +++ /dev/null @@ -1,583 +0,0 @@ -# Sensor Driver Development Example - -This section provides a code example of how to load and start the acceleration sensor driver based on the HDF driver model. For details about the mechanism, see [HDF Driver Development](driver-development.md). This example uses the Bosch BMI160 acceleration sensor that communicates over I2C. - -1. Register the driver entry of the acceleration sensor. - -- Implementation of the entry function - -``` -/* Register the entry structure object of the acceleration sensor. */ -struct HdfDriverEntry g_sensorAccelDevEntry = { - .moduleVersion = 1, /* Version number of the acceleration sensor module */ - .moduleName = "HDF_SENSOR_ACCEL", /* Name of the acceleration sensor module. The value must be the same as that of moduleName in the device_info.hcs file. */ - .Bind = BindAccelDriver, /* Binding function of the acceleration sensor */ - .Init = InitAccelDriver, /* Initialization function of the acceleration sensor */ - .Release = ReleaseAccelDriver, /* Resource release function of the acceleration sensor */ -}; - -/* Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind function first and then the Init function. If the Init function fails to be called, the HDF will call Release to release the driver resource and exit. -HDF_INIT(g_sensorAccelDevEntry); -``` - -- Acceleration sensor configuration - -The acceleration sensor model uses the HCS as the configuration source code. For details about the HCS configuration fields, see [Driver Configuration Management](driver-configuration-management.md). - -``` -/* HCS configuration of the acceleration sensor device */ -device_sensor_accel :: device { - device0 :: deviceNode { - policy = 1; /* Policy for providing the driver service */ - priority = 105; /* Driver startup priority (0–200). A larger value indicates a lower priority. The default value 100 is recommended. The sequence for loading devices with the same priority is random. */ - preload = 2; /* Field for specifying whether to load the driver. Value 0 means to load the driver, and 2 means the opposite. */ - permission = 0664; /* Permission for the driver to create device nodes */ - moduleName = "HDF_SENSOR_ACCEL"; /* Driver name. The value must be the same as that of moduleName in the driver entry structure. */ - serviceName = "sensor_accel"; /* Name of the service provided by the driver. The name must be unique. */ - deviceMatchAttr = "hdf_sensor_accel_driver"; /* Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver. */ - } -} -``` - -1. Initialize and deinitialize the acceleration sensor driver. - -- Initialization entry function **init** - -``` -/* Bind the service provided by the acceleration sensor driver to the HDF. */ -int32_t BindAccelDriver(struct HdfDeviceObject *device) -{ - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - - static struct IDeviceIoService service = { - .object = {0}, - .Dispatch = DispatchAccel, - }; - device->service = &service; - - return HDF_SUCCESS; -} -/* After detecting that the device is in position, call RegisterAccelChipOps to register the differentiation adaptation function. */ -int32_t RegisterAccelChipOps(struct AccelOpsCall *ops) -{ - struct AccelDrvData *drvData = NULL; - - CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); - - drvData = AccelGetDrvData(); - drvData->ops.Init = ops->Init; - drvData->ops.ReadData = ops->ReadData; - return HDF_SUCCESS; -} -/* Hook the acceleration sensor driver normalization function. */ -static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo) -{ - struct AccelDrvData *drvData = AccelGetDrvData(); - - (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); - deviceInfo->ops.GetInfo = SetAccelInfo; - deviceInfo->ops.Enable = SetAccelEnable; - deviceInfo->ops.Disable = SetAccelDisable; - deviceInfo->ops.SetBatch = SetAccelBatch; - deviceInfo->ops.SetMode = SetAccelMode; - deviceInfo->ops.SetOption = SetAccelOption; - - if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), - &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) { - HDF_LOGE("%s: copy sensor info failed", __func__); - return HDF_FAILURE; - } - /* The sensor type ID can be configured in the HCS configuration file or here. */ - drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER; - drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER; - - return HDF_SUCCESS; -} -/* Initialize the sensor register. */ -static int32_t InitAccelAfterConfig(void) -{ - struct SensorDeviceInfo deviceInfo; - - if (InitAccelConfig() != HDF_SUCCESS) { - HDF_LOGE("%s: init accel config failed", __func__); - return HDF_FAILURE; - } - - if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: init accel ops failed", __func__); - return HDF_FAILURE; - } - - if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: add accel device failed", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} -/* Call the device detection function to hook the differentiated device function. */ -static int32_t DetectAccelChip(void) -{ - int32_t num; - int32_t ret; - int32_t loop; - struct AccelDrvData *drvData = AccelGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - - num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]); - for (loop = 0; loop < num; ++loop) { - if (g_accelDetectIfList[loop].DetectChip != NULL) { - ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg); - if (ret == HDF_SUCCESS) { - drvData->detectFlag = true; - break; - } - } - } - - if (loop == num) { - HDF_LOGE("%s: detect accel device failed", __func__); - drvData->detectFlag = false; - return HDF_FAILURE; - } - return HDF_SUCCESS; -} -/* The entry function of the acceleration sensor driver is used to initialize the structure object of the sensor private data, allocate space for the HCS data configuration object of the sensor, invoke the entry function for initializing the sensor HCS data configuration, detect whether the sensor device is in position, create the sensor data reporting timer, implement the sensor normalization API, and register the sensor device. */ -int32_t InitAccelDriver(struct HdfDeviceObject *device) -{ - /* Obtain the private data structure object of the sensor. */ - struct AccelDrvData *drvData = AccelGetDrvData(); - - /* When detecting sensors of the same type from different vendors, the function checks whether this type of sensors is in position. If yes, it no longer detects the other sensors of this type and directly returns the result. */ - if (drvData->detectFlag) { - HDF_LOGE("%s: accel sensor have detected", __func__); - return HDF_SUCCESS; - } - - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - /* Allocate space for the private data structure objects for storing sensor data configurations. The allocated space needs to be released when the driver is released. */ - drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg)); - if (drvData->accelCfg == NULL) { - HDF_LOGE("%s: malloc sensor config data failed", __func__); - return HDF_FAILURE; - } - - drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; - /* Initializing the sensor configuration data aims to parse the configuration information of the sensor communication bus, basic sensor information, sensor attributes, whether the sensor is in position, and register group information. */ - if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: get sensor base config failed", __func__); - goto Base_CONFIG_EXIT; - } - - if (DetectAccelChip() != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor detect device no exist", __func__); - goto DETECT_CHIP_EXIT; - } - drvData->detectFlag = true; - if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: detect sensor device failed", __func__); - goto REG_CONFIG_EXIT; - } - - if (InitAccelAfterConfig() != HDF_SUCCESS) { - HDF_LOGE("%s: init accel after config failed", __func__); - goto INIT_EXIT; - } - - HDF_LOGI("%s: init accel driver success", __func__); - return HDF_SUCCESS; - -INIT_EXIT: - DestroySensorThread(&drvData->thread, &drvData->threadStatus); - (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); -REG_CONFIG_EXIT: - ReleaseSensorAllRegConfig(drvData->accelCfg); - (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); -DETECT_CHIP_EXIT: - drvData->detectFlag = false; -BASE_CONFIG_EXIT: - drvData->accelCfg->root = NULL; - drvData->accelCfg->regCfgGroup = NULL; - OsalMemFree(drvData->accelCfg); - drvData->accelCfg = NULL; - return HDF_FAILURE; -} - -/* Release the resources allocated during driver initialization. */ -void ReleaseAccelDriver(struct HdfDeviceObject *device) -{ - (void)device; - struct AccelDrvData *drvData = NULL; - - drvData = AccelGetDrvData(); - (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus); - (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); - drvData->detectFlag = false; - - if (drvData->accelCfg != NULL) { - drvData->accelCfg->root = NULL; - drvData->accelCfg->regCfgGroup = NULL; - ReleaseSensorAllRegConfig(drvData->accelCfg); - (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); - OsalMemFree(drvData->accelCfg); - drvData->accelCfg = NULL; - } - - drvData->initStatus = false; -} -``` - -1. Configure the acceleration sensor register group. - -You only need to configure the acceleration sensor data according to the template. Template configuration parsing has been implemented via the **InitSensorConfigData** function and only needs to be called during initialization. If new configuration items are added, you need to modify this function accordingly. - -``` -Acceleration sensor data configuration template (accel_config.hcs) -root { - sensorAccelConfig { - accelChipConfig { - /* Sensor information template */ - template sensorInfo { - sensorName = "accelerometer"; /* Acceleration sensor name. The value contains a maximum of 16 bytes. */ - vendorName = "borsh_bmi160"; /* Sensor vendor name. The value contains a maximum of 16 bytes. */ - firmwareVersion = "1.0"; /* Sensor firmware version number. The default value is 1.0. The value contains a maximum of 16 bytes. */ - hardwareVersion = "1.0"; /* Sensor hardware version number. The default value is 1.0. The value contains a maximum of 16 bytes. */ - sensorTypeId = 1; /* Sensor type ID. For details, see SensorTypeTag. */ - sensorId = 1; /* Sensor ID, which is defined by the sensor driver developer. The SensorTypeTag enums are recommended. */ - maxRange = 8; /* Maximum measurement range of the sensor. Set this parameter based on your business requirements. */ - precision = 0; /* Sensor accuracy, which is used together with sensor data reporting. For details, see SensorEvents. */ - power = 230; /* Power consumption of the sensor */ - } - /* Template of the bus type and configuration information used by the sensor */ - template sensorBusConfig { - busType = 0; /* 0 for the I2C bus and 1 for the SPI bus */ - busNum = 6; /* Device ID allocated to the sensor on the chip */ - busAddr = 0; /* Address allocated to the sensor on the chip */ - regWidth = 1; /* Width of the sensor register address */ - regBigEndian = 0; /* Endian mode of the sensor register */ - } - /* Sensor attribute template */ - template sensorAttr { - chipName = ""; /* Sensor chip name */ - chipIdRegister = 0xf; /* Address of the register detecting whether the sensor is in position */ - chipIdValue = 0xd1; /* Value of the register detecting whether the sensor is in position */ - } - } - } -} - -/* You can modify the template configuration based on the differences of sensor devices. If no modification is made, the default template configuration is used. */ -root { - sensorAccelConfig { - accel_bmi160_chip_config : accelChipConfig { - match_attr = "hdf_sensor_accel_driver"; /* The value must be the same as the match_attr field configured for the acceleration sensor. */ - accelInfo :: sensorInfo { - vendorName = "borsh_bmi160"; - sensorTypeId = 1; - sensorId = 1; - } - accelBusConfig :: sensorBusConfig { - busType = 0; /* I2C communication mode */ - busNum = 6; - busAddr = 0x68; - regWidth = 1; /* 1-byte bit width */ - } - accelAttr :: sensorAttr { - chipName = "bmi160"; - chipIdRegister = 0x00; - chipIdValue = 0xd1; - } - accelRegConfig { - /* regAddr: Register address - value: Register value - mask: Mask of the register value - len: Length (in bytes) of the register value - delay: Register delay (in milliseconds) - opsType: Operation type. The options can be 0 (no operation), 1 (read), 2 (write), 3 (read and check), and 4 (bit update). - calType: Calculation type. The options can be 0 (none), 1 (write), 2 (negate), 3 (XOR) 4, (left shift), and 5 (right shift). - shiftNum: Number of shifts - debug: Debugging switch. The value can be 0 (disabled) or 1 (enabled). - save: Data saving switch. The value can be 0 (not save data) or 1 (save data). - */ - /* Groups of sensor register operations. Registers can be configured in sequence based on the groups. */ - /* Register address, register value, mask of the register value, data length of the register value, register delay, operation type, calculation type, number of shifts, debugging switch, data saving switch */ - /* Initialize the register groups. */ - initSeqConfig = [ - 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0, - 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 - ]; - /* Enable the register groups. */ - enableSeqConfig = [ - 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0, - 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0, - 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0 - ]; - /* Disable the register groups. */ - disableSeqConfig = [ - 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 - ]; - } - } - } -} -``` - -1. Implement APIs for acceleration sensor driver operations. - -You need to implement normalized APIs based on sensor types. - -``` -/* Leave a function empty if it is not used. */ -static int32_t SetAccelInfo(struct SensorBasicInfo *info) -{ - (void)info; - - return HDF_ERR_NOT_SUPPORT; -} -/* Deliver the configuration of enabling the register groups. */ -static int32_t SetAccelEnable(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor disable config failed", __func__); - return HDF_FAILURE; - } - - drvData->threadStatus = SENSOR_THREAD_RUNNING; - - return HDF_SUCCESS; -} -/* Deliver the configuration of disabling the register groups. */ -static int32_t SetAccelDisable(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - - ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor disable config failed", __func__); - return HDF_FAILURE; - } - - drvData->threadStatus = SENSOR_THREAD_STOPPED; - - return HDF_SUCCESS; -} -/* Set the sampling interval and data reporting interval of the sensor. */ -static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval) -{ - (void)interval; - - struct AccelDrvData *drvData = AccelGetDrvData(); - drvData->interval = samplingInterval; - - return HDF_SUCCESS; -} -/* Set the data reporting mode of the sensor. Currently, the real-time mode is supported. */ -static int32_t SetAccelMode(int32_t mode) -{ - return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE; -} -/* Set the sensor options. */ -static int32_t SetAccelOption(uint32_t option) -{ - (void)option; - return HDF_ERR_NOT_SUPPORT; -} -``` - -- Differentiated processing APIs - - ``` - /* If a device is successfully detected, register the differentiated processing function to the accel driver model. */ - int32_t DetectAccelBim160Chip(struct SensorCfgData *data) - { - int32_t ret; - struct AccelOpsCall ops; - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - - if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) { - return HDF_SUCCESS; - } - ret = InitAccelPreConfig(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: init BMI160 bus mux config", __func__); - return HDF_FAILURE; - } - if (DetectSensorDevice(data) != HDF_SUCCESS) { - return HDF_FAILURE; - } - - /* Differentiated processing function */ - ops.Init = InitBmi160; - ops.ReadData = ReadBmi160Data; - ret = RegisterAccelChipOps(&ops); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: register BMI160 accel failed", __func__); - (void)ReleaseSensorBusHandle(&data->busCfg); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - /* Initialization processing function */ - static int32_t InitBmi160(struct SensorCfgData *data) - { - int32_t ret; - - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: bmi160 sensor init config failed", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - /* Data processing function */ - int32_t ReadBmi160Data(struct SensorCfgData *data) - { - int32_t ret; - struct AccelData rawData = { 0, 0, 0 }; - int32_t tmp[ACCEL_AXIS_NUM]; - struct SensorReportEvent event; - - (void)memset_s(&event, sizeof(event), 0, sizeof(event)); - - ret = ReadBmi160RawData(data, &rawData, &event.timestamp); - if (ret != HDF_SUCCESS) { - return HDF_FAILURE; - } - - event.sensorId = SENSOR_TAG_ACCELEROMETER; - event.option = 0; - event.mode = SENSOR_WORK_MODE_REALTIME; - - rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G; - rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G; - rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G; - - tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - - event.dataLen = sizeof(tmp); - event.data = (uint8_t *)&tmp; - ret = ReportSensorEvent(&event); - return ret; - } - ``` - -- Data processing function - -Create a sensor timer to periodically sample data based on the configured sampling interval and report the data to the data subscriber. - -``` -/* Scheduled working thread of the sensor */ -static int32_t ReadAccelDataThreadWorker(void *arg) -{ - (void)arg; - int64_t interval; - struct AccelDrvData *drvData = AccelGetDrvData(); - - drvData->threadStatus = SENSOR_THREAD_START; - while (true) { - if (drvData->threadStatus == SENSOR_THREAD_RUNNING) { - if (drvData->ops.ReadData != NULL) { - (void)drvData->ops.ReadData(drvData->accelCfg); - } - interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT)); - OsalMSleep(interval); - } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) { - break; - } else { - OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT); - } - - if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) { - continue; - } - } - - return HDF_SUCCESS; -} -/* Create a sensor timer and initialize the sensor device. */ -static int32_t InitAccelConfig(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) { - HDF_LOGE("%s: accel thread have created", __func__); - return HDF_SUCCESS; - } - - ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel create thread failed", __func__); - drvData->threadStatus = SENSOR_THREAD_NONE; - return HDF_FAILURE; - } - - CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM); - - ret = drvData->ops.Init(drvData->accelCfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel create thread failed", __func__); - drvData->threadStatus = SENSOR_THREAD_NONE; - return HDF_FAILURE; - } - drvData->initStatus = true; - return HDF_SUCCESS; -} -``` - -- Major data structures - -``` -/* Sensor conversion units */ -#define SENSOR_CONVERT_UNIT 1000 -#define SENSOR_1K_UNIT 1024 -/* Sensitivity conversion value of the sensor with a 2g measurement range */ -#define BMI160_ACC_SENSITIVITY_2G 61 -/* Address of the sensor data sampling register */ -#define BMI160_ACCEL_X_LSB_ADDR 0X12 -#define BMI160_ACCEL_X_MSB_ADDR 0X13 -#define BMI160_ACCEL_Y_LSB_ADDR 0X14 -#define BMI160_ACCEL_Y_MSB_ADDR 0X15 -#define BMI160_ACCEL_Z_LSB_ADDR 0X16 -#define BMI160_ACCEL_Z_MSB_ADDR 0X17 -/* Data dimension of the sensor */ -enum AccelAxisNum { - ACCEL_X_AXIS = 0, - ACCEL_Y_AXIS = 1, - ACCEL_Z_AXIS = 2, - ACCEL_AXIS_NUM = 3, -}; -/* Each dimension of the sensor */ -struct AccelData { - int32_t x; - int32_t y; - int32_t z; -}; -/* Private data structure of the sensor */ -struct AccelDrvData { - bool detectFlag; - uint8_t threadStatus; - uint8_t initStatus; - int64_t interval; - struct SensorCfgData *accelCfg; - struct OsalThread thread; - struct AccelOpsCall ops; -}; -/* Differentiation adaptation function */ -struct AccelOpsCall { - int32_t (*Init)(struct SensorCfgData *data); - int32_t (*ReadData)(struct SensorCfgData *data); -}; -``` - diff --git a/en/device-dev/driver/sensor-driver-development-guidelines.md b/en/device-dev/driver/sensor-driver-development-guidelines.md deleted file mode 100644 index afbb833cac70c19f9612461c6d2f9983f58ef544..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sensor-driver-development-guidelines.md +++ /dev/null @@ -1,16 +0,0 @@ -# Sensor Driver Development Guidelines - -- [How to Develop](#section18816105182315) - -Regardless of the OS and system on a chip \(SoC\), the sensor driver is developed based on the HDF, platform, and OSAL APIs to provide a unified driver model for sensor devices. This section uses the acceleration sensor as an example to describe how to develop a sensor driver. - -## How to Develop - -1. Register the acceleration sensor driver. The HDF provides a unified driver management model. The HDF identifies and loads the target module driver based on the configuration information of the acceleration sensor module. -2. Initialize and deinitialize the acceleration sensor driver. Using the **init** function, the HDF starts loading the sensor device driver and allocating configuration resources for sensor device data, respectively. Using the **release** function, the HDF releases the resources and configurations loaded by the driver. -3. Parse the configurations of the acceleration sensor register group. For different types of sensors, you need to configure their respective HCS configuration files in the HCS, check whether the sensor device is in position during the device driver startup, and then load the corresponding configuration file to generate the configuration structure object. -4. Implement APIs for acceleration sensor driver operations. The driver APIs for various types of sensors, such as **init**, **GetInfo**, **Enable**, **Disable**, **SetBatch**, **SetMode**, **SetOption**, and **ReadSensorData**, are normalized to deliver sensor driver configurations and report sensor data. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The sensor driver model provides a collection of APIs to implement sensor driver capabilities, including the driver device management capabilities, abstract bus and platform operation capabilities, general configuration capabilities, and configuration parsing capabilities. For details about the APIs, see [Table 2](sensor-driver-overview.md#table1156812588320). You need to implement the following APIs: some operations to perform on sensors \([Table 3](sensor-driver-overview.md#table1083014911336)\), differentiated data configuration of the sensor HCS, and verification of basic driver functions. - diff --git a/en/device-dev/driver/sensor-driver-overview.md b/en/device-dev/driver/sensor-driver-overview.md deleted file mode 100644 index b3d5e86797f93b7c753fdece5fa02adb18f8fbba..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sensor-driver-overview.md +++ /dev/null @@ -1,244 +0,0 @@ -# Sensor Driver Overview - -- [Introduction](#section667413271505) -- [Available APIs](#section7255104114110) - -## Introduction - -The sensor driver module provides APIs for upper-layer sensor services to implement basic sensor capabilities, including querying the sensor list, enabling or disabling a sensor, subscribing to or unsubscribing from sensor data, and setting sensor options. The sensor driver model is developed based on the Hardware Driver Foundation \(HDF\) and supports functions such as cross-OS migration and differentiated device configuration. The following figure shows the architecture of the sensor driver model. - -**Figure 1** Architecture of the sensor driver model -![](figures/architecture-of-the-sensor-driver-model.png "architecture-of-the-sensor-driver-model") - -The sensor driver model offers the following APIs: - -- Hardware Driver Interfaces \(HDIs\) for sensors: Facilitate service development. -- APIs for implementing sensor driver model capabilities: Implement the capabilities of registering, loading, and unregistering sensor drivers as well as detecting sensor devices depending on the HDF, normalize APIs for sensor devices of the same type, and offer APIs for parsing register configurations, abstract APIs for bus access, and abstract platform APIs. -- APIs to be implemented by developers: Based on the HDF Configuration Source \(HCS\), implement differentiated configuration for sensors of the same type and serialized configuration of sensor device parameters, and offer APIs for some sensor device operations to simplify sensor driver development. - -## Available APIs - -The following table lists the APIs provided by the sensor driver model. - -**Table 1** External APIs provided by the sensor driver model - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Query

-

int32_t GetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)

-

Obtains information about all sensors in the system. The information about a sensor generally includes the sensor name, sensor vendor, firmware version, hardware version, sensor type ID, sensor ID, maximum measurement range, accuracy, and power.

-

Setting

-

int32_t Enable(int32_t sensorId)

-

Enables the sensor that has been subscribed to. The subscriber can obtain the sensor data only after the sensor is enabled.

-

int32_t Disable(int32_t sensorId)

-

Disables a sensor.

-

int32_t SetBatch(iint32_t sensorId, int64_t samplingInterval, int64_t reportInterval)

-

Sets the data sampling interval and data reporting interval for the specified sensor.

-

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

-

Sets the data reporting mode for the specified sensor.

-

int32_t SetOption(int32_t sensorId, uint32_t option)

-

Sets options for the specified sensor, including its measurement range and accuracy.

-

Data subscription and unsubscription

-

int32_t Register(RecordDataCallback cb)

-

Registers the callback for reporting sensor data to the subscriber.

-

int32_t Unregister(void)

-

Unregisters the callback for reporting sensor data.

-

Instance creation

-

const struct SensorInterface *NewSensorInterfaceInstance(void)

-

Creates a SensorInterface instance.

-

int32_t FreeSensorInterfaceInstance(void)

-

Releases the SensorInterface instance.

-
- -The following table lists the APIs provided by the sensor driver model for driver developers. You can directly call these APIs without any implementations. - -**Table 2** APIs provided by the sensor driver model for driver developers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Device management

-

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

-

Adds a sensor of the current type to the sensor management module.

-

int32_t DeleteSensorDevice(int32_t sensorId)

-

Deletes a specified sensor from the sensor management module.

-

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

-

Reports data of a specified sensor type.

-

Abstract bus and platform operations

-

int32_t ReadSensor(struct SensorBusCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen)

-

Reads sensor configuration data from the sensor register based on the bus configuration.

-

int32_t WriteSensor(struct SensorBusCfg *busCfg, uint8_t *writeData, uint16_t len)

-

Writes sensor configuration data to the sensor register based on the bus configuration.

-

int32_t CreateSensorThread(struct OsalThread *thread, OsalThreadEntry threadEntry, char *name, void *entryPara)

-

Creates a scheduled thread for a specified sensor to process sensor data reporting.

-

void DestroySensorThread(struct OsalThread *thread, uint8_t *status);

-

Destroys the scheduled thread created for the sensor.

-

Common configuration

-

int32_t SetSensorRegCfgArray(struct SensorBusCfg *busCfg, const struct SensorRegCfgGroupNode *group);

-

Sets the sensor register group configuration based on the sensor bus type.

-

Configuration parsing

-

-

int32_t GetSensorBaseConfigData(const struct DeviceResourceNode *node, struct SensorCfgData *config)

-

Obtains basic configuration information such as sensor, bus, and attribute configurations based on the HCS resource configuration of the sensor device, and initializes the basic configuration data structure.

-

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

-

Parses the register group information based on the HCS resource configuration of the sensor device and initializes the configuration data structure.

-

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

-

Releases the resources allocated to the sensor configuration data structure.

-

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

-

Obtains the sensor bus handle information.

-

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

-

Releases the sensor bus handle information.

-
- -The following table lists the APIs that need to be implemented by driver developers. - -**Table 3** APIs that need to be implemented by driver developers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Basic functions

-

int32_t init(void)

-

Initializes the configuration of a sensor device after it is detected successfully.

-

int32_t GetInfo(struct SensorBasicInfo *info)

-

Obtains the basic information about the current sensor device from the HCS of sensor devices.

-

int32_t Enable(void)

-

Enables the current sensor device by delivering the register configuration in the operation group based on the HCS of the current sensor device.

-

int32_t Disable(void)

-

Disables the current sensor device by delivering the register configuration in the operation group based on the HCS of the current sensor device.

-

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

-

Sets the processing time of the data reporting thread for the current sensor device based on the data sampling interval and data reporting interval.

-

int32_t SetMode(int32_t mode)

-

Sets the data reporting mode of the current sensor device.

-

int32_t SetOption(uint32_t option)

-

Sets the register configuration such as the measurement range and accuracy based on sensor options.

-

void ReadSensorData(void)

-

Reads sensor data.

-
- -For details about the API implementation, see the [sensor driver development example](sensor-driver-development-example.md). - diff --git a/en/device-dev/driver/sensor-driver-test-guidelines.md b/en/device-dev/driver/sensor-driver-test-guidelines.md deleted file mode 100644 index 042112036cdad78e9aa732e54c8423f8c3ed115e..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sensor-driver-test-guidelines.md +++ /dev/null @@ -1,82 +0,0 @@ -# Sensor Driver Test Guidelines - -After the driver is developed, you can develop self-test cases in the sensor unit test to verify the basic functions of the driver. The developer self-test platform is used as the test environment. - -``` -/* Specify whether to report sensor data. */ -static int32_t g_sensorDataFlag = 0; -/* Retain the address of the sensor interface instance. */ -static const struct SensorInterface *g_sensorDev = nullptr; - -/* Register the data reporting function. */ -static int SensorTestDataCallback(struct SensorEvents *event) -{ - if (event == nullptr) { - return -1; - } - float *data = (float*)event->data; - printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, - event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); - if (*data > 1e-5) { - g_sensorDataFlag = 1; - } - return 0; -} -/* Initialize the sensor interface instance before executing the test cases. */ -void HdfSensorTest::SetUpTestCase() -{ - g_sensorDev = NewSensorInterfaceInstance(); - if (g_sensorDev == nullptr) { - printf("test sensorHdi get Module instace failed\n\r"); - } -} -/* Release case resources. */ -void HdfSensorTest::TearDownTestCase() -{ - if (g_sensorDev != nullptr) { - FreeSensorInterfaceInstance(); - g_sensorDev = nullptr; - } -} -/* Verify the sensor driver. */ -HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) -{ - int32_t sensorInterval = 1000000000; /* Data sampling interval, in nanoseconds */ - int32_t pollTime = 5; /* Data sampling duration, in seconds */ - int32_t accelSensorId = 1; /* Acceleration sensor type ID, which is 1 */ - int32_t count = 0; - int ret; - struct SensorInformation *sensorInfo = nullptr; - - ret = g_sensorDev->Register(SensorTestDataCallback) - EXPECT_EQ(SENSOR_NULL_PTR, ret); - - ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); - EXPECT_EQ(0, ret); - if (sensorInfo == nullptr) { - EXPECT_NE(nullptr, sensorInfo); - return; - } - /* Print the obtained sensor list. */ - for (int i = 0; i < count; i++) { - printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); - } - ret = g_sensorDev->Enable(accelSensorId); - EXPECT_EQ(0, ret); - g_sensorDataFlag = 0; - - ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); - EXPECT_EQ(0, ret); - /* Observe the printed data within the period specified by pollTime. */ - OsalSleep(pollTime); - EXPECT_EQ(1, g_sensorDataFlag); - - ret = g_sensorDev->Disable(accelSensorId); - g_sensorDataFlag = 0; - EXPECT_EQ(0, ret); - - ret = g_sensorDev->Unregister(); - EXPECT_EQ(0, ret); -} -``` - diff --git a/en/device-dev/driver/sensor.md b/en/device-dev/driver/sensor.md deleted file mode 100644 index f9e8d552c0cbad2c430e9457122a25b1d62ee4df..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sensor.md +++ /dev/null @@ -1,11 +0,0 @@ -# SENSOR - -- **[Sensor Driver Overview](sensor-driver-overview.md)** - -- **[Sensor Driver Development Guidelines](sensor-driver-development-guidelines.md)** - -- **[Sensor Driver Development Example](sensor-driver-development-example.md)** - -- **[Sensor Driver Test Guidelines](sensor-driver-test-guidelines.md)** - - diff --git a/en/device-dev/driver/spi.md b/en/device-dev/driver/spi.md deleted file mode 100644 index c635810c74cbb62be99562f6848983e4b7437058..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/spi.md +++ /dev/null @@ -1,9 +0,0 @@ -# SPI - -- **[SPI Overview](spioverview.md)** - -- **[SPI Usage Guidelines](spiusage-guidelines.md)** - -- **[SPI Usage Example](spiusage-example.md)** - - diff --git a/en/device-dev/driver/spioverview.md b/en/device-dev/driver/spioverview.md deleted file mode 100644 index 46303b336baaec8295a11afacc466aed62809c29..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/spioverview.md +++ /dev/null @@ -1,107 +0,0 @@ -# SPI Overview - -- [Introduction](#section9202632114011) -- [Available APIs](#section1859594134119) - -## Introduction - -- Serial Peripheral Interface \(SPI\) is a serial bus specification used for high-speed, full-duplex, and synchronous communication. -- SPI is developed by Motorola. It is commonly used for communication with flash memory, real-time clocks, sensors, and analog-to-digital \(A/D\) converters. -- SPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires: - - SCLK: clock signals output from the SPI controller - - MOSI: data output from the SPI controller and input into an SPI device - - MISO: data output from an SPI device and input into the SPI controller - - CS: signals enabled by an SPI device and controlled by the SPI controller - - -- [Figure 1](#fig15227181812587) shows the connection between one SPI controller and two SPI devices \(device A and device B\). In this figure, device A and device B share three pins \(SCLK, MISO, and MOSI\) of the controller. CS0 of device A and CS1 of device B are connected to CS0 and CS1 of the controller, respectively. - -**Figure 1** SPI controller/device connection - - -![](figures/en-us_image_0000001054142582.png) - -- SPI communication is usually initiated by the SPI controller and is operated as follows: - -1. A single SPI device is selected at a time via the CS to communicate with the SPI controller. -2. Clock signals are provided for the selected SPI device via the SCLK. -3. The SPI controller sends data to SPI devices via the MOSI, and receives data from SPI devices via the MISO. - -- SPI can work in one of the following four modes, equivalent to one of the four possible states for Clock Polarity \(CPOL\) and Clock Phase \(CPHA\): - - If both CPOL and CPHA are **0**, the clock signal level is low in the idle state and data is sampled on the first clock edge. - - If CPOL is **0** and CPHA is **1**, the clock signal level is low in the idle state and data is sampled on the second clock edge. - - If CPOL is **1** and CPHA is **0**, the clock signal level is high in the idle state and data is sampled on the first clock edge. - - If both CPOL and CPHA are **1**, the clock signal level is high in the idle state and data is sampled on the second clock edge. - - -- SPI defines a set of common functions for operating an SPI device, including those for: - - Obtaining and releasing the handle of an SPI device. - - Reading or writing data of a specified length from or into an SPI device. - - Customizing data reading or writing via **SpiMsg**. - - Obtaining and setting SPI device configuration parameters. - - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Currently, these functions are only applicable in the communication initiated by the SPI controller. - -## Available APIs - -**Table 1** APIs for the SPI driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

SPI device handle obtaining/releasing

-

SpiOpen

-

Obtains an SPI device handle.

-

SpiClose

-

Releases an SPI device handle.

-

SPI reading/writing

-

SpiRead

-

Reads data of a specified length from an SPI device.

-

SpiWrite

-

Writes data of a specified length into an SPI device.

-

SpiTransfer

-

Transfers SPI data.

-

SPI device configuration

-

-

SpiSetCfg

-

Sets configuration parameters for an SPI device.

-

SpiGetCfg

-

Obtains configuration parameters of an SPI device.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions provided in this document can be called only in kernel space. - diff --git a/en/device-dev/driver/spiusage-example.md b/en/device-dev/driver/spiusage-example.md deleted file mode 100644 index f3d6cb2b6f667233355952efa8c7c91e780bc182..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/spiusage-example.md +++ /dev/null @@ -1,70 +0,0 @@ -# SPI Usage Example - -The following is a usage example of an SPI device, including how to obtain an SPI device handle, set the configuration parameters, and then read or write data from or into the SPI device, and finally destroy the SPI device handle. - -``` -#include "hdf_log.h" -#include "spi_if.h" - -void SpiTestSample(void) -{ - int32_t ret; - struct SpiCfg cfg; /* SPI device configuration information */ - struct SpiDevInfo spiDevinfo; /* SPI device descriptor */ - DevHandle spiHandle = NULL; /* SPI device handle */ - struct SpiMsg msg; /* Custom message to be transferred */ - uint8_t rbuff[4] = { 0 }; - uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; - uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; - - spiDevinfo.busNum = 0; /* SPI device bus number */ - spiDevinfo.csNum = 0; /* SPI device CS number */ - spiHandle = SpiOpen(&spiDevinfo); /* Obtain an SPI device handle based on spiDevinfo. */ - if (spiHandle == NULL) { - HDF_LOGE("SpiOpen: failed\n"); - return; - } - /* Obtain configuration parameters of an SPI device. */ - ret = SpiGetCfg(spiHandle, &cfg); - if (ret != 0) { - HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); - goto err; - } - cfg.maxSpeedHz = 115200; /* Change the maximum clock frequency to 115200. */ - cfg.bitsPerWord = 8; /* Change the word width to 8 bits. */ - /* Set configuration parameters for an SPI device. */ - ret = SpiSetCfg(spiHandle, &cfg); - if (ret != 0) { - HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); - goto err; - } - /* Write specified length of data into an SPI device. */ - ret = SpiWrite(spiHandle, wbuff, 4); - if (ret != 0) { - HDF_LOGE("SpiWrite: failed, ret %d\n", ret); - goto err; - } - /* Read data of a specified length from an SPI device. */ - ret = SpiRead(spiHandle, rbuff, 4); - if (ret != 0) { - HDF_LOGE("SpiRead: failed, ret %d\n", ret); - goto err; - } - msg.wbuf = wbuff2; /* Pointer to the data to write */ - msg.rbuf = rbuff; /* Pointer to the data to read */ - msg.len = 4; /* The length of the data to be read or written is 4 bits. */ - msg.csChange = 1; /* Disable the CS before the next transfer. */ - msg.delayUs = 0; /* No delay before the next transfer */ - msg.speed = 115200; /* Speed of this transfer */ - /* Launch a custom transfer. The number of messages to be transferred is 1. */ - ret = SpiTransfer(spiHandle, &msg, 1); - if (ret != 0) { - HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); - goto err; - } -err: - /* Destroy the SPI device handle. */ - SpiClose(spiHandle); -} -``` - diff --git a/en/device-dev/driver/spiusage-guidelines.md b/en/device-dev/driver/spiusage-guidelines.md deleted file mode 100644 index f5f9c482c055005b3544881cf16ef8e4e197abc3..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/spiusage-guidelines.md +++ /dev/null @@ -1,386 +0,0 @@ -# SPI Usage Guidelines - -- [How to Use](#section691514116412) -- [Obtaining an SPI Device Handle](#section12372204616215) -- [Obtaining SPI Device Configuration Parameters](#section17121446171311) -- [Setting SPI Device Configuration Parameters](#section97691946634) -- [Performing SPI Communication](#section197116254416) -- [Destroying the SPI Device Handle](#section117661819108) - -## How to Use - -[Figure 1](#fig23885455594) shows the process of using an SPI device. - -**Figure 1** Process of using an SPI device - - -![](figures/en-us_image_0000001054726248.png) - -## Obtaining an SPI Device Handle - -Before performing SPI communication, obtain an SPI device handle by calling **SpiOpen**. This function returns an SPI device handle with a specified bus number and CS number. - -DevHandle SpiOpen\(const struct SpiDevInfo \*info\); - -**Table 1** Description of **SpiOpen** - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

info

-

Pointer to the SPI device descriptor.

-

Return Value

-

Description

-

NULL

-

Failed to obtain an SPI device handle.

-

Device handle

-

Returns the pointer to the SPI device handle.

-
- -The following example shows how to obtain an SPI device handle based on the assumption that both the bus number and CS number of the SPI device are **0**. - -``` -struct SpiDevInfo spiDevinfo; /* SPI device descriptor */ -DevHandle spiHandle = NULL; /* SPI device handle */ -spiDevinfo.busNum = 0; /* SPI device bus number */ -spiDevinfo.csNum = 0; /* SPI device CS number */ - -/* Obtain an SPI device handle. */ -spiHandle = SpiOpen(&spiDevinfo); -if (spiHandle == NULL) { - HDF_LOGE("SpiOpen: failed\n"); - return; -} -``` - -## Obtaining SPI Device Configuration Parameters - -After obtaining the SPI device handle, obtain the SPI device configuration parameters by calling the following function: - -int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\); - -**Table 2** Description of **SpiGetCfg** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

cfg

-

Pointer to SPI device configuration parameters.

-

Return Value

-

Description

-

0

-

Succeeded in obtaining SPI device configuration parameters.

-

Negative value

-

Failed to obtain SPI device configuration parameters.

-
- -``` -int32_t ret; -struct SpiCfg cfg = {0}; /* SPI configuration information */ -ret = PalSpiSetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */ -if (ret != 0) { - HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); -} -``` - -## Setting SPI Device Configuration Parameters - -After obtaining the SPI device handle, set SPI device configuration parameters by calling the following function: - -int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\); - -**Table 3** Description of **SpiSetCfg** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

cfg

-

Pointer to SPI device configuration parameters.

-

Return Value

-

Description

-

0

-

Succeeded in setting SPI device configuration parameters.

-

Negative value

-

Failed to set SPI device configuration parameters.

-
- -``` -int32_t ret; -struct SpiCfg cfg = {0}; /* SPI configuration information */ -cfg.mode = SPI_MODE_LOOP; /* Communicate in loopback mode. */ -cfg.comMode = PAL_SPI_POLLING_TRANSFER; /* Communicate in polling mode. */ -cfg.maxSpeedHz = 115200; /* Maximum transmission frequency */ -cfg.bitsPerWord = 8; /* The width of per word to be read or written is 8 bits. */ -ret = SpiSetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */ -if (ret != 0) { - HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); -} -``` - -## Performing SPI Communication - -- Writing data of a specified length into an SPI device - -To write data into an SPI device only once, call the following function: - -int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); - -**Table 4** Description of **SpiWrite** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

buf

-

Pointer to the data to write.

-

len

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Succeeded in writing data into an SPI device.

-

Negative value

-

Failed to write data into an SPI device.

-
- -``` -int32_t ret; -uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78}; -/* Write data of a specified length into an SPI device. */ -ret = SpiWrite(spiHandle, wbuff, 4); -if (ret != 0) { - HDF_LOGE("SpiWrite: failed, ret %d\n", ret); -} -``` - -- Reading data of a specified length from an SPI device - -To read data from an SPI device only once, call the following function: - -int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); - -**Table 5** Description of **SpiRead** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

buf

-

Pointer to the data to read.

-

len

-

Length of the data to read.

-

Return Value

-

Description

-

0

-

Succeeded in reading data from an SPI device.

-

Negative value

-

Failed to read data from an SPI device.

-
- -``` -int32_t ret; -uint8_t rbuff[4] = {0}; -/* Read data of a specified length from an SPI device. */ -ret = SpiRead(spiHandle, rbuff, 4); -if (ret != 0) { - HDF_LOGE("SpiRead: failed, ret %d\n", ret); -} -``` - -- Launching a custom transfer - -To launch a custom transfer, call the following function: - -int32\_t SpiTransfer\(DevHandle handle, struct SpiMsg \*msgs, uint32\_t count\); - -**Table 6** Description of **SpiTransfer** - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

msgs

-

Pointer to the message array to be transferred.

-

count

-

Length of the message array.

-

Return Value

-

Description

-

0

-

Succeeded in launching the custom transfer.

-

Negative value

-

Failed to launch the custom transfer.

-
- -``` -int32_t ret; -uint8_t wbuff[1] = {0x12}; -uint8_t rbuff[1] = {0}; -struct SpiMsg msg; /* Custom message to be transferred */ -msg.wbuf = wbuff; /* Pointer to the data to read */ -msg.rbuf = rbuff; /* Pointer to the data to read */ -msg.len = 1; /* The length of the data to be read or written is 1 bit. */ -msg.csChange = 1; /* Disable the CS before the next transfer. */ -msg.delayUs = 0; /* No delay before the next transfer */ -msg.speed = 115200; /* Speed of this transfer */ -/* Launch a custom transfer. The number of messages to be transferred is 1. */ -ret = SpiTransfer(spiHandle, &msg, 1); -if (ret != 0) { - HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); -} -``` - -## Destroying the SPI Device Handle - -After the SPI communication, destroy the SPI device handle by calling the following function: - -void SpiClose\(DevHandle handle\); - -This function will release the resources previously obtained. - -**Table 7** Description of **SpiClose** - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle

-
- -``` -PalHandleDestroy(spiHandle); /* Destroy the SPI device handle. */ -``` - diff --git a/en/device-dev/driver/touchscreen.md b/en/device-dev/driver/touchscreen.md deleted file mode 100644 index 49b35d23fb1f1ea0438f92292ae22e794a155dbb..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/touchscreen.md +++ /dev/null @@ -1,9 +0,0 @@ -# TOUCHSCREEN - -- **[Touchscreen Overview](touchscreenoverview.md)** - -- **[Touchscreen Development Guidelines](touchscreendevelopment-guidelines.md)** - -- **[Touchscreen Development Example](touchscreendevelopment-example.md)** - - diff --git a/en/device-dev/driver/touchscreendevelopment-example.md b/en/device-dev/driver/touchscreendevelopment-example.md deleted file mode 100644 index 8d49343af5e1b1c2e1aaaa1fc113d75f2dc8a540..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/touchscreendevelopment-example.md +++ /dev/null @@ -1,300 +0,0 @@ -# Touchscreen Development Example - -- [Device Description Configuration](#section85281142102317) -- [Board-level Hardware Configuration and Private Data Configuration](#section189081946192410) -- [Adding the Touchscreen Driver](#section19856687253) - -This example describes how to develop the touchscreen driver. - -## Device Description Configuration - -The information about modules of the input driver model is shown as follows and enables the HDF to load the modules in sequence. For details, see [Driver Development](driver-development.md). - -``` -input :: host { - hostName = "input_host"; - priority = 100; - device_input_manager :: device { - device0 :: deviceNode { - policy = 2; // Publish services externally. - priority = 100; // Loading priority. The input device manager in the input driver has the highest priority. - preload = 0; // Value 0 indicates that the driver is to be loaded, and value 1 indicates the opposite. - permission = 0660; - moduleName = "HDF_INPUT_MANAGER"; - serviceName = "input_dev_manager"; - deviceMatchAttr = ""; - } - } - device_hdf_touch :: device { - device0 :: deviceNode { - policy = 2; - priority = 120; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH"; - serviceName = "event1"; - deviceMatchAttr = "touch_device1"; - } - } - - device_touch_chip :: device { - device0 :: deviceNode { - policy = 0; - priority = 130; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH_SAMPLE"; - serviceName = "hdf_touch_sample_service"; - deviceMatchAttr = "zsj_sample_5p5"; - } - } -} -``` - -## Board-level Hardware Configuration and Private Data Configuration - -The following describes the configuration of the board-level hardware and private data of the touchscreen. You can modify the configuration based on the service requirements. - -``` -root { - input_config { - touchConfig { - touch0 { - boardConfig { - match_attr = "touch_device1"; - inputAttr { - inputType = 0; // Value 0 indicates that the input device is a touchscreen. - solutionX = 480; - solutionY = 960; - devName = "main_touch"; // Device name - } - busConfig { - busType = 0; // Value 0 indicates the I2C bus. - busNum = 6; - clkGpio = 86; - dataGpio = 87; - i2cClkIomux = [0x114f0048, 0x403]; // Register configuration of the i2c_clk pin - i2cDataIomux = [0x114f004c, 0x403]; // Register configuration of the i2c_data pin - } - pinConfig { - rstGpio = 3; - intGpio = 4; - rstRegCfg = [0x112f0094, 0x400]; // Register configuration of the reset pin - intRegCfg = [0x112f0098, 0x400]; // Register configuration of the interrupt pin - } - powerConfig { - vccType = 2; // Values 1, 2, and 3 indicate the low-dropout regulator (LDO), GPIO, and PMIC, respectively. - vccNum = 20; // The GPIO number is 20. - vccValue = 1800; // The voltage amplitude is 1800 mV. - vciType = 1; - vciNum = 12; - vciValue = 3300; - } - featureConfig { - capacitanceTest = 0; - gestureMode = 0; - gloverMOde = 0; - coverMode = 0; - chargerMode = 0; - knuckleMode = 0; - } - } - chipConfig { - template touchChip { - match_attr = ""; - chipName = "sample"; - vendorName = "zsj"; - chipInfo = "AAAA11222"; // The first four characters indicate the product name. The fifth and sixth characters indicate the IC model. The last three characters indicate the chip model. - busType = 0; - deviceAddr = 0x5D; - irqFlag = 2; // Values 1 and 2 indicate that the interrupt is triggered on the rising and falling edges, respectively. Values 4 and 8 indicate that the interrupt is triggered by the high and low levels, respectively. - maxSpeed = 400; - chipVersion = 0; - powerSequence { - /* Power-on sequence is described as follows: - [Type, status, direction, delay] - Value 0 indicates the power or pin is empty. Values 1 and 2 indicate the VCC (1.8 V) and VCI (3.3 V) power, respectively. Values 3 and 4 indicate the reset and interrupt pins, respectively. - Values 0 and 1 indicate the power-off or pull-down, and the power-on or pull-up, respectively. Value 2 indicates that no operation is performed. - Values 0 and 1 indicate the input and output directions, respectively. Value 2 indicates that no operation is performed. - Delay time, in milliseconds. - */ - powerOnSeq = [4, 0, 1, 0, - 3, 0, 1, 10, - 3, 1, 2, 60, - 4, 2, 0, 0]; - suspendSeq = [3, 0, 2, 10]; - resumeSeq = [3, 1, 2, 10]; - powerOffSeq = [3, 0, 2, 10, - 1, 0, 2, 20]; - } - } - chip0 :: touchChip { - match_attr = "zsj_sample_5p5"; - chipInfo = "ZIDN45100"; - chipVersion = 0; - } - } - } - } - } -} -``` - -## Adding the Touchscreen Driver - -The following example shows how to implement the differentiated APIs provided by the platform driver to obtain and parse the touchscreen data. You can adjust the development process based on the board and touchscreen in use. - -``` -/* Parse the touch reporting data read from the touchscreen into coordinates. */ -static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) -{ - int32_t resX = device->driver->boardCfg->attr.resolutionX; - int32_t resY = device->driver->boardCfg->attr.resolutionY; - - for (int32_t i = 0; i < pointNum; i++) { - frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].valid = true; - } -} -/* Obtain the touch reporting data from the chip. */ -static int32_t ChipDataHandle(ChipDevice *device) -{ - int32_t ret; - uint8_t touchStatus = 0; - uint8_t pointNum; - uint8_t buf[GT_POINT_SIZE * MAX_SUPPORT_POINT] = {0}; - InputI2cClient *i2cClient = &device->driver->i2cClient; - uint8_t reg[GT_ADDR_LEN] = {0}; - FrameData *frame = &device->driver->frameData; - reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; - ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); - if (ret < 0 || touchStatus == GT_EVENT_INVALID) { - return HDF_FAILURE; - } - OsalMutexLock(&device->driver->mutex); - (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData)); - if (touchStatus == GT_EVENT_UP) { - frame->realPointNum = 0; - frame->definedEvent = TOUCH_UP; - goto exit; - } - reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; - pointNum = touchStatus & GT_FINGER_NUM_MASK; - if (pointNum <= 0 || pointNum > MAX_SUPPORT_POINT) { - HDF_LOGE("%s: pointNum is invalid, %d", __func__, pointNum); - (void)ChipCleanBuffer(i2cClient); - OsalMutexUnlock(&device->driver->mutex); - return HDF_FAILURE; - } - frame->realPointNum = pointNum; - frame->definedEvent = TOUCH_DOWN; - /* Read the touch reporting data from the register. */ - (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); - /* Parse the touch reporting data. */ - ParsePointData(device, frame, buf, pointNum); -exit: - OsalMutexUnlock(&device->driver->mutex); - if (ChipCleanBuffer(i2cClient) != HDF_SUCCESS) { - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -static struct TouchChipOps g_sampleChipOps = { - .Init = ChipInit, - .Detect = ChipDetect, - .Resume = ChipResume, - .Suspend = ChipSuspend, - .DataHandle = ChipDataHandle, -}; - -static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device) -{ - TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg)); - if (chipCfg == NULL) { - HDF_LOGE("%s: instance chip config failed", __func__); - return NULL; - } - (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg)); - /* Parse the private configuration of the touchscreen. */ - if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: parse chip config failed", __func__); - OsalMemFree(chipCfg); - chipCfg = NULL; - } - return chipCfg; -} - -static ChipDevice *ChipDeviceInstance(void) -{ - ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice)); - if (chipDev == NULL) { - HDF_LOGE("%s: instance chip device failed", __func__); - return NULL; - } - (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice)); - return chipDev; -} - -static void FreeChipConfig(TouchChipCfg *config) -{ - if (config->pwrSeq.pwrOn.buf != NULL) { - OsalMemFree(config->pwrSeq.pwrOn.buf); - } - if (config->pwrSeq.pwrOff.buf != NULL) { - OsalMemFree(config->pwrSeq.pwrOff.buf); - } - OsalMemFree(config); -} - -static int32_t HdfSampleChipInit(struct HdfDeviceObject *device) -{ - TouchChipCfg *chipCfg = NULL; - ChipDevice *chipDev = NULL; - HDF_LOGE("%s: enter", __func__); - if (device == NULL) { - return HDF_ERR_INVALID_PARAM; - } - /* Parse the private configuration of the touchscreen. */ - chipCfg = ChipConfigInstance(device); - if (chipCfg == NULL) { - return HDF_ERR_MALLOC_FAIL; - } - /* Instantiate the touchscreen device. */ - chipDev = ChipDeviceInstance(); - if (chipDev == NULL) { - goto freeCfg; - } - chipDev->chipCfg = chipCfg; - chipDev->ops = &g_sampleChipOps; - chipDev->chipName = chipCfg->chipName; - chipDev->vendorName = chipCfg->vendorName; - - /* Register the touchscreen device with the platform driver. */ - if (RegisterChipDevice(chipDev) != HDF_SUCCESS) { - goto freeDev; - } - HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName); - return HDF_SUCCESS; - -freeDev: - OsalMemFree(chipDev); -freeCfg: - FreeChipConfig(chipCfg); - return HDF_FAILURE; -} - -struct HdfDriverEntry g_touchSampleChipEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH_SAMPLE", - .Init = HdfSampleChipInit, -}; - -HDF_INIT(g_touchSampleChipEntry); -``` - diff --git a/en/device-dev/driver/touchscreendevelopment-guidelines.md b/en/device-dev/driver/touchscreendevelopment-guidelines.md deleted file mode 100644 index 9e1543c1e668c4bdc8aa62be3073a6539ff5f1de..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/touchscreendevelopment-guidelines.md +++ /dev/null @@ -1,35 +0,0 @@ -# Touchscreen Development Guidelines - -- [How to Develop](#section1255740132616) - -Regardless of the OS and system on a chip \(SoC\), the input driver is developed based on the HDF, platform, and OSAL APIs to provide a unified driver model for touchscreen devices. - -- The following uses the touchscreen driver as an example to describe the loading process of the input driver model: - - Add the touchscreen driver-related descriptions: You can add the touchscreen driver-related descriptions, such as the loading priority, board-level hardware information, and private data, by referring to the existing template. - - - Load the input device manager driver: The HDF automatically loads the input device manager driver, which then creates the device manager and initializes it. - - - Load the touchscreen common driver: The HDF automatically loads the touchscreen common driver, which then parses the board-level configuration, initializes the hardware, and provides the API for registering the touchscreen. - - - Load the touchscreen chip driver: The HDF automatically loads the touchscreen chip driver, which then instantiates the touchscreen device, parses the private data, and implements differentiated APIs provided by the platform. - - - Register the touchscreen device with the platform driver: Register the instantiated touchscreen device with the platform driver, bind this device to the platform driver, and complete touchscreen initialization such as interrupt registration and power-on and power-off. - - - Register the input device: Instantiate the input device and register it with the input manager after the touchscreen is initialized. - - -## How to Develop - -1. Add the touchscreen driver-related descriptions. - - Currently, the input driver is developed based on the HDF and is loaded and started by the HDF. Register the driver information, such as whether to load the driver and the loading priority in the configuration file. Then, the HDF starts the registered driver modules one by one. For details about the driver configuration, see [How to Develop](driver-development.md#section1969312275533). - -2. Complete the board-level configuration and private data configuration of the touchscreen. - - Configure the required I/O pins. For example, configure a register for the I2C pin reserved for the touchscreen to use I2C for transmitting data. - -3. Implement differentiated adaptation APIs of the touchscreen. - - Use the platform APIs to perform operations for the reset pins, interrupt pins and power based on the communications interfaces designed for boards. For details about the GPIO-related operations, see [GPIO Usage Guidelines](gpiousage-guidelines.md). - - diff --git a/en/device-dev/driver/touchscreenoverview.md b/en/device-dev/driver/touchscreenoverview.md deleted file mode 100644 index b136894e5ade080a07e5ff457b20fd74eefd33b9..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/touchscreenoverview.md +++ /dev/null @@ -1,71 +0,0 @@ -# Touchscreen Overview - -- [Introduction](#section124332411260) -- [Available APIs](#section10542625172618) - -## Introduction - -- **Functions of the Touchscreen driver** - - The Touchscreen driver is used to power on its integrated circuit \(IC\), configure and initialize hardware pins, register interrupts, configure Inter-Integrated Circuit \(I2C\) or SPI APIs, set input-related configurations, and download and update firmware. - - -- **Layers of the Touchscreen driver** - - This section describes how to develop the touchscreen driver based on the input driver model. [Figure 1](#fig6251184817261) shows an overall architecture of the touchscreen driver. - - The input driver is developed based on the hardware driver foundation \(HDF\), platform APIs, and operating system abstraction layer \(OSAL\) APIs. It provides hardware driver capabilities through the input Hardware Driver Interfaces \(HDIs\) for upper-layer input services to control the touchscreen. - - -**Figure 1** Architecture of the input driver model -![](figures/architecture-of-the-input-driver-model.png "architecture-of-the-input-driver-model") - -- **Input driver model** - - The input driver model mainly consists of the device manager, common drivers, and chip drivers. The platform data channel provides capabilities for sending data generated by the touchscreen from the kernel to the user space. The driver model adapts to different touchscreen devices and hardware platforms via the configuration file, improving the efficiency of the touchscreen development. The description for each part of the input driver model is as follows: - - - Input device manager: provides various input device drivers with the APIs for registering or unregistering input devices and manages the input device list. - - - Input common driver: provides common abstract drivers \(such as the touchscreen common driver\) of various input devices for initializing the board-level hardware, processing hardware interrupts, and registering input devices with the input device manager. - - - Input chip driver: provides different chip drivers of each vendor. You can minimize the workload for the input chip driver development by calling differentiated APIs reserved by the input platform driver. - - - Event hub: provides a unified data reporting channel, which enables various input devices to report input events. - - - HDF input config: parses and manages the board-level configuration as well as the private configuration of input devices. - - -- **Advantages of developing drivers based on the HDF** - - The touchscreen driver is developed based on the HDF and is implemented via calls to the OSAL and platform APIs, including bus APIs and OS native APIs \(such as memory, lock, thread, and timer\). The OSAL and platform APIs hide the differences of underlying hardware, so that the touchscreen driver can be migrated across platforms and OSs. In this regard, you can develop the touchscreen driver only once but deploy it on multiple devices. - - -## Available APIs - -Based on the attributes of the pins, interfaces on the touchscreens can be classified into the following types: - -- Power interfaces -- I/O control interfaces -- Communications interfaces - -**Figure 2** Common pins of the touchscreen -![](figures/common-pins-of-the-touchscreen.png "common-pins-of-the-touchscreen") - -The interfaces shown in the figure are described as follows: - -1. **Power interfaces** - - LDO\_1P8: 1.8 V digital circuits - - LDO\_3P3: 3.3 V analog circuits - - Generally, the touchscreen driver IC is separated from the LCD driver IC. In this case, the touchscreen driver IC requires both 1.8 V and 3.3 V power supplies. Nowadays, the touchscreen driver IC and LCD driver IC can be integrated. Therefore, the touchscreen, requires only the 1.8 V power supply, and the 3.3 V power required internally is supplied by the LCD VSP power \(typical value: 5.5 V\) in the driver IC. - - -2. **I/O control interfaces** - - RESET: reset pin, which is used to reset the driver IC on the host when suspending or resuming the system. - - INT: interrupt pin, which needs to be set to the input direction and pull-up status during driver initialization. After detecting an external touch signal, the driver triggers the interrupt by operating the interrupt pin. The driver reads the touch reporting data in the ISR function. - -3. **Communications interfaces** - - I2C: Since only a small amount of touch data is reported by the touchscreen, I2C is used to transmit the reported data. For details about the I2C protocol and interfaces, see [I2C Usage Guidelines](i2c-usage-guidelines.md). - - SPI: In addition to touch reporting data coordinates, some vendors need to obtain basic capacitance data. Therefore, Serial Peripheral Interface \(SPI\) is used to transmit such huge amount of data. For details about the SPI protocol and interfaces, see [SPI Usage Guidelines](spiusage-guidelines.md). - - diff --git a/en/device-dev/driver/uart.md b/en/device-dev/driver/uart.md deleted file mode 100644 index 9abd98bb4e661a01011d233577ae4109bcdd208e..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/uart.md +++ /dev/null @@ -1,9 +0,0 @@ -# UART - -- **[UART Overview](uartoverview.md)** - -- **[UART Usage Guidelines](uartusage-guidelines.md)** - -- **[UART Usage Example](uartusage-example.md)** - - diff --git a/en/device-dev/driver/uartoverview.md b/en/device-dev/driver/uartoverview.md deleted file mode 100644 index 2238f2ca5564f4f1faa35bf16590c51a6492ad07..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/uartoverview.md +++ /dev/null @@ -1,106 +0,0 @@ -# UART Overview - -- [Introduction](#section14770623164917) -- [Available APIs](#section149505462492) - -## Introduction - -- The Universal Asynchronous Receiver/Transmitter \(UART\) is a universal serial data bus used for asynchronous communication. It enables bi-directional communication between devices in full-duplex mode. -- UART is widely used to print information for debugging or to connect to various external modules such as GPS and Bluetooth. -- A UART is connected to other modules through two wires \(as shown in [Figure 1](#fig209936401896)\) or four wires \(as shown in [Figure 2](#fig1435614171015)\). - - TX: TX pin of the transmitting UART. It is connected to the RX pin of the peer UART. - - RX: RX pin of the receiving UART. It is connected to the TX pin of the peer UART. - - RTS: Request to Send signal pin. It is connected to the CTS pin of the peer UART and is used to indicate whether the local UART is ready to receive data. - - CTS: Clear to Send signal pin. It is connected to the RTS pin of the peer UART and is used to indicate whether the local UART is allowed to send data to the peer end. - - **Figure 1** 2-wire UART communication - - - ![](figures/en-us_image_0000001053926237.png) - - **Figure 2** 4-wire UART communication - - - ![](figures/en-us_image_0000001054007499.png) - - -- The transmitting and receiving UARTs must ensure that they have the same settings on particular attributes such as the baud rate and data format \(start bit, data bit, parity bit, and stop bit\) before they start to communicate. During data transmission, a UART sends data to the peer end over the TX pin and receives data from the peer end over the RX pin. When the size of the buffer used by a UART for storing received data reaches the preset threshold, the RTS signal of the UART changes to **1** \(data cannot be received\), and the peer UART stops sending data to it because its CTS signal does not allow it to send data. -- The UART interface defines a set of common functions for operating a UART port, including obtaining and releasing device handles, reading and writing data of a specified length, and obtaining and setting the baud rate, as well as the device attributes. - -## Available APIs - -**Table 1** APIs for the UART driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

Obtaining and releasing device handles

-

-

UartOpen

-

Obtains the UART device handle.

-

UartClose

-

Releases a specified UART device handle.

-

Reading and writing data

-

-

UartRead

-

Reads data of a specified length from a UART device.

-

UartWrite

-

Writes data of a specified length into a UART device.

-

Obtaining and setting the baud rate

-

UartGetBaud

-

Obtains the UART baud rate.

-

UartSetBaud

-

Sets the UART baud rate.

-

Obtaining and setting device attributes

-

-

UartGetAttribute

-

Obtains the UART device attributes.

-

UartSetAttribute

-

Sets the UART device attributes.

-

Setting the transmission mode

-

UartSetTransMode

-

Sets the UART transmission mode.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions provided in this document can be called only in kernel space. - diff --git a/en/device-dev/driver/uartusage-example.md b/en/device-dev/driver/uartusage-example.md deleted file mode 100644 index 32572d405213dc537c54c2dafdd7c1902e64a048..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/uartusage-example.md +++ /dev/null @@ -1,67 +0,0 @@ -# UART Usage Example - -The following is a usage example of a UART device, including how to obtain the UART device handle, set the baud rate, device attributes, and transmission mode, read data from or write data into the UART device, and then destroy the UART device handle. - -``` -#include "hdf_log.h" -#include "uart_if.h" - -void UartTestSample(void) -{ - int32_t ret; - uint32_t port; - DevHandle handle = NULL; - uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; - uint8_t rbuff[5] = { 0 }; - struct UartAttribute attribute; - attribute.dataBits = UART_ATTR_DATABIT_7; /* Set the number of data bits to 7. */ - attribute.parity = UART_ATTR_PARITY_NONE; /* Set the parity bit to no parity. */ - attribute.stopBits = UART_ATTR_STOPBIT_1; /* Set the stop bit to 1. */ - attribute.rts = UART_ATTR_RTS_DIS; /* Disable the RTS signal. */ - attribute.cts = UART_ATTR_CTS_DIS; /* Disable the CTS signal. */ - attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* Enable RX FIFO. */ - attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* Enable TX FIFO. */ - /* Set the UART port number actually used. */ - port = 1; - /* Obtain the UART device handle. */ - handle = UartOpen(port); - if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); - return; - } - /* Set the UART baud rate to 9600. */ - ret = UartSetBaud(handle, 9600); - if (ret != 0) { - HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); - goto _ERR; - } - /* Set the UART device attributes. */ - ret = UartSetAttribute(handle, &attribute); - if (ret != 0) { - HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); - goto _ERR; - } - /* Set the UART transmission mode to non-blocking mode. */ - ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); - if (ret != 0) { - HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); - goto _ERR; - } - /* Write 5-byte data into the UART device. */ - ret = UartWrite(handle, wbuff, 5); - if (ret != 0) { - HDF_LOGE("UartWrite: failed, ret %d\n", ret); - goto _ERR; - } - /* Read 5-byte data from the UART device. */ - ret = UartRead(handle, rbuff, 5); - if (ret < 0) { - HDF_LOGE("UartRead: failed, ret %d\n", ret); - goto _ERR; - } -_ERR: - /* Destroy the UART device handle. */ - UartClose(handle); -} -``` - diff --git a/en/device-dev/driver/uartusage-guidelines.md b/en/device-dev/driver/uartusage-guidelines.md deleted file mode 100644 index edd894e92db887d324ef8b51934c720791bb8b5e..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/uartusage-guidelines.md +++ /dev/null @@ -1,506 +0,0 @@ -# UART Usage Guidelines - -- [How to Use](#section47784125013) -- [Obtaining a UART Device Handle](#section146445153110) -- [Setting the UART Baud Rate](#section1862705516339) -- [Obtaining the UART Baud Rate](#section1263651563414) -- [Setting the UART Device Attributes](#section1770091483814) -- [Obtaining UART Device Attributes](#section117543316384) -- [Setting the UART Transmission Mode](#section187233112369) -- [Writing Data of a Specified Length into a UART Device](#section82416423368) -- [Reading Data of a Specified Length from a UART Device](#section192177171373) -- [Destroying the UART Device Handle](#section63131236354) - -## How to Use - -[Figure 1](#fig1852173020185) shows the process of using a UART device. - -**Figure 1** Process of using a UART device - - -![](figures/en-us_image_0000001054006983.png) - -## Obtaining a UART Device Handle - -Before performing UART communication, call **UartOpen** to obtain a UART device handle. This function returns the pointer to the UART device handle with a specified port number. - -DevHandle UartOpen\(uint32\_t port\); - -**Table 1** Description of **UartOpen** - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

port

-

UART port number.

-

Return Value

-

Description

-

NULL

-

Failed to obtain the UART device handle.

-

Device handle

-

Pointer to the UART device handle.

-
- -The following example shows how to obtain a UART device handle based on the assumption that the UART port number is **3**: - -``` -DevHandle handle = NULL; /* The UART device handle */ -uint32_t port = 3; /* UART port number */ -handle = UartOpen(port); -if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); - return; -} -``` - -## Setting the UART Baud Rate - -After obtaining the UART device handle, set the UART baud rate by calling the following function: - -int32\_t UartSetBaud\(DevHandle handle, uint32\_t baudRate\); - -**Table 2** Description of **UartSetBaud** - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

baudRate

-

Baud rate of the UART to set.

-

Return Value

-

Description

-

0

-

Succeeded in setting the UART baud rate.

-

Negative value

-

Failed to set the UART baud rate.

-
- -The following example shows how to set the UART baud rate to **9600**: - -``` -int32_t ret; -/* Set the UART baud rate to 9600. */ -ret = UartSetBaud(handle, 9600); -if (ret != 0) { - HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); -} -``` - -## Obtaining the UART Baud Rate - -After setting the UART baud rate, obtain the current baud rate by calling the following function: - -int32\_t UartGetBaud\(DevHandle handle, uint32\_t \*baudRate\); - -**Table 3** Description of **UartGetBaud** - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

baudRate

-

Pointer to the UART baud rate.

-

Return Value

-

Description

-

0

-

Succeeded in obtaining the UART baud rate.

-

Negative value

-

Failed to obtain the UART baud rate.

-
- -The following example shows how to obtain the UART baud rate: - -``` -int32_t ret; -uint32_t baudRate; -/* Obtain the UART baud rate. */ -ret = UartGetBaud(handle, &baudRate); -if (ret != 0) { - HDF_LOGE("UartGetBaud: failed, ret %d\n", ret); -} -``` - -## Setting the UART Device Attributes - -Before performing UART communication, set the UART device attributes by calling the following function: - -int32\_t UartSetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); - -**Table 4** Description of **UartSetAttribute** - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

attribute

-

Pointer to the UART device attributes to set.

-

Return Value

-

Description

-

0

-

Succeeded in setting the UART device attributes.

-

Negative value

-

Failed to set the UART device attributes.

-
- -The following example shows how to set the UART device attributes: - -``` -int32_t ret; -struct UartAttribute attribute; -attribute.dataBits = UART_ATTR_DATABIT_7; /* Set the number of data bits to 7. */ -attribute.parity = UART_ATTR_PARITY_NONE; /* Set the parity bit to no parity. */ -attribute.stopBits = UART_ATTR_STOPBIT_1; /* Set the stop bit to 1. */ -attribute.rts = UART_ATTR_RTS_DIS; /* Disable the RTS signal. */ -attribute.cts = UART_ATTR_CTS_DIS; /* Disable the CTS signal. */ -attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* Enable RX FIFO. */ -attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* Enable TX FIFO. */ -/* Set the UART device attributes. */ -ret = UartSetAttribute(handle, &attribute); -if (ret != 0) { - HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); -} -``` - -## Obtaining UART Device Attributes - -After setting the UART device attributes, obtain the current device attributes by calling the following function: - -int32\_t UartGetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); - -**Table 5** Description of **UartGetAttribute** - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

attribute

-

Pointer to the UART device attributes.

-

Return Value

-

Description

-

0

-

Succeeded in obtaining the UART device attributes.

-

Negative value

-

Failed to obtain the UART device attributes.

-
- -The following example shows how to obtain the UART device attributes: - -``` -int32_t ret; -struct UartAttribute attribute; -/* Obtain the UART attributes. */ -ret = UartGetAttribute(handle, &attribute); -if (ret != 0) { - HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret); -} -``` - -## Setting the UART Transmission Mode - -Before performing UART communication, set the UART transmission mode by calling the following function: - -int32\_t UartSetTransMode\(DevHandle handle, enum UartTransMode mode\); - -**Table 6** Description of **UartSetTransMode** - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

mode

-

UART transmission mode to set.

-

Return Value

-

Description

-

0

-

Succeeded in setting the UART transmission mode.

-

Negative value

-

Failed to set the UART transmission mode.

-
- -The following example shows how to set the transmission mode to **UART\_MODE\_RD\_BLOCK**: - -``` -int32_t ret; -/* Set the UART transmission mode. */ -ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); -if (ret != 0) { - HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); -} -``` - -## Writing Data of a Specified Length into a UART Device - -To write data into a UART device, call the following function: - -int32\_t UartWrite\(DevHandle handle, uint8\_t \*data, uint32\_t size\); - -**Table 7** Description of **UartWrite** - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

data

-

Pointer to the data to write.

-

size

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Succeeded in writing data into the UART device.

-

Negative value

-

Failed to write data into the UART device.

-
- -The following example shows how to write data of a specified length into the UART device: - -``` -int32_t ret; -uint8_t wbuff[5] = {1, 2, 3, 4, 5}; -/* Write 5-byte data into the UART device. */ -ret = UartWrite(handle, wbuff, 5); -if (ret != 0) { - HDF_LOGE("UartWrite: failed, ret %d\n", ret); -} -``` - -## Reading Data of a Specified Length from a UART Device - -To read data from a UART device, call the following function: - -int32\_t UartRead\(DevHandle handle, uint8\_t \*data, uint32\_t size\); - -**Table 8** Description of **UartRead** - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

data

-

Pointer to the buffer for receiving the data.

-

size

-

Length of the data to read.

-

Return Value

-

Description

-

Non-negative value

-

Length of the data read from the UART device.

-

Negative value

-

Failed to read data from the UART device.

-
- -The following example shows how to read data of a specified length from the UART device: - -``` -int32_t ret; -uint8_t rbuff[5] = {0}; -/* Read 5-byte data from the UART device. */ -ret = UartRead(handle, rbuff, 5); -if (ret < 0) { - HDF_LOGE("UartRead: failed, ret %d\n", ret); -} -``` - ->![](public_sys-resources/icon-caution.gif) **CAUTION:** ->Data is successfully read from the UART device if a non-negative value is returned. If the return value is **0**, no valid data can be read from the UART device. If the return value is greater than **0**, the return value is the length of the data actually read from the UART device. The length is less than or equal to the value of **size** and does not exceed the maximum length of data to read at a time specified by the UART controller in use. - -## Destroying the UART Device Handle - -After the UART communication, destroy the UART device handle by calling the following function: - -void UartClose\(DevHandle handle\); - -This function will release the resources previously obtained. - -**Table 9** Description of **UartClose** - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Pointer to the UART device handle

-
- -The following example shows how to destroy the UART device handle: - -``` -UartClose(handle); /* Destroy the UART device handle. */ -``` - diff --git a/en/device-dev/driver/usage-example.md b/en/device-dev/driver/usage-example.md deleted file mode 100644 index e16e8f2eeadcc12bd537fa8655692af0e88c9893..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/usage-example.md +++ /dev/null @@ -1,98 +0,0 @@ -# Usage Example - -The following is an example of using a MIPI DSI device: - -``` -#include "hdf.h" -#include "mipi_dsi_if.h" - -void PalMipiDsiTestSample(void) -{ - uint8_t chnId; - int32_t ret; - DevHandle handle = NULL; - - /* Device channel ID */ - chnId = 0; - /* Obtain the MIPI DSI device handle based on a specified channel ID. */ - handle = MipiDsiOpen(chnId); - if (handle == NULL) { - HDF_LOGE("MipiDsiOpen: failed!\n"); - return; - } - /* MIPI DSI configuration parameters */ - struct MipiCfg cfg = {0}; - cfg.lane = DSI_4_LANES; - cfg.mode = DSI_CMD_MODE; - cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; - cfg.format = FORMAT_RGB_24_BIT; - cfg.pixelClk = 174; - cfg.phyDataRate = 384; - cfg.timingInfo.hsaPixels = 50; - cfg.timingInfo.hbpPixels = 55; - cfg.timingInfo.hlinePixels = 1200; - cfg.timingInfo.yResLines = 1800; - cfg.timingInfo.vbpLines = 33; - cfg.timingInfo.vsaLines = 76; - cfg.timingInfo.vfpLines = 120; - cfg.timingInfo.xResPixels = 1342; - /* Set MIPI DSI configuration parameters. */ - ret = MipiDsiSetCfg(g_handle, &cfg); - if (ret != 0) { - HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); - return; - } - /* Send the command for initializing the PANEL register. */ - struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); - if (cmd == NULL) { - return; - } - cmd->dtype = DTYPE_DCS_WRITE; - cmd->dlen = 1; - cmd->payload = OsalMemCalloc(sizeof(uint8_t)); - if (cmd->payload == NULL) { - HdfFree(cmd); - return; - } - *(cmd->payload) = DTYPE_GEN_LWRITE; - MipiDsiSetLpMode(mipiHandle); - ret = MipiDsiTx(mipiHandle, cmd); - MipiDsiSetHsMode(mipiHandle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret); - HdfFree(cmd->payload); - HdfFree(cmd); - return; - } - HdfFree(cmd->payload); - HdfFree(cmd); - /* Pointer to the register that reads the PANEL status */ - uint8_t readVal = 0; - struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); - if (cmdRead == NULL) { - return; - } - cmdRead->dtype = DTYPE_DCS_READ; - cmdRead->dlen = 1; - cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); - if (cmdRead->payload == NULL) { - HdfFree(cmdRead); - return; - } - *(cmdRead->payload) = DDIC_REG_STATUS; - MipiDsiSetLpMode(g_handle); - ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); - MipiDsiSetHsMode(g_handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - return; - } - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - /* Release the MIPI DSI device handle. */ - MipiDsiClose(handle); -} -``` - diff --git a/en/device-dev/driver/usage-guidelines.md b/en/device-dev/driver/usage-guidelines.md deleted file mode 100644 index 1934eaf6e0bb68cb83d76d0114635f10f5ec59b7..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/usage-guidelines.md +++ /dev/null @@ -1,365 +0,0 @@ -# Usage Guidelines - -- [How to Use](#section8982671284) -- [Obtaining a MIPI DSI Device Handle](#section57982569176) -- [Setting MIPI DSI Configuration Parameters](#section5935410201815) -- [Sending/Receiving the Pointer to a Command](#section611661316194) -- [Releasing the MIPI DSI Device Handle](#section217313211199) - -## How to Use - -[Figure 1](#fig99821771782) shows the process of using a MIPI DSI device. - -**Figure 1** Process of using a MIPI DSI device - - -![](figures/en-us_image_0000001072553354.png) - -## Obtaining a MIPI DSI Device Handle - -Before performing MIPI DSI communication, obtain a MIPI DSI device handle by calling **MipiDsiOpen**. This function returns a MIPI DSI device handle with a specified channel ID. - -DevHandle MipiDsiOpen\(uint8\_t id\); - -**Table 1** Description of **MipiDsiOpen** - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

id

-

MIPI DSI channel ID.

-

Return Value

-

Description

-

NULL

-

Failed to obtain the MIPI DSI channel ID.

-

Device handle

-

MIPI DSI device handle with a specified channel ID, whose data type is DevHandle.

-
- -The following example shows how to obtain a MIPI DSI device handle with the channel ID **0**: - -``` -DevHandle mipiDsiHandle = NULL; /* Device handle */ -chnId = 0; /* MIPI DSI channel ID */ - -/* Obtain the MIPI DSI device handle based on a specified channel ID. */ -mipiDsiHandle = MipiDsiOpen(chnId); -if (mipiDsiHandle == NULL) { - HDF_LOGE("MipiDsiOpen: failed\n"); - return; -} -``` - -## Setting MIPI DSI Configuration Parameters - -- Set MIPI DSI configuration parameters by calling the following function: - -int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\); - -**Table 2** Description of **MipiDsiSetCfg** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cfg

-

Pointer to MIPI DSI configuration parameters

-

Return Value

-

Description

-

0

-

Succeeded in setting MIPI DSI configuration parameters.

-

Negative value

-

Failed to set MIPI DSI configuration parameters.

-
- -``` -int32_t ret; -struct MipiCfg cfg = {0}; - -/* Configuration parameters of the connected device are as follows: */ -cfg.lane = DSI_4_LANES; -cfg.mode = DSI_CMD_MODE; -cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; -cfg.format = FORMAT_RGB_24_BIT; -cfg.pixelClk = 174; -cfg.phyDataRate = 384; -cfg.timingInfo.hsaPixels = 50; -cfg.timingInfo.hbpPixels = 55; -cfg.timingInfo.hlinePixels = 1200; -cfg.timingInfo.yResLines = 1800; -cfg.timingInfo.vbpLines = 33; -cfg.timingInfo.vsaLines = 76; -cfg.timingInfo.vfpLines = 120; -cfg.timingInfo.xResPixels = 1342; -/* Set MIPI DSI configuration parameters. */ -ret = MipiDsiSetCfg(g_handle, &cfg); -if (ret != 0) { - HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); - return -1; -} -``` - -- Obtain MIPI DSI configuration parameters by calling the following function: - -int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); - -**Table 3** Description of **MipiDsiGetCfg** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cfg

-

Pointer to MIPI DSI configuration parameters

-

Return Value

-

Description

-

0

-

Succeeded in obtaining MIPI DSI configuration parameters.

-

Negative value

-

Failed to obtain MIPI DSI configuration parameters.

-
- -``` -int32_t ret; -struct MipiCfg cfg; -memset(&cfg, 0, sizeof(struct MipiCfg)); -ret = MipiDsiGetCfg(g_handle, &cfg); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); - return HDF_FAILURE; -} -``` - -## Sending/Receiving the Pointer to a Command - -- Send the pointer to a specified command by calling the following function: - -int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); - -**Table 4** Description of **MipiDsiTx** - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cmd

-

Pointer to the command to be sent

-

Return Value

-

Description

-

0

-

Succeeded in sending the specified command.

-

Negative value

-

Failed to send the specified command.

-
- -``` -int32_t ret; -struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); -if (cmd == NULL) { - return HDF_FAILURE; -} -cmd->dtype = DTYPE_DCS_WRITE; -cmd->dlen = 1; -cmd->payload = OsalMemCalloc(sizeof(uint8_t)); -if (cmd->payload == NULL) { - HdfFree(cmd); - return HDF_FAILURE; -} -*(cmd->payload) = DTYPE_GEN_LWRITE; -MipiDsiSetLpMode(mipiHandle); -ret = MipiDsiTx(mipiHandle, cmd); -MipiDsiSetHsMode(mipiHandle); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret); - HdfFree(cmd->payload); - HdfFree(cmd); - return HDF_FAILURE; -} -HdfFree(cmd->payload); -HdfFree(cmd); -``` - -- Receive a specified command by calling the following function: - -int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); - -**Table 5** Description of **MipiDsiRx** - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cmd

-

Pointer to the command to be received

-

readLen

-

Length of the data to read.

-

out

-

Pointer to the read data.

-

Return Value

-

Description

-

0

-

Succeeded in receiving the specified command.

-

Negative value

-

Failed to receive the specified command.

-
- -``` -int32_t ret; -uint8_t readVal = 0; - -struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); -if (cmdRead == NULL) { - return HDF_FAILURE; -} -cmdRead->dtype = DTYPE_DCS_READ; -cmdRead->dlen = 1; -cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); -if (cmdRead->payload == NULL) { - HdfFree(cmdRead); - return HDF_FAILURE; -} -*(cmdRead->payload) = DDIC_REG_STATUS; -MipiDsiSetLpMode(g_handle); -ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); -MipiDsiSetHsMode(g_handle); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - return HDF_FAILURE; -} -HdfFree(cmdRead->payload); -HdfFree(cmdRead); -``` - -## Releasing the MIPI DSI Device Handle - -After the MIPI DSI communication, release the MIPI DSI device handle by calling the following function: - -void MipiDsiClose\(DevHandle handle\); - -This function releases the resources requested by **MipiDsiOpen**. - -**Table 6** Description of **MipiDsiClose** - - - - - - - - - - -

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-
- -``` -MipiDsiClose(mipiHandle); /* Release the MIPI DSI device handle */ -``` - diff --git a/en/device-dev/driver/watchdog.md b/en/device-dev/driver/watchdog.md deleted file mode 100644 index b8f20d1dad97959da8207df5b166e177854a35a9..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/watchdog.md +++ /dev/null @@ -1,9 +0,0 @@ -# WATCHDOG - -- **[Watchdog Overview](watchdogoverview.md)** - -- **[Watchdog Usage Guidelines](watchdogusage-guidelines.md)** - -- **[Watchdog Usage Example](watchdogusage-example.md)** - - diff --git a/en/device-dev/driver/watchdogoverview.md b/en/device-dev/driver/watchdogoverview.md deleted file mode 100644 index 04b3b373d03c4773f5bc45ba9ef3ca8cabc29a85..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/watchdogoverview.md +++ /dev/null @@ -1,78 +0,0 @@ -# Watchdog Overview - -- [Introduction](#section3579126111816) -- [Available APIs](#section17429111981812) - -## Introduction - -A watchdog, also called a watchdog timer, is a hardware timing device. If an error occurs in the main program of the system and fails to reset the watchdog timer, the watchdog timer sends a reset signal to restore the system to a normal state. - -## Available APIs - -**Table 1** Watchdog APIs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

Open/Close

-

WatchdogOpen

-

Opens a watchdog.

-

WatchdogClose

-

Closes a watchdog.

-

Start/Stop

-

WatchdogStart

-

Starts a watchdog.

-

WatchdogStop

-

Stops a watchdog.

-

Timeout duration

-

WatchdogSetTimeout

-

Sets the watchdog timeout duration.

-

WatchdogGetTimeout

-

Obtains the watchdog timeout duration.

-

Status

-

WatchdogGetStatus

-

Obtains the watchdog status.

-

Feeding

-

WatchdogFeed

-

Feeds a watchdog, or resets a watchdog timer.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All watchdog functions provided in this document can be called only in kernel mode. - diff --git a/en/device-dev/driver/watchdogusage-example.md b/en/device-dev/driver/watchdogusage-example.md deleted file mode 100644 index 98f6acfa0e383b059ed257df8411ef03f3f9ee72..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/watchdogusage-example.md +++ /dev/null @@ -1,86 +0,0 @@ -# Watchdog Usage Example - -This example provides a complete process for using a watchdog. - -In this example, open a watchdog, set the timeout duration, and start the watchdog. - -- Feed the watchdog periodically to ensure that the system is not reset due to timer expiry. -- Stop feeding the watchdog and check whether the system is reset after the timer expires. - -Example: - -``` -#include "watchdog_if.h" -#include "hdf_log.h" -#include "osal_irq.h" -#include "osal_time.h" - -#define WATCHDOG_TEST_TIMEOUT 2 -#define WATCHDOG_TEST_FEED_TIME 6 - -static int32_t TestCaseWatchdog(void) -{ - int32_t i; - int32_t ret; - uint32_t timeout; - DevHandle handle = NULL; - - /* Open watchdog 0. */ - handle = WatchdogOpen(0); - if (handle == NULL) { - HDF_LOGE("Open watchdog fail!"); - return -1; - } - - /* Set the timeout duration. */ - ret = WatchdogSetTimeout(handle, WATCHDOG_TEST_TIMEOUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set timeout fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - - /* Obtain the configured timeout duration. */ - ret = WatchdogGetTimeout(handle, &timeout); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); - - /* Start the watchdog. The timer starts. */ - ret = WatchdogStart(handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - - /* Feed the watchdog every 1s. */ - for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { - HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); - ret = WatchdogFeed(handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - OsalSleep(1); - } - /* Because the interval for feeding the watchdog is shorter than the timeout duration, the system does not reset, and logs can be printed normally. */ - HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); - - /* Enable the timer to expire by stopping feeding the watchdog. */ - for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { - HDF_LOGE("%s: watiting dog buck %d times... \n", __func__, i); - OsalSleep(1); - } - - /* The system resets when the timer expires. If the code is correct, the log below is not displayed. */ - HDF_LOGE("%s: dog has't buck!!! \n", __func__, i); - WatchdogClose(handle); - return -1; -} -``` - diff --git a/en/device-dev/driver/watchdogusage-guidelines.md b/en/device-dev/driver/watchdogusage-guidelines.md deleted file mode 100644 index e3eb5c091fb98497a9bc2f31dfe40cb69df93244..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/watchdogusage-guidelines.md +++ /dev/null @@ -1,395 +0,0 @@ -# Watchdog Usage Guidelines - -- [How to Use](#section0719414187) -- [Opening a Watchdog](#section198171379261) -- [Obtaining the Watchdog Status](#section206592910275) -- [Setting the Timeout Duration](#section19605128182714) -- [Obtaining the Timeout Duration](#section11111516208) -- [Starting a Watchdog](#section141174192814) -- [Feeding a Watchdog](#section179101435113910) -- [Stopping a Watchdog](#section15282123192816) -- [Closing a Watchdog](#section7857850173411) - -## How to Use - -[Figure 1](#fig19134125410189) illustrates the process of using a watchdog. - -**Figure 1** Process of using a watchdog - - -![](figures/en-us_image_0000001057622716.png) - -## Opening a Watchdog - -Use **WatchdogOpen** to open a watchdog. A system may have multiple watchdogs. You can open a specified watchdog by using the ID. - -int32\_t WatchdogOpen\(int16\_t wdtId\); - -. - -**Table 1** Description of WatchdogOpen - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

wdtId

-

Watchdog ID.

-

Return Value

-

Description

-

NULL

-

Failed to open the watchdog.

-

DevHandle pointer

-

Pointer to the watchdog handle.

-
- -``` -DevHandle handle = NULL; -handle = WatchdogOpen(0); /* Open watchdog 0.*/ -if (handle == NULL) { - HDF_LOGE("WatchdogOpen: failed, ret %d\n", ret); - return; -} -``` - -## Obtaining the Watchdog Status - -int32\_t WatchdogGetStatus\(DevHandle handle, int32\_t \*status\); - -. - -**Table 2** Description of WatchdogGetStatus - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Watchdog handle.

-

status

-

Pointer to the watchdog status.

-

Return Value

-

Description

-

0

-

The watchdog status is obtained.

-

Negative value

-

Failed to obtain the watchdog status.

-
- -``` -int32_t ret; -int32_t status; -/* Obtain the watchdog status. */ -ret = WatchdogGetStatus(handle, &status); -if (ret != 0) { - HDF_LOGE("WatchdogGetStatus: failed, ret %d\n", ret); - return; -} -``` - -## Setting the Timeout Duration - -int32\_t WatchdogSetTimeout\(PalHandle \*handle, uint32\_t seconds\); - -**Table 3** Description of WatchdogSetTimeout - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Watchdog handle.

-

seconds

-

Timeout duration, in seconds.

-

Return Value

-

Description

-

0

-

The setting is successful.

-

Negative value

-

Setting failed.

-
- -``` -int32_t ret; -uint32_t timeOut = 60; -/* Set the timeout duration, in seconds. */ -ret = WatchdogSetTimeout(handle, timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogSetTimeout: failed, ret %d\n", ret); - return; -} -``` - -## Obtaining the Timeout Duration - -int32\_t WatchdogGetTimeout\(PalHandle \*handle, uint32\_t \*seconds\); - -**Table 4** Description of WatchdogGetTimeout - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Watchdog handle.

-

seconds

-

Pointer to the timeout duration, in seconds.

-

Return Value

-

Description

-

0

-

The timeout duration is obtained.

-

Negative value

-

Failed to obtain the watchdog status.

-
- -``` -int32_t ret; -uint32_t timeOut; -/* Obtain the timeout duration, in seconds. */ -ret = WatchdogGetTimeout(handle, &timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogGetTimeout: failed, ret %d\n", ret); - return; -} -``` - -## Starting a Watchdog - -int32\_t WatchdogStart\(DevHandle handle\); - -**Table 5** Description of WatchdogStart - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Watchdog handle.

-

Return Value

-

Description

-

0

-

The watchdog is started.

-

Negative value

-

Failed to start the watchdog.

-
- -``` -int32_t ret; -/* Start the watchdog. */ -ret = WatchdogStart(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStart: failed, ret %d\n", ret); - return; -} -``` - -## Feeding a Watchdog - -int32\_t WatchdogFeed\(DevHandle handle\); - -**Table 6** Description of WatchdogFeed - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Watchdog handle.

-

Return Value

-

Description

-

0

-

The watchdog is fed.

-

Negative value

-

Failed to feed the watchdog.

-
- -``` -int32_t ret; -/* Feed the watchdog. */ -ret = WatchdogFeed(handle); -if (ret != 0) { - HDF_LOGE("WatchdogFeed: failed, ret %d\n", ret); - return; -} -``` - -## Stopping a Watchdog - -int32\_t WatchdogStop\(DevHandle handle\); - -**Table 7** Description of WatchdogStop - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Watchdog handle.

-

Return Value

-

Description

-

0

-

The watchdog is stopped.

-

Negative value

-

Stopping the watchdog failed.

-
- -``` -int32_t ret; -/* Stop the watchdog. */ -ret = WatchdogStop(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStop: failed, ret %d\n", ret); - return; -} - -``` - -## Closing a Watchdog - -If the watchdog is no longer required, call **WatchdogClose** to close the watchdog handle. - -void WatchdogClose\(DevHandle handle\); - -**Table 8** Description of WatchdogClose - - - - - - - - - - -

Parameter

-

Description

-

handle

-

Watchdog handle.

-
- -``` -/* Close the watchdog. */ -ret = WatchdogClose(handle); -``` - diff --git a/en/device-dev/driver/wlan.md b/en/device-dev/driver/wlan.md deleted file mode 100644 index d6d1fba4014eca409dc4a0d4ef645b1dc9cdffe3..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/wlan.md +++ /dev/null @@ -1,9 +0,0 @@ -# WLAN - -- **[WLAN Overview](wlanoverview.md)** - -- **[WLAN Development Guidelines](wlandevelopment-guidelines.md)** - -- **[WLAN Development Example](wlandevelopment-example.md)** - - diff --git a/en/device-dev/driver/wlandevelopment-example.md b/en/device-dev/driver/wlandevelopment-example.md deleted file mode 100644 index 23c68799d2e8bc2c0c561ef63e4ec3c810e034d9..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/wlandevelopment-example.md +++ /dev/null @@ -1,372 +0,0 @@ -# WLAN Development Example - -This section describes how to initialize the WLAN module on a Hi3881 WLAN chip. - -1. Set parameters for the WLAN module based on hardware attributes. - -``` -/* Set parameters in the wlan_platform.hcs file based on hardware attributes. The following is an example of the WLAN platform configuration. */ -hisi :& deviceList { - device0 :: deviceInst { - deviceInstId = 0; - powers { - power0 { - powerSeqDelay = 0; /* Power supply sequencing delay */ - powerType = 1; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through general-purpose input/output (GPIO). */ - gpioId = 1; /* GPIO pin ID */ - activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */ - } - power1 { - powerSeqDelay = 0; /* Power supply sequencing delay */ - powerType = 0; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through GPIO. */ - } - } - reset { - resetType = 0; /* Reset type. Value 0 indicates that reset is not supported, and value 1 indicates reset through GPIO. */ - gpioId = 2; /* GPIO pin ID */ - activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */ - resetHoldTime = 30; /* Hold time (ms) for a reset */ - } - bootUpTimeout = 30; /* Boot timeout duration (ms) */ - bus { - busType = 0; /* Bus type. Value 0 indicates secure digital input/output (SDIO). */ - busId = 2; /* Bus ID */ - funcNum = [1]; /* SDIO function number */ - timeout = 1000; /* Timeout duration for data read/write */ - blockSize = 512; /* Size of the data block to read or write */ - } - } -} -/* Add configuration file wlan_chip_.hcs (for example, wlan_chip_hi3881.hcs) for each chip and set parameters. The following takes the Hi3881 chip as an example. */ -root { - wlan_config { - hi3881 :& chipList { - chipHi3881 :: chipInst { - match_attr = "hdf_wlan_chips_hi3881"; /* Match attribute */ - chipName = "hi3881"; /* WLAN chip name */ - sdio { - vendorId = 0x0296; /* Vendor ID */ - deviceId = [0x5347]; /* Device ID */ - } - } - } - } -} -``` - -2. Mount the **init** and **deinit** functions of the WLAN chip and WLAN chip driver. - -``` -/* WLAN module initialization and mount process */ -#include "hdf_device_desc.h" -#include "hdf_wifi_product.h" -#include "hdf_log.h" -#include "osal_mem.h" -#include "hdf_wlan_chipdriver_manager.h" -#include "securec.h" -#include "wifi_module.h" -#include "hi_wifi_api.h" -#include "hi_types_base.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* Functions for initializing and deinitializing the WLAN chip */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device); -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); -/* Functions for initializing and deinitializing the WLAN chip driver */ -int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); -int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); - -/* Initialize mac80211 and mount functions of the chip. */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); - -static const char* const HI3881_DRIVER_NAME = "hisi"; - -/* Mount the WLAN chip driver and the functions of mac80211 and the chip. */ -static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) -{ - struct HdfChipDriver *specificDriver = NULL; - if (device == NULL) { - HDF_LOGE("%s fail : channel is NULL", __func__); - return NULL; - } - (void)device; - (void)ifIndex; - specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); - if (specificDriver == NULL) { - HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); - return NULL; - } - if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { - HDF_LOGE("%s fail: memset_s fail!", __func__); - OsalMemFree(specificDriver); - return NULL; - } - - if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { - HDF_LOGE("%s fail : strcpy_s fail", __func__); - OsalMemFree(specificDriver); - return NULL; - } - specificDriver->init = Hi3881Init; - specificDriver->deinit = Hi3881Deinit; - - HiMac80211Init(specificDriver); - - return specificDriver; -} - -/* Release the WLAN chip driver. */ -static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - return; - } - if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { - HDF_LOGE("%s:Not my driver!", __func__); - return; - } - OsalMemFree(chipDriver); -} - -static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { - (void)factory; - return 1; -} - -/* Register functions related to the WLAN chip. */ -static int32_t HDFWlanRegHisiDriverFactory(void) -{ - static struct HdfChipDriverFactory tmpFactory = { 0 }; - struct HdfChipDriverManager *driverMgr = NULL; - driverMgr = HdfWlanGetChipDriverMgr(); - if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; - } - tmpFactory.driverName = HI3881_DRIVER_NAME; - tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; - tmpFactory.InitChip = InitHi3881Chip; - tmpFactory.DeinitChip = DeinitHi3881Chip; - tmpFactory.Build = BuildHi3881Driver; - tmpFactory.Release = ReleaseHi3881Driver; - tmpFactory.ReleaseFactory = NULL; - if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} - -static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) -{ - (void)device; - return HDFWlanRegHisiDriverFactory(); -} - -struct HdfDriverEntry g_hdfHisiChipEntry = { - .moduleVersion = 1, - .Init = HdfWlanHisiChipDriverInit, - .moduleName = "HDF_WLAN_CHIPS" -}; - -HDF_INIT(g_hdfHisiChipEntry); -``` - -``` -#include "hdf_wifi_product.h" -#include "hi_wifi_api.h" -#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) -#include "oal_thread.h" -#include "osal_time.h" -#endif -#include "wifi_mac80211_ops.h" -#include "wal_cfg80211.h" -#include "net_adpater.h" -#include "hdf_wlan_utils.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* Initialize the WLAN chip. */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device) -{ - uint8_t maxPortCount = 1; - int32_t ret = HI_SUCCESS; - uint8_t maxRetryCount = 2; - if (device == NULL) { - HDF_LOGE("%s:NULL ptr!", __func__); - return HI_FAIL; - } - - do { - if (ret != HI_SUCCESS) { - if (device->reset != NULL && device->reset->Reset != NULL) { - device->reset->Reset(device->reset); - } - HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); - } - ret = hi_wifi_init(maxPortCount); - } while (ret != 0 && --maxRetryCount > 0); - - if (ret != 0) { - HDF_LOGE("%s:Init hi3881 driver failed!", __func__); - return ret; - } - return HI_SUCCESS; -} - -/* Deinitialize the WLAN chip. */ -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) -{ - (void)device; - int32_t ret = hi_wifi_deinit(); - if (ret != 0) { - HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); - } - return ret; -} - -/* Initialize the WLAN chip driver. */ -int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - HDF_LOGI("%s: start...", __func__); - hi_u16 mode = wal_get_vap_mode(); - int32_t ret; - nl80211_iftype_uint8 type; - (void)chipDriver; - - if (mode >= WAL_WIFI_MODE_BUTT) { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; - } - - if (mode == WAL_WIFI_MODE_STA) { - type = NL80211_IFTYPE_STATION; - } else if (mode == WAL_WIFI_MODE_AP) { - type = NL80211_IFTYPE_AP; - } else { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; - } - - ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); - if (ret != HI_SUCCESS) { - oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); - } - return ret; -} - -/* Deinitialize the WLAN chip driver. */ -int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - (void)chipDriver; - int32_t ret = wal_deinit_drv_wlan_netdev(netDevice); - if (ret != HDF_SUCCESS) { - return ret; - } - return ReleasePlatformNetDevice(netDevice); -} -``` - -3. During the chip initialization, call the **NetDeviceInit\(\)** function to initialize a network device, call the **NetDeviceAdd\(\)** function to add the network device to a protocol stack, and implement some function pointers of **netdev**. - -``` -hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len) -{ - oal_net_device_stru *netdev = HI_NULL; - - ...... - /* Initialize the network device and obtain the initialized instance. */ - netdev = NetDeviceInit(ifname, *len, LITE_OS); - oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); - ret = wal_init_netif(type, netdev, wdev); - - ...... - - return HI_SUCCESS; -} -/* Mount some function pointers of {@link NetDeviceInterFace}. */ -oal_net_device_ops_stru g_wal_net_dev_ops = -{ - .getStats = wal_netdev_get_stats, - .open = wal_netdev_open, - .stop = wal_netdev_stop, - .xmit = hmac_bridge_vap_xmit, - .ioctl = wal_net_device_ioctl, - .changeMtu = oal_net_device_change_mtu, - .init = oal_net_device_init, - .deInit = oal_net_free_netdev, -#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) - .selectQueue = wal_netdev_select_queue, -#endif - .setMacAddr = wal_netdev_set_mac_addr, -#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) - .netifNotify = HI_NULL, -#endif - .specialEtherTypeProcess = SpecialEtherTypeProcess, -}; - -hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) -{ - /* Add the network device to a protocol stack. */ - hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); - - ...... - - return HI_SUCCESS; -} -``` - -4. Implement functions of **WifiMac80211Ops**. - -``` -/* Mount some function pointers of mac80211. */ - -/* MAC-layer APIs for basic capabilities that need to be implemented by the driver */ -static struct HdfMac80211BaseOps g_baseOps = { - .SetMode = WalSetMode, - .AddKey = WalAddKey, - .DelKey = WalDelKey, - .SetDefaultKey = WalSetDefaultKey, - .GetDeviceMacAddr = WalGetDeviceMacAddr, - .SetMacAddr = WalSetMacAddr, - .SetTxPower = WalSetTxPower, - .GetValidFreqsWithBand = WalGetValidFreqsWithBand, - .GetHwCapability = WalGetHwCapability -}; - -/* MAC-layer APIs for station capabilities that need to be implemented by the driver */ -static struct HdfMac80211STAOps g_staOps = { - .Connect = WalConnect, - .Disconnect = WalDisconnect, - .StartScan = WalStartScan, - .AbortScan = WalAbortScan, - .SetScanningMacAddress = WalSetScanningMacAddress, -}; - -/* MAC-layer APIs for AP capabilities that need to be implemented by the driver */ -static struct HdfMac80211APOps g_apOps = { - .ConfigAp = WalConfigAp, - .StartAp = WalStartAp, - .StopAp = WalStopAp, - .ConfigBeacon = WalChangeBeacon, - .DelStation = WalDelStation, - .SetCountryCode = WalSetCountryCode, - .GetAssociatedStasCount = WalGetAssociatedStasCount, - .GetAssociatedStasInfo = WalGetAssociatedStasInfo -}; - -/* Initialize mac80211 and mount functions of the chip. */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__); - return; - } - chipDriver->ops = &g_baseOps; - chipDriver->staOps = &g_staOps; - chipDriver->apOps = &g_apOps; -} -``` - diff --git a/en/device-dev/driver/wlandevelopment-guidelines.md b/en/device-dev/driver/wlandevelopment-guidelines.md deleted file mode 100644 index 4b270cadbc9666221acce5343ce1079046f12b72..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/wlandevelopment-guidelines.md +++ /dev/null @@ -1,18 +0,0 @@ -# WLAN Development Guidelines - -- [How to Develop](#section96091936185820) - -The WLAN driver is developed based on the HDF and PLATFORM. It provides a unified driver model for WLAN modules of different vendors regardless of the operating system \(OS\) and system on a chip \(SoC\). - -## How to Develop - -1. Set hardware parameters such as **module** \(different features\) and **chip** in the **wifi\_config.hcs** file. -2. Parse the **wifi\_config.hcs** file and generate a structure with the configured parameters. -3. Initialize and create a module. -4. Mount and initialize the chip. -5. Initialize the bus. -6. Mount the upper-layer WPA service. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Some of the above adaptation steps have been provided. For details, see the third part **[WLAN Development Example](wlandevelopment-example.md)**. The steps waiting to be performed by developers include setting configuration parameters based on hardware attributes, adapting and mounting a chip, and performing tests and verification. - diff --git a/en/device-dev/driver/wlanoverview.md b/en/device-dev/driver/wlanoverview.md deleted file mode 100644 index 1d95ddb0028f2d5136f4e35154e5ff67506172ba..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/wlanoverview.md +++ /dev/null @@ -1,229 +0,0 @@ -# WLAN Overview - -- [Introduction](#section23087361515) -- [WLAN Driver API Architecture](#section1533192516212) -- [Available APIs](#section87491484213) - -## Introduction - -The WLAN module is developed based on the Hardware Driver Foundation \(HDF\). It supports cross-OS migration, component adaptation, and modular assembly and compilation. Based on the unified APIs provided by the WLAN module, driver developers of WLAN vendors can adapt their driver code and are capable of creating, disabling, scanning, and connecting to WLAN hotspots. The WLAN driver provides the Hardware Driver Interface \(HDI\) layer with the capabilities of setting and obtaining the device MAC address and setting the transmit power. The following figure shows the framework of the [WLAN module](#fig967034316227): - -**Figure 1** WLAN framework - - -![](figures/en-us_image_0000001055299108.png) - -## WLAN Driver API Architecture - -The WLAN module provides the following three types of APIs: - -1. Capability APIs for the HDI layer - -2. Capability APIs directly invoked by drivers - -3. Capability APIs for vendors - -**Figure 2** Available APIs of the WLAN module - - -![](figures/接口分布图4.png) - -## Available APIs - -The WLAN driver module provides APIs that can be directly called by driver developers, such as creating/releasing a **WifiModule**, connecting to/disconnecting from a WLAN hotspot, applying for/releasing a **NetBuf**, and converting between the **pbuf** structure of Lightweight IP \(lwIP\) and a **NetBuf**. [Table 1](#table1521573319472) provides some APIs. - -**Table 1** APIs that can be directly called by driver developers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

File

-

Function

-

Description

-

wifi_module.h

-

-

struct WifiModule *WifiModuleCreate(const struct HdfConfigWifiModuleConfig *config);

-

Creates a WifiModule.

-

void WifiModuleDelete(struct WifiModule *module);

-

Deletes and releases data of a WifiModule.

-

int32_t DelFeature(struct WifiModule *module, uint16_t featureType);

-

Deletes a feature from a WifiModule.

-

int32_t AddFeature(struct WifiModule *module, uint16_t featureType, struct WifiFeature *featureData);

-

Adds a feature to a WifiModule.

-

wifi_mac80211_ops.h

-

int32_t (*startAp)(NetDevice *netDev);

-

Starts an AP.

-

int32_t (*stopAp)(NetDevice *netDev);

-

Stops an AP.

-

int32_t (*connect)(NetDevice *netDev, WifiConnectParams *param);

-

Connects to a hotspot.

-

int32_t (*disconnect)(NetDevice *netDev, uint16_t reasonCode);

-

Disconnects from a hotspot.

-

hdf_netbuf.h

-

static inline void NetBufQueueInit(struct NetBufQueue *q);

-

Initializes a NetBuf queue.

-

struct NetBuf *NetBufAlloc(uint32_t size);

-

Applies for a NetBuf.

-

void NetBufFree(struct NetBuf *nb);

-

Releases a NetBuf.

-

struct NetBuf *Pbuf2NetBuf(const struct NetDevice *netdev, struct pbuf *lwipBuf);

-

Converts the pbuf structure of lwIP to a NetBuf.

-

struct pbuf *NetBuf2Pbuf(const struct NetBuf *nb);

-

Converts a NetBuf to the pbuf structure of lwIP.

-
- -The WLAN driver module provides APIs for driver developers, such as initializing/deregistering, opening/stopping a **NetDevice**, and obtaining the state of a **NetDevice**. [Table 2](#table74613501475) provides some APIs. - -**Table 2** APIs for driver developers of WLAN vendors to implement - - - - - - - - - - - - - - - - - - - - - - - - - - - -

File

-

Function

-

Description

-

net_device.h

-

int32_t (*init)(struct NetDevice *netDev);

-

Initializes a NetDevice.

-

struct NetDevStats *(*getStats)(struct NetDevice *netDev);

-

Obtains the state of a NetDevice.

-

int32_t (*setMacAddr)(struct NetDevice *netDev, void *addr);

-

Sets the MAC address.

-

void (*deInit)(struct NetDevice *netDev);

-

Deinitializes a NetDevice.

-

int32_t (*open)(struct NetDevice *netDev);

-

Opens a NetDevice.

-

int32_t (*stop)(struct NetDevice *netDev);

-

Stops a NetDevice.

-
- -The WLAN driver provides the HDI layer with the APIs for creating and destroying an **IWiFi** object and setting the MAC address. [Table 3](#table141076311618) provides some APIs. - -**Table 3** APIs provided by the WLAN HAL module - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Header File

-

Function

-

Description

-

wifi_hal.h

-

-

int32_t WifiConstruct(struct IWiFi **wifiInstance);

-

Creates an IWiFi object with basic capabilities.

-

int32_t WifiDestruct(struct IWiFi **wifiInstance);

-

Destroys an IWiFi object.

-

int32_t (*start)(struct IWiFi *);

-

Creates a channel between the HAL and the driver and obtains the NIC supported by the driver.

-

int32_t (*stop)(struct IWiFi *);

-

Stops the channel between the HAL and the driver.

-

wifi_hal_base_feature.h

-

int32_t (*getFeatureType)(const struct IWiFiBaseFeature *);

-

Obtains the feature type.

-

int32_t (*setMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

-

Sets the MAC address.

-

int32_t (*getDeviceMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

-

Obtains the device MAC address.

-

int32_t (*setTxPower)(const struct IWiFiBaseFeature *, int32_t);

-

Sets the transmit power.

-
- diff --git a/en/device-dev/get-code/Readme-EN.md b/en/device-dev/get-code/Readme-EN.md index 5431040667db64eba5ec745df12217f96780f532..5f5dacc4a6cefdf06912a3046c6350a95ff40c5c 100644 --- a/en/device-dev/get-code/Readme-EN.md +++ b/en/device-dev/get-code/Readme-EN.md @@ -1,7 +1,7 @@ # Source Code Acquisition -- [Source Code Acquisition](source-code-acquisition.md) -- [Tool Acquisition](tool-acquisition.md) - - [Docker Environment](docker-environment.md) - - [IDE](ide.md) +- [Source Code Acquisition](sourcecode-acquire.md) +- [Tool Acquisition](gettools.md) + - [Docker Environment](gettools-acquire.md) + - [IDE](gettools-ide.md) diff --git a/en/device-dev/get-code/docker-environment.md b/en/device-dev/get-code/docker-environment.md deleted file mode 100644 index a9dce7ccc7baf0628c9485dccd4013e3c25a00d7..0000000000000000000000000000000000000000 --- a/en/device-dev/get-code/docker-environment.md +++ /dev/null @@ -1,313 +0,0 @@ -# Docker Environment - -- [Introduction](#section107932281315) -- [Preparations](#section7337134183512) -- [Standalone Docker Environment](#section2858536103611) - - [Setting Up the Docker Environment for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\)](#section319412277287) - - [Building for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\)](#section631485163615) - - [Setting Up the Docker Environment for Standard-System Devices \(reference memory ≥ 128 MB\)](#section13585262391) - - [Building for Standard-System Devices \(reference memory ≥ 128 MB\)](#section193711513406) - -- [HPM-based Docker Environment](#section485713518337) - - [Setting Up the Docker Environment](#section3295842510) - - [Obtaining and Building Source Code](#section69141039143518) - - -## Introduction - -OpenHarmony provides the following two types of Docker environments for you to quickly get the development environment ready: - -- Standalone Docker environment: applicable when using Ubuntu or Windows to build a distribution -- HPM-based Docker environment: applicable when using the HarmonyOS Package Manager \(HPM\) to build a distribution - -**Table 1** Docker image - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Docker Environment

-

System Type

-

Operating Platform

-

Docker Image Repository

-

Tag

-

Standalone Docker environment

-

Mini and small systems

-

Ubuntu or Windows

-

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

-

0.0.5

-

Standard system

-

Ubuntu

-

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard

-

0.0.1

-

HPM-based Docker environment

-

Mini and small systems

-

Ubuntu or Windows

-

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

-

0.0.3

-
- -## Preparations - -Before using the Docker environment, perform the following operations: - -1. Install Docker. For details, see [Install Docker Engine](https://docs.docker.com/engine/install/). -2. Obtain the OpenHarmony source code. For details, see [Source Code Acquisition](source-code-acquisition.md). - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >You do not need to obtain the source code for the HPM-based Docker environment. - - -## Standalone Docker Environment - -The Docker image of OpenHarmony is hosted on [HUAWEI CLOUD SWR](https://console.huaweicloud.com/swr/?region=cn-south-1&locale=en-us#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage). Using the Docker image will help simplify environment configurations needed for the building. The following describes the detailed procedure. - -### Setting Up the Docker Environment for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) - -**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** - -1. Obtain the Docker image. - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - -2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - Run the following command in Ubuntu: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - Run the following command in Windows \(assuming that the source code directory is **D:\\OpenHarmony**\): - - ``` - docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - -**Method 2: Using the Dockerfile to Build a Local Docker Image** - -1. Obtain the Dockerfile script for a local Docker image. - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: - - ``` - cd docs/docker - ./build.sh - ``` - -3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - Run the following command in Ubuntu: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - Run the following command in Windows \(assuming that the source code directory is **D:\\OpenHarmony**\): - - ``` - docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - -### Building for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) - -The following uses the Hi3516 platform as an example to describe the build procedure. - -Set the build path to the current path. - -``` -hb set - . -``` - -**Figure 1** Setting page - - -![](figures/en-us_image_0000001101413884.png) - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The mapping between the development board and the building GUI: ->- Hi3861: wifiiot\_hispark\_pegasus@hisilicon ->- Hi3516: ipcamera\_hispark\_taurus@hisilicon ->- Hi3518: ipcamera\_hispark\_aries@hisilicon - -1. Select **ipcamera\_hispark\_taurus@hisilicon** and press **Enter**. -2. Start building. - - ``` - hb build -f - ``` - -3. View the build result. - - The files will be generated in the **out/hispark\_taurus/ipcamera\_hispark\_taurus** directory. - - -### Setting Up the Docker Environment for Standard-System Devices \(reference memory ≥ 128 MB\) - -**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** - -1. Obtain the Docker image. - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - -2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - - -**Method 2: Using the Dockerfile to Build a Local Docker Image** - -1. Obtain the Dockerfile script for a local Docker image. - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: - - ``` - cd docs/docker/standard - ./build.sh - ``` - -3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 - ``` - - -### Building for Standard-System Devices \(reference memory ≥ 128 MB\) - -1. Run the preprocessing script in the root directory of the source code. - - ``` - ../scripts/prepare.sh - ``` - -2. Run the following script to start building for standard-system devices \(reference memory ≥ 128 MB\). - - ``` - ./build.sh --product-name {product_name} - ``` - - **product\_name** indicates the platform supported by the current distribution, for example, Hi3516D V300. - - Files generated during building are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->You can exit Docker by simply running the **exit** command. - -## HPM-based Docker Environment - -**docker\_dist** is a template component in the [HPM](https://hpm.harmonyos.com/#/en/home) system. It helps to quickly initialize an HPM project and use the Docker image to quickly build a distribution of OpenHarmony, greatly simplifying environment configurations needed for building. After configuring the Ubuntu and [hpm-cli](https://device.harmonyos.com/en/docs/develop/bundles/oem_bundle_guide_prepare-0000001050129846) development environments, perform the following steps to access the Docker environment: - -### Setting Up the Docker Environment - -1. Initialize the installation template by running the following command in any of the working directories: - - ``` - hpm init -t @ohos/docker_dist - ``` - -2. Modify the **publishAs** field. - - The obtained bundle is of the template type. Open the **bundle.json** file in the current directory and change the value of **publishAs** from **template** to **distribution** as needed. - - -### Obtaining and Building Source Code - -Start building. Docker can be automatically installed only in Ubuntu. If you are using any other operating system, manually install Docker before pulling the image. - -- **Automatically Installing Docker \(Ubuntu\)** - - Running the following command will automatically install Docker, pull the Docker image, and start the pulling and building of the corresponding solution in the container. - - **Method 1:** - - Add a parameter to specify the solution. For example: - - ``` - hpm run docker solution={product} - ``` - - **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. - - **Method 2:** - - Set an environment variable to specify the solution, and then run the build command. - - 1. Select the desired solution. - - ``` - export solution={product} - ``` - - **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. - - 2. Obtain and build the source code. - - ``` - hpm run docker - ``` - - - This example uses the **@ohos/hispark\_taurus** solution for illustration. If the execution is successful, the output is as follows: - - ``` - ... - ohos ipcamera_hispark_taurus build success! - @ohos/hispark_taurus: distribution building completed. - ``` - - -- **Manually Installing Docker \(Non-Ubuntu\)** - - Perform the following operations to install Docker: - - ``` - # Pull the image. - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# Compile the Docker image in the Linux environment. - hpm run distWithDocker solution={product} - # When using Windows, make sure to configure the Git Bash. - hpm config set shellPath "Git Bash path" - hpm run distWithDocker solution={product} - ``` - - diff --git a/en/device-dev/get-code/figures/3.png b/en/device-dev/get-code/figure/3-22.png similarity index 100% rename from en/device-dev/get-code/figures/3.png rename to en/device-dev/get-code/figure/3-22.png diff --git a/en/device-dev/get-code/figures/en-us_image_0000001101413884.png b/en/device-dev/get-code/figure/en-us_image_0000001101413884.png similarity index 100% rename from en/device-dev/get-code/figures/en-us_image_0000001101413884.png rename to en/device-dev/get-code/figure/en-us_image_0000001101413884.png diff --git a/en/device-dev/get-code/figures/en-us_image_0000001119755646.png b/en/device-dev/get-code/figure/en-us_image_0000001119755646.png similarity index 100% rename from en/device-dev/get-code/figures/en-us_image_0000001119755646.png rename to en/device-dev/get-code/figure/en-us_image_0000001119755646.png diff --git a/en/device-dev/get-code/figures/en-us_image_0000001119915556.png b/en/device-dev/get-code/figure/en-us_image_0000001119915556.png similarity index 100% rename from en/device-dev/get-code/figures/en-us_image_0000001119915556.png rename to en/device-dev/get-code/figure/en-us_image_0000001119915556.png diff --git a/en/device-dev/get-code/figures/en-us_image_0000001166715379.png b/en/device-dev/get-code/figure/en-us_image_0000001166715379.png similarity index 100% rename from en/device-dev/get-code/figures/en-us_image_0000001166715379.png rename to en/device-dev/get-code/figure/en-us_image_0000001166715379.png diff --git a/en/device-dev/get-code/gettools-acquire.md b/en/device-dev/get-code/gettools-acquire.md new file mode 100644 index 0000000000000000000000000000000000000000..453cce21c04f24a2a64605a38e8f5f433ffe6994 --- /dev/null +++ b/en/device-dev/get-code/gettools-acquire.md @@ -0,0 +1,313 @@ +# Docker Environment + +- [Introduction](#section107932281315) +- [Preparations](#section7337134183512) +- [Standalone Docker Environment](#section2858536103611) + - [Setting Up the Docker Environment for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\)](#section319412277287) + - [Building for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\)](#section631485163615) + - [Setting Up the Docker Environment for Standard-System Devices \(reference memory ≥ 128 MB\)](#section13585262391) + - [Building for Standard-System Devices \(reference memory ≥ 128 MB\)](#section193711513406) + +- [HPM-based Docker Environment](#section485713518337) + - [Setting Up the Docker Environment](#section3295842510) + - [Obtaining and Building Source Code](#section69141039143518) + + +## Introduction + +OpenHarmony provides the following two types of Docker environments for you to quickly get the development environment ready: + +- Standalone Docker environment: applicable when using Ubuntu or Windows to build a distribution +- HPM-based Docker environment: applicable when using the HarmonyOS Package Manager \(HPM\) to build a distribution + +**Table 1** Docker image + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Docker Environment

+

System Type

+

Operating Platform

+

Docker Image Repository

+

Tag

+

Standalone Docker environment

+

Mini and small systems

+

Ubuntu or Windows

+

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

+

0.0.5

+

Standard system

+

Ubuntu

+

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard

+

0.0.1

+

HPM-based Docker environment

+

Mini and small systems

+

Ubuntu or Windows

+

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

+

0.0.3

+
+ +## Preparations + +Before using the Docker environment, perform the following operations: + +1. Install Docker. For details, see [Install Docker Engine](https://docs.docker.com/engine/install/). +2. Obtain the OpenHarmony source code. For details, see [Source Code Acquisition](sourcecode-acquire.md). + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >You do not need to obtain the source code for the HPM-based Docker environment. + + +## Standalone Docker Environment + +The Docker image of OpenHarmony is hosted on [HUAWEI CLOUD SWR](https://console.huaweicloud.com/swr/?region=cn-south-1&locale=en-us#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage). Using the Docker image will help simplify environment configurations needed for the building. The following describes the detailed procedure. + +### Setting Up the Docker Environment for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) + +**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** + +1. Obtain the Docker image. + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + +2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + Run the following command in Ubuntu: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + Run the following command in Windows \(assuming that the source code directory is **D:\\OpenHarmony**\): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +**Method 2: Using the Dockerfile to Build a Local Docker Image** + +1. Obtain the Dockerfile script for a local Docker image. + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: + + ``` + cd docs/docker + ./build.sh + ``` + +3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + Run the following command in Ubuntu: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + Run the following command in Windows \(assuming that the source code directory is **D:\\OpenHarmony**\): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +### Building for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) + +The following uses the Hi3516 platform as an example to describe the build procedure. + +Set the build path to the current path. + +``` +hb set + . +``` + +**Figure 1** Setting page + + +![](figure/en-us_image_0000001101413884.png) + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The mapping between the development board and the building GUI: +>- Hi3861: wifiiot\_hispark\_pegasus@hisilicon +>- Hi3516: ipcamera\_hispark\_taurus@hisilicon +>- Hi3518: ipcamera\_hispark\_aries@hisilicon + +1. Select **ipcamera\_hispark\_taurus@hisilicon** and press **Enter**. +2. Start building. + + ``` + hb build -f + ``` + +3. View the build result. + + The files will be generated in the **out/hispark\_taurus/ipcamera\_hispark\_taurus** directory. + + +### Setting Up the Docker Environment for Standard-System Devices \(reference memory ≥ 128 MB\) + +**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** + +1. Obtain the Docker image. + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**Method 2: Using the Dockerfile to Build a Local Docker Image** + +1. Obtain the Dockerfile script for a local Docker image. + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +### Building for Standard-System Devices \(reference memory ≥ 128 MB\) + +1. Run the preprocessing script in the root directory of the source code. + + ``` + ../scripts/prepare.sh + ``` + +2. Run the following script to start building for standard-system devices \(reference memory ≥ 128 MB\). + + ``` + ./build.sh --product-name {product_name} + ``` + + **product\_name** indicates the platform supported by the current distribution, for example, Hi3516D V300. + + Files generated during building are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>You can exit Docker by simply running the **exit** command. + +## HPM-based Docker Environment + +**docker\_dist** is a template component in the [HPM](https://hpm.harmonyos.com/#/en/home) system. It helps to quickly initialize an HPM project and use the Docker image to quickly build a distribution of OpenHarmony, greatly simplifying environment configurations needed for building. After configuring the Ubuntu and [hpm-cli](../bundles/bundles-guide-prepare.md) development environments, perform the following steps to access the Docker environment: + +### Setting Up the Docker Environment + +1. Initialize the installation template by running the following command in any of the working directories: + + ``` + hpm init -t @ohos/docker_dist + ``` + +2. Modify the **publishAs** field. + + The obtained bundle is of the template type. Open the **bundle.json** file in the current directory and change the value of **publishAs** from **template** to **distribution** as needed. + + +### Obtaining and Building Source Code + +Start building. Docker can be automatically installed only in Ubuntu. If you are using any other operating system, manually install Docker before pulling the image. + +- **Automatically Installing Docker \(Ubuntu\)** + + Running the following command will automatically install Docker, pull the Docker image, and start the pulling and building of the corresponding solution in the container. + + **Method 1:** + + Add a parameter to specify the solution. For example: + + ``` + hpm run docker solution={product} + ``` + + **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. + + **Method 2:** + + Set an environment variable to specify the solution, and then run the build command. + + 1. Select the desired solution. + + ``` + export solution={product} + ``` + + **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. + + 2. Obtain and build the source code. + + ``` + hpm run docker + ``` + + + This example uses the **@ohos/hispark\_taurus** solution for illustration. If the execution is successful, the output is as follows: + + ``` + ... + ohos ipcamera_hispark_taurus build success! + @ohos/hispark_taurus: distribution building completed. + ``` + + +- **Manually Installing Docker \(Non-Ubuntu\)** + + Perform the following operations to install Docker: + + ``` + # Pull the image. + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# Compile the Docker image in the Linux environment. + hpm run distWithDocker solution={product} + # When using Windows, make sure to configure the Git Bash. + hpm config set shellPath "Git Bash path" + hpm run distWithDocker solution={product} + ``` + + diff --git a/en/device-dev/get-code/gettools-ide.md b/en/device-dev/get-code/gettools-ide.md new file mode 100644 index 0000000000000000000000000000000000000000..ec5de1cf9a48fb2b4039f55dbd702de396b4e2c0 --- /dev/null +++ b/en/device-dev/get-code/gettools-ide.md @@ -0,0 +1,17 @@ +# IDE + +- [Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\)](#section2452141120244) +- [Acquiring the Application Development Tool \(HUAWEI DevEco Studio\)](#section0904101019258) + +## Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\) + +HUAWEI DevEco Device Tool is a one-stop integrated development environment \(IDE\) provided to develop applications for OpenHarmony devices. It allows on-demand customization of OpenHarmony components, code editing, building, burning, and debugging, and supports C and C++ languages. This tool is installed in Visual Studio Code as a plug-in. For details, see [HUAWEI DevEco Device Tool](https://device.harmonyos.com/en/ide) and [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). + +The roadmap of Huawei DevEco Device Tool for supporting OpenHarmony device development is shown in the figure below. + +![](figure/3-22.png) + +## Acquiring the Application Development Tool \(HUAWEI DevEco Studio\) + +HUAWEI DevEco Studio \(DevEco Studio for short\) is a one-stop IDE oriented to Huawei devices in all scenarios. It provides E2E OpenHarmony application development services, ranging from project template creation to development, building, debugging, and release. With DevEco Studio, you will be able to efficiently develop OpenHarmony applications with distributed capabilities while speeding up innovation. For details, see [HUAWEI DevEco Studio](https://developer.harmonyos.com/en/develop/deveco-studio) and [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). + diff --git a/en/device-dev/get-code/gettools.md b/en/device-dev/get-code/gettools.md new file mode 100644 index 0000000000000000000000000000000000000000..95366cdb4c3f08c8783e132e5489b026622d262a --- /dev/null +++ b/en/device-dev/get-code/gettools.md @@ -0,0 +1,7 @@ +# Tool Acquisition + +- **[Docker Environment](gettools-acquire.md)** + +- **[IDE](gettools-ide.md)** + + diff --git a/en/device-dev/get-code/ide.md b/en/device-dev/get-code/ide.md deleted file mode 100644 index f3551de3126341e207afe450d509d8d37cc0979a..0000000000000000000000000000000000000000 --- a/en/device-dev/get-code/ide.md +++ /dev/null @@ -1,17 +0,0 @@ -# IDE - -- [Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\)](#section2452141120244) -- [Acquiring the Application Development Tool \(HUAWEI DevEco Studio\)](#section0904101019258) - -## Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\) - -HUAWEI DevEco Device Tool is a one-stop integrated development environment \(IDE\) provided to develop applications for OpenHarmony devices. It allows on-demand customization of OpenHarmony components, code editing, building, burning, and debugging, and supports C and C++ languages. This tool is installed in Visual Studio Code as a plug-in. For details, see [HUAWEI DevEco Device Tool](https://device.harmonyos.com/en/ide) and [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). - -The roadmap of Huawei DevEco Device Tool for supporting OpenHarmony device development is shown in the figure below. - -![](figures/3.png) - -## Acquiring the Application Development Tool \(HUAWEI DevEco Studio\) - -HUAWEI DevEco Studio \(DevEco Studio for short\) is a one-stop IDE oriented to Huawei devices in all scenarios. It provides E2E OpenHarmony application development services, ranging from project template creation to development, building, debugging, and release. With DevEco Studio, you will be able to efficiently develop OpenHarmony applications with distributed capabilities while speeding up innovation. For details, see [HUAWEI DevEco Studio](https://developer.harmonyos.com/en/develop/deveco-studio) and [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). - diff --git a/en/device-dev/get-code/public_sys-resources/icon-caution.gif b/en/device-dev/get-code/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/get-code/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/device-dev/get-code/public_sys-resources/icon-danger.gif b/en/device-dev/get-code/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/get-code/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/device-dev/get-code/public_sys-resources/icon-note.gif b/en/device-dev/get-code/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/device-dev/get-code/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/device-dev/get-code/public_sys-resources/icon-notice.gif b/en/device-dev/get-code/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/device-dev/get-code/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/device-dev/get-code/public_sys-resources/icon-tip.gif b/en/device-dev/get-code/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/device-dev/get-code/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/device-dev/get-code/public_sys-resources/icon-warning.gif b/en/device-dev/get-code/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/get-code/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/device-dev/get-code/source-code-acquisition.md b/en/device-dev/get-code/source-code-acquisition.md deleted file mode 100644 index a7d68fe82d7e7b64663197b7d915710410e46069..0000000000000000000000000000000000000000 --- a/en/device-dev/get-code/source-code-acquisition.md +++ /dev/null @@ -1,429 +0,0 @@ -# Source Code Acquisition - -- [About OpenHarmony](#section6370143622110) -- [Overview of Source Code Acquisition](#section12763342204) -- [Method 1: Acquiring Source Code from a Code Repository](#section537312010229) - - [When to Use](#section10881513459) - - [Prerequisites](#section102871547153314) - - [How to Use](#section429012478331) - -- [Method 2: Acquiring Source Code from HPM](#section463013147412) - - [When to Use](#section26661067443) - - [Prerequisites](#section17544943123315) - - [How to Use](#section954619433333) - -- [Method 3: Acquiring Source Code from Image Sites](#section1186691118430) -- [Source Code Directories](#section1072115612811) - -## About OpenHarmony - -OpenHarmony is an open-source project launched by the OpenAtom Foundation. The purpose of this project is to build an open, distributed operating system \(OS\) framework for smart IoT devices in the full-scenario, full-connectivity, and full-intelligence era. - -The open-source code repositories are available at [https://openharmony.gitee.com](https://openharmony.gitee.com). - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->At present, OpenHarmony source code can only be compiled in the Linux environment. - -## Overview of Source Code Acquisition - -This document describes how to acquire OpenHarmony source code and provides its directory structure. The OpenHarmony code is open to you as [bundles](../bundles/overview.md), which can be obtained in any of the following ways: - -- **Method 1**: Acquire the source code from a code repository. You can use the **repo** or **git** tool to download the latest code from the code repository. -- **Method 2**: Obtain the source code from the HarmonyOS Package Manager \(HPM\). Visit the [HPM](https://hpm.harmonyos.com/#/en/home) website, search for your desired open-source distribution, and download the bundle list \(or customize bundles and download the bundle list\). Then use **hpm-cli** to download and install the bundles and compilation toolchain on your local PC. -- **Method 3**: Download the compressed file of a distribution from an image site. This method provides a fast download speed, so you can also use this method for obtaining the source code of an earlier version. - -## Method 1: Acquiring Source Code from a Code Repository - -### When to Use - -- You want to establish a baseline based on stable OpenHarmony releases and distribute the baseline to your customers. - -- You have interconnected your software with OpenHarmony and need official certification from OpenHarmony. - -- You want to contribute code to the OpenHarmony community after chips, modules, and applications are certified by OpenHarmony. - -- You need to address OpenHarmony issues. - -- You want to learn OpenHarmony source code. - - -### Prerequisites - -1. Register your account with Gitee. -2. Register an SSH public key for access to Gitee. -3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading), and configure basic user information. - - ``` - git config --global user.name "yourname" - git config --global user.email "your-email-address" - git config --global credential.helper store - ``` - -4. Run the following commands to install the **repo** tool: - - ``` - curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. - chmod a+x /usr/local/bin/repo - pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests - ``` - - -### How to Use - -**Obtaining the Source Code for Mini, Small, and Standard Systems \(2.0 Canary\)** - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->You can obtain the latest features from the master code, and develop commercial functionalities based on the release code, which is more stable. - -- **Obtaining OpenHarmony master code** - - Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) - - ``` - repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify - repo sync -c - repo forall -c 'git lfs pull' - ``` - - Method 2 \(recommended\): Use the **repo** tool to download the source code over HTTPS. - - ``` - repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify - repo sync -c - repo forall -c 'git lfs pull' - ``` - - -- **Obtaining Latest OpenHarmony\_1.0.1\_release code** - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >Currently, only the source code for mini and small systems can be obtained through this release. - - Use the **repo** tool to download the release code. - - ``` - repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify - repo sync -c - repo forall -c 'git lfs pull' - ``` - -- Obtaining the source code of other OpenHarmony releases - - For details about how to obtain the source code of other releases, see the [Release Notes](https://gitee.com/openharmony/docs/blob/master/en/release-notes/OpenHarmony-Release-Notes.md). - - -## Method 2: Acquiring Source Code from HPM - -### When to Use - -If OpenHarmony is new to you, sample solutions are helpful to your development. You can obtain an open-source distribution from the [HPM](https://hpm.harmonyos.com/#/en/home) website, or customize a distribution by adding or deleting bundles of an open-source distribution. Then use **hpm-cli** to download and install the bundles and compilation toolchain on your local PC. - -### Prerequisites - -You must install **Node.js** and HPM on your local PC. The installation procedure is as follows: - -1. Install **Node.js**. - - Download **Node.js** from its official website and install it on your local PC. - - You are advised to install [Node.js](https://nodejs.org/) 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\). - -2. Install the hpm-cli tool using **npm** delivered with **Node.js**. - - Open the CMD window and run the following command: - - ``` - npm install -g @ohos/hpm-cli - ``` - -3. Run the following command to check whether the installation is successful. If the HPM version is displayed, the installation is successful. - - ``` - hpm -V or hpm --version - ``` - -4. Run the following command to upgrade the HPM version: - - ``` - npm update -g @ohos/hpm-cli - ``` - - -### How to Use - -1. Search for distributions. - 1. Access the [HPM](https://hpm.harmonyos.com/#/en/home) page, and click the **Distribution** tab, as shown in the following figure. - 2. Enter a keyword \(for example: **camera**\) in the search box. All matched distributions are found. - 3. Specify filter criteria, such as the bundle type \(for example: **Board support** and **Kernel support**\), to further filter the distributions. - 4. Locate your desired distribution and click it to view details. - - **Figure 1** HPM page - - - ![](figures/en-us_image_0000001119915556.png) - - -2. Learn more about the distribution. - - 1. Read carefully the information about the distribution to learn its application scenarios, features, bundles, usage, and customization methods, as shown in the following figure. - 2. Click **Download** to download the distribution to your local PC. - 3. Click **Custom** to add or delete bundles of the distribution. - - **Figure 2** Example distribution - - - ![](figures/en-us_image_0000001119755646.png) - -3. Customize bundles. - 1. Access the **Custom solution** page, as shown in the following figure. - 2. Set the toggle switch next to a specific optional bundle to delete it from the distribution, or click **Add bundle** to add new bundles. - 3. Enter the basic information about your project, including the bundle name, version, and description, on the right pane. - 4. Click **Download**. The system then generates the OpenHarmony code structure file \(for example, **my\_cust\_dist.zip**\) and saves it to your local PC. - - **Figure 3** Customizing bundles - - - ![](figures/en-us_image_0000001166715379.png) - - -4. Download and install bundles. - 1. Decompress the downloaded file using the CLI tool CMD \(shell in Linux\). - 2. In the generated directory, run the **hpm install** command. - 3. The downloaded bundles are stored in the **ohos\_bundles** folder under the project directory. \(The source code of some bundles will be copied to a specified directory after the bundles are installed.\) - - -## Method 3: Acquiring Source Code from Image Sites - -To ensure the download performance, you are advised to download the source code or the corresponding solution from the image library of the respective site listed in the table below. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->- The table below provides only the sites for downloading the source code of the latest OpenHarmony Master and LTS versions. For details about earlier versions and how to obtain their source code, see the [Release Notes](https://gitee.com/openharmony/docs/tree/master/en/release-notes). ->- The Master 1.0 version is no longer maintained. - -**Table 1** Sites for acquiring source code from image sites - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LTS Code

-

Version Information

-

Site

-

SHA-256 Verification Code

-

Full code (for mini and small systems)

-

1.1.1

-

Download

-

Download

-

Hi3861 solution (binary)

-

1.1.1

-

Site

-

Download

-

Hi3518 solution (binary)

-

1.1.1

-

Download

-

Download

-

Hi3516 solution (binary)

-

1.1.1

-

Download

-

Download

-

RELEASE-NOTES

-

1.1.1

-

Download

-

-

-

Master Code

-

Version Information

-

Site

-

SHA-256 Verification Code

-

Full code (for standard systems)

-

2.0 Canary

-

Download (Site 1) Download (Site 2)

-

Download

-

Full code (for mini and small systems)

-

1.0 (no longer maintained)

-

Download

-

Download

-

Hi3861 solution (binary)

-

1.0 (no longer maintained)

-

Download

-

Download

-

Hi3518 solution (binary)

-

1.0 (no longer maintained)

-

Download

-

Download

-

Hi3516 solution (binary)

-

1.0 (no longer maintained)

-

Download

-

Download

-

RELEASE-NOTES

-

1.0 (no longer maintained)

-

Download

-

-

-

Compiler Toolchain

-

Version Information

-

Site

-

SHA-256 Verification Code

-

Compiler toolchain

-

-

-

Site

-

-

-
- -## Source Code Directories - -The following table describes the OpenHarmony source code directories. - -**Table 2** Source code directories - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Description

-

applications

-

Application samples, for example, camera

-

base

-

Basic software service subsystem set and hardware service subsystem set

-

build

-

Bundle-based compilation, building, and configuration scripts

-

docs

-

Reference documents

-

domains

-

Enhanced software service subsystem set

-

drivers

-

Driver subsystem

-

foundation

-

Basic system capability subsystem set

-

kernel

-

Kernel subsystem

-

prebuilts

-

Compiler and tool chain subsystem

-

test

-

Testing subsystem

-

third_party

-

Open-source third-party software

-

utils

-

Commonly used development tools

-

vendor

-

Vendor-provided software

-

build.py

-

Compilation script file

-
- diff --git a/en/device-dev/get-code/sourcecode-acquire.md b/en/device-dev/get-code/sourcecode-acquire.md new file mode 100644 index 0000000000000000000000000000000000000000..5c95dbd6a744e6986f6e0e28e7bb38ed8dd685b4 --- /dev/null +++ b/en/device-dev/get-code/sourcecode-acquire.md @@ -0,0 +1,429 @@ +# Source Code Acquisition + +- [About OpenHarmony](#section6370143622110) +- [Overview of Source Code Acquisition](#section12763342204) +- [Method 1: Acquiring Source Code from a Code Repository](#section537312010229) + - [When to Use](#section10881513459) + - [Prerequisites](#section102871547153314) + - [How to Use](#section429012478331) + +- [Method 2: Acquiring Source Code from HPM](#section463013147412) + - [When to Use](#section26661067443) + - [Prerequisites](#section17544943123315) + - [How to Use](#section954619433333) + +- [Method 3: Acquiring Source Code from Image Sites](#section1186691118430) +- [Source Code Directories](#section1072115612811) + +## About OpenHarmony + +OpenHarmony is an open-source project launched by the OpenAtom Foundation. The purpose of this project is to build an open, distributed operating system \(OS\) framework for smart IoT devices in the full-scenario, full-connectivity, and full-intelligence era. + +The open-source code repositories are available at [https://openharmony.gitee.com](https://openharmony.gitee.com). + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>At present, OpenHarmony source code can only be compiled in the Linux environment. + +## Overview of Source Code Acquisition + +This document describes how to acquire OpenHarmony source code and provides its directory structure. The OpenHarmony code is open to you as [bundles](../bundles/bundles-standard-rules.md), which can be obtained in any of the following ways: + +- **Method 1**: Acquire the source code from a code repository. You can use the **repo** or **git** tool to download the latest code from the code repository. +- **Method 2**: Obtain the source code from the HarmonyOS Package Manager \(HPM\). Visit the [HPM](https://hpm.harmonyos.com/#/en/home) website, search for your desired open-source distribution, and download the bundle list \(or customize bundles and download the bundle list\). Then use **hpm-cli** to download and install the bundles and compilation toolchain on your local PC. +- **Method 3**: Download the compressed file of a distribution from an image site. This method provides a fast download speed, so you can also use this method for obtaining the source code of an earlier version. + +## Method 1: Acquiring Source Code from a Code Repository + +### When to Use + +- You want to establish a baseline based on stable OpenHarmony releases and distribute the baseline to your customers. + +- You have interconnected your software with OpenHarmony and need official certification from OpenHarmony. + +- You want to contribute code to the OpenHarmony community after obtaining official OpenHarmony certification for chips, modules, and applications. + +- You need to rectify OpenHarmony issues. + +- You want to learn OpenHarmony source code. + + +### Prerequisites + +1. Register your account with Gitee. +2. Register an SSH public key for access to Gitee. +3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading), and configure basic user information. + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. Run the following commands to install the **repo** tool: + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### How to Use + +**Obtaining the Source Code for Mini/Small/Standard Systems \(2.0 Canary\)** + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>You can obtain the latest features from the master code, and develop commercial functionalities based on the release code, which is more stable. + +- **Obtaining OpenHarmony master code** + + Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) + + ``` + repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify + repo sync -c + repo forall -c 'git lfs pull' + ``` + + Method 2 \(recommended\): Use the **repo** tool to download the source code over HTTPS. + + ``` + repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify + repo sync -c + repo forall -c 'git lfs pull' + ``` + + +- **Obtaining Latest OpenHarmony\_1.0.1\_release code** + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Currently, only the source code for mini and small systems can be obtained through this release. + + Use the **repo** tool to download the release code. + + ``` + repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify + repo sync -c + repo forall -c 'git lfs pull' + ``` + +- Obtaining the source code of other OpenHarmony releases + + For details about how to obtain the source code of other OpenHarmony releases, see the [Release Notes](https://gitee.com/openharmony/docs/blob/master/en/release-notes/OpenHarmony-Release-Notes.md). + + +## Method 2: Acquiring Source Code from HPM + +### When to Use + +If OpenHarmony is new to you, sample solutions are helpful to your development. You can obtain an open-source distribution from the [HPM](https://hpm.harmonyos.com/#/en/home) website, or customize a distribution by adding or deleting bundles of an open-source distribution. Then use **hpm-cli** to download and install the bundles and compilation toolchain on your local PC. + +### Prerequisites + +You must install **Node.js** and HPM on your local PC. The installation procedure is as follows: + +1. Install **Node.js**. + + Download **Node.js** from its official website and install it on your local PC. + + You are advised to install [Node.js](https://nodejs.org/) 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\). + +2. Install the hpm-cli tool using **npm** delivered with **Node.js**. + + Open the CMD window and run the following command: + + ``` + npm install -g @ohos/hpm-cli + ``` + +3. Run the following command to check whether the installation is successful. If the HPM version is displayed, the installation is successful. + + ``` + hpm -V or hpm --version + ``` + +4. Run the following command to upgrade the HPM version: + + ``` + npm update -g @ohos/hpm-cli + ``` + + +### How to Use + +1. Search for distributions. + 1. Access the [HPM](https://hpm.harmonyos.com/#/en/home) page, and click the **Distribution** tab, as shown in the following figure. + 2. Enter a keyword \(for example: **camera**\) in the search box. All matched distributions are found. + 3. Specify filter criteria, such as the bundle type \(for example: **Board support** and **Kernel support**\), to further filter the distributions. + 4. Locate your desired distribution and click it to view details. + + **Figure 1** HPM page + + + ![](figure/en-us_image_0000001119915556.png) + + +2. Learn more about the distribution. + + 1. Read carefully the information about the distribution to learn its application scenarios, features, bundles, usage, and customization methods, as shown in the following figure. + 2. Click **Download** to download the distribution to your local PC. + 3. Click **Custom** to add or delete bundles of the distribution. + + **Figure 2** Example distribution + + + ![](figure/en-us_image_0000001119755646.png) + +3. Customize bundles. + 1. Access the **Custom solution** page, as shown in the following figure. + 2. Set the toggle switch next to a specific optional bundle to delete it from the distribution, or click **Add bundle** to add new bundles. + 3. Enter the basic information about your project, including the bundle name, version, and description, on the right pane. + 4. Click **Download**. The system then generates the OpenHarmony code structure file \(for example, **my\_cust\_dist.zip**\) and saves it to your local PC. + + **Figure 3** Customizing bundles + + + ![](figure/en-us_image_0000001166715379.png) + + +4. Download and install bundles. + 1. Decompress the downloaded file using the CLI tool CMD \(shell in Linux\). + 2. In the generated directory, run the **hpm install** command. + 3. The downloaded bundles are stored in the **ohos\_bundles** folder under the project directory. \(The source code of some bundles will be copied to a specified directory after the bundles are installed.\) + + +## Method 3: Acquiring Source Code from Image Sites + +To ensure the download performance, you are advised to download the source code or the corresponding solution from the image library of the respective site listed in the table below. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- The table below provides only the sites for downloading the latest OpenHarmony master and LTS code. For details about how to obtain the source code of earlier versions, see the [Release Notes](https://gitee.com/openharmony/docs/tree/master/en/release-notes). +>- The Master 1.0 version is no longer maintained. + +**Table 1** Sites for acquiring source code from image sites + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

LTS Code

+

Version Information

+

Site

+

SHA-256 Verification Code

+

Full code (for mini and small systems)

+

1.1.1

+

Download

+

Download

+

Hi3861 solution (binary)

+

1.1.1

+

Download

+

Download

+

Hi3518 solution (binary)

+

1.1.1

+

Download

+

Download

+

Hi3516 solution (binary)

+

1.1.1

+

Download

+

Download

+

RELEASE-NOTES

+

1.1.1

+

Download

+

-

+

Master Code

+

Version Information

+

Site

+

SHA-256 Verification Code

+

Full code (for standard systems)

+

2.0 Canary

+

Download (Site 1) Download (Site 2)

+

Download

+

Full code (for mini and small systems)

+

1.0 (no longer maintained)

+

Download

+

Download

+

Hi3861 solution (binary)

+

1.0 (no longer maintained)

+

Download

+

Download

+

Hi3518 solution (binary)

+

1.0 (no longer maintained)

+

Download

+

Download

+

Hi3516 solution (binary)

+

1.0 (no longer maintained)

+

Download

+

Download

+

RELEASE-NOTES

+

1.0 (no longer maintained)

+

Download

+

-

+

Compiler Toolchain

+

Version Information

+

Site

+

SHA-256 Verification Code

+

Compiler toolchain

+

-

+

Download

+

-

+
+ +## Source Code Directories + +The following table describes the OpenHarmony source code directories. + +**Table 2** Source code directories + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Description

+

applications

+

Application samples, for example, camera

+

base

+

Basic software service subsystem set and hardware service subsystem set

+

build

+

Bundle-based compilation, building, and configuration scripts

+

docs

+

Reference documents

+

domains

+

Enhanced software service subsystem set

+

drivers

+

Driver subsystem

+

foundation

+

Basic system capability subsystem set

+

kernel

+

Kernel subsystem

+

prebuilts

+

Compiler and tool chain subsystem

+

test

+

Testing subsystem

+

third_party

+

Open-source third-party software

+

utils

+

Commonly used development tools

+

vendor

+

Vendor-provided software

+

build.py

+

Compilation script file

+
+ diff --git a/en/device-dev/get-code/sourcecode.md b/en/device-dev/get-code/sourcecode.md new file mode 100644 index 0000000000000000000000000000000000000000..5e118ce26fcaab05055610b3ca990fd6c3f676b0 --- /dev/null +++ b/en/device-dev/get-code/sourcecode.md @@ -0,0 +1,5 @@ +# Source Code Acquisition + +- **[Source Code Acquisition](sourcecode-acquire.md)** + + diff --git a/en/device-dev/get-code/tool-acquisition.md b/en/device-dev/get-code/tool-acquisition.md deleted file mode 100644 index dd1797b10426918c0921386817fb51c1b9e83a3b..0000000000000000000000000000000000000000 --- a/en/device-dev/get-code/tool-acquisition.md +++ /dev/null @@ -1,7 +0,0 @@ -# Tool Acquisition - -- **[Docker Environment](docker-environment.md)** - -- **[IDE](ide.md)** - - diff --git a/en/device-dev/glossary/Readme-EN.md b/en/device-dev/glossary/Readme-EN.md new file mode 100644 index 0000000000000000000000000000000000000000..1e7ccafe473286de0e48494b45a313bedad2c4e1 --- /dev/null +++ b/en/device-dev/glossary/Readme-EN.md @@ -0,0 +1,4 @@ +# Glossary + +[Glossary](glossary.md) + diff --git a/en/device-dev/guide/Readme-EN.md b/en/device-dev/guide/Readme-EN.md index 31bb3cfd5f930e15379766651d890690ab24f29c..ca124ea327c8b4af4d22f6e6d462df5c6de5592b 100644 --- a/en/device-dev/guide/Readme-EN.md +++ b/en/device-dev/guide/Readme-EN.md @@ -1,72 +1,32 @@ # Development Examples -- [WLAN-connected Products](wlan-connected-products.md) - - [LED Peripheral Control](led-peripheral-control.md) - - [Overview](overview.md) - - [Development](development.md) - - [Verification](verification.md) - -- [Cameras Without a Screen](cameras-without-a-screen.md) - - [Camera Control](camera-control.md) - - [Overview](overview-0.md) - - [Development Guidelines](development-guidelines.md) - - [Photographing](photographing.md) - - [Video Recording](video-recording.md) - - - [Use Case](use-case.md) - -- [Cameras with a Screen](cameras-with-a-screen.md) - - [Screen and Camera Control](screen-and-camera-control.md) - - [Overview](overview-1.md) - - [Development Guidelines](development-guidelines-2.md) - - [Photographing](photographing-3.md) - - [Video Recording](video-recording-4.md) - - [Previewing](previewing.md) - - - [Use Case](use-case-5.md) - - - [Visual Application Development](visual-application-development.md) - - [Overview](overview-6.md) - - [Preparations](preparations.md) - - [Adding Pages](adding-pages.md) - - [Building the Home Page](building-the-home-page.md) - - [Building the Details Page](building-the-details-page.md) - - [Debugging and Packaging](debugging-and-packaging.md) - - [Running on the Device](running-on-the-device.md) - - [FAQs](faqs.md) - -- [Development Example for Clock Apps](development-example-for-clock-apps.md) - - [Overview](overview-7.md) - - [Preparations](preparations-8.md) - - [How to Develop](how-to-develop.md) - - [Signing and Packaging](signing-and-packaging.md) - - [Running on the Device](running-on-the-device-9.md) - -- [Development Example for Platform Drivers](development-example-for-platform-drivers.md) - - [Overview](overview-10.md) - - [Preparations](preparations-11.md) - - [Development](development-12.md) - - [Building and Burning](building-and-burning.md) - -- [Development Example for Peripheral Drivers](development-example-for-peripheral-drivers.md) - - [Overview](overview-13.md) - - [Hardware Resources](hardware-resources.md) - - [Input Driver Model](input-driver-model.md) - - - [Setting Up the Environment](setting-up-the-environment.md) - - [Developing a Touchscreen Driver](developing-a-touchscreen-driver.md) - - [Configuring Device Driver Descriptions](configuring-device-driver-descriptions.md) - - [Configuring the Touchscreen](configuring-the-touchscreen.md) - - [Adapting to the Private Drivers of the Touchscreen](adapting-to-the-private-drivers-of-the-touchscreen.md) - - - [Building and Burning](building-and-burning-14.md) - - [Debugging and Verification](debugging-and-verification.md) - - [Startup Log Analysis](startup-log-analysis.md) - - - [Input Driver Model Workflow Analysis](input-driver-model-workflow-analysis.md) - - [Parsing Private Configuration Data](parsing-private-configuration-data.md) - - [Initializing the Input Device Manager and Registering the Driver with the HDF](initializing-the-input-device-manager-and-registering-the-driver-with-the-hdf.md) - - [Initializing the Input Common Driver and Registering the Driver with the HDF](initializing-the-input-common-driver-and-registering-the-driver-with-the-hdf.md) - - [Initializing the Input Chip Driver and Registering the Driver with the HDF](initializing-the-input-chip-driver-and-registering-the-driver-with-the-hdf.md) - - [Function Invocation Logic](function-invocation-logic.md) - +- [WLAN-connected Products](device-wifi.md) + - [LED Peripheral Control](device-wifi-led-outcontrol.md) + - [Third-Party SDK Integration](device-wifi-sdk.md) +- [Cameras Without a Screen](device-iotcamera.md) + - [Camera Control](device-iotcamera-control.md) + - [Overview](device-iotcamera-control-overview.md) + - [Development Guidelines](device-iotcamera-control-demo.md) + - [Photographing](device-iotcamera-control-demo-photodevguide.md) + - [Video Recording](device-iotcamera-control-demo-videodevguide.md) + - [Use Case](device-iotcamera-control-example.md) +- [Cameras with a Screen](device-camera.md) + - [Screen and Camera Control](device-camera-control.md) + - [Overview](device-camera-control-overview.md) + - [Development Guidelines](device-camera-control-demo.md) + - [Photographing](device-camera-control-demo-photoguide.md) + - [Video Recording](device-camera-control-demo-videoguide.md) + - [Previewing](device-camera-control-demo-previewguide.md) + - [Use Case](device-camera-control-example.md) + - [Visual Application Development](device-camera-visual.md) + - [Overview](device-camera-visual-overview.md) + - [Preparations](device-camera-visual-prepare.md) + - [Adding Pages](device-camera-visual-addpage.md) + - [Building the Home Page](device-camera-visual-first-page.md) + - [Building the Details Page](device-camera-visual-details.md) + - [Debugging and Packaging](device-camera-visual-debug.md) + - [Running on the Device](device-camera-visual-run.md) + - [FAQs](device-camera-visual-faqs.md) +- [Development Guidelines on Clock Apps](oem_device_clockapp_des.md) +- [Development Example for Platform Drivers](device-driver-demo.md) +- [Development Example for Peripheral Drivers](device-outerdriver-demo.md) \ No newline at end of file diff --git a/en/device-dev/guide/adapting-to-the-private-drivers-of-the-touchscreen.md b/en/device-dev/guide/adapting-to-the-private-drivers-of-the-touchscreen.md deleted file mode 100644 index 80f6ba5513c1e2db8ecb7d566f91c82536311a5f..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/adapting-to-the-private-drivers-of-the-touchscreen.md +++ /dev/null @@ -1,99 +0,0 @@ -# Adapting to the Private Drivers of the Touchscreen - -The input driver model consists of three parts of drivers. To develop a brand-new touchscreen driver, you only need to adapt your code with the input chip driver and implement differentiated APIs. The sample code in this section illustrates how you will complete the adaptation. - -1. Implement differentiated APIs for the touchscreen to adapt to the input chip driver. - - You can obtain the sample code at **./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c**. - - ``` - static struct TouchChipOps g_gt911ChipOps = { // IC options of the touchscreen - .Init = ChipInit, // Initialize the chip. - .Detect = ChipDetect, // Detect the chip. - .Resume = ChipResume, // Resume the chip. - .Suspend = ChipSuspend, // Suspend the chip. - .DataHandle = ChipDataHandle, // Read the chip data. - .UpdateFirmware = UpdateFirmware, // Update the firmware. - }; - - /* The ICs may be different depending on the touchscreen vendors, and the corresponding register operations are also different. Therefore, the code for the input chip driver focuses only on the adaptation of differentiated APIs. The following sample code demonstrates the data parsing of GT911. */ - - static int32_t ChipDataHandle(ChipDevice *device) - { - ... - /* Read the status register before GT911 obtains coordinates. */ - reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; - ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); - if (ret < 0 || touchStatus == GT_EVENT_INVALID) { - return HDF_FAILURE; - } - ... - /* Read data from the data register based on the value of the status register. */ - reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; - pointNum = touchStatus & GT_FINGER_NUM_MASK; - if (pointNum == 0 || pointNum > MAX_SUPPORT_POINT) { - HDF_LOGE("%s: pointNum is invalid, %u", __func__, pointNum); - (void)ChipCleanBuffer(i2cClient); - OsalMutexUnlock(&device->driver->mutex); - return HDF_FAILURE; - } - frame->realPointNum = pointNum; - frame->definedEvent = TOUCH_DOWN; - (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); - /* Parse the obtained data. */ - ParsePointData(device, frame, buf, pointNum); - ... - } - static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) - { - ... - /* Each coordinate value consists of two bytes. Obtain the final coordinate value by combining the obtained single-byte data. */ - for (i = 0; i < pointNum; i++) { - frame->fingers[i].trackId = buf[GT_POINT_SIZE * i + GT_TRACK_ID]; - frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - /* Print the parsed coordinate value. */ - HDF_LOGD("%s: x = %d, y = %d", __func__, frame->fingers[i].x, frame->fingers[i].y); - } - } - ``` - -2. Initialize the input chip driver and register the driver with the HDF. - - You can obtain the sample code at **./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c**. - - ``` - static int32_t HdfGoodixChipInit(struct HdfDeviceObject *device) - { - ... - /* Use the chipCfg structure to allocate memory, parse the configuration information, and mount the parsed data. */ - chipCfg = ChipConfigInstance(device); - ... - /* Instantiate the touchscreen device. */ - chipDev = ChipDeviceInstance(); - ... - /* Mount touchscreen chip configuration and private operation data. */ - chipDev->chipCfg = chipCfg; - chipDev->ops = &g_gt911ChipOps; - ... - /* Register the chip driver with the platform driver. */ - RegisterChipDevice(chipDev); - ... - } - struct HdfDriverEntry g_touchGoodixChipEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH_GT911", // The value must match the moduleName field of the chip driver in the device_info.hcs file. - .Init = HdfGoodixChipInit, // Initialize the touchscreen chip driver. - }; - HDF_INIT(g_touchGoodixChipEntry); // Register the touchscreen chip driver with the HDF. - ``` - - The private chip drivers present the major differentiations among chip vendors, such as hibernation and wakeup, data parsing, and firmware update. - - Now, you have completed the adaptation for the touchscreen driver based on the HDF and input driver model. - - diff --git a/en/device-dev/guide/adding-pages.md b/en/device-dev/guide/adding-pages.md deleted file mode 100644 index 42eae0107fbdff36aff7879586df0fedebc792b2..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/adding-pages.md +++ /dev/null @@ -1,34 +0,0 @@ -# Adding Pages - -- [Creating the Home Page](#section16935511143715) -- [Creating the Details Page](#section122131729173819) - -## Creating the Home Page - -Upon creation of the project, the **index** page is automatically generated, which is the home page of AirQuality. [Figure 1](#fig16545205773718) shows the project directory. - -**Figure 1** Project directory -![](figures/project-directory.png "project-directory") - -## Creating the Details Page - -To the details page, perform the following steps: - -1. Right-click **pages** and choose **New** \> **JS Page** from the shortcut menu. - - **Figure 2** Adding a page - ![](figures/adding-a-page.png "adding-a-page") - -2. Enter the page name. - - **Figure 3** Entering the page name - ![](figures/entering-the-page-name.png "entering-the-page-name") - -3. Confirm the creation. - - The following figure shows the application project directory after the **detail** page is created. It contains a **.hml** layout file, a **.css** file, and a **.js** file \(containing service logic code\). - - **Figure 4** Complete project directory - ![](figures/complete-project-directory.png "complete-project-directory") - - diff --git a/en/device-dev/guide/building-and-burning-14.md b/en/device-dev/guide/building-and-burning-14.md deleted file mode 100644 index d905b787acbb3639912138621c808faa46645a10..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/building-and-burning-14.md +++ /dev/null @@ -1,17 +0,0 @@ -# Building and Burning - -1. Compile the Makefile and add the following content in this example. - - The file is available at **./drivers/adapter/khdf/linux/model/input/Makefile**. - - Add the following content: - - ``` - obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \ - $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o - ``` - - **touch\_gt911.o** is the content added in this example. - -2. Conduct building and burn. For details about the building and burning operations, see [Build and Burn in Getting Started with Standard System](../quick-start/standard-system.md). - diff --git a/en/device-dev/guide/building-and-burning.md b/en/device-dev/guide/building-and-burning.md deleted file mode 100644 index 25f895cc93816b552eee5058a96b098ec7fdf7e9..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/building-and-burning.md +++ /dev/null @@ -1,20 +0,0 @@ -# Building and Burning - -1. Edit the Makefile and add a source file to it, as shown in the following example: - - ``` - include drivers/hdf/khdf/platform/platform.mk - - obj-y += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_core.o \ - $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_if.o \ - ./i2c_adapter.o \ - ./i2c_sample.o - ``` - - **./i2c\_sample.o** is the source file added to the Makefile in this example. - -2. Build the version and burn the system image to the development board. - - For details about the building and burning operations, see [Build and Burn in Getting Started with Standard System](../quick-start/standard-system.md). - - diff --git a/en/device-dev/guide/building-the-details-page.md b/en/device-dev/guide/building-the-details-page.md deleted file mode 100644 index 915c74a318163d6a50cab13e46f919b129690d1d..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/building-the-details-page.md +++ /dev/null @@ -1,396 +0,0 @@ -# Building the Details Page - -- [detail.hml](#section275215487291) -- [detail.css](#section2589154215301) -- [detail.js](#section163410883117) - -The **detail** page displays the air quality data of a week in a chart. There are two parts on the page: title bar and chart bar. Considering the display effect of the chart bar, use multiple **** components in stead of one **** component. - -Add a root ****, set the **flex-direction** attribute to **column** to arrange the two bars vertically. The example code is as follows: - -``` -
-
- - - History - -
- - -
-``` - -In the preceding example, **onclick="backMain"** indicates that the application returns to the home page when the click event is triggered. The example code for **detail.js** is as follows: - -``` -import router from '@system.router' - -export default { - backMain() { - router.replace({ - // Home page URL - uri: 'pages/index/index', - params: { - // Parameters to pass to the home page - selectedCityIndex: this.selectedCityIndex - } - }); - } -} -``` - -Add **** components to the **** component to form a chart. - -The complete example code in the three files is as follows. - -## detail.hml - -``` -
-
- - - History - -
- - - {{location}} - - - -
-
- - CO - -
-
-
-
-
-
-
-
-
-
-
- - MON - - - TUE - - - WED - - - THU - - - FRI - - - SAT - - - SUN - -
-
-
- - SO2 - -
-
-
-
-
-
-
-
-
-
-
- - MON - - - TUE - - - WED - - - THU - - - FRI - - - SAT - - - SUN - -
-
-
-
- -
-
- - PM10 - -
-
-
-
-
-
-
-
-
-
-
- - MON - - - TUE - - - WED - - - THU - - - FRI - - - SAT - - - SUN - -
-
-
- - PM2.5 - -
-
-
-
-
-
-
-
-
-
-
- - MON - - - TUE - - - WED - - - THU - - - FRI - - - SAT - - - SUN - -
-
-
-
- -
-
- - NO2 - -
-
-
-
-
-
-
-
-
-
-
- - MON - - - TUE - - - WED - - - THU - - - FRI - - - SAT - - - SUN - -
-
-
-
-
-
-``` - -## detail.css - -``` -.location { - text-align: center; - color: #ffffff; - width: 960px; - height: 52px; - font-size: 40px; -} -.container { - height: 480px; - width: 960px; - flex-direction: column; -} - -.header { - width: 960px; - height: 72px; -} - -.back { - width: 36px; - height: 36px; - margin-left: 39px; - margin-top: 23px; -} - -.title { - width: 296px; - height: 40px; - margin-top: 20px; - margin-left: 21px; - color: #e6e6e6; -} - -.chart-list { - width: 960px; - height: 408px; -} - -.list-item-title { - width: 960px; - height: 52px; -} - -.list-item-chart { - width: 960px; - height: 280px; -} - -.chart-wrapper { - width: 308px; - height: 256px; - flex-direction: column; -} - -.gas-name { - width: 308px; - height: 35px; - text-align: left; -} - -.chart { - width: 308px; - height: 155px; - margin-top: 10px; - justify-content: flex-start; - align-items: flex-end; -} - -.chart-item { - width: 24px; - margin-left: 18px; - border-radius: 3px; -} - -.white-line { - width: 308px; - height: 2px; - background-color: #ffffff; - margin-top: 22px; -} - -.week { - width: 308px; - height: 17px; - margin-top: 6px; - border-color: #ffffff; - border-radius: 2px; - margin-top: 6px; -} - -.day { - width: 26px; - height: 17px; - font-size: 10px; - margin-left: 16px; - text-align: center; -} -``` - -## detail.js - -``` -import router from '@system.router' - -export default { - data: { - location: '' - }, - onInit() { - if (this.selectedCityIndex === 0) { - this.location = 'Dongguan'; - } else { - this.location = 'Shenzhen'; - } - }, - backMain() { - router.replace({ - uri: 'pages/index/index', - params: { - selectedCityIndex: this.selectedCityIndex - } - }); - } -} -``` - diff --git a/en/device-dev/guide/building-the-home-page.md b/en/device-dev/guide/building-the-home-page.md deleted file mode 100644 index e50391cee73cb565eb6537ec06a70eb53ee996aa..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/building-the-home-page.md +++ /dev/null @@ -1,581 +0,0 @@ -# Building the Home Page - -The application home page displays air quality information of different cities. The home page provides two screens \(for two information bars\), which can be added as required. Each screen displays the air quality information of one city, including the Air Quality Index \(AQI\), city name, pollution level, update time, and data source. - -The home page of AirQuality consists of three parts: - -- Title bar: displays the page title and provides an exit button. The title bar is fixed at the top of the page. -- Information bar: displays air quality information. Multiple information bars can be added based on user requirements and support looping scroll. -- Indicator bar: shows the position of the current screen among all screens. The indicator bar is fixed at the bottom of the page. - -The following steps describe how to build the home page with a flexible layout that has three rows vertically arranged. - -1. Add a root **** to the **.hml** file. Note that each **.hml** file can contain only one root component. The example code is as follows: - - ``` -
-
- ``` - - **class="container"** indicates the style used by the component. The **container** is a style class defined in the **index.css** file. - - ``` - .container { - flex-direction: column; - height: 480px; - width: 960px; - } - ``` - - The height and width of the root component **** are set in the style class. Note that the height and width must be explicitly specified \(except for some components, such as ****\). Otherwise, the component may fail to display. In the **container** style class, the **flex-direction** attribute is set to **column**, which means that child components of **** are vertically arranged from top to bottom for implementing the flexible page layout. - -2. Add the title bar. The title bar consists of an exit button and title text that are horizontally arranged. Add a **** to hold the title bar and set the **flex-direction** attribute to **row** to arrange the child components from left to right. Add an **** and a **** component in sequence. The example code is as follows: - - ``` -
-
- - - Air quality - -
-
- ``` - - Set component attributes, including the height, width, margin, and color. - - ``` - .header { - width: 960px; - height: 72px; - } - .back { - width: 36px; - height: 36px; - margin-left: 39px; - margin-top: 23px; - } - .title { - width: 296px; - height: 40px; - margin-top: 20px; - margin-left: 21px; - color: #e6e6e6; - } - ``` - - In the **.hml** file, **onclick="exitApp"** sets the click event for the **** component. When the click event is triggered, the **exitApp\(\)** function is executed. The example definition of **exitApp\(\)** in **index.js** is as follows: - - ``` - exitApp() { - console.log('start exit'); - app.terminate(); - console.log('end exit'); - } - ``` - - The **app.terminate\(\)** function is used to exit the program. Before using this function, you must import the **app** module by adding the following code at the beginning of **index.js**: - - ``` - import app from '@system.app' - ``` - - After the code is compiled, run the project on the simulator. The following figure shows the display effect. - - **Figure 1** Title bar - ![](figures/title-bar.png "title-bar") - -3. The **** component is required to implement the switching between screens. - - Add a **** to the root node. - - ``` -
-
- - - Air quality - -
- - -
- ``` - - - Use **class="**swiper**"** to set the height and width of the component. The sample code is as follows: - - ``` - .swiper { - height: 385px; - width: 960px; - } - ``` - - - - **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 ****. **\{\{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 **** component to the **swiperChange** function. The JavaScript code is as follows: - - ``` - // Import the router module for page switching. - import router from'@system.router' - import app from '@system.app' - - export default { - // Define parameters. - data: { - // By default, the first page is displayed. - swiperPage: 0 - }, - onInit () { - }, - exitApp(){ - console.log('start exit'); - app.terminate(); - console.log('end exit'); - }, - // Swiping event, which saves the index value of the current . The index value is saved to the swiperPage variable each time a swiping occurs. - swiperChange (e) { - this.swiperPage = e.index; - } - } - ``` - - -4. Set the information about a city to be displayed on a screen. On each screen, information of different types is displayed using different components. - - Add two **** as child components \(directional layout\) to ****. Add ****, ****, ****, and other components to each **** to display the information. The following example shows the page structure: - - ``` - - - - ------Air quality - ------City name - -----Progress bar - -------A cloud image - --------AQI value - AQI------AQI -
--------AQI details -
-
--------Update time, website, and other information -
-
- - - - - - - - -
-
-
- ``` - - After the code is compiled, the display effect on the simulator is as follows. - - **Figure 2** Title bar and information bar - ![](figures/title-bar-and-information-bar.png "title-bar-and-information-bar") - -5. Add the indicator bar. Currently, the **** component does not support indicator settings. You need to implement a dots indicator by adding **** components and setting the style. Add a **** as a child component to the root node and set the style. Add two **** to the parent ****, set **border-radius** for the two child ****, and dynamically change the background colors of the **** components in the swiping event. - - ``` -
-
-
-
- ``` - - **Figure 3** Indicator bar - ![](figures/indicator-bar.png "indicator-bar") - -6. Set the style, animation effect, and dynamic data binding for all components. The complete example code is as follows: - - - **index.hml** - - ``` -
-
- - - AirQuality - -
- - - {{airData[0].airQuality}} - - {{airData[0].location}} - - - - {{airData[0].detailData}} - - - AQI - -
-
- - CO - - - 100 - -
-
- - NO2 - - - 90 - -
-
- - PM10 - - - 120 - -
-
- - PM2.5 - - - 40 - -
-
- - SO2 - - - 150 - -
- -
- -
- - {{airData[1].airQuality}} - - {{airData[1].location}} - - - - {{airData[1].detailData}} - - - AQI - -
-
- - CO - - - 10 - -
-
- - NO2 - - - 50 - -
-
- - PM10 - - - 60 - -
-
- - PM2.5 - - - 40 - -
-
- - SO2 - - - 150 - -
- -
- -
-
-
-
-
-
-
- ``` - - - **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. - - ``` - .aqi-value { - text-align: center; - font-size: 65px; - color: #f0ffff; - width: 156px; - height: 92px; - top: 134px; - left: 210px; - } - .aqi { - text-align: center; - color: #a2c4a2; - width: 156px; - height: 45px; - top: 90px; - left: 210px; - } - .airquality { - top: 222px; - text-align: center; - width: 156px; - height: 45px; - left: 210px; - } - .image { - top: 285px; - left: 274px; - width: 32px; - height: 32px; - } - .location-text { - text-align: center; - color: #ffffff; - width: 200px; - height: 52px; - font-size: 40px; - left: 380px; - top: 16px; - } - .container { - flex-direction: column; - height: 480px; - width: 960px; - } - .circle-progress { - center-x: 128px; - center-y: 128px; - radius: 128px; - startAngle: 198; - totalAngle: 320; - strokeWidth: 24px; - width: 256px; - height: 256px; - left: 160px; - top: 58px; - } - .detail { - width: 256px; - height: 265px; - left: 544px; - top: 58px; - flex-direction: column; - } - .text-wrapper { - width: 256px; - height: 35px; - margin-top: 6px; - } - .gas-name { - width: 128px; - height: 35px; - text-align: left; - } - .gas-value { - width: 128px; - height: 35px; - text-align: right; - } - .btn { - width: 180px; - height: 50px; - margin-top: 6px; - margin-left: 38px; - background-color: #1a1a1a; - color: #1085CE; - } - .footer { - top: 326px; - width: 960px; - height: 28px; - } - .header { - width: 960px; - height: 72px; - } - .back { - width: 36px; - height: 36px; - margin-left: 39px; - margin-top: 23px; - } - .title { - width: 296px; - height: 40px; - margin-top: 20px; - margin-left: 21px; - color: #e6e6e6; - } - .swiper { - height: 385px; - width: 960px; - } - .images { - width: 60px; - height: 15px; - margin-left: 450px; - } - .update-time { - width: 480px; - height: 28px; - font-size: 20px; - color: #A9A9A9; - text-align: right; - } - .info-source { - width: 450px; - height: 28px; - font-size: 20px; - color: #A9A9A9; - text-align: left; - margin-left: 24px; - } - .circle-div { - width: 12px; - height: 12px; - border-radius: 6px; - } - ``` - - - **index.js** - - A **.js** file is used to implement interaction logic of your application. In the **.js** file of the home page, implement page switching and enable text content and progress bar color to change dynamically according to AQI values. - - ``` - // Import router and app modules. - import router from '@system.router' - import app from '@system.app' - - export default { - data: { - // Bind data. - textColor1: '#00ff00', - textColor2: '#00ff00', - bgColor1: '#669966', - bgColor2: '#669966', - swiperPage: 0, - percent1: 40, - percent2: 90, - iconUncheckedColor: '#262626', - iconcheckedColor: '#ffffff', - iconcheckedBR: '6px', - src1: 'common/cloud_green.png', - src2: 'common/cloud_green.png', - airData: [{ - location: 'Dongguan', - airQuality: 'Good', - detailData: 40 - }, { - location: 'Shenzhen', - airQuality: 'Polluted', - detailData: 90 - }] - }, - onInit () { - // Set the font, background color, and background image for different value ranges. - if(this.airData[0].detailData > 100){ - this.src1 = 'common/cloud_red.png'; - this.textColor1 = '#ff0000'; - this.bgColor1 = '#9d7462'; - } else if(50 < this.airData[0].detailData && this.airData[0].detailData <= 100){ - this.src1 = 'common/cloud_yellow.png'; - this.textColor1 = '#ecf19a'; - 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; - if(this.swiperPage == 0){ - this.iconcheckedColor = '#ffffff'; - this.iconUncheckedColor = '#262626'; - }else{ - this.iconcheckedColor = '#262626'; - this.iconUncheckedColor = '#ffffff'; - } - } - }, - // Switch to the details page. - openDetail () { - router.replace({ - uri: 'pages/detail/detail', - params: {selectedCityIndex:this.swiperPage} - }); - }, - // Exit the application. - exitApp(){ - console.log('start exit'); - app.terminate(); - console.log('end exit'); - }, - // Define the swiping event. Change the indicator dots when the user swipes the screen. - swiperChange (e) { - this.swiperPage = e.index; - if(e.index == 0){ - this.iconcheckedColor = '#ffffff'; - this.iconUncheckedColor = '#262626'; - }else{ - this.iconcheckedColor = '#262626'; - this.iconUncheckedColor = '#ffffff'; - } - } - } - ``` - - diff --git a/en/device-dev/guide/camera-control.md b/en/device-dev/guide/camera-control.md deleted file mode 100644 index 5694352afcf41a300ab8936b6dc2abfed5bc1a56..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/camera-control.md +++ /dev/null @@ -1,9 +0,0 @@ -# Camera Control - -- **[Overview](overview-0.md)** - -- **[Development Guidelines](development-guidelines.md)** - -- **[Use Case](use-case.md)** - - diff --git a/en/device-dev/guide/cameras-with-a-screen.md b/en/device-dev/guide/cameras-with-a-screen.md deleted file mode 100644 index b212cc236c70be6403f659c5eabdaeebfc7d677a..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/cameras-with-a-screen.md +++ /dev/null @@ -1,7 +0,0 @@ -# Cameras with a Screen - -- **[Screen and Camera Control](screen-and-camera-control.md)** - -- **[Visual Application Development](visual-application-development.md)** - - diff --git a/en/device-dev/guide/cameras-without-a-screen.md b/en/device-dev/guide/cameras-without-a-screen.md deleted file mode 100644 index abb3a6616a0364c5ca1d5e19a48fa040c798c2bc..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/cameras-without-a-screen.md +++ /dev/null @@ -1,5 +0,0 @@ -# Cameras Without a Screen - -- **[Camera Control](camera-control.md)** - - diff --git a/en/device-dev/guide/configuring-device-driver-descriptions.md b/en/device-dev/guide/configuring-device-driver-descriptions.md deleted file mode 100644 index d19a91a732b43d0f059d6c5dbd4d8430a386ce98..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/configuring-device-driver-descriptions.md +++ /dev/null @@ -1,64 +0,0 @@ -# Configuring Device Driver Descriptions - -You can configure the device driver description in the configuration file at **./drivers/adapter/khdf/linux/hcs/device\_info/device\_info.hcs**. - -The **device\_info.hcs** file contains all necessary information for registering drivers in the input driver model with the HDF. You do not need to make any modification for the information unless otherwise required in special scenarios. The private configuration data of each driver uses the **deviceMatchAttr** field to match the **match\_attr** field in the **input\_config.hcs** file. - -The input-related content in the configuration file is as follows \(For details about these fields, see [Driver Development](https://device.harmonyos.com/en/docs/develop/drive/oem_drive_hdfdev_load-0000001051276785)[Driver Development](../driver/driver-development.md)\): - -``` -input :: host { - hostName = "input_host"; - priority = 100; - device_input_manager :: device { // Specify the device driver description of the input device manager. - device0 :: deviceNode { - policy = 2; // Services are released to both the kernel space and the user space. - priority = 100; // The default priority for the input device manager is 100. - preload = 0; // Load the driver. - permission = 0660; // Specify the permission for the driver to create device nodes. - moduleName = "HDF_INPUT_MANAGER"; // Match the moduleName in the driver entry structure. - serviceName = "hdf_input_host"; // Specify the device node name to be generated by the HDF. - deviceMatchAttr = ""; // Leave this field empty because private configuration data is not required by the input device manager currently. - } - } - - device_hdf_touch :: device { // Specify the device driver description of the input common driver. - device0 :: deviceNode { - policy = 2; // Services are released to both the kernel space and the user space. - priority = 120; // The default priority for the input common driver is 120. - preload = 0; // Load the driver. - permission = 0660; // Specify the permission for the driver to create device nodes. - moduleName = "HDF_TOUCH"; // Match the moduleName in the driver entry structure. - serviceName = "hdf_input_event1"; // Specify the device node name to be generated by the HDF. - deviceMatchAttr = "touch_device1"; // Keep this value the same as the match_attr value in the private configuration data. - } - } - - device_touch_chip :: device { // Specify the device description of the input chip driver. - device0 :: deviceNode { - policy = 0; // Services are not released to both the kernel space and the user space. - priority = 130; // The default priority for the input chip driver is 130. - preload = 0; // Load the driver. - permission = 0660; // Specify the permission for the driver to create device nodes. - moduleName = "HDF_TOUCH_GT911"; // Match the moduleName in the driver entry structure. - serviceName = "hdf_touch_gt911_service";// Specify the device node name to be generated by the HDF. - deviceMatchAttr = "zsj_gt911_5p5"; // Keep this value the same as the match_attr value in the private configuration data. - } - } - } -``` - -Pay attention to the following fields in the configuration file: - -**priority**: specifies the driver loading priority. - -**preload**: specifies whether to load the driver. - -**moduleName**: This value must be the same as the **moduleName** value in the driver entry structure. - -**serviceName**: This value is used by the HDF to create a device node name. - -**deviceMatchAttr**: This value must be the same as the **match\_attr** value in the private configuration data. - -After the device descriptions are configured, the HDF matches the configuration with the code registered with the driver entry structure based on the **moduleName** field, ensuring that drivers can be loaded properly. If multiple drivers are configured, the **priority** field determines the loading sequence of each driver. - diff --git a/en/device-dev/guide/configuring-the-touchscreen.md b/en/device-dev/guide/configuring-the-touchscreen.md deleted file mode 100644 index 6a6cc59f6aded4d77aea594e683f9e6e682324ed..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/configuring-the-touchscreen.md +++ /dev/null @@ -1,98 +0,0 @@ -# Configuring the Touchscreen - -You can configure the touchscreen in the configuration file at **./drivers/adapter/khdf/linux/hcs/input/input\_config.hcs**. - -The **input\_config.hcs** file consists of the private configuration data of both the common driver and chip driver. Information of this file is read and parsed by the driver code. The configuration in the file includes the board-level hardware information and private configuration of the touchscreen. You can tailor the configuration during your development. - -``` -root { - input_config { - touchConfig { - touch0 { // Configure the first touchscreen. - boardConfig { // Specify the board-level hardware information. - match_attr = "touch_device1"; // Keep this value the same as the match_attr field in the private configuration data of the input common driver in the device description. - inputAttr { - /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */ - inputType = 0; // Set the input type to touch. - solutionX = 480; // Set the resolution in the X-axis. - solutionY = 960; // Set the resolution in the Y-axis. - devName = "main_touch"; // Set the device name. - } - busConfig { - /* 0:i2c 1:spi */ - busType = 0; // GT911 uses the I2C bus for communication. - busNum = 6; // Use the sixth bus of the chip to communicate with the development board through I2C. - clkGpio = 86; // Set the SCL pin of the chip. - dataGpio = 87; // Set the SDA pin of the chip. - i2cClkIomux = [0x114f0048, 0x403]; // Configure the SCL pin information. - i2cDataIomux = [0x114f004c, 0x403]; // Configure the SDA pin information. - } - pinConfig { - rstGpio = 3; // Set the reset pin. - intGpio = 4; // Set the interrupt pin. - rstRegCfg = [0x112f0094, 0x400]; // Configure the reset pin information. - intRegCfg = [0x112f0098, 0x400]; // Configure the interrupt pin information. - } - powerConfig { - /* Value 0 indicates that power supply is not used; value 1 indicates the LDO power supply; value 2 indicates the GPIO power supply; value 3 indicates the PMIC power supply. */ - vccType = 2; // Set the VCC type. Value 2 indicates the GPIO power supply. - vccNum = 20; // Set the VCC number. The GPIO number is 20. - vccValue = 1800; // Set the voltage amplitude to 1800 mV. - vciType = 1; // Set the VCI type. Value 1 indicates the LDO power supply. - vciNum = 12; // Set the VCI number. The LDO number is 12. - vciValue = 3300; // Set the voltage amplitude to 3300 mV. - } - - featureConfig { - capacitanceTest = 0; // Configure the capacitance test. - gestureMode = 0; // Configure the gesture mode. - gloverMode = 0; // Configure the gloves mode. - coverMode = 0; // Configure the cover mode. - chargerMode = 0; // Configure the charging mode. - knuckleMode = 0; // Configure the knuckle mode. - } - } - chipConfig { // Configure the private data of the touchscreen chip. - template touchChip { // Template - match_attr = ""; - chipName = "gt911"; // Set the touchscreen IC model. - vendorName = "zsj"; // Set the vendor name. - chipInfo = "AAAA11222"; // The first four characters indicate the product name. The fifth and sixth characters indicate the IC model. The last three characters indicate the chip model. - busType = 0; // 0 indicates the I2C bus, and 1 indicates the SPI bus. - deviceAddr = 0x5D; // Set the IC communication address. - irqFlag = 2; // Values 1 and 2 indicate that the interrupt is triggered on the rising and falling edges, respectively. Values 4 and 8 indicate that the interrupt is triggered by the high and low levels, respectively. - maxSpeed = 400; // Set the maximum communication rate to 400 Hz. - chipVersion = 0; // Set the touchscreen IC version. - powerSequence { - /* Power-on sequence is described as follows: - [Type, status, direction, delay] - Value 0 indicates the power or pin is empty. Values 1 and 2 indicate the VCC (1.8 V) and VCI (3.3 V) power, respectively. Values 3 and 4 indicate the reset and interrupt pins, respectively. - Values 0 and 1 indicate the power-off or pull-down, and the power-on or pull-up, respectively. Value 2 indicates that no operation is performed. - Values 0 and 1 indicate the input and output directions, respectively. Value 2 indicates that no operation is performed. - Delay time, in milliseconds. - */ - powerOnSeq = [4, 0, 1, 0, // Set the output direction for the interrupt pin and pull down the pin. - 3, 0, 1, 10, // Set the output direction for the reset pin and pull down the pin, with a delay of 10 ms. - 3, 1, 2, 60, // No operation is performed on the reset pin. Pull up the pin, with a delay of 60 ms. - 4, 2, 0, 0]; // Set the input direction for the interrupt pin. - suspendSeq = [3, 0, 2, 10]; // No operation is performed on the reset pin. Pull down the pin, with a delay of 10 ms. - resumeSeq = [3, 1, 2, 10]; // No operation is performed on the reset pin. Pull up the pin, with a delay of 10 ms. - powerOffSeq = [3, 0, 2, 10, // No operation is performed on the reset pin. Pull down the pin, with a delay of 10 ms. - 1, 0, 2, 20]; // No operation is performed on the positive pin. Pull down the pin, with a delay of 20 ms. - } - } - - chip0 :: touchChip { - match_attr = "zsj_gt911_5p5"; // Keep this value the same as the match_attr field in the touchscreen private configuration data in the device description. - chipInfo = "ZIDN45100"; // The chip information is composed of the product name, module number, and chip number, used to identity the current touchscreen in user space. - chipVersion = 0; // IC model version - } - } - } - } - } -} -``` - -In the example, **touchConfig** contains the **touch0** configuration, which describes the **boardConfig** and **chipConfig** configuration information. The **boardConfig** field provides the board-level hardware information of Hi3516D V300, and the **chipConfig** field provides the private configuration data of the touchscreen. To use another touchscreen, you can change the value of the **chipConfig** field. You can also configure multiple touchscreens for your product. In this example, **touch0** represents the hardware interface and chip configuration of the default touchscreen. If you need to configure a secondary touchscreen, add a **touch1** block parallel to **touch0**. - diff --git a/en/device-dev/guide/debugging-and-packaging.md b/en/device-dev/guide/debugging-and-packaging.md deleted file mode 100644 index 97df7e21ab4e36ac3420ba1494bf8452fa5f226e..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/debugging-and-packaging.md +++ /dev/null @@ -1,4 +0,0 @@ -# Debugging and Packaging - -After the code is compiled, debug your application and package it into an App Pack. For details about how to debug and package an application, see [Debugging Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/debug_overview-0000001053822404) and [Building Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/build_overview-0000001055075201) in the [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). Currently, IPCamera applications do not support signature. You should release an unsigned App Pack. - diff --git a/en/device-dev/guide/debugging-and-verification.md b/en/device-dev/guide/debugging-and-verification.md deleted file mode 100644 index 13a210d84987d51e46caf248980815b123107c74..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/debugging-and-verification.md +++ /dev/null @@ -1,5 +0,0 @@ -# Debugging and Verification - -- **[Startup Log Analysis](startup-log-analysis.md)** - - diff --git a/en/device-dev/guide/developing-a-touchscreen-driver.md b/en/device-dev/guide/developing-a-touchscreen-driver.md deleted file mode 100644 index 6fa833ae11f7f29760c9ec5f3822e7f8f41c28af..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/developing-a-touchscreen-driver.md +++ /dev/null @@ -1,17 +0,0 @@ -# Developing a Touchscreen Driver - -Complete the following tasks to adapt a touchscreen IC based on the input driver model: - -1. Configure the touchscreen driver description required for registering the driver with the HDF, for example, whether the driver is loaded and what is the loading priority. - -2. Configure the private data of the touchscreen \(such as the power-on and power-off sequence\) and the platform hardware information \(such as the GPIO port that connects the touchscreen to the development board\). - -3. Adapt to the private drivers of the touchscreen. The input driver model abstracts the development process of input devices. You only need to adapt to the input chip driver without making any modifications for the input device manager and common driver. - -- **[Configuring Device Driver Descriptions](configuring-device-driver-descriptions.md)** - -- **[Configuring the Touchscreen](configuring-the-touchscreen.md)** - -- **[Adapting to the Private Drivers of the Touchscreen](adapting-to-the-private-drivers-of-the-touchscreen.md)** - - diff --git a/en/device-dev/guide/development-12.md b/en/device-dev/guide/development-12.md deleted file mode 100644 index 59fb5d8e5ee93659cfe90543390f8065bcae6b5b..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/development-12.md +++ /dev/null @@ -1,395 +0,0 @@ -# Development - -- [Instantiating the Driver Entry](#section6586911816) -- [Setting Related Parameters](#section114323217503) -- [Adding a Controller](#section115187812516) - -Platform driver development includes the following procedures: - -1. Instantiate the driver entry: Instantiate an **HdfDriverEntry** object as the driver entry. -2. Set related parameters: Configure the **device\_info.hcs** file and obtain and parse device configuration parameters from the HCS to ensure that the driver can be correctly loaded. -3. Add a controller: Initialize the controller hardware, call core-layer APIs to add or delete devices to or from the core layer, and implement a hook. - -The following table lists the files involved in this example and their paths. - -**Table 1** File description - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

File

-

File Path

-

Remarks

-

Sample file

-

/drivers/adapter/khdf/linux/platform/i2c/i2c_sample.c

-

New file

-

Device service file

-

/drivers/adapter/khdf/linux/hcs/device_info/device_info.hcs

-

-

New content will be added to these files.

-

-

Configuration parameter file

-

/drivers/adapter/khdf/linux/hcs/platform/i2c_config.hcs

-

Build file

-

/drivers/adapter/khdf/linux/platform/i2c/Makefile

-

Dependency

-

/drivers/framework/include/core/hdf_device_desc.h

-

Header file to be included

-

-

Core-layer header file

-

/drivers/framework/support/platform/include/i2c_core.h

-

HCS configuration entry file

-

/drivers/adapter/khdf/linux/hcs/hdf.hcs

-

Entry to HCS configuration files

-
- ->![](public_sys-resources/icon-caution.gif) **CAUTION:** ->The file paths involved in this example are used for demonstration only. Determine the paths for storing the source files as required when developing your driver. - -## Instantiating the Driver Entry - -The driver entry must be a global variable of the **HdfDriverEntry** type \(which is defined in **hdf\_device\_desc.h**\), and the value of **moduleName** must be the same as that in **device\_info.hcs**. When loading the driver, the HDF calls the **Bind** function first and then the **Init** function. If an error occurred during the calling of the **Init** function, the HDF calls **Release** to release the driver resource and exit. - -The **Bind** function is not implemented in the I2C driver because the I2C controller is managed by the I2C manager and the **Bind** function has been implemented in the manager. Therefore, services do not need to be bound in the I2C driver. - -The sample code for instantiating the driver entry is as follows: - -``` -/* Define a driver entry object. It must be a global variable of the HdfDriverEntry type (defined in hdf_device_desc.h). */ -struct HdfDriverEntry g_sampleI2cDriverEntry = { - .moduleVersion = 1, - .Init = SampleI2cInit, - .Release = SampleI2cRelease, - .moduleName = "demo_i2c_driver", -}; -/* Call HDF_INIT to register the driver entry with the HDF. */ -HDF_INIT(g_sampleI2cDriverEntry); -``` - -## Setting Related Parameters - -1. \(Mandatory\) Add a device service node. - - Edit the **device\_info.hcs** file and add a driver device service node under **device\_i2c :: device**. The following is an example: - - ``` - root { - device_info { - match_attr = "hdf_manager"; - device_i2c :: device { // I2C devices - device2 :: deviceNode { // Device node of an I2C driver - policy = 0; // Policy for releasing the driver service - priority = 55; // Driver startup priority - permission = 0644; // Permission for the driver to create a device node. - moduleName = "demo_i2c_driver"; // Driver name. The value of this field must be the same as the value of moduleName in the driver entry data structure. - serviceName = "DEMO_I2C_DRIVER"; // Name of the service released by the driver. The name must be unique. - deviceMatchAttr = "demo_i2c_config"; // Keyword matching the private data of the driver. The value must be the same as that of - // match_attr in the private configuration data table of the driver. - } - } - } - } - ``` - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The **priority** attribute \(an integer ranging from 0 to 200\) in the configuration file indicates the priority of a host or drivers. Drivers in a host with a smaller priority value have a higher loading priority than those in other hosts. The driver with a smaller priority value in a host has a higher loading priority than the other drivers in the host. The loading sequence is random for drivers with the same priority. - -2. \(Optional\) Add configuration parameters. - - The driver may require private configuration information to ensure that the register configuration meets the requirements of different products. If private configuration data is required, you can add a driver configuration file to store some default configuration information about the driver. When loading the driver, the HDF obtains the specified configuration information, saves it in the **property** attribute of **HdfDeviceObject**, and passes it to the driver via **Bind** and **Init**. For details about how to use **Bind** and **Init**, see [Driver Development](../driver/driver-development.md). You can create a configuration file and reference it in the **hdf.hcs** file of the board-level driver. In this example, configuration parameters are directly added to the existing configuration file **i2c\_config.hcs**. - - The following configuration parameters are added to the **i2c\_config.hcs** file: - - ``` - root { - platform { - i2c_config_demo { - match_attr = "demo_i2c_config"; // The value of this field must be the same as the value of deviceMatchAttr in device_info.hcs. - - template i2c_controller { // Parameter template - bus = 0; - reg_pbase = 0x120b0000; - reg_size = 0xd1; - } - - controller_demo_0 :: i2c_controller { // Two sample I2C controllers - bus = 8; - } - controller_demo_1 :: i2c_controller { - bus = 9; - } - } - } - } - ``` - - The value of **match\_attr** must be the same as that of **deviceMatch\_Attr** in the **device\_info.hcs** file. The **match\_attr** attribute is used to match the configured parameters in the configuration file \(**i2c\_config.hcs** in this example\) with the particular driver, so that the driver can call **DeviceResourceGetIfaceInstance\(\)** in the **Bind** or **Init** function to obtain these configuration parameters. - - If you create a new configuration file to set parameters, reference this file in the board-level configuration entry file **hdf.hcs**. For example: - - ``` - #include "device_info/device_info.hcs" - #include "i2c/i2c_config.hcs" - ``` - - In this development example, we use an existing configuration file **i2c\_config.hcs** to add parameters, and therefore do not need to add it to the board-level configuration entry file. - -3. Enable the driver to obtain configuration parameters from the HCS. - - In this example, the driver needs to obtain configuration parameters, such as the physical base address of the register, register size, and bus number, through the HCS to correctly configure the controller. - - ``` - /* Obtain configuration parameters from the HCS. */ - static int32_t SampleI2cReadDrs(struct SampleI2cCntlr *sampleCntlr, const struct DeviceResourceNode *node) - { - int32_t ret; - struct DeviceResourceIface *drsOps = NULL; - - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL) { // Ensure that the GetUint32 function is available. - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return HDF_FAILURE; - } - - ret = drsOps->GetUint32(node, "reg_pbase", &sampleCntlr->regBasePhy, 0); // Read the physical base address from the HCS. - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regBase fail!", __func__); - return ret; - } - - ret = drsOps->GetUint16(node, "reg_size", &sampleCntlr->regSize, 0); // Read the register size from the HCS. - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regsize fail!", __func__); - return ret; - } - - ret = drsOps->GetUint16(node, "bus", (uint16_t *)&sampleCntlr->bus, 0); // Read the bus number from the HCS. - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read bus fail!", __func__); - return ret; - } - - return HDF_SUCCESS; - } - ``` - - -## Adding a Controller - -1. Define an I2C controller structure, implement a hook, and assign the hook to the function pointer. - - The **I2cMethod** structure is defined in the **i2c\_core.h** header file. This structure defines the functions to be implemented by the I2C driver by using function pointers. The **SampleI2cTransfer** function is a hook used for data transmission, which must be implemented in the driver and must be assigned to a function pointer. - - The sample code is as follows: - - ``` - /* Custom device structure, which is inherited from I2cCntlr */ - struct SampleI2cCntlr { - struct I2cCntlr cntlr; - OsalSpinlock spin; - volatile unsigned char *regBase; - uint16_t regSize; - int16_t bus; - uint32_t regBasePhy; - }; - - /* Message structure, which is inherited from I2cMsg */ - struct SampleTransferData { - struct I2cMsg *msgs; - int16_t index; - int16_t count; - }; - /* Implement the SampleI2cTransfer hook. */ - static int32_t SampleI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count) - { - int32_t ret = HDF_SUCCESS; - struct SampleI2cCntlr *sampleCntlr = NULL; - struct SampleTransferData td; - - if (cntlr == NULL || cntlr->priv == NULL) { - HDF_LOGE("SampleI2cTransfer: cntlr lor sampleCntlr is null!"); - return HDF_ERR_INVALID_OBJECT; - } - sampleCntlr = (struct SampleI2cCntlr *)cntlr; - - if (msgs == NULL || count <= 0) { - HDF_LOGE("SampleI2cTransfer: err parms! count:%d", count); - return HDF_ERR_INVALID_PARAM; - } - td.msgs = msgs; - td.count = count; - td.index = 0; - - HDF_LOGE("Successfully transmitted!"); // Data transmission is successful. - - td.index = count; // The total number of sent messages is returned. The message handling process is not provided in this sample code. - return (td.index > 0) ? td.index : ret; - } - /* Assign the hook to a function pointer. */ - static struct I2cMethod g_method = { - .transfer = SampleI2cTransfer, - }; - ``` - -2. Write a driver initialization function. - - This example uses **SampleI2cInit** as the name of the driver initialization function \(you can name your own function\). This function must be assigned to the **Init** function in the driver entry structure so that the HDF can call it to initialize the driver. The driver initialization function needs to parse the configuration parameters obtained from the HCS and create a controller based on these parameters. The sample code is as follows: - - ``` - /* Parse parameters, apply for memory, and create a controller. */ - static int32_t SampleI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) - { - int32_t ret; - struct SampleI2cCntlr *sampleCntlr = NULL; - (void)device; - - sampleCntlr = (struct SampleI2cCntlr *)OsalMemCalloc(sizeof(*sampleCntlr)); - if (sampleCntlr == NULL) { - HDF_LOGE("%s: malloc sampleCntlr fail!", __func__); - return HDF_ERR_MALLOC_FAIL; - } - - ret = SampleI2cReadDrs(sampleCntlr, node); // Obtain configuration parameters from the HCS. - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read drs fail! ret:%d", __func__, ret); - goto __ERR__; - } - - sampleCntlr->regBase = OsalIoRemap(sampleCntlr->regBasePhy, sampleCntlr->regSize); - if (sampleCntlr->regBase == NULL) { - HDF_LOGE("%s: ioremap regBase fail!", __func__); - ret = HDF_ERR_IO; - goto __ERR__; - } - - HDF_LOGE("The controller has been initialized!"); // The controller has been initialized successfully. (The initialization process is not provided here.) - - sampleCntlr->cntlr.priv = (void *)node; - sampleCntlr->cntlr.busId = sampleCntlr->bus; - sampleCntlr->cntlr.ops = &g_method; - (void)OsalSpinInit(&sampleCntlr->spin); // Initialize the spin lock. - ret = I2cCntlrAdd(&sampleCntlr->cntlr); // Add a controller to the core layer. - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: add i2c controller fail:%d!", __func__, ret); - goto __ERR__; - } - - return HDF_SUCCESS; - __ERR__: // Handle errors. - if (sampleCntlr != NULL) { - if (sampleCntlr->regBase != NULL) { - OsalIoUnmap((void *)sampleCntlr->regBase); // Cancel address mapping. - sampleCntlr->regBase = NULL; - } - OsalMemFree(sampleCntlr); // Release the memory. - sampleCntlr = NULL; - } - return ret; - } - /* Driver initialization function */ - static int32_t SampleI2cInit(struct HdfDeviceObject *device) - { - int32_t ret; - const struct DeviceResourceNode *childNode = NULL; - - HDF_LOGE("%s: Enter", __func__); - if (device == NULL || device->property == NULL) { - HDF_LOGE("%s: device or property is NULL", __func__); - return HDF_ERR_INVALID_OBJECT; - } - - ret = HDF_SUCCESS; - DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { - ret = SampleI2cParseAndInit(device, childNode); // Call the function for parsing parameters and creating a controller. - if (ret != HDF_SUCCESS) { - break; - } - } - return ret; - } - ``` - -3. Write a driver release function. - - This example uses **SampleI2cRelease** as the name of the driver release function \(you can name your own function\). This function must be assigned to the **Release** function in the driver entry structure so that the HDF can call it to initialize the driver if the driver fails to be initialized via **Init**. The driver release function must contain operations for releasing the memory and deleting the controller. The sample code is as follows: - - ``` - /* Function for deleting the controller */ - static void SampleI2cRemoveByNode(const struct DeviceResourceNode *node) - { - int32_t ret; - int16_t bus; - struct I2cCntlr *cntlr = NULL; - struct SampleI2cCntlr *sampleCntlr = NULL; - struct DeviceResourceIface *drsOps = NULL; - - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL) { - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return; - } - - ret = drsOps->GetUint16(node, "bus", (uint16_t *)&bus, 0); // Obtain the I2C bus number from the HCS. - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read bus fail!", __func__); - return; - } - - cntlr = I2cCntlrGet(bus); - if (cntlr != NULL && cntlr->priv == node) { // Delete the controller based on the I2C bus number. - I2cCntlrPut(cntlr); - I2cCntlrRemove(cntlr); - sampleCntlr = (struct SampleI2cCntlr *)cntlr; - OsalIoUnmap((void *)sampleCntlr->regBase); - OsalMemFree(sampleCntlr); - } - return; - } - /* Release resources. */ - static void SampleI2cRelease(struct HdfDeviceObject *device) - { - const struct DeviceResourceNode *childNode = NULL; - - HDF_LOGI("%s: enter", __func__); - - if (device == NULL || device->property == NULL) { - HDF_LOGE("%s: device or property is NULL", __func__); - return; - } - - DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { - SampleI2cRemoveByNode(childNode); // Delete a controller. - } - } - ``` - - diff --git a/en/device-dev/guide/development-example-for-clock-apps.md b/en/device-dev/guide/development-example-for-clock-apps.md deleted file mode 100644 index d461a0dd393f8283f806ded37aa1b4830e13a56f..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/development-example-for-clock-apps.md +++ /dev/null @@ -1,15 +0,0 @@ -# Development Example for Clock Apps - -- **[Overview](overview-7.md)** - -- **[Preparations](preparations-8.md)** - -- **[How to Develop](how-to-develop.md)** - -- **[Signing and Packaging](signing-and-packaging.md)** - -- **[Running on the Device](running-on-the-device-9.md)** - -- **[FAQs](faqs-10.md)** - - diff --git a/en/device-dev/guide/development-example-for-peripheral-drivers.md b/en/device-dev/guide/development-example-for-peripheral-drivers.md deleted file mode 100644 index 4333c26e067bd1ce6981ef3e0a558e5f03578822..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/development-example-for-peripheral-drivers.md +++ /dev/null @@ -1,15 +0,0 @@ -# Development Example for Peripheral Drivers - -- **[Overview](overview-13.md)** - -- **[Setting Up the Environment](setting-up-the-environment.md)** - -- **[Developing a Touchscreen Driver](developing-a-touchscreen-driver.md)** - -- **[Building and Burning](building-and-burning-14.md)** - -- **[Debugging and Verification](debugging-and-verification.md)** - -- **[Input Driver Model Workflow Analysis](input-driver-model-workflow-analysis.md)** - - diff --git a/en/device-dev/guide/development-example-for-platform-drivers.md b/en/device-dev/guide/development-example-for-platform-drivers.md deleted file mode 100644 index fbb47fb7d32d8b300c97f77d4f5fff0f1d616501..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/development-example-for-platform-drivers.md +++ /dev/null @@ -1,11 +0,0 @@ -# Development Example for Platform Drivers - -- **[Overview](overview-10.md)** - -- **[Preparations](preparations-11.md)** - -- **[Development](development-12.md)** - -- **[Building and Burning](building-and-burning.md)** - - diff --git a/en/device-dev/guide/development-guidelines-2.md b/en/device-dev/guide/development-guidelines-2.md deleted file mode 100644 index 6b5c9a629e1720512db8fa5d6f64388b80fb33fa..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/development-guidelines-2.md +++ /dev/null @@ -1,9 +0,0 @@ -# Development Guidelines - -- **[Photographing](photographing-3.md)** - -- **[Video Recording](video-recording-4.md)** - -- **[Previewing](previewing.md)** - - diff --git a/en/device-dev/guide/development-guidelines.md b/en/device-dev/guide/development-guidelines.md deleted file mode 100644 index fd34356bfaf087978ff851847b5339180b529037..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/development-guidelines.md +++ /dev/null @@ -1,7 +0,0 @@ -# Development Guidelines - -- **[Photographing](photographing.md)** - -- **[Video Recording](video-recording.md)** - - diff --git a/en/device-dev/guide/development.md b/en/device-dev/guide/development.md deleted file mode 100644 index c02ffef834486c29a0693ab8ad4074b77f52462a..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/development.md +++ /dev/null @@ -1,91 +0,0 @@ -# Development - -1. Complete the operations described in [Getting Started with Hi3861](../quick-start/hi3861-development-board.md). - - LED control examples are stored in the file **applications/sample/wifi-iot/app/iothardware/led\_example.c**. - -2. Refer to the schematic diagram to understand the cable connections. The LED of Hispark Pegasus should be connected to pin 9. - - ``` - #define LED_TEST_GPIO 9 - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >For details about the schematic diagram of the development board, contact the Hi3861 customer service personnel. - -3. Initialize the GPIO pin, specify the pin usage, and create a task to turn on or off the LED periodically so that the LED blinks. - - ``` - static void LedExampleEntry(void) - { - osThreadAttr_t attr; - - /* Initialize the GPIO pin. */ - IoTGpioInit(LED_TEST_GPIO); - /* Set pin 9 as the output direction. */ - IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT); - - attr.name = "LedTask"; - attr.attr_bits = 0U; - attr.cb_mem = NULL; - attr.cb_size = 0U; - attr.stack_mem = NULL; - attr.stack_size = LED_TASK_STACK_SIZE; - attr.priority = LED_TASK_PRIO; - - /* Start the task. */ - if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) { - printf("[LedExample] Failed to create LedTask!\n"); - } - } - ``` - -4. Use a cyclic task in which the LED periodically turns on and off to implement LED blinking. - - ``` - static void *LedTask(const char *arg) - { - (void)arg; - while (1) { - switch (g_ledState) { - case LED_ON: - IoTGpioSetOutputVal(LED_TEST_GPIO, 1); - usleep(LED_INTERVAL_TIME_US); - break; - case LED_OFF: - IoTGpioSetOutputVal(LED_TEST_GPIO, 0); - usleep(LED_INTERVAL_TIME_US); - break; - case LED_SPARK: - IoTGpioSetOutputVal(LED_TEST_GPIO, 0); - usleep(LED_INTERVAL_TIME_US); - IoTGpioSetOutputVal(LED_TEST_GPIO, 1); - usleep(LED_INTERVAL_TIME_US); - break; - default: - usleep(LED_INTERVAL_TIME_US); - break; - } - } - return NULL; - } - ``` - -5. Call **SYS\_RUN\(\)** of OpenHarmony to start the service. \(**SYS\_RUN** is defined in the **ohos\_init.h** file.\) - - ``` - SYS_RUN(LedExampleEntry); - ``` - -6. Change the **applications/sample/wifi-iot/app/BUILD.gn** file to enable **led\_example.c** to participate in compilation. - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("app") { - features = [ - "iothardware:led_example" - ] - } - ``` - - diff --git a/en/device-dev/guide/device-camera-control-demo-photoguide.md b/en/device-dev/guide/device-camera-control-demo-photoguide.md new file mode 100644 index 0000000000000000000000000000000000000000..eda733f15340836efaf5e6d25417821836bc333d --- /dev/null +++ b/en/device-dev/guide/device-camera-control-demo-photoguide.md @@ -0,0 +1,396 @@ +# Photographing + +- [When to Use](#en-us_topic_0000001052170554_section1963312376119) +- [Available APIs](#en-us_topic_0000001052170554_section56549532016) +- [Limitations and Constraints](#en-us_topic_0000001052170554_section1165911177314) +- [How to Develop](#en-us_topic_0000001052170554_section138543918214) + +## When to Use + +Use the camera module APIs to capture frames \(photographing\). + +## Available APIs + +**Table 1** APIs for photographing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

Function

+

Description

+

CameraKit

+

int32_t GetCameraIds(std::list<string> cameraList)

+

Obtains IDs of cameras that are currently available.

+

CameraKit

+

CameraAbility& GetCameraAbility(string cameraId)

+

Obtains the camera capability

+

CameraKit

+

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

+

Registers a camera callback for camera status changes.

+

CameraKit

+

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

+

Unregisters a camera callback.

+

CameraKit

+

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

+

Creates a Camera instance.

+

Camera

+

string GetCameraId()

+

Obtains the camera ID.

+

Camera

+

CameraConfig& GetCameraConfig()

+

Obtains the camera configuration.

+

Camera

+

FrameConfig& GetFrameConfig(int32_t type)

+

Obtains the frame configuration.

+

Camera

+

void Configure(CameraConfig& config)

+

Configures the camera using the CameraConfig object.

+

Camera

+

void Release()

+

Releases the Camera object and associated resources.

+

Camera

+

int TriggerLoopingCapture(FrameConfig& frameConfig)

+

Starts looping-frame capture.

+

Camera

+

void StopLoopingCapture()

+

Stops looping-frame capture.

+

Camera

+

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

+

Starts single-frame capture.

+

CameraConfig

+

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

+

Sets a frame state callback to respond to state changes.

+

CameraConfig

+

static CameraConfig* CreateCameraConfig()

+

Creates a CameraConfig instance.

+

CameraAbility

+

std::list<Size> GetSupportedSizes(int format)

+

Obtains the supported image sizes for a specified image format.

+

CameraAbility

+

std::list<T> GetParameterRange(uint32_t key)

+

Obtains the parameter value range based on a specified parameter key.

+

CameraDevice

+

CameraDeviceCallback()

+

A constructor used to create a CameraDeviceCallback instance.

+

CameraDevice

+

void OnCameraStatus​(std::string cameraId, int32_t status)

+

Called when the camera device status changes.

+

CameraStateCallback

+

CameraStateCallback​()

+

A constructor used to create a CameraStateCallback instance.

+

CameraStateCallback

+

void OnConfigured​(Camera& camera)

+

Called when the camera is configured.

+

CameraStateCallback

+

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

+

Called when the camera fails to be configured.

+

CameraStateCallback

+

void OnCreated​(Camera& camera)

+

Called when the camera is successfully created.

+

CameraStateCallback

+

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

+

Called when the camera fails to be created.

+

CameraStateCallback

+

void OnReleased​(Camera& camera)

+

Called when the camera is released.

+

FrameStateCallback

+

FrameStateCallback​()

+

A constructor used to create a FrameStateCallback instance.

+

FrameStateCallback

+

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

+

Called when the frame capture is completed.

+

FrameStateCallback

+

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

+

Called when the frame capture fails.

+

FrameConfig

+

int32_t GetFrameConfigType()

+

Obtains the frame configuration type.

+

FrameConfig

+

std::list<OHOS::Surface> GetSurfaces()

+

Obtains a list of surface objects (shared memories).

+

FrameConfig

+

void AddSurface(OHOS::AGP::UISurface& surface);

+

Adds a surface.

+

FrameConfig

+

void RemoveSurface(OHOS::AGP::UISurface& surface);

+

Removes a surface.

+
+ +## Limitations and Constraints + +None + +## How to Develop + +1. Extend the **CameraDeviceCallback** class and call **OnCameraStatus** to customize operations when the camera device changes, for example, when a camera becomes available or unavailable. + + ``` + class SampleCameraDeviceCallback : public CameraDeviceCallback { + void OnCameraStatus(std::string cameraId, int32_t status) override + { + // Do something when camera is available or unavailable. + } + }; + ``` + +2. Extend the **FrameStateCallback** class. After obtaining the frame data, save the data as a file. + + ``` + static void SampleSaveCapture(const char *p, uint32_t size) + { + cout << "Start saving picture" << endl; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm *ltm = localtime(&tv.tv_sec); + if (ltm != nullptr) { + ostringstream ss("Capture_"); + ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; + + ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); + cout << "write " << size << " bytes" << endl; + pic.write(p, size); + cout << "Saving picture end" << endl; + } + } + + class TestFrameStateCallback : public FrameStateCallback { + void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override + { + cout << "Receive frame complete inform." << endl; + if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { + cout << "Capture frame received." << endl; + list surfaceList = fc.GetSurfaces(); + for (Surface *surface : surfaceList) { + SurfaceBuffer *buffer = surface->AcquireBuffer(); + if (buffer != nullptr) { + char *virtAddr = static_cast(buffer->GetVirAddr()); + if (virtAddr != nullptr) { + SampleSaveCapture(virtAddr, buffer->GetSize()); + } + surface->ReleaseBuffer(buffer); + } + delete surface; + } + delete &fc; + } + } + }; + ``` + +3. Extend the **CameraStateCallback** class and customize operations when the camera state changes \(configuration successful or failed, and creation successful or failed\). + + ``` + class SampleCameraStateMng : public CameraStateCallback { + public: + SampleCameraStateMng() = delete; + SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} + ~SampleCameraStateMng() + { + if (recordFd_ != -1) { + close(recordFd_); + } + } + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} + void OnReleased(Camera &c) override {} + }; + ``` + +4. Create a **CameraKit** instance to set and obtain camera information. + + ``` + CameraKit *camKit = CameraKit::GetInstance(); + list camList = camKit->GetCameraIds(); + string camId; + for (auto &cam : camList) { + cout << "camera name:" << cam << endl; + const CameraAbility *ability = camKit->GetCameraAbility(cam); + /* Find the camera that fits your ability. */ + list sizeList = ability->GetSupportedSizes(0); + if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { + camId = cam; + break; + } + } + ``` + +5. Create a **Camera** instance. + + ``` + EventHandler eventHdlr; // Create a thread to handle callback events. + SampleCameraStateMng CamStateMng(eventHdlr); + + camKit->CreateCamera(camId, CamStateMng, eventHdlr); + ``` + +6. In the main process, synchronize configurations set by callback functions implemented in [step 1](#en-us_topic_0000001052170554_li378084192111), [step 2](#en-us_topic_0000001052170554_li8716104682913), and [step 3](#en-us_topic_0000001052170554_li6671035102514). + + ``` + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + + void Capture() + { + if (cam_ == nullptr) { + cout << "Camera is not ready." << endl; + return; + } + FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); + Surface *surface = Surface::CreateSurface(); + if (surface == nullptr) { + delete fc; + return; + } + surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ + fc->AddSurface(*surface); + cam_->TriggerSingleCapture(*fc); + } + ``` + + diff --git a/en/device-dev/guide/previewing.md b/en/device-dev/guide/device-camera-control-demo-previewguide.md similarity index 100% rename from en/device-dev/guide/previewing.md rename to en/device-dev/guide/device-camera-control-demo-previewguide.md diff --git a/en/device-dev/guide/video-recording-4.md b/en/device-dev/guide/device-camera-control-demo-videoguide.md similarity index 100% rename from en/device-dev/guide/video-recording-4.md rename to en/device-dev/guide/device-camera-control-demo-videoguide.md diff --git a/en/device-dev/guide/device-camera-control-demo.md b/en/device-dev/guide/device-camera-control-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..48b36ad9d6493fe655779cd63e2c9b8be7c2e1f4 --- /dev/null +++ b/en/device-dev/guide/device-camera-control-demo.md @@ -0,0 +1,9 @@ +# Development Guidelines + +- **[Photographing](device-camera-control-demo-photoguide.md)** + +- **[Video Recording](device-camera-control-demo-videoguide.md)** + +- **[Previewing](device-camera-control-demo-previewguide.md)** + + diff --git a/en/device-dev/guide/device-camera-control-example.md b/en/device-dev/guide/device-camera-control-example.md new file mode 100644 index 0000000000000000000000000000000000000000..9e77598359a5ec1e410e39d9354f0d541ac367fb --- /dev/null +++ b/en/device-dev/guide/device-camera-control-example.md @@ -0,0 +1,64 @@ +# Use Case + +This use case takes **camera\_sample** \(contained in the source code\) as an example for photographing, recording, and previewing on the development board. + +- You can obtain source code of the sample from **applications/sample/camera/media/camera\_sample.cpp**. +- Before running the sample camera, you need to compile, burn, and run the image. For details, see [Hi3516 Development Board](../quick-start/quickstart-lite-introduction-hi3516.md#section26131214194212). + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >After the development board is started, the home screen is loaded and displayed above the media layer by default. To prevent covering **camera\_sample**, you should remove the home screen during compilation or packaging. + >How to Remove: In **build/lite/components/applications.json**, comment out or delete the **//applications/sample/camera/launcher:launcher\_hap** line from the **target** field of **camera\_sample\_app**. + +- The compilation result of the sample code is stored in **out/hi3516dv300/ipcamera\_hi3516dv300\_liteos/dev\_tools/bin**. To ensure that the code can be executed on the development board, you can copy the file to a TF card through a card reader, or modify the compilation script of **camera\_sample** to copy the compilation result to **rootfs.img**. + + Modify the first **output\_dir** in the source code path **applications/sample/camera/media/BUILD.gn**. + + - Before: **output\_dir = "$root\_out\_dir/dev\_ools"** + - After: **output\_dir = "$root\_out\_dir/"** + + Recompile the source code repository and burn the code into the development board. Then you can find the **camera\_sample** file in the **bin** directory of the board. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >You should insert a TF card \(up to 128 GB supported\) for photographing and video recording before system startup. This way, the TF card will be automatically mounted to the **/sdcard** directory. If you insert the TF card after the system is started, you have to manually mount the TF card. + >To view the photos and videos in the TF card, copy them to a computer. If you just want to preview photos and videos, you do not need to insert a TF card. + +- Perform the following steps to run the sample: + +1. Run the **cd** command to go to the end path of the executable program and start **camera\_sample** by running the command in the following figure. + + **Figure 1** Starting camera\_sample + ![](figure/starting-camera_sample.png "starting-camera_sample") + + The control commands are displayed as shown in the preceding figure. Press **S** to stop the current operation \(including video recording and preview\), and press **Q** to exit the program. + +2. Press **1** to take a photo in JPG format. The photo is saved in the **/sdcard** directory and named **Capture\***. + + **Figure 2** Serial port logs displayed after the photographing command is executed + ![](figure/serial-port-logs-displayed-after-the-photographing-command-is-executed.png "serial-port-logs-displayed-after-the-photographing-command-is-executed") + + To view the saved file, exit the program and enter the file system. To start the program again, return to the previous step. + + **Figure 3** Saved files + ![](figure/saved-files.png "saved-files") + +3. Press **2** to start recording. The video file is in MP4 format and saved in the **/sdcard** directory with the name **Record\***. Press **S** to stop recording. + + **Figure 4** Serial port logs displayed after the recording command is executed + ![](figure/serial-port-logs-displayed-after-the-recording-command-is-executed.png "serial-port-logs-displayed-after-the-recording-command-is-executed") + +4. Press **3** to start preview. The preview is displayed on the screen. Press **S** to stop preview. + + **Figure 5** Serial port logs displayed after the preview command is executed + ![](figure/serial-port-logs-displayed-after-the-preview-command-is-executed.png "serial-port-logs-displayed-after-the-preview-command-is-executed") + + The following figure shows the preview. + + **Figure 6** Preview effect + ![](figure/preview-effect.jpg "preview-effect") + +5. Press **Q** to exit. + + **Figure 7** Serial port logs displayed after the exit command is executed + ![](figure/serial-port-logs-displayed-after-the-exit-command-is-executed.png "serial-port-logs-displayed-after-the-exit-command-is-executed") + + diff --git a/en/device-dev/guide/device-camera-control-overview.md b/en/device-dev/guide/device-camera-control-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..61f5aa13eb0b6a3e4cdf4362bd5355846f7f4135 --- /dev/null +++ b/en/device-dev/guide/device-camera-control-overview.md @@ -0,0 +1,10 @@ +# Overview + +This document describes how to use the IoT camera development board \(Hi3516D V300\) and its camera and screen to implement photographing, video recording, and video preview. + +This document helps you take a deep dive into OpenHarmony camera control. With this reference, you can develop devices, such as peephole cameras, smart rear-view mirrors, and smart displays. + +If you want to view the running effect first, see [Use Case](device-camera-control-example.md). To customize application behavior, modify the sample code by referring to APIs described in the "Development Guidelines" section. + +For basic concepts of camera development, see [Camera Development Overview](../subsystems/subsys-multimedia-camera-overview.md). + diff --git a/en/device-dev/guide/device-camera-control.md b/en/device-dev/guide/device-camera-control.md new file mode 100644 index 0000000000000000000000000000000000000000..062b965f7a68b9f00b602b2dfb8fe3b1cbacfbc1 --- /dev/null +++ b/en/device-dev/guide/device-camera-control.md @@ -0,0 +1,9 @@ +# Screen and Camera Control + +- **[Overview](device-camera-control-overview.md)** + +- **[Development Guidelines](device-camera-control-demo.md)** + +- **[Use Case](device-camera-control-example.md)** + + diff --git a/en/device-dev/guide/device-camera-visual-addpage.md b/en/device-dev/guide/device-camera-visual-addpage.md new file mode 100644 index 0000000000000000000000000000000000000000..2315fb68c61761574e12018baebf214b3006792a --- /dev/null +++ b/en/device-dev/guide/device-camera-visual-addpage.md @@ -0,0 +1,34 @@ +# Adding Pages + +- [Creating the Home Page](#section16935511143715) +- [Creating the Details Page](#section122131729173819) + +## Creating the Home Page + +Upon creation of the project, the **index** page is automatically generated, which is the home page of AirQuality. [Figure 1](#fig16545205773718) shows the project directory. + +**Figure 1** Project directory +![](figure/project-directory.png "project-directory") + +## Creating the Details Page + +To the details page, perform the following steps: + +1. Right-click **pages** and choose **New** \> **JS Page** from the shortcut menu. + + **Figure 2** Adding a page + ![](figure/adding-a-page.png "adding-a-page") + +2. Enter the page name. + + **Figure 3** Entering the page name + ![](figure/entering-the-page-name.png "entering-the-page-name") + +3. Confirm the creation. + + The following figure shows the application project directory after the **detail** page is created. It contains a **.hml** layout file, a **.css** file, and a **.js** file \(containing service logic code\). + + **Figure 4** Complete project directory + ![](figure/complete-project-directory.png "complete-project-directory") + + diff --git a/en/device-dev/guide/device-camera-visual-debug.md b/en/device-dev/guide/device-camera-visual-debug.md new file mode 100644 index 0000000000000000000000000000000000000000..2d4c192fb9c4948b510b6f0ad85d9e50f0a50a03 --- /dev/null +++ b/en/device-dev/guide/device-camera-visual-debug.md @@ -0,0 +1,4 @@ +# Debugging and Packaging + +After the code is compiled, debug your application and package it into an App Pack. For details about how to debug and package an application, see [Debugging Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ide_debug_device-0000001053822404) and [Building Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/build_overview-0000001055075201) in the [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). Currently, IPCamera applications do not support signature. You should release an unsigned App Pack. + diff --git a/en/device-dev/guide/device-camera-visual-details.md b/en/device-dev/guide/device-camera-visual-details.md new file mode 100644 index 0000000000000000000000000000000000000000..60bd585e6dd6d90cbfe47c6e68cc7a7b5dc85dee --- /dev/null +++ b/en/device-dev/guide/device-camera-visual-details.md @@ -0,0 +1,396 @@ +# Building the Details Page + +- [detail.hml](#section275215487291) +- [detail.css](#section2589154215301) +- [detail.js](#section163410883117) + +The **detail** page displays the air quality data of a week in a chart. There are two parts on the page: title bar and chart bar. Considering the display effect of the chart bar, use multiple **** components instead of one **** component. + +Add a root ****, set the **flex-direction** attribute to **column** to arrange the two bars vertically. The sample code is as follows: + +``` +
+
+ + + History + +
+ + +
+``` + +In the preceding example, **onclick="backMain"** indicates that the application returns to the home page when the click event is triggered. The sample code for **detail.js** is as follows: + +``` +import router from '@system.router' + +export default { + backMain() { + router.replace({ + // Home page URL + uri: 'pages/index/index', + params: { + // Parameters to pass to the home page + selectedCityIndex: this.selectedCityIndex + } + }); + } +} +``` + +Add **** components to the **** component to form a chart. + +The complete sample code in the three files is as follows. + +## detail.hml + +``` +
+
+ + + History + +
+ + + {{location}} + + + +
+
+ + CO + +
+
+
+
+
+
+
+
+
+
+
+ + MON + + + TUE + + + WED + + + THU + + + FRI + + + SAT + + + SUN + +
+
+
+ + SO2 + +
+
+
+
+
+
+
+
+
+
+
+ + MON + + + TUE + + + WED + + + THU + + + FRI + + + SAT + + + SUN + +
+
+
+
+ +
+
+ + PM10 + +
+
+
+
+
+
+
+
+
+
+
+ + MON + + + TUE + + + WED + + + THU + + + FRI + + + SAT + + + SUN + +
+
+
+ + PM2.5 + +
+
+
+
+
+
+
+
+
+
+
+ + MON + + + TUE + + + WED + + + THU + + + FRI + + + SAT + + + SUN + +
+
+
+
+ +
+
+ + NO2 + +
+
+
+
+
+
+
+
+
+
+
+ + MON + + + TUE + + + WED + + + THU + + + FRI + + + SAT + + + SUN + +
+
+
+
+
+
+``` + +## detail.css + +``` +.location { + text-align: center; + color: #ffffff; + width: 960px; + height: 52px; + font-size: 40px; +} +.container { + height: 480px; + width: 960px; + flex-direction: column; +} + +.header { + width: 960px; + height: 72px; +} + +.back { + width: 36px; + height: 36px; + margin-left: 39px; + margin-top: 23px; +} + +.title { + width: 296px; + height: 40px; + margin-top: 20px; + margin-left: 21px; + color: #e6e6e6; +} + +.chart-list { + width: 960px; + height: 408px; +} + +.list-item-title { + width: 960px; + height: 52px; +} + +.list-item-chart { + width: 960px; + height: 280px; +} + +.chart-wrapper { + width: 308px; + height: 256px; + flex-direction: column; +} + +.gas-name { + width: 308px; + height: 35px; + text-align: left; +} + +.chart { + width: 308px; + height: 155px; + margin-top: 10px; + justify-content: flex-start; + align-items: flex-end; +} + +.chart-item { + width: 24px; + margin-left: 18px; + border-radius: 3px; +} + +.white-line { + width: 308px; + height: 2px; + background-color: #ffffff; + margin-top: 22px; +} + +.week { + width: 308px; + height: 17px; + margin-top: 6px; + border-color: #ffffff; + border-radius: 2px; + margin-top: 6px; +} + +.day { + width: 26px; + height: 17px; + font-size: 10px; + margin-left: 16px; + text-align: center; +} +``` + +## detail.js + +``` +import router from '@system.router' + +export default { + data: { + location: '' + }, + onInit() { + if (this.selectedCityIndex === 0) { + this.location = 'Dongguan'; + } else { + this.location = 'Shenzhen'; + } + }, + backMain() { + router.replace({ + uri: 'pages/index/index', + params: { + selectedCityIndex: this.selectedCityIndex + } + }); + } +} +``` + diff --git a/en/device-dev/guide/faqs.md b/en/device-dev/guide/device-camera-visual-faqs.md similarity index 100% rename from en/device-dev/guide/faqs.md rename to en/device-dev/guide/device-camera-visual-faqs.md diff --git a/en/device-dev/guide/device-camera-visual-first-page.md b/en/device-dev/guide/device-camera-visual-first-page.md new file mode 100644 index 0000000000000000000000000000000000000000..5fe705f70f0dee725e2d4f485e7cf8652497b3b9 --- /dev/null +++ b/en/device-dev/guide/device-camera-visual-first-page.md @@ -0,0 +1,581 @@ +# Building the Home Page + +The application home page displays air quality information of different cities. The home page provides two screens \(for two information bars\), which can be added as required. Each screen displays the air quality information of one city, including the Air Quality Index \(AQI\), city name, pollution level, update time, and data source. + +The home page of AirQuality consists of three parts: + +- Title bar: displays the page title and provides an exit button. The title bar is fixed at the top of the page. +- Information bar: displays air quality information. Multiple information bars can be added based on user requirements and support looping scroll. +- Indicator bar: shows the position of the current screen among all screens. The indicator bar is fixed at the bottom of the page. + +The following steps describe how to build the home page with a flexible layout that has three rows vertically arranged. + +1. Add a root **** to the **.hml** file. Note that each **.hml** file can contain only one root component. The sample code is as follows: + + ``` +
+
+ ``` + + **class="container"** indicates the style used by the component. The **container** is a style class defined in the **index.css** file. + + ``` + .container { + flex-direction: column; + height: 480px; + width: 960px; + } + ``` + + The height and width of the root component **** are set in the style class. Note that the height and width must be explicitly specified \(except for some components, such as ****\). Otherwise, the component may fail to display. In the **container** style class, the **flex-direction** attribute is set to **column**, which means that child components of **** are vertically arranged from top to bottom for implementing the flexible page layout. + +2. Add the title bar. The title bar consists of an exit button and title text that are horizontally arranged. Add a **** to hold the title bar and set the **flex-direction** attribute to **row** to arrange the child components from left to right. Add an **** and a **** component in sequence. The sample code is as follows: + + ``` +
+
+ + + Air quality + +
+
+ ``` + + Set component attributes, including the height, width, margin, and color. + + ``` + .header { + width: 960px; + height: 72px; + } + .back { + width: 36px; + height: 36px; + margin-left: 39px; + margin-top: 23px; + } + .title { + width: 296px; + height: 40px; + margin-top: 20px; + margin-left: 21px; + color: #e6e6e6; + } + ``` + + In the **.hml** file, **onclick="exitApp"** sets the click event for the **** component. When the click event is triggered, the **exitApp\(\)** function is executed. The example definition of **exitApp\(\)** in **index.js** is as follows: + + ``` + exitApp() { + console.log('start exit'); + app.terminate(); + console.log('end exit'); + } + ``` + + The **app.terminate\(\)** function is used to exit the program. Before using this function, you must import the **app** module by adding the following code at the beginning of **index.js**: + + ``` + import app from '@system.app' + ``` + + After the code is compiled, run the project on the simulator. The following figure shows the display effect. + + **Figure 1** Title bar + ![](figure/title-bar.png "title-bar") + +3. The **** component is required to implement the switching between screens. + + Add a **** to the root node. + + ``` +
+
+ + + Air quality + +
+ + +
+ ``` + + - Use **class="**swiper**"** to set the height and width of the component. The sample code is as follows: + + ``` + .swiper { + height: 385px; + width: 960px; + } + ``` + + + - **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 ****. **\{\{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 **** component to the **swiperChange** function. The JavaScript code is as follows: + + ``` + // Import the router module for page switching. + import router from'@system.router' + import app from '@system.app' + + export default { + // Define parameters. + data: { + // By default, the first page is displayed. + swiperPage: 0 + }, + onInit () { + }, + exitApp(){ + console.log('start exit'); + app.terminate(); + console.log('end exit'); + }, + // Swiping event, which saves the index value of the current . The index value is saved to the swiperPage variable each time a swiping occurs. + swiperChange (e) { + this.swiperPage = e.index; + } + } + ``` + + +4. Set the information about a city to be displayed on a screen. On each screen, information of different types is displayed using different components. + + Add two **** as child components \(directional layout\) to ****. Add ****, ****, ****, and other components to each **** to display the information. The following example shows the page structure: + + ``` + + + + ------Air quality + ------City name + -----Progress bar + -------A cloud image + --------AQI value + AQI------AQI +
--------AQI details +
+
--------Update time, website, and other information +
+
+ + + + + + + + +
+
+
+ ``` + + After the code is compiled, the display effect on the simulator is as follows. + + **Figure 2** Title bar and information bar + ![](figure/title-bar-and-information-bar.png "title-bar-and-information-bar") + +5. Add the indicator bar. Currently, the **** component does not support indicator settings. You need to implement a dots indicator by adding **** components and setting the style. Add a **** as a child component to the root node and set the style. Add two **** to the parent ****, set **border-radius** for the two child ****, and dynamically change the background colors of the **** components in the swiping event. + + ``` +
+
+
+
+ ``` + + **Figure 3** Indicator bar + ![](figure/indicator-bar.png "indicator-bar") + +6. Set the style, animation effect, and dynamic data binding for all components. The complete sample code is as follows: + + - **index.hml** + + ``` +
+
+ + + AirQuality + +
+ + + {{airData[0].airQuality}} + + {{airData[0].location}} + + + + {{airData[0].detailData}} + + + AQI + +
+
+ + CO + + + 100 + +
+
+ + NO2 + + + 90 + +
+
+ + PM10 + + + 120 + +
+
+ + PM2.5 + + + 40 + +
+
+ + SO2 + + + 150 + +
+ +
+ +
+ + {{airData[1].airQuality}} + + {{airData[1].location}} + + + + {{airData[1].detailData}} + + + AQI + +
+
+ + CO + + + 10 + +
+
+ + NO2 + + + 50 + +
+
+ + PM10 + + + 60 + +
+
+ + PM2.5 + + + 40 + +
+
+ + SO2 + + + 150 + +
+ +
+ +
+
+
+
+
+
+
+ ``` + + - **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. + + ``` + .aqi-value { + text-align: center; + font-size: 65px; + color: #f0ffff; + width: 156px; + height: 92px; + top: 134px; + left: 210px; + } + .aqi { + text-align: center; + color: #a2c4a2; + width: 156px; + height: 45px; + top: 90px; + left: 210px; + } + .airquality { + top: 222px; + text-align: center; + width: 156px; + height: 45px; + left: 210px; + } + .image { + top: 285px; + left: 274px; + width: 32px; + height: 32px; + } + .location-text { + text-align: center; + color: #ffffff; + width: 200px; + height: 52px; + font-size: 40px; + left: 380px; + top: 16px; + } + .container { + flex-direction: column; + height: 480px; + width: 960px; + } + .circle-progress { + center-x: 128px; + center-y: 128px; + radius: 128px; + startAngle: 198; + totalAngle: 320; + strokeWidth: 24px; + width: 256px; + height: 256px; + left: 160px; + top: 58px; + } + .detail { + width: 256px; + height: 265px; + left: 544px; + top: 58px; + flex-direction: column; + } + .text-wrapper { + width: 256px; + height: 35px; + margin-top: 6px; + } + .gas-name { + width: 128px; + height: 35px; + text-align: left; + } + .gas-value { + width: 128px; + height: 35px; + text-align: right; + } + .btn { + width: 180px; + height: 50px; + margin-top: 6px; + margin-left: 38px; + background-color: #1a1a1a; + color: #1085CE; + } + .footer { + top: 326px; + width: 960px; + height: 28px; + } + .header { + width: 960px; + height: 72px; + } + .back { + width: 36px; + height: 36px; + margin-left: 39px; + margin-top: 23px; + } + .title { + width: 296px; + height: 40px; + margin-top: 20px; + margin-left: 21px; + color: #e6e6e6; + } + .swiper { + height: 385px; + width: 960px; + } + .images { + width: 60px; + height: 15px; + margin-left: 450px; + } + .update-time { + width: 480px; + height: 28px; + font-size: 20px; + color: #A9A9A9; + text-align: right; + } + .info-source { + width: 450px; + height: 28px; + font-size: 20px; + color: #A9A9A9; + text-align: left; + margin-left: 24px; + } + .circle-div { + width: 12px; + height: 12px; + border-radius: 6px; + } + ``` + + - **index.js** + + A **.js** file is used to implement interaction logic of your application. In the **.js** file of the home page, implement page switching and enable text content and progress bar color to change dynamically according to AQI values. + + ``` + // Import router and app modules. + import router from '@system.router' + import app from '@system.app' + + export default { + data: { + // Bind data. + textColor1: '#00ff00', + textColor2: '#00ff00', + bgColor1: '#669966', + bgColor2: '#669966', + swiperPage: 0, + percent1: 40, + percent2: 90, + iconUncheckedColor: '#262626', + iconcheckedColor: '#ffffff', + iconcheckedBR: '6px', + src1: 'common/cloud_green.png', + src2: 'common/cloud_green.png', + airData: [{ + location: 'Dongguan', + airQuality: 'Good', + detailData: 40 + }, { + location: 'Shenzhen', + airQuality: 'Polluted', + detailData: 90 + }] + }, + onInit () { + // Set the font, background color, and background image for different value ranges. + if(this.airData[0].detailData > 100){ + this.src1 = 'common/cloud_red.png'; + this.textColor1 = '#ff0000'; + this.bgColor1 = '#9d7462'; + } else if(50 < this.airData[0].detailData && this.airData[0].detailData <= 100){ + this.src1 = 'common/cloud_yellow.png'; + this.textColor1 = '#ecf19a'; + 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; + if(this.swiperPage == 0){ + this.iconcheckedColor = '#ffffff'; + this.iconUncheckedColor = '#262626'; + }else{ + this.iconcheckedColor = '#262626'; + this.iconUncheckedColor = '#ffffff'; + } + } + }, + // Switch to the details page. + openDetail () { + router.replace({ + uri: 'pages/detail/detail', + params: {selectedCityIndex:this.swiperPage} + }); + }, + // Exit the application. + exitApp(){ + console.log('start exit'); + app.terminate(); + console.log('end exit'); + }, + // Define the swiping event. Change the indicator dots when the user swipes the screen. + swiperChange (e) { + this.swiperPage = e.index; + if(e.index == 0){ + this.iconcheckedColor = '#ffffff'; + this.iconUncheckedColor = '#262626'; + }else{ + this.iconcheckedColor = '#262626'; + this.iconUncheckedColor = '#ffffff'; + } + } + } + ``` + + diff --git a/en/device-dev/guide/device-camera-visual-overview.md b/en/device-dev/guide/device-camera-visual-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..bf44297f7f42964b9883c939893a07bbbfe94a18 --- /dev/null +++ b/en/device-dev/guide/device-camera-visual-overview.md @@ -0,0 +1,15 @@ +# Overview + +- [Display Effects](#section3997224182313) + +This document describes how to quickly set up an application development environment \(using the Hi3516D V300 development board\) for event data recorders running on OpenHarmony. An air quality monitoring application, AirQuality, is used as an example to describe how to create, develop, and debug your application. + +## Display Effects + +AirQuality displays information about the urban air quality on two pages, the home page and details page. The following GIF shows AirQuality on the DevEco Studio simulator. + +**Figure 1** Display effects of the AirQuality + + +![](figure/video_2020-07-25_173141.gif) + diff --git a/en/device-dev/guide/device-camera-visual-prepare.md b/en/device-dev/guide/device-camera-visual-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..52beaf139d6ebb7fbe8460cc8bb01fea5b1aa78c --- /dev/null +++ b/en/device-dev/guide/device-camera-visual-prepare.md @@ -0,0 +1,27 @@ +# Preparations + +- [Setting Up the Development Environment](#section1912530122716) +- [Creating a Project](#section1456035192720) + +## Setting Up the Development Environment + +Download and install DevEco Studio. For details, see the [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/software_install-0000001053582415). + +## Creating a Project + +1. Open the project wizard using either of the following methods: + - If no project is open, select **Create HarmonyOS Project** on the welcome page. + - If a project is already open, go to **File** \> **New** \> **New Project** on the menu bar. + +2. Choose the **Smart Vision** for **Device** and **Empty Feature Ability** for **Template**. + + ![](figure/en-us_image_0000001082434703.png) + +3. Click **Next** and configure the project. + - **Project Name**: project name. + - **Package Name**: software package name. By default, this name will also be used as your application ID. Your application must have a unique ID to be released. + - **Save Location**: path for storing project files. The path cannot contain Chinese characters or spaces. + - **Compatible API Version**: compatible API version. + +4. Click **Finish**. DevEco Studio will automatically generate the sample code and resources that match your project type. Wait until the project is created. + diff --git a/en/device-dev/guide/device-camera-visual-run.md b/en/device-dev/guide/device-camera-visual-run.md new file mode 100644 index 0000000000000000000000000000000000000000..3668d68d278d34f1aae9f34c0fcda9ca1157269d --- /dev/null +++ b/en/device-dev/guide/device-camera-visual-run.md @@ -0,0 +1,29 @@ +# Running on the Device + +Before you install the application and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). Burn OpenHarmony into the development board, and run it on the board. For details about how to compile, burn, and run an image, see the [Hi3516 Development Board](../quick-start/quickstart-lite-introduction-hi3516.md#section26131214194212). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the application: + +1. Store the compiled unsigned application installation package and installation tool in an SD card and insert the SD card into the development board slot. The installation tool is in **dev\_tools** of the directory where the image file is generated. +2. Run the following command to disable signature verification, which is enabled by default for application installation: + + ``` + ./sdcard/dev_tools/bin/bm set -s disable + ``` + +3. Run the following command to install the application: + + ``` + ./sdcard/dev_tools/bin/bm install -p /sdcard/airquality.hap + ``` + + The **dev\_tools** directory stores the installation tool, and **airquality.hap** is the application installation package. Replace it with actual the package name. + +4. After the application is installed, touch the application icon on the home screen to enter the application. + + **Figure 1** Home screen + ![](figure/home-screen.png "home-screen") + +5. \(Optional\) Uninstall the application. + + Touch and hold the application icon on the home screen, and touch the uninstall button in the displayed menu. + + diff --git a/en/device-dev/guide/device-camera-visual.md b/en/device-dev/guide/device-camera-visual.md new file mode 100644 index 0000000000000000000000000000000000000000..183a3c5758f90bb42becc05c09e74379f53a9c28 --- /dev/null +++ b/en/device-dev/guide/device-camera-visual.md @@ -0,0 +1,19 @@ +# Visual Application Development + +- **[Overview](device-camera-visual-overview.md)** + +- **[Preparations](device-camera-visual-prepare.md)** + +- **[Adding Pages](device-camera-visual-addpage.md)** + +- **[Building the Home Page](device-camera-visual-first-page.md)** + +- **[Building the Details Page](device-camera-visual-details.md)** + +- **[Debugging and Packaging](device-camera-visual-debug.md)** + +- **[Running on the Device](device-camera-visual-run.md)** + +- **[FAQs](device-camera-visual-faqs.md)** + + diff --git a/en/device-dev/guide/device-camera.md b/en/device-dev/guide/device-camera.md new file mode 100644 index 0000000000000000000000000000000000000000..3fab60c51ec77fb4f023d1337edc3327aa29dbc0 --- /dev/null +++ b/en/device-dev/guide/device-camera.md @@ -0,0 +1,7 @@ +# Cameras with a Screen + +- **[Screen and Camera Control](device-camera-control.md)** + +- **[Visual Application Development](device-camera-visual.md)** + + diff --git a/en/device-dev/guide/device-driver-demo.md b/en/device-dev/guide/device-driver-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..9415d5323083e8dd5780360956a864b46988aec0 --- /dev/null +++ b/en/device-dev/guide/device-driver-demo.md @@ -0,0 +1,453 @@ +# Development Example for Platform Drivers + +- [Overview](#section194201316174215) +- [Preparations](#section6926133918422) +- [Development](#section65801539470) + - [File Description](#section0708184454414) + - [Instantiating the Driver Entry](#section85325864412) + - [Setting Related Parameters](#section8155172019453) + - [Adding a Controller](#section1335374114452) + +- [Building Source Code and Burning Images](#section164824754712) + +## Overview + +This document uses the I2C driver as an example to describe how to develop platform drivers based on the hardware driver foundation \(HDF\). + +>![](../public_sys-resources/icon-caution.gif) **CAUTION:** +>The sample code in this document is for reference only and cannot be directly used for commercial integration. + +The HDF provides a standard driver framework for common peripherals. To use the APIs provided by the HDF to perform operations on peripherals, you only need to adapt the specific driver to the HDF. + +In this example, an I2C driver is used. [Figure 1](#fig148041484161) shows the sequence diagram of the I2C driver. + +**Figure 1** I2C driver sequence diagram + + +![](figure/en-us_image_0000001169991055.png) + +- User Business: business-triggered driver +- i2cManagerEntry: entry to the I2C manager, which is used to register the I2C manager with the HDF +- I2cManager: I2C manager, which manages the I2C controller +- I2cCntlr: I2C controller +- i2cDriverEntry: entry to the I2C controller, which is used to register the I2C controller with the HDF + +## Preparations + +Follow the instructions in [Environment Setup for Standard System](../quick-start/quickstart-standard.md). + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>This development example applies to standard, small, and mini OpenHarmony systems. The following sections use the standard system as an example. You can refer to the specific guide for your system to set up the environment. + +## Development + +### File Description + +The following table lists the files involved in this example and their paths. + +**Table 1** File description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File

+

File Path

+

Remarks

+

Sample file

+

/drivers/adapter/khdf/linux/platform/i2c/i2c_sample.c

+

New file

+

Device service file

+

/drivers/adapter/khdf/linux/hcs/device_info/device_info.hcs

+

+

New content will be added to these files.

+

+

Configuration file

+

/drivers/adapter/khdf/linux/hcs/platform/i2c_config.hcs

+

Build file

+

/drivers/adapter/khdf/linux/platform/i2c/Makefile

+

Dependency

+

/drivers/framework/include/core/hdf_device_desc.h

+

Header file to be included

+

+

Core-layer header file

+

/drivers/framework/support/platform/include/i2c_core.h

+

HCS configuration entry file

+

/drivers/adapter/khdf/linux/hcs/hdf.hcs

+

Entry to HCS configuration files

+
+ +>![](../public_sys-resources/icon-caution.gif) **CAUTION:** +>The file paths involved in this example are used for demonstration only. Determine the paths for storing the source files as required when developing your driver. + +### Instantiating the Driver Entry + +Instantiate an **HdfDriverEntry** object as the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type \(which is defined in **hdf\_device\_desc.h**\), and the value of **moduleName** must be the same as that in **device\_info.hcs**. When loading the driver, the HDF calls the **Bind** function first and then the **Init** function. If an error occurred during the calling of the **Init** function, the HDF calls **Release** to release the driver resource and exit. + +The **Bind** function is not implemented in the I2C driver because the I2C controller is managed by the I2C manager and the **Bind** function has been implemented in the manager. Therefore, services do not need to be bound in the I2C driver. + +The sample code for instantiating the driver entry is as follows: + +``` +/* Define a driver entry object. It must be a global variable of the HdfDriverEntry type (defined in hdf_device_desc.h). */ +struct HdfDriverEntry g_sampleI2cDriverEntry = { + .moduleVersion = 1, + .Init = SampleI2cInit, + .Release = SampleI2cRelease, + .moduleName = "demo_i2c_driver", +}; +/* Call HDF_INIT to register the driver entry with the HDF. */ +HDF_INIT(g_sampleI2cDriverEntry); +``` + +### Setting Related Parameters + +Configure the **device\_info.hcs** file and obtain and parse device configuration parameters from the HCS to ensure that the driver can be correctly loaded. + +1. \(Mandatory\) Add a device service node. + + Edit the **device\_info.hcs** file and add a driver device service node under **device\_i2c :: device**. The following is an example: + + ``` + root { + device_info { + match_attr = "hdf_manager"; + device_i2c :: device { // I2C devices + device2 :: deviceNode { // Device node of an I2C driver + policy = 0; // Policy for releasing the driver service + priority = 55; // Driver startup priority + permission = 0644; // Permission for the driver to create a device node + moduleName = "demo_i2c_driver"; // Driver name. The value of this field must be the same as that of moduleName in the driver entry data structure. + serviceName = "DEMO_I2C_DRIVER"; // Name of the service released by the driver. The name must be unique. + deviceMatchAttr = "demo_i2c_config"; // Keyword matching the private data of the driver. The value must be the same as that of + // match_attr in the private configuration data table of the driver. + } + } + } + } + + ``` + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >The **priority** attribute \(an integer ranging from 0 to 200\) in the configuration file indicates the priority of a host or drivers. Drivers in a host with a smaller priority value have a higher loading priority than those in other hosts. The driver with a smaller priority value in a host has a higher loading priority than the other drivers in the host. The loading sequence is random for drivers with the same priority. + +2. \(Optional\) Add configuration parameters. + + The driver may require private configuration information to ensure that the register configuration meets the requirements of different products. If private configuration data is required, you can add a driver configuration file to store some default configuration information about the driver. When loading the driver, the HDF obtains the specified configuration information, saves it in the **property** attribute of **HdfDeviceObject**, and passes it to the driver via **Bind** and **Init**. For details about how to use **Bind** and **Init**, see [Driver Development](../driver/driver-hdf-development.md). You can create a configuration file and reference it in the **hdf.hcs** file of the board-level driver. In this example, configuration parameters are directly added to the existing configuration file **i2c\_config.hcs**. + + The following configuration parameters are added to the **i2c\_config.hcs** file: + + ``` + root { + platform { + i2c_config_demo { + match_attr = "demo_i2c_config"; // The value of this field must be the same as that of deviceMatchAttr in device_info.hcs. + + template i2c_controller { // Parameter template + bus = 0; + reg_pbase = 0x120b0000; + reg_size = 0xd1; + } + + controller_demo_0 :: i2c_controller { // Two sample I2C controllers + bus = 8; + } + controller_demo_1 :: i2c_controller { + bus = 9; + } + } + } + } + ``` + + The value of **match\_attr** must be the same as that of **deviceMatch\_Attr** in the **device\_info.hcs** file. The **match\_attr** attribute is used to match the configured parameters in the configuration file \(**i2c\_config.hcs** in this example\) with the particular driver, so that the driver can call **DeviceResourceGetIfaceInstance\(\)** in the **Bind** or **Init** function to obtain these configuration parameters. + + If you create a new configuration file to set parameters, reference this file in the board-level configuration entry file **hdf.hcs**. For example: + + ``` + #include "device_info/device_info.hcs" + #include "i2c/i2c_config.hcs" + ``` + + In this development example, we use an existing configuration file **i2c\_config.hcs** to add parameters, and therefore do not need to add it to the board-level configuration entry file. + +3. Enable the driver to obtain configuration parameters from the HCS. + + In this example, the driver needs to obtain configuration parameters, such as the physical base address of the register, register size, and bus number, from the HCS to correctly configure the controller. + + ``` + /* Obtain configuration parameters from the HCS. */ + static int32_t SampleI2cReadDrs(struct SampleI2cCntlr *sampleCntlr, const struct DeviceResourceNode *node) + { + int32_t ret; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { // Ensure that the GetUint32 function is available. + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return HDF_FAILURE; + } + + ret = drsOps->GetUint32(node, "reg_pbase", &sampleCntlr->regBasePhy, 0); // Read the physical base address from the HCS. + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regBase fail!", __func__); + return ret; + } + + ret = drsOps->GetUint16(node, "reg_size", &sampleCntlr->regSize, 0); // Read the register size from the HCS. + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regsize fail!", __func__); + return ret; + } + + ret = drsOps->GetUint16(node, "bus", (uint16_t *)&sampleCntlr->bus, 0); // Read the bus number from the HCS. + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read bus fail!", __func__); + return ret; + } + + return HDF_SUCCESS; + } + ``` + + +### Adding a Controller + +Initialize the controller hardware, call core-layer APIs to add or delete devices to or from the core layer, and implement a hook. + +1. Define an I2C controller structure, implement a hook, and assign the hook to the function pointer. + + The **I2cMethod** structure is defined in the **i2c\_core.h** header file. This structure defines the functions to be implemented by the I2C driver by using function pointers. The **SampleI2cTransfer** function is a hook used for data transmission, which must be implemented in the driver and must be assigned to a function pointer. + + The sample code is as follows: + + ``` + /* Custom device structure, which is inherited from I2cCntlr */ + struct SampleI2cCntlr { + struct I2cCntlr cntlr; + OsalSpinlock spin; + volatile unsigned char *regBase; + uint16_t regSize; + int16_t bus; + uint32_t regBasePhy; + }; + + /* Message structure, which is inherited from I2cMsg */ + struct SampleTransferData { + struct I2cMsg *msgs; + int16_t index; + int16_t count; + }; + /* Hook implementation */ + static int32_t SampleI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count) + { + int32_t ret = HDF_SUCCESS; + struct SampleI2cCntlr *sampleCntlr = NULL; + struct SampleTransferData td; + + if (cntlr == NULL || cntlr->priv == NULL) { + HDF_LOGE("SampleI2cTransfer: cntlr lor sampleCntlr is null!"); + return HDF_ERR_INVALID_OBJECT; + } + sampleCntlr = (struct SampleI2cCntlr *)cntlr; + + if (msgs == NULL || count <= 0) { + HDF_LOGE("SampleI2cTransfer: err parms! count:%d", count); + return HDF_ERR_INVALID_PARAM; + } + td.msgs = msgs; + td.count = count; + td.index = 0; + + HDF_LOGE("Successfully transmitted!"); // Data transmission is successful. + + td.index = count; // The total number of sent messages is returned. The message handling process is not provided in this sample code. + return (td.index > 0) ? td.index : ret; + } + /* Assign the hook to a function pointer. */ + static struct I2cMethod g_method = { + .transfer = SampleI2cTransfer, + }; + ``` + +2. Write a driver initialization function. + + This example uses **SampleI2cInit** as the name of the driver initialization function \(this function name is configurable\). This function must be assigned to the **Init** function in the driver entry structure so that the HDF can call it to initialize the driver. The driver initialization function needs to parse the configuration parameters obtained from the HCS and create a controller based on these parameters. The sample code is as follows: + + ``` + /* Parse parameters, apply for memory, and create a controller. */ + static int32_t SampleI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) + { + int32_t ret; + struct SampleI2cCntlr *sampleCntlr = NULL; + (void)device; + + sampleCntlr = (struct SampleI2cCntlr *)OsalMemCalloc(sizeof(*sampleCntlr)); + if (sampleCntlr == NULL) { + HDF_LOGE("%s: malloc sampleCntlr fail!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + ret = SampleI2cReadDrs(sampleCntlr, node); // Obtain configuration parameters from the HCS. + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read drs fail! ret:%d", __func__, ret); + goto __ERR__; + } + + sampleCntlr->regBase = OsalIoRemap(sampleCntlr->regBasePhy, sampleCntlr->regSize); + if (sampleCntlr->regBase == NULL) { + HDF_LOGE("%s: ioremap regBase fail!", __func__); + ret = HDF_ERR_IO; + goto __ERR__; + } + + HDF_LOGE("The controller has been initialized!"); // The controller has been initialized successfully. (The initialization process is not provided here.) + + sampleCntlr->cntlr.priv = (void *)node; + sampleCntlr->cntlr.busId = sampleCntlr->bus; + sampleCntlr->cntlr.ops = &g_method; + (void)OsalSpinInit(&sampleCntlr->spin); // Initialize the spin lock. + ret = I2cCntlrAdd(&sampleCntlr->cntlr); // Add a controller to the core layer. + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: add i2c controller fail:%d!", __func__, ret); + goto __ERR__; + } + + return HDF_SUCCESS; + __ERR__: // Handle errors. + if (sampleCntlr != NULL) { + if (sampleCntlr->regBase != NULL) { + OsalIoUnmap((void *)sampleCntlr->regBase); // Cancel address mapping. + sampleCntlr->regBase = NULL; + } + OsalMemFree(sampleCntlr); // Release the memory. + sampleCntlr = NULL; + } + return ret; + } + /* Driver initialization function */ + static int32_t SampleI2cInit(struct HdfDeviceObject *device) + { + int32_t ret; + const struct DeviceResourceNode *childNode = NULL; + + HDF_LOGE("%s: Enter", __func__); + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is NULL", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + ret = HDF_SUCCESS; + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + ret = SampleI2cParseAndInit(device, childNode); // Call the function for parsing parameters and creating a controller. + if (ret != HDF_SUCCESS) { + break; + } + } + return ret; + } + ``` + +3. Write a driver release function. + + This example uses **SampleI2cRelease** as the name of the driver release function \(you can name your own function\). This function must be assigned to the **Release** function in the driver entry structure so that the HDF can call it to initialize the driver if the driver fails to be initialized via **Init**. The driver release function must contain operations for releasing the memory and deleting the controller. The sample code is as follows: + + ``` + /* Function for deleting the controller */ + static void SampleI2cRemoveByNode(const struct DeviceResourceNode *node) + { + int32_t ret; + int16_t bus; + struct I2cCntlr *cntlr = NULL; + struct SampleI2cCntlr *sampleCntlr = NULL; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return; + } + + ret = drsOps->GetUint16(node, "bus", (uint16_t *)&bus, 0); // Obtain the I2C bus number from the HCS. + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read bus fail!", __func__); + return; + } + + cntlr = I2cCntlrGet(bus); + if (cntlr != NULL && cntlr->priv == node) { // Delete the controller based on the I2C bus number. + I2cCntlrPut(cntlr); + I2cCntlrRemove(cntlr); + sampleCntlr = (struct SampleI2cCntlr *)cntlr; + OsalIoUnmap((void *)sampleCntlr->regBase); + OsalMemFree(sampleCntlr); + } + return; + } + /* Release resources. */ + static void SampleI2cRelease(struct HdfDeviceObject *device) + { + const struct DeviceResourceNode *childNode = NULL; + + HDF_LOGI("%s: enter", __func__); + + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is NULL", __func__); + return; + } + + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + SampleI2cRemoveByNode(childNode); // Delete a controller. + } + } + ``` + + +## Building Source Code and Burning Images + +1. Edit the Makefile and add a source file to it, as shown in the following example: + + ``` + include drivers/hdf/khdf/platform/platform.mk + + obj-y += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_core.o \ + $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_if.o \ + ./i2c_adapter.o \ + ./i2c_sample.o + ``` + + **./i2c\_sample.o** is the source file added to the Makefile in this example. + +2. Build source code and burn images to the development board. + + For details, see the related sections in [Getting Started for Standard System](../quick-start/quickstart-standard.md). + + diff --git a/en/device-dev/guide/device-iotcamera-control-demo-photodevguide.md b/en/device-dev/guide/device-iotcamera-control-demo-photodevguide.md new file mode 100644 index 0000000000000000000000000000000000000000..a8da63373f6c284ee608836d504e38e5ee7c1569 --- /dev/null +++ b/en/device-dev/guide/device-iotcamera-control-demo-photodevguide.md @@ -0,0 +1,396 @@ +# Photographing + +- [When to Use](#en-us_topic_0000001052170554_section1963312376119) +- [Available APIs](#en-us_topic_0000001052170554_section56549532016) +- [Limitations and Constraints](#en-us_topic_0000001052170554_section1165911177314) +- [How to Develop](#en-us_topic_0000001052170554_section138543918214) + +## When to Use + +Use the camera module APIs to capture frames \(photographing\). + +## Available APIs + +**Table 1** APIs for photographing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

Function

+

Description

+

CameraKit

+

int32_t GetCameraIds(std::list<string> cameraList)

+

Obtains IDs of cameras that are currently available.

+

CameraKit

+

CameraAbility& GetCameraAbility(string cameraId)

+

Obtains the camera capability

+

CameraKit

+

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

+

Registers a camera callback for camera status changes.

+

CameraKit

+

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

+

Unregisters a camera callback.

+

CameraKit

+

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

+

Creates a Camera instance.

+

Camera

+

string GetCameraId()

+

Obtains the camera ID.

+

Camera

+

CameraConfig& GetCameraConfig()

+

Obtains the camera configuration.

+

Camera

+

FrameConfig& GetFrameConfig(int32_t type)

+

Obtains the frame configuration.

+

Camera

+

void Configure(CameraConfig& config)

+

Configures the camera using the CameraConfig object.

+

Camera

+

void Release()

+

Releases the Camera object and associated resources.

+

Camera

+

int TriggerLoopingCapture(FrameConfig& frameConfig)

+

Starts looping-frame capture.

+

Camera

+

void StopLoopingCapture()

+

Stops looping-frame capture.

+

Camera

+

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

+

Starts single-frame capture.

+

CameraConfig

+

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

+

Sets a frame state callback to respond to state changes.

+

CameraConfig

+

static CameraConfig* CreateCameraConfig()

+

Creates a CameraConfig instance.

+

CameraAbility

+

std::list<Size> GetSupportedSizes(int format)

+

Obtains the supported image sizes for a specified image format.

+

CameraAbility

+

std::list<T> GetParameterRange(uint32_t key)

+

Obtains the parameter value range based on a specified parameter key.

+

CameraDevice

+

CameraDeviceCallback()

+

A constructor used to create a CameraDeviceCallback instance.

+

CameraDevice

+

void OnCameraStatus​(std::string cameraId, int32_t status)

+

Called when the camera device status changes.

+

CameraStateCallback

+

CameraStateCallback​()

+

A constructor used to create a CameraStateCallback instance.

+

CameraStateCallback

+

void OnConfigured​(Camera& camera)

+

Called when the camera is configured.

+

CameraStateCallback

+

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

+

Called when the camera fails to be configured.

+

CameraStateCallback

+

void OnCreated​(Camera& camera)

+

Called when the camera is successfully created.

+

CameraStateCallback

+

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

+

Called when the camera fails to be created.

+

CameraStateCallback

+

void OnReleased​(Camera& camera)

+

Called when the camera is released.

+

FrameStateCallback

+

FrameStateCallback​()

+

A constructor used to create a FrameStateCallback instance.

+

FrameStateCallback

+

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

+

Called when the frame capture is completed.

+

FrameStateCallback

+

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

+

Called when the frame capture fails.

+

FrameConfig

+

int32_t GetFrameConfigType()

+

Obtains the frame configuration type.

+

FrameConfig

+

std::list<OHOS::Surface> GetSurfaces()

+

Obtains a list of surface objects (shared memories).

+

FrameConfig

+

void AddSurface(OHOS::AGP::UISurface& surface);

+

Adds a surface.

+

FrameConfig

+

void RemoveSurface(OHOS::AGP::UISurface& surface);

+

Removes a surface.

+
+ +## Limitations and Constraints + +None + +## How to Develop + +1. Extend the **CameraDeviceCallback** class and call **OnCameraStatus** to customize operations when the camera device changes, for example, when a camera becomes available or unavailable. + + ``` + class SampleCameraDeviceCallback : public CameraDeviceCallback { + void OnCameraStatus(std::string cameraId, int32_t status) override + { + // Do something when camera is available or unavailable. + } + }; + ``` + +2. Extend the **FrameStateCallback** class. After obtaining the frame data, save the data as a file. + + ``` + static void SampleSaveCapture(const char *p, uint32_t size) + { + cout << "Start saving picture" << endl; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm *ltm = localtime(&tv.tv_sec); + if (ltm != nullptr) { + ostringstream ss("Capture_"); + ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; + + ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); + cout << "write " << size << " bytes" << endl; + pic.write(p, size); + cout << "Saving picture end" << endl; + } + } + + class TestFrameStateCallback : public FrameStateCallback { + void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override + { + cout << "Receive frame complete inform." << endl; + if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { + cout << "Capture frame received." << endl; + list surfaceList = fc.GetSurfaces(); + for (Surface *surface : surfaceList) { + SurfaceBuffer *buffer = surface->AcquireBuffer(); + if (buffer != nullptr) { + char *virtAddr = static_cast(buffer->GetVirAddr()); + if (virtAddr != nullptr) { + SampleSaveCapture(virtAddr, buffer->GetSize()); + } + surface->ReleaseBuffer(buffer); + } + delete surface; + } + delete &fc; + } + } + }; + ``` + +3. Extend the **CameraStateCallback** class and customize operations when the camera state changes \(configuration successful or failed, and creation successful or failed\). + + ``` + class SampleCameraStateMng : public CameraStateCallback { + public: + SampleCameraStateMng() = delete; + SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} + ~SampleCameraStateMng() + { + if (recordFd_ != -1) { + close(recordFd_); + } + } + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} + void OnReleased(Camera &c) override {} + }; + ``` + +4. Create a **CameraKit** instance to set and obtain camera information. + + ``` + CameraKit *camKit = CameraKit::GetInstance(); + list camList = camKit->GetCameraIds(); + string camId; + for (auto &cam : camList) { + cout << "camera name:" << cam << endl; + const CameraAbility *ability = camKit->GetCameraAbility(cam); + /* Find the camera that fits your ability. */ + list sizeList = ability->GetSupportedSizes(0); + if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { + camId = cam; + break; + } + } + ``` + +5. Create a **Camera** instance. + + ``` + EventHandler eventHdlr; // Create a thread to handle callback events. + SampleCameraStateMng CamStateMng(eventHdlr); + + camKit->CreateCamera(camId, CamStateMng, eventHdlr); + ``` + +6. In the main process, synchronize configurations set by callback functions implemented in [step 1](#en-us_topic_0000001052170554_li378084192111), [step 2](#en-us_topic_0000001052170554_li8716104682913), and [step 3](#en-us_topic_0000001052170554_li6671035102514). + + ``` + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + + void Capture() + { + if (cam_ == nullptr) { + cout << "Camera is not ready." << endl; + return; + } + FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); + Surface *surface = Surface::CreateSurface(); + if (surface == nullptr) { + delete fc; + return; + } + surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ + fc->AddSurface(*surface); + cam_->TriggerSingleCapture(*fc); + } + ``` + + diff --git a/en/device-dev/guide/video-recording.md b/en/device-dev/guide/device-iotcamera-control-demo-videodevguide.md similarity index 100% rename from en/device-dev/guide/video-recording.md rename to en/device-dev/guide/device-iotcamera-control-demo-videodevguide.md diff --git a/en/device-dev/guide/device-iotcamera-control-demo.md b/en/device-dev/guide/device-iotcamera-control-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..6f187156291b9c813d199060c055e0d205e295db --- /dev/null +++ b/en/device-dev/guide/device-iotcamera-control-demo.md @@ -0,0 +1,7 @@ +# Development Guidelines + +- **[Photographing](device-iotcamera-control-demo-photodevguide.md)** + +- **[Video Recording](device-iotcamera-control-demo-videodevguide.md)** + + diff --git a/en/device-dev/guide/device-iotcamera-control-example.md b/en/device-dev/guide/device-iotcamera-control-example.md new file mode 100644 index 0000000000000000000000000000000000000000..bb9875ea20896e4319e8124befa33a74a6c3f280 --- /dev/null +++ b/en/device-dev/guide/device-iotcamera-control-example.md @@ -0,0 +1,45 @@ +# Use Case + +- For details about the development board, compilation, burning, and image running, see [Hi3518 Development Board](../quick-start/quickstart-lite-introduction-hi3518.md#section14815247616). A compilation result file of sample code is stored in **out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample**. You can copy the file to a TF card, or modify the compilation script of **camera\_sample** to copy the result to **rootfs.img**. + + Modify **output\_dir** in **applications/sample/camera/media/BUILD.gn**. + + - Before: **output\_dir = "$root\_out\_dir/dev\_tools"** + - After: **output\_dir = "$root\_out\_dir/"** + + Recompile the source code repository and burn the code into the development board. Then you can find the **camera\_sample** file in the **bin** directory of the board. + +- The sample code for camera development is stored in **applications/sample/camera/media/camera\_sample.cpp**. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >You should insert a TF card \(maximum capacity: 128 GB\) for photographing and video recording functions. After the system is started, the TF card is automatically mounted to the **/sdcard** directory. If the TF card is inserted after the system is started, you have to manually mount the TF card. To view the photos and videos in the TF card, copy the content to a computer. The preview function does not require a TF card. + + +1. Run the **cd** command to go to the end path of the executable program and start **camera\_sample** by running the command in the following figure. + + **Figure 1** Starting camera\_sample + ![](figure/starting-camera_sample.png "starting-camera_sample") + + The control commands are displayed as shown in the preceding figure. Press **S** to stop the current operation \(including video recording and preview\), and press **Q** to exit the program. + +2. Press **1** to take a photo in JPG format. The photo is saved in the **/sdcard** directory and named **Capture\***. + + **Figure 2** Serial port logs displayed after the photographing command is executed + ![](figure/serial-port-logs-displayed-after-the-photographing-command-is-executed.png "serial-port-logs-displayed-after-the-photographing-command-is-executed") + + To view the saved file, exit the program and enter the file system. To start the program again, return to the previous step. + + **Figure 3** Saved files + ![](figure/saved-files.png "saved-files") + +3. Press **2** to start recording. The video file is in MP4 format and saved in the **/sdcard** directory with the name **Record\***. Press **S** to stop recording. + + **Figure 4** Serial port logs displayed after the recording command is executed + ![](figure/serial-port-logs-displayed-after-the-recording-command-is-executed.png "serial-port-logs-displayed-after-the-recording-command-is-executed") + +4. Press **Q** to exit. + + **Figure 5** Serial port logs displayed after the exit command is executed + ![](figure/serial-port-logs-displayed-after-the-exit-command-is-executed.png "serial-port-logs-displayed-after-the-exit-command-is-executed") + + diff --git a/en/device-dev/guide/device-iotcamera-control-overview.md b/en/device-dev/guide/device-iotcamera-control-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..d5a493f3a209e1fd4dc4deb2b2c195956bcac273 --- /dev/null +++ b/en/device-dev/guide/device-iotcamera-control-overview.md @@ -0,0 +1,10 @@ +# Overview + +This document describes how to use the IoT camera development board and the built-in camera of the development kit to implement photographing and video recording. + +You can perform operations provided in [Use Case](device-iotcamera-control-example.md) to learn more about development board peripheral control and then develop devices such as cameras. + +If you want to view the sample effect first, see [Use Case](device-iotcamera-control-example.md). To customize application behavior, modify the sample code by referring to APIs described in the next section. + +For details about basic concepts for camera development, see the [camera development overview](../subsystems/subsys-multimedia-camera-overview.md). + diff --git a/en/device-dev/guide/device-iotcamera-control.md b/en/device-dev/guide/device-iotcamera-control.md new file mode 100644 index 0000000000000000000000000000000000000000..f2720769bb74584a87e538a45093ee13bfb95869 --- /dev/null +++ b/en/device-dev/guide/device-iotcamera-control.md @@ -0,0 +1,9 @@ +# Camera Control + +- **[Overview](device-iotcamera-control-overview.md)** + +- **[Development Guidelines](device-iotcamera-control-demo.md)** + +- **[Use Case](device-iotcamera-control-example.md)** + + diff --git a/en/device-dev/guide/device-iotcamera.md b/en/device-dev/guide/device-iotcamera.md new file mode 100644 index 0000000000000000000000000000000000000000..7cbb7f06d6d084d8c3876d78b30514b95cc7b948 --- /dev/null +++ b/en/device-dev/guide/device-iotcamera.md @@ -0,0 +1,5 @@ +# Cameras Without a Screen + +- **[Camera Control](device-iotcamera-control.md)** + + diff --git a/en/device-dev/guide/device-outerdriver-demo.md b/en/device-dev/guide/device-outerdriver-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..6ac02acd6475a8fd1e8ba6a7d20c421ad2b7351d --- /dev/null +++ b/en/device-dev/guide/device-outerdriver-demo.md @@ -0,0 +1,483 @@ +# Development Example for Peripheral Drivers + +- [Overview](#section86753818426) + - [Hardware Resources](#section123071189431) + - [Input Driver Model](#section53684425430) + +- [Setting Up the Environment](#section661075474418) +- [Developing a Touchscreen Driver](#section15233162984520) + - [Configuring Device Driver Descriptions](#section16761205604515) + - [Configuring the Touchscreen](#section156331030144617) + - [Adapting to the Private Drivers of the Touchscreen](#section17127331595) + +- [Building Source Code and Burning Images](#section16465031164711) +- [Debugging and Verification](#section62577313482) +- [Input Driver Model Workflow Analysis](#section1578569154917) + - [Parsing Private Configuration Data](#section1310113815495) + - [Initializing the Input Device Manager and Registering the Driver with the HDF](#section614512119500) + - [Initializing the Input Common Driver and Registering the Driver with the HDF](#section16194201755019) + - [Initializing the Input Chip Driver and Registering the Driver with the HDF](#section1090743312505) + - [Function Invocation Logic](#section81801147529) + + +## Overview + +This document describes how to develop a touchscreen driver on the Hi3516D V300 development board using the HDF input driver model, helping you quickly get started with peripheral driver development. + +### Hardware Resources + +The touchscreen integrated circuit \(IC\) provided by the Hi3516D V300 development board is GT911, which uses the standard inter-integrated circuit \(I2C\) to communicate with the development board and connects to the main board through the 6-pin flexible flat cable. The following figure shows the distribution of the 6 pins and their connection. + +![](figure/绘图1.png) + +### Input Driver Model + +The input driver model mainly consists of the device manager, common drivers, and chip drivers. + +- Input device manager: provides various input device drivers with the APIs for registering or unregistering input devices and manages the input device list. +- Input common driver: provides common drivers for initializing the board-level hardware, processing hardware interrupts, and registering input devices with the input device manager. +- Input chip driver: calls differentiated APIs reserved by the input platform driver to minimize the workload for input chip driver development. + +In addition, the input driver model implements functions for reporting input data and parsing input device configurations. + +For details about the input driver model, see [Touchscreen Overview](../driver/drive-peripherals-touch-des.md#section175431838101617). + +## Setting Up the Environment + +Follow the instructions in [Environment Setup for Standard System](../quick-start/quickstart-standard.md). + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>This development example applies to standard, small, and mini OpenHarmony systems. The following sections use the standard system as an example. You can refer to the specific guide for your system to set up the environment. + +## Developing a Touchscreen Driver + +Complete the following tasks to adapt a touchscreen IC based on the input driver model. + +### Configuring Device Driver Descriptions + +Configure the touchscreen driver description required for registering the driver with the HDF, for example, whether the driver is loaded and what is the loading priority. + +You can configure the device driver description in the configuration file at **./drivers/adapter/khdf/linux/hcs/device\_info/device\_info.hcs**. + +The **device\_info.hcs** file contains all necessary information for registering drivers in the input driver model with the HDF. You do not need to make any modification for the information unless otherwise required in special scenarios. The private configuration data of each driver uses the **deviceMatchAttr** field to match the **match\_attr** field in the **input\_config.hcs** file. + +The input-related fields in the configuration file are as follows. For details about these fields, see [Driver Development](../driver/driver-hdf-development.md). + +``` +input :: host { + hostName = "input_host"; + priority = 100; + device_input_manager :: device { // Specify the device driver description of the input device manager. + device0 :: deviceNode { + policy = 2; // Services are released to both the kernel space and the user space. + priority = 100; // The default priority for the input device manager is 100. + preload = 0; // Load the driver. + permission = 0660; // Specify the permission for the driver to create device nodes. + moduleName = "HDF_INPUT_MANAGER"; // Match the moduleName in the driver entry structure. + serviceName = "hdf_input_host"; // Specify the device node name to be generated by the HDF. + deviceMatchAttr = ""; // Leave this field empty because private configuration data is not required by the input device manager currently. + } + } + + device_hdf_touch :: device { // Specify the device driver description of the input common driver. + device0 :: deviceNode { + policy = 2; // Services are released to both the kernel space and the user space. + priority = 120; // The default priority for the input common driver is 120. + preload = 0; // Load the driver. + permission = 0660; // Specify the permission for the driver to create device nodes. + moduleName = "HDF_TOUCH"; // Match the moduleName in the driver entry structure. + serviceName = "hdf_input_event1"; // Specify the device node name to be generated by the HDF. + deviceMatchAttr = "touch_device1"; // Keep this value the same as the match_attr value in the private configuration data. + } + } + + device_touch_chip :: device { // Specify the device description of the input chip driver. + device0 :: deviceNode { + policy = 0; // Services are not released to the kernel space or the user space. + priority = 130; // The default priority for the input chip driver is 130. + preload = 0; // Load the driver. + permission = 0660; // Specify the permission for the driver to create device nodes. + moduleName = "HDF_TOUCH_GT911"; // Match the moduleName in the driver entry structure. + serviceName = "hdf_touch_gt911_service";// Specify the device node name to be generated by the HDF. + deviceMatchAttr = "zsj_gt911_5p5"; // Keep this value the same as the match_attr value in the private configuration data. + } + } + } +``` + +Pay attention to the following fields in the configuration file: + +**priority**: specifies the driver loading priority. + +**preload**: specifies whether to load the driver. + +**moduleName**: This value must be the same as the **moduleName** value in the driver entry structure. + +**serviceName**: This value is used by the HDF to create a device node name. + +**deviceMatchAttr**: This value must be the same as the **match\_attr** value in the private configuration data. + +After the device descriptions are configured, the HDF matches the configuration with the code registered with the driver entry structure based on the **moduleName** field, ensuring that drivers can be loaded properly. If multiple drivers are configured, the **priority** field determines the loading sequence of each driver. + +### Configuring the Touchscreen + +The private data includes the power-on and power-off sequence, and the platform hardware information includes the GPIO port that connects the touchscreen to the main board. + +You can configure the touchscreen in the configuration file at **./drivers/adapter/khdf/linux/hcs/input/input\_config.hcs**. + +The **input\_config.hcs** file consists of the private configuration data of both the common driver and chip driver. Information of this file is read and parsed by the driver code. The configuration in the file includes the board-level hardware information and private configuration of the touchscreen. You can tailor the configuration during your development. + +``` +root { + input_config { + touchConfig { + touch0 { // Configure the first touchscreen. + boardConfig { // Specify the board-level hardware information. + match_attr = "touch_device1"; // Keep this value the same as the match_attr field in the private configuration data of the input common driver in the device description. + inputAttr { + /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */ + inputType = 0; // Set the input type to touch. + solutionX = 480; // Set the resolution in the X-axis. + solutionY = 960; // Set the resolution in the Y-axis. + devName = "main_touch"; // Set the device name. + } + busConfig { + /* 0:i2c 1:spi */ + busType = 0; // GT911 uses the I2C bus for communication. + busNum = 6; // Use the sixth bus of the chip to communicate with the development board through I2C. + clkGpio = 86; // Set the SCL pin of the chip. + dataGpio = 87; // Set the SDA pin of the chip. + i2cClkIomux = [0x114f0048, 0x403]; // Configure the SCL pin information. + i2cDataIomux = [0x114f004c, 0x403]; // Configure the SDA pin information. + } + pinConfig { + rstGpio = 3; // Set the reset pin. + intGpio = 4; // Set the interrupt pin. + rstRegCfg = [0x112f0094, 0x400]; // Configure the reset pin information. + intRegCfg = [0x112f0098, 0x400]; // Configure the interrupt pin information. + } + powerConfig { + /* 0:unused 1:ldo 2:gpio 3:pmic */ + vccType = 2; // Set the VCC type. Value 2 indicates the GPIO power supply. + vccNum = 20; // gpio20 + vccValue = 1800; // Set the voltage amplitude to 1800 mV. + vciType = 1; // Set the VCI type. Value 1 indicates the LDO power supply. + vciNum = 12; // ldo12 + vciValue = 3300; // Set the voltage amplitude to 3300 mV. + } + + featureConfig { + capacitanceTest = 0; // Configure the capacitance test. + gestureMode = 0; // Configure the gesture mode. + gloverMode = 0; // Configure the gloves mode. + coverMode = 0; // Configure the cover mode. + chargerMode = 0; // Configure the charging mode. + knuckleMode = 0; // Configure the knuckle mode. + } + } + chipConfig { // Configure the private data of the touchscreen chip. + template touchChip { // Set the template. + match_attr = ""; + chipName = "gt911"; // Set the touchscreen IC model. + vendorName = "zsj"; // Set the vendor name. + chipInfo = "AAAA11222"; // The first four characters indicate the product name. The fifth and sixth characters indicate the IC model. The last three characters indicate the chip model. + busType = 0; // 0 indicates the I2C bus, and 1 indicates the SPI bus. + deviceAddr = 0x5D; // Set the IC communication address. + irqFlag = 2; // Values 1 and 2 indicate that the interrupt is triggered on the rising and falling edges, respectively. Values 4 and 8 indicate that the interrupt is triggered by the high and low levels, respectively. + maxSpeed = 400; // Set the maximum communication rate to 400 Hz. + chipVersion = 0; // Set the touchscreen IC version. + powerSequence { + /* Power-on sequence is described as follows: + [Type, status, direction, delay] + Value 0 indicates the power or pin is empty. Values 1 and 2 indicate the VCC (1.8 V) and VCI (3.3 V) power, respectively. Values 3 and 4 indicate the reset and interrupt pins, respectively. + Values 0 and 1 indicate the power-off or pull-down, and the power-on or pull-up, respectively. Value 2 indicates that no operation is performed. + Values 0 and 1 indicate the input and output directions, respectively. Value 2 indicates that no operation is performed. + Delay time, in milliseconds. + */ + powerOnSeq = [4, 0, 1, 0, // Set the output direction for the interrupt pin and pull down the pin. + 3, 0, 1, 10, // Set the output direction for the reset pin and pull down the pin, with a delay of 10 ms. + 3, 1, 2, 60, // No operation is performed on the reset pin. Pull up the pin, with a delay of 60 ms. + 4, 2, 0, 0]; // Set the input direction for the interrupt pin. + suspendSeq = [3, 0, 2, 10]; // No operation is performed on the reset pin. Pull down the pin, with a delay of 10 ms. + resumeSeq = [3, 1, 2, 10]; // No operation is performed on the reset pin. Pull up the pin, with a delay of 10 ms. + powerOffSeq = [3, 0, 2, 10, // No operation is performed on the reset pin. Pull down the pin, with a delay of 10 ms. + 1, 0, 2, 20]; // No operation is performed on the positive pin. Pull down the pin, with a delay of 20 ms. + } + } + + chip0 :: touchChip { + match_attr = "zsj_gt911_5p5"; // Keep this value the same as the match_attr field in the touchscreen private configuration data in the device description. + chipInfo = "ZIDN45100"; // The chip information is composed of the product name, module number, and chip number, used to identity the current touchscreen in user space. + chipVersion = 0; // Set the IC model version. + } + } + } + } + } +} +``` + +In the example, **touchConfig** contains the **touch0** configuration, which describes the **boardConfig** and **chipConfig** configuration information. The **boardConfig** field provides the board-level hardware information of Hi3516D V300, and the **chipConfig** field provides the private configuration data of the touchscreen. To use another touchscreen, you can change the value of the **chipConfig** field. You can also configure multiple touchscreens for your product. In this example, **touch0** represents the hardware interface and chip configuration of the default touchscreen. If you need to configure a secondary touchscreen, add a **touch1** block parallel to **touch0**. + +### Adapting to the Private Drivers of the Touchscreen + +The input driver model abstracts the development process of input devices. You only need to adapt to the input chip driver without making any modifications for the input device manager and common driver. + +The input driver model consists of three parts of drivers. To develop a brand-new touchscreen driver, you only need to adapt your code with the input chip driver and implement differentiated APIs. The sample code in this section illustrates how you will complete the adaptation. + +1. Implement differentiated APIs for the touchscreen to adapt to the input chip driver. + + You can obtain the sample code at **./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c**. + + ``` + static struct TouchChipOps g_gt911ChipOps = { // IC options of the touchscreen + .Init = ChipInit, // Initialize the chip. + .Detect = ChipDetect, // Detect the chip. + .Resume = ChipResume, // Resume the chip. + .Suspend = ChipSuspend, // Suspend the chip. + .DataHandle = ChipDataHandle, // Read the chip data. + .UpdateFirmware = UpdateFirmware, // Update the firmware. + }; + + /* The ICs may be different depending on the touchscreen vendors, and the corresponding register operations are also different. Therefore, the code for the input chip driver focuses only on the adaptation of differentiated APIs. The following sample code demonstrates the data parsing of GT911. */ + + static int32_t ChipDataHandle(ChipDevice *device) + { + ... + /* Read the status register before GT911 obtains coordinates. */ + reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; + ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); + if (ret < 0 || touchStatus == GT_EVENT_INVALID) { + return HDF_FAILURE; + } + ... + /* Read data from the data register based on the value of the status register. */ + reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; + pointNum = touchStatus & GT_FINGER_NUM_MASK; + if (pointNum == 0 || pointNum > MAX_SUPPORT_POINT) { + HDF_LOGE("%s: pointNum is invalid, %u", __func__, pointNum); + (void)ChipCleanBuffer(i2cClient); + OsalMutexUnlock(&device->driver->mutex); + return HDF_FAILURE; + } + frame->realPointNum = pointNum; + frame->definedEvent = TOUCH_DOWN; + (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); + /* Parse the obtained data. */ + ParsePointData(device, frame, buf, pointNum); + ... + } + static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) + { + ... + /* Each coordinate value consists of two bytes. Obtain the final coordinate value by combining the obtained single-byte data. */ + for (i = 0; i < pointNum; i++) { + frame->fingers[i].trackId = buf[GT_POINT_SIZE * i + GT_TRACK_ID]; + frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + /* Print the parsed coordinate value. */ + HDF_LOGD("%s: x = %d, y = %d", __func__, frame->fingers[i].x, frame->fingers[i].y); + } + } + ``` + +2. Initialize the input chip driver and register the driver with the HDF. + + You can obtain the sample code at **./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c**. + + ``` + static int32_t HdfGoodixChipInit(struct HdfDeviceObject *device) + { + ... + /* Use the chipCfg structure to allocate memory, parse the configuration information, and mount the parsed data. */ + chipCfg = ChipConfigInstance(device); + ... + /* Instantiate the touchscreen device. */ + chipDev = ChipDeviceInstance(); + ... + /* Mount touchscreen chip configuration and private operation data. */ + chipDev->chipCfg = chipCfg; + chipDev->ops = &g_gt911ChipOps; + ... + /* Register the chip driver with the platform driver. */ + RegisterChipDevice(chipDev); + ... + } + struct HdfDriverEntry g_touchGoodixChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_GT911", // The value must match the moduleName field of the chip driver in the device_info.hcs file. + .Init = HdfGoodixChipInit, // Initialize the touchscreen chip driver. + }; + HDF_INIT(g_touchGoodixChipEntry); // Register the touchscreen chip driver with the HDF. + ``` + + The private chip drivers present the major differentiations among chip vendors, such as hibernation and wakeup, data parsing, and firmware update. + + Now, you have completed the adaptation for the touchscreen driver based on the HDF and input driver model. + + +## Building Source Code and Burning Images + +1. Compile the Makefile. + + Open the file at **./drivers/adapter/khdf/linux/model/input/Makefile**. + + Add the following content: + + ``` + obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \ + $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o + ``` + + **touch\_gt911.o** is the content added in this example. + +2. Build source code and burn images. For details, see the related sections in [Getting Started for Standard System](../nottoctopics/en-us_topic_0000001135402541.md#section375234715135). + +## Debugging and Verification + +The following is part of the startup log: + +``` +[I/HDF_INPUT_DRV] HdfInputManagerInit: enter // Initialize the input device manager. +[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // The initialization is successful. +[I/osal_cdev] add cdev hdf_input_host success +[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // Initialize the input common driver. +[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // The initialization is successful. +[I/osal_cdev] add cdev hdf_input_event1 success +[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // Initialize the input chip driver. +[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060 +[I/HDF_INPUT_DRV] Product_ID: 911_1060, x_sol = 960, y_sol = 480 +[I/HDF_LOG_TAG] ChipDriverInit: chipDetect succ, ret = 0 +[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch +[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // The initialization is successful. +``` + +## Input Driver Model Workflow Analysis + +To help you get familiarized with the working process of the input driver model, the following sections will describe the key code loaded by the input driver model. + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>You do not need to perform development related to the input driver model. + +### Parsing Private Configuration Data + +You can obtain the sample code at **./drivers/framework/model/input/driver/input\_config\_parser.c**. + +The configuration parsing functions provided by the OSAL can parse the fields in the **hcs** file. For details, see the implementation of each function in **input\_config\_parser.c**. If the provided template cannot meet business requirements, add required information to the **hcs** file and then develop parsing functions based on the added fields. + +``` +static int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode, BoardAttrCfg *attr) +{ + int32_t ret; + ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0); // Obtain the inputType field and save it in the BoardAttrCfg structure. + CHECK_PARSER_RET(ret, "GetUint8"); + ... + return HDF_SUCCESS; +} +``` + +### Initializing the Input Device Manager and Registering the Driver with the HDF + +You can obtain the sample code at **./drivers/framework/model/input/driver/hdf\_input\_device\_manager.c**. + +``` +static int32_t HdfInputManagerInit(struct HdfDeviceObject *device) +{ + /* Allocate memory to the device manager, which will store all input devices. */ + g_inputManager = InputManagerInstance(); + ... +} +struct HdfDriverEntry g_hdfInputEntry = { + .moduleVersion = 1, + .moduleName = "HDF_INPUT_MANAGER", + .Bind = HdfInputManagerBind, + .Init = HdfInputManagerInit, + .Release = HdfInputManagerRelease, +}; + +HDF_INIT(g_hdfInputEntry); // Driver input entry +``` + +### Initializing the Input Common Driver and Registering the Driver with the HDF + +You can obtain the sample code at **./drivers/framework/model/input/driver/hdf\_touch.c**. + +``` +static int32_t HdfTouchDriverProbe(struct HdfDeviceObject *device) +{ + ... + /* Use the boardCfg structure to allocate memory and parse the configuration information obtained from the HCS. */ + boardCfg = BoardConfigInstance(device); + ... + /* Allocate memory in the touchDriver structure. */ + touchDriver = TouchDriverInstance(); + ... + /* Initialize common resources based on the parsed board-level information, such as IIC initialization. */ + ret = TouchDriverInit(touchDriver, boardCfg); + if (ret == HDF_SUCCESS) { + ... + /* Add the driver to the common driver management linked list, which is used to query the driver after it is bound to the device. */ + AddTouchDriver(touchDriver); + ... + } + ... +} +struct HdfDriverEntry g_hdfTouchEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH", + .Bind = HdfTouchDriverBind, + .Init = HdfTouchDriverProbe, + .Release = HdfTouchDriverRelease, +}; + + HDF_INIT(g_hdfTouchEntry); // Driver input entry +``` + +### Initializing the Input Chip Driver and Registering the Driver with the HDF + +For details, see related content in [Adapting to the Private Drivers of the Touchscreen](#section17127331595). + +### Function Invocation Logic + +The init function of the input device manager initializes the device management linked list, and the init function of the common driver allocates memory for related structures. The **RegisterChipDevice** function passes touchscreen chip driver information to the related structures of the input common driver and initializes hardware information \(for example, interrupt registration\). The **RegisterInputDevice** function registers **inputDev** \(binding the device and the driver\) with the device manager. The **RegisterInputDevice** function adds **inputDev** to the device management linked list. The function implementation is as follows: + +``` +// Code location: ./drivers/framework/model/input/driver/hdf_touch.c +int32_t RegisterChipDevice(ChipDevice *chipDev) +{ + ... + /* Bind the device to the driver and create an inputDev instance using InputDeviceInstance. */ + DeviceBindDriver(chipDev); + ... + /* Implement the interrupt registration and interrupt handling functions. The interrupt handling function contains the channel for reporting data to the user space. */ + ChipDriverInit(chipDev); + ... + /* Allocate memory for instantiating inputDev. */ + inputDev = InputDeviceInstance(chipDev); + ... + /* Register inputDev with the input device manager. */ + RegisterInputDevice(inputDev); + ... +} + +// Code location: ./drivers/framework/model/input/driver/hdf_input_device_manager.c +int32_t RegisterInputDevice(InputDevice *inputDev) +{ + ... + /* Allocate a device ID, which is unique for each input device. */ + ret = AllocDeviceID(inputDev); + ... + /* This function contains special processing for hid devices but does nothing for the touchscreen driver. */ + CreateDeviceNode(inputDev); + /* Apply for the buffer for the IOService capability, which is required to transmit kernel-space data to the user space. */ + AllocPackageBuffer(inputDev); + /* Add the input device to the global device management linked list. */ + AddInputDevice(inputDev); + ... +} +``` + diff --git a/en/device-dev/guide/device-wifi-led-outcontrol.md b/en/device-dev/guide/device-wifi-led-outcontrol.md new file mode 100644 index 0000000000000000000000000000000000000000..af9d86a4d2b7b3b514e02d41b2e0949fc386cc50 --- /dev/null +++ b/en/device-dev/guide/device-wifi-led-outcontrol.md @@ -0,0 +1,110 @@ +# LED Peripheral Control + +- [Overview](#section14639174516337) +- [Development](#section13857170163412) +- [Verification](#section1949121910344) + +## Overview + +Based on the Hi3861 platform, the OpenHarmony WLAN module provides abundant peripheral operation capabilities, including the I2C, I2S, ADC, UART, SPI, SDIO, GPIO, PWM, and flash memory. This document describes how to control GPIO pins by calling the OpenHarmony native development kit \(NDK\) interface to implement LED blinking. For details about how to control other IoT peripherals, see the API guide. + +## Development + +1. Complete the operations described in [Getting Started with Hi3861](../quick-start/quickstart-lite-introduction-hi3861.md#section19352114194115). + + LED control examples are stored in the file **applications/sample/wifi-iot/app/iothardware/led\_example.c**. + +2. Understand the cable connections by referring to the schematic diagram. You can learn that LED of hispark pegasus is connected to pin 9 of the chip. + + ``` + #define LED_TEST_GPIO 9 + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >For details about the schematic diagram of the development board, contact the Hi3861 customer service personnel. + +3. Initialize the GPIO pin, specify the pin usage, and create a task to turn on or off the LED periodically so that the LED blinks. + + ``` + static void LedExampleEntry(void) + { + osThreadAttr_t attr; + + /* Initialize the GPIO pin. */ + IoTGpioInit(LED_TEST_GPIO); + /* Set pin 9 as the output direction. */ + IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT); + + attr.name = "LedTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = LED_TASK_STACK_SIZE; + attr.priority = LED_TASK_PRIO; + + /* Start the task. */ + if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) { + printf("[LedExample] Failed to create LedTask!\n"); + } + } + ``` + +4. Use a cyclic task in which the LED periodically turns on and off to implement LED blinking. + + ``` + static void *LedTask(const char *arg) + { + (void)arg; + while (1) { + switch (g_ledState) { + case LED_ON: + IoTGpioSetOutputVal(LED_TEST_GPIO, 1); + usleep(LED_INTERVAL_TIME_US); + break; + case LED_OFF: + IoTGpioSetOutputVal(LED_TEST_GPIO, 0); + usleep(LED_INTERVAL_TIME_US); + break; + case LED_SPARK: + IoTGpioSetOutputVal(LED_TEST_GPIO, 0); + usleep(LED_INTERVAL_TIME_US); + IoTGpioSetOutputVal(LED_TEST_GPIO, 1); + usleep(LED_INTERVAL_TIME_US); + break; + default: + usleep(LED_INTERVAL_TIME_US); + break; + } + } + return NULL; + } + ``` + +5. Call **SYS\_RUN\(\)** of OpenHarmony to start the service. \(**SYS\_RUN** is defined in the **ohos\_init.h** file.\) + + ``` + SYS_RUN(LedExampleEntry); + ``` + +6. Change the **applications/sample/wifi-iot/app/BUILD.gn** file to enable **led\_example.c** to participate in compilation. + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("app") { + features = [ + "iothardware:led_example" + ] + } + ``` + + +## Verification + +For details about the compilation and burning processes, see [Building Source Code](../quick-start/quickstart-lite-steps-board3861-connection.md#section191121332125319) and [Burning Images](../quick-start/quickstart-lite-steps-board3861-connection.md#section19458165166) in the _Getting Started with Hi3861_. + +After the preceding two steps are complete, press the **RST** button to reset the module. If the LED blinks periodically as expected, the verification is passed. + +**Figure 1** LED blinking +![](figure/led-blinking.gif "led-blinking") + diff --git a/en/device-dev/guide/device-wifi-sdk.md b/en/device-dev/guide/device-wifi-sdk.md new file mode 100644 index 0000000000000000000000000000000000000000..dee530d9b864c0a98ddcde0288576294c69769f5 --- /dev/null +++ b/en/device-dev/guide/device-wifi-sdk.md @@ -0,0 +1,325 @@ +# Third-Party SDK Integration + +- [Planning a Directory Structure](#section1736472718351) +- [Building the Service libs](#section442815485351) +- [Compiling Adaptation Code](#section3984721113613) +- [Compiling Code](#section830417531286) +- [Compiling a Script](#section13500201173710) +- [Compiling Service Code](#section8754114803918) +- [Runtime](#section7737749184012) +- [End](#section153301392411) + +To build a more open and complete Internet of Things \(IoT\) ecosystem, OpenHarmony has opened up a group of directories to integrate SDKs provided by different vendors. This guide describes how to integrate SDKs into OpenHarmony based on the Hi3861 board. + +## Planning a Directory Structure + +A third-party SDK consists of a static library and the adaption code. The SDK service logic is compiled to obtain the static library **libs** through the hardware module tool chain. Each module has its corresponding **libs**. The southbound APIs of the SDK are different from the APIs of OpenHarmony. The difference can be shielded by using the adaptation code **adapter**. Different modules can share the same **adapter**. + +Based on the preceding features, third-party SDK directories can be divided as follows in the OpenHarmony directory structure: + +- domains/iot/link/: The **adapter** is stored in this directory and is decoupled from the module. +- device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/: The service library **libs** is stored in this directory and is bound to the module. + +You must perform the following steps before adaptation. The following uses the demolink SDK as an example. + +1. Create vendor directories, **domains/iot/link/demolink/** and **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/**, to isolate different vendors. +2. Create the **domains/iot/link/demolink/BUILD.gn** file to build the adaptation code. +3. Create the **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/** directory to store the service library **libs**. + +``` +. +├── domains +│ └── iot +│ └── link +│ ├── demolink +│ │ └── BUILD.gn +│ ├── libbuild +│ │ └── BUILD.gn +│ └── BUILD.gn +└── device + └── hisilicon + └── hispark_pegasus + └── sdk_liteos + └── 3rd_sdk + └── demolink + └── libs +``` + +## Building the Service **libs** + +Generally, the platform SDK service is provided as a static library. After obtaining the OpenHarmony code, the platform vendor needs to compile the service library **libs** based on the corresponding hardware module vendor and save the compilation result to the **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/** directory. The following describes how to build the service library **libs**. + +OpenHarmony has planned the **domains/iot/link/libbuild/** directory for compiling the service library **libs**. This directory contains the **domains/iot/link/libbuild/BUILD.gn** and **domains/iot/link/BUILD.gn** files. The directory structure is as follows: + +``` +. +└── domains + └── iot + └── link + ├── demolink + │ └── BUILD.gn + ├── libbuild + │ └── BUILD.gn + └── BUILD.gn +``` + +Before building **libs**, you must perform the following steps: + +1. Place the service source code files \(including **.c** and **.h** files\) in the **domains/iot/link/libbuild/** directory. + + ``` + . + └── domains + └── iot + └── link + ├── demolink + │ ├── demosdk_adapter.c + │ ├── demosdk_adapter.h + │ └── BUILD.gn + ├── libbuild + │ ├── demosdk.c + │ ├── demosdk.h + │ └── BUILD.gn + └── BUILD.gn + ``` + +2. Adapt to the **domains/iot/link/libbuild/BUILD.gn** file and restore the file after the compilation is complete. + + In the **BUILD.gn** file, **sources** specifies the source file to build and **include\_dirs** specifies the path of the dependent header file so that the target build result is the static library **libdemosdk.a**. + + ``` + static_library("demosdk") { + sources = [ + "demosdk.c" + ] + include_dirs = [ + "//domains/iot/link/libbuild", + "//domains/iot/link/demolink" + ] + } + ``` + +3. Adapt to the **domains/iot/link/BUILD.gn** file and restore the file after the compilation is complete. + + The **BUILD.gn** file is used to specify build entries. You need to enter all static library entries to be compiled in **features** so that the **domains/iot/link/libbuild/BUILD.gn** file is used in the build. + + ``` + import("//build/lite/config/subsystem/lite_subsystem.gni") + import("//build/lite/config/component/lite_component.gni") + lite_subsystem("iot") { + subsystem_components = [ + ":link" + ] + } + lite_component("link") { + features = [ + "libbuild:demosdk" + ] + } + ``` + + +After the preceding operations are complete, run the **hb build -T //domains/iot/link:iot** command in the root directory of the code and then check whether the target library file is generated in the **out/hispark\_pegasus/wifiiot\_hispark\_pegasus/libs/** directory. + +![](figure/en-us_image_0000001078563230.png) + +Copy the library file to the **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/** directory and delete the **.c** and **.h** files from the **domains/iot/link/libbuild/** directory. + +## Compiling Adaptation Code + +## Compiling Code + +The APIs used in the platform SDK are different from the OpenHarmony APIs and cannot be directly used. Therefore, the adaptation code **adapter** is required for intermediate conversion. This section uses **DemoSdkCreateTask** in **domains/iot/link/demolink/demosdk\_adapter.c** as an example to describe how to compile adaptation code on OpenHarmony. + +1. Check the description, parameters, and return values of the **DemoSdkCreateTask** API to adapt. + + ``` + struct TaskPara { + char *name; + void *(*func)(char* arg); + void *arg; + unsigned char prio; + unsigned int size; + }; + + /* + * Create a thread for the IoT OS. + * Returns 0 if the operation is successful; returns a non-zero value otherwise. + */ + int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para); + ``` + +2. Check the OpenHarmony API document, select an API with similar features, and compare the parameters and usage. This guide uses **osThreadNew** as an example. By comparing this API with **DemoSdkCreateTask**, you can find that the parameters on which the two APIs depend are basically the same, but the structures to which the parameters belong are different. + + ``` + typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) + } osThreadAttr_t; + + /// Create a thread and add it to Active Threads. + /// \param[in] func thread function. + /// \param[in] argument pointer that is passed to the thread function as start argument. + /// \param[in] attr thread attributes; NULL: default values. + /// \return thread ID for reference by other functions or NULL in case of error. + osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + ``` + +3. Perform code adaptation to shield the difference. + + ``` + int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para) + { + osThreadAttr_t attr = {0}; + osThreadId_t threadId; + if (handle == 0 || para == 0) { + return DEMOSDK_ERR; + } + if (para->func == 0) { + return DEMOSDK_ERR; + } + if (para->name == 0) { + return DEMOSDK_ERR; + } + attr.name = para->name; + attr.priority = para->prio; + attr.stack_size = para->size; + threadId = osThreadNew((osThreadFunc_t)para->func, para->arg, &attr); + if (threadId == 0) { + printf("osThreadNew fail\n"); + return DEMOSDK_ERR; + } + *(unsigned int *)handle = (unsigned int)threadId; + return DEMOSDK_OK; + } + ``` + + +## Compiling a Script + +After completing code adaptation, create the **BUILD.gn** file in the directory where the **adapter** is located. This file can be used to compile the adaptation code into a static library and link the static library to the **bin** package during the entire package build. In the **domains/iot/link/demolink/BUILD.gn** file, **sources** specifies the source files to be used in the build and **include\_dirs** specifies the path of the dependent header file so that the target build result is the static library **libdemolinkadapter.a**. + +``` +import("//build/lite/config/component/lite_component.gni") +static_library("demolinkadapter") { + sources = [ + "demosdk_adapter.c" + ] + include_dirs = [ + "//kernel/liteos-m/kal/cmsis", + "//domains/iot/link/demolink" + ] +} +``` + +Modify the **domains/iot/link/BUILD.gn** file so that the **domain/iot/hilink/BUILD.gn** file is used in the build. + +``` +import("//build/lite/config/subsystem/lite_subsystem.gni") +import("//build/lite/config/component/lite_component.gni") +lite_subsystem("iot") { + subsystem_components = [ + ":link" + ] +} +lite_component("link") { + features = [ + "demolink:demolinkadapter" + ] +} +``` + +## Compiling Service Code + +After the service library **libs** and adaptation code are ready, compile the service entry function to call the service entry of the third-party SDK. + +The following uses **demolink** as an example to describe how to compile code in **applications/sample/wifi-iot/app/** to call the **demosdk** entry function. + +1. Create a directory. + + Before compiling a service, you must create a directory \(or a directory structure\) in **applications/sample/wifi-iot/app/** to store service source code files. + + For example, add the service directory **demolink** to the app, and create the service entry code **helloworld.c** and compile the **BUILD.gn** file. + + ``` + . + └── applications + └── sample + └── wifi-iot + └── app + │── demolink + │ │── helloworld.c + │ └── BUILD.gn + └── BUILD.gn + ``` + +2. Compile service code. + + Compile the service entry function **DemoSdkMain** in the **helloworld.c** file, call the service entry **DemoSdkEntry** of **demolink**, and call the entry function through **SYS\_RUN\(\)** to start the service. + + ``` + #include "hos_init.h" + #include "demosdk.h" + + void DemoSdkMain(void) + { + DemoSdkEntry(); + } + + SYS_RUN(DemoSdkMain); + ``` + +3. Compile build scripts. + + Add the **applications/sample/wifi-iot/app/demolink/BUILD.gn** file, specify the paths of the source code and header file, and compile the static library file **libexample\_demolink.a**. + + ``` + static_library("example_demolink") { + sources = [ + "helloworld.c" + ] + include_dirs = [ + "//utils/native/lite/include", + "//domains/iot/link/libbuild" + ] + } + ``` + + Modify the **applications/sample/wifi-iot/app/BUILD.gn** file so that **demolink** is used in compilation. + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("app") { + features = [ + "demolink:example_demolink" + ] + } + ``` + + +## Runtime + +Run the **hb build** command in the root directory of the code to compile and output the version package. Start **demolink**. The following shows the running result, which is consistent with the expected result of **demolink**. + +``` +ready to OS start +sdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00 +formatting spiffs... +FileSystem mount ok. +wifi init success! +it is demosdk entry. +it is demo biz: hello world. +it is demo biz: hello world. +``` + +## End + +The third-party SDK integration is complete. + diff --git a/en/device-dev/guide/device-wifi.md b/en/device-dev/guide/device-wifi.md new file mode 100644 index 0000000000000000000000000000000000000000..73a5fc8cae7ea60dd1612b47fe8f8352688876db --- /dev/null +++ b/en/device-dev/guide/device-wifi.md @@ -0,0 +1,7 @@ +# WLAN-connected Products + +- **[LED Peripheral Control](device-wifi-led-outcontrol.md)** + +- **[Third-Party SDK Integration](device-wifi-sdk.md)** + + diff --git a/en/device-dev/guide/device.md b/en/device-dev/guide/device.md new file mode 100644 index 0000000000000000000000000000000000000000..bbce9d52a9d027aed593e2dbe2e7d7ad69a95405 --- /dev/null +++ b/en/device-dev/guide/device.md @@ -0,0 +1,15 @@ +# Device Development Guidelines + +- **[WLAN-connected Products](device-wifi.md)** + +- **[Cameras Without a Screen](device-iotcamera.md)** + +- **[Cameras with a Screen](device-camera.md)** + +- **[Development Guidelines on Clock Apps](oem_device_clockapp_des.md)** + +- **[Development Example for Platform Drivers](device-driver-demo.md)** + +- **[Development Example for Peripheral Drivers](device-outerdriver-demo.md)** + + diff --git a/en/device-dev/guide/faqs-10.md b/en/device-dev/guide/faqs-10.md deleted file mode 100644 index b9828da1546f7dc0a067b0dc0a684bd33cc30e57..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/faqs-10.md +++ /dev/null @@ -1,39 +0,0 @@ -# FAQs - -- [hdc\_std Fails to Connect to a Device](#section1221016541119) -- [hdc\_std Fails to Run](#section219185710311) - -## hdc\_std Fails to Connect to a Device - -- **Symptom** - - **\[Empty\]** is displayed in the output after the **hdc\_std list targets** command is run. - -- **Possible Causes and Solutions** - 1. The device cannot be identified. - - Check whether **HDC Device** exists in the universal serial bus device of the device manager. If **HDC Device** does not exist, the device cannot be connected. In this case, remove and then insert the device or burn the latest image for the device. - - 2. hdc\_std works improperly. - - Run the **hdc kill** or **hdc start -r** command to kill or restart the hdc service, and then run the **hdc list targets** command to check whether device information is obtained. - - If no device information is obtained, check whether the adb process exists in the task manager. If the adb process exists, kill this process because it may affect the hdc service. After that, run **hdc kill** or **hdc start -r** and then **hdc list targets** again. - - 3. hdc\_std does not match the device. - - If the latest image is burnt for the device, hdc\_std must also be of the latest version. As hdc\_std is updated continuously, obtain hdc\_std of the latest version from the **developtools\_hdc\_standard** repository in the **prebuilt** directory. - - - -## hdc\_std Fails to Run - -- **Symptom** - - The **hdc\_std.exe** file does not run after being clicked. - -- **Possible Causes and Solutions** - - **hdc\_std.exe** requires no installation and can be directly used on a disk. It can also be added to environment variables. Open the cmd window and run the **hdc\_std** command to use **hdc\_std.exe**. - - diff --git a/en/device-dev/guide/figures/adding-a-page.png b/en/device-dev/guide/figure/adding-a-page.png similarity index 100% rename from en/device-dev/guide/figures/adding-a-page.png rename to en/device-dev/guide/figure/adding-a-page.png diff --git a/en/device-dev/guide/figures/clock.png b/en/device-dev/guide/figure/clock.png similarity index 100% rename from en/device-dev/guide/figures/clock.png rename to en/device-dev/guide/figure/clock.png diff --git a/en/device-dev/guide/figures/complete-project-directory.png b/en/device-dev/guide/figure/complete-project-directory.png similarity index 100% rename from en/device-dev/guide/figures/complete-project-directory.png rename to en/device-dev/guide/figure/complete-project-directory.png diff --git a/en/device-dev/guide/figures/en-us_image_0000001078563230.png b/en/device-dev/guide/figure/en-us_image_0000001078563230.png similarity index 100% rename from en/device-dev/guide/figures/en-us_image_0000001078563230.png rename to en/device-dev/guide/figure/en-us_image_0000001078563230.png diff --git a/en/device-dev/guide/figures/en-us_image_0000001082434703.png b/en/device-dev/guide/figure/en-us_image_0000001082434703.png similarity index 100% rename from en/device-dev/guide/figures/en-us_image_0000001082434703.png rename to en/device-dev/guide/figure/en-us_image_0000001082434703.png diff --git a/en/device-dev/guide/figures/en-us_image_0000001161922745.png b/en/device-dev/guide/figure/en-us_image_0000001169991055.png similarity index 100% rename from en/device-dev/guide/figures/en-us_image_0000001161922745.png rename to en/device-dev/guide/figure/en-us_image_0000001169991055.png diff --git a/en/device-dev/guide/figures/entering-the-page-name.png b/en/device-dev/guide/figure/entering-the-page-name.png similarity index 100% rename from en/device-dev/guide/figures/entering-the-page-name.png rename to en/device-dev/guide/figure/entering-the-page-name.png diff --git a/en/device-dev/guide/figures/home-screen.png b/en/device-dev/guide/figure/home-screen.png similarity index 100% rename from en/device-dev/guide/figures/home-screen.png rename to en/device-dev/guide/figure/home-screen.png diff --git a/en/device-dev/guide/figures/indicator-bar.png b/en/device-dev/guide/figure/indicator-bar.png similarity index 100% rename from en/device-dev/guide/figures/indicator-bar.png rename to en/device-dev/guide/figure/indicator-bar.png diff --git a/en/device-dev/guide/figures/led-blinking.gif b/en/device-dev/guide/figure/led-blinking.gif similarity index 100% rename from en/device-dev/guide/figures/led-blinking.gif rename to en/device-dev/guide/figure/led-blinking.gif diff --git a/en/device-dev/guide/figures/preview-effect.jpg b/en/device-dev/guide/figure/preview-effect.jpg similarity index 100% rename from en/device-dev/guide/figures/preview-effect.jpg rename to en/device-dev/guide/figure/preview-effect.jpg diff --git a/en/device-dev/guide/figures/project-directory.png b/en/device-dev/guide/figure/project-directory.png similarity index 100% rename from en/device-dev/guide/figures/project-directory.png rename to en/device-dev/guide/figure/project-directory.png diff --git a/en/device-dev/guide/figures/saved-files.png b/en/device-dev/guide/figure/saved-files.png similarity index 100% rename from en/device-dev/guide/figures/saved-files.png rename to en/device-dev/guide/figure/saved-files.png diff --git a/en/device-dev/guide/figures/serial-port-logs-displayed-after-the-exit-command-is-executed.png b/en/device-dev/guide/figure/serial-port-logs-displayed-after-the-exit-command-is-executed.png similarity index 100% rename from en/device-dev/guide/figures/serial-port-logs-displayed-after-the-exit-command-is-executed.png rename to en/device-dev/guide/figure/serial-port-logs-displayed-after-the-exit-command-is-executed.png diff --git a/en/device-dev/guide/figures/serial-port-logs-displayed-after-the-photographing-command-is-executed.png b/en/device-dev/guide/figure/serial-port-logs-displayed-after-the-photographing-command-is-executed.png similarity index 100% rename from en/device-dev/guide/figures/serial-port-logs-displayed-after-the-photographing-command-is-executed.png rename to en/device-dev/guide/figure/serial-port-logs-displayed-after-the-photographing-command-is-executed.png diff --git a/en/device-dev/guide/figures/serial-port-logs-displayed-after-the-preview-command-is-executed.png b/en/device-dev/guide/figure/serial-port-logs-displayed-after-the-preview-command-is-executed.png similarity index 100% rename from en/device-dev/guide/figures/serial-port-logs-displayed-after-the-preview-command-is-executed.png rename to en/device-dev/guide/figure/serial-port-logs-displayed-after-the-preview-command-is-executed.png diff --git a/en/device-dev/guide/figures/serial-port-logs-displayed-after-the-recording-command-is-executed.png b/en/device-dev/guide/figure/serial-port-logs-displayed-after-the-recording-command-is-executed.png similarity index 100% rename from en/device-dev/guide/figures/serial-port-logs-displayed-after-the-recording-command-is-executed.png rename to en/device-dev/guide/figure/serial-port-logs-displayed-after-the-recording-command-is-executed.png diff --git a/en/device-dev/guide/figures/starting-camera_sample.png b/en/device-dev/guide/figure/starting-camera_sample.png similarity index 100% rename from en/device-dev/guide/figures/starting-camera_sample.png rename to en/device-dev/guide/figure/starting-camera_sample.png diff --git a/en/device-dev/guide/figures/title-bar-and-information-bar.png b/en/device-dev/guide/figure/title-bar-and-information-bar.png similarity index 100% rename from en/device-dev/guide/figures/title-bar-and-information-bar.png rename to en/device-dev/guide/figure/title-bar-and-information-bar.png diff --git a/en/device-dev/guide/figures/title-bar.png b/en/device-dev/guide/figure/title-bar.png similarity index 100% rename from en/device-dev/guide/figures/title-bar.png rename to en/device-dev/guide/figure/title-bar.png diff --git a/en/device-dev/guide/figures/video_2020-07-25_173141.gif b/en/device-dev/guide/figure/video_2020-07-25_173141.gif similarity index 100% rename from en/device-dev/guide/figures/video_2020-07-25_173141.gif rename to en/device-dev/guide/figure/video_2020-07-25_173141.gif diff --git "a/en/device-dev/guide/figures/\347\273\230\345\233\2761.png" "b/en/device-dev/guide/figure/\347\273\230\345\233\2761.png" similarity index 100% rename from "en/device-dev/guide/figures/\347\273\230\345\233\2761.png" rename to "en/device-dev/guide/figure/\347\273\230\345\233\2761.png" diff --git a/en/device-dev/guide/function-invocation-logic.md b/en/device-dev/guide/function-invocation-logic.md deleted file mode 100644 index 8f633c3a85a43be32973b50af8729acfeb0ea5ba..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/function-invocation-logic.md +++ /dev/null @@ -1,40 +0,0 @@ -# Function Invocation Logic - -The init function of the input device manager initializes the device management linked list, and the init function of the common driver allocates memory for related structures. The **RegisterChipDevice** function passes touchscreen chip driver information to the related structures of the input common driver and initializes hardware information \(for example, interrupt registration\). The **RegisterInputDevice** function registers **inputDev** \(binding the device and the driver\) with the device manager. The **RegisterInputDevice** function adds **inputDev** to the device management linked list. The function implementation is as follows: - -``` -// Code location: ./drivers/framework/model/input/driver/hdf_touch.c -int32_t RegisterChipDevice(ChipDevice *chipDev) -{ - ... - /* Bind the device to the driver and create an inputDev instance using InputDeviceInstance. */ - DeviceBindDriver(chipDev); - ... - /* Implement the interrupt registration and interrupt handling functions. The interrupt handling function contains the channel for reporting data to the user space. */ - ChipDriverInit(chipDev); - ... - /* Allocate memory for instantiating inputDev. */ - inputDev = InputDeviceInstance(chipDev); - ... - /* Register inputDev with the input device manager. */ - RegisterInputDevice(inputDev); - ... -} - -// Code location: ./drivers/framework/model/input/driver/hdf_input_device_manager.c -int32_t RegisterInputDevice(InputDevice *inputDev) -{ - ... - /* Allocate a device ID, which is unique for each input device. */ - ret = AllocDeviceID(inputDev); - ... - /* This function contains special processing for hid devices but does nothing for the touchscreen driver. */ - CreateDeviceNode(inputDev); - /* Apply for the buffer for the IOService capability, which is required to transmit kernel-space data to the user space. */ - AllocPackageBuffer(inputDev); - /* Add the input device to the global device management linked list. */ - AddInputDevice(inputDev); - ... -} -``` - diff --git a/en/device-dev/guide/hardware-resources.md b/en/device-dev/guide/hardware-resources.md deleted file mode 100644 index 5e93297911c69fdcd9ebaa6cb383c4761e5715b1..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/hardware-resources.md +++ /dev/null @@ -1,6 +0,0 @@ -# Hardware Resources - -The touchscreen integrated circuit \(IC\) provided by the Hi3516D V300 development board is GT911, which uses the standard inter-integrated circuit \(I2C\) to communicate with the development board and connects to the main board through the 6-pin flexible flat cable. The following figure shows the distribution of the 6 pins and their connection. - -![](figures/绘图1.png) - diff --git a/en/device-dev/guide/how-to-develop.md b/en/device-dev/guide/how-to-develop.md deleted file mode 100644 index 28b0a31d6c892bf82adf85b0bc86f2312812ad4b..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/how-to-develop.md +++ /dev/null @@ -1,230 +0,0 @@ -# How to Develop - -The Clock app displays the current time through a clock face and numbers. - -As shown in [Figure 1 Clock display effect](overview-7.md#fig7763172132019), the page consists of two parts: - -- Clock face area: displays a dynamic analog clock whose hands rotate accurately. -- Digital time area: displays the current time in numerals. - -To build such an app, we can create a page that has a flexible layout with two rows vertically arranged. The development procedure is as follows: - -1. Add a root **** to the **.hml** file. Note that each **.hml** file can contain only one root component. The example code is as follows: - - ``` -
-
- ``` - - **class="container"** indicates the style used by the component. The **container** is a style class defined in the **index.css** file. - - ``` - .container { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - } - ``` - - The height and width of the root component **** are set in the style class. Note that the height and width must be explicitly specified \(except for some components, such as ****\). Otherwise, the component may fail to display. In the **container** style class, the **flex-direction** attribute is set to **column**, which means that child components of **** are vertically arranged from top to bottom for implementing the flexible page layout. - -2. Implement clock hand rotation using the **** component. The **** component provides a stack container where child components are successively stacked and the latter one overwrites the previous one. - - Add a stack container to the root component. The example code is as follows: - - ``` -
- - - - - - -
- ``` - - **style="transform: rotate\(\{\{ second \* 6 \}\}deg\)** sets the rotation event of a component. **transform** translates, rotates, or scales an element. **rotate** rotates an element. You can set the element to rotate around its x-axis or y-axis. - - Set attributes, such as the height, width, and position, of the component in the CSS file. The example code is as follows: - - ``` - .stack { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 50%; - } - ``` - - Set attributes, such as the height and width, of the component in the CSS file. The example code is as follows: - - ``` - .clock-bg { - width: 80%; - height: 80%; - object-fit: scale-down; - } - ``` - - Set attributes, such as the height and width of the hour, minute, and second hands, of the component in the CSS file. The example code is as follows: - - ``` - .clock-hand { - width: 25%; - height: 65%; - object-fit: contain; - } - ``` - - Add a timer in the **index.js** file to update the hour, minute, and second variables in real time so that time can be automatically updated on the app UI. The example code is as follows: - - ``` - export default { - timer: undefined, - // Define parameters. - data: { - hour: 0, // Define hours. - minute: 0, // Define minutes. - second: 0 // Define seconds. - }, - onInit () { - this.updateTime(); - this.timer = setInterval(this.updateTime, 1000)// Set the update time of the timer to 1 second. - }, - updateTime: function () { - var nowTime = new Date() - this.hour = nowTime.getHours() - this.minute = nowTime.getMinutes() - this.second = nowTime.getSeconds() - if (this.hour < 10) { - this.hour = '0' + this.hour - } - if (this.minute < 10) { - this.minute = '0' + this.minute - } - if (this.second < 10) { - this.second = '0' + this.second - } - }, - } - ``` - -3. Display the current time in digital form under the analog clock. Add the **** component at the end of the root layout. The following example shows the page structure: - - ``` - {{ hour }}:{{ minute }}:{{ second }} - ``` - - **class="digit-clock"** sets the height, width, and font size of the component. The example code is as follows: - - ``` - .digit-clock { - font-size: 58px; - width: 100%; - margin-top: 0px; - text-align: center; - } - ``` - -4. Set the style, animation effect, and dynamic data binding for all components. The complete example code is as follows: - - - **index.hml** - - ``` -
- - - - - - - {{ hour }}:{{ minute }}:{{ second }} -
- ``` - - - **index.css** - - ``` - .container { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - } - - .stack { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 50%; - } - - .digit-clock { - font-size: 58px; - width: 100%; - margin-top: 0px; - text-align: center; - } - - .clock-bg { - width: 80%; - height: 80%; - object-fit: scale-down; - } - - .clock-hand { - width: 25%; - height: 65%; - object-fit: contain; - } - ``` - - - **index.js** - - A **.js** file is used to implement interaction logic of your app. In the **.js** file of the page, implement the function of periodically obtaining the system time. - - ``` - export default { - timer: undefined, - data: { - hour: 0, - minute: 0, - second: 0 - }, - onInit() { - this.updateTime() - this.timer = setInterval(this.updateTime, 1000) - }, - updateTime: function () { - var nowTime = new Date() - this.hour = nowTime.getHours() - this.minute = nowTime.getMinutes() - this.second = nowTime.getSeconds() - if (this.hour < 10) { - this.hour = '0' + this.hour - } - if (this.minute < 10) { - this.minute = '0' + this.minute - } - if (this.second < 10) { - this.second = '0' + this.second - } - }, - onDestroy() { - clearInterval(this.timer); - } - } - ``` - - diff --git a/en/device-dev/guide/initializing-the-input-chip-driver-and-registering-the-driver-with-the-hdf.md b/en/device-dev/guide/initializing-the-input-chip-driver-and-registering-the-driver-with-the-hdf.md deleted file mode 100644 index 80abf74934cd632f99e0bf8dbd87f6097158b9a0..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/initializing-the-input-chip-driver-and-registering-the-driver-with-the-hdf.md +++ /dev/null @@ -1,4 +0,0 @@ -# Initializing the Input Chip Driver and Registering the Driver with the HDF - -For details, see step [Initialize the input chip driver and register the driver with the HDF](adapting-to-the-private-drivers-of-the-touchscreen.md). - diff --git a/en/device-dev/guide/initializing-the-input-common-driver-and-registering-the-driver-with-the-hdf.md b/en/device-dev/guide/initializing-the-input-common-driver-and-registering-the-driver-with-the-hdf.md deleted file mode 100644 index cf43752893cfad241dd78633c42c2957f6122d86..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/initializing-the-input-common-driver-and-registering-the-driver-with-the-hdf.md +++ /dev/null @@ -1,35 +0,0 @@ -# Initializing the Input Common Driver and Registering the Driver with the HDF - -You can obtain the sample code at **./drivers/framework/model/input/driver/hdf\_touch.c**. - -``` -static int32_t HdfTouchDriverProbe(struct HdfDeviceObject *device) -{ - ... - /* Use the boardCfg structure to allocate memory and parse the configuration information obtained from the HCS. */ - boardCfg = BoardConfigInstance(device); - ... - /* Allocate memory in the touchDriver structure. */ - touchDriver = TouchDriverInstance(); - ... - /* Initialize common resources based on the parsed board-level information, such as IIC initialization. */ - ret = TouchDriverInit(touchDriver, boardCfg); - if (ret == HDF_SUCCESS) { - ... - /* Add the driver to the common driver management linked list, which is used to query the driver after it is bound to the device. */ - AddTouchDriver(touchDriver); - ... - } - ... -} -struct HdfDriverEntry g_hdfTouchEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH", - .Bind = HdfTouchDriverBind, - .Init = HdfTouchDriverProbe, - .Release = HdfTouchDriverRelease, -}; - - HDF_INIT(g_hdfTouchEntry); // Driver registration entry -``` - diff --git a/en/device-dev/guide/initializing-the-input-device-manager-and-registering-the-driver-with-the-hdf.md b/en/device-dev/guide/initializing-the-input-device-manager-and-registering-the-driver-with-the-hdf.md deleted file mode 100644 index a8ebbf4a5de71f905ff090114d5541a7d46afbe3..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/initializing-the-input-device-manager-and-registering-the-driver-with-the-hdf.md +++ /dev/null @@ -1,22 +0,0 @@ -# Initializing the Input Device Manager and Registering the Driver with the HDF - -You can obtain the sample code at **./drivers/framework/model/input/driver/hdf\_input\_device\_manager.c**. - -``` -static int32_t HdfInputManagerInit(struct HdfDeviceObject *device) -{ - /* Allocate memory to the device manager, which will store all input devices. */ - g_inputManager = InputManagerInstance(); - ... -} -struct HdfDriverEntry g_hdfInputEntry = { - .moduleVersion = 1, - .moduleName = "HDF_INPUT_MANAGER", - .Bind = HdfInputManagerBind, - .Init = HdfInputManagerInit, - .Release = HdfInputManagerRelease, -}; - -HDF_INIT(g_hdfInputEntry); // Driver registration entry -``` - diff --git a/en/device-dev/guide/input-driver-model-workflow-analysis.md b/en/device-dev/guide/input-driver-model-workflow-analysis.md deleted file mode 100644 index c99c0617eaa8da4150494580902e215567c2dee2..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/input-driver-model-workflow-analysis.md +++ /dev/null @@ -1,18 +0,0 @@ -# Input Driver Model Workflow Analysis - -To help you get familiarized with the working process of the input driver model, the following sections will describe the key code loaded by the input driver model. - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->You do not need to perform development related to the input driver model. - -- **[Parsing Private Configuration Data](parsing-private-configuration-data.md)** - -- **[Initializing the Input Device Manager and Registering the Driver with the HDF](initializing-the-input-device-manager-and-registering-the-driver-with-the-hdf.md)** - -- **[Initializing the Input Common Driver and Registering the Driver with the HDF](initializing-the-input-common-driver-and-registering-the-driver-with-the-hdf.md)** - -- **[Initializing the Input Chip Driver and Registering the Driver with the HDF](initializing-the-input-chip-driver-and-registering-the-driver-with-the-hdf.md)** - -- **[Function Invocation Logic](function-invocation-logic.md)** - - diff --git a/en/device-dev/guide/input-driver-model.md b/en/device-dev/guide/input-driver-model.md deleted file mode 100644 index a4f2cdb3720235bcf0fd941caf6ae05c68792bd8..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/input-driver-model.md +++ /dev/null @@ -1,12 +0,0 @@ -# Input Driver Model - -The input driver model mainly consists of the device manager, common drivers, and chip drivers. - -- Input device manager: provides various input device drivers with the APIs for registering or unregistering input devices and manages the input device list. -- Input common driver: provides common drivers for initializing the board-level hardware, processing hardware interrupts, and registering input devices with the input device manager. -- Input chip driver: calls differentiated APIs reserved by the input platform driver to minimize the workload for input chip driver development. - -In addition, the input driver model implements functions for reporting input data and parsing input device configurations. - -For details about the input driver model, see [Touchscreen Overview](https://device.harmonyos.com/en/docs/develop/drive/oem_drive_touch_des-0000001052857350)[Touchscreen Overview](../driver/touchscreenoverview.md). - diff --git a/en/device-dev/guide/led-peripheral-control.md b/en/device-dev/guide/led-peripheral-control.md deleted file mode 100644 index abe05cea370b4b7743e120ce2207aa54834de1b1..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/led-peripheral-control.md +++ /dev/null @@ -1,9 +0,0 @@ -# LED Peripheral Control - -- **[Overview](overview.md)** - -- **[Development](development.md)** - -- **[Verification](verification.md)** - - diff --git a/en/device-dev/guide/oem_device_clockapp_des.md b/en/device-dev/guide/oem_device_clockapp_des.md new file mode 100644 index 0000000000000000000000000000000000000000..5a7836cea35b322fb0bc27c81d4f7b371a97482f --- /dev/null +++ b/en/device-dev/guide/oem_device_clockapp_des.md @@ -0,0 +1,332 @@ +# Development Guidelines on Clock Apps + +- [Overview](#section11522349121115) +- [Preparations](#section6592121861218) +- [How to Develop](#section19901741111312) +- [Signing and Packaging](#section10601181101516) +- [Running on the Real Device](#section092721731511) +- [FAQs](#section1122413460153) + - [hdc\_std Fails to Connect to a Device](#section1922725151614) + - [hdc\_std Fails to Run](#section15657547131615) + + +## Overview + +This document describes how to quickly set up a development environment \(using the Hi3516D V300 development board\) and develop a clock app running on OpenHarmony. You can click [here](https://gitee.com/openharmony/app_samples/tree/master/common/Clock) to obtain the sample code. + +The clock app displays the current time, as shown in the following figure. + +**Figure 1** Clock display effect + + +![](figure/clock.png) + +## Preparations + +Download and install DevEco Studio. For details, see the [HUAWEI DevEco Studio User Guide](../../application-dev/quick-start/deveco-studio-(openharmony)-user-guide.md). + +## How to Develop + +The Clock app displays the current time through a clock face and numbers. + +As shown in [Figure 1 Clock display effect](oem_device_clockapp_des.md#fig7763172132019), the UI consists of two parts: + +- Clock face area: displays a dynamic analog clock whose hands rotate accurately. +- Digital time area: displays the current time in numerals. + +To build such an app, we can create a page that has a flexible layout with two rows vertically arranged. The development procedure is as follows: + +1. Add a root component **** to the **.hml** file. Note that each **.hml** file can contain only one root component. The sample code is as follows: + + ``` +
+
+ ``` + + **class="container"** indicates the style used by the component. The **container** is a style class defined in the **index.css** file. + + ``` + .container { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + } + ``` + + The height and width of the root component **** are set in the style class. Note that the height and width must be explicitly specified \(except for some components, such as ****\). Otherwise, the component may fail to display. In the **container** style class, the **flex-direction** attribute is set to **column**, which means that child components of **** are vertically arranged from top to bottom for implementing the flexible page layout. + +2. Implement clock hand rotation using the **** component. The **** component provides a stack container where child components are successively stacked and the latter one overwrites the previous one. + + Add a stack container to the root component. The sample code is as follows: + + ``` +
+ + + + + + +
+ ``` + + **style="transform: rotate\(\{\{ second \* 6 \}\}deg\)** sets the rotation event of a component. **transform** translates, rotates, or scales an image. **rotate** rotates an image. You can set an image to rotate around its x-axis or y-axis. + + Set attributes, such as the height, width, and position, of the stack component in the CSS file. The sample code is as follows: + + ``` + .stack { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 50%; + } + ``` + + Set attributes, such as the height and width, of the clock-bg component in the CSS file. The sample code is as follows: + + ``` + .clock-bg { + width: 80%; + height: 80%; + object-fit: scale-down; + } + ``` + + Set attributes, such as the height and width of the hour, minute, and second hands, of the clock-hand component in the CSS file. The sample code is as follows: + + ``` + .clock-hand { + width: 25%; + height: 65%; + object-fit: contain; + } + ``` + + Add a timer in the **index.js** file to update the hour, minute, and second variables in real time so that the time can be automatically updated on the app UI. The sample code is as follows: + + ``` + export default { + timer: undefined, + // Define parameters. + data: { + hour: 0, // Define hours. + minute: 0, // Define minutes. + second: 0 // Define seconds. + }, + onInit () { + this.updateTime(); + this.timer = setInterval(this.updateTime, 1000)// Set the timer to 1 second. + }, + updateTime: function () { + var nowTime = new Date() + this.hour = nowTime.getHours() + this.minute = nowTime.getMinutes() + this.second = nowTime.getSeconds() + if (this.hour < 10) { + this.hour = '0' + this.hour + } + if (this.minute < 10) { + this.minute = '0' + this.minute + } + if (this.second < 10) { + this.second = '0' + this.second + } + }, + } + ``` + +3. Display the current time in numerals under the analog clock. Add the text component at the end of the root layout. The following example shows the UI structure: + + ``` + {{ hour }}:{{ minute }}:{{ second }} + ``` + + class=**"digit-clock"** sets the height, width, and font size of the component. The sample code is as follows: + + ``` + .digit-clock { + font-size: 58px; + width: 100%; + margin-top: 0px; + text-align: center; + } + ``` + +4. Set the style, animation effect, and dynamic data binding for all components. The complete sample code is as follows: + - **index.hml** + + ``` +
+ + + + + + + {{ hour }}:{{ minute }}:{{ second }} +
+ ``` + + + - **index.css** + + ``` + .container { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + } + + .stack { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 50%; + } + + .digit-clock { + font-size: 58px; + width: 100%; + margin-top: 0px; + text-align: center; + } + + .clock-bg { + width: 80%; + height: 80%; + object-fit: scale-down; + } + + .clock-hand { + width: 25%; + height: 65%; + object-fit: contain; + } + ``` + + + - **index.js** + + A **.js** file is used to implement logic interactions of the clock app. The following **.js** file implements the function of periodically obtaining the system time. + + ``` + export default { + timer: undefined, + data: { + hour: 0, + minute: 0, + second: 0 + }, + onInit() { + this.updateTime() + this.timer = setInterval(this.updateTime, 1000) + }, + updateTime: function () { + var nowTime = new Date() + this.hour = nowTime.getHours() + this.minute = nowTime.getMinutes() + this.second = nowTime.getSeconds() + if (this.hour < 10) { + this.hour = '0' + this.hour + } + if (this.minute < 10) { + this.minute = '0' + this.minute + } + if (this.second < 10) { + this.second = '0' + this.second + } + }, + onDestroy() { + clearInterval(this.timer); + } + } + ``` + + + +## Signing and Packaging + +After finishing writing the app code, you need to sign and package the app before running it on a real device. For details, see [Signing and Packaging Guide](../../application-dev/quick-start/configuring-the-openharmony-app-signature.md). + +## Running on the Real Device + +Before you install the app and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/tool_install-0000001050164976). Burn OpenHarmony into the development board, and run it on the board. For details about how to build, burn, and run an image, see [Getting Started with Hi3516](../quick-start/quickstart-standard.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the app: + +1. Obtain the HDC client from the following path: + + ``` + developtools/hdc_standard/prebuilt/windows/hdc_std.exe + ``` + + Change the HDC client name to **hdc.exe** and add the path above to the system environment variable **path**. + +2. Open the **cmd** window, and run the following commands to push the HAP file to the device directory, and install it: + + ``` + hdc smode + hdc target mount + hdc file send clock.hap /data/clock.hap + hdc shell chmod 666 /data/clock.hap + hdc shell bm install -p /data/clock.hap + ``` + +3. Run the following command to start the app. **ohos.samples.clock** indicates the app package name, and **MainAbility** indicates the ability started by the app. + + ``` + hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock + ``` + +4. \(Optional\) Run the following command to uninstall the app. **ohos.samples.clock** indicates the app package name. + + ``` + hdc shell bm uninstall -n ohos.samples.clock + ``` + + +## FAQs + +### hdc\_std Fails to Connect to a Device + +- **Symptom** + + **\[Empty\]** is displayed in the output after the **hdc\_std list targets** command is run. + +- **Possible Causes and Solutions** + 1. The device fails to be identified. + + Check whether **HDC Device** exists in the universal serial bus device of the device manager. If **HDC Device** does not exist, the device cannot be connected. In this case, remove and then insert the device or burn the latest image for the device. + + 2. hdc\_std works improperly. + + Run the **hdc kill** or **hdc start -r** command to kill or restart the HDC service, and then run the **hdc list targets** command to check whether device information is obtained. + + 3. hdc\_std does not match the device. + + If the latest image is burnt for the device, hdc\_std must also be of the latest version. As hdc\_std is updated continuously, obtain hdc\_std of the latest version from the **developtools\_hdc\_standard** repository in the **prebuilt** directory. + + + +### hdc\_std Fails to Run + +- **Symptom** + + The **hdc\_std.exe** file does not run after being clicked. + +- **Possible Causes and Solutions** + + **hdc\_std.exe** requires no installation and can be directly used on a disk. It can also be added to environment variables. Open the **cmd** window and run the **hdc\_std** command to use **hdc\_std.exe**. + + diff --git a/en/device-dev/guide/overview-0.md b/en/device-dev/guide/overview-0.md deleted file mode 100644 index 39a2eba2ffd3e70fa55b95840b2ff05f0893243c..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/overview-0.md +++ /dev/null @@ -1,10 +0,0 @@ -# Overview - -This document describes how to use the IoT camera development board and the built-in camera of the development kit to implement photographing and video recording. - -You can perform operations provided in [Use Case](use-case.md) to learn more about development board peripheral control and then develop devices such as cameras. - -If you want to view the sample effect first, see [Use Case](use-case.md). To customize application behavior, modify the sample code by referring to APIs described in the next section. - -For details about basic concepts for camera development, see the [camera development overview](../subsystems/overview.md). - diff --git a/en/device-dev/guide/overview-1.md b/en/device-dev/guide/overview-1.md deleted file mode 100644 index fb22f918ac419c6783e78bca66a00fb332b9bcad..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/overview-1.md +++ /dev/null @@ -1,10 +0,0 @@ -# Overview - -This document describes how to use the IoT camera development board \(Hi3516D V300\) and its camera and screen to implement photographing, video recording, and video preview. - -This document helps you take a deep dive into OpenHarmony camera control. With this reference, you can develop devices, such as peephole cameras, smart rear-view mirrors, and smart displays. - -If you want to view the running effect first, see [Use Case](use-case-5.md). To customize application behavior, modify the sample code by referring to APIs described in the "Development Guidelines" section. - -For basic concepts of camera development, see [Camera Development Overview](../subsystems/overview.md). - diff --git a/en/device-dev/guide/overview-10.md b/en/device-dev/guide/overview-10.md deleted file mode 100644 index f2936c824fa1dc1ddee20998e9501f350f205651..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/overview-10.md +++ /dev/null @@ -1,26 +0,0 @@ -# Overview - -- [When to Use](#section191543223549) - -This document uses the I2C driver as an example to describe how to develop platform drivers based on the hardware driver foundation \(HDF\). - ->![](public_sys-resources/icon-caution.gif) **CAUTION:** ->The sample code in this document is for reference only and cannot be directly used for commercial integration. - -## When to Use - -The HDF provides a standard driver framework for common peripherals. To use the APIs provided by the HDF to perform operations on peripherals, you only need to adapt the specific driver to the HDF. - -In this example, an I2C driver is used. [Figure 1](#fig148041484161) shows the sequence diagram of the I2C driver. - -**Figure 1** I2C driver sequence diagram - - -![](figures/en-us_image_0000001161922745.png) - -- User Business: business-triggered driver -- i2cManagerEntry: entry to the I2C manager, which is used to register the I2C manager with the HDF -- I2cManager: I2C manager, which manages the I2C controller -- I2cCntlr: I2C controller -- i2cDriverEntry: entry to the I2C controller, which is used to register the I2C controller with the HDF - diff --git a/en/device-dev/guide/overview-13.md b/en/device-dev/guide/overview-13.md deleted file mode 100644 index 608d2272089797a51ae741056816d32d5028c113..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/overview-13.md +++ /dev/null @@ -1,9 +0,0 @@ -# Overview - -This document describes how to develop a touchscreen driver on the Hi3516D V300 development board using the HDF input driver model, helping you quickly get started with peripheral driver development. - -- **[Hardware Resources](hardware-resources.md)** - -- **[Input Driver Model](input-driver-model.md)** - - diff --git a/en/device-dev/guide/overview-6.md b/en/device-dev/guide/overview-6.md deleted file mode 100644 index 13a514937591a52c53f35897110ab7d949505d7a..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/overview-6.md +++ /dev/null @@ -1,15 +0,0 @@ -# Overview - -- [Display Effects](#section3997224182313) - -This document describes how to quickly set up an application development environment \(using the Hi3516DV300 development board\) for event data recorders running on OpenHarmony. An air quality monitoring application, AirQuality, is used as an example to describe how to create, develop, and debug your application. - -## Display Effects - -AirQuality displays information about the urban air quality on two pages, the home page and details page. The following GIF shows AirQuality on the DevEco Studio simulator. - -**Figure 1** Display effects of the AirQuality - - -![](figures/video_2020-07-25_173141.gif) - diff --git a/en/device-dev/guide/overview-7.md b/en/device-dev/guide/overview-7.md deleted file mode 100644 index a1d94bca1274c243b4046785121ecacd56a0a93b..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/overview-7.md +++ /dev/null @@ -1,15 +0,0 @@ -# Overview - -- [Display Effect](#section3997224182313) - -This document describes how to quickly set up a development environment \(using the Hi3516D V300 development board\) and develop a clock app running on OpenHarmony. You can click [here](https://gitee.com/openharmony/app_samples/tree/master/common/Clock) to obtain the sample code. - -## Display Effect - -The Clock app displays the current time, as shown in the following figure. - -**Figure 1** Clock display effect - - -![](figures/clock.png) - diff --git a/en/device-dev/guide/overview.md b/en/device-dev/guide/overview.md deleted file mode 100644 index 598fa8d3b918f7e9f37ec53fd3ff80c81b26254f..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/overview.md +++ /dev/null @@ -1,4 +0,0 @@ -# Overview - -Based on the Hi3861 platform, the OpenHarmony WLAN module provides abundant peripheral operation capabilities, including the I2C, I2S, ADC, UART, SPI, SDIO, GPIO, PWM, and flash memory. This document describes how to control GPIO pins by calling the OpenHarmony native development kit \(NDK\) interface to implement LED blinking. For details about how to control other IoT peripherals, see the API guide. - diff --git a/en/device-dev/guide/parsing-private-configuration-data.md b/en/device-dev/guide/parsing-private-configuration-data.md deleted file mode 100644 index a66a1a0f634b3ceee01ba8ab6ad13a6a929abdaf..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/parsing-private-configuration-data.md +++ /dev/null @@ -1,17 +0,0 @@ -# Parsing Private Configuration Data - -You can obtain the sample code at **./drivers/framework/model/input/driver/input\_config\_parser.c**. - -The configuration parsing functions provided by the OSAL can parse the fields in the **hcs** file. For details, see the implementation of each function in **input\_config\_parser.c**. If the provided template cannot meet business requirements, you need to add required information to the **hcs** file and then develop parsing functions based on the added fields. - -``` -static int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode, BoardAttrCfg *attr) -{ - int32_t ret; - ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0); // Obtain the inputType field and save it in the BoardAttrCfg structure. - CHECK_PARSER_RET(ret, "GetUint8"); - ... - return HDF_SUCCESS; -} -``` - diff --git a/en/device-dev/guide/photographing-3.md b/en/device-dev/guide/photographing-3.md deleted file mode 100644 index 7d6450e761f1a0d4823c683ae95546de5a0a18fb..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/photographing-3.md +++ /dev/null @@ -1,395 +0,0 @@ -# Photographing - -- [When to Use](#en-us_topic_0000001052170554_section1963312376119) -- [Available APIs](#en-us_topic_0000001052170554_section56549532016) -- [Limitations and Constraints](#en-us_topic_0000001052170554_section1165911177314) -- [How to Develop](#en-us_topic_0000001052170554_section138543918214) - -## When to Use - -Use the camera module APIs to capture frames \(photographing\). - -## Available APIs - -**Table 1** APIs for photographing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Class

-

Function

-

Description

-

CameraKit

-

int32_t GetCameraIds(std::list<string> cameraList)

-

Obtains IDs of cameras that are currently available.

-

CameraKit

-

CameraAbility& GetCameraAbility(string cameraId)

-

Obtains the camera capability

-

CameraKit

-

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

-

Registers a camera callback for camera status changes.

-

CameraKit

-

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

-

Unregisters a camera callback.

-

CameraKit

-

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

-

Creates a Camera instance.

-

Camera

-

string GetCameraId()

-

Obtains the camera ID.

-

Camera

-

CameraConfig& GetCameraConfig()

-

Obtains the camera configuration.

-

Camera

-

FrameConfig& GetFrameConfig(int32_t type)

-

Obtains the frame configuration.

-

Camera

-

void Configure(CameraConfig& config)

-

Configures the camera using the CameraConfig object.

-

Camera

-

void Release()

-

Releases the Camera object and associated resources.

-

Camera

-

int TriggerLoopingCapture(FrameConfig& frameConfig)

-

Starts looping-frame capture.

-

Camera

-

void StopLoopingCapture()

-

Stops looping-frame capture.

-

Camera

-

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

-

Starts single-frame capture.

-

CameraConfig

-

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

-

Sets a frame state callback to respond to state changes.

-

CameraConfig

-

static CameraConfig* CreateCameraConfig()

-

Creates a CameraConfig instance.

-

CameraAbility

-

std::list<Size> GetSupportedSizes(int format)

-

Obtains the supported image sizes for a specified image format.

-

CameraAbility

-

std::list<T> GetParameterRange(uint32_t key)

-

Obtains the parameter value range based on a specified parameter key.

-

CameraDevice

-

CameraDeviceCallback()

-

A constructor used to create a CameraDeviceCallback instance.

-

CameraDevice

-

void OnCameraStatus​(std::string cameraId, int32_t status)

-

Called when the camera device status changes.

-

CameraStateCallback

-

CameraStateCallback​()

-

A constructor used to create a CameraStateCallback instance.

-

CameraStateCallback

-

void OnConfigured​(Camera& camera)

-

Called when the camera is configured.

-

CameraStateCallback

-

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

-

Called when the camera fails to be configured.

-

CameraStateCallback

-

void OnCreated​(Camera& camera)

-

Called when the camera is successfully created.

-

CameraStateCallback

-

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

-

Called when the camera fails to be created.

-

CameraStateCallback

-

void OnReleased​(Camera& camera)

-

Called when the camera is released.

-

FrameStateCallback

-

FrameStateCallback​()

-

A constructor used to create a FrameStateCallback instance.

-

FrameStateCallback

-

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

-

Called when the frame capture is completed.

-

FrameStateCallback

-

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

-

Called when the frame capture fails.

-

FrameConfig

-

int32_t GetFrameConfigType()

-

Obtains the frame configuration type.

-

FrameConfig

-

std::list<OHOS::Surface> GetSurfaces()

-

Obtains a list of surface objects (shared memories).

-

FrameConfig

-

void AddSurface(OHOS::AGP::UISurface& surface);

-

Adds a surface.

-

FrameConfig

-

void RemoveSurface(OHOS::AGP::UISurface& surface);

-

Removes a surface.

-
- -## Limitations and Constraints - -None - -## How to Develop - -1. Extend the **CameraDeviceCallback** class and call **OnCameraStatus** to customize operations when the camera device changes, for example, when a camera becomes available or unavailable. - - ``` - class SampleCameraDeviceCallback : public CameraDeviceCallback { - void OnCameraStatus(std::string cameraId, int32_t status) override - { - // Do something when camera is available or unavailable. - } - }; - ``` - -2. Extend the **FrameStateCallback** class. After obtaining the frame data, save the data as a file. - - ``` - static void SampleSaveCapture(const char *p, uint32_t size) - { - cout << "Start saving picture" << endl; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm *ltm = localtime(&tv.tv_sec); - if (ltm != nullptr) { - ostringstream ss("Capture_"); - ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; - - ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); - cout << "write " << size << " bytes" << endl; - pic.write(p, size); - cout << "Saving picture end" << endl; - } - } - - class TestFrameStateCallback : public FrameStateCallback { - void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override - { - cout << "Receive frame complete inform." << endl; - if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { - cout << "Capture frame received." << endl; - list surfaceList = fc.GetSurfaces(); - for (Surface *surface : surfaceList) { - SurfaceBuffer *buffer = surface->AcquireBuffer(); - if (buffer != nullptr) { - char *virtAddr = static_cast(buffer->GetVirAddr()); - if (virtAddr != nullptr) { - SampleSaveCapture(virtAddr, buffer->GetSize()); - } - surface->ReleaseBuffer(buffer); - } - delete surface; - } - delete &fc; - } - } - }; - ``` - -3. Extend the **CameraStateCallback** class and customize operations when the camera state changes \(configuration successful or failed, and creation successful or failed\). - - ``` - class SampleCameraStateMng : public CameraStateCallback { - public: - SampleCameraStateMng() = delete; - SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} - ~SampleCameraStateMng() - { - if (recordFd_ != -1) { - close(recordFd_); - } - } - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} - void OnReleased(Camera &c) override {} - }; - ``` - -4. Create a **CameraKit** instance to set and obtain camera information. - - ``` - CameraKit *camKit = CameraKit::GetInstance(); - list camList = camKit->GetCameraIds(); - string camId; - for (auto &cam : camList) { - cout << "camera name:" << cam << endl; - const CameraAbility *ability = camKit->GetCameraAbility(cam); - /* Find the camera that fits your ability. */ - list sizeList = ability->GetSupportedSizes(0); - if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { - camId = cam; - break; - } - } - ``` - -5. Create a **Camera** instance. - - ``` - EventHandler eventHdlr; // Create a thread to handle callback events. - SampleCameraStateMng CamStateMng(eventHdlr); - - camKit->CreateCamera(camId, CamStateMng, eventHdlr); - ``` - -6. In the main process, synchronize configurations set by callback functions implemented in [step 1](#en-us_topic_0000001052170554_li378084192111), [step 2](#en-us_topic_0000001052170554_li8716104682913), and [step 3](#en-us_topic_0000001052170554_li6671035102514). - - ``` - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - - void Capture() - { - if (cam_ == nullptr) { - cout << "Camera is not ready." << endl; - return; - } - FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); - Surface *surface = Surface::CreateSurface(); - if (surface == nullptr) { - delete fc; - } - surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ - fc->AddSurface(*surface); - cam_->TriggerSingleCapture(*fc); - } - ``` - - diff --git a/en/device-dev/guide/photographing.md b/en/device-dev/guide/photographing.md deleted file mode 100644 index a1617550bfbd2352e3bb1fc4739d93ed25f8fb78..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/photographing.md +++ /dev/null @@ -1,395 +0,0 @@ -# Photographing - -- [When to Use](#en-us_topic_0000001052170554_section1963312376119) -- [Available APIs](#en-us_topic_0000001052170554_section56549532016) -- [Limitations and Constraints](#en-us_topic_0000001052170554_section1165911177314) -- [How to Develop](#en-us_topic_0000001052170554_section138543918214) - -## When to Use - -Use the camera module APIs to capture frames \(photographing\). - -## Available APIs - -**Table 1** APIs for photographing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Class

-

Function

-

Description

-

CameraKit

-

int32_t GetCameraIds(std::list<string> cameraList)

-

Obtains IDs of cameras that are currently available.

-

CameraKit

-

CameraAbility& GetCameraAbility(string cameraId)

-

Obtains the camera capability

-

CameraKit

-

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

-

Registers a camera callback for camera status changes.

-

CameraKit

-

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

-

Unregisters a camera callback.

-

CameraKit

-

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

-

Creates a Camera instance.

-

Camera

-

string GetCameraId()

-

Obtains the camera ID.

-

Camera

-

CameraConfig& GetCameraConfig()

-

Obtains the camera configuration.

-

Camera

-

FrameConfig& GetFrameConfig(int32_t type)

-

Obtains the frame configuration.

-

Camera

-

void Configure(CameraConfig& config)

-

Configures the camera using the CameraConfig object.

-

Camera

-

void Release()

-

Releases the Camera object and associated resources.

-

Camera

-

int TriggerLoopingCapture(FrameConfig& frameConfig)

-

Starts looping-frame capture.

-

Camera

-

void StopLoopingCapture()

-

Stops looping-frame capture.

-

Camera

-

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

-

Starts single-frame capture.

-

CameraConfig

-

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

-

Sets a frame state callback to respond to state changes.

-

CameraConfig

-

static CameraConfig* CreateCameraConfig()

-

Creates a CameraConfig instance.

-

CameraAbility

-

std::list<Size> GetSupportedSizes(int format)

-

Obtains the supported image sizes for a specified image format.

-

CameraAbility

-

std::list<T> GetParameterRange(uint32_t key)

-

Obtains the parameter value range based on a specified parameter key.

-

CameraDevice

-

CameraDeviceCallback()

-

A constructor used to create a CameraDeviceCallback instance.

-

CameraDevice

-

void OnCameraStatus​(std::string cameraId, int32_t status)

-

Called when the camera device status changes.

-

CameraStateCallback

-

CameraStateCallback​()

-

A constructor used to create a CameraStateCallback instance.

-

CameraStateCallback

-

void OnConfigured​(Camera& camera)

-

Called when the camera is configured.

-

CameraStateCallback

-

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

-

Called when the camera fails to be configured.

-

CameraStateCallback

-

void OnCreated​(Camera& camera)

-

Called when the camera is successfully created.

-

CameraStateCallback

-

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

-

Called when the camera fails to be created.

-

CameraStateCallback

-

void OnReleased​(Camera& camera)

-

Called when the camera is released.

-

FrameStateCallback

-

FrameStateCallback​()

-

A constructor used to create a FrameStateCallback instance.

-

FrameStateCallback

-

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

-

Called when the frame capture is completed.

-

FrameStateCallback

-

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

-

Called when the frame capture fails.

-

FrameConfig

-

int32_t GetFrameConfigType()

-

Obtains the frame configuration type.

-

FrameConfig

-

std::list<OHOS::Surface> GetSurfaces()

-

Obtains a list of surface objects (shared memories).

-

FrameConfig

-

void AddSurface(OHOS::AGP::UISurface& surface);

-

Adds a surface.

-

FrameConfig

-

void RemoveSurface(OHOS::AGP::UISurface& surface);

-

Removes a surface.

-
- -## Limitations and Constraints - -None - -## How to Develop - -1. Extend the **CameraDeviceCallback** class and call **OnCameraStatus** to customize operations when the camera device changes, for example, when a camera becomes available or unavailable. - - ``` - class SampleCameraDeviceCallback : public CameraDeviceCallback { - void OnCameraStatus(std::string cameraId, int32_t status) override - { - // Do something when camera is available or unavailable. - } - }; - ``` - -2. Extend the **FrameStateCallback** class. After obtaining the frame data, save the data as a file. - - ``` - static void SampleSaveCapture(const char *p, uint32_t size) - { - cout << "Start saving picture" << endl; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm *ltm = localtime(&tv.tv_sec); - if (ltm != nullptr) { - ostringstream ss("Capture_"); - ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; - - ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); - cout << "write " << size << " bytes" << endl; - pic.write(p, size); - cout << "Saving picture end" << endl; - } - } - - class TestFrameStateCallback : public FrameStateCallback { - void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override - { - cout << "Receive frame complete inform." << endl; - if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { - cout << "Capture frame received." << endl; - list surfaceList = fc.GetSurfaces(); - for (Surface *surface : surfaceList) { - SurfaceBuffer *buffer = surface->AcquireBuffer(); - if (buffer != nullptr) { - char *virtAddr = static_cast(buffer->GetVirAddr()); - if (virtAddr != nullptr) { - SampleSaveCapture(virtAddr, buffer->GetSize()); - } - surface->ReleaseBuffer(buffer); - } - delete surface; - } - delete &fc; - } - } - }; - ``` - -3. Extend the **CameraStateCallback** class and customize operations when the camera state changes \(configuration successful or failed, and creation successful or failed\). - - ``` - class SampleCameraStateMng : public CameraStateCallback { - public: - SampleCameraStateMng() = delete; - SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} - ~SampleCameraStateMng() - { - if (recordFd_ != -1) { - close(recordFd_); - } - } - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} - void OnReleased(Camera &c) override {} - }; - ``` - -4. Create a **CameraKit** instance to set and obtain camera information. - - ``` - CameraKit *camKit = CameraKit::GetInstance(); - list camList = camKit->GetCameraIds(); - string camId; - for (auto &cam : camList) { - cout << "camera name:" << cam << endl; - const CameraAbility *ability = camKit->GetCameraAbility(cam); - /* Find the camera that fits your ability. */ - list sizeList = ability->GetSupportedSizes(0); - if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { - camId = cam; - break; - } - } - ``` - -5. Create a **Camera** instance. - - ``` - EventHandler eventHdlr; // Create a thread to handle callback events. - SampleCameraStateMng CamStateMng(eventHdlr); - - camKit->CreateCamera(camId, CamStateMng, eventHdlr); - ``` - -6. In the main process, synchronize configurations set by callback functions implemented in [step 1](#en-us_topic_0000001052170554_li378084192111), [step 2](#en-us_topic_0000001052170554_li8716104682913), and [step 3](#en-us_topic_0000001052170554_li6671035102514). - - ``` - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - - void Capture() - { - if (cam_ == nullptr) { - cout << "Camera is not ready." << endl; - return; - } - FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); - Surface *surface = Surface::CreateSurface(); - if (surface == nullptr) { - delete fc; - } - surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ - fc->AddSurface(*surface); - cam_->TriggerSingleCapture(*fc); - } - ``` - - diff --git a/en/device-dev/guide/preparations-11.md b/en/device-dev/guide/preparations-11.md deleted file mode 100644 index 50badfb8ff63a2f6fc2a5ee80fe58b0fa8a4221b..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/preparations-11.md +++ /dev/null @@ -1,7 +0,0 @@ -# Preparations - -Set up the environment by referring to [Setting Up a Standard OpenHarmony Environment](../quick-start/standard-system.md). - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->This development example applies to standard, small, and mini OpenHarmony systems. The following sections use the standard system as an example. You can refer to the specific guide for your system to set up the environment. - diff --git a/en/device-dev/guide/preparations-8.md b/en/device-dev/guide/preparations-8.md deleted file mode 100644 index e56d1485fdb5dfd7833cec5df4d23159168ca493..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/preparations-8.md +++ /dev/null @@ -1,8 +0,0 @@ -# Preparations - -- [Setting Up the Development Environment and Creating a Project](#section1912530122716) - -## Setting Up the Development Environment and Creating a Project - -Download and install DevEco Studio. For details, see the [HUAWEI DevEco Studio User Guide](../../application-dev/quick-start/deveco-studio-(openharmony)-user-guide.md). - diff --git a/en/device-dev/guide/preparations.md b/en/device-dev/guide/preparations.md deleted file mode 100644 index 9b4572fc68620f830d040b4537fecb852b9fc9dd..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/preparations.md +++ /dev/null @@ -1,27 +0,0 @@ -# Preparations - -- [Setting Up the Development Environment](#section1912530122716) -- [Creating a Project](#section1456035192720) - -## Setting Up the Development Environment - -Download and install DevEco Studio. For details, see the [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/software_install-0000001053582415). - -## Creating a Project - -1. Open the project wizard using either of the following methods: - - If no project is open, select **Create HarmonyOS Project** on the welcome page. - - If a project is already open, go to **File** \> **New** \> **New Project** on the menu bar. - -2. Choose the **Smart Vision** for **Device** and **Empty Feature Ability** for **Template**. - - ![](figures/en-us_image_0000001082434703.png) - -3. Click **Next** and configure the project. - - **Project Name**: project name. - - **Package Name**: software package name. By default, this name will also be used as your application ID. Your application must have a unique ID to be released. - - **Save Location**: path for storing project files. The path cannot contain Chinese characters or spaces. - - **Compatible API Version**: compatible API version. - -4. Click **Finish**. DevEco Studio will automatically generate the sample code and resources that match your project type. Wait until the project is created. - diff --git a/en/device-dev/guide/public_sys-resources/icon-caution.gif b/en/device-dev/guide/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/guide/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/device-dev/guide/public_sys-resources/icon-danger.gif b/en/device-dev/guide/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/guide/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/device-dev/guide/public_sys-resources/icon-note.gif b/en/device-dev/guide/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/device-dev/guide/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/device-dev/guide/public_sys-resources/icon-notice.gif b/en/device-dev/guide/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/device-dev/guide/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/device-dev/guide/public_sys-resources/icon-tip.gif b/en/device-dev/guide/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/device-dev/guide/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/device-dev/guide/public_sys-resources/icon-warning.gif b/en/device-dev/guide/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/guide/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/device-dev/guide/running-on-the-device-9.md b/en/device-dev/guide/running-on-the-device-9.md deleted file mode 100644 index 72fdad2eca6863415f1db8890939a18f49d09103..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/running-on-the-device-9.md +++ /dev/null @@ -1,35 +0,0 @@ -# Running on the Device - -Before you install the app and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). Burn OpenHarmony into the development board, and run it on the board. For details about how to build, burn, and run an image, see [Getting Started with Hi3516](../quick-start/standard-system.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the app: - -1. Obtain the HDC client from the following path: - - ``` - developtools/hdc_standard/prebuilt/windows/hdc_std.exe - ``` - - Change the HDC client name to **hdc.exe** and add the path above to the system environment variable **path**. - -2. Open the **cmd** window, and run the following commands to push the HAP file to the device directory, and install it: - - ``` - hdc smode - hdc target mount - hdc file send clock.hap /data/clock.hap - hdc shell chmod 666 /data/clock.hap - hdc shell bm install -p /data/clock.hap - ``` - -3. Run the following command to start the app. **ohos.samples.clock** indicates the app package name, and **MainAbility** indicates the ability started by the app. - - ``` - hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock - ``` - -4. \(Optional\) Run the following command to uninstall the app. **ohos.samples.clock** indicates the app package name. - - ``` - hdc shell bm uninstall -n ohos.samples.clock - ``` - - diff --git a/en/device-dev/guide/running-on-the-device.md b/en/device-dev/guide/running-on-the-device.md deleted file mode 100644 index 79167a2934ce10c5e799b2c59d09830ac68e7ac4..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/running-on-the-device.md +++ /dev/null @@ -1,29 +0,0 @@ -# Running on the Device - -Before you install the application and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/tool_install-0000001050164976). Burn OpenHarmony into the development board, and run it on the board. For details about how to compile, burn, and run an image, see the [Getting Started with Hi3516](../quick-start/hi3516-development-board.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the application: - -1. Store the compiled unsigned application installation package and installation tool in an SD card and insert the SD card into the development board slot. The installation tool is in **idev\_tools** of the directory where the image file is generated. -2. Run the following command to disable signature verification, which is enabled by default for application installation: - - ``` - ./sdcard/dev_tools/bin/bm set -s disable - ``` - -3. Run the following command to install the application: - - ``` - ./sdcard/dev_tools/bin/bm install -p /sdcard/airquality.hap - ``` - - The **dev\_tools** directory stores the installation tool, and **airquality.hap** is the application installation package. Replace it with actual the package name. - -4. After the application is installed, touch the application icon on the home screen to enter the application. - - **Figure 1** Home screen - ![](figures/home-screen.png "home-screen") - -5. \(Optional\) Uninstall the application. - - Touch and hold the application icon on the home screen, and touch the uninstall button in the displayed menu. - - diff --git a/en/device-dev/guide/screen-and-camera-control.md b/en/device-dev/guide/screen-and-camera-control.md deleted file mode 100644 index e017e08b1bcec34edc084d41bbc1fd0f1773461f..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/screen-and-camera-control.md +++ /dev/null @@ -1,9 +0,0 @@ -# Screen and Camera Control - -- **[Overview](overview-1.md)** - -- **[Development Guidelines](development-guidelines-2.md)** - -- **[Use Case](use-case-5.md)** - - diff --git a/en/device-dev/guide/setting-up-the-environment.md b/en/device-dev/guide/setting-up-the-environment.md deleted file mode 100644 index 9c2593432e6ebf03654d188c35e1a1953fe3e5f0..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/setting-up-the-environment.md +++ /dev/null @@ -1,7 +0,0 @@ -# Setting Up the Environment - -Set up the environment by referring to [Setting Up a Standard OpenHarmony Environment](../quick-start/standard-system.md). - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->This development example applies to standard, small, and mini OpenHarmony systems. The following sections use the standard system as an example. You can refer to the specific guide for your system to set up the environment. - diff --git a/en/device-dev/guide/signing-and-packaging.md b/en/device-dev/guide/signing-and-packaging.md deleted file mode 100644 index 80e390ea1a19510c5efeca200abe14e667f36b46..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/signing-and-packaging.md +++ /dev/null @@ -1,4 +0,0 @@ -# Signing and Packaging - -After finishing writing the app code, you need to sign and package the app before running it on a real device. For details, see [Signing and Packaging Guide](../../application-dev/quick-start/configuring-the-openharmony-app-signature.md). - diff --git a/en/device-dev/guide/startup-log-analysis.md b/en/device-dev/guide/startup-log-analysis.md deleted file mode 100644 index 967f333237e42aea6541c8377786360b6f9ce7c8..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/startup-log-analysis.md +++ /dev/null @@ -1,19 +0,0 @@ -# Startup Log Analysis - -The following is part of the startup log: - -``` -[I/HDF_INPUT_DRV] HdfInputManagerInit: enter // Initialize the input device manager. -[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // The initialization is successful. -[I/osal_cdev] add cdev hdf_input_host success -[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // Initialize the input common driver. -[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // The initialization is successful. -[I/osal_cdev] add cdev hdf_input_event1 success -[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // Initialize the input chip driver. -[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060 -[I/HDF_INPUT_DRV] Product_ID: 911_1060, x_sol = 960, y_sol = 480 -[I/HDF_LOG_TAG] ChipDriverInit: chipDetect succ, ret = 0 -[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch -[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // The initialization is successful. -``` - diff --git a/en/device-dev/guide/third-party-sdk-integration.md b/en/device-dev/guide/third-party-sdk-integration.md deleted file mode 100644 index db6388833d5fc135ad5dc7dd8f9109f9c57d139b..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/third-party-sdk-integration.md +++ /dev/null @@ -1,325 +0,0 @@ -# Third-Party SDK Integration - -- [Planning a Directory Structure](#section1736472718351) -- [Building the Service libs](#section442815485351) -- [Compiling Adaptation Code](#section3984721113613) -- [Compiling Code](#section830417531286) -- [Compiling a Script](#section13500201173710) -- [Compiling Service Code](#section8754114803918) -- [Runtime](#section7737749184012) -- [End](#section153301392411) - -To build a more open and complete Internet of Things \(IoT\) ecosystem, OpenHarmony has opened up a group of directories to integrate SDKs provided by different vendors. This guide describes how to integrate SDKs into OpenHarmony based on the Hi3861 board. - -## Planning a Directory Structure - -A third-party SDK consists of a static library and the adaption code. The SDK service logic is compiled to obtain the static library **libs** through the hardware module tool chain. Each module has its corresponding **libs**. The southbound APIs of the SDK are different from the APIs of OpenHarmony. The difference can be shielded by using the adaptation code **adapter**. Different modules can share the same **adapter**. - -Based on the preceding features, third-party SDK directories can be divided as follows in the OpenHarmony directory structure: - -- domains/iot/link/: The **adapter** is stored in this directory and is decoupled from the module. -- device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/: The service library **libs** is stored in this directory and is bound to the module. - -You must perform the following steps before adaptation. The following uses the demolink SDK as an example. - -1. Create vendor directories, **domains/iot/link/demolink/** and **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/**, to isolate different vendors. -2. Create the **domains/iot/link/demolink/BUILD.gn** file to build the adaptation code. -3. Create the **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/** directory to store the service library **libs**. - -``` -. -├── domains -│ └── iot -│ └── link -│ ├── demolink -│ │ └── BUILD.gn -│ ├── libbuild -│ │ └── BUILD.gn -│ └── BUILD.gn -└── device - └── hisilicon - └── hispark_pegasus - └── sdk_liteos - └── 3rd_sdk - └── demolink - └── libs -``` - -## Building the Service **libs** - -Generally, the platform SDK service is provided as a static library. After obtaining the OpenHarmony code, the platform vendor needs to compile the service library **libs** based on the corresponding hardware module vendor and save the compilation result to the **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/** directory. The following describes how to build the service library **libs**. - -OpenHarmony has planned the **domains/iot/link/libbuild/** directory for compiling the service library **libs**. This directory contains the **domains/iot/link/libbuild/BUILD.gn** and **domains/iot/link/BUILD.gn** files. The directory structure is as follows: - -``` -. -└── domains - └── iot - └── link - ├── demolink - │ └── BUILD.gn - ├── libbuild - │ └── BUILD.gn - └── BUILD.gn -``` - -Before building **libs**, you must perform the following steps: - -1. Place the service source code files \(including **.c** and **.h** files\) in the **domains/iot/link/libbuild/** directory. - - ``` - . - └── domains - └── iot - └── link - ├── demolink - │ ├── demosdk_adapter.c - │ ├── demosdk_adapter.h - │ └── BUILD.gn - ├── libbuild - │ ├── demosdk.c - │ ├── demosdk.h - │ └── BUILD.gn - └── BUILD.gn - ``` - -2. Adapt to the **domains/iot/link/libbuild/BUILD.gn** file and restore the file after the compilation is complete. - - In the **BUILD.gn** file, **sources** specifies the source file to build and **include\_dirs** specifies the path of the dependent header file so that the target build result is the static library **libdemosdk.a**. - - ``` - static_library("demosdk") { - sources = [ - "demosdk.c" - ] - include_dirs = [ - "//domains/iot/link/libbuild", - "//domains/iot/link/demolink" - ] - } - ``` - -3. Adapt to the **domains/iot/link/BUILD.gn** file and restore the file after the compilation is complete. - - The **BUILD.gn** file is used to specify build entries. You need to enter all static library entries to be compiled in **features** so that the **domains/iot/link/libbuild/BUILD.gn** file is used in the build. - - ``` - import("//build/lite/config/subsystem/lite_subsystem.gni") - import("//build/lite/config/component/lite_component.gni") - lite_subsystem("iot") { - subsystem_components = [ - ":link" - ] - } - lite_component("link") { - features = [ - "libbuild:demosdk" - ] - } - ``` - - -After the preceding operations are complete, run the **hb build -T //domains/iot/link:iot** command in the root directory of the code and then check whether the target library file is generated in the **out/hispark\_pegasus/wifiiot\_hispark\_pegasus/libs/** directory. - -![](figures/en-us_image_0000001078563230.png) - -Copy the library file to the **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/** directory and delete the **.c** and **.h** files from the **domains/iot/link/libbuild/** directory. - -## Compiling Adaptation Code - -## Compiling Code - -The APIs used in the platform SDK are different from the OpenHarmony APIs and cannot be directly used. Therefore, the adaptation code **adapter** is required for intermediate conversion. This section uses **DemoSdkCreateTask** in **domains/iot/link/demolink/demosdk\_adapter.c** as an example to describe how to compile adaptation code on OpenHarmony. - -1. Check the description, parameters, and return values of the **DemoSdkCreateTask** API to adapt. - - ``` - struct TaskPara { - char *name; - void *(*func)(char* arg); - void *arg; - unsigned char prio; - unsigned int size; - }; - - /* - * Create a thread for the IoT OS. - * Return 0 if the operation is successful; return a non-zero value otherwise. - */ - int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para); - ``` - -2. Check the OpenHarmony API document, select an API with similar features, and compare the parameters and usage. This guide uses **osThreadNew** as an example. By comparing this API with **DemoSdkCreateTask**, you can find that the parameters on which the two APIs depend are basically the same, but the structures to which the parameters belong are different. - - ``` - typedef struct { - const char *name; ///< name of the thread - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block - void *stack_mem; ///< memory for stack - uint32_t stack_size; ///< size of stack - osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) - TZ_ModuleId_t tz_module; ///< TrustZone module identifier - uint32_t reserved; ///< reserved (must be 0) - } osThreadAttr_t; - - /// Create a thread and add it to Active Threads. - /// \param[in] func thread function. - /// \param[in] argument pointer that is passed to the thread function as start argument. - /// \param[in] attr thread attributes; NULL: default values. - /// \return thread ID for reference by other functions or NULL in case of error. - osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); - ``` - -3. Perform code adaptation to shield the difference. - - ``` - int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para) - { - osThreadAttr_t attr = {0}; - osThreadId_t threadId; - if (handle == 0 || para == 0) { - return DEMOSDK_ERR; - } - if (para->func == 0) { - return DEMOSDK_ERR; - } - if (para->name == 0) { - return DEMOSDK_ERR; - } - attr.name = para->name; - attr.priority = para->prio; - attr.stack_size = para->size; - threadId = osThreadNew((osThreadFunc_t)para->func, para->arg, &attr); - if (threadId == 0) { - printf("osThreadNew fail\n"); - return DEMOSDK_ERR; - } - *(unsigned int *)handle = (unsigned int)threadId; - return DEMOSDK_OK; - } - ``` - - -## Compiling a Script - -After completing code adaptation, create the **BUILD.gn** file in the directory where the **adapter** is located. This file can be used to compile the adaptation code into a static library and link the static library to the **bin** package during the entire package build. In the **domains/iot/link/demolink/BUILD.gn** file, **sources** specifies the source files to be used in the build and **include\_dirs** specifies the path of the dependent header file so that the target build result is the static library **libdemolinkadapter.a**. - -``` -import("//build/lite/config/component/lite_component.gni") -static_library("demolinkadapter") { - sources = [ - "demosdk_adapter.c" - ] - include_dirs = [ - "//kernel/liteos-m/kal/cmsis", - "//domains/iot/link/demolink" - ] -} -``` - -Modify the **domains/iot/link/BUILD.gn** file so that the **domain/iot/hilink/BUILD.gn** file is used in the build. - -``` -import("//build/lite/config/subsystem/lite_subsystem.gni") -import("//build/lite/config/component/lite_component.gni") -lite_subsystem("iot") { - subsystem_components = [ - ":link" - ] -} -lite_component("link") { - features = [ - "demolink:demolinkadapter" - ] -} -``` - -## Compiling Service Code - -After the service library **libs** and adaptation code are ready, compile the service entry function to call the service entry of the third-party SDK. - -The following uses **demolink** as an example to describe how to compile code in **applications/sample/wifi-iot/app/** to call the **demosdk** entry function. - -1. Create a directory. - - Before compiling a service, you must create a directory \(or a directory structure\) in **applications/sample/wifi-iot/app/** to store service source code files. - - For example, add the service directory **demolink** to the app, and create the service entry code **helloworld.c** and compile the **BUILD.gn** file. - - ``` - . - └── applications - └── sample - └── wifi-iot - └── app - │── demolink - │ │── helloworld.c - │ └── BUILD.gn - └── BUILD.gn - ``` - -2. Compile service code. - - Compile the service entry function **DemoSdkMain** in the **helloworld.c** file, call the service entry **DemoSdkEntry** of **demolink**, and call the entry function through **SYS\_RUN\(\)** to start the service. - - ``` - #include "hos_init.h" - #include "demosdk.h" - - void DemoSdkMain(void) - { - DemoSdkEntry(); - } - - SYS_RUN(DemoSdkMain); - ``` - -3. Compile build scripts. - - Add the **applications/sample/wifi-iot/app/demolink/BUILD.gn** file, specify the paths of the source code and header file, and compile the static library file **libexample\_demolink.a**. - - ``` - static_library("example_demolink") { - sources = [ - "helloworld.c" - ] - include_dirs = [ - "//utils/native/lite/include", - "//domains/iot/link/libbuild" - ] - } - ``` - - Modify the **applications/sample/wifi-iot/app/BUILD.gn** file so that **demolink** is used in compilation. - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("app") { - features = [ - "demolink:example_demolink" - ] - } - ``` - - -## Runtime - -Run the **hb build** command in the root directory of the code to compile and output the version package. Start **demolink**. The following shows the running result, which is consistent with the expected result of **demolink**. - -``` -ready to OS start -sdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00 -formatting spiffs... -FileSystem mount ok. -wifi init success! -it is demosdk entry. -it is demo biz: hello world. -it is demo biz: hello world. -``` - -## End - -The third-party SDK integration is complete. - diff --git a/en/device-dev/guide/use-case-5.md b/en/device-dev/guide/use-case-5.md deleted file mode 100644 index f4e481e1cef8c4815def24a9aa9c604df9b01680..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/use-case-5.md +++ /dev/null @@ -1,64 +0,0 @@ -# Use Case - -This use case takes **camera\_sample** \(contained in the source code\) as an example for photographing, recording, and previewing on the development board. - -- You can obtain source code of the sample from **applications/sample/camera/media/camera\_sample.cpp**. -- Before running the sample camera, you need to compile, burn, and run the image. For details, see [Getting Started with Hi3516](../quick-start/hi3516-development-board.md). - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >After the development board is started, the home screen is loaded and displayed above the media layer by default. To prevent covering **camera\_sample**, you should remove the home screen during compilation or packaging. - >How to Remove: In **build/lite/components/applications.json**, comment out or delete the **//applications/sample/camera/launcher:launcher\_hap** line from the **target** field of **camera\_sample\_app**. - -- The compilation result of the sample code is stored in **out/hi3516dv300/ipcamera\_hi3516dv300\_liteos/dev\_tools/bin**. To ensure that the code can be executed on the development board, you can copy the file to a TF card through a card reader, or modify the compilation script of **camera\_sample** to copy the compilation result to **rootfs.img**. - - Modify the first **output\_dir** in the source code path **applications/sample/camera/media/BUILD.gn**. - - - Before: **output\_dir = "$root\_out\_dir/dev\_ools"** - - After: **output\_dir = "$root\_out\_dir/"** - - Recompile the source code repository and burn the code into the development board. Then you can find the **camera\_sample** file in the **bin** directory of the board. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >You should insert a TF card \(up to 128 GB supported\) for photographing and video recording before system startup. This way, the TF card will be automatically mounted to the **/sdcard** directory. If you insert the TF card after the system is started, you have to manually mount the TF card. - >To view the photos and videos in the TF card, copy them to a computer. If you just want to preview photos and videos, you do not need to insert a TF card. - -- Perform the following steps to run the sample: - -1. Run the **cd** command to go to the end path of the executable program and start **camera\_sample** by running the command in the following figure. - - **Figure 1** Starting camera\_sample - ![](figures/starting-camera_sample.png "starting-camera_sample") - - The control commands are displayed as shown in the preceding figure. Press **S** to stop the current operation \(including video recording and preview\), and press **Q** to exit the program. - -2. Press **1** to take a photo in JPG format. The photo is saved in the **/sdcard** directory and named **Capture\***. - - **Figure 2** Serial port logs displayed after the photographing command is executed - ![](figures/serial-port-logs-displayed-after-the-photographing-command-is-executed.png "serial-port-logs-displayed-after-the-photographing-command-is-executed") - - To view the saved file, exit the program and enter the file system. To start the program again, return to the previous step. - - **Figure 3** Saved files - ![](figures/saved-files.png "saved-files") - -3. Press **2** to start recording. The video file is in MP4 format and saved in the **/sdcard** directory with the name **Record\***. Press **S** to stop recording. - - **Figure 4** Serial port logs displayed after the recording command is executed - ![](figures/serial-port-logs-displayed-after-the-recording-command-is-executed.png "serial-port-logs-displayed-after-the-recording-command-is-executed") - -4. Press **3** to start preview. The preview is displayed on the screen. Press **S** to stop preview. - - **Figure 5** Serial port logs displayed after the preview command is executed - ![](figures/serial-port-logs-displayed-after-the-preview-command-is-executed.png "serial-port-logs-displayed-after-the-preview-command-is-executed") - - The following figure shows the preview. - - **Figure 6** Preview effect - ![](figures/preview-effect.jpg "preview-effect") - -5. Press **Q** to exit. - - **Figure 7** Serial port logs displayed after the exit command is executed - ![](figures/serial-port-logs-displayed-after-the-exit-command-is-executed.png "serial-port-logs-displayed-after-the-exit-command-is-executed") - - diff --git a/en/device-dev/guide/use-case.md b/en/device-dev/guide/use-case.md deleted file mode 100644 index 274e2d375df15cf35285544f1c48c37f6b8e3c94..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/use-case.md +++ /dev/null @@ -1,45 +0,0 @@ -# Use Case - -- For details about the development board, compilation, burning, and image running, see [Getting Started with Hi3518](../quick-start/hi3518-development-board.md). A compilation result file of sample code is stored in **out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample**. You can copy the file to a TF card, or modify the compilation script of **camera\_sample** to copy the result to **rootfs.img**. - - Modify **output\_dir** in **applications/sample/camera/media/BUILD.gn**. - - - Before: **output\_dir = "$root\_out\_dir/dev\_tools"** - - After: **output\_dir = "$root\_out\_dir/"** - - Recompile the source code repository and burn the code into the development board. Then you can find the **camera\_sample** file in the **bin** directory of the board. - -- The sample code for camera development is stored in **applications/sample/camera/media/camera\_sample.cpp**. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >You should insert a TF card \(maximum capacity: 128 GB\) for photographing and video recording functions. After the system is started, the TF card is automatically mounted to the **/sdcard** directory. If the TF card is inserted after the system is started, you have to manually mount the TF card. To view the photos and videos in the TF card, copy the content to a computer. The preview function does not require a TF card. - - -1. Run the **cd** command to go to the end path of the executable program and start **camera\_sample** by running the command in the following figure. - - **Figure 1** Starting camera\_sample - ![](figures/starting-camera_sample.png "starting-camera_sample") - - The control commands are displayed as shown in the preceding figure. Press **S** to stop the current operation \(including video recording and preview\), and press **Q** to exit the program. - -2. Press **1** to take a photo in JPG format. The photo is saved in the **/sdcard** directory and named **Capture\***. - - **Figure 2** Serial port logs displayed after the photographing command is executed - ![](figures/serial-port-logs-displayed-after-the-photographing-command-is-executed.png "serial-port-logs-displayed-after-the-photographing-command-is-executed") - - To view the saved file, exit the program and enter the file system. To start the program again, return to the previous step. - - **Figure 3** Saved files - ![](figures/saved-files.png "saved-files") - -3. Press **2** to start recording. The video file is in MP4 format and saved in the **/sdcard** directory with the name **Record\***. Press **S** to stop recording. - - **Figure 4** Serial port logs displayed after the recording command is executed - ![](figures/serial-port-logs-displayed-after-the-recording-command-is-executed.png "serial-port-logs-displayed-after-the-recording-command-is-executed") - -4. Press **Q** to exit. - - **Figure 5** Serial port logs displayed after the exit command is executed - ![](figures/serial-port-logs-displayed-after-the-exit-command-is-executed.png "serial-port-logs-displayed-after-the-exit-command-is-executed") - - diff --git a/en/device-dev/guide/verification.md b/en/device-dev/guide/verification.md deleted file mode 100644 index 55254e77cd032307a97cc73ffa3b45169789be56..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/verification.md +++ /dev/null @@ -1,9 +0,0 @@ -# Verification - -For details about the compilation and burning processes, see [Modifying Source Code](../quick-start/running-a-hello-world-program.md) and [Burning Images](../quick-start/wlan-connection.md) in _Getting Started with Hi3861_. - -After the preceding two steps are complete, press the **RST** button to reset the module. The LED blinks periodically, which meets the expectation. The verification is complete. - -**Figure 1** LED blinking -![](figures/led-blinking.gif "led-blinking") - diff --git a/en/device-dev/guide/visual-application-development.md b/en/device-dev/guide/visual-application-development.md deleted file mode 100644 index b13654cffb462ca5fa2919848035a3e8b5f9a6ac..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/visual-application-development.md +++ /dev/null @@ -1,19 +0,0 @@ -# Visual Application Development - -- **[Overview](overview-6.md)** - -- **[Preparations](preparations.md)** - -- **[Adding Pages](adding-pages.md)** - -- **[Building the Home Page](building-the-home-page.md)** - -- **[Building the Details Page](building-the-details-page.md)** - -- **[Debugging and Packaging](debugging-and-packaging.md)** - -- **[Running on the Device](running-on-the-device.md)** - -- **[FAQs](faqs.md)** - - diff --git a/en/device-dev/guide/wlan-connected-products.md b/en/device-dev/guide/wlan-connected-products.md deleted file mode 100644 index 184f46eb0e144c6d086c2b35264557825fe5bb8e..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/wlan-connected-products.md +++ /dev/null @@ -1,5 +0,0 @@ -# WLAN-connected Products - -- **[LED Peripheral Control](led-peripheral-control.md)** - - diff --git a/en/device-dev/kernel/Readme-EN.md b/en/device-dev/kernel/Readme-EN.md index 2ec9f17abde6255b6bfb7b20df50fac5357972ea..b8a0bb660407fe0500f9a7ca89d7c589d12a7852 100644 --- a/en/device-dev/kernel/Readme-EN.md +++ b/en/device-dev/kernel/Readme-EN.md @@ -1,93 +1,86 @@ -# Kernel - -- [Lite Kernel](lite-kernel.md) - - [OpenHarmony Lite Kernel Basic Functions](openharmony-lite-kernel-basic-functions.md) - - [Process](process.md) - - [Thread](thread.md) - - [Memory](memory.md) - - [Network](network.md) - - - [OpenHarmony Lite Kernel File System](openharmony-lite-kernel-file-system.md) - - [VFS](vfs.md) - - [NFS](nfs.md) - - [RAMFS](ramfs.md) - - [FAT](fat.md) - - [JFFS2](jffs2.md) - - - [Standard Library](standard-library.md) - - [Standard Library](standard-library-0.md) - - [Differences from the Linux Standard Library](differences-from-the-linux-standard-library.md) - - - [Commissioning](commissioning.md) - - [Introduction to the Shell](introduction-to-the-shell.md) - - [Shell Command Development Guidelines](shell-command-development-guidelines.md) - - [Shell Command Programming Example](shell-command-programming-example.md) - - [Shell Command Reference](shell-command-reference.md) - - [System Commands](system-commands.md) - - [cpup](cpup.md) - - [date](date.md) - - [dmesg](dmesg.md) - - [exec](exec.md) - - [free](free.md) - - [help](help.md) - - [hwi](hwi.md) - - [kill](kill.md) - - [log](log.md) - - [memcheck](memcheck.md) - - [oom](oom.md) - - [pmm](pmm.md) - - [reset](reset.md) - - [sem](sem.md) - - [stack](stack.md) - - [su](su.md) - - [swtmr](swtmr.md) - - [systeminfo](systeminfo.md) - - [task](task.md) - - [uname](uname.md) - - [vmm](vmm.md) - - [watch](watch.md) - - - [File Commands](file-commands.md) - - [cat](cat.md) - - [cd](cd.md) - - [chgrp](chgrp.md) - - [chmod](chmod.md) - - [chown](chown.md) - - [cp](cp.md) - - [format](format.md) - - [ls](ls.md) - - [lsfd](lsfd.md) - - [mkdir](mkdir.md) - - [mount](mount.md) - - [partinfo](partinfo.md) - - [partition](partition.md) - - [pwd](pwd.md) - - [rm](rm.md) - - [rmdir](rmdir.md) - - [statfs](statfs.md) - - [sync](sync.md) - - [touch](touch.md) - - [writeproc](writeproc.md) - - [umount](umount.md) - - - [Network Commands](network-commands.md) - - [arp](arp.md) - - [dhclient](dhclient.md) - - [dns](dns.md) - - [ifconfig](ifconfig.md) - - [ipdebug](ipdebug.md) - - [netstat](netstat.md) - - [ntpdate](ntpdate.md) - - [ping](ping.md) - - [ping6](ping6.md) - - [telnet](telnet.md) - - [tftp](tftp.md) - - - [Magic Key Usage](magic-key-usage.md) - - [User-Space Exception Information](user-space-exception-information.md) - -- [Linux Kernel](linux-kernel.md) - - [Linux Kernel Overview](linux-kernel-overview.md) - - [Guidelines for Using Patches on OpenHarmony Development Boards](guidelines-for-using-patches-on-openharmony-development-boards.md) - - [Guidelines for Compiling and Building the Linux Kernel](guidelines-for-compiling-and-building-the-linux-kernel.md) +# Kernel +- [Kernel for Mini and Small Systems](kernel-lite.md) + - [Kernel for Small Systems](kernel-lite-small.md) + - [Basic Kernel](kernel-lite-small-basic.md) + - [Process](kernel-lite-small-process.md) + - [Thread](kernel-lite-small-thread.md) + - [Memory](kernel-lite-small-memory.md) + - [Network](kernel-lite-small-net.md) + - [File System](kernel-lite-small-file.md) + - [VFS](kernel-lite-small-file-vfs.md) + - [NFS](kernel-lite-small-file-nfs.md) + - [RAMFS](kernel-lite-small-file-ramfs.md) + - [FAT](kernel-lite-small-file-fat.md) + - [JFFS2](kernel-lite-small-file-jffs.md) + - [Standard Library](kernel-lite-small-lib.md) + - [Standard Library](kernel-lite-small-lib-standard.md) + - [Differences from the Linux Standard Library](kernel-lite-small-lib-differ.md) + - [Commissioning](kernel-lite-small-shell.md) + - [Introduction to the Shell](kernel-lite-small-shell-des.md) + - [Shell Command Development Guidelines](kernel-lite-small-shell-guide.md) + - [Shell Command Programming Example](kernel-lite-small-shell-sample.md) + - [Shell Command Reference](kernel-lite-small-shell-cmd.md) + - [System Commands](kernel-lite-small-shell-cmd-sys.md) + - [cpup](kernel-lite-small-shell-cmd-sys-cpup.md) + - [date](kernel-lite-small-shell-cmd-sys-date.md) + - [dmesg](kernel-lite-small-shell-cmd-sys-demsg.md) + - [exec](kernel-lite-small-shell-cmd-sys-exec.md) + - [free](kernel-lite-small-shell-cmd-sys-free.md) + - [help](kernel-lite-small-shell-cmd-sys-help.md) + - [hwi](kernel-lite-small-shell-cmd-sys-hwi.md) + - [kill](kernel-lite-small-shell-cmd-sys-kill.md) + - [log](kernel-lite-small-shell-cmd-sys-log.md) + - [memcheck](kernel-lite-small-shell-cmd-sys-mem.md) + - [oom](kernel-lite-small-shell-cmd-sys-oom.md) + - [pmm](kernel-lite-small-shell-cmd-sys-pmm.md) + - [reset](kernel-lite-small-shell-cmd-sys-reset.md) + - [sem](kernel-lite-small-shell-cmd-sys-sem.md) + - [stack](kernel-lite-small-shell-cmd-sys-stack.md) + - [su](kernel-lite-small-shell-cmd-sys-su.md) + - [swtmr](kernel-lite-small-shell-cmd-sys-swymr.md) + - [systeminfo](kernel-lite-small-shell-cmd-sys-sys.md) + - [task](kernel-lite-small-shell-cmd-sys-task.md) + - [uname](kernel-lite-small-shell-cmd-sys-uname.md) + - [vmm](kernel-lite-small-shell-cmd-sys-vmm.md) + - [watch](kernel-lite-small-shell-cmd-sys-watch.md) + - [File Commands](kernel-lite-small-shell-cmd-file.md) + - [cat](kernel-lite-small-shell-cmd-file-cat.md) + - [cd](kernel-lite-small-shell-cmd-file-cd.md) + - [chgrp](kernel-lite-small-shell-cmd-file-chgrp.md) + - [chmod](kernel-lite-small-shell-cmd-file-chmod.md) + - [chown](kernel-lite-small-shell-cmd-file-chown.md) + - [cp](kernel-lite-small-shell-cmd-file-cp.md) + - [format](kernel-lite-small-shell-cmd-file-format.md) + - [ls](kernel-lite-small-shell-cmd-file-is.md) + - [lsfd](kernel-lite-small-shell-cmd-file-isfd.md) + - [mkdir](kernel-lite-small-shell-cmd-file-mkdir.md) + - [mount](kernel-lite-small-shell-cmd-file-mount.md) + - [partinfo](kernel-lite-small-shell-cmd-file-part.md) + - [partition](kernel-lite-small-shell-cmd-file-partion.md) + - [pwd](kernel-lite-small-shell-cmd-file-pwd.md) + - [rm](kernel-lite-small-shell-cmd-file-rm.md) + - [rmdir](kernel-lite-small-shell-cmd-file-rmdir.md) + - [statfs](kernel-lite-small-shell-cmd-file-sta.md) + - [sync](kernel-lite-small-shell-cmd-file-sync.md) + - [touch](kernel-lite-small-shell-cmd-file-touch.md) + - [writeproc](kernel-lite-small-shell-cmd-file-write.md) + - [umount](kernel-lite-small-shell-cmd-file-umount.md) + - [Network Commands](kernel-lite-small-shell-cmd-net.md) + - [arp](kernel-lite-small-shell-cmd-net-arp.md) + - [dhclient](kernel-lite-small-shell-cmd-net-dh.md) + - [dns](kernel-lite-small-shell-cmd-net-dns.md) + - [ifconfig](kernel-lite-small-shell-cmd-net-ipc.md) + - [ipdebug](kernel-lite-small-shell-cmd-net-ipd.md) + - [netstat](kernel-lite-small-shell-cmd-net-net.md) + - [ntpdate](kernel-lite-small-shell-cmd-net-ntp.md) + - [ping](kernel-lite-small-shell-cmd-net-ping.md) + - [ping6](kernel-lite-small-shell-cmd-net-ping6.md) + - [telnet](kernel-lite-small-shell-cmd-net-tel.md) + - [tftp](kernel-lite-small-shell-cmd-net-tftp.md) + - [Magic Key Usage](kernel-lite-small-shell-cmd-mag.md) + - [User-Space Exception Information](kernel-lite-small-shell-cmd-abn.md) +- [Kernel for Standard Systems](kernel-standard.md) + - [Linux Kernel Overview](kernel-standard-des.md) + - [Guidelines for Using Patches on OpenHarmony Development Boards](kernel-standard-patch.md) + - [Guidelines for Compiling and Building the Linux Kernel](kernel-standard-build.md) \ No newline at end of file diff --git a/en/device-dev/kernel/arp.md b/en/device-dev/kernel/arp.md deleted file mode 100644 index 0589669289c590d43958472e8a660866098dd165..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/arp.md +++ /dev/null @@ -1,114 +0,0 @@ -# arp - -- [Command Function](#section201149459368) -- [Syntax](#section579813484364) -- [Parameter Description](#section168065311366) -- [Usage](#section19190125723612) -- [Example](#section10383416372) - -## Command Function - -On an Ethernet, hosts communicate with each other using MAC addresses \(non-IP addresses\). Therefore, IP addresses must be converted into MAC addresses so that hosts can communicate with each other on a LAN \(Ethernet\). To resolve this issue, the host stores a table containing the mapping between IP addresses and MAC addresses, that is, the ARP cache table. When the host needs to send an IP packet to the destination IP address on a LAN, the host can query the destination MAC address from the ARP cache table. The ARP cache table is maintained by the TCP/IP protocol stack. You can run the **arp** command to view and modify the ARP cache table. - -## Syntax - -arp - -arp \[_-i IF_\] -s _IPADDR HWADDR_ - -arp \[_-i IF_\] -d _IPADDR_ - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

No parameter

-

Prints the content of the entire ARP cache table.

-

N/A

-

-i IF

-

Indicates the network interface. This parameter is optional.

-

N/A

-

-s IPADDR

-

HWADDR

-

Adds an ARP entry. The second parameter is the IP address and MAC address of the other host on the LAN.

-

N/A

-

-d IPADDR

-

Deletes an ARP entry.

-

N/A

-
- -## Usage - -- The **arp** command is used to query and modify the ARP cache table of the TCP/IP protocol stack. If ARP entries for IP addresses on different subnets are added, the protocol stack returns a failure message. -- This command can be used only after the TCP/IP protocol stack is enabled. - -## Example - -Example: - -1. Enter **arp**. - - **Figure 1** Printing the entire ARP cache table - - - ![](figures/snipaste_2021-01-26_10-38-58.png) - - **Table 2** Output description - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Address

-

Indicates the IPv4 address of a network device.

-

HWaddress

-

Indicates the MAC address of a network device.

-

Iface

-

Indicates the name of the interface used by the ARP entry.

-

Type

-

Indicates whether the ARP entry is dynamic or static. A dynamic ARP entry is automatically created by the protocol stack, and a static ARP entry is added by the user.

-
- - diff --git a/en/device-dev/kernel/cat.md b/en/device-dev/kernel/cat.md deleted file mode 100644 index b6cbfd94caeb9d9e14769da53b3e7ae69df1f4eb..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/cat.md +++ /dev/null @@ -1,53 +0,0 @@ -# cat - -- [Command Function](#section16710153391315) -- [Syntax](#section1699392313158) -- [Parameter Description](#section1677217374136) -- [Usage](#section186772414131) -- [Example](#section12158131814561) -- [Output](#section183926225561) - -## Command Function - -This command is used to display the content of a text file. - -## Syntax - -cat \[_pathname_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

pathname

-

Indicates the file path.

-

An existing file

-
- -## Usage - -Run the **cat** \[_pathname_\] command to display the content of a text file. - -## Example - -Enter **cat hello-harmony.txt**. - -## Output - -**Figure 1** Viewing content of the **hello-harmony.txt** file -![](figures/viewing-content-of-the-hello-harmony-txt-file.png "viewing-content-of-the-hello-harmony-txt-file") - diff --git a/en/device-dev/kernel/cd.md b/en/device-dev/kernel/cd.md deleted file mode 100644 index 52825654be515c883babb87db3131038d7285492..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/cd.md +++ /dev/null @@ -1,57 +0,0 @@ -# cd - -- [Command Function](#section11690184921316) -- [Syntax](#section75695409569) -- [Parameter Description](#section71961353181311) -- [Usage](#section3629759111317) -- [Example](#section211620301412) -- [Output](#section1968117214577) - -## Command Function - -This command is used to change the current working directory. - -## Syntax - -cd \[_path_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

path

-

Indicates the file path.

-

The user must have the execution (search) permission for the specified directory.

-
- -## Usage - -- If the **path** parameter is not specified, the system switches to the root directory. -- If the **path** parameter is specified, the system switches to the specified path. -- The **path** value starting with a slash \(/\) represents the root directory. -- The **path** value starting with a dot \(.\) represents the current directory. -- The **path** value starting with two dots \(..\) represents the parent directory. - -## Example - -Enter **cd ..**. - -## Output - -**Figure 1** Directory switching result -![](figures/directory-switching-result.png "directory-switching-result") - diff --git a/en/device-dev/kernel/chgrp.md b/en/device-dev/kernel/chgrp.md deleted file mode 100644 index bca849032f2c618bf837b6a5b052edf7a1d4a384..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/chgrp.md +++ /dev/null @@ -1,60 +0,0 @@ -# chgrp - -- [Command Function](#section6103119161418) -- [Syntax](#section186958132141) -- [Parameter Description](#section81796174141) -- [Usage](#section14330152417140) -- [Example](#section951823119149) -- [Output](#section14271133125715) - -## Command Function - -This command is used to change a file group. - -## Syntax - -chgrp \[_group_\] \[_pathname_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

group

-

Indicates the file group.

-

[0, 0xFFFFFFFF]

-

pathname

-

Indicates the file path.

-

An existing file

-
- -## Usage - -By specifying a file group before the file name in this command, you can change the group to which the file belongs. - -## Example - -Enter **chgrp 100 hello-harmony.txt**. - -## Output - -**Figure 1** Changing the group of the **hello-harmony.txt** file to **100** -![](figures/changing-the-group-of-the-hello-harmony-txt-file-to-100.png "changing-the-group-of-the-hello-harmony-txt-file-to-100") - diff --git a/en/device-dev/kernel/chmod.md b/en/device-dev/kernel/chmod.md deleted file mode 100644 index 0645a96d31a8c52cd6c39b11213154c2bdf36025..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/chmod.md +++ /dev/null @@ -1,60 +0,0 @@ -# chmod - -- [Command Function](#section13992936121418) -- [Syntax](#section63342439147) -- [Parameter Description](#section894414671411) -- [Usage](#section182415221419) -- [Example](#section8518195718147) -- [Output](#section127391818158) - -## Command Function - -This command is used to change the file operation permission. - -## Syntax - -chmod \[_mode_\] \[_pathname_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

mode

-

Indicates the permission for a file or directory. The value is an octal number, representing the permission of User (owner), Group (group), or Other (other groups).

-

[0, 777]

-

pathname

-

Indicates the file path.

-

An existing file

-
- -## Usage - -By specifying the **mode** parameter before the file name, you can change the permission for this file. - -## Example - -Enter **chmod 666 hello-harmony.txt**. - -## Output - -**Figure 1** Changing the permission on the **hello-harmony.txt** file to **666** -![](figures/changing-the-permission-on-the-hello-harmony-txt-file-to-666.png "changing-the-permission-on-the-hello-harmony-txt-file-to-666") - diff --git a/en/device-dev/kernel/chown.md b/en/device-dev/kernel/chown.md deleted file mode 100644 index 39b3ed6e04da7941af5a86e6023766f319e8de94..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/chown.md +++ /dev/null @@ -1,69 +0,0 @@ -# chown - -- [Command Function](#section247414691513) -- [Syntax](#section14773151018159) -- [Parameter Description](#section598731391517) -- [Usage](#section16524152071510) -- [Example](#section17901152561510) -- [Output](#section15513163115816) - -## Command Function - -This command is used to change the owner and group of a specified file. - -## Syntax - -chown \[_owner_\] \[_group_\] \[_pathname_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

owner

-

Indicates the file owner.

-

[0, 0xFFFFFFFF]

-

group

-

Indicates the file group.

-
  • Left blank
  • [0, 0xFFFFFFFF]
-

pathname

-

Indicates the file path.

-

An existing file

-
- -## Usage - -- By specifying the **owner** and **group** parameters in this command, you can change the owner and group of the file. -- If the **owner** or **group** value is **-1**, the owner or group of the file will not be changed. -- The **group** parameter can be left blank. - -## Example - -Enter **chown 100 200 hello-harmony.txt**. - -## Output - -**Figure 1** Changing the owner and group of the hello-harmony.txt file to 100 and 200 respectively -![](figures/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png "changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively") - diff --git a/en/device-dev/kernel/commissioning.md b/en/device-dev/kernel/commissioning.md deleted file mode 100644 index f7be69f45389758ac2eb5493f63b52140cb0ffcc..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/commissioning.md +++ /dev/null @@ -1,15 +0,0 @@ -# Commissioning - -- **[Introduction to the Shell](introduction-to-the-shell.md)** - -- **[Shell Command Development Guidelines](shell-command-development-guidelines.md)** - -- **[Shell Command Programming Example](shell-command-programming-example.md)** - -- **[Shell Command Reference](shell-command-reference.md)** - -- **[Magic Key Usage](magic-key-usage.md)** - -- **[User-Space Exception Information](user-space-exception-information.md)** - - diff --git a/en/device-dev/kernel/cp.md b/en/device-dev/kernel/cp.md deleted file mode 100644 index e5c6d12695b650a2268fa6defe5371a2a78dd7bd..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/cp.md +++ /dev/null @@ -1,68 +0,0 @@ -# cp - -- [Command Function](#section6841203041513) -- [Syntax](#section24286359150) -- [Parameter Description](#section558617385152) -- [Usage](#section16128156162) -- [Example](#section19354171211618) -- [Output](#section16754183195914) - -## Command Function - -This command is used to create a copy for a file. - -## Syntax - -cp \[_SOURCEFILE_\] \[_DESTFILE_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

SOURCEFILE

-

Indicates the path to the source file.

-

Currently, only files are supported. Directories are not supported.

-

DESTFILE

-

Indicates the path to the destination file.

-

Both directories and files are supported.

-
- -## Usage - -- The name of the source file cannot be the same as that of the destination file in the same path. -- The source file must exist and cannot be a directory. -- The source file path supports wildcards: asterisks \(\*\) and question marks \(?\). The asterisk \(\*\) indicates any number of characters, and the question mark \(?\) represents a single character. The destination file path does not support wildcards. If the specified source file path matches multiple files, the destination file path must be a directory. -- If the destination file path is a directory, this directory must exist. In this case, the destination file is named after the source file. -- If the destination file path is a file, the directory for this file must exist. In this case, the file copy is renamed. -- Currently, this command can be used to copy only one file. If more than two parameters are specified, only the first two parameters take effect. -- If the destination file does not exist, a new file is created. If the destination file already exists, the existing file is overwritten. - -When important system resources are copied, unexpected results such as a system breakdown may occur. For example, when the **/dev/uartdev-0** file is copied, the system may stop responding. - -## Example - -Enter **cp hello-harmony.txt ./tmp/**. - -## Output - -**Figure 1** File copying result -![](figures/file-copying-result.png "file-copying-result") - diff --git a/en/device-dev/kernel/cpup.md b/en/device-dev/kernel/cpup.md deleted file mode 100644 index 0eb2985b3f8b471862be7f0a17350dce9cebf200..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/cpup.md +++ /dev/null @@ -1,63 +0,0 @@ -# cpup - -- [Command Function](#section1842161614217) -- [Syntax](#section5629527427) -- [Parameter Description](#section133651361023) -- [Usage](#section156611948521) -- [Example](#section68501605319) -- [Output](#section19871522144219) - -## Command Function - -This command is used to query the CPU usage of the system. - -## Syntax - -cpup \[_mode_\] \[_taskID_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

mode

-

Indicates the period in which the CPU usage is to be queried. By default, the CPU usage within the last 10 seconds is displayed.

-
  • 0: displays the CPU usage of the system within the last 10 seconds.
  • 1: displays the CPU usage of the system within the last 1 second.
  • Other value: displays the total CPU usage since the system is started.
-

[0, 0xFFFFFFFF]

-

taskID

-

Indicates the task ID.

-

[0, 0xFFFFFFFF]

-
- -## Usage - -- If the parameters are not specified, the CPU usage within the last 10 seconds is displayed. -- If only the **mode** parameter is specified, the CPU usage within the specified period is displayed. -- If both the **mode** and **taskID** parameters are specified, the CPU usage of the specified task within the given period is displayed. - -## Example - -Enter **cpup 1 5**. - -## Output - -**Figure 1** CPU usage -![](figures/cpu-usage.png "cpu-usage") - diff --git a/en/device-dev/kernel/date.md b/en/device-dev/kernel/date.md deleted file mode 100644 index f9e52b6c1cd360f4fd263340730bebf5c60eae56..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/date.md +++ /dev/null @@ -1,92 +0,0 @@ -# date - -- [Command Function](#section56472016338) -- [Syntax](#section16635112512316) -- [Parameter Description](#section15896030039) -- [Usage](#section116361036636) -- [Example](#section021711411237) -- [Output](#section17950184414312) - -## Command Function - -This command is used to query and set the system date and time. - -## Syntax - -date - -date --help - -date +\[_Format_\] - -date -s_ _\[_YY/MM/DD_\] - -date_ _-s_ _\[_hh:mm:ss_\]__ - -date -r \[_Filename_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

--help

-

Uses the help.

-

N/A

-

+Format

-

Prints the date and time based on Format.

-

Placeholders listed in --help.

-

-s YY/MM/DD

-

Sets the system date and separates the year, month, and day by slashes (/).

-

>= 1970/01/01

-

-s hh:mm:ss

-

Sets the system time and separates the hour, minute, and second by colons (:).

-

N/A

-

-r Filename

-

Queries the modification time of the Filename file.

-

N/A

-
- -## Usage - -- If the **date** parameter is not specified, the current system date and time are displayed by default. -- The **--help**, **+Format**, **-s**, and **-r** parameters are mutually exclusive. - -## Example - -Enter **date +%Y--%m--%d**. - -## Output - -**Figure 1** System date printed based on the specified format -![](figures/system-date-printed-based-on-the-specified-format.png "system-date-printed-based-on-the-specified-format") - diff --git a/en/device-dev/kernel/dhclient.md b/en/device-dev/kernel/dhclient.md deleted file mode 100644 index ab3f5ba9984951888a488e883d602f852d61d50c..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/dhclient.md +++ /dev/null @@ -1,138 +0,0 @@ -# dhclient - -- [Command Function](#section366714216619) -- [Syntax](#section8833164614615) -- [Parameter Description](#section12809111019453) -- [Usage](#section15935131220717) -- [Example](#section79281818476) -- [Output](#section12742311179) - -## Command Function - -This command is used to set and view **dhclient** parameters. - -## Syntax - -dhclient <_netif name_\> - -dhclient -x <_netif name_\> - -dhclient -gb <_netif name_\> - -dhclient -sv <_vendor_\> - -dhclient -gv - -dhclient -gd <_index_\> - -dhclient -sd <_dns\_ip_\> - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

<netif name>

-

Starts the DHCP request of the network interface card (NIC).

-

NIC name, eth0

-

-x <netif name>

-

Disables the DHCP function for the NIC.

-

NIC name, eth0

-

-gb <netif name>

-

Checks whether the DHCP request of the NIC is complete.

-

NIC name, eth0

-

-sv <vendor>

-

Sets the vendor information of a DHCP request.

-

Vendor information (The value is a string of 32 characters.)

-

-gv

-

Displays the vendor information in a DHCP request.

-

N/A

-

-gd <index>

-

Obtains information about the DNS server at the specified index.

-

Index, 0 or 1

-

-sd <dns_ip>

-

Indicates the IP address of the active DNS server.

-

IP address of the DNS server

-
- -## Usage - -dhclient eth0 - -dhclient -x eth0 - -dhclient -gb eth0 - -dhclient -sv MFSI - -dhclient -gv - -dhclient -gd 0 - -dhclient -sd 8.8.8.8 - -## Example - -![](figures/en-us_image_0000001053224218.png) - -## Output - -**Table 2** Output description - - - - - - - - - - - - - -

Parameter

-

Description

-

dhclient: set vendor info [MFSI] success

-

Indicates that the MFSI information is successfully set.

-

dns[0]: 192.168.1.100

-

Indicates that the IP address of the DNS server is 192.168.1.100.

-
- diff --git a/en/device-dev/kernel/dmesg.md b/en/device-dev/kernel/dmesg.md deleted file mode 100644 index 4890f812707b7308504c214a5157a751b4a3d665..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/dmesg.md +++ /dev/null @@ -1,111 +0,0 @@ -# dmesg - -- [Command Function](#section4643204919313) -- [Syntax](#section6553153635) -- [Parameter Description](#section208971157532) -- [Usage](#section213115219413) -- [Example](#section13736564418) -- [Output](#section194005101413) - -## Command Function - -This command is used to control the dmesg buffer of the kernel. - -## Syntax - -dmesg - -dmesg \[_-c/-C/-D/-E/-L/-U_\] - -dmesg -s \[_size_\] - -dmesg -l \[_level_\] - -dmesg \> \[_fileA_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

-c

-

Prints content in the buffer and clears the buffer.

-

N/A

-

-C

-

Clears the buffer.

-

N/A

-

-D/-E

-

Enables or disables printing to the console.

-

N/A

-

-L/-U

-

Enables or disables printing via the serial port.

-

N/A

-

-s size

-

Sets the size of the buffer.

-

N/A

-

-l level

-

Sets the buffering level.

-

0 - 5

-

> fileA

-

Writes the content in the buffer to a file.

-

N/A

-
- -## Usage - -- This command depends on **LOSCFG\_SHELL\_DMESG**. Before running this command, enable the **Enable Shell dmesg** configuration item using **menuconfig**. - - Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell dmesg - -- If the parameters are not specified, all content in the buffer is printed. -- The parameters followed by hyphens \(-\) are mutually exclusive. - 1. Before writing content to a file, ensure that the file system has been mounted. - 2. Disabling the serial port printing will adversely affect the shell. You are advised to set up a connection using Telnet before disabling the serial port. - - -## Example - -Enter **dmesg \> /usr/dmesg.log**. - -## Output - -**Figure 1** Writing dmesg content to a file -![](figures/writing-dmesg-content-to-a-file.png "writing-dmesg-content-to-a-file") - diff --git a/en/device-dev/kernel/exec.md b/en/device-dev/kernel/exec.md deleted file mode 100644 index 3db30ca0a4ee351d499fea9431203c046b9f5202..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/exec.md +++ /dev/null @@ -1,58 +0,0 @@ -# exec - -- [Command Function](#section4643204919313) -- [Syntax](#section6553153635) -- [Parameter Description](#section208971157532) -- [Usage](#section213115219413) -- [Example](#section13736564418) -- [Output](#section194005101413) - -## Command Function - -This command is a built-in shell command used to execute user-space programs. - -## Syntax - -exec <_executable-file_\> - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

executable-file

-

Indicates a valid executable file.

-

N/A

-
- -## Usage - -Currently, this command supports only valid binary programs. The programs are successfully executed and then run in the background by default. However, the programs share the same device with the shell. As a result, the output of the programs and the shell may be interlaced. - -## Example - -Enter **exec helloworld**. - -## Output - -``` -OHOS # exec helloworld -OHOS # hello world! -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->After the executable file is executed, prompt **OHOS \#** is printed first. The shell **exec** command is executed in the background, causing the prompt to be printed in advance. - diff --git a/en/device-dev/kernel/figures/changing-the-group-of-the-hello-harmony-txt-file-to-100.png b/en/device-dev/kernel/figure/changing-the-group-of-the-hello-harmony-txt-file-to-100.png similarity index 100% rename from en/device-dev/kernel/figures/changing-the-group-of-the-hello-harmony-txt-file-to-100.png rename to en/device-dev/kernel/figure/changing-the-group-of-the-hello-harmony-txt-file-to-100.png diff --git a/en/device-dev/kernel/figures/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png b/en/device-dev/kernel/figure/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png similarity index 100% rename from en/device-dev/kernel/figures/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png rename to en/device-dev/kernel/figure/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png diff --git a/en/device-dev/kernel/figures/changing-the-permission-on-the-hello-harmony-txt-file-to-666.png b/en/device-dev/kernel/figure/changing-the-permission-on-the-hello-harmony-txt-file-to-666.png similarity index 100% rename from en/device-dev/kernel/figures/changing-the-permission-on-the-hello-harmony-txt-file-to-666.png rename to en/device-dev/kernel/figure/changing-the-permission-on-the-hello-harmony-txt-file-to-666.png diff --git a/en/device-dev/kernel/figures/command-output-0.png b/en/device-dev/kernel/figure/command-output-19.png similarity index 100% rename from en/device-dev/kernel/figures/command-output-0.png rename to en/device-dev/kernel/figure/command-output-19.png diff --git a/en/device-dev/kernel/figures/command-output.png b/en/device-dev/kernel/figure/command-output.png similarity index 100% rename from en/device-dev/kernel/figures/command-output.png rename to en/device-dev/kernel/figure/command-output.png diff --git a/en/device-dev/kernel/figures/cpu-usage.png b/en/device-dev/kernel/figure/cpu-usage.png similarity index 100% rename from en/device-dev/kernel/figures/cpu-usage.png rename to en/device-dev/kernel/figure/cpu-usage.png diff --git a/en/device-dev/kernel/figures/creating-file-c.png b/en/device-dev/kernel/figure/creating-file-c.png similarity index 100% rename from en/device-dev/kernel/figures/creating-file-c.png rename to en/device-dev/kernel/figure/creating-file-c.png diff --git a/en/device-dev/kernel/figures/creating-the-share-directory.png b/en/device-dev/kernel/figure/creating-the-share-directory.png similarity index 100% rename from en/device-dev/kernel/figures/creating-the-share-directory.png rename to en/device-dev/kernel/figure/creating-the-share-directory.png diff --git a/en/device-dev/kernel/figures/deleting-directory-dir.png b/en/device-dev/kernel/figure/deleting-directory-dir.png similarity index 100% rename from en/device-dev/kernel/figures/deleting-directory-dir.png rename to en/device-dev/kernel/figure/deleting-directory-dir.png diff --git a/en/device-dev/kernel/figures/deleting-the-log1-txt-file.png b/en/device-dev/kernel/figure/deleting-the-log1-txt-file.png similarity index 100% rename from en/device-dev/kernel/figures/deleting-the-log1-txt-file.png rename to en/device-dev/kernel/figure/deleting-the-log1-txt-file.png diff --git a/en/device-dev/kernel/figures/deleting-the-sd-directory.png b/en/device-dev/kernel/figure/deleting-the-sd-directory.png similarity index 100% rename from en/device-dev/kernel/figures/deleting-the-sd-directory.png rename to en/device-dev/kernel/figure/deleting-the-sd-directory.png diff --git a/en/device-dev/kernel/figures/directory-switching-result.png b/en/device-dev/kernel/figure/directory-switching-result.png similarity index 100% rename from en/device-dev/kernel/figures/directory-switching-result.png rename to en/device-dev/kernel/figure/directory-switching-result.png diff --git a/en/device-dev/kernel/figures/displaying-the-memory-usage-in-three-units.png b/en/device-dev/kernel/figure/displaying-the-memory-usage-in-three-units.png similarity index 100% rename from en/device-dev/kernel/figures/displaying-the-memory-usage-in-three-units.png rename to en/device-dev/kernel/figure/displaying-the-memory-usage-in-three-units.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001051690323.png b/en/device-dev/kernel/figure/en-us_image_0000001051690323.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001051690323.png rename to en/device-dev/kernel/figure/en-us_image_0000001051690323.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001052370303.png b/en/device-dev/kernel/figure/en-us_image_0000001052370303.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001052370303.png rename to en/device-dev/kernel/figure/en-us_image_0000001052370303.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001052370305.png b/en/device-dev/kernel/figure/en-us_image_0000001052370305.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001052370305.png rename to en/device-dev/kernel/figure/en-us_image_0000001052370305.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001052370307.png b/en/device-dev/kernel/figure/en-us_image_0000001052370307.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001052370307.png rename to en/device-dev/kernel/figure/en-us_image_0000001052370307.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001052530298.png b/en/device-dev/kernel/figure/en-us_image_0000001052530298.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001052530298.png rename to en/device-dev/kernel/figure/en-us_image_0000001052530298.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001052810300.png b/en/device-dev/kernel/figure/en-us_image_0000001052810300.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001052810300.png rename to en/device-dev/kernel/figure/en-us_image_0000001052810300.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001052810304.png b/en/device-dev/kernel/figure/en-us_image_0000001052810304.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001052810304.png rename to en/device-dev/kernel/figure/en-us_image_0000001052810304.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001053224218.png b/en/device-dev/kernel/figure/en-us_image_0000001053224218.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001053224218.png rename to en/device-dev/kernel/figure/en-us_image_0000001053224218.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001053710680.png b/en/device-dev/kernel/figure/en-us_image_0000001053710680.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001053710680.png rename to en/device-dev/kernel/figure/en-us_image_0000001053710680.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001053826366.png b/en/device-dev/kernel/figure/en-us_image_0000001053826366.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001053826366.png rename to en/device-dev/kernel/figure/en-us_image_0000001053826366.png diff --git a/en/device-dev/kernel/figures/en-us_image_0000001054624363.png b/en/device-dev/kernel/figure/en-us_image_0000001054624363.png similarity index 100% rename from en/device-dev/kernel/figures/en-us_image_0000001054624363.png rename to en/device-dev/kernel/figure/en-us_image_0000001054624363.png diff --git a/en/device-dev/kernel/figures/file-copying-result.png b/en/device-dev/kernel/figure/file-copying-result.png similarity index 100% rename from en/device-dev/kernel/figures/file-copying-result.png rename to en/device-dev/kernel/figure/file-copying-result.png diff --git a/en/device-dev/kernel/figures/no-out-of-bounds-memory-access.png b/en/device-dev/kernel/figure/no-out-of-bounds-memory-access.png similarity index 100% rename from en/device-dev/kernel/figures/no-out-of-bounds-memory-access.png rename to en/device-dev/kernel/figure/no-out-of-bounds-memory-access.png diff --git a/en/device-dev/kernel/figures/out-of-bounds-memory-access.png b/en/device-dev/kernel/figure/out-of-bounds-memory-access.png similarity index 100% rename from en/device-dev/kernel/figures/out-of-bounds-memory-access.png rename to en/device-dev/kernel/figure/out-of-bounds-memory-access.png diff --git a/en/device-dev/kernel/figures/output-of-telnet-on.png b/en/device-dev/kernel/figure/output-of-telnet-on.png similarity index 100% rename from en/device-dev/kernel/figures/output-of-telnet-on.png rename to en/device-dev/kernel/figure/output-of-telnet-on.png diff --git a/en/device-dev/kernel/figures/output-of-the-statfs-command.png b/en/device-dev/kernel/figure/output-of-the-statfs-command.png similarity index 100% rename from en/device-dev/kernel/figures/output-of-the-statfs-command.png rename to en/device-dev/kernel/figure/output-of-the-statfs-command.png diff --git a/en/device-dev/kernel/figures/posix-framework.png b/en/device-dev/kernel/figure/posix-framework.png similarity index 100% rename from en/device-dev/kernel/figures/posix-framework.png rename to en/device-dev/kernel/figure/posix-framework.png diff --git a/en/device-dev/kernel/figures/querying-information-about-a-specified-software-timer.png b/en/device-dev/kernel/figure/querying-information-about-a-specified-software-timer.png similarity index 100% rename from en/device-dev/kernel/figures/querying-information-about-a-specified-software-timer.png rename to en/device-dev/kernel/figure/querying-information-about-a-specified-software-timer.png diff --git a/en/device-dev/kernel/figures/querying-information-about-all-semaphores-in-use.png b/en/device-dev/kernel/figure/querying-information-about-all-semaphores-in-use.png similarity index 100% rename from en/device-dev/kernel/figures/querying-information-about-all-semaphores-in-use.png rename to en/device-dev/kernel/figure/querying-information-about-all-semaphores-in-use.png diff --git a/en/device-dev/kernel/figures/querying-information-about-all-software-timers.png b/en/device-dev/kernel/figure/querying-information-about-all-software-timers.png similarity index 100% rename from en/device-dev/kernel/figures/querying-information-about-all-software-timers.png rename to en/device-dev/kernel/figure/querying-information-about-all-software-timers.png diff --git a/en/device-dev/kernel/figures/querying-partial-task-information.png b/en/device-dev/kernel/figure/querying-partial-task-information.png similarity index 100% rename from en/device-dev/kernel/figures/querying-partial-task-information.png rename to en/device-dev/kernel/figure/querying-partial-task-information.png diff --git a/en/device-dev/kernel/figures/querying-pids.png b/en/device-dev/kernel/figure/querying-pids.png similarity index 100% rename from en/device-dev/kernel/figures/querying-pids.png rename to en/device-dev/kernel/figure/querying-pids.png diff --git a/en/device-dev/kernel/figures/querying-the-current-path.png b/en/device-dev/kernel/figure/querying-the-current-path.png similarity index 100% rename from en/device-dev/kernel/figures/querying-the-current-path.png rename to en/device-dev/kernel/figure/querying-the-current-path.png diff --git a/en/device-dev/kernel/figures/relationship-between-the-vfs-and-file-systems.png b/en/device-dev/kernel/figure/relationship-between-the-vfs-and-file-systems.png similarity index 100% rename from en/device-dev/kernel/figures/relationship-between-the-vfs-and-file-systems.png rename to en/device-dev/kernel/figure/relationship-between-the-vfs-and-file-systems.png diff --git a/en/device-dev/kernel/figures/sending-a-signal-to-a-specified-process.png b/en/device-dev/kernel/figure/sending-a-signal-to-a-specified-process.png similarity index 100% rename from en/device-dev/kernel/figures/sending-a-signal-to-a-specified-process.png rename to en/device-dev/kernel/figure/sending-a-signal-to-a-specified-process.png diff --git a/en/device-dev/kernel/figures/signal-sending-failure.png b/en/device-dev/kernel/figure/signal-sending-failure.png similarity index 100% rename from en/device-dev/kernel/figures/signal-sending-failure.png rename to en/device-dev/kernel/figure/signal-sending-failure.png diff --git a/en/device-dev/kernel/figures/snipaste_2021-01-26_10-38-58-1.png b/en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58-20.png similarity index 100% rename from en/device-dev/kernel/figures/snipaste_2021-01-26_10-38-58-1.png rename to en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58-20.png diff --git a/en/device-dev/kernel/figures/snipaste_2021-01-26_10-38-58-2.png b/en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58-21.png similarity index 100% rename from en/device-dev/kernel/figures/snipaste_2021-01-26_10-38-58-2.png rename to en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58-21.png diff --git a/en/device-dev/kernel/figures/snipaste_2021-01-26_10-38-58.png b/en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58.png similarity index 100% rename from en/device-dev/kernel/figures/snipaste_2021-01-26_10-38-58.png rename to en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58.png diff --git a/en/device-dev/kernel/figures/state-transition-of-a-process.png b/en/device-dev/kernel/figure/state-transition-of-a-process.png similarity index 100% rename from en/device-dev/kernel/figures/state-transition-of-a-process.png rename to en/device-dev/kernel/figure/state-transition-of-a-process.png diff --git a/en/device-dev/kernel/figures/state-transition-of-a-thread.png b/en/device-dev/kernel/figure/state-transition-of-a-thread.png similarity index 100% rename from en/device-dev/kernel/figures/state-transition-of-a-thread.png rename to en/device-dev/kernel/figure/state-transition-of-a-thread.png diff --git a/en/device-dev/kernel/figures/switching-to-the-user-whose-uid-and-gid-are-both-1000.png b/en/device-dev/kernel/figure/switching-to-the-user-whose-uid-and-gid-are-both-1000.png similarity index 100% rename from en/device-dev/kernel/figures/switching-to-the-user-whose-uid-and-gid-are-both-1000.png rename to en/device-dev/kernel/figure/switching-to-the-user-whose-uid-and-gid-are-both-1000.png diff --git a/en/device-dev/kernel/figures/system-date-printed-based-on-the-specified-format.png b/en/device-dev/kernel/figure/system-date-printed-based-on-the-specified-format.png similarity index 100% rename from en/device-dev/kernel/figures/system-date-printed-based-on-the-specified-format.png rename to en/device-dev/kernel/figure/system-date-printed-based-on-the-specified-format.png diff --git a/en/device-dev/kernel/figures/task-command-monitoring-result.png b/en/device-dev/kernel/figure/task-command-monitoring-result.png similarity index 100% rename from en/device-dev/kernel/figures/task-command-monitoring-result.png rename to en/device-dev/kernel/figure/task-command-monitoring-result.png diff --git a/en/device-dev/kernel/figures/tree-structure-of-the-file-system.png b/en/device-dev/kernel/figure/tree-structure-of-the-file-system.png similarity index 100% rename from en/device-dev/kernel/figures/tree-structure-of-the-file-system.png rename to en/device-dev/kernel/figure/tree-structure-of-the-file-system.png diff --git a/en/device-dev/kernel/figures/unmounting-result.png b/en/device-dev/kernel/figure/unmounting-result.png similarity index 100% rename from en/device-dev/kernel/figures/unmounting-result.png rename to en/device-dev/kernel/figure/unmounting-result.png diff --git a/en/device-dev/kernel/figures/usage-of-system-resources.png b/en/device-dev/kernel/figure/usage-of-system-resources.png similarity index 100% rename from en/device-dev/kernel/figures/usage-of-system-resources.png rename to en/device-dev/kernel/figure/usage-of-system-resources.png diff --git a/en/device-dev/kernel/figures/viewing-content-of-the-current-directory.png b/en/device-dev/kernel/figure/viewing-content-of-the-current-directory.png similarity index 100% rename from en/device-dev/kernel/figures/viewing-content-of-the-current-directory.png rename to en/device-dev/kernel/figure/viewing-content-of-the-current-directory.png diff --git a/en/device-dev/kernel/figures/viewing-content-of-the-hello-harmony-txt-file.png b/en/device-dev/kernel/figure/viewing-content-of-the-hello-harmony-txt-file.png similarity index 100% rename from en/device-dev/kernel/figures/viewing-content-of-the-hello-harmony-txt-file.png rename to en/device-dev/kernel/figure/viewing-content-of-the-hello-harmony-txt-file.png diff --git a/en/device-dev/kernel/figures/viewing-the-usage-of-physical-pages.png b/en/device-dev/kernel/figure/viewing-the-usage-of-physical-pages.png similarity index 100% rename from en/device-dev/kernel/figures/viewing-the-usage-of-physical-pages.png rename to en/device-dev/kernel/figure/viewing-the-usage-of-physical-pages.png diff --git a/en/device-dev/kernel/figures/virtual-memory-usage-of-the-process-with-pid-3.png b/en/device-dev/kernel/figure/virtual-memory-usage-of-the-process-with-pid-3.png similarity index 100% rename from en/device-dev/kernel/figures/virtual-memory-usage-of-the-process-with-pid-3.png rename to en/device-dev/kernel/figure/virtual-memory-usage-of-the-process-with-pid-3.png diff --git a/en/device-dev/kernel/figures/writing-dmesg-content-to-a-file.png b/en/device-dev/kernel/figure/writing-dmesg-content-to-a-file.png similarity index 100% rename from en/device-dev/kernel/figures/writing-dmesg-content-to-a-file.png rename to en/device-dev/kernel/figure/writing-dmesg-content-to-a-file.png diff --git a/en/device-dev/kernel/file-commands.md b/en/device-dev/kernel/file-commands.md deleted file mode 100644 index b75130d6cdb08de238a18e95a0b03e811f9c0f28..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/file-commands.md +++ /dev/null @@ -1,45 +0,0 @@ -# File Commands - -- **[cat](cat.md)** - -- **[cd](cd.md)** - -- **[chgrp](chgrp.md)** - -- **[chmod](chmod.md)** - -- **[chown](chown.md)** - -- **[cp](cp.md)** - -- **[format](format.md)** - -- **[ls](ls.md)** - -- **[lsfd](lsfd.md)** - -- **[mkdir](mkdir.md)** - -- **[mount](mount.md)** - -- **[partinfo](partinfo.md)** - -- **[partition](partition.md)** - -- **[pwd](pwd.md)** - -- **[rm](rm.md)** - -- **[rmdir](rmdir.md)** - -- **[statfs](statfs.md)** - -- **[sync](sync.md)** - -- **[touch](touch.md)** - -- **[writeproc](writeproc.md)** - -- **[umount](umount.md)** - - diff --git a/en/device-dev/kernel/format.md b/en/device-dev/kernel/format.md deleted file mode 100644 index 11336955c0987b66e83d272edda4b12e36a52b30..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/format.md +++ /dev/null @@ -1,69 +0,0 @@ -# format - -- [Command Function](#section1922331919169) -- [Syntax](#section249226169) -- [Parameter Description](#section985173416177) -- [Usage](#section1510162714162) -- [Example](#section25691431161611) -- [Output](#section17368112365920) - -## Command Function - -This command is used to format a disk. - -## Syntax - -format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

dev_inodename

-

Indicates the device name.

-

sectors

-

Indicates the size of the allocated memory unit or sector. The value 0 indicates that the parameter is null. (The value must be 0 or a power of 2. For FAT32, the maximum value is 128. If the parameter is set to 0, a proper cluster size is automatically selected. The available cluster size range varies depending on the partition size. If the cluster size is incorrectly specified, the formatting may fail.)

-

option

-
Indicates the formatting option for selecting the file system type. The options are as follows:
  • 0x01: FMT_FAT
  • 0x02: FMT_FAT32
  • 0x07: FMT_ANY
  • 0x08: FMT_ERASE (not supported by the USB flash drive)
-
-

Other values are invalid. The system will automatically select the formatting mode. If the low-level formatting bit is 1 during the formatting of a USB flash drive, an error message is printed.

-

label

-

Indicates the volume label name. This parameter is optional, and the value is a string. If null is specified for this parameter, the previously set volume label name is cleared.

-
- -## Usage - -- The **format** command is used to format a disk. You can find the device name in the **dev** directory. A storage card must be installed before the formatting. -- This command can be used to format only the USB flash drive, SD card, and MMC, but not the NAND flash and NOR flash. -- The **sectors** parameter must be set to a valid value. An invalid value may cause exceptions. - -## Example - -Enter **format /dev/mmcblk0 128 2**. - -## Output - -Formatting result - -![](figures/en-us_image_0000001052370307.png) - diff --git a/en/device-dev/kernel/free.md b/en/device-dev/kernel/free.md deleted file mode 100644 index 640004a9f60ae70c204fde9d9d11de93ce085aed..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/free.md +++ /dev/null @@ -1,119 +0,0 @@ -# free - -- [Command Function](#section175151514841) -- [Syntax](#section8488721749) -- [Parameter Description](#section27272181949) -- [Usage](#section148661259410) -- [Example](#section68081530242) -- [Output](#section171235517543) - -## Command Function - -This command is used to display the system memory usage and the sizes of the **text**, **data**, **rodata**, and **bss** segments. - -## Syntax - -free \[_-k | -m_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

No parameter

-

Displays the size in the unit of byte.

-

N/A

-

-k

-

Displays the size in the unit of KB.

-

N/A

-

-m

-

Displays the size in the unit of MB.

-

N/A

-
- -## Usage - -None - -## Example - -Enter **free**, **free -k**, and **free -m**, respectively. - -## Output - -**Figure 1** Displaying the memory usage in three units -![](figures/displaying-the-memory-usage-in-three-units.png "displaying-the-memory-usage-in-three-units") - -**Table 2** Output description - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

total

-

Indicates the total size of the dynamic memory pool.

-

used

-

Indicates the size of the used memory.

-

free

-

Indicates the size of the unallocated memory.

-

heap

-

Indicates the size of the allocated heap.

-

text

-

Indicates the size of a code segment.

-

data

-

Indicates the size of a data segment.

-

rodata

-

Indicates the size of a read-only data segment.

-

bss

-

Indicates the size of the memory occupied by uninitialized global variables.

-
- diff --git a/en/device-dev/kernel/guidelines-for-compiling-and-building-the-linux-kernel.md b/en/device-dev/kernel/guidelines-for-compiling-and-building-the-linux-kernel.md deleted file mode 100644 index a310e530bfb4368baaca86b1095c384d20f02912..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/guidelines-for-compiling-and-building-the-linux-kernel.md +++ /dev/null @@ -1,45 +0,0 @@ -# Guidelines for Compiling and Building the Linux Kernel - -- [Example of Development Using the Hi3516D V300 Board and Ubuntu x86 Server](#section19369206113115) - - [Scenario 1: building the native kernel at the version level](#section1025111193220) - - [Scenario 2: building the modified kernel separately](#section17446652173211) - - -## Example of Development Using the Hi3516D V300 Board and Ubuntu x86 Server - -### Scenario 1: building the native kernel at the version level - -Perform a full build for the project to generate the **uImage** kernel image. - -``` -./build.sh --product-name Hi3516DV300 # Build the uImage kernel image of the Hi3516D V300 board. -``` - -### Scenario 2: building the modified kernel separately - -1. Set up the build environment. - - 1. Merge the required patch by referring to [guidelines for using patches on development boards](guidelines-for-using-patches-on-openharmony-development-boards.md). - 2. Prepare for the build environment. You can use the Arm Clang or GCC compiler. - - Enter the root directory of the project and configure environment variables: - - ``` - export PATH=`pwd`/prebuilts/clang/host/linux-x86/clang-r353983c/bin:`pwd`/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/:$PATH # Configure the build environment. - MAKE_OPTIONES="ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CC=clang HOSTCC=clang" # Use Clang provided by the project. - ``` - -2. Modify the kernel code or kernel configuration \(**defconfig** file provided by OpenHarmony can be used for reference\). -3. Create a build directory and generate the **.config** file of the kernel. - - ``` - make ${MAKE_OPTIONES} hi3516dv300_emmc_smp_hos_l2_defconfig # Use the defconfig file to build the kernel. - ``` - -4. Build the kernel image. - - ``` - make ${MAKE_OPTIONES} -j32 uImage # Build the uImage kernel image. - ``` - - diff --git a/en/device-dev/kernel/guidelines-for-using-patches-on-openharmony-development-boards.md b/en/device-dev/kernel/guidelines-for-using-patches-on-openharmony-development-boards.md deleted file mode 100644 index 6b05e850113e75cf1f21dc6a68a3a0a836552f51..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/guidelines-for-using-patches-on-openharmony-development-boards.md +++ /dev/null @@ -1,17 +0,0 @@ -# Guidelines for Using Patches on OpenHarmony Development Boards - -The patch files are stored in the **kernel/linux/patches/linux-4.19** source code path of the project. You can obtain the driver patch of a specific chip architecture from this directory. - -To use the patch of a specific chip platform driver, you need to merge the required kernel patch into the kernel code. - -Merge the corresponding patches for different chip platforms. - -The following uses Hi3516D V300 as an example: - -``` -patch -p1 < device/hisilicon/hi3516dv300/sdk_linux/open_source/linux/hisi_linux-4.19_hos_l2.patch -``` - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->Because patches are applied after the code environment of **kernel/linux-4.19** is copied during compilation and building of the OpenHarmony project, you must retain the original code environment of **kernel/linux-4.19** before running the OpenHarmony version-level build command. - diff --git a/en/device-dev/kernel/hwi.md b/en/device-dev/kernel/hwi.md deleted file mode 100644 index 72d7bd3f10e5f63e42cb4989259c76e187a9d4a6..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/hwi.md +++ /dev/null @@ -1,94 +0,0 @@ -# hwi - -- [Command Function](#section445335110416) -- [Syntax](#section1795712553416) -- [Parameter Description](#section92544592410) -- [Usage](#section104151141252) -- [Example](#section11545171957) -- [Output](#section075617368542) - -## Command Function - -This command is used to query information about the current interrupts. - -## Syntax - -hwi - -## Parameter Description - -None - -## Usage - -- Enter **hwi** to display the current interrupt ID, count of interrupts, and registered interrupt name. -- If **LOSCFG\_CPUP\_INCLUDE\_IRQ** is enabled, the processing time \(cycles\), CPU usage, and interrupt type of each interrupt are displayed. - -## Example - -Enter **hwi**. - -## Output - -1. Interrupt information \(with **LOSCFG\_CPUP\_INCLUDE\_IRQ** disabled\) - - ![](figures/en-us_image_0000001053826366.png) - -2. Interrupt information \(with **LOSCFG\_CPUP\_INCLUDE\_IRQ** enabled\) - - ![](figures/en-us_image_0000001052810304.png) - - **Table 1** Output description - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

InterruptNo

-

Indicates the interrupt ID.

-

Count

-

Indicates the count of interrupts.

-

Name

-

Indicates the registered interrupt name.

-

CYCLECOST

-

Indicates the interrupt processing time (cycles).

-

CPUUSE

-

Indicates the CPU usage.

-

CPUUSE10s

-

Indicates CPU usage within the last 10 seconds.

-

CPUUSE1s

-

Indicates CPU usage within the last 1 second.

-

mode

-

Indicates the interrupt mode.

-
  • normal: non-shared interrupt.
  • shared: shared interrupt.
-
- - diff --git a/en/device-dev/kernel/introduction-to-the-shell.md b/en/device-dev/kernel/introduction-to-the-shell.md deleted file mode 100644 index 497aade9dff0b3e08f776b7f97d4ca0544b39ab3..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/introduction-to-the-shell.md +++ /dev/null @@ -1,36 +0,0 @@ -# Introduction to the Shell - -- [Important Notes](#section12298165312328) - -The Shell provided by the OpenHarmony kernel supports commonly used commissioning commands, including those related to the system, files, networks, and dynamic loading. In addition, you can add custom commands to the shell of the OpenHarmony kernel to address your service needs. - -- System-related commands: querying information about system tasks, kernel semaphores, system software timers, CPU usage, and current interrupts - -- File-related commands: basic functions such as **ls** and **cd** - -- Network-related commands: querying the IP addresses of other devices connected to the development board, querying the IP address of the local device, testing the network connectivity, and setting the access point \(AP\) and station modes of the development board - - For details about the process of adding commands, see [Shell Command Development Guidelines](shell-command-development-guidelines.md) and [Shell Command Programming Example](shell-command-programming-example.md). - - -## Important Notes - -Note the following when using the shell: - -- You can use the **exec** command to run executable files. -- The shell supports English input in default mode. If you enter Chinese characters in the UTF-8 format, you can delete them only by pressing the backspace key for three times. - -- When entering shell commands, file names, and directory names, you can press **Tab** to enable automatic completion. If there are multiple completions, multiple items are printed based on the same characters they have. If more than 24 lines of completions are available, the system displays message "Display all num possibilities?\(y/n\)", asking you to determine whether to print all items. You can enter **y** to print all items or enter **n** to exit the printing. If more than 24 lines are printed after your selection, the system displays "--More--". In this case, you can press **Enter** to continue the printing or press **q** \(or **Ctrl+c**\) to exit. - -- The shell working directory is separated from the system working directory. You can run commands such as **cd** and **pwd** on the shell to perform operations on the shell working directory, and run commands such as **chdir** and **getcwd** to perform operations on the system working directory. Pay special attention when an input parameter in a file system operation command is a relative path. - -- Before using network shell commands, you need to call the **tcpip\_init** function to initialize the network and set up the Telnet connection. By default, the kernel does not call **tcpip\_init**. - -- You are not advised to run shell commands to perform operations on device files in the **/dev** directory, which may cause unexpected results. - -- The shell functions do not comply with the POSIX standards and are used only for commissioning. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The shell functions are used for commissioning only and can be enabled only in the Debug version \(by enabling the **LOSCFG\_DEBUG\_VERSION** configuration item using **menuconfig**\). - - diff --git a/en/device-dev/kernel/kernel-lite-mini.md b/en/device-dev/kernel/kernel-lite-mini.md new file mode 100644 index 0000000000000000000000000000000000000000..f87451dcc80d174191386a4112bd676fe6a9ab4b --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-mini.md @@ -0,0 +1,2 @@ +# Kernel for Mini Systems + diff --git a/en/device-dev/kernel/kernel-lite-small-basic.md b/en/device-dev/kernel/kernel-lite-small-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..d373831984d8fa1e3dd10572af268edf6444f4c1 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-basic.md @@ -0,0 +1,11 @@ +# Basic Kernel + +- **[Process](kernel-lite-small-process.md)** + +- **[Thread](kernel-lite-small-thread.md)** + +- **[Memory](kernel-lite-small-memory.md)** + +- **[Network](kernel-lite-small-net.md)** + + diff --git a/en/device-dev/kernel/fat.md b/en/device-dev/kernel/kernel-lite-small-file-fat.md similarity index 100% rename from en/device-dev/kernel/fat.md rename to en/device-dev/kernel/kernel-lite-small-file-fat.md diff --git a/en/device-dev/kernel/jffs2.md b/en/device-dev/kernel/kernel-lite-small-file-jffs.md similarity index 100% rename from en/device-dev/kernel/jffs2.md rename to en/device-dev/kernel/kernel-lite-small-file-jffs.md diff --git a/en/device-dev/kernel/kernel-lite-small-file-nfs.md b/en/device-dev/kernel/kernel-lite-small-file-nfs.md new file mode 100644 index 0000000000000000000000000000000000000000..7b93df28d139c1347f291481370518c7ccb3bbb1 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-file-nfs.md @@ -0,0 +1,163 @@ +# NFS + +- [Overview](#section18322139164413) +- [Important Notes](#section532912331467) +- [Development Guidelines](#section166873374711) + +## Overview + +NFS allows you to share files across hosts and OSs over a network. You can treat NFS as a file system service, which is equivalent to folder sharing in the Windows OS to some extent. + +An NFS client can mount a directory shared by a remote NFS server to the local host to run programs and share files without occupying the current system resources. The directory of the remote server is like a disk to the local host. + +## Important Notes + +- NFS files do not support permissions control. Use file permission **777** when creating NFS directories and files. + +- NFS files do not support read or write blocking. + +- NFS files do not support the signal function. + +- In NFS, the path length \(excluding the IP address\) in a **mount** operation cannot exceed 255 characters. If the maximum length is exceeded, the error code **ENAMETOOLONG** error is returned. + +- You can perform the following operation on NFS files: **open**, **close**, **read**, **write**, **seek**, **dup**, **dup2**, **sync**, **opendir**, **closedir**, **readdir**, **readdir\_r**, **rewinddir**, **scandir**, **statfs**, **remove**, **unlink**, **mkdir**, **rmdir**, **rename**, **stat**, **stat64**, **seek64**, **mmap**, **mount**, and **umount**. + +- Two transport layer protocols are supported in NFS: TCP \(default\) and UDP. + +- When you use **open** with the parameter **O\_TRUNC** to open a file, the file content will be cleared only when you have the write permission on the file. + +- When file A is not closed and the **rename\(\)** function renames file A as B, the fd is not changed. + +- The NFS feature is currently in the beta test and may be unstable. You are advised not to use the feature in commercial products. + + +## Development Guidelines + +1. **Create an NFS server.** + + This section uses the Ubuntu operating system \(OS\) as an example to describe how to configure an NFS server. + + 1. Install the NFS server software. + + Set the download source of the Ubuntu OS when the network connection is normal. + + ``` + sudo apt-get install nfs-kernel-server + ``` + + 2. Create a directory for mounting and set full permissions for the directory. + + ``` + mkdir /home/sqbin/nfs + sudo chmod 777 /home/sqbin/nfs + ``` + + 3. Configure and start the NFS server. + + Append the following line in the **/etc/exports** file: + + ``` + /home/sqbin/nfs *(rw,no_root_squash,async) + ``` + + **/home/sqbin/nfs** is the root directory shared by the NFS server. + + Start the NFS server. + + ``` + sudo /etc/init.d/nfs-kernel-server start + ``` + + Restart the NFS server. + + ``` + sudo /etc/init.d/nfs-kernel-server restart + ``` + + +2. **Configure a board as the NFS client.** + + In this section, the NFS client is a device running the OpenHarmony kernel. + + 1. Set the hardware connection. + + Connect the OpenHarmony kernel device to the NFS server. Set their IP addresses in the same network segment. For example, set the IP address of the NFS server to **10.67.212.178/24** and set the IP address of the OpenHarmony kernel device to **10.67.212.3/24**. Note that the preceding IP addresses are private IP addresses used as examples. You need to use your actual IP addresses. + + You can run the **ifconfig** command to view the device's IP address. + + 2. Start the network and ensure that the network between the board and NFS server is normal. + + Start the Ethernet or another type of network, and then run **ping** to check whether the network connection to the server is normal. + + ``` + OHOS # ping 10.67.212.178 + [0]Reply from 10.67.212.178: time=1ms TTL=63 + [1]Reply from 10.67.212.178: time=0ms TTL=63 + [2]Reply from 10.67.212.178: time=1ms TTL=63 + [3]Reply from 10.67.212.178: time=1ms TTL=63 + --- 10.67.212.178 ping statistics --- + 4 packets transmitted, 4 received, 0 loss + ``` + + Initialize the NFS client. + + ``` + OHOS # mkdir /nfs + OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 + ``` + + If the following information is displayed, the NFS client is initialized. + + ``` + OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 + Mount nfs on 10.67.212.178:/home/sqbin/nfs, uid:1011, gid:1000 + Mount nfs finished. + ``` + + This command mounts the **/home/sqbin/nfs** directory on the NFS server whose IP address is 10.67.212.178 to the **/nfs** directory on the device. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >This section assumes that the NFS server is available, that is, the **/home/sqbin/nfs** directory on the NFS server 10.67.212.178 is accessible. + + The **mount** command format is as follows: + + ``` + mount nfs + ``` + + In this command, **SERVER\_IP** indicates the IP address of the NFS server, **SERVER\_PATH** indicates the path of the shared directory on the NFS server, and **CLIENT\_PATH** indicates the NFS path on the device. + + If you do not want to restrict the NFS access permission, set the permission of the NFS root directory to **777** on the Linux CLI. + + ``` + chmod -R 777 /home/sqbin/nfs + ``` + + The NFS client setting is complete, and the NFS file system has been mounted. + + +3. **Share files using NFS.** + + Create the **dir** directory on the NFS server and save the directory. Run the **ls** command in the OpenHarmony kernel. + + ``` + OHOS # ls /nfs + ``` + + The following information is returned from the serial port: + + ``` + OHOS # ls /nfs + Directory /nfs: + drwxr-xr-x 0 u:0 g:0 dir + ``` + + The **dir** directory created on the NFS server has been synchronized to the **/nfs** directory on the device. + + Similarly, you can create files and directories on the device and access them on the NFS server. + + **Platform differences:** + + Currently, the NFS client supports some NFS v3 specifications. Therefore, the NFS client is not fully compatible with all types of NFS servers. During the development and test, you are advised to use the Linux NFS server. + + diff --git a/en/device-dev/kernel/ramfs.md b/en/device-dev/kernel/kernel-lite-small-file-ramfs.md similarity index 100% rename from en/device-dev/kernel/ramfs.md rename to en/device-dev/kernel/kernel-lite-small-file-ramfs.md diff --git a/en/device-dev/kernel/kernel-lite-small-file-vfs.md b/en/device-dev/kernel/kernel-lite-small-file-vfs.md new file mode 100644 index 0000000000000000000000000000000000000000..8634d9cf6c751e8ef23ce6a2b304c36f40fe9e35 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-file-vfs.md @@ -0,0 +1,171 @@ +# VFS + +- [Overview](#section132540468341) +- [Basic Concepts](#section229417111227) +- [Working Principles](#section18114182834215) +- [Important Notes](#section18311145173712) +- [Development Guidelines](#section422619258380) +- [Use Code](#section180311121420) +- [Result Verification](#section16772334714) + +## Overview + +## Basic Concepts + +In essence, VFS is not a real file system. It is an abstract layer on top of a heterogeneous file system and provides you with a unified Unix-like file operation interface. + +Different types of file systems provide different interfaces. If there are multiple types of file systems in the system, different and non-standard interfaces are required for accessing these file systems. The VFS can be introduced as an abstract layer in the system to harmonize the differences between these heterogeneous file systems. In this way, the system does not need to care about the storage medium and file system type at the bottom layer when accessing a file system. The figure below illustrates the relationship between the VFS and file systems. + +**Figure 1** Relationship between the VFS and file systems +![](figure/relationship-between-the-vfs-and-file-systems.png "relationship-between-the-vfs-and-file-systems") + +In the OpenHarmony kernel, the VFS framework is implemented using the tree structure in the memory. Each node in the tree is an **inode** structure. After a device is registered and a file system is mounted, the corresponding node is generated in the tree based on the path. VFS provides the following functions: + +- Node query +- Unified file system invoking \(standard\) + +## Working Principles + +At the VFS layer, standard Unix file operation functions \(such as **open**, **read**, and **write**\) can be used to access different file systems on different media. + +There are three types of **inode** tree nodes in the VFS framework memory: + +- Virtual node: virtual file of the VFS framework, for example, **/usr** and **/usr/bin**, which ensures the continuity of the tree +- Device node: mapping to a device in the **/dev** directory, for example, **/dev/mmcblk0** +- Mount point: used to mount a specific file system, for example, **/vs/sd** or **/mnt** + +**Figure 2** Tree structure of the file system +![](figure/tree-structure-of-the-file-system.png "tree-structure-of-the-file-system") + +## Important Notes + +- For all file systems in VFS, the name of a directory or file can contain a maximum of 255 bytes, and the maximum length of a full path is 259 bytes. Directories or files whose length exceeds the maximum length cannot be created. + +- Currently, only the JFFS2 file system supports complete permission control. + +- After the **inode\_find\(\)** function is called, the number of found **inode** connections is incremented by 1. After the call is complete, the **inode\_release\(\)** function is called to decrease the number of **inode** connections by 1. Therefore, the two functions must be used together. + +- Devices are classified into character devices and block devices. To ensure data security of the file system on a block device, mount the file system and then operate data through the file system interface. + +- The **los\_vfs\_init\(\)** function can be called only once. Multiple calls cause exceptions to the file system. + +- The file names and directory names in all file systems of the OpenHarmony kernel can contain only hyphens \(-\) and underscores \(\_\), but no other special characters. If other special characters are used, unpredictable errors may occur. + +- The OpenHarmony kernel supports the **open\(\)+O\_DIRECTORY** method to obtain directory data. + +- The mount point must be an empty directory. A file system cannot be mounted to the same mount point or to a directory or file under another mount point. Otherwise, the device or system may be damaged. + +- Only one of the **O\_RDWR**, **O\_WRONLY**, and **O\_RDONLY** parameters can be used with **open** to open a file. If two or more of them are used, the file read or write operation is rejected, and the error code **EACCESS** is returned. + +- Before unmounting a file system in the OpenHarmony kernel, ensure that all directories and files are closed. Otherwise, unmounting fails. Forcible unmounting may cause problems such as file system and file damage. + +- Before removing an SD card, ensure that all directories and files are closed and unmounting is performed. Forcible removal may cause problems such as SD card data loss and SD card damage. + + +## Development Guidelines + +**How to Develop** + +It is recommended that driver developers use the VFS framework to register or uninstall devices \(that is, call **register\_driver\(\)** and **register\_blockdriver\(\)** to obtain device nodes\) and the application layer use **open\(\)** and **read\(\)** to operate character device files to invoke drivers. + +**File Descriptor** + +A process can have a maximum of 256 file descriptors \(including file and socket descriptors\). The system can have a maximum of 640 file descriptors, where there can be a maximum of + +- 512 file descriptors + +- 128 socket descriptors + + +**Operations Supported by VFS** + +open, close, read, write, seek, ioctl, fcntl, mmap, sync, dup, dup2, truncate, opendir, closedir, readdir, rewinddir, mount, umount, statfs, unlink, remove, mkdir, rmdir, rename, stat, utime, seek64, fallocate, fallocate64, truncate64, chmod, and chown + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- Currently, only the interfaces for modifying the attributes of JFFS2 files and VFS device nodes are provided. Each system has its own processing mode for attributes such as read-only. +>- In the OpenHarmony kernel, the attributes do not conflict with each other, and they can be modified randomly. +>- A read-only file or directory in the OpenHarmony kernel cannot be deleted. +>- A read-only file or directory in the OpenHarmony kernel can be renamed. +>- A read-only file cannot be opened in **O\_CREAT**, **O\_TRUNC**, or other modes with the write permission. +>- If the hidden attribute is added to a system file in the OpenHarmony kernel, the system file can be found only on the command line interface \(CLI\) in the Windows OS. \(This system file cannot be viewed regardless of whether **Show hidden files, folders, and drivers** is selected.\) + +## Use Code + +``` +/* The following code shows how to create and traverse directories. */ +#include +#include +#include +#include +#include +#include + +int main() +{ + int ret; + char *dirname = "/test"; + char *pathname0 = "/test/test0"; + char *pathname1 = "/test/test1"; + char *pathname2 = "/test/test2"; + struct dirent **namelist; + int num; + + ret = mkdir(dirname, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", dirname, errno); + goto EXIT; + } + + ret = mkdir(pathname0, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", pathname0, errno); + goto EXIT0; + } + + ret = mkdir(pathname1, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", pathname1, errno); + goto EXIT1; + } + + ret = mkdir(pathname2, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", pathname2, errno); + goto EXIT2; + } + + num = scandir(dirname, &namelist, NULL, alphasort); + if (num < 0) { + perror("scandir"); + } else { + while (num--) { + printf("%s\n", namelist[num]->d_name); + free(namelist[num]); + } + free(namelist); + } + + printf("fs_demo exit.\n"); + return 0; + +EXIT2: + remove(pathname2); +EXIT1: + remove(pathname1); +EXIT0: + remove(pathname0); +EXIT: + remove(dirname); + return 0; +} +``` + +## Result Verification + +``` +OHOS # test2 +test1 +test0 +fs_demo exit. +``` + diff --git a/en/device-dev/kernel/kernel-lite-small-file.md b/en/device-dev/kernel/kernel-lite-small-file.md new file mode 100644 index 0000000000000000000000000000000000000000..4a1e2be2e6b70eb7d6e18e123e6678de49b0ef30 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-file.md @@ -0,0 +1,54 @@ +# File System + +The OpenHarmony lite kernel supports the following file systems: Virtual File System \(VFS\), Network File System \(NFS\), RAM File System \(RAMFS\), File Allocation Table \(FAT\), and Journalling Flash File System Version 2 \(JFFS2\). + +The table below describes the functions of these file systems. + +**Table 1** File system functions + + + + + + + + + + + + + + + + + + + + + + +

File System

+

Function

+

VFS

+

In essence, VFS is not a real file system. It is an abstract layer on top of a heterogeneous file system and provides you with a unified Unix-like file operation interface.

+

NFS

+

NFS allows you to share files across hosts and OSs over a network.

+

RAMFS

+

RAMFS is a RAM-based file system. All files are stored in the RAM, and file read/write operations are performed in the RAM, which reduces the read/write loss of the memory and improves the data read/write speed. It provides a RAM-based storage buffer for dynamic file systems.

+

FAT

+

There are FAT12, FAT16, and FAT32. FAT is often used on removable storage media (such as USB flash drives, SD cards, and portable hard disks) to provide better compatibility between devices and desktop systems such as Windows and Linux.

+

JFFS2

+

JFFS2 is a journal-type file system implemented on Memory Technology Devices (MTDs). It is mainly used to manage files of the NOR flash memory. JFFS2 used in the OpenHarmony kernel supports multiple partitions.

+
+ +- **[VFS](kernel-lite-small-file-vfs.md)** + +- **[NFS](kernel-lite-small-file-nfs.md)** + +- **[RAMFS](kernel-lite-small-file-ramfs.md)** + +- **[FAT](kernel-lite-small-file-fat.md)** + +- **[JFFS2](kernel-lite-small-file-jffs.md)** + + diff --git a/en/device-dev/kernel/differences-from-the-linux-standard-library.md b/en/device-dev/kernel/kernel-lite-small-lib-differ.md similarity index 100% rename from en/device-dev/kernel/differences-from-the-linux-standard-library.md rename to en/device-dev/kernel/kernel-lite-small-lib-differ.md diff --git a/en/device-dev/kernel/kernel-lite-small-lib-standard.md b/en/device-dev/kernel/kernel-lite-small-lib-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..c617ebcef2bccda9d515a7e88a5a39cd1605cfac --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-lib-standard.md @@ -0,0 +1,197 @@ +# Standard Library + +- [Framework](#section1247343413257) +- [Development Example](#section4807125622614) +- [FAQs](#section1219455217277) + +The OpenHarmony kernel uses the **musl libc** library that supports the Portable Operating System Interface \(POSIX\). You can develop components and applications working on the kernel based on the POSIX. + +## Framework + +**Figure 1** POSIX framework +![](figure/posix-framework.png "posix-framework") + +When a system invokes an interface, the OpenHarmony kernel is adapted to provide the interface's external features. + +For details about the APIs supported by the standard library, see the API document of the C library, which also covers the differences between the standard library and the POSIX standard. + +## Development Example + +In this example, the main thread creates **THREAD\_NUM** child threads. Once a child thread is started, it enters the standby state. After the main thread successfully wakes up all child threads, they continue to execute until the lifecycle ends. The main thread uses the **pthread\_join** method to wait until all child threads are executed. + +``` +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define THREAD_NUM 3 +int g_startNum = 0; /* Number of started threads */ +int g_wakenNum = 0; /* Number of wakeup threads */ + +struct testdata { + pthread_mutex_t mutex; + pthread_cond_t cond; +} g_td; + +/* + * Entry function of child threads. + */ +static void *ChildThreadFunc(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + /* Locks a mutex. */ + rc = pthread_mutex_lock(&g_td.mutex); + if (rc != 0) { + printf("ERROR:take mutex lock failed, error code is %d!\n", rc); + goto EXIT; + } + + /* The value of g_startNum is increased by 1. The value indicates the number of child threads that have locked a mutex. */ + g_startNum++; + + /* Wait for the condition variable. */ + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + if (rc != 0) { + printf("ERROR: pthread condition wait failed, error code is %d!\n", rc); + (void)pthread_mutex_unlock(&g_td.mutex); + goto EXIT; + } + + /* Attempt to lock a mutex, which is failed in normal cases. */ + rc = pthread_mutex_trylock(&g_td.mutex); + if (rc == 0) { + printf("ERROR: mutex gets an abnormal lock!\n"); + goto EXIT; + } + + /* The value of g_wakenNum is increased by 1. The value indicates the number of child threads that have been woken up by the condition variable. */ + g_wakenNum++; + + /* Unlock a mutex. */ + rc = pthread_mutex_unlock(&g_td.mutex); + if (rc != 0) { + printf("ERROR: mutex release failed, error code is %d!\n", rc); + goto EXIT; + } +EXIT: + return NULL; +} + +static int testcase(void) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + /* Initialize a mutex. */ + rc = pthread_mutex_init(&g_td.mutex, NULL); + if (rc != 0) { + printf("ERROR: mutex init failed, error code is %d!\n", rc); + goto ERROROUT; + } + + /* Initialize the condition variable. */ + rc = pthread_cond_init(&g_td.cond, NULL); + if (rc != 0) { + printf("ERROR: pthread condition init failed, error code is %d!\n", rc); + goto ERROROUT; + } + + /* Create child threads in batches. The number is specified by THREAD_NUM. */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, ChildThreadFunc, NULL); + if (rc != 0) { + printf("ERROR: pthread create failed, error code is %d!\n", rc); + goto ERROROUT; + } + } + + /* Wait until all child threads lock a mutex. */ + while (g_startNum < THREAD_NUM) { + usleep(100); + } + + /* Lock a mutex and block all threads using pthread_cond_wait. */ + rc = pthread_mutex_lock(&g_td.mutex); + if (rc != 0) { + printf("ERROR: mutex lock failed, error code is %d\n", rc); + goto ERROROUT; + } + + /* Unlock a mutex. */ + rc = pthread_mutex_unlock(&g_td.mutex); + if (rc != 0) { + printf("ERROR: mutex unlock failed, error code is %d!\n", rc); + goto ERROROUT; + } + + for (int j = 0; j < THREAD_NUM; j++) { + /* Broadcast signals on the condition variable. */ + rc = pthread_cond_signal(&g_td.cond); + if (rc != 0) { + printf("ERROR: pthread condition failed, error code is %d!\n", rc); + goto ERROROUT; + } + } + + sleep(1); + + /* Check whether all child threads are woken up. */ + if (g_wakenNum != THREAD_NUM) { + printf("ERROR: not all threads awaken, only %d thread(s) awaken!\n", g_wakenNum); + goto ERROROUT; + } + + /* Wait for all threads to terminate. */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + if (rc != 0) { + printf("ERROR: pthread join failed, error code is %d!\n", rc); + goto ERROROUT; + } + } + + /* Destroy the condition variable. */ + rc = pthread_cond_destroy(&g_td.cond); + if (rc != 0) { + printf("ERROR: pthread condition destroy failed, error code is %d!\n", rc); + goto ERROROUT; + } + return 0; +ERROROUT: + return -1; +} + +/* + * Sample code main function + */ +int main(int argc, char *argv[]) +{ + int rc; + + /* Start the test function. */ + rc = testcase(); + if (rc != 0) { + printf("ERROR: testcase failed!\n"); + } + + return 0; +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +``` + +## FAQs + +None + diff --git a/en/device-dev/kernel/kernel-lite-small-lib.md b/en/device-dev/kernel/kernel-lite-small-lib.md new file mode 100644 index 0000000000000000000000000000000000000000..7b82773508bebc7f6f2b519897411f9a26df1bc4 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-lib.md @@ -0,0 +1,7 @@ +# Standard Library + +- **[Standard Library](kernel-lite-small-lib-standard.md)** + +- **[Differences from the Linux Standard Library](kernel-lite-small-lib-differ.md)** + + diff --git a/en/device-dev/kernel/kernel-lite-small-memory.md b/en/device-dev/kernel/kernel-lite-small-memory.md new file mode 100644 index 0000000000000000000000000000000000000000..7e5191df7b4d967ad5d879522e4a9c372f2a9e2f --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-memory.md @@ -0,0 +1,353 @@ +# Memory + +- [Basic Concepts](#section1392116583424) +- [When to Use](#section159581619194319) +- [API Description](#section114001032104317) + +## Basic Concepts + +Memory management is an important procedure in software development, including memory allocation, usage, and reclamation. + +Sound memory management approaches and strategies help you improve software performance and reliability. + +## When to Use + +For user-space development, the OpenHarmony kernel provides a set of APIs for you to perform memory-related operations, such as memory application, release, remapping, and attribute setting, in addition to standard APIs provided by the C library. + +## API Description + +**Table 1** Standard APIs in the C library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Header File

+

Function

+

Description

+

strings.h

+

int bcmp(const void *s1, const void *s2, size_t n)

+

Compares byte sequences.

+

strings.h

+

void bcopy(const void *src, void *dest, size_t n)

+

Copies byte sequences.

+

strings.h

+

void bzero(void *s, size_t n)

+

Sets byte sequences to zero.

+

string.h

+

void *memccpy(void *dest, const void *src, int c, size_t n)

+

Copies the first n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest. The copy checks whether a character specified by c is found. If c is found, this function returns the next character of character c in the destination memory area.

+

string.h

+

void *memchr(const void *s, int c, size_t n)

+

Searches for the first occurrence of the character specified by c in the n-byte memory area pointed to by s.

+

string.h

+

int memcmp(const void *s1, const void *s2, size_t n)

+

Compares two memory areas.

+

string.h

+

void *memcpy(void *dest, const void *src, size_t n)

+

Copies n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest.

+

string.h

+

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)

+

Searches for a needle string in its haystack string.

+

string.h

+

void *memmove(void *dest, const void *src, size_t n)

+

Copies n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest.

+

string.h

+

void *mempcpy(void *dest, const void *src, size_t n)

+

Copies n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest.

+

string.h

+

void *memset(void *s, int c, size_t n)

+

Copies a character to the specified memory area.

+

stdlib.h

+

void *malloc(size_t size)

+

Dynamically allocates a memory block of size.

+

stdlib.h

+

void *calloc(size_t nmemb, size_t size)

+

Dynamically allocates nmemb memory blocks of size.

+

stdlib.h

+

void *realloc(void *ptr, size_t size)

+

Changes the size of the memory block pointed to by ptr to size bytes.

+

stdlib.h/malloc.h

+

void *valloc(size_t size)

+

Allocates a block of memory with the specified size and aligns the allocated memory by page size.

+

stdlib.h

+

void free(void *ptr)

+

Releases the memory space pointed to by ptr.

+

malloc.h

+

size_t malloc_usable_size(void *ptr)

+

Obtains the size of the memory block pointed to by ptr.

+

unistd.h

+

int getpagesize(void)

+

Obtains the page size.

+

unistd.h

+

void *sbrk(intptr_t increment)

+

Changes the data segment size.

+
+ +Details on API differences: + +- **mmap** + + **Function prototype:** + + void \*mmap\(void \*addr, size\_t length, int prot, int flags, int fd, off\_t offset\); + + **Function description:** applies for virtual memory. + + **Parameter description:** + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

addr

+

Indicates the pointer to the start address of the mapping between the virtual address space of the calling process and a file or device. If this parameter is NULL, the kernel determines the address to start (recommended). Otherwise, the portability of the program will deteriorate, because the available addresses vary depending on the OS.

+

length

+

Indicates the length of the mapping.

+

prot

+

Indicates the permission to be granted on the mapping area. The options are as follows:

+
  • PROT_READ: The mapping area is readable.
  • PROT_WRITE: The mapping area is writable.
  • PROT_EXEC: The mapping area is executable.
  • PROT_NONE: The mapping area cannot be accessed.
+

flags

+

Specifies whether updates are visible to other processes mapping the same segment. The options are as follows:

+
  • MAP_PRIVATE: The mapping area is private, and updates to the mapping are invisible to other processes mapping the same segment.
  • MAP_SHARED: Updates to the mapping are visible to other processes mapping the same segment, and are stored to the disk file.
+

fd

+

Indicates the file descriptor.

+

offset

+

Indicates the offset into the file where the mapping will start.

+
+ + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >For details about the implementation differences between **mmap** and Linux function, see [Differences from the Linux Standard Library](kernel-lite-small-lib-differ.md). + + **Return values:** + + - Returns the pointer to the page-aligned address where the mapping is placed if the operation is successful. + - Returns **\(void \*\)-1** if the operation fails. + + +- **munmap** + + **Function prototype:** + + int munmap\(void \*addr, size\_t length\); + + **Function description:** releases virtual memory. + + **Parameter description:** + + + + + + + + + + + + + +

Parameter

+

Description

+

addr

+

Indicates the pointer to the start address of the memory region to unmap.

+

length

+

Indicates the length of the address range to unmap.

+
+ + **Return values:** + + - Returns **0** if the operation is successful. + - Returns **-1** if the operation fails. + + +- **mprotect** + + **Function prototype:** + + int mprotect\(void \*addr, size\_t length, int prot\); + + **Function description:** modifies the access permission on a memory region. + + **Parameter description:** + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

addr

+

Indicates the pointer to the start address of the memory region to modify, which must be a multiple of the page size. If the access permission is abnormal, the kernel throws an exception and kills the process rather than send SIGSEGV signals to the current process.

+

length

+

Indicates the length of the memory region to modify.

+

prot

+

Indicates the permission of the memory region to modify. The options are as follows:

+
  • PROT_READ: The memory region is readable.
  • PROT_WRITE: The memory region is writable.
  • PROT_EXEC: The memory region is executable.
  • PROT_NONE: The memory region cannot be accessed.
+
+ + **Return values:** + + - Returns **0** if the operation is successful. + - Returns **-1** if the operation fails. + + +- **mremap** + + **Function prototype:** + + void \*mremap\(void \*old\_address, size\_t old\_size, size\_t new\_size, int flags, void new\_address\); + + **Function description:** remaps the virtual memory address. + + **Parameter description:** + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

old_address

+

Indicates the old address of the virtual memory block that needs to be expanded or shrunk. The old_address must be page-aligned.

+

old_size

+

Indicates the old size of the virtual memory block.

+

new_size

+

Indicates the new size of the virtual memory block.

+

flags

+

Indicates the flags to control the remapping. If there is no sufficient space to expand the mapping in the current location, the operation will fail.

+
  • MREMAP_MAYMOVE: allows the kernel to relocate the mapping to a new virtual address.
  • MREMAP_FIXED: enables the mremap() function to accept the fifth parameter void *new_address, which specifies that the mapping address must be page-aligned. All previous mappings within the address range specified by new_address and new_size are unmapped. If MREMAP_FIXED is specified, MREMAP_MAYMOVE must also be specified.
+
+ + **Return values:** + + - Returns the pointer to the new virtual memory area if the operation is successful. + - Returns **\(void \*\)-1** if the operation fails. + + diff --git a/en/device-dev/kernel/kernel-lite-small-net.md b/en/device-dev/kernel/kernel-lite-small-net.md new file mode 100644 index 0000000000000000000000000000000000000000..0f542fa52928ae3748dc0a6f51bb24a028dda547 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-net.md @@ -0,0 +1,303 @@ +# Network + +- [Basic Concepts](#section9840143083510) +- [When to Use](#section1575885183516) +- [API Description](#section16351198193614) + +## Basic Concepts + +The network module implements basic functions of the TCP/IP protocol stack and provides the standard POSIX socket interfaces. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Currently, the OS uses **lwIP** to provide network capabilities. + +## When to Use + +For user-space development, the OpenHarmony kernel provides a set of APIs for you to implement network functionalities, including creating and disabling sockets, transmitting and receiving data, and setting network attributes, in addition to standard POSIX socket functions provided by the C library. + +## API Description + +**Table 1** Standard APIs in the C library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Header File

+

Function

+

Description

+

sys/socket.h

+

int accept(int socket, struct sockaddr *address, socklen_t *address_len)

+

Accepts incoming connection requests.

+

sys/socket.h

+

int bind(int s, const struct sockaddr *name, socklen_t namelen)

+

Binds an IP address to a socket.

+

sys/socket.h

+

int shutdown(int socket, int how)

+

Shuts down a socket.

+

sys/socket.h

+

int getpeername(int s, struct sockaddr *name, socklen_t *namelen)

+

Retrieves the peer address of the specified socket.

+

sys/socket.h

+

int getsockname(int s, struct sockaddr *name, socklen_t *namelen)

+

Retrieves the local address of the specified socket.

+

sys/socket.h

+

int getsockopt(int s, struct sockaddr *name, socklen_t *namelen)

+

Retrieves the socket options.

+

sys/socket.h

+

int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)

+

Sets the socket options.

+

unistd.h

+

int close(int s)

+

Closes a socket.

+

sys/socket.h

+

int connect(int s, const struct sockaddr *name, socklen_t namelen)

+

Initiates a connection to a socket.

+

sys/socket.h

+

int listen(int sockfd, int backlog)

+

Listens for network connections.

+

sys/socket.h

+

ssize_t recv(int socket, void *buffer, size_t length, int flags)

+

Receives data from another socket.

+

sys/socket.h

+

ssize_t recvmsg(int s, struct msghdr *message, int flags)

+

Receives data from a specified socket based on the input parameters.

+

sys/socket.h

+

ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len)

+

Receives data from a specified socket and obtains the IP address of the data source.

+

sys/socket.h

+

ssize_t send(int s, const void *dataptr, size_t size, int flags)

+

Sends data to another socket.

+

sys/socket.h

+

ssize_t sendmsg(int s, const struct msghdr *message, int flags)

+

Sends data to another socket based on the input parameters.

+

sys/socket.h

+

ssize_t sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)

+

Sends data to another socket at the specified destination IP address.

+

sys/socket.h

+

int socket(int domain, int type, int protocol)

+

Creates a socket.

+

sys/select.h

+

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)

+

Monitors the I/O events of multiple file descriptors.

+

sys/ioctl.h

+

int ioctl(int s, int request, ...)

+

Obtains and sets socket options.

+

arpa/inet.h

+

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)

+

Converts an IP address in binary format to a string.

+

arpa/inet.h

+

int inet_pton(int af, const char *src, void *dst)

+

Converts a string to an IP address in binary format.

+
+ +Details on API differences: + +- **sendmsg** + + **Function prototype:** + + ssize\_t sendmsg\(int s, const struct msghdr \*message, int flags\) + + **Function description:** sends a message on a socket. + + **Parameter description:** + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

s

+

Indicates the socket descriptor.

+

message

+

Indicates the pointer to the message to be sent. The ancillary message is not supported.

+

flags

+

Indicates the socket flags for sending the message. The options are as follows:

+
  • MSG_MORE: allows messages that have been sent for multiple times to be packaged and sent at a time.
  • MSG_DONTWAIT: enables a non-blocking operation.
+
+ + **Return values:** + + - Returns the number of bytes that have been sent if the operation is successful. + - Returns **-1** and sets **errno** if the operation fails. + + +- **recvmsg** + + **Function prototype:** + + ssize\_t recvmsg\(int s, struct msghdr \*message, int flags\) + + **Function description:** receives a message from a socket. + + **Parameter description:** + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

s

+

Indicates the socket descriptor.

+

message

+

Indicates the pointer to the address to receive the message. The ancillary message is not supported.

+

flags

+

Indicates the socket flags for receiving the message. The options are as follows:

+
  • MSG_PEEK: allows the message to be read without being removed.
  • MSG_DONTWAIT: enables a non-blocking operation.
+
+ + **Return values:** + + - Returns the number of bytes that have been received if the operation is successful. + - Returns **-1** and sets **errno** if the operation fails. + + +- **ioctl** + + **Function prototype:** + + int ioctl\(int s, int request, ...\) + + **Function description:** obtains or sets socket options. + + **Parameter description:** + + + + + + + + + + + + + +

Parameter

+

Description

+

s

+

Indicates the socket descriptor.

+

request

+

Indicates the operation to perform on the socket options. The options are as follows:

+
  • FIONREAD: obtains the number of bytes of the data that can be read from the socket.
  • FIONBIO: sets whether the socket is non-blocked.
+
+ + **Return values:** + + - Returns **0** if the operation is successful. + - Returns **-1** and sets **errno** if the operation fails. + + diff --git a/en/device-dev/kernel/kernel-lite-small-process.md b/en/device-dev/kernel/kernel-lite-small-process.md new file mode 100644 index 0000000000000000000000000000000000000000..4ce3abc48b9d4c97f222aa495ec7167a00974567 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-process.md @@ -0,0 +1,301 @@ +# Process + +- [Basic Concepts](#section29197338383) +- [When to Use](#section85513272398) +- [API Description](#section4517119124015) + +## Basic Concepts + +Processes are resource management units in the OS. They can use or wait to use CPUs and use system resources such as memory. They run independently from one another. + +The OpenHarmony kernel allows multiple processes to run simultaneously, switch, and communicate, facilitating your management over service programs. In this regard, you will have more time to devote to the implementation of service functionalities. + +Processes in the OpenHarmony kernel use the preemptive scheduling mechanism, round-robin \(RR\) scheduling. + +These processes are assigned 32 priorities \(**0** to **31**\). Among them, user processes can be configured with 22 priorities from **10** \(highest\) to **31** \(lowest\). + +A high-priority process can preempt the resources of a low-priority process. The low-priority process can be scheduled only after the high-priority process is blocked or terminated. + +Each user-space process has its own memory space, which is invisible to other processes. In this way, processes are isolated from each other. + +The user-space root process init is started by the kernel. Then other user-space processes are created by the init process via the **fork** call. + +**A process may have the following states:** + +- **Init**: The process is being created. + +- **Ready**: The process is in the ready list and waits for being scheduled by the CPU. + +- **Running**: The process is running. + +- **Pending**: The process is blocked and suspended. When all threads in a process are blocked, the process is blocked and suspended. + +- **Zombies**: The process stops running and waits for the parent process to reclaim its control block resources. + + +**Figure 1** State transition of a process +![](figure/state-transition-of-a-process.png "state-transition-of-a-process") + +**Description of the process state transition:** + +- Init→Ready: + + When a process is created, the process enters the **Init** state to start initialization after obtaining the process control block. After the process is initialized, the process is inserted into the scheduling queue and therefore enters the **Ready** state. + +- Ready→Running: + + When a process switchover is triggered, the process with the highest priority in the ready list is executed and enters the **Running** state. If this process has no thread in the **Ready** state, the process is deleted from the ready list and resides only in the **Running** state. However, if it has threads in the **Ready** state, the process still stays in the ready list. In this case, the process is in both the **Ready** and **Running** states. + +- Running→Pending: + + If all threads in a process are entering the **Pending** state, the process will enter the **Pending** state together with its last thread. Then, a process switchover is triggered. + +- Pending→Ready: + + When any thread in a **Pending** process restores to the **Ready** state, the process is added to the ready list and changes to the **Ready** state. + +- Ready→Pending: + + When the last ready thread in a process enters the **Pending** state, the process is deleted from the ready list, and the process changes from the **Ready** state to the **Pending** state. + +- Running→Ready: + + A process may change from the **Running** state to the **Ready** state in either of the following scenarios: + + 1. After a process with a higher priority is created or restored, processes will be scheduled. The process with the highest priority in the ready list will change to the **Running** state, and the originally running process will change from the **Running** state to the **Ready** state. + 2. If a process has the **SCHED\_RR** scheduling policy and shares the same priority with another process in the **Ready** state, this process will change from the **Running** state to the **Ready** state after its time slices are used up, and the other process with the same priority will change from the **Ready** state to the **Running** state. + +- Running→Zombies: + + After the main thread or all threads of a process are stopped, the process changes from the **Running** state to the **Zombies** state and waits for the parent process to reclaim resources. + + +## When to Use + +After processes are created, you can operate the resources only in your own process space, except shared resources. In user space, processes can be suspended, restored, and delayed. In addition, you can set and obtain the scheduling priority and scheduling policy of processes. When a process is terminated, it proactively releases its resources. However, the PID resources of the process are reclaimed by the parent process via **wait**/**waitpid** or when the parent process exits. + +## API Description + +The following table describes the APIs provided by the process management module of the OpenHarmony kernel. + +**Table 1** APIs provided by the process management module + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Category

+

Function

+

Description

+

Remarks

+

Process

+

fork

+

Creates a new process.

+

N/A

+

exit

+

Exits the process.

+

N/A

+

atexit

+

Registers the callback that will be called when the process is terminated normally.

+

N/A

+

abort

+

Terminates the process.

+

N/A

+

getpid

+

Obtains the process ID.

+

N/A

+

getppid

+

Obtains the parent process ID.

+

N/A

+

getpgrp

+

Obtains the ID of the process group of the calling process.

+

N/A

+

getpgid

+

Obtains the process group ID of the process identified by pid.

+

N/A

+

setpgrp

+

Sets the process group ID of the calling process.

+

N/A

+

setpgid

+

Sets the process group ID of the process identified by pid.

+

N/A

+

kill

+

Sends a signal to a specified process.

+
  • Only signals 1 to 30 can be sent.
  • The default behavior for signals does not include STOP and CONTINUE and terminates the process without a core dump.
  • SIGSTOP, SIGKILL, and SIGCONT cannot be masked.
  • After an asynchronous signal is sent to a process, the signal callback is invoked only after the process is scheduled. For the sake of security, the process can be killed only by itself, and the kernel cannot forcibly kill the process by sending signals.
  • After the process is killed, SIGCHLD is sent to its parent process. The sending action cannot be canceled.
  • A sleeping process cannot be woken up by a signal.
+

wait

+

Waits for any child process to terminate and reclaims its resources.

+

The status value is defined by the following macros:

+
  • WIFEXITED(status): If the child process terminates normally, true is returned. Otherwise, false is returned.
  • WEXITSTATUS(status): If WIFEXITED(status) is true, this macro can be used to obtain the exit code that the child process passed to exit().
  • WTERMSIG(status): If a child process terminates abnormally, the child process exit code obtained by the parent process through WTERMSIG is always SIGUSR2. This is the only case supported.
  • The following operations are not supported: WIFSTOPPED, WSTOPSIG, WCOREDUMP, and WIFCONTINUED.
+

waitpid

+

Waits for a specified child process to terminate and reclaims its resources.

+

The options to control the function behavior do not support WUNTRACED and WCONTINUED.

+

The status value is defined by the following macros:

+
  • WIFEXITED(status): If the child process terminates normally, true is returned. Otherwise, false is returned.
  • WEXITSTATUS(status): If WIFEXITED(status) is true, this macro can be used to obtain the exit code that the child process passed to exit().
  • WTERMSIG(status): If a child process terminates abnormally, the child process exit code obtained by the parent process through WTERMSIG is always SIGUSR2. This is the only case supported.
  • The following operations are not supported: WIFSTOPPED, WSTOPSIG, WCOREDUMP, and WIFCONTINUED.
+

Scheduling

+

getpriority

+

Obtains the static priority of a specified ID.

+
  • PRIO_PGRP and PRIO_USER are not supported.
+
  • The priority to obtain and set refers to the static priority. The dynamic priority is not involved.
+

setpriority

+

Sets the static priority of a specified ID.

+

sched_rr_get_interval

+

Obtains the execution time limit of a process.

+

N/A

+

sched_yield

+

Yields the running process.

+

N/A

+

sched_get_priority_max

+

Obtains the maximum static priority that can be used for a process.

+

The scheduling policy can only be SCHED_RR.

+

sched_get_priority_min

+

Obtains the minimum static priority that can be used for a process.

+

sched_getscheduler

+

Obtains the scheduling policy of a process.

+

sched_setscheduler

+

Sets a scheduling policy for a process.

+

sched_getparam

+

Obtains scheduling parameters of a process.

+

N/A

+

sched_setparam

+

Sets scheduling parameters related to a scheduling policy for a process.

+

N/A

+

exec

+

execl

+

Executes a specified user program file in ELF format.

+

N/A

+

execle

+

Executes a specified user program file in ELF format.

+

N/A

+

execlp

+

Executes a specified user program file in ELF format.

+

N/A

+

execv

+

Executes a specified user program file in ELF format.

+

N/A

+

execve

+

Executes a specified user program file in ELF format.

+

N/A

+

execvp

+

Executes a specified user program file in ELF format.

+

N/A

+
+ diff --git a/en/device-dev/kernel/user-space-exception-information.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-abn.md similarity index 100% rename from en/device-dev/kernel/user-space-exception-information.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-abn.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cat.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cat.md new file mode 100644 index 0000000000000000000000000000000000000000..db3798fee685ae6eff096a156023177358810019 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cat.md @@ -0,0 +1,53 @@ +# cat + +- [Command Function](#section16710153391315) +- [Syntax](#section1699392313158) +- [Parameter Description](#section1677217374136) +- [Usage](#section186772414131) +- [Example](#section12158131814561) +- [Output](#section183926225561) + +## Command Function + +This command is used to display the content of a text file. + +## Syntax + +cat \[_pathname_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

pathname

+

Indicates the file path.

+

An existing file

+
+ +## Usage + +Run the **cat** \[_pathname_\] command to display the content of a text file. + +## Example + +Enter **cat hello-harmony.txt**. + +## Output + +**Figure 1** Viewing content of the **hello-harmony.txt** file +![](figure/viewing-content-of-the-hello-harmony-txt-file.png "viewing-content-of-the-hello-harmony-txt-file") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cd.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cd.md new file mode 100644 index 0000000000000000000000000000000000000000..e901db1567ec14955417acda2be585f1b2ecdaf5 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cd.md @@ -0,0 +1,57 @@ +# cd + +- [Command Function](#section11690184921316) +- [Syntax](#section75695409569) +- [Parameter Description](#section71961353181311) +- [Usage](#section3629759111317) +- [Example](#section211620301412) +- [Output](#section1968117214577) + +## Command Function + +This command is used to change the current working directory. + +## Syntax + +cd \[_path_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

path

+

Indicates the file path.

+

The user must have the execution (search) permission for the specified directory.

+
+ +## Usage + +- If the **path** parameter is not specified, the system switches to the root directory. +- If the **path** parameter is specified, the system switches to the specified path. +- The **path** value starting with a slash \(/\) represents the root directory. +- The **path** value starting with a dot \(.\) represents the current directory. +- The **path** value starting with two dots \(..\) represents the parent directory. + +## Example + +Enter **cd ..**. + +## Output + +**Figure 1** Directory switching result +![](figure/directory-switching-result.png "directory-switching-result") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chgrp.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chgrp.md new file mode 100644 index 0000000000000000000000000000000000000000..b9fdfe09c32a883f3fdec32d4f421c0975f1b4f5 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chgrp.md @@ -0,0 +1,60 @@ +# chgrp + +- [Command Function](#section6103119161418) +- [Syntax](#section186958132141) +- [Parameter Description](#section81796174141) +- [Usage](#section14330152417140) +- [Example](#section951823119149) +- [Output](#section14271133125715) + +## Command Function + +This command is used to change a file group. + +## Syntax + +chgrp \[_group_\] \[_pathname_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

group

+

Indicates the file group.

+

[0, 0xFFFFFFFF]

+

pathname

+

Indicates the file path.

+

An existing file

+
+ +## Usage + +By specifying a file group before the file name in this command, you can change the group to which the file belongs. + +## Example + +Enter **chgrp 100 hello-harmony.txt**. + +## Output + +**Figure 1** Changing the group of the **hello-harmony.txt** file to **100** +![](figure/changing-the-group-of-the-hello-harmony-txt-file-to-100.png "changing-the-group-of-the-hello-harmony-txt-file-to-100") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chmod.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chmod.md new file mode 100644 index 0000000000000000000000000000000000000000..734b648c4f321c31da9dad7fad892444a5acd8df --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chmod.md @@ -0,0 +1,60 @@ +# chmod + +- [Command Function](#section13992936121418) +- [Syntax](#section63342439147) +- [Parameter Description](#section894414671411) +- [Usage](#section182415221419) +- [Example](#section8518195718147) +- [Output](#section127391818158) + +## Command Function + +This command is used to change the file operation permission. + +## Syntax + +chmod \[_mode_\] \[_pathname_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

mode

+

Indicates the permission for a file or directory. The value is an octal number, representing the permission of User (owner), Group (group), or Other (other groups).

+

[0, 777]

+

pathname

+

Indicates the file path.

+

An existing file

+
+ +## Usage + +By specifying the **mode** parameter before the file name, you can change the permission for this file. + +## Example + +Enter **chmod 666 hello-harmony.txt**. + +## Output + +**Figure 1** Changing the permission on the **hello-harmony.txt** file to **666** +![](figure/changing-the-permission-on-the-hello-harmony-txt-file-to-666.png "changing-the-permission-on-the-hello-harmony-txt-file-to-666") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chown.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chown.md new file mode 100644 index 0000000000000000000000000000000000000000..62683b53615c8e753ec9db80e00b72693ae9f96a --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-chown.md @@ -0,0 +1,69 @@ +# chown + +- [Command Function](#section247414691513) +- [Syntax](#section14773151018159) +- [Parameter Description](#section598731391517) +- [Usage](#section16524152071510) +- [Example](#section17901152561510) +- [Output](#section15513163115816) + +## Command Function + +This command is used to change the owner and group of a specified file. + +## Syntax + +chown \[_owner_\] \[_group_\] \[_pathname_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

owner

+

Indicates the file owner.

+

[0, 0xFFFFFFFF]

+

group

+

Indicates the file group.

+
  • Left blank
  • [0, 0xFFFFFFFF]
+

pathname

+

Indicates the file path.

+

An existing file

+
+ +## Usage + +- By specifying the **owner** and **group** parameters in this command, you can change the owner and group of the file. +- If the **owner** or **group** value is **-1**, the owner or group of the file will not be changed. +- The **group** parameter can be left blank. + +## Example + +Enter **chown 100 200 hello-harmony.txt**. + +## Output + +**Figure 1** Changing the owner and group of the hello-harmony.txt file to 100 and 200 respectively +![](figure/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png "changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cp.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cp.md new file mode 100644 index 0000000000000000000000000000000000000000..d654bd86f5da5f1dad144220e3955fc67e4a7599 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-cp.md @@ -0,0 +1,68 @@ +# cp + +- [Command Function](#section6841203041513) +- [Syntax](#section24286359150) +- [Parameter Description](#section558617385152) +- [Usage](#section16128156162) +- [Example](#section19354171211618) +- [Output](#section16754183195914) + +## Command Function + +This command is used to create a copy for a file. + +## Syntax + +cp \[_SOURCEFILE_\] \[_DESTFILE_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

SOURCEFILE

+

Indicates the path to the source file.

+

Currently, only files are supported. Directories are not supported.

+

DESTFILE

+

Indicates the path to the destination file.

+

Both directories and files are supported.

+
+ +## Usage + +- The name of the source file cannot be the same as that of the destination file in the same path. +- The source file must exist and cannot be a directory. +- The source file path supports wildcards: asterisks \(\*\) and question marks \(?\). The asterisk \(\*\) indicates any number of characters, and the question mark \(?\) represents a single character. The destination file path does not support wildcards. If the specified source file path matches multiple files, the destination file path must be a directory. +- If the destination file path is a directory, this directory must exist. In this case, the destination file is named after the source file. +- If the destination file path is a file, the directory for this file must exist. In this case, the file copy is renamed. +- Currently, this command can be used to copy only one file. If more than two parameters are specified, only the first two parameters take effect. +- If the destination file does not exist, a new file is created. If the destination file already exists, the existing file is overwritten. + +When important system resources are copied, unexpected results such as a system breakdown may occur. For example, when the **/dev/uartdev-0** file is copied, the system may stop responding. + +## Example + +Enter **cp hello-harmony.txt ./tmp/**. + +## Output + +**Figure 1** File copying result +![](figure/file-copying-result.png "file-copying-result") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-format.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-format.md new file mode 100644 index 0000000000000000000000000000000000000000..06ff11d299af0cae40e548e8da3263cc7aaed5ed --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-format.md @@ -0,0 +1,69 @@ +# format + +- [Command Function](#section1922331919169) +- [Syntax](#section249226169) +- [Parameter Description](#section985173416177) +- [Usage](#section1510162714162) +- [Example](#section25691431161611) +- [Output](#section17368112365920) + +## Command Function + +This command is used to format a disk. + +## Syntax + +format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

dev_inodename

+

Indicates the device name.

+

sectors

+

Indicates the size of the allocated memory unit or sector. The value 0 indicates that the parameter is null. (The value must be 0 or a power of 2. For FAT32, the maximum value is 128. If the parameter is set to 0, a proper cluster size is automatically selected. The available cluster size range varies depending on the partition size. If the cluster size is incorrectly specified, the formatting may fail.)

+

option

+
Indicates the formatting option for selecting the file system type. The options are as follows:
  • 0x01: FMT_FAT
  • 0x02: FMT_FAT32
  • 0x07: FMT_ANY
  • 0x08: FMT_ERASE (not supported by the USB flash drive)
+
+

Other values are invalid. The system will automatically select the formatting mode. If the low-level formatting bit is 1 during the formatting of a USB flash drive, an error message is printed.

+

label

+

Indicates the volume label name. This parameter is optional, and the value is a string. If null is specified for this parameter, the previously set volume label name is cleared.

+
+ +## Usage + +- The **format** command is used to format a disk. You can find the device name in the **dev** directory. A storage card must be installed before the formatting. +- This command can be used to format only the USB flash drive, SD card, and MMC, but not the NAND flash and NOR flash. +- The **sectors** parameter must be set to a valid value. An invalid value may cause exceptions. + +## Example + +Enter **format /dev/mmcblk0 128 2**. + +## Output + +Formatting result + +![](figure/en-us_image_0000001052370307.png) + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-is.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-is.md new file mode 100644 index 0000000000000000000000000000000000000000..20a95c9dcf2ffd4804a13d1d2a9f7d30b1e1b962 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-is.md @@ -0,0 +1,58 @@ +# ls + +- [Command Function](#section6538163771614) +- [Syntax](#section45881743111616) +- [Parameter Description](#section17528148171617) +- [Usage](#section041212533166) +- [Example](#section986105716167) +- [Output](#section2036124918592) + +## Command Function + +This command is used to display the content of a specified directory. + +## Syntax + +ls \[_path_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

path

+

If path is left blank, the content of the current directory is displayed.

+

If the path value is an invalid file name, the following failure message is displayed:

+

ls error: No such directory

+

If the path value is a valid directory, the content of this directory is displayed.

+
  • Left blank
  • A valid directory
+
+ +## Usage + +- This command can be used to display the content of the current directory. +- This command can also display the size of a file. +- The **ls** command with the **proc** directory passed cannot calculate the file size and **0** is displayed in the command output. + +## Example + +Enter **ls**. + +## Output + +**Figure 1** Viewing content of the current directory +![](figure/viewing-content-of-the-current-directory.png "viewing-content-of-the-current-directory") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-isfd.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-isfd.md new file mode 100644 index 0000000000000000000000000000000000000000..02962165e1e8998171905ffdcc3fea368c973eb6 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-isfd.md @@ -0,0 +1,29 @@ +# lsfd + +- [Command Function](#section2053406181716) +- [Syntax](#section523771017172) +- [Usage](#section27241213201719) +- [Example](#section442617197173) +- [Output](#section42491639151813) + +## Command Function + +This command is used to display the file descriptors and names of currently opened files. + +## Syntax + +lsfd + +## Usage + +Run the **lsfd** command to view file descriptors and names of the opened files. + +## Example + +Enter **lsfd**. + +## Output + +**Figure 1** Command output +![](figure/command-output-19.png "command-output-19") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-mkdir.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-mkdir.md new file mode 100644 index 0000000000000000000000000000000000000000..77106a85f0ff8cea82322cafbaf3a62fd5051f1a --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-mkdir.md @@ -0,0 +1,54 @@ +# mkdir + +- [Command Function](#section1083613274175) +- [Syntax](#section820913118178) +- [Parameter Description](#section1256834121718) +- [Usage](#section1294234115172) +- [Example](#section1113345211713) +- [Output](#section10142201012) + +## Command Function + +This command is used to create a directory. + +## Syntax + +mkdir \[_directory_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

directory

+

Indicates the directory to be created.

+

N/A

+
+ +## Usage + +- If the **mkdir** command is followed by the name of the directory to be created, the directory is created in the current directory. +- If the **mkdir** command is followed by a path and the name of the directory to be created, the directory is created in the specified path. + +## Example + +Enter **mkdir share**. + +## Output + +**Figure 1** Creating the share directory +![](figure/creating-the-share-directory.png "creating-the-share-directory") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-mount.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-mount.md new file mode 100644 index 0000000000000000000000000000000000000000..37feb309a276cdc1d5ccb7c8c339c219141b2507 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-mount.md @@ -0,0 +1,78 @@ +# mount + +- [Command Function](#section11631837182) +- [Syntax](#section1697638111820) +- [Parameter Description](#section1650151221819) +- [Usage](#section124541520171912) +- [Example](#section7424625171917) +- [Output](#section14757018116) + +## Command Function + +This command is used to mount a device to a specified directory. + +## Syntax + +mount <_device_\> <_path_\> <_name_\> \[_uid gid_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

device

+

Indicates the path of the device to be mounted. The format is the path of the device.

+

A device in the system

+

path

+

Indicates the directory of the device.

+

The user must have the execution (search) permission for the specified directory.

+

N/A

+

name

+

Indicates the file system type.

+

vfat, yaffs, jffs, ramfs, nfs, procfs, romfs

+

uid gid

+

uid indicates the user ID.

+

gid indicates the group ID.

+

This parameter is optional. The default values are uid:0 and gid:0.

+

N/A

+
+ +## Usage + +By specifying the device to be mounted, directory, and file system format in the **mount** command, you can successfully mount the file system to the specified directory. + +## Example + +Enter **mount /dev/mmcblk0p0 /bin1/vs/sd vfat**. + +## Output + +Mounting **/dev/mmcblk0p0** to the **/bin1/vs/sd** directory + +![](figure/en-us_image_0000001051690323.png) + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-part.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-part.md new file mode 100644 index 0000000000000000000000000000000000000000..da5b18b5bdd5e36f0fe08c425ded9138dddb6df5 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-part.md @@ -0,0 +1,52 @@ +# partinfo + +- [Command Function](#section1777503617199) +- [Syntax](#section185501447132114) +- [Parameter Description](#section1304151212252) +- [Usage](#section4566131982520) +- [Example](#section4351134942514) +- [Output](#section66689331412) + +## Command Function + +This command is used to query information about multiple partitions of a hard disk or SD card identified by the system. + +## Syntax + +partinfo <_dev\_inodename_\> + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

dev_inodename

+

Indicates the name of the partition to be queried.

+

A valid partition name

+
+ +## Usage + +None + +## Example + +Enter **partinfo /dev/mmcblk0p0**. + +## Output + +![](figure/en-us_image_0000001052370303.png) + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-partion.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-partion.md new file mode 100644 index 0000000000000000000000000000000000000000..837e05d60891cbf73bac965aed673f4f2b341026 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-partion.md @@ -0,0 +1,62 @@ +# partition + +- [Command Function](#section255095212257) +- [Syntax](#section10258056122515) +- [Parameter Description](#section177200581256) +- [Usage](#section17866411262) +- [Example](#section1927174202610) +- [Output](#section11321011223) + +## Command Function + +This command is used to query flash partition information. + +## Syntax + +partition \[_nand / spinor_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

nand

+

Displays information about the NAND flash partition.

+

N/A

+

spinor

+

Displays information about the spinor flash partition.

+

N/A

+
+ +## Usage + +- The **partition** command is used to query flash partition information. +- The NAND flash partition information can be viewed only when the YAFFS file system is enabled. The spinor flash partition information can be viewed only when the JFFS or ROMFS file system is enabled. + +## Example + +Enter **partition spinor**. + +## Output + +Viewing spinor flash partition information + +![](figure/en-us_image_0000001052810300.png) + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-pwd.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-pwd.md new file mode 100644 index 0000000000000000000000000000000000000000..9f7182efd733fd05cad0f0a4c8d78f60ac50b074 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-pwd.md @@ -0,0 +1,34 @@ +# pwd + +- [Command Function](#section197737712267) +- [Syntax](#section1544061016267) +- [Parameter Description](#section599112120262) +- [Usage](#section66901116152615) +- [Example](#section7427181922612) +- [Output](#section116313389418) + +## Command Function + +This command is used to display the current path. + +## Syntax + +pwd + +## Parameter Description + +None + +## Usage + +The **pwd** command writes the full path name of the current directory \(from the root directory\) to the standard output. All directories are separated by slashes \(/\). The directory following the first slash \(/\) indicates the root directory, and the last directory is the current directory. + +## Example + +Enter **pwd**. + +## Output + +**Figure 1** Querying the current path +![](figure/querying-the-current-path.png "querying-the-current-path") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-rm.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-rm.md new file mode 100644 index 0000000000000000000000000000000000000000..072bb443e543c0309a97877e7f6a571387b5095f --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-rm.md @@ -0,0 +1,67 @@ +# rm + +- [Command Function](#section181141523142613) +- [Syntax](#section8800926132619) +- [Parameter Description](#section15476229152617) +- [Usage](#section10578163215262) +- [Example](#section18548133511263) +- [Output](#section1565323814265) + +## Command Function + +This command is used to delete a file or folder. + +## Syntax + +rm \[_-r_\] \[_dirname / filename_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-r

+

Deletes a directory. This parameter is optional. It is required if a directory is to be deleted.

+

N/A

+

dirname/filename

+

Indicates the name of the file or directory to be deleted. The value can be a path.

+

N/A

+
+ +## Usage + +- The **rm** command deletes only one file or directory at a time. +- The **rm -r** command can be used to delete a non-empty directory. + +## Example + +Example: + +1. Enter **rm log1.txt**. +2. Enter **rm -r sd**. + +## Output + +**Figure 1** Deleting the **log1.txt** file +![](figure/deleting-the-log1-txt-file.png "deleting-the-log1-txt-file") + +**Figure 2** Deleting the **sd** directory +![](figure/deleting-the-sd-directory.png "deleting-the-sd-directory") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-rmdir.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-rmdir.md new file mode 100644 index 0000000000000000000000000000000000000000..78b7459cd91a8b17f9a7dcc2770362f6599ca5ec --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-rmdir.md @@ -0,0 +1,55 @@ +# rmdir + +- [Command Function](#section1839611420266) +- [Syntax](#section329574512266) +- [Parameter Description](#section15865747102620) +- [Usage](#section107857508261) +- [Example](#section11196165315262) +- [Output](#section1073811415613) + +## Command Function + +This command is used to delete a directory. + +## Syntax + +rmdir \[_dir_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

dir

+

Indicates the name of the directory to be deleted. The directory must be empty. You can enter a path for this parameter.

+

N/A

+
+ +## Usage + +- The **rmdir** command can only be used to delete directories. +- The **rmdir** command can delete only one directory at a time. +- The **rmdir** command can delete only empty directories. + +## Example + +Enter **rmdir dir**. + +## Output + +**Figure 1** Deleting directory **dir** +![](figure/deleting-directory-dir.png "deleting-directory-dir") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-sta.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-sta.md new file mode 100644 index 0000000000000000000000000000000000000000..d2dc901d2cd4c7bc8907b3a9dff3a4812ea099ea --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-sta.md @@ -0,0 +1,52 @@ +# statfs + +- [Command Function](#section153921657152613) +- [Syntax](#section135391102717) +- [Parameter Description](#section074312314279) +- [Usage](#section133816772712) +- [Example](#section526149182717) + +## Command Function + +This command is used to print information about a file system, such as the type, total size, and available size. + +## Syntax + +statfs \[_directory_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

directory

+

Indicates the file system directory.

+

The file system must exist and support the statfs command. Currently, the following file systems are supported: JFFS2, FAT, and NFS.

+
+ +## Usage + +The printed information varies depending on the file system. + +## Example + +The following uses the NFS file system as an example: + +Enter **statfs /nfs**. + +**Figure 1** Output of the statfs command +![](figure/output-of-the-statfs-command.png "output-of-the-statfs-command") + diff --git a/en/device-dev/kernel/sync.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-sync.md similarity index 100% rename from en/device-dev/kernel/sync.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-file-sync.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-touch.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-touch.md new file mode 100644 index 0000000000000000000000000000000000000000..eef1d51cfac06ed388294a2cf896960faf4510ed --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-touch.md @@ -0,0 +1,59 @@ +# touch + +- [Command Function](#section17541924112716) +- [Syntax](#section866182711274) +- [Parameter Description](#section268912296270) +- [Usage](#section412093332714) +- [Example](#section414434814354) +- [Output](#section1028419515711) + +## Command Function + +- This command is used to create an empty file in a specified directory. +- If this command is executed to create an existing file, the execution will be successful but the timestamp will not be updated. + +## Syntax + +touch \[_filename_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

filename

+

Indicates the name of the file to be created.

+

N/A

+
+ +## Usage + +- The **touch** command creates a read-write empty file. +- The **touch** command creates only one file at a time. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >If you run the **touch** command to create a file in a path storing important system resources, unexpected results such as a system breakdown may occur. For example, if you run the **touch uartdev-0** command in the **/dev** path, the system may stop responding. + + +## Example + +Enter **touch file.c**. + +## Output + +**Figure 1** Creating **file.c** +![](figure/creating-file-c.png "creating-file-c") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-umount.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-umount.md new file mode 100644 index 0000000000000000000000000000000000000000..ad2e4575a2e6bc658144afb407ae1a27fd95e468 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-umount.md @@ -0,0 +1,55 @@ +# umount + +- [Command Function](#section365125133520) +- [Syntax](#section9615254123512) +- [Parameter Description](#section63446577355) +- [Usage](#section92931509368) +- [Example](#section144311323616) +- [Output](#section360525113611) + +## Command Function + +This command is used to unmount a specified file system. + +## Syntax + +umount \[_dir_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

dir

+

Indicates the directory from which the file system is to be unmounted.

+

Directory to which the file system has been mounted

+
+ +## Usage + +By specifying the **dir** parameter in the **unmount** command, you can unmount the specified file system from the directory. + +## Example + +Enter **umount /bin1/vs/sd**. + +## Output + +Unmounting the file system from **/bin1/vs/sd** + +**Figure 1** Unmounting result +![](figure/unmounting-result.png "unmounting-result") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-write.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-write.md new file mode 100644 index 0000000000000000000000000000000000000000..5bffaf6a19ae64f27475d646b8982f31c8012d36 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file-write.md @@ -0,0 +1,69 @@ +# writeproc + +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameter Description](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section12742311179) + +## Command Function + +This command is used to write data to a specified proc file system. The proc file system supports the input of string parameters. Each file needs to implement its own method. + +## Syntax + +writeproc <_data_\> \>\> /proc/<_filename_\> + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

data

+

Indicates the string to be entered, which ends with a space. If you need to enter a space, use "" to enclose the space.

+

N/A

+

filename

+

Indicates the proc file to which data is to be passed.

+

N/A

+
+ +## Usage + +The proc file implements its own **write** command. After the **writeproc** command is called, the input parameter will be passed to the **write** command. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The proc file system does not support multi-thread access. + +## Example + +Enter **writeproc test \>\> /proc/uptime**. + +## Output + +OHOS \# writeproc test \>\> /proc/uptime + +\[INFO\]write buf is: test + +test \>\> /proc/uptime + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The uptime proc file temporarily implements the **write** command. The **INFO** log is generated by the implemented **test** command. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-file.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file.md new file mode 100644 index 0000000000000000000000000000000000000000..b47f48fbebd91c9f0edb883f48aa53b360100b46 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-file.md @@ -0,0 +1,45 @@ +# File Commands + +- **[cat](kernel-lite-small-shell-cmd-file-cat.md)** + +- **[cd](kernel-lite-small-shell-cmd-file-cd.md)** + +- **[chgrp](kernel-lite-small-shell-cmd-file-chgrp.md)** + +- **[chmod](kernel-lite-small-shell-cmd-file-chmod.md)** + +- **[chown](kernel-lite-small-shell-cmd-file-chown.md)** + +- **[cp](kernel-lite-small-shell-cmd-file-cp.md)** + +- **[format](kernel-lite-small-shell-cmd-file-format.md)** + +- **[ls](kernel-lite-small-shell-cmd-file-is.md)** + +- **[lsfd](kernel-lite-small-shell-cmd-file-isfd.md)** + +- **[mkdir](kernel-lite-small-shell-cmd-file-mkdir.md)** + +- **[mount](kernel-lite-small-shell-cmd-file-mount.md)** + +- **[partinfo](kernel-lite-small-shell-cmd-file-part.md)** + +- **[partition](kernel-lite-small-shell-cmd-file-partion.md)** + +- **[pwd](kernel-lite-small-shell-cmd-file-pwd.md)** + +- **[rm](kernel-lite-small-shell-cmd-file-rm.md)** + +- **[rmdir](kernel-lite-small-shell-cmd-file-rmdir.md)** + +- **[statfs](kernel-lite-small-shell-cmd-file-sta.md)** + +- **[sync](kernel-lite-small-shell-cmd-file-sync.md)** + +- **[touch](kernel-lite-small-shell-cmd-file-touch.md)** + +- **[writeproc](kernel-lite-small-shell-cmd-file-write.md)** + +- **[umount](kernel-lite-small-shell-cmd-file-umount.md)** + + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-mag.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-mag.md new file mode 100644 index 0000000000000000000000000000000000000000..9bcfa88de03da750fda2be03b4ef15505a27c91f --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-mag.md @@ -0,0 +1,40 @@ +# Magic Key Usage + +- [When to Use](#section2350114718546) +- [How to Use](#section3305151511559) + +## When to Use + +When the system does not respond, you can use the magic key function to check whether the system is locked and interrupted \(the magic key also does not respond\) or view the system task running status. + +If the interrupt is responded, you can use the magic key to check the CPU usage \(**cpup**\) in the task information to find out the task that occupies the CPU for a long period of time and causes other tasks in the system not to respond. \(Generally, the high-priority tasks always preempt the CPU and cause the low-priority tasks not to respond.\) + +## How to Use + +1. Configure macro **LOSCFG\_ENABLE\_MAGICKEY**. + +The magic key depends on the **LOSCFG\_ENABLE\_MAGICKEY** macro. To use the magic key, enable the **Enable MAGIC KEY** configuration item using **menuconfig**. + +Debug ---\> Enable MAGIC KEY + +If this configuration item is disabled, the magic key is invalid. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>1. In **menuconfig**, you can move the cursor to **LOSCFG\_ENABLE\_MAGICKEY** and enter a question mark \(?\) to view the help information. + +2. Press **Ctrl+R** to enable the magic key detection function. + +When the UART or USB-to-virtual serial port is connected, press **Ctrl+R** to enable the magic key detection function. The message "Magic key on" is displayed. After you press **Ctrl+R** again, the magic key detection function is disabled, and message "Magic key off" is displayed. The functions of the magic key are as follows: + +- **Ctrl+Z**: help key, which is used to display the brief introduction to related magic keys. + +- **Ctrl+T**: displays task information. + +- **Ctrl+P**: The system proactively enters the panic state. After the panic-related information is printed, the system is suspended. + +- **Ctrl+E**: The system checks the integrity of the memory pool. If an error is detected, the system displays an error message. If no error is detected, the system displays "system memcheck over, all passed!". + + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>When the magic key detection function is enabled and special characters need to be entered through the UART or USB-to-virtual serial port, ensure that the special characters are not the same as the magic key values. Otherwise, the magic key may be triggered by mistake, which may cause errors in the original design. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-arp.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-arp.md new file mode 100644 index 0000000000000000000000000000000000000000..b0267af58de2fbc692cabe60efe2f02ba0c367ad --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-arp.md @@ -0,0 +1,114 @@ +# arp + +- [Command Function](#section201149459368) +- [Syntax](#section579813484364) +- [Parameter Description](#section168065311366) +- [Usage](#section19190125723612) +- [Example](#section10383416372) + +## Command Function + +On an Ethernet, hosts communicate with each other using MAC addresses \(non-IP addresses\). Therefore, IP addresses must be converted into MAC addresses so that hosts can communicate with each other on a LAN \(Ethernet\). To resolve this issue, the host stores a table containing the mapping between IP addresses and MAC addresses, that is, the ARP cache table. When the host needs to send an IP packet to the destination IP address on a LAN, the host can query the destination MAC address from the ARP cache table. The ARP cache table is maintained by the TCP/IP protocol stack. You can run the **arp** command to view and modify the ARP cache table. + +## Syntax + +arp + +arp \[_-i IF_\] -s _IPADDR HWADDR_ + +arp \[_-i IF_\] -d _IPADDR_ + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

No parameter

+

Prints the content of the entire ARP cache table.

+

N/A

+

-i IF

+

Indicates the network interface. This parameter is optional.

+

N/A

+

-s IPADDR

+

HWADDR

+

Adds an ARP entry. The second parameter is the IP address and MAC address of the other host on the LAN.

+

N/A

+

-d IPADDR

+

Deletes an ARP entry.

+

N/A

+
+ +## Usage + +- The **arp** command is used to query and modify the ARP cache table of the TCP/IP protocol stack. If ARP entries for IP addresses on different subnets are added, the protocol stack returns a failure message. +- This command can be used only after the TCP/IP protocol stack is enabled. + +## Example + +Example: + +1. Enter **arp**. + + **Figure 1** Printing the entire ARP cache table + + + ![](figure/snipaste_2021-01-26_10-38-58.png) + + **Table 2** Output description + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Address

+

Indicates the IPv4 address of a network device.

+

HWaddress

+

Indicates the MAC address of a network device.

+

Iface

+

Indicates the name of the interface used by the ARP entry.

+

Type

+

Indicates whether the ARP entry is dynamic or static. A dynamic ARP entry is automatically created by the protocol stack, and a static ARP entry is added by the user.

+
+ + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-dh.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-dh.md new file mode 100644 index 0000000000000000000000000000000000000000..fd93fad650c847384d2b77405089bf6c8780d450 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-dh.md @@ -0,0 +1,138 @@ +# dhclient + +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameter Description](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section12742311179) + +## Command Function + +This command is used to set and view **dhclient** parameters. + +## Syntax + +dhclient <_netif name_\> + +dhclient -x <_netif name_\> + +dhclient -gb <_netif name_\> + +dhclient -sv <_vendor_\> + +dhclient -gv + +dhclient -gd <_index_\> + +dhclient -sd <_dns\_ip_\> + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

<netif name>

+

Starts the DHCP request of the network interface card (NIC).

+

NIC name, eth0

+

-x <netif name>

+

Disables the DHCP function for the NIC.

+

NIC name, eth0

+

-gb <netif name>

+

Checks whether the DHCP request of the NIC is complete.

+

NIC name, eth0

+

-sv <vendor>

+

Sets the vendor information of a DHCP request.

+

Vendor information (The value is a string of 32 characters.)

+

-gv

+

Displays the vendor information in a DHCP request.

+

N/A

+

-gd <index>

+

Obtains information about the DNS server at the specified index.

+

Index, 0 or 1

+

-sd <dns_ip>

+

Indicates the IP address of the active DNS server.

+

IP address of the DNS server

+
+ +## Usage + +dhclient eth0 + +dhclient -x eth0 + +dhclient -gb eth0 + +dhclient -sv MFSI + +dhclient -gv + +dhclient -gd 0 + +dhclient -sd 8.8.8.8 + +## Example + +![](figure/en-us_image_0000001053224218.png) + +## Output + +**Table 2** Output description + + + + + + + + + + + + + +

Parameter

+

Description

+

dhclient: set vendor info [MFSI] success

+

Indicates that the MFSI information is successfully set.

+

dns[0]: 192.168.1.100

+

Indicates that the IP address of the DNS server is 192.168.1.100.

+
+ diff --git a/en/device-dev/kernel/dns.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-dns.md similarity index 100% rename from en/device-dev/kernel/dns.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-net-dns.md diff --git a/en/device-dev/kernel/ifconfig.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipc.md similarity index 100% rename from en/device-dev/kernel/ifconfig.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipc.md diff --git a/en/device-dev/kernel/ipdebug.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipd.md similarity index 100% rename from en/device-dev/kernel/ipdebug.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipd.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-net.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-net.md new file mode 100644 index 0000000000000000000000000000000000000000..362fa9a4301ca48b86cab9e2732fcfdfd9a89c4e --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-net.md @@ -0,0 +1,83 @@ +# netstat + +- [Command Function](#section13469162113816) +- [Syntax](#section795712373812) +- [Parameter Description](#section17629431193817) +- [Usage](#section5277153519380) +- [Example](#section108141437163820) +- [Output](#section1357015107117) + +## Command Function + +The **netstat** command is a console command and is used for monitoring the TCP/IP network. It can display the actual network connections and the status of each network interface device. It is used to display the statistics related to the TCP and UDP protocols and check the network connection to each port on the device \(board\). + +## Syntax + +netstat + +## Parameter Description + +None + +## Usage + +Run the command directly. + +## Example + +Enter **netstat**. + +**Figure 1** Output information + + +![](figure/snipaste_2021-01-26_10-38-58-20.png) + +## Output + +**Table 1** Output description + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Proto

+

Indicates the protocol type.

+

Recv-Q

+

Indicates the amount of data that is not read by the user.

+

For Listen TCP, the value indicates the number of TCP connections that have completed three-way handshake but are not accepted by users.

+

Send-Q

+

For a TCP connection, this value indicates the amount of data that has been sent but not acknowledged.

+

For a UDP connection, this value indicates the amount of data buffered before IP address resolution is complete.

+

Local Address

+

Indicates the local IP address and port number.

+

Foreign Address

+

Indicates the remote IP address and port number.

+

State

+

Indicates the TCP connection status. This parameter is meaningless for UDP.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The command output like "========== total sockets 32 ====== unused sockets 22 BootTime 27 s ==========" indicates that there are 32 sockets in total, 22 sockets are not used, and it has been 27 seconds since the system starts. + diff --git a/en/device-dev/kernel/ntpdate.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ntp.md similarity index 100% rename from en/device-dev/kernel/ntpdate.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ntp.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping.md new file mode 100644 index 0000000000000000000000000000000000000000..0d83722cacc365360530ae1ea7d9e141cb86155c --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping.md @@ -0,0 +1,98 @@ +# ping + +- [Command Function](#section119672573385) +- [Syntax](#section869419010390) +- [Parameter Description](#section9877183173918) +- [Usage](#section1097046193914) +- [Example](#section14564129113911) +- [Output](#section1621732891215) + +## Command Function + +This command is used to test whether the network connection is normal. + +## Syntax + +ping_ _\[_-n cnt_\] \[_-w interval_\] \[_-l data\_len_\]_ _ + +ping \[_-t_\] \[_-w interval_\] __ + +ping _-k_ + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

IP

+

Indicates the IPv4 address whose network connectivity is to be tested.

+

N/A

+

-n cnt

+

Indicates the number of execution times. If this parameter is not specified, the default value is 4.

+

1-65535

+

-w interval

+

Indicates the interval between two ping packets, in ms.

+

>0

+

-l data_len

+

Indicates the length of the ping packet, that is, the ICMP echo request packet.

+

The ICMP packet header is not included.

+

0-65500

+

-t

+

Indicates a permanent ping thread, which will be killed until the ping -k command is executed.

+

N/A

+

-k

+

Kills the ping thread and stops the ping operation.

+

N/A

+
+ +## Usage + +- Run the **ping** command by setting a destination IP address to check whether the network connection to the destination IP address is normal. +- If the destination IP address is unreachable, the system displays a message indicating that the request times out. +- If no route is available to the destination IP address, an error message is displayed. +- This command can be used only after the TCP/IP protocol stack is enabled. + +## Example + +Enter **ping 192.168.1.10**. + +## Output + +**Figure 1** Output of pinging the IP address of the TFTP server + + +![](figure/snipaste_2021-01-26_10-38-58-21.png) + diff --git a/en/device-dev/kernel/ping6.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping6.md similarity index 100% rename from en/device-dev/kernel/ping6.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping6.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-tel.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-tel.md new file mode 100644 index 0000000000000000000000000000000000000000..30c190696e0d3b2ef1a2ead7cc8d1e25997909b3 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-tel.md @@ -0,0 +1,65 @@ +# telnet + +- [Command Function](#section3551830123913) +- [Syntax](#section14897133233918) +- [Parameter Description](#section977718353392) +- [Usage](#section134991538183916) +- [Example](#section1097414426398) +- [Output](#section11846624191310) + +## Command Function + +This command is used to enable or disable the Telnet server service. + +## Syntax + +telnet \[_on | off_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

on

+

Enables the Telnet server service.

+

N/A

+

off

+

Disables the Telnet server service.

+

N/A

+
+ +## Usage + +- Before enabling Telnet, ensure that the network driver and network protocol stack have been initialized and the NIC of the board is in the **link up** state. +- Currently, multiple clients \(Telnet + IP\) cannot connect to the development board at the same time. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >Telnet is under debugging and disabled by default. Do not use it in formal products. + + +## Example + +Enter **telnet on**. + +## Output + +**Figure 1** Output of **telnet on** +![](figure/output-of-telnet-on.png "output-of-telnet-on") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-tftp.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-tftp.md new file mode 100644 index 0000000000000000000000000000000000000000..3da40ac274b26ac660065256ad5d8a99c9da8468 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net-tftp.md @@ -0,0 +1,87 @@ +# tftp + +- [Command Function](#section15142134573911) +- [Syntax](#section20958174917394) +- [Parameter Description](#section576613532395) +- [Usage](#section149795134408) +- [Example](#section148921918114015) +- [Output](#section7872155631313) + +## Command Function + +Trivial File Transfer Protocol \(TFTP\) is a protocol in the TCP/IP protocol suite for transferring files between clients and servers. TFTP provides simple and low-overhead file transfer services. The port number is 69. + +The **tftp** command is used to download files from the TFTP server. + +## Syntax + +./bin/tftp _<-g/-p\>_ _-l_ _\[FullPathLocalFile\] -r \[RemoteFile\] \[Host\]_ + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-g/-p

+

Indicates the file transfer direction.

+
  • -g: downloads files from the TFTP server.
  • -p: uploads files to the TFTP server.
+

N/A

+

-l FullPathLocalFile

+

Indicates the complete path of a local file.

+

N/A

+

-r RemoteFile

+

Indicates the file name on the server.

+

N/A

+

Host

+

Indicates the server IP address.

+

N/A

+
+ +## Usage + +1. Deploy a TFTP server on the server and configure the TFTP server correctly. +2. Use the **tftp** command to upload and download files on the OpenHarmony board. +3. The size of the file to be transferred cannot exceed 32 MB. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >TFTP is under debugging and disabled by default. Do not use it in formal products. + + +## Example + +Download the **out** file from the server. + +## Output + +``` +OHOS # ./bin/tftp -g -l /nfs/out -r out 192.168.1.2 +TFTP transfer finish +``` + +After the **tftp** command is executed, **TFTP transfer finish** is displayed if the file transfer is complete. If the file transfer fails, other information is displayed to help locate the fault. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-net.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net.md new file mode 100644 index 0000000000000000000000000000000000000000..68d76bf26eccdeef28fa67938389cdae428d81f4 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-net.md @@ -0,0 +1,25 @@ +# Network Commands + +- **[arp](kernel-lite-small-shell-cmd-net-arp.md)** + +- **[dhclient](kernel-lite-small-shell-cmd-net-dh.md)** + +- **[dns](kernel-lite-small-shell-cmd-net-dns.md)** + +- **[ifconfig](kernel-lite-small-shell-cmd-net-ipc.md)** + +- **[ipdebug](kernel-lite-small-shell-cmd-net-ipd.md)** + +- **[netstat](kernel-lite-small-shell-cmd-net-net.md)** + +- **[ntpdate](kernel-lite-small-shell-cmd-net-ntp.md)** + +- **[ping](kernel-lite-small-shell-cmd-net-ping.md)** + +- **[ping6](kernel-lite-small-shell-cmd-net-ping6.md)** + +- **[telnet](kernel-lite-small-shell-cmd-net-tel.md)** + +- **[tftp](kernel-lite-small-shell-cmd-net-tftp.md)** + + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-cpup.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-cpup.md new file mode 100644 index 0000000000000000000000000000000000000000..fc8d35798807612cd32d68d78af1735edab736fc --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-cpup.md @@ -0,0 +1,63 @@ +# cpup + +- [Command Function](#section1842161614217) +- [Syntax](#section5629527427) +- [Parameter Description](#section133651361023) +- [Usage](#section156611948521) +- [Example](#section68501605319) +- [Output](#section19871522144219) + +## Command Function + +This command is used to query the CPU usage of the system. + +## Syntax + +cpup \[_mode_\] \[_taskID_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

mode

+

Indicates the period in which the CPU usage is to be queried. By default, the CPU usage within the last 10 seconds is displayed.

+
  • 0: displays the CPU usage of the system within the last 10 seconds.
  • 1: displays the CPU usage of the system within the last 1 second.
  • Other value: displays the total CPU usage since the system is started.
+

[0, 0xFFFFFFFF]

+

taskID

+

Indicates the task ID.

+

[0, 0xFFFFFFFF]

+
+ +## Usage + +- If the parameters are not specified, the CPU usage within the last 10 seconds is displayed. +- If only the **mode** parameter is specified, the CPU usage within the specified period is displayed. +- If both the **mode** and **taskID** parameters are specified, the CPU usage of the specified task within the given period is displayed. + +## Example + +Enter **cpup 1 5**. + +## Output + +**Figure 1** CPU usage +![](figure/cpu-usage.png "cpu-usage") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-date.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-date.md new file mode 100644 index 0000000000000000000000000000000000000000..ebd63e75d05e9f349275be20f465b3c3a15ca561 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-date.md @@ -0,0 +1,92 @@ +# date + +- [Command Function](#section56472016338) +- [Syntax](#section16635112512316) +- [Parameter Description](#section15896030039) +- [Usage](#section116361036636) +- [Example](#section021711411237) +- [Output](#section17950184414312) + +## Command Function + +This command is used to query and set the system date and time. + +## Syntax + +date + +date --help + +date +\[_Format_\] + +date -s_ _\[_YY/MM/DD_\] + +date_ _-s_ _\[_hh:mm:ss_\]__ + +date -r \[_Filename_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

--help

+

Uses the help.

+

N/A

+

+Format

+

Prints the date and time based on Format.

+

Placeholders listed in --help.

+

-s YY/MM/DD

+

Sets the system date and separates the year, month, and day by slashes (/).

+

>= 1970/01/01

+

-s hh:mm:ss

+

Sets the system time and separates the hour, minute, and second by colons (:).

+

N/A

+

-r Filename

+

Queries the modification time of the Filename file.

+

N/A

+
+ +## Usage + +- If the **date** parameter is not specified, the current system date and time are displayed by default. +- The **--help**, **+Format**, **-s**, and **-r** parameters are mutually exclusive. + +## Example + +Enter **date +%Y--%m--%d**. + +## Output + +**Figure 1** System date printed based on the specified format +![](figure/system-date-printed-based-on-the-specified-format.png "system-date-printed-based-on-the-specified-format") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-demsg.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-demsg.md new file mode 100644 index 0000000000000000000000000000000000000000..d122787795603df26b1d319151fa094c4cd674fa --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-demsg.md @@ -0,0 +1,111 @@ +# dmesg + +- [Command Function](#section4643204919313) +- [Syntax](#section6553153635) +- [Parameter Description](#section208971157532) +- [Usage](#section213115219413) +- [Example](#section13736564418) +- [Output](#section194005101413) + +## Command Function + +This command is used to control the dmesg buffer of the kernel. + +## Syntax + +dmesg + +dmesg \[_-c/-C/-D/-E/-L/-U_\] + +dmesg -s \[_size_\] + +dmesg -l \[_level_\] + +dmesg \> \[_fileA_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-c

+

Prints content in the buffer and clears the buffer.

+

N/A

+

-C

+

Clears the buffer.

+

N/A

+

-D/-E

+

Enables or disables printing to the console.

+

N/A

+

-L/-U

+

Enables or disables printing via the serial port.

+

N/A

+

-s size

+

Sets the size of the buffer.

+

N/A

+

-l level

+

Sets the buffering level.

+

0 - 5

+

> fileA

+

Writes the content in the buffer to a file.

+

N/A

+
+ +## Usage + +- This command depends on **LOSCFG\_SHELL\_DMESG**. Before running this command, enable the **Enable Shell dmesg** configuration item using **menuconfig**. + + Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell dmesg + +- If the parameters are not specified, all content in the buffer is printed. +- The parameters followed by hyphens \(-\) are mutually exclusive. + 1. Before writing content to a file, ensure that the file system has been mounted. + 2. Disabling the serial port printing will adversely affect the shell. You are advised to set up a connection using Telnet before disabling the serial port. + + +## Example + +Enter **dmesg \> /usr/dmesg.log**. + +## Output + +**Figure 1** Writing dmesg content to a file +![](figure/writing-dmesg-content-to-a-file.png "writing-dmesg-content-to-a-file") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-exec.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-exec.md new file mode 100644 index 0000000000000000000000000000000000000000..e68a27f893b835538ac24e9ed38eacf4854d10ed --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-exec.md @@ -0,0 +1,58 @@ +# exec + +- [Command Function](#section4643204919313) +- [Syntax](#section6553153635) +- [Parameter Description](#section208971157532) +- [Usage](#section213115219413) +- [Example](#section13736564418) +- [Output](#section194005101413) + +## Command Function + +This command is a built-in shell command used to execute user-space programs. + +## Syntax + +exec <_executable-file_\> + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

executable-file

+

Indicates a valid executable file.

+

N/A

+
+ +## Usage + +Currently, this command supports only valid binary programs. The programs are successfully executed and then run in the background by default. However, the programs share the same device with the shell. As a result, the output of the programs and the shell may be interlaced. + +## Example + +Enter **exec helloworld**. + +## Output + +``` +OHOS # exec helloworld +OHOS # hello world! +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>After the executable file is executed, prompt **OHOS \#** is printed first. The shell **exec** command is executed in the background, causing the prompt to be printed in advance. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-free.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-free.md new file mode 100644 index 0000000000000000000000000000000000000000..09e281e9f498c2673b1c71974cc80ab23cc4cce0 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-free.md @@ -0,0 +1,119 @@ +# free + +- [Command Function](#section175151514841) +- [Syntax](#section8488721749) +- [Parameter Description](#section27272181949) +- [Usage](#section148661259410) +- [Example](#section68081530242) +- [Output](#section171235517543) + +## Command Function + +This command is used to display the system memory usage and the sizes of the **text**, **data**, **rodata**, and **bss** segments. + +## Syntax + +free \[_-k | -m_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

No parameter

+

Displays the size in the unit of byte.

+

N/A

+

-k

+

Displays the size in the unit of KB.

+

N/A

+

-m

+

Displays the size in the unit of MB.

+

N/A

+
+ +## Usage + +None + +## Example + +Enter **free**, **free -k**, and **free -m**, respectively. + +## Output + +**Figure 1** Displaying the memory usage in three units +![](figure/displaying-the-memory-usage-in-three-units.png "displaying-the-memory-usage-in-three-units") + +**Table 2** Output description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

total

+

Indicates the total size of the dynamic memory pool.

+

used

+

Indicates the size of the used memory.

+

free

+

Indicates the size of the unallocated memory.

+

heap

+

Indicates the size of the allocated heap.

+

text

+

Indicates the size of a code segment.

+

data

+

Indicates the size of a data segment.

+

rodata

+

Indicates the size of a read-only data segment.

+

bss

+

Indicates the size of the memory occupied by uninitialized global variables.

+
+ diff --git a/en/device-dev/kernel/help.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-help.md similarity index 100% rename from en/device-dev/kernel/help.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-help.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-hwi.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-hwi.md new file mode 100644 index 0000000000000000000000000000000000000000..90027ac456a656ca1dd41d7451491df2caba5ba7 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-hwi.md @@ -0,0 +1,94 @@ +# hwi + +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameter Description](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + +## Command Function + +This command is used to query information about the current interrupts. + +## Syntax + +hwi + +## Parameter Description + +None + +## Usage + +- Enter **hwi** to display the current interrupt ID, count of interrupts, and registered interrupt name. +- If **LOSCFG\_CPUP\_INCLUDE\_IRQ** is enabled, the processing time \(cycles\), CPU usage, and interrupt type of each interrupt are displayed. + +## Example + +Enter **hwi**. + +## Output + +1. Interrupt information \(with **LOSCFG\_CPUP\_INCLUDE\_IRQ** disabled\) + + ![](figure/en-us_image_0000001053826366.png) + +2. Interrupt information \(with **LOSCFG\_CPUP\_INCLUDE\_IRQ** enabled\) + + ![](figure/en-us_image_0000001052810304.png) + + **Table 1** Output description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

InterruptNo

+

Indicates the interrupt ID.

+

Count

+

Indicates the count of interrupts.

+

Name

+

Indicates the registered interrupt name.

+

CYCLECOST

+

Indicates the interrupt processing time (cycles).

+

CPUUSE

+

Indicates the CPU usage.

+

CPUUSE10s

+

Indicates CPU usage within the last 10 seconds.

+

CPUUSE1s

+

Indicates CPU usage within the last 1 second.

+

mode

+

Indicates the interrupt mode.

+
  • normal: non-shared interrupt.
  • shared: shared interrupt.
+
+ + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-kill.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-kill.md new file mode 100644 index 0000000000000000000000000000000000000000..3b69b6c8da73988cfbd00566587adffc425613b7 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-kill.md @@ -0,0 +1,82 @@ +# kill + +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameter Description](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section12742311179) + +## Command Function + +This command is used to send a specific signal to a specified process. + +## Syntax + +kill \[_signo_ | _-signo_\] \[_pid_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

signo

+

Indicates the signal ID.

+

[1, 30]

+

pid

+

Indicates the process ID.

+

[1, MAX_INT]

+
+ +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>The valid range of the **signo** value is \[0, 64\], and the recommended value range is \[1, 30\]. Other values in the valid range are reserved. + +## Usage + +The **signo** and **pid** parameters are mandatory. + +The **pid** value range varies depending on the system configuration. For example, if the maximum **pid** value supported by the system is **256**, this value range is \[1-256\]. + +## Example + +1. Query the current process list and determine the PID \(7\) of the process to be killed. + +**Figure 1** Querying PIDs +![](figure/querying-pids.png "querying-pids") + +2. Run **kill 14 7** to send signal 14 \(the default behavior of **SIGALRM** is to terminate the process\) to process 7 **helloworld\_d** \(user-space\). Then query the current process list. Process 7 has been terminated. The result of the **kill 14 7** command is the same as that of the **kill -14 7** command. + +**Figure 2** Command output +![](figure/command-output.png "command-output") + +## Output + +The command output is as follows: + +**Figure 3** Sending a signal to a specified process +![](figure/sending-a-signal-to-a-specified-process.png "sending-a-signal-to-a-specified-process") + +The signal is successfully sent if no error is reported. + +**Figure 4** Signal sending failure +![](figure/signal-sending-failure.png "signal-sending-failure") + +The preceding figure shows a signal sending failure caused by invalid parameters. In this case, check that the signal ID and PID are valid. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-log.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-log.md new file mode 100644 index 0000000000000000000000000000000000000000..ae7b0cde098849ed4a0762b59394ac75531c7fc7 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-log.md @@ -0,0 +1,72 @@ +# log + +- [Command Function](#section128219131856) +- [Syntax](#section3894181710519) +- [Parameter Description](#section7693122310515) +- [Usage](#section1982111281512) +- [Example](#section176301333259) +- [Output](#section14354765415) + +## Command Function + +This command is used to modify and query log configurations. + +## Syntax + +log level \[_levelNum_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

levelNum

+

Indicates the print level of configuration logs.

+

[0x0, 0x5]

+
+ +## Usage + +- This command depends on **LOSCFG\_SHELL\_LK**. Before running this command, enable the **Enable Shell lk** configuration item using **menuconfig**. + + Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell lK + +- The **log level** command is used to configure log levels, which can be: + + TRACE\_EMG = 0, + + TRACE\_COMMON = 1, + + TRACE\_ERROR = 2, + + TRACE\_WARN = 3, + + TRACE\_INFO = 4, + + TRACE\_DEBUG = 5 + + If the level is not within the valid range, a message is printed. + +- If the **\[levelNum\]** parameter is not specified, the current log level and its usage are printed by default. + +## Example + +Enter **log level 4**. + +## Output + +![](figure/en-us_image_0000001052530298.png) + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-mem.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-mem.md new file mode 100644 index 0000000000000000000000000000000000000000..965a6eb17045482ecf59a9e19e0f4e8e5e7cfa77 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-mem.md @@ -0,0 +1,38 @@ +# memcheck + +- [Command Function](#section191633812516) +- [Syntax](#section428816435510) +- [Parameter Description](#section1939943304411) +- [Usage](#section228914491951) +- [Example](#section17373205314515) +- [Output](#section13406205385413) + +## Command Function + +This command is used to check whether the dynamically requested memory block is complete and whether nodes in the memory pool are damaged due to out-of-bounds memory access. + +## Syntax + +memcheck + +## Parameter Description + +None + +## Usage + +- If all nodes in the memory pool are complete, "system memcheck over, all passed!" is displayed. +- If a node in the memory pool is incomplete, information about the memory block of the damaged node is displayed. + +## Example + +Enter **memcheck**. + +## Output + +**Figure 1** No out-of-bounds memory access +![](figure/no-out-of-bounds-memory-access.png "no-out-of-bounds-memory-access") + +**Figure 2** Out-of-bounds memory access +![](figure/out-of-bounds-memory-access.png "out-of-bounds-memory-access") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-oom.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-oom.md new file mode 100644 index 0000000000000000000000000000000000000000..7748844b3fc8ddc7d2a213b262481fc554aaa1be --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-oom.md @@ -0,0 +1,120 @@ +# oom + +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameter Description](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section12742311179) + +## Command Function + +This command is used to query and set the low memory threshold and the page cache reclaim threshold. + +## Syntax + +oom + +oom -i \[_interval_\] + +oom -m \[_mem byte_\] + +oom -r \[_mem byte_\] + +oom -h | --help + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-i [interval]

+

Sets the interval for checking the Out Of Memory (OOM) thread task.

+

100 ms – 10000 ms

+

-m [mem byte]

+

Sets the low memory threshold.

+

0 MB (does not check for low memory) – 1 MB

+

-r [mem byte]

+

Sets the page cache reclaim threshold.

+

Ranging from the low memory threshold to the maximum available system memory

+

-h | --help

+

Uses the help.

+

N/A

+
+ +## Usage + +- If no parameter is specified, the current configurations of the OOM function are displayed. + +## Example + +When the system memory is insufficient, the system displays a message indicating the insufficiency. + +## Output + +![](figure/en-us_image_0000001053710680.png) + +**Table 2** Output description + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

[oom] OS is in low memory state

+

total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte)

+

The memory usage of the OS is low.

+

The available physical memory in the entire OS is 0x1bcf000 bytes, 0x1b50000 bytes have been used, and 0x7f000 bytes are available. The current low memory threshold is 0x80000 bytes.

+

[oom] candidate victim process init pid: 1, actual phy mem byte: 82602

+

The memory usage of each process is printed. The init process actually uses 82602 bytes, and the shared memory is calculated based on the proportion.

+

[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558

+

The actual memory used by the UserProcess12 process is 25951558 bytes.

+

[oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558

+

The process that uses the most memory currently is UserProcess12.

+

excFrom: User!

+

When the system memory is low, the UserProcess12 process fails to apply for memory and exits as a result.

+
+ diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-pmm.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-pmm.md new file mode 100644 index 0000000000000000000000000000000000000000..34e2594d5d6d61d6cbb935b62986eb796334d5b5 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-pmm.md @@ -0,0 +1,91 @@ +# pmm + +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameter Description](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + +## Command Function + +This command is used to check the usage of the physical pages and page cache of the system memory. + +## Syntax + +pmm + +## Parameter Description + +None + +## Usage + +This command is available only in the **Debug** version. + +## Example + +Enter **pmm**. + +## Output + +**Figure 1** Viewing the usage of physical pages +![](figure/viewing-the-usage-of-physical-pages.png "viewing-the-usage-of-physical-pages") + +**Table 1** Output description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

phys_seg

+

Indicates the address of the physical page control block.

+

base

+

Indicates the first physical page address, that is, start address of the physical page memory.

+

size

+

Indicates the size of the physical page memory.

+

free_pages

+

Indicates the number of idle physical pages.

+

active anon

+

Indicates the number of active anonymous pages in the page cache.

+

inactive anon

+

Indicates the number of inactive anonymous pages in the page cache.

+

active file

+

Indicates the number of active file pages in the page cache.

+

inactive file

+

Indicates the number of inactive file pages in the page cache.

+

pmm pages

+
  • total: indicates the total number of physical pages.
  • used: indicates the number of used physical pages.
  • free: indicates the number of idle physical pages.
+
+ diff --git a/en/device-dev/kernel/reset.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-reset.md similarity index 100% rename from en/device-dev/kernel/reset.md rename to en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-reset.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sem.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sem.md new file mode 100644 index 0000000000000000000000000000000000000000..1941131dd0fcc3a410f4786a9491a2ee34d79547 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sem.md @@ -0,0 +1,91 @@ +# sem + +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameter Description](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section1975118519456) + +## Command Function + +This command is used to query information about kernel semaphores. + +## Syntax + +sem \[_ID__ / fulldata_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

ID

+

Indicates the semaphore ID.

+

[0, 0xFFFFFFFF]

+

fulldata

+

Queries information about all the semaphores in use. The information to be printed includes SemID, Count, OriginalCount, Creater(TaskEntry), and LastAccessTime.

+

N/A

+
+ +## Usage + +- If the parameters are not specified, this command displays the number of used semaphores and the total number of semaphores. +- If the **ID** parameter is specified, semaphores of the specified ID are displayed. +- The **fulldata** parameter depends on **LOSCFG\_DEBUG\_SEMAPHORE**. Before specifying the **fulldata** parameter, enable the **Enable Semaphore Debugging** configuration item using **menuconfig**. + + Debug ---\> Enable a Debug Version ---\> Enable Debug LiteOS Kernel Resource ---\> Enable Semaphore Debugging + + +## Example + +Example 1: Enter **sem fulldata**. + +## Output + +**Figure 1** Querying information about all semaphores in use +![](figure/querying-information-about-all-semaphores-in-use.png "querying-information-about-all-semaphores-in-use") + +**Table 2** Output description + + + + + + + + + + + + + +

Parameter

+

Description

+

SemID

+

Indicates the semaphore ID.

+

Count

+

Indicates the number of used semaphores.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- The **ID** value can be in decimal or hexadecimal format. +>- When the **ID** value is within the range of \[0, 1023\], semaphore information of the specified ID is displayed. If the semaphore ID is not used, a message is displayed to inform you of this case. For other values, a message is displayed indicating that the input parameter is incorrect. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-stack.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-stack.md new file mode 100644 index 0000000000000000000000000000000000000000..e9d5ab785c3dbca69d6245083c90e6522e3fd826 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-stack.md @@ -0,0 +1,73 @@ +# stack + +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameter Description](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + +## Command Function + +This command is used to check the usage of each stack in the system. + +## Syntax + +stack + +## Parameter Description + +None + +## Usage + +None + +## Example + +Enter **stack**. + +## Output + +**Figure 1** System stack usage + + +![](figure/en-us_image_0000001054624363.png) + +**Table 1** Output description + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

stack name

+

Indicates the system stack name.

+

cpu id

+

Indicates the CPU ID.

+

stack addr

+

Indicates the stack address.

+

total size

+

Indicates the stack size.

+

used size

+

Indicates the used size of the stack.

+
+ diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-su.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-su.md new file mode 100644 index 0000000000000000000000000000000000000000..44f370e01867c0ac061f77598d178c93d71241fb --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-su.md @@ -0,0 +1,62 @@ +# su + +- [Command Function](#section297810431676) +- [Syntax](#section157131147876) +- [Parameter Description](#section04145521671) +- [Usage](#section14615155610719) +- [Example](#section13338150985) +- [Output](#section125021924194613) + +## Command Function + +This command is used to switch the user. + +## Syntax + +su \[_uid_\] \[_gid_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

uid

+

Indicates the ID of the target user.

+
  • Left blank
  • [0, 60000]
+

gid

+

Indicates the ID of the target user group.

+
  • Left blank
  • [0, 60000]
+
+ +## Usage + +- The **su** command is used to switch to user **root** by default. The default value for both **uid** and **gid** is **0**. +- If the **uid** and **gid** parameters are specified, this command can switch to the user with the specified **uid** and **gid**. +- If the input parameter is out of the range, an error message is printed. + +## Example + +Enter **su 1000 1000**. + +## Output + +**Figure 1** Switching to the user whose **uid** and **gid** are both **1000** +![](figure/switching-to-the-user-whose-uid-and-gid-are-both-1000.png "switching-to-the-user-whose-uid-and-gid-are-both-1000") + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-swymr.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-swymr.md new file mode 100644 index 0000000000000000000000000000000000000000..c69f0d3c071d618f595d4418f3763b05ebda77eb --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-swymr.md @@ -0,0 +1,110 @@ +# swtmr + +- [Command Function](#section166171064814) +- [Syntax](#section424011111682) +- [Parameter Description](#section1268410459465) +- [Usage](#section169806213815) +- [Example](#section16676026389) +- [Output](#section1541991614710) + +## Command Function + +This command is used to query information about system software timers. + +## Syntax + +swtmr \[_ID_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

ID

+

Indicates the ID of a software timer.

+

[0, 0xFFFFFFFF]

+
+ +## Usage + +- If the parameter is not specified, information about all software timers is displayed. +- If the **ID** parameter is specified, information about the specified software timer is displayed. + +## Example + +Enter **swtmr** and **swtmr 1**. + +## Output + +**Figure 1** Querying information about all software timers +![](figure/querying-information-about-all-software-timers.png "querying-information-about-all-software-timers") + +**Figure 2** Querying information about a specified software timer +![](figure/querying-information-about-a-specified-software-timer.png "querying-information-about-a-specified-software-timer") + +**Table 2** Output description + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

SwTmrID

+

Indicates the ID of the software timer.

+

State

+

Indicates the status of the software timer.

+

The value can be UnUsed, Created, or Ticking.

+

Mode

+

Indicates the mode of the software timer.

+

The value can be Once, Period, or NSD (one-time timer that will not be automatically deleted after the timer expires).

+

Interval

+

Indicates the number of ticks used by the software timer.

+

Count

+

Indicates the number of times that the software timer has been working.

+

Arg

+

Indicates the input parameter.

+

handlerAddr

+

Indicates the callback address.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- The **ID** value can be in decimal or hexadecimal format. +>- If the **ID** value is within the range of \[0, _Number of current software timers - 1_\], the status of the specified software timer is returned. For other values, an error message is displayed. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sys.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sys.md new file mode 100644 index 0000000000000000000000000000000000000000..8868225020ea651976928fda71a42afe12fc715c --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sys.md @@ -0,0 +1,91 @@ +# systeminfo + +- [Command Function](#section863016434820) +- [Syntax](#section139791817795) +- [Parameter](#section19472339164813) +- [Usage](#section285522592) +- [Example](#section9471171015105) +- [Output](#section1657011114915) + +## Command Function + +This command is used to display the resource usage of the current OS, including tasks, semaphores, mutexes, queues, and timers. + +## Syntax + +systeminfo + +## Parameter + +None + +## Usage + +None + +## Example + +Enter **systeminfo**. + +## Output + +**Figure 1** Usage of system resources +![](figure/usage-of-system-resources.png "usage-of-system-resources") + +**Table 1** Output description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Module

+

Indicates the module name.

+

Used

+

Indicates the quantity of currently used resources.

+

Total

+

Indicates the total quantity of available resources.

+

Enabled

+

Indicates whether the module is enabled.

+

Task

+

Indicates the task.

+

Sem

+

Indicates the semaphore.

+

Mutex

+

Indicates the mutex.

+

Queue

+

Indicates the queue.

+

SwTmr

+

Indicates the timer.

+
+ diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-task.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-task.md new file mode 100644 index 0000000000000000000000000000000000000000..bcef76f8b87049ab74a81be659756f7721caf3b0 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-task.md @@ -0,0 +1,125 @@ +# task + +- [Command Function](#section0533181714106) +- [Syntax](#section1014412308101) +- [Parameter Description](#section116057158506) +- [Usage](#section2053502951112) +- [Example](#section12629113381116) +- [Output](#section19299103465015) + +## Command Function + +This command is used to query information about processes and threads. + +## Syntax + +task/task -a + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-a

+

Displays all information.

+

N/A

+
+ +## Usage + +If the parameter is not specified, partial task information is printed by default. + +## Example + +Enter **task**. + +## Output + +**Figure 1** Querying partial task information +![](figure/querying-partial-task-information.png "querying-partial-task-information") + +**Table 2** Output description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

PID

+

Indicates the process ID.

+

PPID

+

Indicates the parent process ID.

+

PGID

+

Indicates the process group ID.

+

UID

+

Indicates the user ID.

+

Status

+

Indicates the current task status.

+

CPUUSE10s

+

Indicates the CPU usage within 10 seconds.

+

PName

+

Indicates the process name.

+

TID

+

Indicates the task ID.

+

StackSize

+

Indicates the size of the task stack.

+

WaterLine

+

Indicates the peak value used by the stack.

+

MEMUSE

+

Indicates the memory usage.

+

TaskName

+

Indicates the task name.

+
+ diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-uname.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-uname.md new file mode 100644 index 0000000000000000000000000000000000000000..7a9a79658247b8bbc3a97978aa945ed5182b4837 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-uname.md @@ -0,0 +1,72 @@ +# uname + +- [Command Function](#section107697383115) +- [Syntax](#section162824341116) +- [Usage](#section2652124861114) +- [Example](#section0107995132) +- [Output](#section1215113245511) + +## Command Function + +This command is used to display the name, version creation time, system name, and version information of the current OS. + +## Syntax + +uname \[_-a | -s | -t | -v | --help_\] + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

No parameter

+

Displays the OS name by default.

+

-a

+

Displays all information.

+

-t

+

Displays the time when the version is created.

+

-s

+

Displays the OS name.

+

-v

+

Displays the version information.

+

--help

+

Displays the help information.

+
+ +## Usage + +The **uname** command displays the name of the current OS by default. The **uname -a | -t| -s| -v** command displays the name of the in-use OS in the standard output. These parameters are mutually exclusive. + +## Example + +Enter **uname -a**. + +## Output + +Querying system information + +![](figure/en-us_image_0000001052370305.png) + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-vmm.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-vmm.md new file mode 100644 index 0000000000000000000000000000000000000000..920498ee8af7bb23537cd0225b4966645e35ab2f --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-vmm.md @@ -0,0 +1,158 @@ +# vmm + +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameter Description](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + +## Command Function + +This command is used to query the virtual memory usage of a process. + +## Syntax + +vmm \[_-a / -h / --help_\] + +vmm \[_pid_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-a

+

Displays the virtual memory usage of all processes.

+

N/A

+

-h | --help

+

Displays the help information.

+

N/A

+

pid

+

Indicates the ID of the process to query.

+

[0, 63]

+
+ +## Usage + +By default, the virtual memory usage of all processes is displayed. + +## Example + +Enter **vmm 3**. + +## Output + +**Figure 1** Virtual memory usage of the process with PID 3 +![](figure/virtual-memory-usage-of-the-process-with-pid-3.png "virtual-memory-usage-of-the-process-with-pid-3") + +**Table 2** Basic process information + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

PID

+

Indicates the process ID.

+

aspace

+

Indicates the address of the virtual memory control block.

+

name

+

Indicates the process name.

+

base

+

Indicates the start address of the virtual memory.

+

size

+

Indicates the size of virtual memory.

+

pages

+

Indicates the number of used physical pages.

+
+ +**Table 3** Virtual memory region information + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

region

+

Indicates the address of the control block in the virtual memory region.

+

name

+

Indicates the name of the virtual memory region.

+

base

+

Indicates the start address of the virtual memory region.

+

size

+

Indicates the size of the virtual memory region.

+

mmu_flags

+

Indicates the MMU mapping attribute of the virtual memory region.

+

pages

+

Indicates the number of used physical pages (including the shared memory).

+

pg/ref

+

Indicates the number of used physical pages.

+
+ diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-watch.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-watch.md new file mode 100644 index 0000000000000000000000000000000000000000..99eb40aabfed18d4a06fd2d9847fc2794b694607 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys-watch.md @@ -0,0 +1,98 @@ +# watch + +- [Command Function](#section20643141481314) +- [Syntax](#section1075441721316) +- [Parameter Description](#section1472810220135) +- [Usage](#section186772414131) +- [Example](#section4764192791314) +- [Output](#section5791253155517) + +## Command Function + +This command is used to periodically monitor the execution result of a command. + +## Syntax + +watch + +watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] + +## Parameter Description + +**Table 1** Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Default Value

+

Value Range

+

-c / --count

+

Indicates the number of times that the command is executed.

+

0xFFFFFF

+

(0, 0xFFFFFF]

+

-n / --interval

+

Indicates the interval for periodically running the command, in seconds.

+

1s

+

(0, 0xFFFFFF]

+

-t / -no-title

+

Disables time display on the top.

+

N/A

+

N/A

+

command

+

Indicates the command to be monitored.

+

N/A

+

N/A

+

--over

+

Stops the current command monitoring.

+

N/A

+

N/A

+
+ +## Usage + +You can run the **watch --over** command to stop the currently running command monitoring. + +## Example + +Enter **watch -n 2 -c 6 task**. + +## Output + +**Figure 1** **task** command monitoring result +![](figure/task-command-monitoring-result.png "task-command-monitoring-result") + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>In this example, the **task** command has been executed every 2 seconds for six times, and the preceding figure shows the output of the last execution. + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys.md new file mode 100644 index 0000000000000000000000000000000000000000..5549fe5c32bd6c2660afc196b0061d88cf8f8b70 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd-sys.md @@ -0,0 +1,47 @@ +# System Commands + +- **[cpup](kernel-lite-small-shell-cmd-sys-cpup.md)** + +- **[date](kernel-lite-small-shell-cmd-sys-date.md)** + +- **[dmesg](kernel-lite-small-shell-cmd-sys-demsg.md)** + +- **[exec](kernel-lite-small-shell-cmd-sys-exec.md)** + +- **[free](kernel-lite-small-shell-cmd-sys-free.md)** + +- **[help](kernel-lite-small-shell-cmd-sys-help.md)** + +- **[hwi](kernel-lite-small-shell-cmd-sys-hwi.md)** + +- **[kill](kernel-lite-small-shell-cmd-sys-kill.md)** + +- **[log](kernel-lite-small-shell-cmd-sys-log.md)** + +- **[memcheck](kernel-lite-small-shell-cmd-sys-mem.md)** + +- **[oom](kernel-lite-small-shell-cmd-sys-oom.md)** + +- **[pmm](kernel-lite-small-shell-cmd-sys-pmm.md)** + +- **[reset](kernel-lite-small-shell-cmd-sys-reset.md)** + +- **[sem](kernel-lite-small-shell-cmd-sys-sem.md)** + +- **[stack](kernel-lite-small-shell-cmd-sys-stack.md)** + +- **[su](kernel-lite-small-shell-cmd-sys-su.md)** + +- **[swtmr](kernel-lite-small-shell-cmd-sys-swymr.md)** + +- **[systeminfo](kernel-lite-small-shell-cmd-sys-sys.md)** + +- **[task](kernel-lite-small-shell-cmd-sys-task.md)** + +- **[uname](kernel-lite-small-shell-cmd-sys-uname.md)** + +- **[vmm](kernel-lite-small-shell-cmd-sys-vmm.md)** + +- **[watch](kernel-lite-small-shell-cmd-sys-watch.md)** + + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-cmd.md b/en/device-dev/kernel/kernel-lite-small-shell-cmd.md new file mode 100644 index 0000000000000000000000000000000000000000..ca4697ae096f4b8bd08daaa2de56f60b00c77a59 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-cmd.md @@ -0,0 +1,13 @@ +# Shell Command Reference + +This chapter describes the functions, syntax, parameter ranges, usages, and examples of key system commands. + +For details about the commands that are not described in this document, see the output of the [help](kernel-lite-small-shell-cmd-sys-help.md) command. You can also use the **-h | --help** option of a command to view the help information about the command. + +- **[System Commands](kernel-lite-small-shell-cmd-sys.md)** + +- **[File Commands](kernel-lite-small-shell-cmd-file.md)** + +- **[Network Commands](kernel-lite-small-shell-cmd-net.md)** + + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-des.md b/en/device-dev/kernel/kernel-lite-small-shell-des.md new file mode 100644 index 0000000000000000000000000000000000000000..2bbbee37a67679fd6818ef68463549b4841ac47e --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-des.md @@ -0,0 +1,36 @@ +# Introduction to the Shell + +- [Important Notes](#section12298165312328) + +The Shell provided by the OpenHarmony kernel supports commonly used commissioning commands, including those related to the system, files, networks, and dynamic loading. In addition, you can add custom commands to the shell of the OpenHarmony kernel to address your service needs. + +- System-related commands: querying information about system tasks, kernel semaphores, system software timers, CPU usage, and current interrupts + +- File-related commands: basic functions such as **ls** and **cd** + +- Network-related commands: querying the IP addresses of other devices connected to the development board, querying the IP address of the local device, testing the network connectivity, and setting the access point \(AP\) and station modes of the development board + + For details about the process of adding commands, see [Shell Command Development Guidelines](kernel-lite-small-shell-guide.md) and [Shell Command Programming Example](kernel-lite-small-shell-sample.md). + + +## Important Notes + +Note the following when using the shell: + +- You can use the **exec** command to run executable files. +- The shell supports English input in default mode. If you enter Chinese characters in the UTF-8 format, you can delete them only by pressing the backspace key for three times. + +- When entering shell commands, file names, and directory names, you can press **Tab** to enable automatic completion. If there are multiple completions, multiple items are printed based on the same characters they have. If more than 24 lines of completions are available, the system displays message "Display all num possibilities?\(y/n\)", asking you to determine whether to print all items. You can enter **y** to print all items or enter **n** to exit the printing. If more than 24 lines are printed after your selection, the system displays "--More--". In this case, you can press **Enter** to continue the printing or press **q** \(or **Ctrl+c**\) to exit. + +- The shell working directory is separated from the system working directory. You can run commands such as **cd** and **pwd** on the shell to perform operations on the shell working directory, and run commands such as **chdir** and **getcwd** to perform operations on the system working directory. Pay special attention when an input parameter in a file system operation command is a relative path. + +- Before using network shell commands, you need to call the **tcpip\_init** function to initialize the network and set up the Telnet connection. By default, the kernel does not call **tcpip\_init**. + +- You are not advised to run shell commands to perform operations on device files in the **/dev** directory, which may cause unexpected results. + +- The shell functions do not comply with the POSIX standards and are used only for commissioning. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >The shell functions are used for commissioning only and can be enabled only in the Debug version \(by enabling the **LOSCFG\_DEBUG\_VERSION** configuration item using **menuconfig**\). + + diff --git a/en/device-dev/kernel/kernel-lite-small-shell-guide.md b/en/device-dev/kernel/kernel-lite-small-shell-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..9c984d76ba256de8a9ff82b1f4670c168a0ac19a --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell-guide.md @@ -0,0 +1,167 @@ +# Shell Command Development Guidelines + +- [Development Guidelines](#section22071515161018) + +## Development Guidelines + +You can perform the following operations to add shell commands: + +1. Include the following header files: + + ``` + #include "shell.h" + #include "shcmd.h" + ``` + +2. Register commands. You can register commands either statically or dynamically when the system is running. In most cases, static registration is widely used by common system commands, and dynamic registration is widely used by user commands. + + 1. Static registration: + + 1. Register a command using a macro. + + The prototype of the macro is as follows: + + ``` + SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) + ``` + + **Table 1** Parameters of the SHELLCMD\_ENTRY macro + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

l

+

Indicates the global variable name to be passed during the static registration. Note that the name cannot be the same as other symbol names in the system.

+

cmdType

+

Indicates the command type.

+
  • CMD_TYPE_EX: does not support standard command parameters and will mask the command keywords you entered. For example, if you enter ls /ramfs, only /ramfs will be passed to the registration function, and the ls command keyword will be masked.

    +
  • CMD_TYPE_STD: supports standard command parameters. All the characters you entered will be passed to the registration function after being parsed.

    +
+

cmdKey

+

Indicates the command keyword, which is the name used to access a shell function.

+

paraNum

+

Indicates the maximum number of input parameters in the execution function to be invoked. This parameter is not supported currently.

+

cmdHook

+

Indicates the address of the execution function, that is, the function that is actually executed by the command.

+
+ + For example: + + ``` + SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) + ``` + + 2. Add the required options to the **build/mk/liteos\_tables\_ldflags.mk** file. + + For example, when registering the **ls** command, add **-uls\_shellcmd** to the **build/mk/liteos\_tables\_ldflags.mk** file. **-u** is followed by the first parameter of **SHELLCMD\_ENTRY**. + + + 2. Dynamic registration: + + The prototype of the function to register is as follows: + + ``` + UINT32 osCmdReg(CmdT ype cmdType, CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) + ``` + + **Table 2** Parameters of UINT32 osCmdReg + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

cmdType

+

Indicates the command type.

+
  • CMD_TYPE_EX: does not support standard command parameters and will mask the command keywords you entered. For example, if you enter ls /ramfs, only /ramfs will be passed to the registration function, and the ls command keyword will be masked.

    +
  • CMD_TYPE_STD: supports standard command parameters. All the characters you entered will be passed to the registration function after being parsed.

    +
+

cmdKey

+

Indicates the command keyword, which is the name used to access a shell function.

+

paraNum

+

Indicates the maximum number of input parameters in the execution function to be invoked. This parameter is not supported currently. The default value is XARGS(0xFFFFFFFF).

+

cmdHook

+

Indicates the address of the execution function, that is, the function that is actually executed by the command.

+
+ + For example: + + ``` + osCmdReg(CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) + ``` + + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >The command keyword must be unique. Specifically, two different commands cannot share the same command keyword. Otherwise, only one command is executed. + >When executing user commands sharing the same keyword, the shell executes only the first command in the **help** commands. + +3. Use the following function prototype to add built-in commands: + + ``` + UINT32 osShellCmdLs(UINT32 argc, CHAR **argv) + ``` + + **Table 3** Parameters of osShellCmdLs + + + + + + + + + + + + + +

Parameter

+

Description

+

argc

+

Indicates the number of parameters in the shell command.

+

argv

+

Indicates a pointer array, where each element points to a string. You can determine whether to pass the command keyword to the registration function by specifying the command type.

+
+ +4. Enter the shell command in either of the following methods: + - Enter the shell command in the serial port tool. + + - Enter the shell command in the Telnet tool. For details, see [telnet](kernel-lite-small-shell-cmd-net-tel.md). + + + diff --git a/en/device-dev/kernel/shell-command-programming-example.md b/en/device-dev/kernel/kernel-lite-small-shell-sample.md similarity index 100% rename from en/device-dev/kernel/shell-command-programming-example.md rename to en/device-dev/kernel/kernel-lite-small-shell-sample.md diff --git a/en/device-dev/kernel/kernel-lite-small-shell.md b/en/device-dev/kernel/kernel-lite-small-shell.md new file mode 100644 index 0000000000000000000000000000000000000000..e780951cf490b49819a1bdb13d33a3753a1f10cf --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-shell.md @@ -0,0 +1,15 @@ +# Commissioning + +- **[Introduction to the Shell](kernel-lite-small-shell-des.md)** + +- **[Shell Command Development Guidelines](kernel-lite-small-shell-guide.md)** + +- **[Shell Command Programming Example](kernel-lite-small-shell-sample.md)** + +- **[Shell Command Reference](kernel-lite-small-shell-cmd.md)** + +- **[Magic Key Usage](kernel-lite-small-shell-cmd-mag.md)** + +- **[User-Space Exception Information](kernel-lite-small-shell-cmd-abn.md)** + + diff --git a/en/device-dev/kernel/kernel-lite-small-thread.md b/en/device-dev/kernel/kernel-lite-small-thread.md new file mode 100644 index 0000000000000000000000000000000000000000..d1d04cc376ee7a85153d5bafadc003999109e932 --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small-thread.md @@ -0,0 +1,702 @@ +# Thread + +- [Basic Concepts](#section1179311337405) +- [When to Use](#section44877547404) +- [API Description](#section2069477134115) + +## Basic Concepts + +Threads are the minimum running units that compete for system resources. They can use or wait to use CPUs and use system resources such as memory. They run independently from one another. + +Threads in each process of the OpenHarmony kernel run and are scheduled independently. The scheduling of threads in a process is not affected by threads in other processes. + +Threads in the OpenHarmony kernel use the preemptive scheduling mechanism, either round-robin \(RR\) scheduling or First In First Out \(FIFO\) scheduling. + +Threads in the OpenHarmony kernel are assigned 32 priorities, ranging from **0** \(highest\) to **31** \(lowest\). + +A high-priority thread in a process can preempt the resources of a low-priority thread in this process. The low-priority thread can be scheduled only after the high-priority thread is blocked or terminated. + +**A thread may have the following states:** + +- **Init**: The thread is being created. + +- **Ready**: The thread is in the ready list and waits for being scheduled by the CPU. + +- **Running**: The thread is running. + +- **Blocked**: The thread is blocked and suspended. The **Blocked** states include **pending** \(blocked due to lock, event, or semaphore issues\), **suspended** \(active pending\), **delay** \(blocked due to delays\), and **pendtime** \(blocked by waiting timeout of locks, events, or semaphores\). + +- **Exit**: The thread stops running and waits for the parent thread to reclaim its control block resources. + + +**Figure 1** State transition of a thread +![](figure/state-transition-of-a-thread.png "state-transition-of-a-thread") + +**Description of the thread state transition:** + +- Init→Ready: + + When a thread is created, the thread enters the **Init** state to start initialization after obtaining the control block. After the thread is initialized, the thread is inserted into the scheduling queue and therefore enters the **Ready** state. + +- Ready→Running: + + When a thread switchover is triggered, the thread with the highest priority in the ready list is executed and enters the **Running** state. This thread will be deleted from the ready list. + +- Running→Blocked: + + When a running thread is blocked \(for example, is pended, delayed, or reading semaphores\), its state changes from **Running** to **Blocked**. Then, a thread switchover is triggered to run the thread with the highest priority in the ready list. + +- Blocked→Ready: + + After the blocked thread is restored \(the thread is restored, the delay times out, the semaphore reading times out, or the semaphore is read\), the thread is added to the ready list and changes from the **Blocked** state to the **Ready** state. + +- Ready→Blocked: + + A thread may also be blocked \(suspended\) in the **Ready** state. The blocked thread will change from the **Ready** state to the **Blocked** state and is deleted from the ready list. In this case, the thread will not be scheduled until it is restored. + +- Running→Ready: + + After a thread with a higher priority is created or restored, threads will be scheduled. The thread with the highest priority in the ready list will change to the **Running** state. The originally running thread will change from the **Running** state to the **Ready** state and be added to the ready list. + +- Running→Exit: + + When a running thread is terminated, its state changes from **Running** to **Exit**. The thread without the **PTHREAD\_CREATE\_DETACHED** attribute will present the **Exit** state after being terminated. + + +## When to Use + +After a thread is created, it can be scheduled, suspended, restored, and delayed in user space. In addition, you can set and obtain the scheduling priority and scheduling policy of the thread. + +## API Description + +The following table describes the APIs provided by the thread management module of the OpenHarmony kernel. + +**Table 1** APIs provided by the thread management module + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Header File

+

Function

+

Description

+

Remarks

+

pthread.h

+

pthread_attr_destroy

+

Destroys a thread attribute object.

+

N/A

+

pthread.h

+

pthread_attr_getinheritsched

+

Obtains inherit scheduler attributes of a thread attribute object.

+

N/A

+

pthread.h

+

pthread_attr_getschedparam

+

Obtains scheduling parameter attributes of a thread attribute object.

+

N/A

+

pthread.h

+

pthread_attr_getschedpolicy

+

Obtains scheduling policy attributes of a thread attribute object.

+

OpenHarmony supports the SCHED_FIFO and SCHED_RR scheduling policies.

+

pthread.h

+

pthread_attr_getstacksize

+

Obtains the stack size of a thread attribute object.

+

N/A

+

pthread.h

+

pthread_attr_init

+

Initializes a thread attribute object.

+

N/A

+

pthread.h

+

pthread_attr_setdetachstate

+

Sets the detach state for a thread attribute object.

+

N/A

+

pthread.h

+

pthread_attr_setinheritsched

+

Sets inherit scheduler attributes for a thread attribute object.

+

N/A

+

pthread.h

+

pthread_attr_setschedparam

+

Sets scheduling parameter attributes for a thread attribute object.

+

A larger value represents a higher priority of the thread in the system.

+

Note: The inheritsched field of the pthread_attr_t attribute must be set to PTHREAD_EXPLICIT_SCHED. Otherwise, the configured thread scheduling priority does not take effect. The default value is PTHREAD_INHERIT_SCHED.

+

pthread.h

+

pthread_attr_setschedpolicy

+

Sets scheduling policy attributes for a thread attribute object.

+

OpenHarmony supports the SCHED_FIFO and SCHED_RR scheduling policies.

+

pthread.h

+

pthread_attr_setstacksize

+

Sets the stack size for a thread attribute object.

+

N/A

+

pthread.h

+

pthread_getattr_np

+

Obtains the attributes of a created thread.

+

N/A

+

pthread.h

+

pthread_cancel

+

Sends a cancellation request to a thread.

+

N/A

+

pthread.h

+

pthread_testcancel

+

Requests delivery of any pending cancellation request.

+

N/A

+

pthread.h

+

pthread_setcanceltype

+

Sets the cancelability type for the calling thread.

+

N/A

+

pthread.h

+

pthread_setcancelstate

+

Sets the cancelability state for the calling thread.

+

N/A

+

pthread.h

+

pthread_create

+

Creates a thread.

+

N/A

+

pthread.h

+

pthread_detach

+

Detaches a thread.

+

N/A

+

pthread.h

+

pthread_equal

+

Compares whether two thread IDs are equal.

+

N/A

+

pthread.h

+

pthread_exit

+

Terminates the calling thread.

+

N/A

+

pthread.h

+

pthread_getschedparam

+

Obtains the scheduling policy and parameters of a thread.

+

OpenHarmony supports the SCHED_FIFO and SCHED_RR scheduling policies.

+

pthread.h

+

pthread_join

+

Waits for a thread to terminate.

+

N/A

+

pthread.h

+

pthread_self

+

Obtains the ID of the calling thread.

+

N/A

+

pthread.h

+

pthread_setschedprio

+

Sets a static scheduling priority for a thread.

+

N/A

+

pthread.h

+

pthread_kill

+

Sends a signal to a thread.

+

N/A

+

pthread.h

+

pthread_once

+

Enables the initialization function to be called only once.

+

N/A

+

pthread.h

+

pthread_atfork

+

Registers a fork handler to be called before and after fork().

+

N/A

+

pthread.h

+

pthread_cleanup_pop

+

Removes the routine at the top of the clean-up handler stack.

+

N/A

+

pthread.h

+

pthread_cleanup_push

+

Pushes the routine to the top of the clean-up handler stack.

+

N/A

+

pthread.h

+

pthread_barrier_destroy

+

Destroys a barrier (an advanced real-time thread).

+

N/A

+

pthread.h

+

pthread_barrier_init

+

Initializes a barrier (an advanced real-time thread).

+

N/A

+

pthread.h

+

pthread_barrier_wait

+

Synchronizes participating threads at a barrier.

+

N/A

+

pthread.h

+

pthread_barrierattr_destroy

+

Destroys a barrier attribute object.

+

N/A

+

pthread.h

+

pthread_barrierattr_init

+

Initializes a barrier attribute object.

+

N/A

+

pthread.h

+

pthread_mutex_destroy

+

Destroys a mutex.

+

N/A

+

pthread.h

+

pthread_mutex_init

+

Initializes a mutex.

+

N/A

+

pthread.h

+

pthread_mutex_lock

+

Locks a mutex.

+

N/A

+

pthread.h

+

pthread_mutex_trylock

+

Attempts to lock a mutex.

+

N/A

+

pthread.h

+

pthread_mutex_unlock

+

Unlocks a mutex.

+

N/A

+

pthread.h

+

pthread_mutexattr_destroy

+

Destroys a mutex attribute object.

+

N/A

+

pthread.h

+

pthread_mutexattr_gettype

+

Obtains the mutex type attribute.

+

N/A

+

pthread.h

+

pthread_mutexattr_init

+

Initializes a mutex attribute object.

+

N/A

+

pthread.h

+

pthread_mutexattr_settype

+

Sets the mutex type attribute.

+

N/A

+

pthread.h

+

pthread_mutex_timedlock

+

Blocks the calling thread to lock a mutex.

+

N/A

+

pthread.h

+

pthread_rwlock_destroy

+

Destroys a read-write lock.

+

N/A

+

pthread.h

+

pthread_rwlock_init

+

Initializes a read-write lock.

+

N/A

+

pthread.h

+

pthread_rwlock_rdlock

+

Applies a read lock to a read-write lock.

+

N/A

+

pthread.h

+

pthread_rwlock_timedrdlock

+

Blocks the calling thread to lock a read-write lock for reading.

+

N/A

+

pthread.h

+

pthread_rwlock_timedwrlock

+

Blocks the calling thread to lock a read-write lock for writing.

+

N/A

+

pthread.h

+

pthread_rwlock_tryrdlock

+

Attempts to apply a read lock to a read-write lock.

+

N/A

+

pthread.h

+

pthread_rwlock_trywrlock

+

Attempts to apply a write lock to a read-write lock.

+

N/A

+

pthread.h

+

pthread_rwlock_unlock

+

Unlocks a read-write lock.

+

N/A

+

pthread.h

+

pthread_rwlock_wrlock

+

Applies a write lock to a read-write lock.

+

N/A

+

pthread.h

+

pthread_rwlockattr_destroy

+

Destroys a read-write lock attribute object.

+

N/A

+

pthread.h

+

pthread_rwlockattr_init

+

Initializes a read-write lock attribute object.

+

N/A

+

pthread.h

+

pthread_cond_broadcast

+

Unblocks all threads that are currently blocked on the condition variable cond.

+

N/A

+

pthread.h

+

pthread_cond_destroy

+

Destroys a condition variable.

+

N/A

+

pthread.h

+

pthread_cond_init

+

Initializes a condition variable.

+

N/A

+

pthread.h

+

pthread_cond_signal

+

Unblocks a thread.

+

N/A

+

pthread.h

+

pthread_cond_timedwait

+

Blocks the calling thread to wait for the condition set by pthread_con_signal() for a period of time specified by ts.

+

N/A

+

pthread.h

+

pthread_cond_wait

+

Blocks the calling thread to wait for the condition set by pthread_con_signal().

+

N/A

+

semaphore.h

+

sem_destroy

+

Destroys a specified anonymous semaphore that is no longer used.

+

N/A

+

semaphore.h

+

sem_getvalue

+

Obtains the count value of a specified semaphore.

+

N/A

+

semaphore.h

+

sem_init

+

Creates and initializes an anonymous semaphore.

+

N/A

+

semaphore.h

+

sem_post

+

Increments the semaphore count by 1.

+

N/A

+

semaphore.h

+

sem_timedwait

+

Obtains the semaphore, with a timeout period specified.

+

N/A

+

semaphore.h

+

sem_trywait

+

Attempts to obtain the semaphore.

+

N/A

+

semaphore.h

+

sem_wait

+

Obtains the semaphore.

+

N/A

+
+ diff --git a/en/device-dev/kernel/kernel-lite-small.md b/en/device-dev/kernel/kernel-lite-small.md new file mode 100644 index 0000000000000000000000000000000000000000..7964a667d365b26721febc5fcb5e8cd169f1b73c --- /dev/null +++ b/en/device-dev/kernel/kernel-lite-small.md @@ -0,0 +1,11 @@ +# Kernel for Small Systems + +- **[Basic Kernel](kernel-lite-small-basic.md)** + +- **[File System](kernel-lite-small-file.md)** + +- **[Standard Library](kernel-lite-small-lib.md)** + +- **[Commissioning](kernel-lite-small-shell.md)** + + diff --git a/en/device-dev/kernel/kernel-lite.md b/en/device-dev/kernel/kernel-lite.md new file mode 100644 index 0000000000000000000000000000000000000000..523555a5f4ec2692c5493bcbe08624a9f545812f --- /dev/null +++ b/en/device-dev/kernel/kernel-lite.md @@ -0,0 +1,5 @@ +# Kernel for Mini and Small Systems + +- **[Kernel for Small Systems](kernel-lite-small.md)** + + diff --git a/en/device-dev/kernel/kernel-standard-build.md b/en/device-dev/kernel/kernel-standard-build.md new file mode 100644 index 0000000000000000000000000000000000000000..5dd23ea67832db1fa75e6ec1ac6a70fdafd137fc --- /dev/null +++ b/en/device-dev/kernel/kernel-standard-build.md @@ -0,0 +1,47 @@ +# Guidelines for Compiling and Building the Linux Kernel + +- [Example 1](#section19369206113115) + - [Scenario 1: Building the Native Kernel at the Version Level](#section1025111193220) + - [Scenario 2: Building the Modified Kernel Separately](#section17446652173211) + + +## Example 1 + +The following uses the Hi3516D V300 board and Ubuntu x86 server as an example. + +### Scenario 1: Building the Native Kernel at the Version Level + +Perform a full build for the project to generate the **uImage** kernel image. + +``` +./build.sh --product-name Hi3516DV300 # Build the uImage kernel image of the Hi3516D V300 board. +``` + +### Scenario 2: Building the Modified Kernel Separately + +1. Set up the build environment. + + 1. Merge the required patch by referring to [guidelines for using patches on development boards](kernel-standard-patch.md). + 2. Prepare for the build environment. You can use the Arm Clang or GCC compiler. + + Enter the root directory of the project and configure environment variables: + + ``` + export PATH=`pwd`/prebuilts/clang/host/linux-x86/clang-r353983c/bin:`pwd`/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/:$PATH # Configure the build environment. + MAKE_OPTIONES="ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CC=clang HOSTCC=clang" # Use Clang provided by the project. + ``` + +2. Modify the kernel code or kernel configuration \(**defconfig** file provided by OpenHarmony can be used for reference\). +3. Create a build directory and generate the **.config** file of the kernel. + + ``` + make ${MAKE_OPTIONES} hi3516dv300_emmc_smp_hos_l2_defconfig # Use the defconfig file to build the kernel. + ``` + +4. Build the kernel image. + + ``` + make ${MAKE_OPTIONES} -j32 uImage # Build the uImage kernel image. + ``` + + diff --git a/en/device-dev/kernel/linux-kernel-overview.md b/en/device-dev/kernel/kernel-standard-des.md similarity index 100% rename from en/device-dev/kernel/linux-kernel-overview.md rename to en/device-dev/kernel/kernel-standard-des.md diff --git a/en/device-dev/kernel/kernel-standard-patch.md b/en/device-dev/kernel/kernel-standard-patch.md new file mode 100644 index 0000000000000000000000000000000000000000..e1ecf1aad2a3ea5e004a9d55699738b2f7fade1e --- /dev/null +++ b/en/device-dev/kernel/kernel-standard-patch.md @@ -0,0 +1,17 @@ +# Guidelines for Using Patches on OpenHarmony Development Boards + +The patch files are stored in the **kernel/linux/patches/linux-4.19** source code path of the project. You can obtain the driver patch of a specific chip architecture from this directory. + +To use the patch of a specific chip platform driver, you need to merge the required kernel patch into the kernel code. + +Merge the corresponding patches for different chip platforms. + +The following uses Hi3516D V300 as an example: + +``` +patch -p1 < device/hisilicon/hi3516dv300/sdk_linux/open_source/linux/hisi_linux-4.19_hos_l2.patch +``` + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>Because patches are applied after the code environment of **kernel/linux-4.19** is copied during compilation and building of the OpenHarmony project, you must retain the original code environment of **kernel/linux-4.19** before running the OpenHarmony version-level build command. + diff --git a/en/device-dev/kernel/kernel-standard.md b/en/device-dev/kernel/kernel-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..cdbdf659c166ba32ea9b47e15b06e57184149032 --- /dev/null +++ b/en/device-dev/kernel/kernel-standard.md @@ -0,0 +1,9 @@ +# Kernel for Standard Systems + +- **[Linux Kernel Overview](kernel-standard-des.md)** + +- **[Guidelines for Using Patches on OpenHarmony Development Boards](kernel-standard-patch.md)** + +- **[Guidelines for Compiling and Building the Linux Kernel](kernel-standard-build.md)** + + diff --git a/en/device-dev/kernel/kernel.md b/en/device-dev/kernel/kernel.md new file mode 100644 index 0000000000000000000000000000000000000000..356b5d646277ab0bd61df5175f9292b5a4982831 --- /dev/null +++ b/en/device-dev/kernel/kernel.md @@ -0,0 +1,7 @@ +# Kernel + +- **[Kernel for Mini and Small Systems](kernel-lite.md)** + +- **[Kernel for Standard Systems](kernel-standard.md)** + + diff --git a/en/device-dev/kernel/kill.md b/en/device-dev/kernel/kill.md deleted file mode 100644 index 72a2a65937e17fba4e5dd277d6284126ffa04ee7..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/kill.md +++ /dev/null @@ -1,82 +0,0 @@ -# kill - -- [Command Function](#section366714216619) -- [Syntax](#section8833164614615) -- [Parameter Description](#section12809111019453) -- [Usage](#section15935131220717) -- [Example](#section79281818476) -- [Output](#section12742311179) - -## Command Function - -This command is used to send a specific signal to a specified process. - -## Syntax - -kill \[_signo_ | _-signo_\] \[_pid_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

signo

-

Indicates the signal ID.

-

[1, 30]

-

pid

-

Indicates the process ID.

-

[1, MAX_INT]

-
- ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->The valid range of the **signo** value is \[0, 64\], and the recommended value range is \[1, 30\]. Other values in the valid range are reserved. - -## Usage - -The **signo** and **pid** parameters are mandatory. - -The **pid** value range varies depending on the system configuration. For example, if the maximum **pid** value supported by the system is **256**, this value range is \[1-256\]. - -## Example - -1. Query the current process list and determine the PID \(7\) of the process to be killed. - -**Figure 1** Querying PIDs -![](figures/querying-pids.png "querying-pids") - -2. Run **kill 14 7** to send signal 14 \(the default behavior of **SIGALRM** is to terminate the process\) to process 7 **helloworld\_d** \(user-space\). Then query the current process list. Process 7 has been terminated. The result of the **kill 14 7** command is the same as that of the **kill -14 7** command. - -**Figure 2** Command output -![](figures/command-output.png "command-output") - -## Output - -The command output is as follows: - -**Figure 3** Sending a signal to a specified process -![](figures/sending-a-signal-to-a-specified-process.png "sending-a-signal-to-a-specified-process") - -The signal is successfully sent if no error is reported. - -**Figure 4** Signal sending failure -![](figures/signal-sending-failure.png "signal-sending-failure") - -The preceding figure shows a signal sending failure caused by invalid parameters. In this case, check that the signal ID and PID are valid. - diff --git a/en/device-dev/kernel/linux-kernel.md b/en/device-dev/kernel/linux-kernel.md deleted file mode 100644 index 9391b466f5f056bda10b6cff24a0142cce6fef51..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/linux-kernel.md +++ /dev/null @@ -1,9 +0,0 @@ -# Linux Kernel - -- **[Linux Kernel Overview](linux-kernel-overview.md)** - -- **[Guidelines for Using Patches on OpenHarmony Development Boards](guidelines-for-using-patches-on-openharmony-development-boards.md)** - -- **[Guidelines for Compiling and Building the Linux Kernel](guidelines-for-compiling-and-building-the-linux-kernel.md)** - - diff --git a/en/device-dev/kernel/lite-kernel.md b/en/device-dev/kernel/lite-kernel.md deleted file mode 100644 index 3927b0fb506a8a301ca2b168f58e99170365406a..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/lite-kernel.md +++ /dev/null @@ -1,11 +0,0 @@ -# Lite Kernel - -- **[OpenHarmony Lite Kernel Basic Functions](openharmony-lite-kernel-basic-functions.md)** - -- **[OpenHarmony Lite Kernel File System](openharmony-lite-kernel-file-system.md)** - -- **[Standard Library](standard-library.md)** - -- **[Commissioning](commissioning.md)** - - diff --git a/en/device-dev/kernel/log.md b/en/device-dev/kernel/log.md deleted file mode 100644 index 7702a920dc8d7520de4f78100dcb4b5f39474b90..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/log.md +++ /dev/null @@ -1,72 +0,0 @@ -# log - -- [Command Function](#section128219131856) -- [Syntax](#section3894181710519) -- [Parameter Description](#section7693122310515) -- [Usage](#section1982111281512) -- [Example](#section176301333259) -- [Output](#section14354765415) - -## Command Function - -This command is used to modify and query log configurations. - -## Syntax - -log level \[_levelNum_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

levelNum

-

Indicates the print level of configuration logs.

-

[0x0, 0x5]

-
- -## Usage - -- This command depends on **LOSCFG\_SHELL\_LK**. Before running this command, enable the **Enable Shell lk** configuration item using **menuconfig**. - - Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell lK - -- The **log level** command is used to configure log levels, which can be: - - TRACE\_EMG = 0, - - TRACE\_COMMON = 1, - - TRACE\_ERROR = 2, - - TRACE\_WARN = 3, - - TRACE\_INFO = 4, - - TRACE\_DEBUG = 5 - - If the level is not within the valid range, a message is printed. - -- If the **\[levelNum\]** parameter is not specified, the current log level and its usage are printed by default. - -## Example - -Enter **log level 4**. - -## Output - -![](figures/en-us_image_0000001052530298.png) - diff --git a/en/device-dev/kernel/ls.md b/en/device-dev/kernel/ls.md deleted file mode 100644 index 24912f8546337540b7037276d62b1c531156f33c..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/ls.md +++ /dev/null @@ -1,58 +0,0 @@ -# ls - -- [Command Function](#section6538163771614) -- [Syntax](#section45881743111616) -- [Parameter Description](#section17528148171617) -- [Usage](#section041212533166) -- [Example](#section986105716167) -- [Output](#section2036124918592) - -## Command Function - -This command is used to display the content of a specified directory. - -## Syntax - -ls \[_path_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

path

-

If path is left blank, the content of the current directory is displayed.

-

If the path value is an invalid file name, the following failure message is displayed:

-

ls error: No such directory

-

If the path value is a valid directory, the content of this directory is displayed.

-
  • Left blank
  • A valid directory
-
- -## Usage - -- This command can be used to display the content of the current directory. -- This command can also display the size of a file. -- The **ls** command with the **proc** directory passed cannot calculate the file size and **0** is displayed in the command output. - -## Example - -Enter **ls**. - -## Output - -**Figure 1** Viewing content of the current directory -![](figures/viewing-content-of-the-current-directory.png "viewing-content-of-the-current-directory") - diff --git a/en/device-dev/kernel/lsfd.md b/en/device-dev/kernel/lsfd.md deleted file mode 100644 index 950cfda3a3dad5c6aae7292e1b23298a89d24ec0..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/lsfd.md +++ /dev/null @@ -1,29 +0,0 @@ -# lsfd - -- [Command Function](#section2053406181716) -- [Syntax](#section523771017172) -- [Usage](#section27241213201719) -- [Example](#section442617197173) -- [Output](#section42491639151813) - -## Command Function - -This command is used to display the file descriptors and names of currently opened files. - -## Syntax - -lsfd - -## Usage - -Run the **lsfd** command to view file descriptors and names of the opened files. - -## Example - -Enter **lsfd**. - -## Output - -**Figure 1** Command output -![](figures/command-output-0.png "command-output-0") - diff --git a/en/device-dev/kernel/magic-key-usage.md b/en/device-dev/kernel/magic-key-usage.md deleted file mode 100644 index 4beecc99310464737b92ebca1cf1d75d2ba898a4..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/magic-key-usage.md +++ /dev/null @@ -1,40 +0,0 @@ -# Magic Key Usage - -- [When to Use](#section2350114718546) -- [How to Use](#section3305151511559) - -## When to Use - -When the system does not respond, you can use the magic key function to check whether the system is locked and interrupted \(the magic key also does not respond\) or view the system task running status. - -If the interrupt is responded, you can use the magic key to check the CPU usage \(**cpup**\) in the task information to find out the task that occupies the CPU for a long period of time and causes other tasks in the system not to respond. \(Generally, the high-priority tasks always preempt the CPU and cause the low-priority tasks not to respond.\) - -## How to Use - -1. Configure macro **LOSCFG\_ENABLE\_MAGICKEY**. - -The magic key depends on the **LOSCFG\_ENABLE\_MAGICKEY** macro. To use the magic key, enable the **Enable MAGIC KEY** configuration item using **menuconfig**. - -Debug ---\> Enable MAGIC KEY - -If this configuration item is disabled, the magic key is invalid. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->1. In **menuconfig**, you can move the cursor to **LOSCFG\_ENABLE\_MAGICKEY** and enter a question mark \(?\) to view the help information. - -2. Press **Ctrl+R** to enable the magic key detection function. - -When the UART or USB-to-virtual serial port is connected, press **Ctrl+R** to enable the magic key detection function. The message "Magic key on" is displayed. After you press **Ctrl+R** again, the magic key detection function is disabled, and message "Magic key off" is displayed. The functions of the magic key are as follows: - -- **Ctrl+Z**: help key, which is used to display the brief introduction to related magic keys. - -- **Ctrl+T**: displays task information. - -- **Ctrl+P**: The system proactively enters the panic state. After the panic-related information is printed, the system is suspended. - -- **Ctrl+E**: The system checks the integrity of the memory pool. If an error is detected, the system displays an error message. If no error is detected, the system displays "system memcheck over, all passed!". - - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->When the magic key detection function is enabled and special characters need to be entered through the UART or USB-to-virtual serial port, ensure that the special characters are not the same as the magic key values. Otherwise, the magic key may be triggered by mistake, which may cause errors in the original design. - diff --git a/en/device-dev/kernel/memcheck.md b/en/device-dev/kernel/memcheck.md deleted file mode 100644 index 20e8bbccbf638aef8861aeabe4017c133aab7b1a..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/memcheck.md +++ /dev/null @@ -1,38 +0,0 @@ -# memcheck - -- [Command Function](#section191633812516) -- [Syntax](#section428816435510) -- [Parameter Description](#section1939943304411) -- [Usage](#section228914491951) -- [Example](#section17373205314515) -- [Output](#section13406205385413) - -## Command Function - -This command is used to check whether the dynamically requested memory block is complete and whether nodes in the memory pool are damaged due to out-of-bounds memory access. - -## Syntax - -memcheck - -## Parameter Description - -None - -## Usage - -- If all nodes in the memory pool are complete, "system memcheck over, all passed!" is displayed. -- If a node in the memory pool is incomplete, information about the memory block of the damaged node is displayed. - -## Example - -Enter **memcheck**. - -## Output - -**Figure 1** No out-of-bounds memory access -![](figures/no-out-of-bounds-memory-access.png "no-out-of-bounds-memory-access") - -**Figure 2** Out-of-bounds memory access -![](figures/out-of-bounds-memory-access.png "out-of-bounds-memory-access") - diff --git a/en/device-dev/kernel/memory.md b/en/device-dev/kernel/memory.md deleted file mode 100644 index f189a61be22662a5151caf30b45f8c8508487188..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/memory.md +++ /dev/null @@ -1,353 +0,0 @@ -# Memory - -- [Basic Concepts](#section1392116583424) -- [When to Use](#section159581619194319) -- [Available APIs](#section114001032104317) - -## Basic Concepts - -Memory management is an important procedure in software development, including memory allocation, usage, and reclamation. - -Sound memory management approaches and strategies help you improve software performance and reliability. - -## When to Use - -For user-space development, the OpenHarmony kernel provides a set of APIs for you to perform memory-related operations, such as memory application, release, remapping, and attribute setting, in addition to standard APIs provided by the C library. - -## Available APIs - -**Table 1** Standard APIs in the C library - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Header File

-

Function

-

Description

-

strings.h

-

int bcmp(const void *s1, const void *s2, size_t n)

-

Compares byte sequences.

-

strings.h

-

void bcopy(const void *src, void *dest, size_t n)

-

Copies byte sequences.

-

strings.h

-

void bzero(void *s, size_t n)

-

Sets byte sequences to zero.

-

string.h

-

void *memccpy(void *dest, const void *src, int c, size_t n)

-

Copies the first n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest. The copy checks whether a character specified by c is found. If c is found, this function returns the next character of character c in the destination memory area.

-

string.h

-

void *memchr(const void *s, int c, size_t n)

-

Searches for the first occurrence of the character specified by c in the n-byte memory area pointed to by s.

-

string.h

-

int memcmp(const void *s1, const void *s2, size_t n)

-

Compares two memory areas.

-

string.h

-

void *memcpy(void *dest, const void *src, size_t n)

-

Copies n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest.

-

string.h

-

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)

-

Searches for a needle string in its haystack string.

-

string.h

-

void *memmove(void *dest, const void *src, size_t n)

-

Copies n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest.

-

string.h

-

void *mempcpy(void *dest, const void *src, size_t n)

-

Copies n bytes from the source memory area pointed to by src to the destination memory area pointed to by dest.

-

string.h

-

void *memset(void *s, int c, size_t n)

-

Copies a character to the specified memory area.

-

stdlib.h

-

void *malloc(size_t size)

-

Dynamically allocates a memory block of size.

-

stdlib.h

-

void *calloc(size_t nmemb, size_t size)

-

Dynamically allocates nmemb memory blocks of size.

-

stdlib.h

-

void *realloc(void *ptr, size_t size)

-

Changes the size of the memory block pointed to by ptr to size bytes.

-

stdlib.h/malloc.h

-

void *valloc(size_t size)

-

Allocates a block of memory with the specified size and aligns the allocated memory by page size.

-

stdlib.h

-

void free(void *ptr)

-

Releases the memory space pointed to by ptr.

-

malloc.h

-

size_t malloc_usable_size(void *ptr)

-

Obtains the size of the memory block pointed to by ptr.

-

unistd.h

-

int getpagesize(void)

-

Obtains the page size.

-

unistd.h

-

void *sbrk(intptr_t increment)

-

Changes the data segment size.

-
- -Details on API differences: - -- **mmap** - - **Function prototype:** - - void \*mmap\(void \*addr, size\_t length, int prot, int flags, int fd, off\_t offset\); - - **Function description:** applies for virtual memory. - - **Parameter description:** - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

addr

-

Indicates the pointer to the start address of the mapping between the virtual address space of the calling process and a file or device. If this parameter is NULL, the kernel determines the address to start (recommended). Otherwise, the portability of the program will deteriorate, because the available addresses vary depending on the OS.

-

length

-

Indicates the length of the mapping.

-

prot

-

Indicates the permission to be granted on the mapping area. The options are as follows:

-
  • PROT_READ: The mapping area is readable.
  • PROT_WRITE: The mapping area is writable.
  • PROT_EXEC: The mapping area is executable.
  • PROT_NONE: The mapping area cannot be accessed.
-

flags

-

Specifies whether updates are visible to other processes mapping the same segment. The options are as follows:

-
  • MAP_PRIVATE: The mapping area is private, and updates to the mapping are invisible to other processes mapping the same segment.
  • MAP_SHARED: Updates to the mapping are visible to other processes mapping the same segment, and are stored to the disk file.
-

fd

-

Indicates the file descriptor.

-

offset

-

Indicates the offset into the file where the mapping will start.

-
- - >![](public_sys-resources/icon-note.gif) **NOTE:** - >For details about the implementation differences between **mmap** and Linux function, see [Differences from the Linux Standard Library](differences-from-the-linux-standard-library.md). - - **Return values:** - - - Returns the pointer to the page-aligned address where the mapping is placed if the operation is successful. - - Returns **\(void \*\)-1** if the operation fails. - - -- **munmap** - - **Function prototype:** - - int munmap\(void \*addr, size\_t length\); - - **Function description:** releases virtual memory. - - **Parameter description:** - - - - - - - - - - - - - -

Parameter

-

Description

-

addr

-

Indicates the pointer to the start address of the memory region to unmap.

-

length

-

Indicates the length of the address range to unmap.

-
- - **Return values:** - - - Returns **0** if the operation is successful. - - Returns **-1** if the operation fails. - - -- **mprotect** - - **Function prototype:** - - int mprotect\(void \*addr, size\_t length, int prot\); - - **Function description:** modifies the access permission on a memory region. - - **Parameter description:** - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

addr

-

Indicates the pointer to the start address of the memory region to modify, which must be a multiple of the page size. If the access permission is abnormal, the kernel throws an exception and kills the process rather than send SIGSEGV signals to the current process.

-

length

-

Indicates the length of the memory region to modify.

-

prot

-

Indicates the permission of the memory region to modify. The options are as follows:

-
  • PROT_READ: The memory region is readable.
  • PROT_WRITE: The memory region is writable.
  • PROT_EXEC: The memory region is executable.
  • PROT_NONE: The memory region cannot be accessed.
-
- - **Return values:** - - - Returns **0** if the operation is successful. - - Returns **-1** if the operation fails. - - -- **mremap** - - **Function prototype:** - - void \*mremap\(void \*old\_address, size\_t old\_size, size\_t new\_size, int flags, void new\_address\); - - **Function description:** remaps the virtual memory address. - - **Parameter description:** - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

old_address

-

Indicates the old address of the virtual memory block that needs to be expanded or shrunk. The old_address must be page-aligned.

-

old_size

-

Indicates the old size of the virtual memory block.

-

new_size

-

Indicates the new size of the virtual memory block.

-

flags

-

Indicates the flags to control the remapping. If there is no sufficient space to expand the mapping in the current location, the operation will fail.

-
  • MREMAP_MAYMOVE: allows the kernel to relocate the mapping to a new virtual address.
  • MREMAP_FIXED: enables the mremap() function to accept the fifth parameter void *new_address, which specifies that the mapping address must be page-aligned. All previous mappings within the address range specified by new_address and new_size are unmapped. If MREMAP_FIXED is specified, MREMAP_MAYMOVE must also be specified.
-
- - **Return values:** - - - Returns the pointer to the new virtual memory area if the operation is successful. - - Returns **\(void \*\)-1** if the operation fails. - - diff --git a/en/device-dev/kernel/mkdir.md b/en/device-dev/kernel/mkdir.md deleted file mode 100644 index 37e762b7f7c5f8d5bbe3e8ccaecaf863175adc73..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/mkdir.md +++ /dev/null @@ -1,54 +0,0 @@ -# mkdir - -- [Command Function](#section1083613274175) -- [Syntax](#section820913118178) -- [Parameter Description](#section1256834121718) -- [Usage](#section1294234115172) -- [Example](#section1113345211713) -- [Output](#section10142201012) - -## Command Function - -This command is used to create a directory. - -## Syntax - -mkdir \[_directory_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

directory

-

Indicates the directory to be created.

-

N/A

-
- -## Usage - -- If the **mkdir** command is followed by the name of the directory to be created, the directory is created in the current directory. -- If the **mkdir** command is followed by a path and the name of the directory to be created, the directory is created in the specified path. - -## Example - -Enter **mkdir share**. - -## Output - -**Figure 1** Creating the share directory -![](figures/creating-the-share-directory.png "creating-the-share-directory") - diff --git a/en/device-dev/kernel/mount.md b/en/device-dev/kernel/mount.md deleted file mode 100644 index 4ba01ec183a67d020cb1fd33e295f1dd104f4d20..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/mount.md +++ /dev/null @@ -1,78 +0,0 @@ -# mount - -- [Command Function](#section11631837182) -- [Syntax](#section1697638111820) -- [Parameter Description](#section1650151221819) -- [Usage](#section124541520171912) -- [Example](#section7424625171917) -- [Output](#section14757018116) - -## Command Function - -This command is used to mount a device to a specified directory. - -## Syntax - -mount <_device_\> <_path_\> <_name_\> \[_uid gid_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

device

-

Indicates the path of the device to be mounted. The format is the path of the device.

-

A device in the system

-

path

-

Indicates the directory of the device.

-

The user must have the execution (search) permission for the specified directory.

-

N/A

-

name

-

Indicates the file system type.

-

vfat, yaffs, jffs, ramfs, nfs, procfs, romfs

-

uid gid

-

uid indicates the user ID.

-

gid indicates the group ID.

-

This parameter is optional. The default values are uid:0 and gid:0.

-

N/A

-
- -## Usage - -By specifying the device to be mounted, directory, and file system format in the **mount** command, you can successfully mount the file system to the specified directory. - -## Example - -Enter **mount /dev/mmcblk0p0 /bin1/vs/sd vfat**. - -## Output - -Mounting **/dev/mmcblk0p0** to the **/bin1/vs/sd** directory - -![](figures/en-us_image_0000001051690323.png) - diff --git a/en/device-dev/kernel/netstat.md b/en/device-dev/kernel/netstat.md deleted file mode 100644 index fe85534166fe35e43d60fb59c6e160340485df9f..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/netstat.md +++ /dev/null @@ -1,83 +0,0 @@ -# netstat - -- [Command Function](#section13469162113816) -- [Syntax](#section795712373812) -- [Parameter Description](#section17629431193817) -- [Usage](#section5277153519380) -- [Example](#section108141437163820) -- [Output](#section1357015107117) - -## Command Function - -The **netstat** command is a console command and is used for monitoring the TCP/IP network. It can display the actual network connections and the status of each network interface device. It is used to display the statistics related to the TCP and UDP protocols and check the network connection to each port on the device \(board\). - -## Syntax - -netstat - -## Parameter Description - -None - -## Usage - -Run the command directly. - -## Example - -Enter **netstat**. - -**Figure 1** Output information - - -![](figures/snipaste_2021-01-26_10-38-58-1.png) - -## Output - -**Table 1** Output description - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Proto

-

Indicates the protocol type.

-

Recv-Q

-

Indicates the amount of data that is not read by the user.

-

For Listen TCP, the value indicates the number of TCP connections that have completed three-way handshake but are not accepted by users.

-

Send-Q

-

For a TCP connection, this value indicates the amount of data that has been sent but not acknowledged.

-

For a UDP connection, this value indicates the amount of data buffered before IP address resolution is complete.

-

Local Address

-

Indicates the local IP address and port number.

-

Foreign Address

-

Indicates the remote IP address and port number.

-

State

-

Indicates the TCP connection status. This parameter is meaningless for UDP.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The command output like "========== total sockets 32 ====== unused sockets 22 BootTime 27 s ==========" indicates that there are 32 sockets in total, 22 sockets are not used, and it has been 27 seconds since the system starts. - diff --git a/en/device-dev/kernel/network-commands.md b/en/device-dev/kernel/network-commands.md deleted file mode 100644 index 87571257010b07ad22d44be257458089c3f76b61..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/network-commands.md +++ /dev/null @@ -1,25 +0,0 @@ -# Network Commands - -- **[arp](arp.md)** - -- **[dhclient](dhclient.md)** - -- **[dns](dns.md)** - -- **[ifconfig](ifconfig.md)** - -- **[ipdebug](ipdebug.md)** - -- **[netstat](netstat.md)** - -- **[ntpdate](ntpdate.md)** - -- **[ping](ping.md)** - -- **[ping6](ping6.md)** - -- **[telnet](telnet.md)** - -- **[tftp](tftp.md)** - - diff --git a/en/device-dev/kernel/network.md b/en/device-dev/kernel/network.md deleted file mode 100644 index 9899f4ae3070ec6ebb1559337782c2d99303f760..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/network.md +++ /dev/null @@ -1,303 +0,0 @@ -# Network - -- [Basic Concepts](#section9840143083510) -- [When to Use](#section1575885183516) -- [Description](#section16351198193614) - -## Basic Concepts - -The network module implements basic functions of the TCP/IP protocol stack and provides the standard POSIX socket interfaces. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Currently, the OS uses **lwIP** to provide network capabilities. - -## When to Use - -For user-space development, the OpenHarmony kernel provides a set of APIs for you to implement network functionalities, including creating and disabling sockets, transmitting and receiving data, and setting network attributes, in addition to standard POSIX socket functions provided by the C library. - -## Description - -**Table 1** Standard APIs in the C library - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Header File

-

Function

-

Description

-

sys/socket.h

-

int accept(int socket, struct sockaddr *address, socklen_t *address_len)

-

Accepts incoming connection requests.

-

sys/socket.h

-

int bind(int s, const struct sockaddr *name, socklen_t namelen)

-

Binds an IP address to a socket.

-

sys/socket.h

-

int shutdown(int socket, int how)

-

Shuts down a socket.

-

sys/socket.h

-

int getpeername(int s, struct sockaddr *name, socklen_t *namelen)

-

Retrieves the peer address of the specified socket.

-

sys/socket.h

-

int getsockname(int s, struct sockaddr *name, socklen_t *namelen)

-

Retrieves the local address of the specified socket.

-

sys/socket.h

-

int getsockopt(int s, struct sockaddr *name, socklen_t *namelen)

-

Retrieves the socket options.

-

sys/socket.h

-

int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)

-

Sets the socket options.

-

unistd.h

-

int close(int s)

-

Closes a socket.

-

sys/socket.h

-

int connect(int s, const struct sockaddr *name, socklen_t namelen)

-

Initiates a connection to a socket.

-

sys/socket.h

-

int listen(int sockfd, int backlog)

-

Listens for network connections.

-

sys/socket.h

-

ssize_t recv(int socket, void *buffer, size_t length, int flags)

-

Receives data from another socket.

-

sys/socket.h

-

ssize_t recvmsg(int s, struct msghdr *message, int flags)

-

Receives data from a specified socket based on the input parameters.

-

sys/socket.h

-

ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len)

-

Receives data from a specified socket and obtains the IP address of the data source.

-

sys/socket.h

-

ssize_t send(int s, const void *dataptr, size_t size, int flags)

-

Sends data to another socket.

-

sys/socket.h

-

ssize_t sendmsg(int s, const struct msghdr *message, int flags)

-

Sends data to another socket based on the input parameters.

-

sys/socket.h

-

ssize_t sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)

-

Sends data to another socket at the specified destination IP address.

-

sys/socket.h

-

int socket(int domain, int type, int protocol)

-

Creates a socket.

-

sys/select.h

-

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)

-

Monitors the I/O events of multiple file descriptors.

-

sys/ioctl.h

-

int ioctl(int s, int request, ...)

-

Obtains and sets socket options.

-

arpa/inet.h

-

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)

-

Converts an IP address in binary format to a string.

-

arpa/inet.h

-

int inet_pton(int af, const char *src, void *dst)

-

Converts a string to an IP address in binary format.

-
- -Details on API differences: - -- **sendmsg** - - **Function prototype:** - - ssize\_t sendmsg\(int s, const struct msghdr \*message, int flags\) - - **Function description:** sends a message on a socket. - - **Parameter description:** - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

s

-

Indicates the socket descriptor.

-

message

-

Indicates the pointer to the message to be sent. The ancillary message is not supported.

-

flags

-

Indicates the socket flags for sending the message. The options are as follows:

-
  • MSG_MORE: allows messages that have been sent for multiple times to be packaged and sent at a time.
  • MSG_DONTWAIT: enables a non-blocking operation.
-
- - **Return values:** - - - Returns the number of bytes that have been sent if the operation is successful. - - Returns **-1** and sets **errno** if the operation fails. - - -- **recvmsg** - - **Function prototype:** - - ssize\_t recvmsg\(int s, struct msghdr \*message, int flags\) - - **Function description:** receives a message from a socket. - - **Parameter description:** - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

s

-

Indicates the socket descriptor.

-

message

-

Indicates the pointer to the address to receive the message. The ancillary message is not supported.

-

flags

-

Indicates the socket flags for receiving the message. The options are as follows:

-
  • MSG_PEEK: allows the message to be read without being removed.
  • MSG_DONTWAIT: enables a non-blocking operation.
-
- - **Return values:** - - - Returns the number of bytes that have been received if the operation is successful. - - Returns **-1** and sets **errno** if the operation fails. - - -- **ioctl** - - **Function prototype:** - - int ioctl\(int s, int request, ...\) - - **Function description:** obtains or sets socket options. - - **Parameter description:** - - - - - - - - - - - - - -

Parameter

-

Description

-

s

-

Indicates the socket descriptor.

-

request

-

Indicates the operation to perform on the socket options. The options are as follows:

-
  • FIONREAD: obtains the number of bytes of the data that can be read from the socket.
  • FIONBIO: sets whether the socket is non-blocked.
-
- - **Return values:** - - - Returns **0** if the operation is successful. - - Returns **-1** and sets **errno** if the operation fails. - - diff --git a/en/device-dev/kernel/nfs.md b/en/device-dev/kernel/nfs.md deleted file mode 100644 index 5953ad82e372bd6871d158c2ecd74c21e8efdef3..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/nfs.md +++ /dev/null @@ -1,163 +0,0 @@ -# NFS - -- [Overview](#section18322139164413) -- [Important Notes](#section532912331467) -- [Development Guidelines](#section166873374711) - -## Overview - -NFS allows you to share files across hosts and OSs over a network. You can treat NFS as a file system service, which is equivalent to folder sharing in the Windows OS to some extent. - -An NFS client can mount a directory shared by a remote NFS server to the local host to run programs and share files without occupying the current system resources. The directory of the remote server is like a disk to the local host. - -## Important Notes - -- NFS files do not support permissions control. Use file permission **777** when creating NFS directories and files. - -- NFS files do not support read or write blocking. - -- NFS files do not support the signal function. - -- In NFS, the path length \(excluding the IP address\) in a **mount** operation cannot exceed 255 characters. If the maximum length is exceeded, the error code **ENAMETOOLONG** error is returned. - -- You can perform the following operation on NFS files: **open**, **close**, **read**, **write**, **seek**, **dup**, **dup2**, **sync**, **opendir**, **closedir**, **readdir**, **readdir\_r**, **rewinddir**, **scandir**, **statfs**, **remove**, **unlink**, **mkdir**, **rmdir**, **rename**, **stat**, **stat64**, **seek64**, **mmap**, **mount**, and **umount**. - -- Two transport layer protocols are supported in NFS: TCP \(default\) and UDP. - -- When you use **open** with the parameter **O\_TRUNC** to open a file, the file content will be cleared only when you have the write permission on the file. - -- When file A is not closed and the **rename\(\)** function renames file A as B, the fd is not changed. - -- The NFS feature is currently in the beta test and may be unstable. You are advised not to use the feature in commercial products. - - -## Development Guidelines - -1. **Create an NFS server.** - - This section uses the Ubuntu operating system \(OS\) as an example to describe how to configure an NFS server. - - 1. Install the NFS server software. - - Set the download source of the Ubuntu OS when the network connection is normal. - - ``` - sudo apt-get install nfs-kernel-server - ``` - - 2. Create a directory for mounting and set full permissions for the directory. - - ``` - mkdir /home/sqbin/nfs - sudo chmod 777 /home/sqbin/nfs - ``` - - 3. Configure and start the NFS server. - - Append the following line in the **/etc/exports** file: - - ``` - /home/sqbin/nfs *(rw,no_root_squash,async) - ``` - - **/home/sqbin/nfs** is the root directory shared by the NFS server. - - Start the NFS server. - - ``` - sudo /etc/init.d/nfs-kernel-server start - ``` - - Restart the NFS server. - - ``` - sudo /etc/init.d/nfs-kernel-server restart - ``` - - -2. **Configure a board as the NFS client.** - - In this section, the NFS client is a device running the OpenHarmony kernel. - - 1. Set the hardware connection. - - Connect the OpenHarmony kernel device to the NFS server. Set their IP addresses in the same network segment. For example, set the IP address of the NFS server to **10.67.212.178/24** and set the IP address of the OpenHarmony kernel device to **10.67.212.3/24**. Note that the preceding IP addresses are private IP addresses used as examples. You need to use your actual IP addresses. - - You can run the **ifconfig** command to view the device's IP address. - - 2. Start the network and ensure that the network between the board and NFS server is normal. - - Start the Ethernet or another type of network, and then run **ping** to check whether the network connection to the server is normal. - - ``` - OHOS # ping 10.67.212.178 - [0]Reply from 10.67.212.178: time=1ms TTL=63 - [1]Reply from 10.67.212.178: time=0ms TTL=63 - [2]Reply from 10.67.212.178: time=1ms TTL=63 - [3]Reply from 10.67.212.178: time=1ms TTL=63 - --- 10.67.212.178 ping statistics --- - 4 packets transmitted, 4 received, 0 loss - ``` - - Initialize the NFS client. - - ``` - OHOS # mkdir /nfs - OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 - ``` - - If the following information is displayed, the NFS client is initialized. - - ``` - OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 - Mount nfs on 10.67.212.178:/home/sqbin/nfs, uid:1011, gid:1000 - Mount nfs finished. - ``` - - This command mounts the **/home/sqbin/nfs** directory on the NFS server whose IP address is 10.67.212.178 to the **/nfs** directory on the device. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >This section assumes that the NFS server is available, that is, the **/home/sqbin/nfs** directory on the NFS server 10.67.212.178 is accessible. - - The **mount** command format is as follows: - - ``` - mount nfs - ``` - - In this command, **SERVER\_IP** indicates the IP address of the NFS server, **SERVER\_PATH** indicates the path of the shared directory on the NFS server, and **CLIENT\_PATH** indicates the NFS path on the device. - - If you do not want to restrict the NFS access permission, set the permission of the NFS root directory to **777** on the Linux CLI. - - ``` - chmod -R 777 /home/sqbin/nfs - ``` - - The NFS client setting is complete, and the NFS file system has been mounted. - - -3. **Share files using NFS.** - - Create the **dir** directory on the NFS server and save the directory. Run the **ls** command in the OpenHarmony kernel. - - ``` - OHOS # ls /nfs - ``` - - The following information is returned from the serial port: - - ``` - OHOS # ls /nfs - Directory /nfs: - drwxr-xr-x 0 u:0 g:0 dir - ``` - - The **dir** directory created on the NFS server has been synchronized to the **/nfs** directory on the device. - - Similarly, you can create files and directories on the device and access them on the NFS server. - - **Platform differences:** - - Currently, the NFS client supports some NFS v3 specifications. Therefore, the NFS client is not fully compatible with all types of NFS servers. During the development and test, you are advised to use the Linux NFS server. - - diff --git a/en/device-dev/kernel/oom.md b/en/device-dev/kernel/oom.md deleted file mode 100644 index f97c98347a567e251f5003483d9c214cb02b9351..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/oom.md +++ /dev/null @@ -1,120 +0,0 @@ -# oom - -- [Command Function](#section366714216619) -- [Syntax](#section8833164614615) -- [Parameter Description](#section12809111019453) -- [Usage](#section15935131220717) -- [Example](#section79281818476) -- [Output](#section12742311179) - -## Command Function - -This command is used to query and set the low memory threshold and the page cache reclaim threshold. - -## Syntax - -oom - -oom -i \[_interval_\] - -oom -m \[_mem byte_\] - -oom -r \[_mem byte_\] - -oom -h | --help - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

-i [interval]

-

Sets the interval for checking the Out Of Memory (OOM) thread task.

-

100 ms – 10000 ms

-

-m [mem byte]

-

Sets the low memory threshold.

-

0 MB (does not check for low memory) – 1 MB

-

-r [mem byte]

-

Sets the page cache reclaim threshold.

-

Ranging from the low memory threshold to the maximum available system memory

-

-h | --help

-

Uses the help.

-

N/A

-
- -## Usage - -- If no parameter is specified, the current configurations of the OOM function are displayed. - -## Example - -When the system memory is insufficient, the system displays a message indicating the insufficiency. - -## Output - -![](figures/en-us_image_0000001053710680.png) - -**Table 2** Output description - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

[oom] OS is in low memory state

-

total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte)

-

The memory usage of the OS is low.

-

The available physical memory in the entire OS is 0x1bcf000 bytes, 0x1b50000 bytes have been used, and 0x7f000 bytes are available. The current low memory threshold is 0x80000 bytes.

-

[oom] candidate victim process init pid: 1, actual phy mem byte: 82602

-

The memory usage of each process is printed. The init process actually uses 82602 bytes, and the shared memory is calculated based on the proportion.

-

[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558

-

The actual memory used by the UserProcess12 process is 25951558 bytes.

-

[oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558

-

The process that uses the most memory currently is UserProcess12.

-

excFrom: User!

-

When the system memory is low, the UserProcess12 process fails to apply for memory and exits as a result.

-
- diff --git a/en/device-dev/kernel/openharmony-lite-kernel-basic-functions.md b/en/device-dev/kernel/openharmony-lite-kernel-basic-functions.md deleted file mode 100644 index 8e3d07b35fb20071a4799e33f88480253820194f..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/openharmony-lite-kernel-basic-functions.md +++ /dev/null @@ -1,11 +0,0 @@ -# OpenHarmony Lite Kernel Basic Functions - -- **[Process](process.md)** - -- **[Thread](thread.md)** - -- **[Memory](memory.md)** - -- **[Network](network.md)** - - diff --git a/en/device-dev/kernel/openharmony-lite-kernel-file-system.md b/en/device-dev/kernel/openharmony-lite-kernel-file-system.md deleted file mode 100644 index 443fc42c437c4eb5b001c163b4ae4b56355186d5..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/openharmony-lite-kernel-file-system.md +++ /dev/null @@ -1,54 +0,0 @@ -# OpenHarmony Lite Kernel File System - -The OpenHarmony lite kernel supports the following file systems: Virtual File System \(VFS\), Network File System \(NFS\), RAM File System \(RAMFS\), File Allocation Table \(FAT\), and Journalling Flash File System Version 2 \(JFFS2\). - -The table below describes the functions of these file systems. - -**Table 1** File system functions - - - - - - - - - - - - - - - - - - - - - - -

File System

-

Function

-

VFS

-

In essence, VFS is not a real file system. It is an abstract layer on top of a heterogeneous file system and provides you with a unified Unix-like file operation interface.

-

NFS

-

NFS allows you to share files across hosts and OSs over a network.

-

RAMFS

-

RAMFS is a RAM-based file system. All files are stored in the RAM, and file read/write operations are performed in the RAM, which reduces the read/write loss of the memory and improves the data read/write speed. It provides a RAM-based storage buffer for dynamic file systems.

-

FAT

-

There are FAT12, FAT16, and FAT32. FAT is often used on removable storage media (such as USB flash drives, SD cards, and portable hard disks) to provide better compatibility between devices and desktop systems such as Windows and Linux.

-

JFFS2

-

JFFS2 is a journal-type file system implemented on Memory Technology Devices (MTDs). It is mainly used to manage files of the NOR flash memory. JFFS2 used in the OpenHarmony kernel supports multiple partitions.

-
- -- **[VFS](vfs.md)** - -- **[NFS](nfs.md)** - -- **[RAMFS](ramfs.md)** - -- **[FAT](fat.md)** - -- **[JFFS2](jffs2.md)** - - diff --git a/en/device-dev/kernel/partinfo.md b/en/device-dev/kernel/partinfo.md deleted file mode 100644 index 0de22f29a1033c0187ec9a97b384cbba7b3f12b1..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/partinfo.md +++ /dev/null @@ -1,52 +0,0 @@ -# partinfo - -- [Command Function](#section1777503617199) -- [Syntax](#section185501447132114) -- [Parameter Description](#section1304151212252) -- [Usage](#section4566131982520) -- [Example](#section4351134942514) -- [Output](#section66689331412) - -## Command Function - -This command is used to query information about multiple partitions of a hard disk or SD card identified by the system. - -## Syntax - -partinfo <_dev\_inodename_\> - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

dev_inodename

-

Indicates the name of the partition to be queried.

-

A valid partition name

-
- -## Usage - -None - -## Example - -Enter **partinfo /dev/mmcblk0p0**. - -## Output - -![](figures/en-us_image_0000001052370303.png) - diff --git a/en/device-dev/kernel/partition.md b/en/device-dev/kernel/partition.md deleted file mode 100644 index adebf41920c2a0f957c11020848dba1feb22e93d..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/partition.md +++ /dev/null @@ -1,62 +0,0 @@ -# partition - -- [Command Function](#section255095212257) -- [Syntax](#section10258056122515) -- [Parameter Description](#section177200581256) -- [Usage](#section17866411262) -- [Example](#section1927174202610) -- [Output](#section11321011223) - -## Command Function - -This command is used to query flash partition information. - -## Syntax - -partition \[_nand / spinor_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

nand

-

Displays information about the NAND flash partition.

-

N/A

-

spinor

-

Displays information about the spinor flash partition.

-

N/A

-
- -## Usage - -- The **partition** command is used to query flash partition information. -- The NAND flash partition information can be viewed only when the YAFFS file system is enabled. The spinor flash partition information can be viewed only when the JFFS or ROMFS file system is enabled. - -## Example - -Enter **partition spinor**. - -## Output - -Viewing spinor flash partition information - -![](figures/en-us_image_0000001052810300.png) - diff --git a/en/device-dev/kernel/ping.md b/en/device-dev/kernel/ping.md deleted file mode 100644 index 8a829c7ee45729bd729c292bf7e52751f9a8e354..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/ping.md +++ /dev/null @@ -1,98 +0,0 @@ -# ping - -- [Command Function](#section119672573385) -- [Syntax](#section869419010390) -- [Parameter Description](#section9877183173918) -- [Usage](#section1097046193914) -- [Example](#section14564129113911) -- [Output](#section1621732891215) - -## Command Function - -This command is used to test whether the network connection is normal. - -## Syntax - -ping_ _\[_-n cnt_\] \[_-w interval_\] \[_-l data\_len_\]_ _ - -ping \[_-t_\] \[_-w interval_\] __ - -ping _-k_ - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

IP

-

Indicates the IPv4 address whose network connectivity is to be tested.

-

N/A

-

-n cnt

-

Indicates the number of execution times. If this parameter is not specified, the default value is 4.

-

1-65535

-

-w interval

-

Indicates the interval between two ping packets, in ms.

-

>0

-

-l data_len

-

Indicates the length of the ping packet, that is, the ICMP echo request packet.

-

The ICMP packet header is not included.

-

0-65500

-

-t

-

Indicates a permanent ping thread, which will be killed until the ping -k command is executed.

-

N/A

-

-k

-

Kills the ping thread and stops the ping operation.

-

N/A

-
- -## Usage - -- Run the **ping** command by setting a destination IP address to check whether the network connection to the destination IP address is normal. -- If the destination IP address is unreachable, the system displays a message indicating that the request times out. -- If no route is available to the destination IP address, an error message is displayed. -- This command can be used only after the TCP/IP protocol stack is enabled. - -## Example - -Enter **ping 192.168.1.10**. - -## Output - -**Figure 1** Output of pinging the IP address of the TFTP server - - -![](figures/snipaste_2021-01-26_10-38-58-2.png) - diff --git a/en/device-dev/kernel/pmm.md b/en/device-dev/kernel/pmm.md deleted file mode 100644 index 6d44a3c6f051735afc8e97fbb3bcce8400c81526..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/pmm.md +++ /dev/null @@ -1,91 +0,0 @@ -# pmm - -- [Command Function](#section445335110416) -- [Syntax](#section1795712553416) -- [Parameter Description](#section92544592410) -- [Usage](#section104151141252) -- [Example](#section11545171957) -- [Output](#section075617368542) - -## Command Function - -This command is used to check the usage of the physical pages and page cache of the system memory. - -## Syntax - -pmm - -## Parameter Description - -None - -## Usage - -This command is available only in the **Debug** version. - -## Example - -Enter **pmm**. - -## Output - -**Figure 1** Viewing the usage of physical pages -![](figures/viewing-the-usage-of-physical-pages.png "viewing-the-usage-of-physical-pages") - -**Table 1** Output description - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

phys_seg

-

Indicates the address of the physical page control block.

-

base

-

Indicates the first physical page address, that is, start address of the physical page memory.

-

size

-

Indicates the size of the physical page memory.

-

free_pages

-

Indicates the number of idle physical pages.

-

active anon

-

Indicates the number of active anonymous pages in the page cache.

-

inactive anon

-

Indicates the number of inactive anonymous pages in the page cache.

-

active file

-

Indicates the number of active file pages in the page cache.

-

inactive file

-

Indicates the number of inactive file pages in the page cache.

-

pmm pages

-
  • total: indicates the total number of physical pages.
  • used: indicates the number of used physical pages.
  • free: indicates the number of idle physical pages.
-
- diff --git a/en/device-dev/kernel/process.md b/en/device-dev/kernel/process.md deleted file mode 100644 index 6cb4b62be89c4981d339121017e13cf127d2ca83..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/process.md +++ /dev/null @@ -1,301 +0,0 @@ -# Process - -- [Basic Concepts](#section29197338383) -- [When to Use](#section85513272398) -- [Available APIs](#section4517119124015) - -## Basic Concepts - -Processes are resource management units in the OS. They can use or wait to use CPUs and use system resources such as memory. They run independently from one another. - -The OpenHarmony kernel allows multiple processes to run simultaneously, switch, and communicate, facilitating your management over service programs. In this regard, you will have more time to devote to the implementation of service functionalities. - -Processes in the OpenHarmony kernel use the preemptive scheduling mechanism, round-robin \(RR\) scheduling. - -These processes are assigned 32 priorities \(**0** to **31**\). Among them, user processes can be configured with 22 priorities from **10** \(highest\) to **31** \(lowest\). - -A high-priority process can preempt the resources of a low-priority process. The low-priority process can be scheduled only after the high-priority process is blocked or terminated. - -Each user-space process has its own memory space, which is invisible to other processes. In this way, processes are isolated from each other. - -The user-space root process init is started by the kernel. Then other user-space processes are created by the init process via the **fork** call. - -**A process may have the following states:** - -- **Init**: The process is being created. - -- **Ready**: The process is in the ready list and waits for being scheduled by the CPU. - -- **Running**: The process is running. - -- **Pending**: The process is blocked and suspended. When all threads in a process are blocked, the process is blocked and suspended. - -- **Zombies**: The process stops running and waits for the parent process to reclaim its control block resources. - - -**Figure 1** State transition of a process -![](figures/state-transition-of-a-process.png "state-transition-of-a-process") - -**Description of the process state transition:** - -- Init→Ready: - - When a process is created, the process enters the **Init** state to start initialization after obtaining the process control block. After the process is initialized, the process is inserted into the scheduling queue and therefore enters the **Ready** state. - -- Ready→Running: - - When a process switchover is triggered, the process with the highest priority in the ready list is executed and enters the **Running** state. If this process has no thread in the **Ready** state, the process is deleted from the ready list and resides only in the **Running** state. However, if it has threads in the **Ready** state, the process still stays in the ready list. In this case, the process is in both the **Ready** and **Running** states. - -- Running→Pending: - - If all threads in a process are entering the **Pending** state, the process will enter the **Pending** state together with its last thread. Then, a process switchover is triggered. - -- Pending→Ready: - - When any thread in a **Pending** process restores to the **Ready** state, the process is added to the ready list and changes to the **Ready** state. - -- Ready→Pending: - - When the last ready thread in a process enters the **Pending** state, the process is deleted from the ready list, and the process changes from the **Ready** state to the **Pending** state. - -- Running→Ready: - - A process may change from the **Running** state to the **Ready** state in either of the following scenarios: - - 1. After a process with a higher priority is created or restored, processes will be scheduled. The process with the highest priority in the ready list will change to the **Running** state, and the originally running process will change from the **Running** state to the **Ready** state. - 2. If a process has the **SCHED\_RR** scheduling policy and shares the same priority with another process in the **Ready** state, this process will change from the **Running** state to the **Ready** state after its time slices are used up, and the other process with the same priority will change from the **Ready** state to the **Running** state. - -- Running→Zombies: - - After the main thread or all threads of a process are stopped, the process changes from the **Running** state to the **Zombies** state and waits for the parent process to reclaim resources. - - -## When to Use - -After processes are created, you can operate the resources only in your own process space, except shared resources. In user space, processes can be suspended, restored, and delayed. In addition, you can set and obtain the scheduling priority and scheduling policy of processes. When a process is terminated, it proactively releases its resources. However, the PID resources of the process are reclaimed by the parent process via **wait**/**waitpid** or when the parent process exits. - -## Available APIs - -The following table describes the APIs provided by the process management module of the OpenHarmony kernel. - -**Table 1** APIs provided by the process management module - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

Function

-

Description

-

Remarks

-

Process

-

fork

-

Creates a new process.

-

N/A

-

exit

-

Exits the process.

-

N/A

-

atexit

-

Registers the callback that will be called when the process is terminated normally.

-

N/A

-

abort

-

Terminates the process.

-

N/A

-

getpid

-

Obtains the process ID.

-

N/A

-

getppid

-

Obtains the parent process ID.

-

N/A

-

getpgrp

-

Obtains the ID of the process group of the calling process.

-

N/A

-

getpgid

-

Obtains the process group ID of the process identified by pid.

-

N/A

-

setpgrp

-

Sets the process group ID of the calling process.

-

N/A

-

setpgid

-

Sets the process group ID of the process identified by pid.

-

N/A

-

kill

-

Sends a signal to a specified process.

-
  • Only signals 1 to 30 can be sent.
  • The default behavior for signals does not include STOP and CONTINUE and terminates the process without a core dump.
  • SIGSTOP, SIGKILL, and SIGCONT cannot be masked.
  • After an asynchronous signal is sent to a process, the signal callback is invoked only after the process is scheduled. For the sake of security, the process can be killed only by itself, and the kernel cannot forcibly kill the process by sending signals.
  • After the process is killed, SIGCHLD is sent to its parent process. The sending action cannot be canceled.
  • A sleeping process cannot be woken up by a signal.
-

wait

-

Waits for any child process to terminate and reclaims its resources.

-

The status value is defined by the following macros:

-
  • WIFEXITED(status): If the child process terminates normally, true is returned. Otherwise, false is returned.
  • WEXITSTATUS(status): If WIFEXITED(status) is true, this macro can be used to obtain the exit code that the child process passed to exit().
  • WTERMSIG(status): If a child process terminates abnormally, the child process exit code obtained by the parent process through WTERMSIG is always SIGUSR2. This is the only case supported.
  • The following operations are not supported: WIFSTOPPED, WSTOPSIG, WCOREDUMP, and WIFCONTINUED.
-

waitpid

-

Waits for a specified child process to terminate and reclaims its resources.

-

The options to control the function behavior do not support WUNTRACED and WCONTINUED.

-

The status value is defined by the following macros:

-
  • WIFEXITED(status): If the child process terminates normally, true is returned. Otherwise, false is returned.
  • WEXITSTATUS(status): If WIFEXITED(status) is true, this macro can be used to obtain the exit code that the child process passed to exit().
  • WTERMSIG(status): If a child process terminates abnormally, the child process exit code obtained by the parent process through WTERMSIG is always SIGUSR2. This is the only case supported.
  • The following operations are not supported: WIFSTOPPED, WSTOPSIG, WCOREDUMP, and WIFCONTINUED.
-

Scheduling

-

getpriority

-

Obtains the static priority of a specified ID.

-
  • PRIO_PGRP and PRIO_USER are not supported.
-
  • The priority to obtain and set refers to the static priority. The dynamic priority is not involved.
-

setpriority

-

Sets the static priority of a specified ID.

-

sched_rr_get_interval

-

Obtains the execution time limit of a process.

-

N/A

-

sched_yield

-

Yields the running process.

-

N/A

-

sched_get_priority_max

-

Obtains the maximum static priority that can be used for a process.

-

The scheduling policy can only be SCHED_RR.

-

sched_get_priority_min

-

Obtains the minimum static priority that can be used for a process.

-

sched_getscheduler

-

Obtains the scheduling policy of a process.

-

sched_setscheduler

-

Sets a scheduling policy for a process.

-

sched_getparam

-

Obtains scheduling parameters of a process.

-

N/A

-

sched_setparam

-

Sets scheduling parameters related to a scheduling policy for a process.

-

N/A

-

exec

-

execl

-

Executes a specified user program file in ELF format.

-

N/A

-

execle

-

Executes a specified user program file in ELF format.

-

N/A

-

execlp

-

Executes a specified user program file in ELF format.

-

N/A

-

execv

-

Executes a specified user program file in ELF format.

-

N/A

-

execve

-

Executes a specified user program file in ELF format.

-

N/A

-

execvp

-

Executes a specified user program file in ELF format.

-

N/A

-
- diff --git a/en/device-dev/kernel/public_sys-resources/icon-caution.gif b/en/device-dev/kernel/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/kernel/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/device-dev/kernel/public_sys-resources/icon-danger.gif b/en/device-dev/kernel/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/kernel/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/device-dev/kernel/public_sys-resources/icon-note.gif b/en/device-dev/kernel/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/device-dev/kernel/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/device-dev/kernel/public_sys-resources/icon-notice.gif b/en/device-dev/kernel/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/device-dev/kernel/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/device-dev/kernel/public_sys-resources/icon-tip.gif b/en/device-dev/kernel/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/device-dev/kernel/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/device-dev/kernel/public_sys-resources/icon-warning.gif b/en/device-dev/kernel/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/kernel/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/device-dev/kernel/pwd.md b/en/device-dev/kernel/pwd.md deleted file mode 100644 index f277c5391ef0a704c51ab67b29126c8868b5a09c..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/pwd.md +++ /dev/null @@ -1,34 +0,0 @@ -# pwd - -- [Command Function](#section197737712267) -- [Syntax](#section1544061016267) -- [Parameter Description](#section599112120262) -- [Usage](#section66901116152615) -- [Example](#section7427181922612) -- [Output](#section116313389418) - -## Command Function - -This command is used to display the current path. - -## Syntax - -pwd - -## Parameter Description - -None - -## Usage - -The **pwd** command writes the full path name of the current directory \(from the root directory\) to the standard output. All directories are separated by slashes \(/\). The directory following the first slash \(/\) indicates the root directory, and the last directory is the current directory. - -## Example - -Enter **pwd**. - -## Output - -**Figure 1** Querying the current path -![](figures/querying-the-current-path.png "querying-the-current-path") - diff --git a/en/device-dev/kernel/rm.md b/en/device-dev/kernel/rm.md deleted file mode 100644 index b828771a11901997a0efc0dc09fcd4d9c118b507..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/rm.md +++ /dev/null @@ -1,67 +0,0 @@ -# rm - -- [Command Function](#section181141523142613) -- [Syntax](#section8800926132619) -- [Parameter Description](#section15476229152617) -- [Usage](#section10578163215262) -- [Example](#section18548133511263) -- [Output](#section1565323814265) - -## Command Function - -This command is used to delete a file or folder. - -## Syntax - -rm \[_-r_\] \[_dirname / filename_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

-r

-

Deletes a directory. This parameter is optional. It is required if a directory is to be deleted.

-

N/A

-

dirname/filename

-

Indicates the name of the file or directory to be deleted. The value can be a path.

-

N/A

-
- -## Usage - -- The **rm** command deletes only one file or directory at a time. -- The **rm -r** command can be used to delete a non-empty directory. - -## Example - -Example: - -1. Enter **rm log1.txt**. -2. Enter **rm -r sd**. - -## Output - -**Figure 1** Deleting the **log1.txt** file -![](figures/deleting-the-log1-txt-file.png "deleting-the-log1-txt-file") - -**Figure 2** Deleting the **sd** directory -![](figures/deleting-the-sd-directory.png "deleting-the-sd-directory") - diff --git a/en/device-dev/kernel/rmdir.md b/en/device-dev/kernel/rmdir.md deleted file mode 100644 index 9d35e2c1c866847aa54c83fc216df38bec50a791..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/rmdir.md +++ /dev/null @@ -1,55 +0,0 @@ -# rmdir - -- [Command Function](#section1839611420266) -- [Syntax](#section329574512266) -- [Parameter Description](#section15865747102620) -- [Usage](#section107857508261) -- [Example](#section11196165315262) -- [Output](#section1073811415613) - -## Command Function - -This command is used to delete a directory. - -## Syntax - -rmdir \[_dir_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

dir

-

Indicates the name of the directory to be deleted. The directory must be empty. You can enter a path for this parameter.

-

N/A

-
- -## Usage - -- The **rmdir** command can only be used to delete directories. -- The **rmdir** command can delete only one directory at a time. -- The **rmdir** command can delete only empty directories. - -## Example - -Enter **rmdir dir**. - -## Output - -**Figure 1** Deleting directory **dir** -![](figures/deleting-directory-dir.png "deleting-directory-dir") - diff --git a/en/device-dev/kernel/sem.md b/en/device-dev/kernel/sem.md deleted file mode 100644 index 08e04352c5934a4fc38310df39c7c2133558fc61..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/sem.md +++ /dev/null @@ -1,91 +0,0 @@ -# sem - -- [Command Function](#section366714216619) -- [Syntax](#section8833164614615) -- [Parameter Description](#section12809111019453) -- [Usage](#section15935131220717) -- [Example](#section79281818476) -- [Output](#section1975118519456) - -## Command Function - -This command is used to query information about kernel semaphores. - -## Syntax - -sem \[_ID__ / fulldata_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

ID

-

Indicates the semaphore ID.

-

[0, 0xFFFFFFFF]

-

fulldata

-

Queries information about all the semaphores in use. The information to be printed includes SemID, Count, OriginalCount, Creater(TaskEntry), and LastAccessTime.

-

N/A

-
- -## Usage - -- If the parameters are not specified, this command displays the number of used semaphores and the total number of semaphores. -- If the **ID** parameter is specified, semaphores of the specified ID are displayed. -- The **fulldata** parameter depends on **LOSCFG\_DEBUG\_SEMAPHORE**. Before specifying the **fulldata** parameter, enable the **Enable Semaphore Debugging** configuration item using **menuconfig**. - - Debug ---\> Enable a Debug Version ---\> Enable Debug LiteOS Kernel Resource ---\> Enable Semaphore Debugging - - -## Example - -Example 1: Enter **sem fulldata**. - -## Output - -**Figure 1** Querying information about all semaphores in use -![](figures/querying-information-about-all-semaphores-in-use.png "querying-information-about-all-semaphores-in-use") - -**Table 2** Output description - - - - - - - - - - - - - -

Parameter

-

Description

-

SemID

-

Indicates the semaphore ID.

-

Count

-

Indicates the number of used semaphores.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->- The **ID** value can be in decimal or hexadecimal format. ->- When the **ID** value is within the range of \[0, 1023\], semaphore information of the specified ID is displayed. If the semaphore ID is not used, a message is displayed to inform you of this case. For other values, a message is displayed indicating that the input parameter is incorrect. - diff --git a/en/device-dev/kernel/shell-command-development-guidelines.md b/en/device-dev/kernel/shell-command-development-guidelines.md deleted file mode 100644 index 766aff15ee4cfa14a45cfccd44e922d65f53f133..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/shell-command-development-guidelines.md +++ /dev/null @@ -1,167 +0,0 @@ -# Shell Command Development Guidelines - -- [Development Guidelines](#section22071515161018) - -## Development Guidelines - -You can perform the following operations to add shell commands: - -1. Include the following header files: - - ``` - #include "shell.h" - #include "shcmd.h" - ``` - -2. Register commands. You can register commands either statically or dynamically when the system is running. In most cases, static registration is widely used by common system commands, and dynamic registration is widely used by user commands. - - 1. Static registration: - - 1. Register a command using a macro. - - The prototype of the macro is as follows: - - ``` - SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) - ``` - - **Table 1** Parameters of the SHELLCMD\_ENTRY macro - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

l

-

Indicates the global variable name to be passed during the static registration. Note that the name cannot be the same as other symbol names in the system.

-

cmdType

-

Indicates the command type.

-
  • CMD_TYPE_EX: does not support standard command parameters and will mask the command keywords you entered. For example, if you enter ls /ramfs, only /ramfs will be passed to the registration function, and the ls command keyword will be masked.

    -
  • CMD_TYPE_STD: supports standard command parameters. All the characters you entered will be passed to the registration function after being parsed.

    -
-

cmdKey

-

Indicates the command keyword, which is the name used to access a shell function.

-

paraNum

-

Indicates the maximum number of input parameters in the execution function to be invoked. This parameter is not supported currently.

-

cmdHook

-

Indicates the address of the execution function, that is, the function that is actually executed by the command.

-
- - For example: - - ``` - SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) - ``` - - 2. Add the required options to the **build/mk/liteos\_tables\_ldflags.mk** file. - - For example, when registering the **ls** command, add **-uls\_shellcmd** to the **build/mk/liteos\_tables\_ldflags.mk** file. **-u** is followed by the first parameter of **SHELLCMD\_ENTRY**. - - - 2. Dynamic registration: - - The prototype of the function to register is as follows: - - ``` - UINT32 osCmdReg(CmdT ype cmdType, CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) - ``` - - **Table 2** Parameters of UINT32 osCmdReg - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

cmdType

-

Indicates the command type.

-
  • CMD_TYPE_EX: does not support standard command parameters and will mask the command keywords you entered. For example, if you enter ls /ramfs, only /ramfs will be passed to the registration function, and the ls command keyword will be masked.

    -
  • CMD_TYPE_STD: supports standard command parameters. All the characters you entered will be passed to the registration function after being parsed.

    -
-

cmdKey

-

Indicates the command keyword, which is the name used to access a shell function.

-

paraNum

-

Indicates the maximum number of input parameters in the execution function to be invoked. This parameter is not supported currently. The default value is XARGS(0xFFFFFFFF).

-

cmdHook

-

Indicates the address of the execution function, that is, the function that is actually executed by the command.

-
- - For example: - - ``` - osCmdReg(CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) - ``` - - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >The command keyword must be unique. Specifically, two different commands cannot share the same command keyword. Otherwise, only one command is executed. - >When executing user commands sharing the same keyword, the shell executes only the first command in the **help** commands. - -3. Use the following function prototype to add built-in commands: - - ``` - UINT32 osShellCmdLs(UINT32 argc, CHAR **argv) - ``` - - **Table 3** Parameters of osShellCmdLs - - - - - - - - - - - - - -

Parameter

-

Description

-

argc

-

Indicates the number of parameters in the shell command.

-

argv

-

Indicates a pointer array, where each element points to a string. You can determine whether to pass the command keyword to the registration function by specifying the command type.

-
- -4. Enter the shell command in either of the following methods: - - Enter the shell command in the serial port tool. - - - Enter the shell command in the Telnet tool. For details, see [telnet](telnet.md). - - - diff --git a/en/device-dev/kernel/shell-command-reference.md b/en/device-dev/kernel/shell-command-reference.md deleted file mode 100644 index 1c1df368f21fee6269b33805f9178611dfc956ed..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/shell-command-reference.md +++ /dev/null @@ -1,13 +0,0 @@ -# Shell Command Reference - -This chapter describes the functions, syntax, parameter ranges, usages, and examples of key system commands. - -For details about the commands that are not described in this document, see the output of the [help](help.md) command. You can also use the **-h | --help** option of a command to view the help information about the command. - -- **[System Commands](system-commands.md)** - -- **[File Commands](file-commands.md)** - -- **[Network Commands](network-commands.md)** - - diff --git a/en/device-dev/kernel/stack.md b/en/device-dev/kernel/stack.md deleted file mode 100644 index a3bf37a1c193ebe6f7c86b8bd9d2713452081a0e..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/stack.md +++ /dev/null @@ -1,73 +0,0 @@ -# stack - -- [Command Function](#section445335110416) -- [Syntax](#section1795712553416) -- [Parameter Description](#section92544592410) -- [Usage](#section104151141252) -- [Example](#section11545171957) -- [Output](#section075617368542) - -## Command Function - -This command is used to check the usage of each stack in the system. - -## Syntax - -stack - -## Parameter Description - -None - -## Usage - -None - -## Example - -Enter **stack**. - -## Output - -**Figure 1** System stack usage - - -![](figures/en-us_image_0000001054624363.png) - -**Table 1** Output description - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

stack name

-

Indicates the system stack name.

-

cpu id

-

Indicates the CPU ID.

-

stack addr

-

Indicates the stack address.

-

total size

-

Indicates the stack size.

-

used size

-

Indicates the used size of the stack.

-
- diff --git a/en/device-dev/kernel/standard-library-0.md b/en/device-dev/kernel/standard-library-0.md deleted file mode 100644 index 5d885291e116ea56c42f6865b32e59ab20300950..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/standard-library-0.md +++ /dev/null @@ -1,197 +0,0 @@ -# Standard Library - -- [Framework](#section1247343413257) -- [Development Example](#section4807125622614) -- [FAQs](#section1219455217277) - -The OpenHarmony kernel uses the **musl libc** library that supports the Portable Operating System Interface \(POSIX\). You can develop components and applications working on the kernel based on the POSIX. - -## Framework - -**Figure 1** POSIX framework -![](figures/posix-framework.png "posix-framework") - -When a system invokes an interface, the OpenHarmony kernel is adapted to provide the interface's external features. - -For details about the APIs supported by the standard library, see the API document of the C library, which also covers the differences between the standard library and the POSIX standard. - -## Development Example - -In this example, the main thread creates **THREAD\_NUM** child threads. Once a child thread is started, it enters the standby state. After the main thread successfully wakes up all child threads, they continue to execute until the lifecycle ends. The main thread uses the **pthread\_join** method to wait until all child threads are executed. - -``` -#include -#include -#include - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#define THREAD_NUM 3 -int g_startNum = 0; /* Number of started threads */ -int g_wakenNum = 0; /* Number of wakeup threads */ - -struct testdata { - pthread_mutex_t mutex; - pthread_cond_t cond; -} g_td; - -/* - * Entry function of child threads. - */ -static void *ChildThreadFunc(void *arg) -{ - int rc; - pthread_t self = pthread_self(); - - /* Locks a mutex. */ - rc = pthread_mutex_lock(&g_td.mutex); - if (rc != 0) { - printf("ERROR:take mutex lock failed, error code is %d!\n", rc); - goto EXIT; - } - - /* The value of g_startNum is increased by 1. The value indicates the number of child threads that have locked a mutex. */ - g_startNum++; - - /* Wait for the condition variable. */ - rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); - if (rc != 0) { - printf("ERROR: pthread condition wait failed, error code is %d!\n", rc); - (void)pthread_mutex_unlock(&g_td.mutex); - goto EXIT; - } - - /* Attempt to lock a mutex, which is failed in normal cases. */ - rc = pthread_mutex_trylock(&g_td.mutex); - if (rc == 0) { - printf("ERROR: mutex gets an abnormal lock!\n"); - goto EXIT; - } - - /* The value of g_wakenNum is increased by 1. The value indicates the number of child threads that have been woken up by the condition variable. */ - g_wakenNum++; - - /* Unlock a mutex. */ - rc = pthread_mutex_unlock(&g_td.mutex); - if (rc != 0) { - printf("ERROR: mutex release failed, error code is %d!\n", rc); - goto EXIT; - } -EXIT: - return NULL; -} - -static int testcase(void) -{ - int i, rc; - pthread_t thread[THREAD_NUM]; - - /* Initialize a mutex. */ - rc = pthread_mutex_init(&g_td.mutex, NULL); - if (rc != 0) { - printf("ERROR: mutex init failed, error code is %d!\n", rc); - goto ERROROUT; - } - - /* Initialize the condition variable. */ - rc = pthread_cond_init(&g_td.cond, NULL); - if (rc != 0) { - printf("ERROR: pthread condition init failed, error code is %d!\n", rc); - goto ERROROUT; - } - - /* Create child threads in batches. The number is specified by THREAD_NUM. */ - for (i = 0; i < THREAD_NUM; i++) { - rc = pthread_create(&thread[i], NULL, ChildThreadFunc, NULL); - if (rc != 0) { - printf("ERROR: pthread create failed, error code is %d!\n", rc); - goto ERROROUT; - } - } - - /* Wait until all child threads lock a mutex. */ - while (g_startNum < THREAD_NUM) { - usleep(100); - } - - /* Lock a mutex and block all threads using pthread_cond_wait. */ - rc = pthread_mutex_lock(&g_td.mutex); - if (rc != 0) { - printf("ERROR: mutex lock failed, error code is %d\n", rc); - goto ERROROUT; - } - - /* Unlock a mutex. */ - rc = pthread_mutex_unlock(&g_td.mutex); - if (rc != 0) { - printf("ERROR: mutex unlock failed, error code is %d!\n", rc); - goto ERROROUT; - } - - for (int j = 0; j < THREAD_NUM; j++) { - /* Broadcast signals on the condition variable. */ - rc = pthread_cond_signal(&g_td.cond); - if (rc != 0) { - printf("ERROR: pthread condition failed, error code is %d!\n", rc); - goto ERROROUT; - } - } - - sleep(1); - - /* Check whether all child threads are woken up. */ - if (g_wakenNum != THREAD_NUM) { - printf("ERROR: not all threads awaken, only %d thread(s) awaken!\n", g_wakenNum); - goto ERROROUT; - } - - /* Wait for all threads to terminate. */ - for (i = 0; i < THREAD_NUM; i++) { - rc = pthread_join(thread[i], NULL); - if (rc != 0) { - printf("ERROR: pthread join failed, error code is %d!\n", rc); - goto ERROROUT; - } - } - - /* Destroy the condition variable. */ - rc = pthread_cond_destroy(&g_td.cond); - if (rc != 0) { - printf("ERROR: pthread condition destroy failed, error code is %d!\n", rc); - goto ERROROUT; - } - return 0; -ERROROUT: - return -1; -} - -/* - * Sample code main function - */ -int main(int argc, char *argv[]) -{ - int rc; - - /* Start the test function. */ - rc = testcase(); - if (rc != 0) { - printf("ERROR: testcase failed!\n"); - } - - return 0; -} -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ -``` - -## FAQs - -None - diff --git a/en/device-dev/kernel/standard-library.md b/en/device-dev/kernel/standard-library.md deleted file mode 100644 index 558eeb7fd7862b35e585fd54f753b4a647a1947d..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/standard-library.md +++ /dev/null @@ -1,7 +0,0 @@ -# Standard Library - -- **[Standard Library](standard-library-0.md)** - -- **[Differences from the Linux Standard Library](differences-from-the-linux-standard-library.md)** - - diff --git a/en/device-dev/kernel/statfs.md b/en/device-dev/kernel/statfs.md deleted file mode 100644 index e823440c5929b4fc2e927264d44faf225dbdb6b6..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/statfs.md +++ /dev/null @@ -1,52 +0,0 @@ -# statfs - -- [Command Function](#section153921657152613) -- [Syntax](#section135391102717) -- [Parameter Description](#section074312314279) -- [Usage](#section133816772712) -- [Example](#section526149182717) - -## Command Function - -This command is used to print information about a file system, such as the type, total size, and available size. - -## Syntax - -statfs \[_directory_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

directory

-

Indicates the file system directory.

-

The file system must exist and support the statfs command. Currently, the following file systems are supported: JFFS2, FAT, and NFS.

-
- -## Usage - -The printed information varies depending on the file system. - -## Example - -The following uses the NFS file system as an example: - -Enter **statfs /nfs**. - -**Figure 1** Output of the statfs command -![](figures/output-of-the-statfs-command.png "output-of-the-statfs-command") - diff --git a/en/device-dev/kernel/su.md b/en/device-dev/kernel/su.md deleted file mode 100644 index 77c7843aff7eae3a28492e61b375231d1ae01efb..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/su.md +++ /dev/null @@ -1,62 +0,0 @@ -# su - -- [Command Function](#section297810431676) -- [Syntax](#section157131147876) -- [Parameter Description](#section04145521671) -- [Usage](#section14615155610719) -- [Example](#section13338150985) -- [Output](#section125021924194613) - -## Command Function - -This command is used to switch the user. - -## Syntax - -su \[_uid_\] \[_gid_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

uid

-

Indicates the ID of the target user.

-
  • Left blank
  • [0, 60000]
-

gid

-

Indicates the ID of the target user group.

-
  • Left blank
  • [0, 60000]
-
- -## Usage - -- The **su** command is used to switch to user **root** by default. The default value for both **uid** and **gid** is **0**. -- If the **uid** and **gid** parameters are specified, this command can switch to the user with the specified **uid** and **gid**. -- If the input parameter is out of the range, an error message is printed. - -## Example - -Enter **su 1000 1000**. - -## Output - -**Figure 1** Switching to the user whose **uid** and **gid** are both **1000** -![](figures/switching-to-the-user-whose-uid-and-gid-are-both-1000.png "switching-to-the-user-whose-uid-and-gid-are-both-1000") - diff --git a/en/device-dev/kernel/swtmr.md b/en/device-dev/kernel/swtmr.md deleted file mode 100644 index 69b4720d91e1e8a1a55141eb3350294de7e438e9..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/swtmr.md +++ /dev/null @@ -1,110 +0,0 @@ -# swtmr - -- [Command Function](#section166171064814) -- [Syntax](#section424011111682) -- [Parameter Description](#section1268410459465) -- [Usage](#section169806213815) -- [Example](#section16676026389) -- [Output](#section1541991614710) - -## Command Function - -This command is used to query information about system software timers. - -## Syntax - -swtmr \[_ID_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

ID

-

Indicates the ID of a software timer.

-

[0, 0xFFFFFFFF]

-
- -## Usage - -- If the parameter is not specified, information about all software timers is displayed. -- If the **ID** parameter is specified, information about the specified software timer is displayed. - -## Example - -Enter **swtmr** and **swtmr 1**. - -## Output - -**Figure 1** Querying information about all software timers -![](figures/querying-information-about-all-software-timers.png "querying-information-about-all-software-timers") - -**Figure 2** Querying information about a specified software timer -![](figures/querying-information-about-a-specified-software-timer.png "querying-information-about-a-specified-software-timer") - -**Table 2** Output description - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

SwTmrID

-

Indicates the ID of the software timer.

-

State

-

Indicates the status of the software timer.

-

The value can be UnUsed, Created, or Ticking.

-

Mode

-

Indicates the mode of the software timer.

-

The value can be Once, Period, or NSD (one-time timer that will not be automatically deleted after the timer expires).

-

Interval

-

Indicates the number of ticks used by the software timer.

-

Count

-

Indicates the number of times that the software timer has been working.

-

Arg

-

Indicates the input parameter.

-

handlerAddr

-

Indicates the callback address.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->- The **ID** value can be in decimal or hexadecimal format. ->- If the **ID** value is within the range of \[0, _Number of current software timers - 1_\], the status of the specified software timer is returned. For other values, an error message is displayed. - diff --git a/en/device-dev/kernel/system-commands.md b/en/device-dev/kernel/system-commands.md deleted file mode 100644 index cb95770023d2c98f56f2a8068b38111e0c628fe6..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/system-commands.md +++ /dev/null @@ -1,47 +0,0 @@ -# System Commands - -- **[cpup](cpup.md)** - -- **[date](date.md)** - -- **[dmesg](dmesg.md)** - -- **[exec](exec.md)** - -- **[free](free.md)** - -- **[help](help.md)** - -- **[hwi](hwi.md)** - -- **[kill](kill.md)** - -- **[log](log.md)** - -- **[memcheck](memcheck.md)** - -- **[oom](oom.md)** - -- **[pmm](pmm.md)** - -- **[reset](reset.md)** - -- **[sem](sem.md)** - -- **[stack](stack.md)** - -- **[su](su.md)** - -- **[swtmr](swtmr.md)** - -- **[systeminfo](systeminfo.md)** - -- **[task](task.md)** - -- **[uname](uname.md)** - -- **[vmm](vmm.md)** - -- **[watch](watch.md)** - - diff --git a/en/device-dev/kernel/systeminfo.md b/en/device-dev/kernel/systeminfo.md deleted file mode 100644 index 058d899cdf7b4d1213763e531237f2c518e91a9f..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/systeminfo.md +++ /dev/null @@ -1,91 +0,0 @@ -# systeminfo - -- [Command Function](#section863016434820) -- [Syntax](#section139791817795) -- [Parameter](#section19472339164813) -- [Usage](#section285522592) -- [Example](#section9471171015105) -- [Output](#section1657011114915) - -## Command Function - -This command is used to display the resource usage of the current OS, including tasks, semaphores, mutexes, queues, and timers. - -## Syntax - -systeminfo - -## Parameter - -None - -## Usage - -None - -## Example - -Enter **systeminfo**. - -## Output - -**Figure 1** Usage of system resources -![](figures/usage-of-system-resources.png "usage-of-system-resources") - -**Table 1** Output description - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Module

-

Indicates the module name.

-

Used

-

Indicates the quantity of currently used resources.

-

Total

-

Indicates the total quantity of available resources.

-

Enabled

-

Indicates whether the module is enabled.

-

Task

-

Indicates the task.

-

Sem

-

Indicates the semaphore.

-

Mutex

-

Indicates the mutex.

-

Queue

-

Indicates the queue.

-

SwTmr

-

Indicates the timer.

-
- diff --git a/en/device-dev/kernel/task.md b/en/device-dev/kernel/task.md deleted file mode 100644 index 4bac34f5c9b33579900118efb6267edae157999d..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/task.md +++ /dev/null @@ -1,125 +0,0 @@ -# task - -- [Command Function](#section0533181714106) -- [Syntax](#section1014412308101) -- [Parameter Description](#section116057158506) -- [Usage](#section2053502951112) -- [Example](#section12629113381116) -- [Output](#section19299103465015) - -## Command Function - -This command is used to query information about processes and threads. - -## Syntax - -task/task -a - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

-a

-

Displays all information.

-

N/A

-
- -## Usage - -If the parameter is not specified, partial task information is printed by default. - -## Example - -Enter **task**. - -## Output - -**Figure 1** Querying partial task information -![](figures/querying-partial-task-information.png "querying-partial-task-information") - -**Table 2** Output description - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

PID

-

Indicates the process ID.

-

PPID

-

Indicates the parent process ID.

-

PGID

-

Indicates the process group ID.

-

UID

-

Indicates the user ID.

-

Status

-

Indicates the current task status.

-

CPUUSE10s

-

Indicates the CPU usage within 10 seconds.

-

PName

-

Indicates the process name.

-

TID

-

Indicates the task ID.

-

StackSize

-

Indicates the size of the task stack.

-

WaterLine

-

Indicates the peak value used by the stack.

-

MEMUSE

-

Indicates the memory usage.

-

TaskName

-

Indicates the task name.

-
- diff --git a/en/device-dev/kernel/telnet.md b/en/device-dev/kernel/telnet.md deleted file mode 100644 index d58498d777835091a5e536dd4db6549daa67e0f1..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/telnet.md +++ /dev/null @@ -1,65 +0,0 @@ -# telnet - -- [Command Function](#section3551830123913) -- [Syntax](#section14897133233918) -- [Parameter Description](#section977718353392) -- [Usage](#section134991538183916) -- [Example](#section1097414426398) -- [Output](#section11846624191310) - -## Command Function - -This command is used to enable or disable the Telnet server service. - -## Syntax - -telnet \[_on | off_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

on

-

Enables the Telnet server service.

-

N/A

-

off

-

Disables the Telnet server service.

-

N/A

-
- -## Usage - -- Before enabling Telnet, ensure that the network driver and network protocol stack have been initialized and the NIC of the board is in the **link up** state. -- Currently, multiple clients \(Telnet + IP\) cannot connect to the development board at the same time. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >Telnet is under debugging and disabled by default. Do not use it in formal products. - - -## Example - -Enter **telnet on**. - -## Output - -**Figure 1** Output of **telnet on** -![](figures/output-of-telnet-on.png "output-of-telnet-on") - diff --git a/en/device-dev/kernel/tftp.md b/en/device-dev/kernel/tftp.md deleted file mode 100644 index c1bbd2eba3924c83503b38a30e0a39d5cc14d20b..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/tftp.md +++ /dev/null @@ -1,87 +0,0 @@ -# tftp - -- [Command Function](#section15142134573911) -- [Syntax](#section20958174917394) -- [Parameter Description](#section576613532395) -- [Usage](#section149795134408) -- [Example](#section148921918114015) -- [Output](#section7872155631313) - -## Command Function - -Trivial File Transfer Protocol \(TFTP\) is a protocol in the TCP/IP protocol suite for transferring files between clients and servers. TFTP provides simple and low-overhead file transfer services. The port number is 69. - -The **tftp** command is used to download files from the TFTP server. - -## Syntax - -./bin/tftp _<-g/-p\>_ _-l_ _\[FullPathLocalFile\] -r \[RemoteFile\] \[Host\]_ - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

-g/-p

-

Indicates the file transfer direction.

-
  • -g: downloads files from the TFTP server.
  • -p: uploads files to the TFTP server.
-

N/A

-

-l FullPathLocalFile

-

Indicates the complete path of a local file.

-

N/A

-

-r RemoteFile

-

Indicates the file name on the server.

-

N/A

-

Host

-

Indicates the server IP address.

-

N/A

-
- -## Usage - -1. Deploy a TFTP server on the server and configure the TFTP server correctly. -2. Use the **tftp** command to upload and download files on the OpenHarmony board. -3. The size of the file to be transferred cannot exceed 32 MB. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >TFTP is under debugging and disabled by default. Do not use it in formal products. - - -## Example - -Download the **out** file from the server. - -## Output - -``` -OHOS # ./bin/tftp -g -l /nfs/out -r out 192.168.1.2 -TFTP transfer finish -``` - -After the **tftp** command is executed, **TFTP transfer finish** is displayed if the file transfer is complete. If the file transfer fails, other information is displayed to help locate the fault. - diff --git a/en/device-dev/kernel/thread.md b/en/device-dev/kernel/thread.md deleted file mode 100644 index 6c6f3cc1c7a37a35c44f5d0414cffbabcfd6d42d..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/thread.md +++ /dev/null @@ -1,702 +0,0 @@ -# Thread - -- [Basic Concepts](#section1179311337405) -- [When to Use](#section44877547404) -- [Available APIs](#section2069477134115) - -## Basic Concepts - -Threads are the minimum running units that compete for system resources. They can use or wait to use CPUs and use system resources such as memory. They run independently from one another. - -Threads in each process of the OpenHarmony kernel run and are scheduled independently. The scheduling of threads in a process is not affected by threads in other processes. - -Threads in the OpenHarmony kernel use the preemptive scheduling mechanism, either round-robin \(RR\) scheduling or First In First Out \(FIFO\) scheduling. - -Threads in the OpenHarmony kernel are assigned 32 priorities, ranging from **0** \(highest\) to **31** \(lowest\). - -A high-priority thread in a process can preempt the resources of a low-priority thread in this process. The low-priority thread can be scheduled only after the high-priority thread is blocked or terminated. - -**A thread may have the following states:** - -- **Init**: The thread is being created. - -- **Ready**: The thread is in the ready list and waits for being scheduled by the CPU. - -- **Running**: The thread is running. - -- **Blocked**: The thread is blocked and suspended. The **Blocked** states include **pending** \(blocked due to lock, event, or semaphore issues\), **suspended** \(active pending\), **delay** \(blocked due to delays\), and **pendtime** \(blocked by waiting timeout of locks, events, or semaphores\). - -- **Exit**: The thread stops running and waits for the parent thread to reclaim its control block resources. - - -**Figure 1** State transition of a thread -![](figures/state-transition-of-a-thread.png "state-transition-of-a-thread") - -**Description of the thread state transition:** - -- Init→Ready: - - When a thread is created, the thread enters the **Init** state to start initialization after obtaining the control block. After the thread is initialized, the thread is inserted into the scheduling queue and therefore enters the **Ready** state. - -- Ready→Running: - - When a thread switchover is triggered, the thread with the highest priority in the ready list is executed and enters the **Running** state. This thread will be deleted from the ready list. - -- Running→Blocked: - - When a running thread is blocked \(for example, is pended, delayed, or reading semaphores\), its state changes from **Running** to **Blocked**. Then, a thread switchover is triggered to run the thread with the highest priority in the ready list. - -- Blocked→Ready: - - After the blocked thread is restored \(the thread is restored, the delay times out, the semaphore reading times out, or the semaphore is read\), the thread is added to the ready list and changes from the **Blocked** state to the **Ready** state. - -- Ready→Blocked: - - A thread may also be blocked \(suspended\) in the **Ready** state. The blocked thread will change from the **Ready** state to the **Blocked** state and is deleted from the ready list. In this case, the thread will not be scheduled until it is restored. - -- Running→Ready: - - After a thread with a higher priority is created or restored, threads will be scheduled. The thread with the highest priority in the ready list will change to the **Running** state. The originally running thread will change from the **Running** state to the **Ready** state and be added to the ready list. - -- Running→Exit: - - When a running thread is terminated, its state changes from **Running** to **Exit**. The thread without the **PTHREAD\_CREATE\_DETACHED** attribute will present the **Exit** state after being terminated. - - -## When to Use - -After a thread is created, it can be scheduled, suspended, restored, and delayed in user space. In addition, you can set and obtain the scheduling priority and scheduling policy of the thread. - -## Available APIs - -The following table describes the APIs provided by the thread management module of the OpenHarmony kernel. - -**Table 1** APIs provided by the thread management module - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Header File

-

Function

-

Description

-

Remarks

-

pthread.h

-

pthread_attr_destroy

-

Destroys a thread attribute object.

-

N/A

-

pthread.h

-

pthread_attr_getinheritsched

-

Obtains inherit scheduler attributes of a thread attribute object.

-

N/A

-

pthread.h

-

pthread_attr_getschedparam

-

Obtains scheduling parameter attributes of a thread attribute object.

-

N/A

-

pthread.h

-

pthread_attr_getschedpolicy

-

Obtains scheduling policy attributes of a thread attribute object.

-

OpenHarmony supports the SCHED_FIFO and SCHED_RR scheduling policies.

-

pthread.h

-

pthread_attr_getstacksize

-

Obtains the stack size of a thread attribute object.

-

N/A

-

pthread.h

-

pthread_attr_init

-

Initializes a thread attribute object.

-

N/A

-

pthread.h

-

pthread_attr_setdetachstate

-

Sets the detach state for a thread attribute object.

-

N/A

-

pthread.h

-

pthread_attr_setinheritsched

-

Sets inherit scheduler attributes for a thread attribute object.

-

N/A

-

pthread.h

-

pthread_attr_setschedparam

-

Sets scheduling parameter attributes for a thread attribute object.

-

A larger value represents a higher priority of the thread in the system.

-

Note: The inheritsched field of the pthread_attr_t attribute must be set to PTHREAD_EXPLICIT_SCHED. Otherwise, the configured thread scheduling priority does not take effect. The default value is PTHREAD_INHERIT_SCHED.

-

pthread.h

-

pthread_attr_setschedpolicy

-

Sets scheduling policy attributes for a thread attribute object.

-

OpenHarmony supports the SCHED_FIFO and SCHED_RR scheduling policies.

-

pthread.h

-

pthread_attr_setstacksize

-

Sets the stack size for a thread attribute object.

-

N/A

-

pthread.h

-

pthread_getattr_np

-

Obtains the attributes of a created thread.

-

N/A

-

pthread.h

-

pthread_cancel

-

Sends a cancellation request to a thread.

-

N/A

-

pthread.h

-

pthread_testcancel

-

Requests delivery of any pending cancellation request.

-

N/A

-

pthread.h

-

pthread_setcanceltype

-

Sets the cancelability type for the calling thread.

-

N/A

-

pthread.h

-

pthread_setcancelstate

-

Sets the cancelability state for the calling thread.

-

N/A

-

pthread.h

-

pthread_create

-

Creates a thread.

-

N/A

-

pthread.h

-

pthread_detach

-

Detaches a thread.

-

N/A

-

pthread.h

-

pthread_equal

-

Compares whether two thread IDs are equal.

-

N/A

-

pthread.h

-

pthread_exit

-

Terminates the calling thread.

-

N/A

-

pthread.h

-

pthread_getschedparam

-

Obtains the scheduling policy and parameters of a thread.

-

OpenHarmony supports the SCHED_FIFO and SCHED_RR scheduling policies.

-

pthread.h

-

pthread_join

-

Waits for a thread to terminate.

-

N/A

-

pthread.h

-

pthread_self

-

Obtains the ID of the calling thread.

-

N/A

-

pthread.h

-

pthread_setschedprio

-

Sets a static scheduling priority for a thread.

-

N/A

-

pthread.h

-

pthread_kill

-

Sends a signal to a thread.

-

N/A

-

pthread.h

-

pthread_once

-

Enables the initialization function to be called only once.

-

N/A

-

pthread.h

-

pthread_atfork

-

Registers a fork handler to be called before and after fork().

-

N/A

-

pthread.h

-

pthread_cleanup_pop

-

Removes the routine at the top of the clean-up handler stack.

-

N/A

-

pthread.h

-

pthread_cleanup_push

-

Pushes the routine to the top of the clean-up handler stack.

-

N/A

-

pthread.h

-

pthread_barrier_destroy

-

Destroys a barrier (an advanced real-time thread).

-

N/A

-

pthread.h

-

pthread_barrier_init

-

Initializes a barrier (an advanced real-time thread).

-

N/A

-

pthread.h

-

pthread_barrier_wait

-

Synchronizes participating threads at a barrier.

-

N/A

-

pthread.h

-

pthread_barrierattr_destroy

-

Destroys a barrier attribute object.

-

N/A

-

pthread.h

-

pthread_barrierattr_init

-

Initializes a barrier attribute object.

-

N/A

-

pthread.h

-

pthread_mutex_destroy

-

Destroys a mutex.

-

N/A

-

pthread.h

-

pthread_mutex_init

-

Initializes a mutex.

-

N/A

-

pthread.h

-

pthread_mutex_lock

-

Locks a mutex.

-

N/A

-

pthread.h

-

pthread_mutex_trylock

-

Attempts to lock a mutex.

-

N/A

-

pthread.h

-

pthread_mutex_unlock

-

Unlocks a mutex.

-

N/A

-

pthread.h

-

pthread_mutexattr_destroy

-

Destroys a mutex attribute object.

-

N/A

-

pthread.h

-

pthread_mutexattr_gettype

-

Obtains the mutex type attribute.

-

N/A

-

pthread.h

-

pthread_mutexattr_init

-

Initializes a mutex attribute object.

-

N/A

-

pthread.h

-

pthread_mutexattr_settype

-

Sets the mutex type attribute.

-

N/A

-

pthread.h

-

pthread_mutex_timedlock

-

Blocks the calling thread to lock a mutex.

-

N/A

-

pthread.h

-

pthread_rwlock_destroy

-

Destroys a read-write lock.

-

N/A

-

pthread.h

-

pthread_rwlock_init

-

Initializes a read-write lock.

-

N/A

-

pthread.h

-

pthread_rwlock_rdlock

-

Applies a read lock to a read-write lock.

-

N/A

-

pthread.h

-

pthread_rwlock_timedrdlock

-

Blocks the calling thread to lock a read-write lock for reading.

-

N/A

-

pthread.h

-

pthread_rwlock_timedwrlock

-

Blocks the calling thread to lock a read-write lock for writing.

-

N/A

-

pthread.h

-

pthread_rwlock_tryrdlock

-

Attempts to apply a read lock to a read-write lock.

-

N/A

-

pthread.h

-

pthread_rwlock_trywrlock

-

Attempts to apply a write lock to a read-write lock.

-

N/A

-

pthread.h

-

pthread_rwlock_unlock

-

Unlocks a read-write lock.

-

N/A

-

pthread.h

-

pthread_rwlock_wrlock

-

Applies a write lock to a read-write lock.

-

N/A

-

pthread.h

-

pthread_rwlockattr_destroy

-

Destroys a read-write lock attribute object.

-

N/A

-

pthread.h

-

pthread_rwlockattr_init

-

Initializes a read-write lock attribute object.

-

N/A

-

pthread.h

-

pthread_cond_broadcast

-

Unblocks all threads that are currently blocked on the condition variable cond.

-

N/A

-

pthread.h

-

pthread_cond_destroy

-

Destroys a condition variable.

-

N/A

-

pthread.h

-

pthread_cond_init

-

Initializes a condition variable.

-

N/A

-

pthread.h

-

pthread_cond_signal

-

Unblocks a thread.

-

N/A

-

pthread.h

-

pthread_cond_timedwait

-

Blocks the calling thread to wait for the condition set by pthread_con_signal() for a period of time specified by ts.

-

N/A

-

pthread.h

-

pthread_cond_wait

-

Blocks the calling thread to wait for the condition set by pthread_con_signal().

-

N/A

-

semaphore.h

-

sem_destroy

-

Destroys a specified anonymous semaphore that is no longer used.

-

N/A

-

semaphore.h

-

sem_getvalue

-

Obtains the count value of a specified semaphore.

-

N/A

-

semaphore.h

-

sem_init

-

Creates and initializes an anonymous semaphore.

-

N/A

-

semaphore.h

-

sem_post

-

Increments the semaphore count by 1.

-

N/A

-

semaphore.h

-

sem_timedwait

-

Obtains the semaphore, with a timeout period specified.

-

N/A

-

semaphore.h

-

sem_trywait

-

Attempts to obtain the semaphore.

-

N/A

-

semaphore.h

-

sem_wait

-

Obtains the semaphore.

-

N/A

-
- diff --git a/en/device-dev/kernel/touch.md b/en/device-dev/kernel/touch.md deleted file mode 100644 index 8b7b21b93d9b80b2511074ab59eadede0855aa7d..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/touch.md +++ /dev/null @@ -1,59 +0,0 @@ -# touch - -- [Command Function](#section17541924112716) -- [Syntax](#section866182711274) -- [Parameter Description](#section268912296270) -- [Usage](#section412093332714) -- [Example](#section414434814354) -- [Output](#section1028419515711) - -## Command Function - -- This command is used to create an empty file in a specified directory. -- If this command is executed to create an existing file, the execution will be successful but the timestamp will not be updated. - -## Syntax - -touch \[_filename_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

filename

-

Indicates the name of the file to be created.

-

N/A

-
- -## Usage - -- The **touch** command creates a read-write empty file. -- The **touch** command creates only one file at a time. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >If you run the **touch** command to create a file in a path storing important system resources, unexpected results such as a system breakdown may occur. For example, if you run the **touch uartdev-0** command in the **/dev** path, the system may stop responding. - - -## Example - -Enter **touch file.c**. - -## Output - -**Figure 1** Creating **file.c** -![](figures/creating-file-c.png "creating-file-c") - diff --git a/en/device-dev/kernel/umount.md b/en/device-dev/kernel/umount.md deleted file mode 100644 index 931ab380dfe501594c0c3a0122b98254682d61df..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/umount.md +++ /dev/null @@ -1,55 +0,0 @@ -# umount - -- [Command Function](#section365125133520) -- [Syntax](#section9615254123512) -- [Parameter Description](#section63446577355) -- [Usage](#section92931509368) -- [Example](#section144311323616) -- [Output](#section360525113611) - -## Command Function - -This command is used to unmount a specified file system. - -## Syntax - -umount \[_dir_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

dir

-

Indicates the directory from which the file system is to be unmounted.

-

Directory to which the file system has been mounted

-
- -## Usage - -By specifying the **dir** parameter in the **unmount** command, you can unmount the specified file system from the directory. - -## Example - -Enter **umount /bin1/vs/sd**. - -## Output - -Unmounting the file system from **/bin1/vs/sd** - -**Figure 1** Unmounting result -![](figures/unmounting-result.png "unmounting-result") - diff --git a/en/device-dev/kernel/uname.md b/en/device-dev/kernel/uname.md deleted file mode 100644 index a66e69e5ca2a6c3b7f2cc700c1d89b7849beec30..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/uname.md +++ /dev/null @@ -1,72 +0,0 @@ -# uname - -- [Command Function](#section107697383115) -- [Syntax](#section162824341116) -- [Usage](#section2652124861114) -- [Example](#section0107995132) -- [Output](#section1215113245511) - -## Command Function - -This command is used to display the name, version creation time, system name, and version information of the current OS. - -## Syntax - -uname \[_-a | -s | -t | -v | --help_\] - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

No parameter

-

Displays the OS name by default.

-

-a

-

Displays all information.

-

-t

-

Displays the time when the version is created.

-

-s

-

Displays the OS name.

-

-v

-

Displays the version information.

-

--help

-

Displays the help information.

-
- -## Usage - -The **uname** command displays the name of the current OS by default. The **uname -a | -t| -s| -v** command displays the name of the in-use OS in the standard output. These parameters are mutually exclusive. - -## Example - -Enter **uname -a**. - -## Output - -Querying system information - -![](figures/en-us_image_0000001052370305.png) - diff --git a/en/device-dev/kernel/vfs.md b/en/device-dev/kernel/vfs.md deleted file mode 100644 index 9b3ea51a6f5eee1b4e968b72ea87052eec067249..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/vfs.md +++ /dev/null @@ -1,171 +0,0 @@ -# VFS - -- [Overview](#section132540468341) -- [Basic Concepts](#section229417111227) -- [Working Principles](#section18114182834215) -- [Important Notes](#section18311145173712) -- [Development Guidelines](#section422619258380) -- [Use Code](#section180311121420) -- [Result Verification](#section16772334714) - -## Overview - -## Basic Concepts - -In essence, VFS is not a real file system. It is an abstract layer on top of a heterogeneous file system and provides you with a unified Unix-like file operation interface. - -Different types of file systems provide different interfaces. If there are multiple types of file systems in the system, different and non-standard interfaces are required for accessing these file systems. The VFS can be introduced as an abstract layer in the system to harmonize the differences between these heterogeneous file systems. In this way, the system does not need to care about the storage medium and file system type at the bottom layer when accessing a file system. The figure below illustrates the relationship between the VFS and file systems. - -**Figure 1** Relationship between the VFS and file systems -![](figures/relationship-between-the-vfs-and-file-systems.png "relationship-between-the-vfs-and-file-systems") - -In the OpenHarmony kernel, the VFS framework is implemented using the tree structure in the memory. Each node in the tree is an **inode** structure. After a device is registered and a file system is mounted, the corresponding node is generated in the tree based on the path. VFS provides the following functions: - -- Node query -- Unified file system invoking \(standard\) - -## Working Principles - -At the VFS layer, standard Unix file operation functions \(such as **open**, **read**, and **write**\) can be used to access different file systems on different media. - -There are three types of **inode** tree nodes in the VFS framework memory: - -- Virtual node: virtual file of the VFS framework, for example, **/usr** and **/usr/bin**, which ensures the continuity of the tree -- Device node: mapping to a device in the **/dev** directory, for example, **/dev/mmcblk0** -- Mount point: used to mount a specific file system, for example, **/vs/sd** or **/mnt** - -**Figure 2** Tree structure of the file system -![](figures/tree-structure-of-the-file-system.png "tree-structure-of-the-file-system") - -## Important Notes - -- For all file systems in VFS, the name of a directory or file can contain a maximum of 255 bytes, and the maximum length of a full path is 259 bytes. Directories or files whose length exceeds the maximum length cannot be created. - -- Currently, only the JFFS2 file system supports complete permission control. - -- After the **inode\_find\(\)** function is called, the number of found **inode** connections is incremented by 1. After the call is complete, the **inode\_release\(\)** function is called to decrease the number of **inode** connections by 1. Therefore, the two functions must be used together. - -- Devices are classified into character devices and block devices. To ensure data security of the file system on a block device, mount the file system and then operate data through the file system interface. - -- The **los\_vfs\_init\(\)** function can be called only once. Multiple calls cause exceptions to the file system. - -- The file names and directory names in all file systems of the OpenHarmony kernel can contain only hyphens \(-\) and underscores \(\_\), but no other special characters. If other special characters are used, unpredictable errors may occur. - -- The OpenHarmony kernel supports the **open\(\)+O\_DIRECTORY** method to obtain directory data. - -- The mount point must be an empty directory. A file system cannot be mounted to the same mount point or to a directory or file under another mount point. Otherwise, the device or system may be damaged. - -- Only one of the **O\_RDWR**, **O\_WRONLY**, and **O\_RDONLY** parameters can be used with **open** to open a file. If two or more of them are used, the file read or write operation is rejected, and the error code **EACCESS** is returned. - -- Before unmounting a file system in the OpenHarmony kernel, ensure that all directories and files are closed. Otherwise, unmounting fails. Forcible unmounting may cause problems such as file system and file damage. - -- Before removing an SD card, ensure that all directories and files are closed and unmounting is performed. Forcible removal may cause problems such as SD card data loss and SD card damage. - - -## Development Guidelines - -**How to Develop** - -It is recommended that driver developers use the VFS framework to register or uninstall devices \(that is, call **register\_driver\(\)** and **register\_blockdriver\(\)** to obtain device nodes\) and the application layer use **open\(\)** and **read\(\)** to operate character device files to invoke drivers. - -**File Descriptor** - -A process can have a maximum of 256 file descriptors \(including file and socket descriptors\). The system can have a maximum of 640 file descriptors, where there can be a maximum of - -- 512 file descriptors - -- 128 socket descriptors - - -**Operations Supported by VFS** - -open, close, read, write, seek, ioctl, fcntl, mmap, sync, dup, dup2, truncate, opendir, closedir, readdir, rewinddir, mount, umount, statfs, unlink, remove, mkdir, rmdir, rename, stat, utime, seek64, fallocate, fallocate64, truncate64, chmod, and chown - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->- Currently, only the interfaces for modifying the attributes of JFFS2 files and VFS device nodes are provided. Each system has its own processing mode for attributes such as read-only. ->- In the OpenHarmony kernel, the attributes do not conflict with each other, and they can be modified randomly. ->- A read-only file or directory in the OpenHarmony kernel cannot be deleted. ->- A read-only file or directory in the OpenHarmony kernel can be renamed. ->- A read-only file cannot be opened in **O\_CREAT**, **O\_TRUNC**, or other modes with the write permission. ->- If the hidden attribute is added to a system file in the OpenHarmony kernel, the system file can be found only on the command line interface \(CLI\) in the Windows OS. \(This system file cannot be viewed regardless of whether **Show hidden files, folders, and drivers** is selected.\) - -## Use Code - -``` -/* The following code shows how to create and traverse directories. */ -#include -#include -#include -#include -#include -#include - -int main() -{ - int ret; - char *dirname = "/test"; - char *pathname0 = "/test/test0"; - char *pathname1 = "/test/test1"; - char *pathname2 = "/test/test2"; - struct dirent **namelist; - int num; - - ret = mkdir(dirname, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", dirname, errno); - goto EXIT; - } - - ret = mkdir(pathname0, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", pathname0, errno); - goto EXIT0; - } - - ret = mkdir(pathname1, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", pathname1, errno); - goto EXIT1; - } - - ret = mkdir(pathname2, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", pathname2, errno); - goto EXIT2; - } - - num = scandir(dirname, &namelist, NULL, alphasort); - if (num < 0) { - perror("scandir"); - } else { - while (num--) { - printf("%s\n", namelist[num]->d_name); - free(namelist[num]); - } - free(namelist); - } - - printf("fs_demo exit.\n"); - return 0; - -EXIT2: - remove(pathname2); -EXIT1: - remove(pathname1); -EXIT0: - remove(pathname0); -EXIT: - remove(dirname); - return 0; -} -``` - -## Result Verification - -``` -OHOS # test2 -test1 -test0 -fs_demo exit. -``` - diff --git a/en/device-dev/kernel/vmm.md b/en/device-dev/kernel/vmm.md deleted file mode 100644 index c5d73aaa832540c3323e3d65516a2fb8b32d603a..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/vmm.md +++ /dev/null @@ -1,158 +0,0 @@ -# vmm - -- [Command Function](#section445335110416) -- [Syntax](#section1795712553416) -- [Parameter Description](#section92544592410) -- [Usage](#section104151141252) -- [Example](#section11545171957) -- [Output](#section075617368542) - -## Command Function - -This command is used to query the virtual memory usage of a process. - -## Syntax - -vmm \[_-a / -h / --help_\] - -vmm \[_pid_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

-a

-

Displays the virtual memory usage of all processes.

-

N/A

-

-h | --help

-

Displays the help information.

-

N/A

-

pid

-

Indicates the ID of the process to query.

-

[0, 63]

-
- -## Usage - -By default, the virtual memory usage of all processes is displayed. - -## Example - -Enter **vmm 3**. - -## Output - -**Figure 1** Virtual memory usage of the process with PID 3 -![](figures/virtual-memory-usage-of-the-process-with-pid-3.png "virtual-memory-usage-of-the-process-with-pid-3") - -**Table 2** Basic process information - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

PID

-

Indicates the process ID.

-

aspace

-

Indicates the address of the virtual memory control block.

-

name

-

Indicates the process name.

-

base

-

Indicates the start address of the virtual memory.

-

size

-

Indicates the size of virtual memory.

-

pages

-

Indicates the number of used physical pages.

-
- -**Table 3** Virtual memory region information - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

region

-

Indicates the address of the control block in the virtual memory region.

-

name

-

Indicates the name of the virtual memory region.

-

base

-

Indicates the start address of the virtual memory region.

-

size

-

Indicates the size of the virtual memory region.

-

mmu_flags

-

Indicates the MMU mapping attribute of the virtual memory region.

-

pages

-

Indicates the number of used physical pages (including the shared memory).

-

pg/ref

-

Indicates the number of used physical pages.

-
- diff --git a/en/device-dev/kernel/watch.md b/en/device-dev/kernel/watch.md deleted file mode 100644 index 1e3211a4c14524d4bb972610b377caf5c21e9d8c..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/watch.md +++ /dev/null @@ -1,98 +0,0 @@ -# watch - -- [Command Function](#section20643141481314) -- [Syntax](#section1075441721316) -- [Parameter Description](#section1472810220135) -- [Usage](#section186772414131) -- [Example](#section4764192791314) -- [Output](#section5791253155517) - -## Command Function - -This command is used to periodically monitor the execution result of a command. - -## Syntax - -watch - -watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Default Value

-

Value Range

-

-c / --count

-

Indicates the number of times that the command is executed.

-

0xFFFFFF

-

(0, 0xFFFFFF]

-

-n / --interval

-

Indicates the interval for periodically running the command, in seconds.

-

1s

-

(0, 0xFFFFFF]

-

-t / -no-title

-

Disables time display on the top.

-

N/A

-

N/A

-

command

-

Indicates the command to be monitored.

-

N/A

-

N/A

-

--over

-

Stops the current command monitoring.

-

N/A

-

N/A

-
- -## Usage - -You can run the **watch --over** command to stop the currently running command monitoring. - -## Example - -Enter **watch -n 2 -c 6 task**. - -## Output - -**Figure 1** **task** command monitoring result -![](figures/task-command-monitoring-result.png "task-command-monitoring-result") - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->In this example, the **task** command has been executed every 2 seconds for six times, and the preceding figure shows the output of the last execution. - diff --git a/en/device-dev/kernel/writeproc.md b/en/device-dev/kernel/writeproc.md deleted file mode 100644 index c7b4c69b6e8b7eac0963d68a62a85f665c5c9c37..0000000000000000000000000000000000000000 --- a/en/device-dev/kernel/writeproc.md +++ /dev/null @@ -1,69 +0,0 @@ -# writeproc - -- [Command Function](#section366714216619) -- [Syntax](#section8833164614615) -- [Parameter Description](#section12809111019453) -- [Usage](#section15935131220717) -- [Example](#section79281818476) -- [Output](#section12742311179) - -## Command Function - -This command is used to write data to a specified proc file system. The proc file system supports the input of string parameters. Each file needs to implement its own method. - -## Syntax - -writeproc <_data_\> \>\> /proc/<_filename_\> - -## Parameter Description - -**Table 1** Parameters - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

data

-

Indicates the string to be entered, which ends with a space. If you need to enter a space, use "" to enclose the space.

-

N/A

-

filename

-

Indicates the proc file to which data is to be passed.

-

N/A

-
- -## Usage - -The proc file implements its own **write** command. After the **writeproc** command is called, the input parameter will be passed to the **write** command. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The proc file system does not support multi-thread access. - -## Example - -Enter **writeproc test \>\> /proc/uptime**. - -## Output - -OHOS \# writeproc test \>\> /proc/uptime - -\[INFO\]write buf is: test - -test \>\> /proc/uptime - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The uptime proc file temporarily implements the **write** command. The **INFO** log is generated by the implemented **test** command. - diff --git a/en/device-dev/overview.md b/en/device-dev/overview.md index 4a5832db5a9e81baccd6d4cbb4bf500c0f5a06a3..d8e511406ec63d9d17428a53e7ad9e60cf1a6448 100644 --- a/en/device-dev/overview.md +++ b/en/device-dev/overview.md @@ -55,42 +55,42 @@ In addition, OpenHarmony provides a series of optional system components that ca

Preparing for your development

- +

Quick start

Getting started with setup, build, burning, debugging, and running of OpenHarmony

-

Getting Started for Mini and Small Systems

+

Getting Started for Mini and Small Systems

Basic capabilities

Using basic capabilities of OpenHarmony

- +

Advanced development

Developing smart devices based on system capabilities

- +

Porting and adaptation

  • Porting and adapting the OpenHarmony to an SoC
  • Porting and adapting the OpenHarmony to a third-party library
- +

Contributing components

Contributing components to OpenHarmony

- +

Reference

@@ -114,9 +114,9 @@ In addition, OpenHarmony provides a series of optional system components that ca -

About OpenHarmony

+

About OpenHarmony

-

Getting familiar with OpenHarmony

+

Getting familiar with OpenHarmony

@@ -125,42 +125,42 @@ In addition, OpenHarmony provides a series of optional system components that ca

Preparing for your development

- +

Quick start

Getting started with setup, build, burning, debugging, and running of OpenHarmony

-

Getting Started for Standard System

+

Getting Started for Standard System

Basic capabilities

-

Using basic capabilities of OpenHarmony

+

Using basic capabilities of OpenHarmony

- +

Advanced development

Developing smart devices based on system capabilities

- +

Porting and adaptation

Porting and adapting the OpenHarmony to a third-party library

-

Third-Party Library Porting Guide

+

Third-Party Library Porting Guide

Contributing components

-

Contributing components to OpenHarmony

+

Contributing components to OpenHarmony

- +

Reference

diff --git a/en/device-dev/porting/Readme-EN.md b/en/device-dev/porting/Readme-EN.md index b4f760b020e0cd05bae29470c24a27d49696bb63..abfe82c4f402c993526c03799b02f8147ef27936 100644 --- a/en/device-dev/porting/Readme-EN.md +++ b/en/device-dev/porting/Readme-EN.md @@ -1,26 +1,33 @@ # Porting Guide -- [Third-Party Library Porting Guide](third-party-library-porting-guide.md) - - [Overview](overview.md) - - [Porting a Library Built Using CMake](porting-a-library-built-using-cmake.md) - - [Porting a Library Built Using Makefile](porting-a-library-built-using-makefile.md) - -- [Third-Party SoC Porting Guide](third-party-soc-porting-guide.md) - - [Porting Preparations](porting-preparations.md) - - [Before You Start](before-you-start.md) - - [Building Adaptation Process](building-adaptation-process.md) - - - [Kernel Porting](kernel-porting.md) - - [Overview](overview-0.md) - - [Basic Kernel Adaptation](basic-kernel-adaptation.md) - - [Kernel Porting Verification](kernel-porting-verification.md) - - - [Board-Level OS Porting](board-level-os-porting.md) - - [Overview](overview-1.md) - - [Board-Level Driver Adaptation](board-level-driver-adaptation.md) - - [Implementation of APIs at the HAL](implementation-of-apis-at-the-hal.md) - - [System Modules](system-modules.md) - - [XTS](xts.md) - - - [FAQ](faq.md) - +- [Third-Party Library Porting Guide](transplant-thirdparty.md) + - [Overview](transplant-thirdparty-overview.md) + - [Porting a Library Built Using CMake](transplant-thirdparty-cmake.md) + - [Porting a Library Built Using Makefile](transplant-thirdparty-makefile.md) +- [Mini System SoC Porting Guide](transplant-minichip.md) + - [Porting Preparations](transplant-chip-prepare.md) + - [Before You Start](transplant-chip-prepare-knows.md) + - [Building Adaptation Process](transplant-chip-prepare-process.md) + - [Kernel Porting](transplant-chip-kernel.md) + - [Overview](transplant-chip-kernel-overview.md) + - [Basic Kernel Adaptation](transplant-chip-kernel-adjustment.md) + - [Kernel Porting Verification](transplant-chip-kernel-verify.md) + - [Board-Level OS Porting](transplant-chip-board.md) + - [Overview](transplant-chip-board-overview.md) + - [Board-Level Driver Adaptation](transplant-chip-board-drive.md) + - [Implementation of APIs at the HAL](transplant-chip-board-hal.md) + - [System Modules](transplant-chip-board-component.md) + - [Third-party Module Adaptation](transplant-chip-board-bundle.md) + - [XTS](transplant-chip-board-xts.md) + - [FAQ](transplant-chip-faqs.md) +- [Small System SoC Porting Guide](transplant-smallchip.md) + - [Porting Preparations](transplant-smallchip-prepare.md) + - [Before You Start](transplant-smallchip-prepare-needs.md) + - [Compilation and Building](transplant-smallchip-prepare-building.md) + - [Kernel Porting](transplant-smallchip-kernel.md) + - [LiteOS Cortex-A](transplant-smallchip-kernel-a.md) + - [Linux Kernel](transplant-smallchip-kernel-linux.md) + - [Driver Porting](transplant-smallchip-drive.md) + - [Overview](transplant-smallchip-drive-des.md) + - [Platform Driver Porting](transplant-smallchip-drive-plat.md) + - [Device Driver Porting](transplant-smallchip-drive-oom.md) \ No newline at end of file diff --git a/en/device-dev/porting/basic-kernel-adaptation.md b/en/device-dev/porting/basic-kernel-adaptation.md deleted file mode 100644 index 8713d4e6c026edc5ec6b37188011427478e5bcfd..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/basic-kernel-adaptation.md +++ /dev/null @@ -1,83 +0,0 @@ -# Basic Kernel Adaptation - -- [Adaptation Process](#section14523241594) -- [Feature Configuration](#section112994366592) - -The LiteOS Cortex-M kernel provides the system initialization process and customized configuration options required for system running. During kernel porting, you must pay attention to the functions related to hardware configuration in the initialization process and understand the kernel configuration options so that the minimum kernel that matches the board can be tailored. - -## Adaptation Process - -Basic adaptation consists of the following steps: - -1. Modify the code in the **startup.S** and corresponding link configuration files. -2. Initialize the serial port and register the handler function for the tick interrupt response in the **main.c** file - -**Figure 1** Startup process - - -![](figures/en-us_image_0000001073943511.png) - -In the **startup.S** file, you must ensure that the entry function \(for example, **reset\_vector**\) of the interrupt vector table is stored in the RAM start address specified by the link configuration files. The link configuration files of IAR, Keil, and GCC projects are **xxx.icf**, **xxx.sct**, and **xxx.ld**, respectively. The startup file provided by the vendor does not need to be modified if the **startup.S** file has initialized the system clock and returned to the **main** function. Otherwise, the preceding functions need to be implemented. - -In the **main.c** file, you need to register the UartInit function used for initializing the serial port and the handler function used for the system tick. - -- The UartInit function initializes the board serial port, and the function name can be defined based on the board. This function is optional. You can determine whether to call it based on whether the board supports the serial port. If the board supports the serial port, this function must enable TX and RX channels of the serial port and set the baud rate. -- You can call **HalTickStart** to set the **OsTickHandler** function for the tick interrupt response. - -For the chip whose interrupt vector table cannot be redirected, you need to disable the **LOSCFG\_PLATFORM\_HWI** macro, and add the **OsTickHandler** function for the tick interrupt response in the **startup.S** file. - -## Feature Configuration - -The **los\_config.h** file defines both complete configuration and default configuration of **liteos\_m**. All configuration items in this file can be customized for different boards as required. - -You can define configuration items in the **device/xxxx/target\_config.h** file of the corresponding board. For other undefined configuration items, default values in the **los\_config.h** file will be used. - -The following table shows some typical configuration items: - -**Table 1** Typical configuration items - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Item

-

Description

-

LOSCFG_BASE_CORE_SWTMR

-

Switch of the software timer. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

-

LOSCFG_BASE_CORE_SWTMR_ALIGN

-

Switch of the time alignment feature, which depends on the switch status of the software timer. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

-

LOSCFG_BASE_IPC_MUX

-

Switch of the mux feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

-

LOSCFG_BASE_IPC_QUEUE

-

Switch of the queue feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

-

LOSCFG_BASE_IPC_SEM

-

Switch of the semaphore feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

-

LOSCFG_PLATFORM_EXC

-

Switch of the exception feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

-

LOSCFG_KERNEL_PRINTF

-

Switch of the print feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

-
- diff --git a/en/device-dev/porting/before-you-start.md b/en/device-dev/porting/before-you-start.md deleted file mode 100644 index 3b25588a1b4e0804d58c6e0055e8165b9384b29b..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/before-you-start.md +++ /dev/null @@ -1,84 +0,0 @@ -# Before You Start - -- [Porting Directory](#section284217487490) -- [Porting Process](#section639315306506) -- [Porting Specifications](#section187870185219) - -This document provides basic guidance for OpenHarmony developers and system on a chip \(SoC\) or module vendors to port OpenHarmony to typical chip architectures, such as the cortex-M and RISC-V series. Currently, the Bluetooth service is not supported. Due to the complexity of the OpenHarmony project, this document is subject to update as the version and APIs change. - -This guide is intended for readers who have experience in developing embedded systems. Therefore, it mainly describes operations and key points during platform porting instead of basic introduction to the OS. - -## Porting Directory - -The implementation of the OpenHarmony project directories and functions relies on the OS itself. If no enhancement for a complex feature is involved, you only need to focus on the directories described in the following table. - -**Table 1** Key directories in the porting process - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

/build/lite

-

Basic building framework for OpenHarmony

-

/kernel/liteos_m

-

Basic kernel. The implementation related to the chip architecture is in the arch directory.

-

/device

-

Board-level code implementation, which is provided by third-party vendors based on the OpenHarmony specifications. For detailed structure about the device directory and porting process, see Board-Level OS Porting.

-

/vendor

-

Product-level implementation, which is contributed by Huawei or product vendors.

-
- -The **device** directory is in the internal structure of **device/\{Chip solution vendor\}/\{Development board\}**. The following uses Hisilicon **hispark\_taurus** as an example: - -``` -device -└── hisilicon # Name of the chip solution vendor - ├── common # Common part of the chip solution development board - └── hispark_taurus # Name of the development board - ├── BUILD.gn # Entry to building the development board - ├── hals # OS hardware adaptation of the chip solution vendor - ├── linux # Linux version - │ └── config.gni # Configurations of the building toolchain and building options for the Linux version - └── liteos_a # LiteOS Cortex-A version - └── config.gni # Configurations of the building toolchain and building options for the LiteOS Cortex-A version -``` - -The **vendor** directory is in the internal structure of **vendor/\{Product solution vendor\}/\{Product name\}**. The following uses Huawei Wi-Fi IoT product as an example: - -``` -vendor # Product solution vendor -└── huawei # Name of the product solution vendor - └── wifiiot # Product name - ├── hals # OS adaptation of the product solution vendor - ├── BUILD.gn # Product building script - └── config.json # Product configuration file -``` - -## Porting Process - -The **device** directory of OpenHarmony is the adaptation directory for the basic SoC. You can skip the porting process and directly develop system applications if complete SoC adaptation code is already available in the directory. If there is no corresponding SoC porting implementation in the directory, complete the porting process by following the instructions provided in this document. The following figure shows the process of porting OpenHarmony to a third-party SoC. - -**Figure 1** Key steps for SoC porting -![](figures/key-steps-for-soc-porting.png "key-steps-for-soc-porting") - -## Porting Specifications - -- The porting must comply with the basic OpenHarmony principles described in [Contribution](https://gitee.com/openharmony/docs/blob/master/en/contribute/contribution.md). -- The code required for third-party SoC adaptation is stored in the **device**, **vendor**, and **arch** directories. Naming and usage of these directories must comply with specified naming and usage specifications. For details, see [Directory Specifications](overview-0.md) and [Board-Level Directory Specifications](overview-1.md#section6204129143013). - diff --git a/en/device-dev/porting/board-level-os-porting.md b/en/device-dev/porting/board-level-os-porting.md deleted file mode 100644 index e70229d4a090f88acacea19f58ff606e8395bc7b..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/board-level-os-porting.md +++ /dev/null @@ -1,13 +0,0 @@ -# Board-Level OS Porting - -- **[Overview](overview-1.md)** - -- **[Board-Level Driver Adaptation](board-level-driver-adaptation.md)** - -- **[Implementation of APIs at the HAL](implementation-of-apis-at-the-hal.md)** - -- **[System Modules](system-modules.md)** - -- **[XTS](xts.md)** - - diff --git a/en/device-dev/porting/figures/en-us_image_0000001072304191.png b/en/device-dev/porting/figure/en-us_image_0000001072304191.png similarity index 100% rename from en/device-dev/porting/figures/en-us_image_0000001072304191.png rename to en/device-dev/porting/figure/en-us_image_0000001072304191.png diff --git a/en/device-dev/porting/figures/en-us_image_0000001073943511.png b/en/device-dev/porting/figure/en-us_image_0000001073943511.png similarity index 100% rename from en/device-dev/porting/figures/en-us_image_0000001073943511.png rename to en/device-dev/porting/figure/en-us_image_0000001073943511.png diff --git a/en/device-dev/porting/figure/en-us_image_0000001126198996.png b/en/device-dev/porting/figure/en-us_image_0000001126198996.png new file mode 100644 index 0000000000000000000000000000000000000000..57e7e35c2eb4d0bcafecd07c32639ca0e8b17b6e Binary files /dev/null and b/en/device-dev/porting/figure/en-us_image_0000001126198996.png differ diff --git a/en/device-dev/porting/figure/en-us_image_0000001126354076.png b/en/device-dev/porting/figure/en-us_image_0000001126354076.png new file mode 100644 index 0000000000000000000000000000000000000000..c6cae9cb23b2d1767b415ba1fa668349e329034b Binary files /dev/null and b/en/device-dev/porting/figure/en-us_image_0000001126354076.png differ diff --git a/en/device-dev/porting/figure/en-us_image_0000001126358814.png b/en/device-dev/porting/figure/en-us_image_0000001126358814.png new file mode 100644 index 0000000000000000000000000000000000000000..39c6cb96611a7ced5e17bbeee96ac77ba5c1bf58 Binary files /dev/null and b/en/device-dev/porting/figure/en-us_image_0000001126358814.png differ diff --git a/en/device-dev/porting/figure/en-us_image_0000001172273945.jpg b/en/device-dev/porting/figure/en-us_image_0000001172273945.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a1e7f8b695bebf395ea6cfa0aed55495c4896118 Binary files /dev/null and b/en/device-dev/porting/figure/en-us_image_0000001172273945.jpg differ diff --git a/en/device-dev/porting/figure/en-us_image_0000001172393865.jpg b/en/device-dev/porting/figure/en-us_image_0000001172393865.jpg new file mode 100644 index 0000000000000000000000000000000000000000..efb1e17b00d37b072a3032678144984e2e13b2d6 Binary files /dev/null and b/en/device-dev/porting/figure/en-us_image_0000001172393865.jpg differ diff --git a/en/device-dev/porting/figure/hdf_wifi.png b/en/device-dev/porting/figure/hdf_wifi.png new file mode 100644 index 0000000000000000000000000000000000000000..4a0441de4621bd558383ba1323d21c793bcf192a Binary files /dev/null and b/en/device-dev/porting/figure/hdf_wifi.png differ diff --git a/en/device-dev/porting/figure/kernel-startup-framework.jpg b/en/device-dev/porting/figure/kernel-startup-framework.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ac1271b5dcd4fc06199df236a4741a71d8040eb4 Binary files /dev/null and b/en/device-dev/porting/figure/kernel-startup-framework.jpg differ diff --git a/en/device-dev/porting/figures/key-steps-for-soc-porting.png b/en/device-dev/porting/figure/key-steps-for-soc-porting.png similarity index 100% rename from en/device-dev/porting/figures/key-steps-for-soc-porting.png rename to en/device-dev/porting/figure/key-steps-for-soc-porting.png diff --git a/en/device-dev/porting/figures/process-for-board-level-driver-adaptation.png b/en/device-dev/porting/figure/process-for-board-level-driver-adaptation.png similarity index 100% rename from en/device-dev/porting/figures/process-for-board-level-driver-adaptation.png rename to en/device-dev/porting/figure/process-for-board-level-driver-adaptation.png diff --git a/en/device-dev/porting/figures/successful-startup-of-openharmony.png b/en/device-dev/porting/figure/successful-startup-of-openharmony.png similarity index 100% rename from en/device-dev/porting/figures/successful-startup-of-openharmony.png rename to en/device-dev/porting/figure/successful-startup-of-openharmony.png diff --git "a/en/device-dev/porting/figure/\345\210\206\347\261\273.png" "b/en/device-dev/porting/figure/\345\210\206\347\261\273.png" new file mode 100644 index 0000000000000000000000000000000000000000..7edac54ec2fcd1fc93330d47acb2d44fceef2710 Binary files /dev/null and "b/en/device-dev/porting/figure/\345\210\206\347\261\273.png" differ diff --git a/en/device-dev/porting/kernel-porting-verification.md b/en/device-dev/porting/kernel-porting-verification.md deleted file mode 100644 index b00b1cb1556201cb15da99b87cf559a9cda798f3..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/kernel-porting-verification.md +++ /dev/null @@ -1,59 +0,0 @@ -# Kernel Porting Verification - -Add the sample program file **main.c** to the **device** directory of the project and compile the file. After LOS\_KernelInit is complete, this sample program will create two tasks that loop the **LOS\_TaskDelay** function and print the log information cyclically. In this way, you can check whether system scheduling and the clock work properly. - -``` -VOID TaskSampleEntry2(VOID) // Entry function of task 2 -{ - while(1) { - LOS_TaskDelay(10000); - printf("taskSampleEntry2 running...\n"); - } -} - -VOID TaskSampleEntry1(VOID) // Entry function of task 1 -{ - while(1) { - LOS_TaskDelay(2000); - printf("taskSampleEntry1 running...\n"); - } -} - -UINT32 TaskSample(VOID) -{ - UINT32 uwRet; - UINT32 taskID1,taskID2; - TSK_INIT_PARAM_S stTask1={0}; - stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1; - stTask1.uwStackSize = 0X1000; - stTask1.pcName = "taskSampleEntry1"; - stTask1.usTaskPrio = 6; // Set the priority of stTask1, which is different from that of stTask2. - uwRet = LOS_TaskCreate(&taskID1, &stTask1); - - stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2; - stTask1.uwStackSize = 0X1000; - stTask1.pcName = "taskSampleEntry2"; - stTask1.usTaskPrio = 7; - uwRet = LOS_TaskCreate(&taskID2, &stTask1); - - return LOS_OK; -} - -LITE_OS_SEC_TEXT_INIT int main(void) -{ - UINT32 ret; - UartInit(); // Configure the hardware serial port and output the debug log over this serial port. The actual function name varies with the board. - printf("\n\rhello world!!\n\r"); - ret = LOS_KernelInit(); - TaskSample(); - if (ret == LOS_OK) { - LOS_Start(); // Start system scheduling, execute stTask1/stTask2 cyclically, and output task logs over the serial port. - } - while (1) { - __asm volatile("wfi"); - } -} -``` - -If the first task is executed properly, the core process of the minimum system is valid. Due to the XTS framework's dependency on the link scripts of Utils and Bootstrap as well as the building framework, testing the kernel by executing the XTS is not supported. You can test whether the minimum system is completely ported in [XTS](xts.md). - diff --git a/en/device-dev/porting/kernel-porting.md b/en/device-dev/porting/kernel-porting.md deleted file mode 100644 index ce6f9d8c039b649b86657569141b682be86533b4..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/kernel-porting.md +++ /dev/null @@ -1,9 +0,0 @@ -# Kernel Porting - -- **[Overview](overview-0.md)** - -- **[Basic Kernel Adaptation](basic-kernel-adaptation.md)** - -- **[Kernel Porting Verification](kernel-porting-verification.md)** - - diff --git a/en/device-dev/porting/overview-0.md b/en/device-dev/porting/overview-0.md deleted file mode 100644 index 46e8c9491f46f61dcce2ac50e2c627349976e12d..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/overview-0.md +++ /dev/null @@ -1,64 +0,0 @@ -# Overview - -- [Porting Scenario](#section93781277367) -- [Directory Specifications](#section18127744153119) -- [Chip Architecture Adaptation](#section137431650339) - -## Porting Scenario - -The chip architecture adaptation process is optional. If the particular chip architecture is supported in the **liteos\_m/kernel/arch** directory, you can directly implement the board adaptation. Otherwise, chip architecture porting is required. - -## Directory Specifications - -The kernel used by module chips is LiteOS Cortex-M, which consists of four modules, namely kernel abstraction layer \(KAL\), components, kernel, and utils. - -- **KAL**: provides APIs exposed externally and depends on the components and kernel modules. -- **Components**: is pluggable and relies on the kernel module. - -- **Kernel**: stores hardware-related code in the **arch** directory and other code. The implementation of kernel function sets \(such as task and sem\), for example, task context switching and atomic operations, depends on the hardware-related code in the **arch** directory. -- **Utils**: functions as a basic code block where other modules rely. - -**Figure 1** Architecture of the LiteOS Cortex-M kernel - - -![](figures/en-us_image_0000001072304191.png) - -The directory structure of the kernel is described as follows: - -``` -. -├── components --- Components available for porting and header files exposed externally -├── kal --- APIs exposed externally, including CMSIS APIs and part of POSIX APIs -├── kernel --- Code for defining the minimum kernel function set -│ ├── arch --- Code of the kernel instruction architecture layer -│ │ ├── arm --- Code of the ARM32 architecture -│ │ │ ├── cortex-m3 --- Code of the Cortex-M3 architecture -│ │ │ │ ├── iar --- Implementation of the IAR toolchain -│ │ │ │ ├── keil --- Implementation of the Keil toolchain -│ │ │ │ └── xxx --- Implementation of the particular toolchain -│ │ │ └── cortex-m4 --- Code of the Cortex-M4 architecture -│ │ │ ├── iar --- Implementation of the IAR toolchain -│ │ │ ├── keil --- Implementation of the Keil toolchain -│ │ │ └── xxx --- Implementation of the particular toolchain -│ │ ├── include --- Header files that declare the APIs required, kernel-independent -│ │ └── risc-v --- RISK_V architecture -│ │ └── gcc --- Implementation of the IAR toolchain -│ ├── include --- Code for defining the minimum kernel function set -│ └── src --- Code for implementing the minimum kernel function set -└──utils --- Basic code -``` - -## Chip Architecture Adaptation - -As shown in the [Directory Specifications](#section18127744153119), the **arch/include** directory defines the functions that need to be implemented on the common chip architecture. The code related to the chip architecture contains assembly code, which varies based on building toolchains. Therefore, the code for adapting to different toolchains \(for example, IAR, Keil, GCC, etc.\) must be implemented in a specific chip architecture. - -The **arch/include** directory defines common files and functions. All functions in this directory need to be implemented to adapt to a newly added architecture. For details, refer to the following header files. - -``` -los_arch.h --- Defines the functions required for initializing the chip architecture. -los_atomic.h --- Defines the atomic operation functions required by the chip architecture. -los_context.h --- Defines the context functions required by the chip architecture. -los_interrupt.h --- Defines the interrupt and exception functions required by the chip architecture. -los_timer.h --- Defines the timer functions required by the chip architecture. -``` - diff --git a/en/device-dev/porting/overview-1.md b/en/device-dev/porting/overview-1.md deleted file mode 100644 index a7332baa3775232b85193c40ab6984c32aa54b96..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/overview-1.md +++ /dev/null @@ -1,57 +0,0 @@ -# Overview - -- [Porting Process](#section1283115812294) -- [Board-Level Directory Specifications](#section6204129143013) - -## Porting Process - -After the minimum system is ported, you can port the board-level system by: - -1. Implementing the board-level driver adaptation -2. Completing the implementation at the HAL -3. Implementing the XTS -4. Verifying service functions - -**Figure 1** Process for board-level driver adaptation -![](figures/process-for-board-level-driver-adaptation.png "process-for-board-level-driver-adaptation") - -## Board-Level Directory Specifications - -For details about board-level system building adaptation, see [Compilation and Building Subsystem](building-adaptation-process.md). The board-related drivers, software development software kits \(SDKs\), directories, and HAL implementation are stored in the **device** directory. The directory structure and its description are as follows: - -``` -. -├── device --- Sample board -│ └── xxx --- -│ └── xxx --- . This directory contains the demo of the LiteOS Cortex-M kernel, which can run properly. -│ ├── BUILD.gn --- Building configuration file of the board -│ ├── board --- Specific implementation of the board (Optional. If a product-level demo is provided, implementation at the application layer is stored in this directory.) -│ ├── liteos_m --- LiteOS Cortex-M kernel to use based on the kernel_type in the BUILD.gn file -│ │ └── config.gni --- Building options -│ ├── libraries --- Board-level SDK -│ │ └── include --- SDK-provided header files that are exposed externally -│ │ └── ... --- binary or source files -│ ├── main.c --- main function entry (Product level configuration is used if the same definition exists at the product level.) -│ ├── target_config.h --- Board-level kernel configuration -│ ├── project --- Board-level project configuration file (Product-level configuration is used if the same definition exists at the product level.) -│ └── adapter --- HAL interfaces (Optional) -│ └── hals -│ ├── communication -│ │ └── wifi_lite -│ │ ├── ... -│ └── iot_hardware -│ ├── upgrade -│ ├── utils -│ └── wifiiot_lite -├── vendor --- End-to-end feature product sample of OpenHarmony -│ └── huawei --- Vendor name -│ └── wifiiot --- Feature product -│ ├── app -│ │ └── main.c --- main function entry of the product -│ ├── project --- Project configuration file -│ ├── BUILD.gn --- Project building entry -│ └── config.json --- Building configuration file of the product and components used for product configuration -└── out --- Output directory during the building - ├── ... --- .bin files generated during board/product building -``` - diff --git a/en/device-dev/porting/porting-a-library-built-using-cmake.md b/en/device-dev/porting/porting-a-library-built-using-cmake.md deleted file mode 100644 index a7d399c983a5841878aa59c6c4bd01dec39d4135..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/porting-a-library-built-using-cmake.md +++ /dev/null @@ -1,435 +0,0 @@ -# Porting a Library Built Using CMake - -- [Source Code Acquisition](#section1771132116245) -- [Porting Guidelines](#section9737174410328) -- [Cross-Compilation](#section38205577332) - - [Compilation Reference](#section1088111263418) - - [Cross-Compilation Settings](#section8168182883515) - -- [Library Test](#section6686144293611) -- [Adding the Compiled double-conversion Library to the OpenHarmony Project](#section1651053153715) - -The following shows how to port the double-conversion library. - -## Source Code Acquisition - -Acquire the source code of double-conversion from [https://github.com/google/double-conversion](https://github.com/google/double-conversion). The following table lists the directory structure. - -**Table 1** Directory structure of the source code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

double-conversion/cmake/

-

Template used for building with CMake

-

double-conversion/double-conversion/

-

Directory of source files

-

double-conversion/msvc/

-

-

-

double-conversion/test/

-

Source files of the test cases

-

double-conversion/.gitignore

-

-

-

double-conversion/AUTHORS

-

-

-

double-conversion/BUILD

-

-

-

double-conversion/CMakeLists.txt

-

Top-level file used for building with CMake

-

double-conversion/COPYING

-

-

-

double-conversion/Changelog

-

-

-

double-conversion/LICENSE

-

-

-

double-conversion/Makefile

-

-

-

double-conversion/README.md

-

-

-

double-conversion/SConstruct

-

-

-

double-conversion/WORKSPACE

-

-

-
- -## Porting Guidelines - -Cross-compile the double-conversion library by modifying the toolchain to generate executable files for the OpenHarmony platform and then add these files to the OpenHarmony project by invoking CMake via GN. - -## Cross-Compilation - -### Compilation Reference - -The [README.md](https://github.com/google/double-conversion/blob/master/README.md) file in the code repository details the procedures for compiling the double-conversion library using CMake as well as the testing methods. This document focuses on the building, compilation, and testing of the library. If you have any questions during library porting, refer to the **README.md** file. For porting of other third-party libraries that can be independently built with CMake, you can refer to the compilation guides provided by the libraries. - -### Cross-Compilation Settings - -The following steps show how to configure and modify the toolchains for cross-compiling the libraries built using CMake to compile executable files for the OpenHarmony platform. - -1. Configure the toolchains. - - Add configuration of the clang toolchains to the top-level file **CMakeLists.txt** listed in [Table 1](#table824211132418). - - ``` - set(CMAKE_CROSSCOMPILING TRUE) - set(CMAKE_SYSTEM_NAME Generic) - set(CMAKE_CXX_COMPILER_ID Clang) - set(CMAKE_TOOLCHAIN_PREFIX llvm-) - # Specify the C compiler (ensure that the path of the toolchain has been added to the PATH environment variable) and its flags. To perform cross-compilation using clang, the --target flag must be specified. - set(CMAKE_C_COMPILER clang) - set(CMAKE_C_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") - # Specify the C++ compiler (ensure that the path of the toolchain has been added to the PATH environment variable) and its flags. To perform cross-compilation, the --target flag must be specified. - set(CMAKE_CXX_COMPILER clang++) - set(CMAKE_CXX_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") - # Specify the linker and its flags. --target and --sysroot must be specified. You can specify OHOS_ROOT_PATH via the suffix parameter of the cmake command. - set(MY_LINK_FLAGS "--target=arm-liteos --sysroot=${OHOS_SYSROOT_PATH}") - set(CMAKE_LINKER clang) - set(CMAKE_CXX_LINKER clang++) - set(CMAKE_C_LINKER clang) - set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINKER} - ${MY_LINK_FLAGS} -o ") - set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINKER} - ${MY_LINK_FLAGS} -o ") - # Specify the path for searching chained libraries. - set(CMAKE_SYSROOT ${OHOS_SYSROOT_PATH}) - ``` - -2. Perform the compilation. - - Run a Linux command to enter the directory \(listed in [Table 1](#table824211132418)\) for storing double-conversion source files and then run the following commands: - - ``` - mkdir build && cd build - cmake .. -DBUILD_TESTING=ON -DOHOS_SYSROOT_PATH="..." - make -j - ``` - - **OHOS\_SYSROOT\_PATH** specifies the absolute path where **sysroot** is located. Taking OpenHarmony for example, set **OHOS\_SYSROOT\_PATH** to the absolute path of **openHarmony/prebuilts/lite/sysroot**. - -3. View the result. - - After step 2 is complete, a static library file and test cases are generated in the **build** directory. - - **Table 2** Directory structure of compiled files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

double-conversion/build/libdouble-conversion.a

-

Static library file

-

double-conversion/build/test/

-

Test cases and CMake cache files

-

double-conversion/build/CMakeCache.txt

-

Cache files during CMake building

-

double-conversion/build/CMakeFiles/

-

-

-

double-conversion/build/cmake_install.cmake

-

-

-

double-conversion/build/CTestTestfile.cmake

-

-

-

double-conversion/build/DartConfiguration.tcl

-

-

-

double-conversion/build/generated/

-

-

-

double-conversion/build/Makefile

-

-

-

double-conversion/build/Testing/

-

-

-
- - -## Library Test - -1. Set up the OpenHarmony environment. - - Using Hi3518EV300 as an example, compile the OpenHarmony image and burn it to the development board. For details, see [Developing the First Example Program Running on Hi3518](https://gitee.com/openharmony/docs/blob/master/docs-en/quick-start/developing-the-first-example-program-running-on-hi3518.md). - - The following screen is displayed after a successful login to the OS. - - **Figure 1** Successful startup of OpenHarmony - ![](figures/successful-startup-of-openharmony.png "successful-startup-of-openharmony") - -2. Mount the **nfs** directory and put the executable file **cctest** into the **test** directory \(listed in [Table 2](#table1452412391911)\) to the **nfs** directory. -3. Perform the test cases. - - If the double-conversion library is not cross-compiled, you can execute the test cases by running the **make test** command and obtain the result via CMake. However, this command is not applicable to the library after cross-compilation. This way, you can perform the test cases by executing the generated test case files. - - - After the **nfs** directory is successfully mounted, run the following command to list all items in the test cases: - - ``` - cd nfs - ./cctest --list - ``` - - Some items are as follows: - - ``` - test-bignum/Assign< - test-bignum/ShiftLeft< - test-bignum/AddUInt64< - test-bignum/AddBignum< - test-bignum/SubtractBignum< - test-bignum/MultiplyUInt32< - test-bignum/MultiplyUInt64< - test-bignum/MultiplyPowerOfTen< - test-bignum/DivideModuloIntBignum< - test-bignum/Compare< - test-bignum/PlusCompare< - test-bignum/Square< - test-bignum/AssignPowerUInt16< - test-bignum-dtoa/BignumDtoaVariousDoubles< - test-bignum-dtoa/BignumDtoaShortestVariousFloats< - test-bignum-dtoa/BignumDtoaGayShortest< - test-bignum-dtoa/BignumDtoaGayShortestSingle< - test-bignum-dtoa/BignumDtoaGayFixed< - test-bignum-dtoa/BignumDtoaGayPrecision< - test-conversions/DoubleToShortest< - test-conversions/DoubleToShortestSingle< - ... - ``` - - - Run the following command to test **test-bignum**: - - ``` - ./cctest test-bignum - ``` - - The test is passed if the following information is displayed: - - ``` - Ran 13 tests. - ``` - - -## Adding the Compiled double-conversion Library to the OpenHarmony Project - -1. Copy the double-conversion library to the OpenHarmony project. - - Copy this library that can be cross-compiled to the **third\_party** directory of OpenHarmony. To avoid modifying the **BUILD.gn** file in the directory of the third-party library to be ported, add a directory to store adaptation files, including **BUILD.gn**, **build\_thirdparty.py**, and **config.gni**, for converting GN to CMake building. - - **Table 3** Directory structure of the ported library - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

openHarmony/third_party/double-conversion/BUILD.gn

-

GN file for adding the third-party library to the OpenHarmony project

-

openHarmony/third_party/double-conversion/build_thirdpaty.py

-

Script file for GN to call the shell command to convert compilation from GN to CMake.

-

openHarmony/third_party/double-conversion/config.gni

-

Third-party library compilation configuration file, which can be modified to determine whether the test cases will be used during the building

-

openHarmony/third_party/double-conversion/double-conversion/

-

Directory of the third-party library to be ported

-
- -2. Add the GN file to the CMake adaptation file. - - - The following shows the implementation for building using the newly added **BUILD.gn** file. For other third-party libraries that can be independently compiled using CMake, you only need to change the target paths when porting them to OpenHarmony. - - ``` - import("config.gni") - group("double-conversion") { - if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - deps = [":make"] - } - } - if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - action("make") { - script = "//third_party/double-conversion/build_thirdparty.py" - outputs = ["$root_out_dir/log_dc.txt"] - exec_path = rebase_path(rebase_path("./build", ohos_third_party_dir)) - command = "rm * .* -rf && $CMAKE_TOOLS_PATH/cmake .. $CMAKE_FLAG $CMAKE_TOOLCHAIN_FLAG && make -j" - args = [ - "--path=$exec_path", - "--command=${command}" - ] - } - } - ``` - - - The newly added **config.gni** file is used to configure the library in the following example implementation. For other third-party libraries that can be independently compiled using CMake, you only need to change the configuration of **CMAKE\_FLAG** when porting them to OpenHarmony. - - ``` - #CMAKE_FLAG: config compile feature - CMAKE_FLAG = "-DBUILD_TESTING=ON -DCMAKE_CXX_STANDARD=11" - - #toolchain: follow up-layer, depend on $ohos_build_compiler - if (ohos_build_compiler == "clang") { - CMAKE_TOOLCHAIN_FLAG = "-DOHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" - } else { - CMAKE_TOOLCHAIN_FLAG = "" - } - - #CMake tools path,no need setting if this path already joined to $PATH. - CMAKE_TOOLS_PATH = "setting CMake tools path..." - ``` - - - The following shows the implementation of the newly added **build\_thirdparty.py** file. For other third-party libraries that can be independently compiled using CMake, you can port them to OpenHarmony without modifications. - - ``` - import os - import sys - from subprocess import Popen - import argparse - import shlex - - def cmd_exec(command): - cmd = shlex.split(command) - proc = Popen(cmd) - proc.wait() - ret_code = proc.returncode - if ret_code != 0: - raise Exception("{} failed, return code is {}".format(cmd, ret_code)) - - def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--path', help='Build path.') - parser.add_argument('--command', help='Build command.') - parser.add_argument('--enable', help='enable python.', nargs='*') - args = parser.parse_args() - - if args.enable: - if args.enable[0] == 'false': - return - - if args.path: - curr_dir = os.getcwd() - os.chdir(args.path) - if args.command: - if '&&' in args.command: - command = args.command.split('&&') - for data in command: - cmd_exec(data) - else: - cmd_exec(args.command) - os.chdir(curr_dir) - - if __name__ == '__main__': - sys.exit(main()) - ``` - - - Add a configuration item in the configuration file to control compiling of the library. By default, library compilation is disabled. - - For example, add the following configuration to the **//build/lite/ohos\_var.gni** file: - - ``` - declare_args() { - ohos_build_thirdparty_migrated_from_fuchisa = true - } - ``` - -3. Build the library. - - - Manual building - - Execute the following command: - - ``` - hb build -T //third_party/double-conversion:double-conversion - ``` - - If the compilation is successful, a static library file and test cases will be generated in the [build](#li15717101715249) directory. - - diff --git a/en/device-dev/porting/porting-a-library-built-using-makefile.md b/en/device-dev/porting/porting-a-library-built-using-makefile.md deleted file mode 100644 index ed7a88af264885f96282dd63ae5827083dfc8a49..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/porting-a-library-built-using-makefile.md +++ /dev/null @@ -1,309 +0,0 @@ -# Porting a Library Built Using Makefile - -- [Source Code Acquisition](#section114115321416) -- [Cross-Compilation Settings](#section81263255384) -- [Library Test](#section1830015913391) -- [Adding the Compiled yxml Library to the OpenHarmony Project](#section1898016213406) - -The following shows how to port the yxml library. - -## Source Code Acquisition - -Acquire the source code of yxml from [the open-source repository](https://github.com/getdnsapi/yxml). The following table lists the directory structure. - -**Table 1** Directory structure of the source code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

yxml/bench/

-

Benchmark-related code

-

yxml/test/

-

Input and output files as well as scripts of the test cases

-

yxml/Makefile

-

File for organizing compilation

-

yxml/.gitattributes

-

-

-

yxml/.gitignore

-

-

-

yxml/COPYING

-

-

-

yxml/yxml.c

-

-

-

yxml/yxml.c.in

-

-

-

yxml/yxml-gen.pl

-

-

-

yxml/yxml.h

-

-

-

yxml/yxml.md

-

-

-

yxml/yxml-states

-

-

-
- -## Cross-Compilation Settings - -The following steps show how to configure and modify the toolchains for cross-compiling the libraries built using CMake to compile executable files for the OpenHarmony platform. - -1. Configure the toolchains. - - Replace the original configuration of MakeFile \(listed in [Table 1](#table16520154171813)\) in the root directory of the yxml library with the following clang toolchains configuration. - - clang toolchains configuration: - - ``` - # Set the cross-compilation toolchain and ensure that the path of the toolchain has been added to the PATH environment variable. - CC:=clang - AR:=llvm-ar - # The --target and --sysroot flags must be specified. - CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g --target=arm-liteos -march=armv7-a --sysroot=$(OHOS_ROOT_PATH)prebuilts/lite/sysroot - ``` - - Original configuration: - - ``` - CC:=gcc - AR:=ar - CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g - ``` - -2. Perform the compilation. - - Run a Linux command to enter the directory \(listed in [Table 1](#table16520154171813)\) for storing yxml source files and then run the following command: - - ``` - make test OHOS_SYSROOT_PATH=... - ``` - - **OHOS\_SYSROOT\_PATH** specifies the absolute path of the directory where **sysroot** is located. Taking OpenHarmony for example, set **OHOS\_SYSROOT\_PATH** to the absolute path of **prebuilts/lite/sysroot/**. - -3. View the result. - - After step 2 is complete, a static library file and test case are generated in the **out** directory of the yxml library. - - **Table 2** Directory structure of compiled files - - - - - - - - - - - - - -

Directory

-

Description

-

openHarmony/third_party/yxml/yxml/out/lib/

-

Static library file

-

openHarmony/third_party/yxml/yxml/out/test/

-

Test cases as well as the input and output files

-
- - -## Library Test - -The test procedure for the yxml library is similar to that for the double-conversion library. For details, see the procedure described in [Porting a Library Built Using CMake](porting-a-library-built-using-cmake.md#section6686144293611). The following describes how to use the test cases of the yxml library. - -**Table 3** Directory structure of the test directory - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

openHarmony/third_party/yxml/yxml/out/test/test.sh

-

Automatic test script, which cannot be used because OpenHarmony does not support automatic script execution. However, you can refer to this script to conduct a manual test.

-

openHarmony/third_party/yxml/yxml/out/test/test

-

Executable file for testing.

-

openHarmony/third_party/yxml/yxml/out/test/*.xml

-

Input test file.

-

openHarmony/third_party/yxml/yxml/out/test/*.out

-

Expected output file.

-
- -The content of the **test.sh** file is as follows: - -``` -#!/bin/sh -for i in *.xml; do - b=`basename $i .xml` - o=${b}.out - t=${b}.test - ./test <$i >$t - if [ -n "`diff -q $o $t`" ]; then - echo "Test failed for $i:" - diff -u $o $t - exit 1 - fi -done -echo "All tests completed successfully." -``` - -The shell of OpenHarmony does not support input and output redirection symbols \(< and \>\). During the test, you need to copy the content in the **_\*_.xml** file to the shell and press **Enter**. The output content is displayed in the shell screen. - -The following operations are performed based on the assumption that the OpenHarmony environment has been set up and the **nfs** directory has been mounted and accessed. - -1. Execute the following command: - - ``` - ./test - ``` - -2. Copy the content in the **_\*_.xml** file to shell. - - Taking the **pi01.xml** file in the [test](#table115941423164318) directory as an example, copy the following content to shell and press **Enter**: - - ``` - - ``` - -3. Check whether the output in the shell is the same as that of the **_\*_.out** file in the [test](#table115941423164318) directory. - - The output is as follows: - - ``` - pistart SomePI - picontent abc - piend - elemstart a - elemend - ok - ``` - - The output is the same as the **pi01.out** file in the [test](#table115941423164318) directory. The test is passed. - - -## Adding the Compiled yxml Library to the OpenHarmony Project - -The procedure for adding the yxml library is almost the same as that for adding the double-conversion library, except that the implementation of **build.gn** and **config.gni** files. For details, see the procedure described in [Porting a Library Built Using CMake](porting-a-library-built-using-cmake.md#section1651053153715). - -- The implementation of the newly added **BUILD.gn** file in the yxml library is as follows: - -``` -import("config.gni") -group("yxml") { - if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - deps = [":make"] - } -} -if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - action("make") { - script = "//third_party/yxml/build_thirdparty.py" - outputs = ["$target_out_dir/log_yxml.txt"] - exec_path = rebase_path(rebase_path("./yxml", root_build_dir)) - command = "make clean && $MAKE_COMMAND" - args = [ - "--path=$exec_path", - "--command=${command}" - ] - } -} -``` - -- The configuration of the newly added **config.gni** file in the yxml library is as follows: - -``` -TEST_ENABLE = "YES" - -if (TEST_ENABLE == "YES") { - MAKE_COMMAND = "make test OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" -} else { - MAKE_COMMAND = "make OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" -} -``` - -- The following table lists the directory structure of the OpenHarmony project. - -**Table 4** Directory structure of the ported library - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

openHarmony/third_party/yxml/BUILD.gn

-

GN file for adding the third-party library to the OpenHarmony project

-

openHarmony/third_party/yxml/build_thirdpaty.py

-

Script file for GN to call the shell command to convert compilation from GN to Makefile.

-

openHarmony/third_party/yxml/config.gni

-

Third-party library compilation configuration file, which can be modified to determine whether the test cases will be used during the building

-

openHarmony/third_party/yxml/yxml/

-

Directory of the third-party library to be ported

-
- diff --git a/en/device-dev/porting/porting-preparations.md b/en/device-dev/porting/porting-preparations.md deleted file mode 100644 index 0e0f02a7044a9c634e2f101918e9c12747056bde..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/porting-preparations.md +++ /dev/null @@ -1,7 +0,0 @@ -# Porting Preparations - -- **[Before You Start](before-you-start.md)** - -- **[Building Adaptation Process](building-adaptation-process.md)** - - diff --git a/en/device-dev/porting/public_sys-resources/icon-caution.gif b/en/device-dev/porting/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/porting/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/device-dev/porting/public_sys-resources/icon-danger.gif b/en/device-dev/porting/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/porting/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/device-dev/porting/public_sys-resources/icon-note.gif b/en/device-dev/porting/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/device-dev/porting/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/device-dev/porting/public_sys-resources/icon-notice.gif b/en/device-dev/porting/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/device-dev/porting/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/device-dev/porting/public_sys-resources/icon-tip.gif b/en/device-dev/porting/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/device-dev/porting/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/device-dev/porting/public_sys-resources/icon-warning.gif b/en/device-dev/porting/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/porting/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/device-dev/porting/system-modules.md b/en/device-dev/porting/system-modules.md deleted file mode 100644 index 686ea0751d80679d063a624cf1eceb04c415fbd0..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/system-modules.md +++ /dev/null @@ -1,26 +0,0 @@ -# System Modules - -- [SAMGR](#section105874301910) -- [DFX](#section20064420420) - -System modules, such as the system ability manager \(SAMGR\) and DFX subsystem, provide basic capabilities for upper-layer applications. During board-level system porting, you can directly select the system modules as required without any adaptation. - -## SAMGR - -**Introduction** - -This service-oriented framework enables you to develop services, features, and external APIs, and implement multi-service process sharing and service invocation for inter-process communication \(IPC\). - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->This module must be used during board-level system porting. Otherwise, other service modules cannot run properly. - -For details about how to use SAMGR, see [samgr\_lite](https://gitee.com/openharmony/distributedschedule_samgr_lite/blob/master/README.md). - -## DFX - -**Introduction** - -The design for X \(DFX\) subsystem mainly includes design for reliability \(DFR\) and design for testability \(DFT\), providing code maintenance and testing. - -For details, see [dfx](../subsystems/dfx.md). - diff --git a/en/device-dev/porting/third-party-library-porting-guide.md b/en/device-dev/porting/third-party-library-porting-guide.md deleted file mode 100644 index 2f5cbcb9396ab5f55bf6f7ae956a5a2edfd1a833..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/third-party-library-porting-guide.md +++ /dev/null @@ -1,9 +0,0 @@ -# Third-Party Library Porting Guide - -- **[Overview](overview.md)** - -- **[Porting a Library Built Using CMake](porting-a-library-built-using-cmake.md)** - -- **[Porting a Library Built Using Makefile](porting-a-library-built-using-makefile.md)** - - diff --git a/en/device-dev/porting/third-party-soc-porting-guide.md b/en/device-dev/porting/third-party-soc-porting-guide.md deleted file mode 100644 index 19cd7887dee6cc3d7002e6173d3a01b181e19cdb..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/third-party-soc-porting-guide.md +++ /dev/null @@ -1,11 +0,0 @@ -# Third-Party SoC Porting Guide - -- **[Porting Preparations](porting-preparations.md)** - -- **[Kernel Porting](kernel-porting.md)** - -- **[Board-Level OS Porting](board-level-os-porting.md)** - -- **[FAQ](faq.md)** - - diff --git a/en/device-dev/porting/transplant-chip-board-bundle.md b/en/device-dev/porting/transplant-chip-board-bundle.md new file mode 100644 index 0000000000000000000000000000000000000000..1f0a46c450c150796b2c8e385981dcfea044944a --- /dev/null +++ b/en/device-dev/porting/transplant-chip-board-bundle.md @@ -0,0 +1,57 @@ +# Third-party Module Adaptation + +To use third-party modules in the **third\_party** directory, you may need to adapt the modules. This section uses mbedTLS as an example to describe how to integrate the adaptation code with the OpenHarmony compilation framework. For the principles of mbedTLS and the specific logic of the adaptation code, see the adaptation guide on the mbedTLS official website. + +1. Write the adaptation layer code. + + Write the required adaptation layer code based on the mbedTLS adaptation guide. In this example, adaptation of the hardware random number is used for illustration, and the paths are relative to **third\_party/mbedtls**: + + 1. Copy the **include/mbedtls/config.h** file to the **ports** directory, and enable **MBEDTLS\_ENTROPY\_HARDWARE\_ALT** in the file. + 2. In the **ports** directory, create the **entropy\_poll\_alt.c** file under **include** and implement the hardware random number API in **entropy\_poll.h**. + 3. Add the path of the adapted **entropy\_poll\_alt.c** file to **mbedtls\_sources** in the **BUILD.gn** file. + 4. Add the line **MBEDTLS\_CONFIG\_FILE** to **lite\_library\("mbedtls\_static"\)** in the **BUILD.gn** file to specify the path of the new configuration file. + + ``` + lite_library("mbedtks_static") { + ... + defines += ["MBEDTLS_CONFIG_FILE=<../port/config.h>"] + ... + } + ``` + + + You are advised to make the preceding modifications in a new **config.h** file or **_xxx_\_alt.c** file. Do not directly edit the code in the original file. Intrusive modifications may cause a large number of scattered conflicts during subsequent version updates, increasing the update maintenance costs. + +2. Create a patch. + + The preceding adaptation is hardware-specific. Therefore, when uploading code to the library, you cannot directly store the code in the **third\_party/mbedtls** directory. Instead, you need to integrate the preceding modifications into a patch and inject the patch into the code for a build. + + 1. Add the patch configuration file **device/<_company_\>/<_board_\>/patch.yml**. + 2. In the **device/<_company_\>/<_board_\>/patch.yml** file, add the information about the patch to apply. + + ``` + # Path of the patch to apply. This path is relative to the code root directory. + third_party/mbedtls: + # Directory in which the patch is stored. + - device///third_party/mbedtls/adapter.patch + third_party/wpa_supplicant: + # When there are multiple patches in a path, the patches are executed in sequence. + - device///third_party/wpa_supplicant/xxxxx.patch + - device///third_party/wpa_supplicant/yyyyy.patch + ... + ``` + + 3. Create a patch file as described in step [1](#li12446195633211) and save it to the corresponding directory. + +3. Start a build with the patch. + + Add **--patch** when triggering a build. The following is the command for executing a full build with a patch: + + ``` + hb build -f --patch + ``` + + >![](../public_sys-resources/icon-caution.gif) **CAUTION:** + >The information about the product to which the patch is most recently applied will be recorded. Next time the build is performed, the previous patch is rolled back \(that is, **\`patch -p1 -R < xxx\`** is executed\). If the patch fails to be rolled back or a patch fails to be added, the build process is terminated. In this case, resolve the patch conflict and try again. + + diff --git a/en/device-dev/porting/transplant-chip-board-component.md b/en/device-dev/porting/transplant-chip-board-component.md new file mode 100644 index 0000000000000000000000000000000000000000..2e29bb3150ed0a0e6de9b827f4799df05577be2c --- /dev/null +++ b/en/device-dev/porting/transplant-chip-board-component.md @@ -0,0 +1,26 @@ +# System Modules + +- [SAMGR](#section105874301910) +- [DFX](#section20064420420) + +System modules, such as the system ability manager \(SAMGR\) and DFX subsystem, provide basic capabilities for upper-layer applications. During board-level system porting, you can directly select the system modules as required without any adaptation. + +## SAMGR + +**Introduction** + +This service-oriented framework enables you to develop services, features, and external APIs, and implement multi-service process sharing and service invocation for inter-process communication \(IPC\). + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>This module must be used during board-level system porting. Otherwise, other service modules cannot run properly. + +For details about how to use SAMGR, see [samgr\_lite](https://gitee.com/openharmony/distributedschedule_samgr_lite/blob/master/README.md). + +## DFX + +**Introduction** + +The design for X \(DFX\) subsystem mainly includes design for reliability \(DFR\) and design for testability \(DFT\), providing code maintenance and testing. + +For details about how to use the DFX subsystem, see [DFX](../subsystems/subsys-dfx-overview.md). + diff --git a/en/device-dev/porting/board-level-driver-adaptation.md b/en/device-dev/porting/transplant-chip-board-drive.md similarity index 100% rename from en/device-dev/porting/board-level-driver-adaptation.md rename to en/device-dev/porting/transplant-chip-board-drive.md diff --git a/en/device-dev/porting/implementation-of-apis-at-the-hal.md b/en/device-dev/porting/transplant-chip-board-hal.md similarity index 100% rename from en/device-dev/porting/implementation-of-apis-at-the-hal.md rename to en/device-dev/porting/transplant-chip-board-hal.md diff --git a/en/device-dev/porting/transplant-chip-board-overview.md b/en/device-dev/porting/transplant-chip-board-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..036de7066aee8df287fba20aec2d8f6c83b2a440 --- /dev/null +++ b/en/device-dev/porting/transplant-chip-board-overview.md @@ -0,0 +1,57 @@ +# Overview + +- [Porting Process](#section1283115812294) +- [Board-Level Directory Specifications](#section6204129143013) + +## Porting Process + +After the minimum system is ported, you can port the board-level system by: + +1. Implementing the board-level driver adaptation +2. Completing the implementation at the HAL +3. Implementing the XTS +4. Verifying service functions + +**Figure 1** Process for board-level driver adaptation +![](figure/process-for-board-level-driver-adaptation.png "process-for-board-level-driver-adaptation") + +## Board-Level Directory Specifications + +For details about board-level system building adaptation, see [Compilation and Building Subsystem](transplant-chip-prepare-process.md). The board-related drivers, software development software kits \(SDKs\), directories, and HAL implementation are stored in the **device** directory. The directory structure and its description are as follows: + +``` +. +├── device --- Sample board +│ └── xxx --- +│ └── xxx --- . This directory contains the demo of the LiteOS Cortex-M kernel, which can run properly. +│ ├── BUILD.gn --- Building configuration file of the board +│ ├── board --- Specific implementation of the board (Optional. If a product-level demo is provided, implementation at the application layer is stored in this directory.) +│ ├── liteos_m --- LiteOS Cortex-M kernel to use based on the kernel_type in the BUILD.gn file +│ │ └── config.gni --- Building options +│ ├── libraries --- Board-level SDK +│ │ └── include --- SDK-provided header files that are exposed externally +│ │ └── ... --- binary or source files +│ ├── main.c --- main function entry (Product level configuration is used if the same definition exists at the product level.) +│ ├── target_config.h --- Board-level kernel configuration +│ ├── project --- Board-level project configuration file (Product-level configuration is used if the same definition exists at the product level.) +│ └── adapter --- HAL interfaces (Optional) +│ └── hals +│ ├── communication +│ │ └── wifi_lite +│ │ ├── ... +│ └── iot_hardware +│ ├── upgrade +│ ├── utils +│ └── wifiiot_lite +├── vendor --- End-to-end feature product sample of OpenHarmony +│ └── huawei --- Vendor name +│ └── wifiiot --- Feature product +│ ├── app +│ │ └── main.c --- main function entry of the product +│ ├── project --- Project configuration file +│ ├── BUILD.gn --- Project building entry +│ └── config.json --- Building configuration file of the product and components used for product configuration +└── out --- Output directory during the building + ├── ... --- .bin files generated during board/product building +``` + diff --git a/en/device-dev/porting/transplant-chip-board-xts.md b/en/device-dev/porting/transplant-chip-board-xts.md new file mode 100644 index 0000000000000000000000000000000000000000..35c40e9dc60e204096d5f5d136350087555790d5 --- /dev/null +++ b/en/device-dev/porting/transplant-chip-board-xts.md @@ -0,0 +1,63 @@ +# XTS + +- [Introduction](#section6725155811454) + - [Adding the XTS Subsystem to the Building Component](#section46981118105417) + - [Executing ACTS Cases for the IoTLink Module](#section9489122319819) + + +## Introduction + +X Test Suite \(XTS\) is a set of OpenHarmony certification test suites. Currently, the application compatibility test suite \(ACTS\) is supported. The **test/xts** repository contains the **acts** directory and **tools** software package. + +- The **acts** directory stores the source code and configuration files of ACTS test cases. The ACTS helps device vendors detect the software incompatibility as early as possible and ensures that the software is compatible with OpenHarmony during the entire development process. +- The **tools** software package stores the test case development framework related to **acts**. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The startup of the XTS depends on the SAMGR module. + +The XTS adaptation consists of the following steps: + +1. Add the XTS subsystem to the building component. +2. Execute ACTS cases for the IoTLink module. + +### Adding the XTS Subsystem to the Building Component + +The following example shows how to add the XTS subsystem to the building component **hispark\_aries**: + +1. Add the definition of the XTS subsystem to the **vendor/hisilicon/hispark\_aries/config.json** file. + + ``` + { + "subsystem": "test", + "components": [ + { "component": "xts_acts", "features":[] }, + { "component": "xts_tools", "features":[] } + ] + }, + ``` + +2. Set the building type to the debug version so that the XTS subsystem can be built. + +### Executing ACTS Cases for the IoTLink Module + +The following example shows how to execute ACTS cases for the IoTLink module of **hispark\_aries**: + +1. Obtain the built image. + + Obtain the image from the **out/hispark\_pegasus/wifiiot\_hispark\_pegasus/** directory. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >To check whether the ACTS is integrated into the current image, check whether the corresponding **.a** file is compiled. + +2. Burn the image into the development board. +3. Execute the test by performing the following steps. + - Use a serial port tool to log in to the development board and save information about the serial port. + + - Restart the device and view serial port logs. + +4. Analyze the test result. + - View the serial port logs, whose format is as follows: + + - The log for each test suite starts with **Start to run test suite:** and ends with **xx Tests xx Failures xx Ignored**. + + diff --git a/en/device-dev/porting/transplant-chip-board.md b/en/device-dev/porting/transplant-chip-board.md new file mode 100644 index 0000000000000000000000000000000000000000..4800ddd71c39115f9e9e2b0358eb699e33454f97 --- /dev/null +++ b/en/device-dev/porting/transplant-chip-board.md @@ -0,0 +1,15 @@ +# Board-Level OS Porting + +- **[Overview](transplant-chip-board-overview.md)** + +- **[Board-Level Driver Adaptation](transplant-chip-board-drive.md)** + +- **[Implementation of APIs at the HAL](transplant-chip-board-hal.md)** + +- **[System Modules](transplant-chip-board-component.md)** + +- **[Third-party Module Adaptation](transplant-chip-board-bundle.md)** + +- **[XTS](transplant-chip-board-xts.md)** + + diff --git a/en/device-dev/porting/faq.md b/en/device-dev/porting/transplant-chip-faqs.md similarity index 100% rename from en/device-dev/porting/faq.md rename to en/device-dev/porting/transplant-chip-faqs.md diff --git a/en/device-dev/porting/transplant-chip-kernel-adjustment.md b/en/device-dev/porting/transplant-chip-kernel-adjustment.md new file mode 100644 index 0000000000000000000000000000000000000000..88acd2d145496f7650d96d56b25c49af3b76462c --- /dev/null +++ b/en/device-dev/porting/transplant-chip-kernel-adjustment.md @@ -0,0 +1,83 @@ +# Basic Kernel Adaptation + +- [Adaptation Process](#section14523241594) +- [Feature Configuration](#section112994366592) + +The LiteOS Cortex-M kernel provides the system initialization process and customized configuration options required for system running. During kernel porting, you must pay attention to the functions related to hardware configuration in the initialization process and understand the kernel configuration options so that the minimum kernel that matches the board can be tailored. + +## Adaptation Process + +Basic adaptation consists of the following steps: + +1. Modify the code in the **startup.S** and corresponding link configuration files. +2. Initialize the serial port and register the handler function for the tick interrupt response in the **main.c** file + +**Figure 1** Startup process + + +![](figure/en-us_image_0000001073943511.png) + +In the **startup.S** file, you must ensure that the entry function \(for example, **reset\_vector**\) of the interrupt vector table is stored in the RAM start address specified by the link configuration files. The link configuration files of IAR, Keil, and GCC projects are **xxx.icf**, **xxx.sct**, and **xxx.ld**, respectively. The startup file provided by the vendor does not need to be modified if the **startup.S** file has initialized the system clock and returned to the **main** function. Otherwise, the preceding functions need to be implemented. + +In the **main.c** file, you need to register the UartInit function used for initializing the serial port and the handler function used for the system tick. + +- The UartInit function initializes the board serial port, and the function name can be defined based on the board. This function is optional. You can determine whether to call it based on whether the board supports the serial port. If the board supports the serial port, this function must enable TX and RX channels of the serial port and set the baud rate. +- You can call **HalTickStart** to set the **OsTickHandler** function for the tick interrupt response. + +For the chip whose interrupt vector table cannot be redirected, you need to disable the **LOSCFG\_PLATFORM\_HWI** macro, and add the **OsTickHandler** function for the tick interrupt response in the **startup.S** file. + +## Feature Configuration + +The **los\_config.h** file defines both complete configuration and default configuration of **liteos\_m**. All configuration items in this file can be customized for different boards as required. + +You can define configuration items in the **device/xxxx/target\_config.h** file of the corresponding board. For other undefined configuration items, default values in the **los\_config.h** file will be used. + +The following table shows some typical configuration items: + +**Table 1** Typical configuration items + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Item

+

Description

+

LOSCFG_BASE_CORE_SWTMR

+

Switch of the software timer. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

+

LOSCFG_BASE_CORE_SWTMR_ALIGN

+

Switch of the time alignment feature, which depends on the switch status of the software timer. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

+

LOSCFG_BASE_IPC_MUX

+

Switch of the mux feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

+

LOSCFG_BASE_IPC_QUEUE

+

Switch of the queue feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

+

LOSCFG_BASE_IPC_SEM

+

Switch of the semaphore feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

+

LOSCFG_PLATFORM_EXC

+

Switch of the exception feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

+

LOSCFG_KERNEL_PRINTF

+

Switch of the print feature. The values 1 and 0 indicate that the switch is turned on and turned off, respectively.

+
+ diff --git a/en/device-dev/porting/transplant-chip-kernel-overview.md b/en/device-dev/porting/transplant-chip-kernel-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..48634e90d7b415d3998cb1d2df615a466aaa9eb7 --- /dev/null +++ b/en/device-dev/porting/transplant-chip-kernel-overview.md @@ -0,0 +1,64 @@ +# Overview + +- [Porting Scenario](#section93781277367) +- [Directory Specifications](#section18127744153119) +- [Chip Architecture Adaptation](#section137431650339) + +## Porting Scenario + +The chip architecture adaptation process is optional. If the particular chip architecture is supported in the **liteos\_m/kernel/arch** directory, you can directly implement the board adaptation. Otherwise, chip architecture porting is required. + +## Directory Specifications + +The kernel used by module chips is LiteOS Cortex-M, which consists of four modules, namely kernel abstraction layer \(KAL\), components, kernel, and utils. + +- **KAL**: provides APIs exposed externally and depends on the components and kernel modules. +- **Components**: is pluggable and relies on the kernel module. + +- **Kernel**: stores hardware-related code in the **arch** directory and other code. The implementation of kernel function sets \(such as task and sem\), for example, task context switching and atomic operations, depends on the hardware-related code in the **arch** directory. +- **Utils**: functions as a basic code block where other modules rely. + +**Figure 1** Architecture of the LiteOS Cortex-M kernel + + +![](figure/en-us_image_0000001072304191.png) + +The directory structure of the kernel is described as follows: + +``` +. +├── components --- Components available for porting and header files exposed externally +├── kal --- APIs exposed externally, including CMSIS APIs and part of POSIX APIs +├── kernel --- Code for defining the minimum kernel function set +│ ├── arch --- Code of the kernel instruction architecture layer +│ │ ├── arm --- Code of the ARM32 architecture +│ │ │ ├── cortex-m3 --- Code of the Cortex-M3 architecture +│ │ │ │ ├── iar --- Implementation of the IAR toolchain +│ │ │ │ ├── keil --- Implementation of the Keil toolchain +│ │ │ │ └── xxx --- Implementation of the particular toolchain +│ │ │ └── cortex-m4 --- Code of the Cortex-M4 architecture +│ │ │ ├── iar --- Implementation of the IAR toolchain +│ │ │ ├── keil --- Implementation of the Keil toolchain +│ │ │ └── xxx --- Implementation of the particular toolchain +│ │ ├── include --- Header files that declare the APIs required, kernel-independent +│ │ └── risc-v --- RISK_V architecture +│ │ └── gcc --- Implementation of the IAR toolchain +│ ├── include --- Code for defining the minimum kernel function set +│ └── src --- Code for implementing the minimum kernel function set +└──utils --- Basic code +``` + +## Chip Architecture Adaptation + +As shown in the [Directory Specifications](#section18127744153119), the **arch/include** directory defines the functions that need to be implemented on the common chip architecture. The code related to the chip architecture contains assembly code, which varies based on building toolchains. Therefore, the code for adapting to different toolchains \(for example, IAR, Keil, GCC, etc.\) must be implemented in a specific chip architecture. + +The **arch/include** directory defines common files and functions. All functions in this directory need to be implemented to adapt to a newly added architecture. For details, refer to the following header files. + +``` +los_arch.h --- Defines the functions required for initializing the chip architecture. +los_atomic.h --- Defines the atomic operation functions required by the chip architecture. +los_context.h --- Defines the context functions required by the chip architecture. +los_interrupt.h --- Defines the interrupt and exception functions required by the chip architecture. +los_timer.h --- Defines the timer functions required by the chip architecture. +``` + diff --git a/en/device-dev/porting/transplant-chip-kernel-verify.md b/en/device-dev/porting/transplant-chip-kernel-verify.md new file mode 100644 index 0000000000000000000000000000000000000000..56aa1d19d06af1d3a2c994a64b898045e0270484 --- /dev/null +++ b/en/device-dev/porting/transplant-chip-kernel-verify.md @@ -0,0 +1,59 @@ +# Kernel Porting Verification + +Add the sample program file **main.c** to the **device** directory of the project and compile the file. After LOS\_KernelInit is complete, this sample program will create two tasks that loop the **LOS\_TaskDelay** function and print the log information cyclically. In this way, you can check whether system scheduling and the clock work properly. + +``` +VOID TaskSampleEntry2(VOID) // Entry function of task 2 +{ + while(1) { + LOS_TaskDelay(10000); + printf("taskSampleEntry2 running...\n"); + } +} + +VOID TaskSampleEntry1(VOID) // Entry function of task 1 +{ + while(1) { + LOS_TaskDelay(2000); + printf("taskSampleEntry1 running...\n"); + } +} + +UINT32 TaskSample(VOID) +{ + UINT32 uwRet; + UINT32 taskID1,taskID2; + TSK_INIT_PARAM_S stTask1={0}; + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1; + stTask1.uwStackSize = 0X1000; + stTask1.pcName = "taskSampleEntry1"; + stTask1.usTaskPrio = 6; // Set the priority of stTask1, which is different from that of stTask2. + uwRet = LOS_TaskCreate(&taskID1, &stTask1); + + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2; + stTask1.uwStackSize = 0X1000; + stTask1.pcName = "taskSampleEntry2"; + stTask1.usTaskPrio = 7; + uwRet = LOS_TaskCreate(&taskID2, &stTask1); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT int main(void) +{ + UINT32 ret; + UartInit(); // Configure the hardware serial port and output the debug log over this serial port. The actual function name varies with the board. + printf("\n\rhello world!!\n\r"); + ret = LOS_KernelInit(); + TaskSample(); + if (ret == LOS_OK) { + LOS_Start(); // Start system scheduling, execute stTask1/stTask2 cyclically, and output task logs over the serial port. + } + while (1) { + __asm volatile("wfi"); + } +} +``` + +If the first task is executed properly, the core process of the minimum system is valid. Due to the XTS framework's dependency on the link scripts of Utils and Bootstrap as well as the building framework, testing the kernel by executing the XTS is not supported. You can test whether the minimum system is completely ported in [XTS](transplant-chip-board-xts.md). + diff --git a/en/device-dev/porting/transplant-chip-kernel.md b/en/device-dev/porting/transplant-chip-kernel.md new file mode 100644 index 0000000000000000000000000000000000000000..7f9366086a58c40a65915482a8891469bdc1b12c --- /dev/null +++ b/en/device-dev/porting/transplant-chip-kernel.md @@ -0,0 +1,9 @@ +# Kernel Porting + +- **[Overview](transplant-chip-kernel-overview.md)** + +- **[Basic Kernel Adaptation](transplant-chip-kernel-adjustment.md)** + +- **[Kernel Porting Verification](transplant-chip-kernel-verify.md)** + + diff --git a/en/device-dev/porting/transplant-chip-prepare-knows.md b/en/device-dev/porting/transplant-chip-prepare-knows.md new file mode 100644 index 0000000000000000000000000000000000000000..731df255c420f947b4be298bca7b9ce89b6b5215 --- /dev/null +++ b/en/device-dev/porting/transplant-chip-prepare-knows.md @@ -0,0 +1,84 @@ +# Before You Start + +- [Porting Directory](#section284217487490) +- [Porting Process](#section639315306506) +- [Porting Specifications](#section187870185219) + +This document provides basic guidance for OpenHarmony developers and system on a chip \(SoC\) or module vendors to port OpenHarmony to typical chip architectures, such as the cortex-M and RISC-V series. Currently, the Bluetooth service is not supported. Due to the complexity of the OpenHarmony project, this document is subject to update as the version and APIs change. + +This guide is intended for readers who have experience in developing embedded systems. Therefore, it mainly describes operations and key points during platform porting instead of basic introduction to the OS. + +## Porting Directory + +The implementation of the OpenHarmony project directories and functions relies on the OS itself. If no enhancement for a complex feature is involved, you only need to focus on the directories described in the following table. + +**Table 1** Key directories in the porting process + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

/build/lite

+

Basic building framework for OpenHarmony

+

/kernel/liteos_m

+

Basic kernel. The implementation related to the chip architecture is in the arch directory.

+

/device

+

Board-level code implementation, which is provided by third-party vendors based on the OpenHarmony specifications. For detailed structure about the device directory and porting process, see Board-Level OS Porting.

+

/vendor

+

Product-level implementation, which is contributed by Huawei or product vendors.

+
+ +The **device** directory is in the internal structure of **device/\{Chip solution vendor\}/\{Development board\}**. The following uses HiSilicon **hispark\_taurus** as an example: + +``` +device +└── hisilicon # Name of the chip solution vendor + ├── common # Common part of the chip solution development board + └── hispark_taurus # Name of the development board + ├── BUILD.gn # Entry to building the development board + ├── hals # OS hardware adaptation of the chip solution vendor + ├── linux # Linux version + │ └── config.gni # Configurations of the building toolchain and building options for the Linux version + └── liteos_a # LiteOS Cortex-A version + └── config.gni # Configurations of the building toolchain and building options for the LiteOS Cortex-A version +``` + +The **vendor** directory is in the internal structure of **vendor/\{Product solution vendor\}/\{Product name\}**. The following uses Huawei Wi-Fi IoT product as an example: + +``` +vendor # Product solution vendor +└── huawei # Name of the product solution vendor + └── wifiiot # Product name + ├── hals # OS adaptation of the product solution vendor + ├── BUILD.gn # Product building script + └── config.json # Product configuration file +``` + +## Porting Process + +The **device** directory of OpenHarmony is the adaptation directory for the basic SoC. You can skip the porting process and directly develop system applications if complete SoC adaptation code is already available in the directory. If there is no corresponding SoC porting implementation in the directory, complete the porting process by following the instructions provided in this document. The following figure shows the process of porting OpenHarmony to a third-party SoC. + +**Figure 1** Key steps for SoC porting +![](figure/key-steps-for-soc-porting.png "key-steps-for-soc-porting") + +## Porting Specifications + +- The porting must comply with the basic OpenHarmony principles described in [Contribution](https://gitee.com/openharmony/docs/blob/master/en/contribute/contribution.md). +- The code required for third-party SoC adaptation is stored in the **device**, **vendor**, and **arch** directories. Naming and usage of these directories must comply with specified naming and usage specifications. For details, see [Directory Specifications](transplant-chip-kernel-overview.md) and [Board-Level Directory Specifications](transplant-chip-board-overview.md#section6204129143013). + diff --git a/en/device-dev/porting/building-adaptation-process.md b/en/device-dev/porting/transplant-chip-prepare-process.md similarity index 100% rename from en/device-dev/porting/building-adaptation-process.md rename to en/device-dev/porting/transplant-chip-prepare-process.md diff --git a/en/device-dev/porting/transplant-chip-prepare.md b/en/device-dev/porting/transplant-chip-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..f981ad0f6d0e48e56db1e5673c30b86ee3e5808f --- /dev/null +++ b/en/device-dev/porting/transplant-chip-prepare.md @@ -0,0 +1,7 @@ +# Porting Preparations + +- **[Before You Start](transplant-chip-prepare-knows.md)** + +- **[Building Adaptation Process](transplant-chip-prepare-process.md)** + + diff --git a/en/device-dev/porting/transplant-minichip.md b/en/device-dev/porting/transplant-minichip.md new file mode 100644 index 0000000000000000000000000000000000000000..38a8e78dc15a0880b33aa775c6b13056f4aecc7c --- /dev/null +++ b/en/device-dev/porting/transplant-minichip.md @@ -0,0 +1,11 @@ +# Mini System SoC Porting Guide + +- **[Porting Preparations](transplant-chip-prepare.md)** + +- **[Kernel Porting](transplant-chip-kernel.md)** + +- **[Board-Level OS Porting](transplant-chip-board.md)** + +- **[FAQ](transplant-chip-faqs.md)** + + diff --git a/en/device-dev/porting/transplant-smallchip-drive-des.md b/en/device-dev/porting/transplant-smallchip-drive-des.md new file mode 100644 index 0000000000000000000000000000000000000000..f0d29c993046768d62315a1818157137067e3db3 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-drive-des.md @@ -0,0 +1,11 @@ +# Overview + +Drivers can be classified as platform drivers or device drivers. The platform drivers are generally in the SoC, such as the GPIO, I2C, and SPI drivers. The device drivers are typically ouside of the SoC, such as the LCD, TP, and WLAN drivers. + +**Figure 1** OpenHarmony driver classification + + +![](figure/分类.png) + +The Hardware Driver Foundation \(HDF\) is designed to work across OSs. The HDF driver framework provides strong support for drivers to achieve this goal. During HDF driver development, you are advised to use only the APIs provided by the HDF driver framework. Otherwise, the driver cannot be used across OSs. Before driver development, familiarize yourself with the [HDF](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/hdf.md). + diff --git a/en/device-dev/porting/transplant-smallchip-drive-oom.md b/en/device-dev/porting/transplant-smallchip-drive-oom.md new file mode 100644 index 0000000000000000000000000000000000000000..76c1b0741c29ce369584502081e4df794ce3af43 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-drive-oom.md @@ -0,0 +1,390 @@ +# Device Driver Porting + +- [LCD Driver Porting](#section1574513454119) +- [Touchscreen Driver Porting](#section20284142116422) +- [WLAN Driver Porting](#section0969448164217) + +This section describes how to port device drivers. + +## LCD Driver Porting + +To port an LCD driver, write the driver, create an instance of the corresponding model in the driver, and complete the registration. + +The LCD drivers are stored in **//drivers/framework/model/display/driver/panel**. + +1. Create a panel driver. + + Create an HDF driver and call the **RegisterPanel** method to register a model instance during driver initialization. + + ``` + int32_t LCDxxEntryInit(struct HdfDeviceObject *object) + { + struct PanelData *panel = CreateYourPanel(); + // Register a model instance. + if (RegisterPanel(panel) != HDF_SUCCESS) { + HDF_LOGE("%s: RegisterPanel failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + struct HdfDriverEntry g_xxxxDevEntry = { + .moduleVersion = 1, + .moduleName = "LCD_XXXX", + .Init = LCDxxEntryInit, + }; + + HDF_INIT(g_xxxxDevEntry); + ``` + +2. Configure and load the panel driver. + + Modify the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Add configurations for the device named **device\_lcd** for the display host. + + >![](../public_sys-resources/icon-caution.gif) **CAUTION:** + >Make sure the value of **moduleName** is the same as that of **moduleName** in the panel driver. + + ``` + root { + ... + display :: host { + device_lcd :: device { + deviceN :: deviceNode { + policy = 0; + priority = 100; + preload = 2; + moduleName = "LCD_XXXX"; + } + } + } + } + ``` + + +## Touchscreen Driver Porting + +This section describes how to port a touchscreen driver. The touchscreen drivers are stored in the source code directory **//drivers/framework/model/input/driver/touchscreen**. To port a touchscreen driver, register a **ChipDevice** model instance with the system. + +For details about how to develop a touchscreen driver, see [Touchscreen Development Guidelines](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/touchscreen.md). + +1. Create a touchscreen driver. + + Create the **touch\_ic\_name.c** file in the **touchscreen** directory. Write the following content: + + ``` + #include "hdf_touch.h" + + static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device) + { + ChipDevice *tpImpl = CreateXXXXTpImpl(); + if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) {// Register the ChipDevice model instance. + ReleaseXXXXTpImpl(tpImpl); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + struct HdfDriverEntry g_touchXXXXChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_XXXX", // Make sure the value is the same as that in the subsequent configuration. + .Init = HdfXXXXChipInit, + }; + + HDF_INIT(g_touchXXXXChipEntry); + ``` + + The following methods need to be implemented in **ChipDevice**: + + + + + + + + + + + + + + + + + + + + + + + + + +

Method

+

Description

+

int32_t (*Init)(ChipDevice *device)

+

Initializes the device.

+

int32_t (*Detect)(ChipDevice *device)

+

Detects the device.

+

int32_t (*Suspend)(ChipDevice *device)

+

Places the device in sleep mode.

+

int32_t (*Resume)(ChipDevice *device)

+

Wakes up the device.

+

int32_t (*DataHandle)(ChipDevice *device)

+

Reads data from the device and writes touch point data to device > driver > frameData.

+

int32_t (*UpdateFirmware)(ChipDevice *device)

+

Updates the firmware.

+
+ +2. Configure the product and load the driver. + + All device information of the product is defined in the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Modify the file and add configurations to the **device** named **device\_touch\_chip** in the **host** of the **input** command. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Make sure the value of **moduleName** is the same as that of **moduleName** in the touchscreen driver. + + ``` + deviceN :: deviceNode { + policy = 0; + priority = 130; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH_XXXX"; + deviceMatchAttr = "touch_XXXX_configs"; + } + ``` + + +## WLAN Driver Porting + +The WLAN driver is divided into two parts. One of the parts manages WLAN devices, and the other part manages WLAN traffic. + +**Figure 1** OpenHarmony WLAN driver architecture + + +![](figure/hdf_wifi.png) + +As shown in [Figure 1](#fig155920160203), the part on the left manages WLAN devices, and the part on the right manages WLAN traffic. The HDF WLAN framework abstracts these two parts. The porting process of the driver can be considered as the implementation of the APIs required by the two parts. These APIs are described as follows: + + + + + + + + + + + + + + + + + + + + +

API

+

Header File

+

API Description

+

HdfChipDriverFactory

+

drivers\framework\include\wifi\hdf_wlan_chipdriver_manager.h

+

Factory of the ChipDriver, which is used to support multiple WLAN interfaces of a chip.

+

HdfChipDriver

+

drivers\framework\include\wifi\wifi_module.h

+

Manages a specific WLAN interface.

+

NetDeviceInterFace

+

drivers\framework\include\wifi\net_device.h

+

Communicates with the protocol stack, such as sending data and setting the status of network interfaces.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>For details about the API development, see [WLAN Development Guidelines](https://gitee.com/openharmony/docs/blob/master/en/device-dev/driver/wlan.md). + +The porting procedure is as follows: + +1. Create a WLAN chip driver. + + Create the **hdf\_wlan\_chip\_name.c** file in **/device/vendor\_name/peripheral/wifi/chip\_name/**. The sample code is as follows: + + ``` + static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) { + static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); // Implement the method. + struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) {// Register the driver factory. + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + struct HdfDriverEntry g_hdfXXXChipEntry = { + .moduleVersion = 1, + .Init = HdfWlanXXXChipDriverInit, + .Release = HdfWlanXXXChipRelease, + .moduleName = "HDF_WIFI_CHIP_XXX" // Make sure the name is the same as the configured one. + }; + + HDF_INIT(g_hdfXXXChipEntry); + ``` + + In the **CreateChipDriverFactory** method, create an object of the **HdfChipDriverFactory** type. This object provides the following methods: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Method

+

Description

+

const char *driverName

+

Indicates the driver name.

+

int32_t (*InitChip)(struct HdfWlanDevice *device)

+

Initializes the chip.

+

int32_t (*DeinitChip)(struct HdfWlanDevice *device)

+

Deinitializes the chip.

+

void (*ReleaseFactory)(struct HdfChipDriverFactory *factory)

+

Releases the HdfChipDriverFactory object.

+

struct HdfChipDriver *(*Build)(struct HdfWlanDevice *device, uint8_t ifIndex)

+

Creates an HdfChipDriver. In the input parameters, device indicates the device information, and ifIndex indicates the sequence number of this interface in the chip.

+

void (*Release)(struct HdfChipDriver *chipDriver)

+

Releases the chip driver.

+

uint8_t (*GetMaxIFCount)(struct HdfChipDriverFactory *factory)

+

Obtains the maximum number of interfaces supported by the current chip.

+
+ + The **Build** method creates an **HdfChipDriver** object that manages the specified network interface. This object needs to provide the following methods: + + + + + + + + + + + + + + + + + + + + + + +

Method

+

Description

+

int32_t (*init)(struct HdfChipDriver *chipDriver, NetDevice *netDev)

+

Initializes the current network interface. The NetDeviceInterFace needs to be provided for the netDev.

+

int32_t (*deinit)(struct HdfChipDriver *chipDriver, NetDevice *netDev)

+

Deinitializes the current network interface.

+

struct HdfMac80211BaseOps *ops

+

Provides the WLAN basic capability interface set.

+

struct HdfMac80211STAOps *staOps

+

Provides the interface set required for supporting the STA mode.

+

struct HdfMac80211APOps *apOps

+

Provides the interface set required for supporting the AP mode.

+
+ +2. Create a configuration file to describe the chips supported by the driver. + + Create a chip configuration file in the product configuration directory and save it to the source code path **//vendor/vendor\_name/product\_name/config/wifi/wlan\_chip\_chip\_name.hcs**. + + The sample code is as follows: + + ``` + root { + wlan_config { + chip_name :& chipList { + chip_name :: chipInst { + match_attr = "hdf_wlan_chips_chip_name"; /* Indicates the configuration matching attribute, which is used to provide the configuration root of the driver.*/ + driverName = "driverName"; /* Indicates the driver name, which must be the same as that of driverName in HdfChipDriverFactory.*/ + sdio { + vendorId = 0xXXXX; /* your vendor id */ + deviceId = [0xXXXX]; /*your supported devices */ + } + } + } + } + } + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Replace the values of **vendor\_name**, **product\_name**, and **chip\_name** in the path and file with the actual names. + >Set **vendorId** and **deviceId** to the actual vendor ID and chip ID, respectively. + +3. Edit the configuration file and load the driver. + + All device information of the product is defined in the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Modify the file and add configurations to the **device** named **device\_wlan\_chips** in the **host** of the **network** command. The sample code is as follows: + + ``` + deviceN :: deviceNode { + policy = 0; + preload = 2; + moduleName = "HDF_WLAN_CHIPS"; + deviceMatchAttr = "hdf_wlan_chips_chip_name"; + serviceName = "driverName"; + } + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Make sure the value of **moduleName** is the same as that of **moduleName** in the WLAN driver. + +4. Modify the **Kconfig** file to make the ported WLAN driver appear in the kernel configuration. + + Add configurations to **device/vendor\_name/drivers/Kconfig**. The sample code is as follows: + + ``` + config DRIVERS_HDF_WIFI_chip_name + bool "Enable chip_name Host driver" + default n + depends on DRIVERS_HDF_WLAN help + Answer Y to enable chip_name Host driver. + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Replace **chip\_name** with the actual chip name. + +5. Modify the build script to enable the driver to participate in the kernel build. + + Add the following content to the end of the source code file **//device/vendor\_name/drivers/lite.mk**: + + ``` + ifeq ($(LOSCFG_DRIVERS_HDF_WIFI_chip_name), y) + # After the build is complete, an object named hdf_wlan_chipdriver_chip_name needs to be linked. You are advised to use this name to prevent conflicts. + LITEOS_BASELIB += -lhdf_wlan_chipdriver_chip_name + # Add the build directory gpio. + LIB_SUBDIRS += ../peripheral/wifi/chip_name + endif + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Replace **chip\_name** with the actual chip name. + + diff --git a/en/device-dev/porting/transplant-smallchip-drive-plat.md b/en/device-dev/porting/transplant-smallchip-drive-plat.md new file mode 100644 index 0000000000000000000000000000000000000000..b6fd4a386b65c9f78d75123b48591a7d17bbaa84 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-drive-plat.md @@ -0,0 +1,165 @@ +# Platform Driver Porting + +Create a platform driver in the source code directory **//device/vendor\_name/soc\_name/drivers**. If there is no repository for the vendor of your SoC, contact the [device SIG](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard.md) to create one. + +The recommended directory structure is as follows: + +``` +device +├── vendor_name +│ ├── drivers +│ │ │ ├── common +│ │ │ ├── Kconfig # Entry of the vendor driver kernel menu +│ │ │ └── lite.mk # Build entry +│ ├── soc_name +│ │ ├── drivers +│ │ │ ├── dmac +│ │ │ ├── gpio +│ │ │ ├── i2c +│ │ │ ├── LICENSE +│ │ │ ├── mipi_dsi +│ │ │ ├── mmc +│ │ │ ├── pwm +│ │ │ ├── README.md # docs Add documentation information as needed. +│ │ │ ├── README_zh.md +│ │ │ ├── rtc +│ │ │ ├── spi +│ │ │ ├── uart +│ │ │ └── watchdog +│ ├── board_name +``` + +The HDF creates driver models for all platform drivers. The main task of porting platform drivers is to inject instances into the models. You can find the definitions of these models in the source code directory **//drivers/framework/support/platform/include**. + +The following uses the GPIO as an example to describe how to port the platform driver: + +1. Create a GPIO driver. + + Create the **soc\_name\_gpio.c** file in the source code directory **//device/vendor\_name/soc\_name/drivers/gpio**. The sample code is as follows: + + ``` + #include "gpio_core.h" + + // Define the GPIO structure if necessary. + struct SocNameGpioCntlr { + struct GpioCntlr cntlr; // Structure required by the HDF GPIO driver framework. + int myData; // The following information is required by the current driver. + }; + + // The Bind method is mainly used to release services in the HDF driver. As this method is not needed here, simply return a success message. + static int32_t GpioBind(struct HdfDeviceObject *device) + { + (void)device; + return HDF_SUCCESS; + } + + // Entry for initializing the driver when the Init method is used. You need to register the model instance in the Init method. + static int32_t GpioInit(struct HdfDeviceObject *device) + { + SocNameGpioCntlr *impl = CreateGpio(); // Implement the CreateGpio method. + ret = GpioCntlrAdd(&impl->cntlr); // Register a GPIO model instance. + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: err add controller:%d", __func__, ret); + return ret; + } + return HDF_SUCCESS; + } + + // The Release method is called when the driver is uninstalled to reclaim resources. + static void GpioRelease(struct HdfDeviceObject *device) + { + // The GpioCntlrFromDevice method obtains the model instance registered in the init method from the abstract device object. + struct GpioCntlr *cntlr = GpioCntlrFromDevice(device); + // Release resources. + } + + struct HdfDriverEntry g_gpioDriverEntry = { + .moduleVersion = 1, + .Bind = GpioBind, + .Init = GpioInit, + .Release = GpioRelease, + .moduleName = "SOC_NAME_gpio_driver", // Name to be used in the configuration file to load the driver. + }; + HDF_INIT(g_gpioDriverEntry); // Register a GPIO driver entry. + ``` + +2. Create a build entry for the vendor driver. + + As described above, **device/vendor\_name/drivers/lite.mk** is the entry for building vendor drivers. We need to start building from this entry. + + ``` + # File: device/vendor_name/drivers/lite.mk + + SOC_VENDOR_NAME := $(subst $/",,$(LOSCFG_DEVICE_COMPANY)) + SOC_NAME := $(subst $/",,$(LOSCFG_PLATFORM)) + BOARD_NAME := $(subst $/",,$(LOSCFG_PRODUCT_NAME)) + + # Specify the SoC for building. + LIB_SUBDIRS += $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR_NAME)/$(SOC_NAME)/drivers/ + ``` + +3. Create a build entry for the SoC driver. + + ``` + # File: device/vendor_name/soc_name/drivers/lite.mk + + SOC_DRIVER_ROOT := $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR_NAME)/$(SOC_NAME)/drivers/ + + # Check whether the kernel compilation switch of the GPIO is enabled. + ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO), y) + # After the construction is complete, an object named hdf_gpio needs to be linked. + LITEOS_BASELIB += -lhdf_gpio + # Add the build directory gpio. + LIB_SUBDIRS += $(SOC_DRIVER_ROOT)/gpio + endif + + # Add other drivers here. + ``` + +4. Create a build entry for the GPIO driver. + + ``` + include $(LITEOSTOPDIR)/config.mk + include $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mk + + # Specify the name of the output object. Ensure that the name is the same as LITEOS_BASELIB in the SoC driver build entry. + MODULE_NAME := hdf_gpio + + # Add the INCLUDE of the HDF framework. + LOCAL_CFLAGS += $(HDF_INCLUDE) + + # Specify the file to be compiled. + LOCAL_SRCS += soc_name_gpio.c + + # Build parameters + LOCAL_CFLAGS += -fstack-protector-strong -Wextra -Wall -Werror -fsigned-char -fno-strict-aliasing -fno-common + + include $(HDF_DRIVER) + ``` + +5. Configure the product loading driver. + + All device information of the product is defined in the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. + + Add the platform driver to the host of the platform. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >The value of **moduleName** must be the same as that defined in the driver. + + ``` + root { + ... + platform :: host { + device_gpio :: device { + device0 :: deviceNode { + policy = 0; + priority = 10; + permission = 0644; + moduleName = "SOC_NAME_gpio_driver"; + } + } + } + } + ``` + + diff --git a/en/device-dev/porting/transplant-smallchip-drive.md b/en/device-dev/porting/transplant-smallchip-drive.md new file mode 100644 index 0000000000000000000000000000000000000000..a79db8073393aeffdbaf19445f95dee3cefb9218 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-drive.md @@ -0,0 +1,9 @@ +# Driver Porting + +- **[Overview](transplant-smallchip-drive-des.md)** + +- **[Platform Driver Porting](transplant-smallchip-drive-plat.md)** + +- **[Device Driver Porting](transplant-smallchip-drive-oom.md)** + + diff --git a/en/device-dev/porting/transplant-smallchip-kernel-a.md b/en/device-dev/porting/transplant-smallchip-kernel-a.md new file mode 100644 index 0000000000000000000000000000000000000000..f64a0e832b18161a3cfd6339962f21b7776f45a8 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-kernel-a.md @@ -0,0 +1,263 @@ +# LiteOS Cortex-A + +- [Overview](#section14876256185510) + - [Porting Scenario](#section1986014410569) + - [Directory Specifications](#section10916181716564) + +- [Adaptation Process](#section814974018565) + - [Programming Example](#section10854481825) + +- [Verification](#section646410453212) + +## Overview + +### Porting Scenario + +LiteOS Cortex-A supports the ARMv7-a instruction set architecture. If you are porting the kernel to a chipset that uses ARMv7-a, you can directly perform basic adaptation. Otherwise, you need to add support for the architecture used by the chipset. This process is complex and not covered in this document. + +### Directory Specifications + +For details about the LiteOS Cortex-A directory specifications, see [LiteOS Cortex-A Overview](https://gitee.com/openharmony/kernel_liteos_a). + +## Adaptation Process + +LiteOS Cortex-A provides the system initialization process and custom configuration options required for system running. During porting, pay attention to the functions related to hardware configuration in the initialization process. + +The LiteOS Cortex-A initialization process consists of five steps: + +1. Add the **target\_config.h** file and compile the macros **DDR\_MEM\_ADDR** and **DDR\_MEM\_SIZE**, which indicate the start address and length of the board memory, respectively. The prelinker script **board.ld.S** creates the linker script **board.ld** based on the two macros. +2. The kernel creates a kernel image based on the linker script **board.ld**. +3. Operations such as initialization of the interrupt vector table and MMU page table are performed in the assembly files: **reset\_vector\_up.S** and **reset\_vector\_mp.S**, from which a single-core CPU and a multi-core CPU start, respectively. +4. The assembly code in **reset\_vector.S** jumps to the **main** function of the C programming language to initialize the hardware clock, software timer, memory, and tasks. This process depends on the feature macro configuration in **target\_config.h** . The **SystemInit** task to be implemented in the board code is then created, and **OsSchedStart\(\)** is enabled for task scheduling. +5. The **DeviceManagerStart** function is called to initialize the HDF driver. This process is implemented by calling the driver configuration file **hdf.hcs** and driver source code in the board code. + +Below is the overall initialization process. + +**Figure 1** Overall initialization process + + +![](figure/en-us_image_0000001126358814.png) + +As can be seen from preceding figure, kernel basic adaptation involves the following parts: + +- Adding the **target\_config.h** file, which contains board hardware parameters and feature parameters described in the following table: + + **Table 1** Parameters in the target\_config.h file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

OS_SYS_CLOCK

+

System cycle frequency

+

DDR_MEM_ADDR

+

Start address of the system memory

+

DDR_MEM_SIZE

+

Size of the system memory

+

PERIPH_PMM_BASE

+

Base address of the peripheral register

+

PERIPH_PMM_SIZE

+

Size of the peripheral register

+

OS_HWI_MIN

+

Minimum number of system interrupts

+

OS_HWI_MAX

+

Maximum number of system interrupts

+

NUM_HAL_INTERRUPT_UART0

+

UART0 interrupt ID

+

UART0_REG_BASE

+

UART0 register base address

+

GIC_BASE_ADDR

+

Base address of the GIC interrupt register

+

GICD_OFFSET

+

Offset address of the GICD relative to the GIC base address

+

GICC_OFFSET

+

Offset address of the GICC relative to the GIC base address

+
+ +- Implementing the **SystemInit** function to initialize services in the user space. Figure 2 shows a typical initialization scenario. + + **Figure 1** Service startup process + + + ![](figure/en-us_image_0000001126198996.png) + +- Implementing the **main** function for basic kernel initialization and initialization of services in the board kernel space. Figure 3 shows the initialization process, where the kernel startup framework takes the lead in the initialization process. The light blue part in the figure indicates the phase in which external modules can be registered and started in the startup framework. + + >![](../public_sys-resources/icon-caution.gif) **CAUTION:** + >Modules at the same layer cannot depend on each other. + + **Figure 2** Kernel startup framework + ![](figure/kernel-startup-framework.jpg "kernel-startup-framework") + + **Table 2** Startup framework layers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Level

+

Description

+

LOS_INIT_LEVEL_EARLIEST

+

Earliest initialization.

+

This layer does not depend on the architecture. The board and subsequent modules, such as the Trace module, will initialize the software-only modules on which they depend.

+

LOS_INIT_LEVEL_ARCH_EARLY

+

Early initialization of the architecture.

+

This layer depends on the architecture. Subsequent modules will initialize the modules on which they depend. It is recommended that functions not required for startup be placed at the LOS_INIT_LEVEL_ARCH layer.

+

LOS_INIT_LEVEL_PLATFORM_EARLY

+

Early initialization of the platform.

+

This layer depends on the board platform and drivers. Subsequent modules will initialize the modules on which they depend. It is recommended that functions required for startup be placed at the LOS_INIT_LEVEL_PLATFORM layer.

+

Example: UART module

+

LOS_INIT_LEVEL_KMOD_PREVM

+

Kernel module initialization before memory initialization.

+

This layer involves initialization of the modules that need to be enabled before memory initialization.

+

LOS_INIT_LEVEL_VM_COMPLETE

+

Initialization after the basic memory is ready.

+

This layer involves initialization of the modules that need to be enabled and do not depend on the inter-process communication mechanism and system processes.

+

Example: shared memory function

+

LOS_INIT_LEVEL_ARCH

+

Late initialization of the architecture.

+

This layer depends on the architecture extension function. Subsequent modules will initialize the modules on which they depend.

+

LOS_INIT_LEVEL_PLATFORM

+

Late initialization of the platform.

+

This layer depends on the board platform and drivers. Subsequent modules will initialize the modules on which they depend.

+

Example: initialization of the driver kernel abstraction layer (MMC and MTD)

+

LOS_INIT_LEVEL_KMOD_BASIC

+

Initialization of the kernel basic modules.

+

This layer is used to initialize the basic modules that can be detached from the kernel.

+

Example: VFS initialization

+

LOS_INIT_LEVEL_KMOD_EXTENDED

+

Initialization of the kernel extended modules.

+

This layer is used to initialize the extended modules that can be detached from the kernel.

+

Example: system call initialization, ProcFS initialization, Futex initialization, HiLog initialization, HiEvent initialization, and LiteIPC initialization

+

LOS_INIT_LEVEL_KMOD_TASK

+

Kernel task creation

+

This layer can be used to create kernel tasks (kernel thread and software timer tasks).

+

Example: creation of the resident resource reclaiming task, SystemInit task, and CPU usage statistics task.

+
+ + Adaptation for board porting. Focus on layers between **LOS\_INIT\_LEVEL\_ARCH** and **LOS\_INIT\_LEVEL\_KMOD\_TASK** and try to divide the initialization process into as many phases as possible for refined registration. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Modules at the same layer cannot depend on each other. It is recommended that a new module be split based on the preceding startup phase and be registered and started as required. + >You can view the symbol table in the **.rodata.init.kernel.\*** segment of the **OHOS\_Image.map** file generated after the build is complete, so as to learn about the initialization entry of each module that has been registered with the kernel startup framework and check whether the newly registered initialization entry takes effect. + + +### Programming Example + +In the board SDK file: + +``` +/* Header file of the kernel startup framework */ +#include "los_init.h" +...... + +/* Initialization function of the new module */ +unsigned int OsSampleModInit(void) +{ + PRINTK("OsSampleModInit SUCCESS!\n"); + ...... +} +...... +/* Register the new module at the target layer of the startup framework. */ +LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED); +``` + +## Verification + +``` +main core booting up... +OsSampleModInit SUCCESS! +releasing 1 secondary cores +cpu 1 entering scheduler +cpu 0 entering scheduler +``` + +According to the preceding information displayed during the system startup, the kernel calls the initialization function of the registered module during the startup to initialize the module. + +The system enters the kernel-space shell and the task commands can be properly executed. + +``` +OHOS # help +*******************shell commands:************************* + +arp cat cd chgrp chmod chown cp cpup +date dhclient dmesg dns format free help hwi +ifconfig ipdebug kill log ls lsfd memcheck mkdir +mount netstat oom partinfo partition ping ping6 pmm +pwd reset rm rmdir sem shm stack statfs +su swtmr sync systeminfo task telnet touch umount +uname v2p virstatfs vmm watch writeproc +``` + diff --git a/en/device-dev/porting/transplant-smallchip-kernel-linux.md b/en/device-dev/porting/transplant-smallchip-kernel-linux.md new file mode 100644 index 0000000000000000000000000000000000000000..3296d239e64311a2712ab66746be2f2e86c0fed2 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-kernel-linux.md @@ -0,0 +1,125 @@ +# Linux Kernel + +- [Overview](#section6282121355111) + - [Basic Information](#section19589322515) + - [Bootloader](#section19062510518) + +- [Adaptation, Building, Burning, and Startup](#section11112101695215) +- [Verification](#section17318153325311) + +## Overview + +Linux kernel porting involves basic kernel compilation, building, and verification after third-party chipset patches are installed based on the Linux kernel baseline. + +### Basic Information + +The current Linux kernel baseline evolves based on the Linux LTS version 4.19 and incorporates the CVE and bugfix patches. For details, see the [code library](https://gitee.com/openharmony/kernel_linux). The code path for the **repo** project is **kernel/linux-4.19**. + +### Bootloader + +You can use the Bootloader provided by the chipset vendor or open-source U-Boot to load the kernel image. For example, you can use [U-Boot](https://gitee.com/openharmony/device_hisilicon_third_party_uboot) for the Hi3516D V300 development board. + +## Adaptation, Building, Burning, and Startup + +1. Prepare the kernel configuration files, especially the chipset-related configuration files. + + Source code directory of the configuration files: **kernel/linux/config/** + + Create a **<_YOUR\_CHIP_\>\_small\_defconfig** file, such as **hi3516dv300\_small\_defconfig**, in the **linux-4.19/arch/arm/configs/** directory. The configuration file can be created by combining the general-purpose **small\_common\_defconfig** file and chipset-specific configurations. + +2. Prepare the chipset patches. + + Source code directory of the patch files: **kernel/linux/patches/linux-4.19** + + Create a **<_YOUR\_CHIP_\>\_patch** directory by referring to the existing patch directory **hi3516dv300\_small\_patch**, and place the related chipset patches, such as **hdf.patch** \(recommended\), in this directory. + +3. Build the code. + + In the project directory **kernel/linux/patches/**, after version-level build commands are passed to the **kernel\_module\_build.sh** and **kernel.mk** files, adapt the **patch** and **defconfig** configuration file paths, compiler, chipset architecture, and kernel image format. + + Adjust the patches based on build error logs. Typical error scenarios are as follows: + + \(1\) A conflict occurs in installing a patch. In this case, context adaptation is required. + + \(2\) The build fails due to kernel version mismatch. In this case, kernel adaptation is required, including function implementation adjustment. + + >![](../public_sys-resources/icon-caution.gif) **CAUTION:** + >- As in the **kernel.mk** file, patches are applied after the code environment of **kernel/linux-4.19** is copied during compilation and building of the OpenHarmony project. Retain the original code environment of **kernel/linux-4.19** before running the OpenHarmony version-level build command. + >- You can modify the patches in **out/<\*\*\*\>/kernel/linux-4.19**, to which the code environment is copied. + +4. Burn images and start the development board. + + The burning mode varies according to the development board of the chipset. Pay attention to the size of each burnt image and the configuration of the boot parameters. Below is the U-Boot parameter settings of Hi3516D V300: + + ``` + setenv bootargs 'mem=128M console=ttyAMA0,115200 root=/dev/mmcblk0p3 ro rootfstype=ext4 rootwait blkdevparts=mmcblk0:1M(boot),9M(kernel),50M(rootfs),50M(userfs)' + ``` + + +## Verification + +Debug the **init** process, start shell, and run a simple program in the user space to check whether the kernel porting is successful. Below is the OS image structure of the OpenHarmony [small system](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des-0000001105598722) and the Linux user-space program startup process. + +**Figure 1** OS image structure and user-space program startup process based on the Linux kernel + + +![](figure/en-us_image_0000001126354076.png) + +Based on the preceding process, the recommended verification procedure is as follows: + +1. Create a root file system image. + + Create a root file system image **rootfs.img** by following instructions in [Adding a Chipset Solution and a Product Solution](https://device.harmonyos.com/en/docs/develop/subsystems/oem_subsys_build_guide-0000001060378721). As shown in the preceding figure, the startup process is closely related to the product configuration. You need to complete the following configuration when creating **rootfs.img**: + + - Component configuration + + In the product component configuration file **_vendor_/\{_company_\}/\{_product_\}/config.json**, configure the **init\_lite** component of the startup subsystem and the **linux\_4\_1\_9** component of the kernel subsystem. + + - System service configuration + + Modify the system service configuration file **_vendor_/\{_company_\}/\{_product_\}/init\_configs/init\_xxx.cfg** to start the shell service. + + - File system configuration + + In the file system configuration file **_vendor_/\{_company_\}/\{_product_\}/fs.yml**, create the **/bin/sh -\> mksh** and **/lib/ld-musl-arm.so.1 -\> libc.so** soft links. These two files are the shell executable program and the c library on which the executable program depends, respectively. + + - Startup configuration + + In the **_vendor_/\{_company_\}/\{_product_\}/init\_configs/etc** directory, configure startup settings, including the **fstab**, **rsS**, and **S_xxx_** files. Configure the startup settings as needed. + + + After the build is complete, check the **rootfs** content in the product compilation output directory to determine whether the generated **rootfs.img** file meets the expectation. + +2. Debug the init process and shell. + + Burn **rootfs.img** and debug the init process and shell. The burning tools and processes vary according to the development board. Follow the instructions provided by the chipset solution vendor. Before burning **rootfs.img**, ensure that the bootloader and Linux kernel are started properly. When **rootfs.img** is properly mounted by the kernel, the **/bin/init** program is executed, indicating the start of the user space. + + The init process calls the **/etc/init.d/rcS** script. The **rcS** script runs the first command **/bin/mount -a** to load the **fstab** file. After the commands in this file are executed, **rcS** calls the **S_xxx_** scripts in sequence to create and scan for device nodes and configure file permissions. + + Then the init process reads the **init.cfg** system service configuration file and starts the shell as configured. If the preceding process is executed properly, the system enters the shell. + + If the init startup log contains the version number, the init program is started properly: + + **Figure 2** Log indicating that the init process is started properly + + + ![](figure/en-us_image_0000001172273945.jpg) + + After entering the shell, run the **ls** command. The following figure shows the information printed over the serial port. + + **Figure 3** Information printed after the ls command is executed in the shell + + + ![](figure/en-us_image_0000001172393865.jpg) + +3. Configure the NFS. + + After the init process and shell are started, run the following command in the root directory to enable the NFS service. In this example, the server IP address is 192.168.1.22 and the client IP address is 192.168.1.4. + + ``` + ifconfig eth0 192.168.1.4 netmask 255.255.255.0 + mkdir -p /storgage/nfs + mount -t nfs -o nolock,addr=192.168.1.22 192.168.1.22:/nfs /storage/nfs + ``` + + diff --git a/en/device-dev/porting/transplant-smallchip-kernel.md b/en/device-dev/porting/transplant-smallchip-kernel.md new file mode 100644 index 0000000000000000000000000000000000000000..cd252f8b951795654a29ecdc06cc83f1a9342c5b --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-kernel.md @@ -0,0 +1,7 @@ +# Kernel Porting + +- **[LiteOS Cortex-A](transplant-smallchip-kernel-a.md)** + +- **[Linux Kernel](transplant-smallchip-kernel-linux.md)** + + diff --git a/en/device-dev/porting/transplant-smallchip-prepare-building.md b/en/device-dev/porting/transplant-smallchip-prepare-building.md new file mode 100644 index 0000000000000000000000000000000000000000..b386a049feca70e65d61c8b234b6c4988b426b60 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-prepare-building.md @@ -0,0 +1,142 @@ +# Compilation and Building + +- [Compilation Environment Setup](#section3336103410314) +- [Introduction to the Compilation and Building Subsystem](#section354343816319) +- [Adding a Chipset Solution](#section18612153175011) + +## Compilation Environment Setup + +Set up the basic environment by following instructions in [Ubuntu Build Environment](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_environment_lin-0000001105407498). Both the user space and LiteOS Cortex-A kernel space are compiled using the LLVM compiler. If you choose to port the Linux kernel, run the following command to install the gcc-arm-linux-gnueabi cross compiler for compiling the Linux kernel-space image: + +``` +sudo apt-get install gcc-arm-linux-gnueabi +``` + +## Introduction to the Compilation and Building Subsystem + +To learn more about the compilation and building subsystem, including the compilation and building process, compilation scripts, and building chipset source code or single components, see [Compilation and Building](https://gitee.com/openharmony/docs/blob/master/en/device-dev/subsystems/compilation-and-building.md). + +## Adding a Chipset Solution + +After learning the compilation framework and setting up the compilation environment, perform the following steps to create a chipset solution: + +1. Create a category. + + The directory structure is as follows: device/\{_chipset solution vendor_\}/\{_development board_\}. For example, if you are using the hispark\_taurus development board from HiSilicon, create the following directory in the root directory of the code: + + ``` + mkdir -p device/hisilicon/hispark_taurus + ``` + + The chipset solution directory tree is as follows: + + ``` + device + └── company # Chipset solution vendor + └── board # Name of the development board + ├── BUILD.gn # Build script + ├── hals # Southbound APIs for OS adaptation + ├── linux # Linux kernel version (optional) + │ └── config.gni # Build options for the Linux version + └── liteos_a # LiteOS kernel version (optional) + └── config.gni # Build options for the LiteOS Cortex-A version + ``` + + For example, if you are porting the Linux kernel to the hispark\_taurus development board, the directory tree is as follows: + + ``` + device + └── hisilicon + └── hispark_tautus + ├── BUILD.gn + ├── hals + ├── ...... + └── linux + └── config.gni + ``` + + After the directory tree is created, store the source code related to the development board in the **hispark\_taurus** directory. + +2. Configure the build options of the development board. + + You can configure the build options in the **config.gni** file described in [1](#li20894101862). The compilation and building framework will then compile all OS components in the user space based on your configuration. The **config.gni** file contains the following key fields: + + ``` + kernel_type: kernel used by the development board, for example, liteos_a, liteos_m, or linux. + kernel_version: kernel version used by the development board, for example, 4.19. + board_cpu: CPU of the development board, for example, cortex-a7 or riscv32. + board_arch: chipset architecture of the development board, for example, armv7-a or rv32imac. + board_toolchain: name of the customized compiler used by the development board, for example, gcc-arm-none-eabi. If this field is not specified, ohos-clang will be used by default. + board_toolchain_prefix: prefix of the compiler, for example, gcc-arm-none-eabi. + board_toolchain_type: compiler type, for example, gcc or clang. Currently, only GCC and clang are supported. + board_cflags: build options of the .c file configured for the development board. + board_cxx_flags: build options of the .cpp file configured for the development board. + board_ld_flags: link options configured for the development board. + ``` + + For HiSilicon's hispark\_taurus development board, the content in **device/hisilicon/hispark\_taurus/config.gni** is as follows: + + ``` + # Board CPU type, e.g. "cortex-a7", "riscv32". + board_cpu = "cortex-a7" + + # Name of the compiler that is used for system building + # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. + # Note: The "ohos-clang" toolchain is used by default. You can also customize the toolchain. + board_toolchain = "mips-linux-gnu-gcc" + + # Path where the toolchain is installed, which can be left blank if the installation path has been added to ~/.bashrc. + board_toolchain_path = + rebase_path("//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/bin", + root_build_dir) + + # Prefix of the toolchain + board_toolchain_prefix = "arm-linux-ohoseabi-" + + # Type of the compiler, which can be gcc or clang + board_toolchain_type = "gcc" + + # Building flags related to the board + board_cflags = [ + ] + board_cxx_flags = [ + ] + board_ld_flags = [] + + # Board related headfiles search path. + board_include_dirs = [] + board_include_dirs += [ rebase_path( + "//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/target/usr/include", + root_build_dir) ] + + # Board adapter dir for OHOS components. + board_adapter_dir = "" + + # Sysroot path. + board_configed_sysroot = "" + + # Board storage type, it used for file system generation. + storage_type = "emmc" + ``` + +3. Edit the build script of the development board. + + In the **BUILD.gn** file described in 1, build code related to the development board, such as code for the on-device driver, on-device interface adaptation \(media and graphics\), and SDK on the development board. + + For example, edit the **device/hisilicon/hispark\_taurus/BUILD.gn** file as follows: + + ``` + # It is recommended that the group name be the same as the developer board name. + group("hispark_taurus") { + deps = [ "//kernel/linux/patches:linux_kernel" ] # Start kernel compilation. + deps += [ + ...... # Other compilation units of the development board + ] + } + ``` + +4. Start building and debugging. + + In the directory of the development board, run the **hb set** and **hb build** commands to start building the chipset solution. The compilation framework starts the building with the **BUILD.gn** file in the directory as the entry. + + diff --git a/en/device-dev/porting/transplant-smallchip-prepare-needs.md b/en/device-dev/porting/transplant-smallchip-prepare-needs.md new file mode 100644 index 0000000000000000000000000000000000000000..685a2a7a8cd49654abc2326776f3b8f276372af2 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-prepare-needs.md @@ -0,0 +1,98 @@ +# Before You Start + +This document provides guidance on how to port the Linux and LiteOS Cortex-A kernels on the OpenHarmony [small system](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des-0000001105598722) to a development board. It is intended for developers with experience in developing embedded systems. Before following instructions in this document, it is recommended that you familiarize yourself with [OpenHarmony](https://gitee.com/openharmony/docs/blob/master/en/OpenHarmony-Overview.md), including its technical architecture, directory structure, kernel subsystem, and driver subsystem. The following table lists the development boards that have been adapted to the small system. + +**Table 1** Development boards compatible with the OpenHarmony small system + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Development Board

+

Kernel

+

Architecture

+

ROM

+

RAM

+

File System

+

Flash Type

+

hispark_taurus

+

LiteOS Cortex-A and Linux 4.19

+

Arm Cortex-A7

+

8 GB

+

1 GB

+

VFAT, EXT4

+

eMMC4.5

+

hispark_aries

+

LiteOS-A

+

Arm Cortex-A7

+

16 MB

+

512 MB

+

JFFS2

+

SPI NOR

+
+ +In addition to the aforementioned development boards, LiteOS Cortex-A and Linux 4.19 can be ported to development boards that meet the requirements described in the table below. + +**Table 2** Requirements for porting OpenHarmony small system kernels + + + + + + + + + + + + + + + + + + + + + + +

Kernel

+

Supported Architecture

+

ROM

+

File System

+

Flash Type

+

LiteOS-A

+

ARMv7

+

> 2 MB

+

VFAT, JFFS2, YAFFS2

+

SPI NOR, NAND, eMMC

+

Linux 4.19

+

ARM, Arm64, MIPS, x86

+

> 5 MB

+

VFAT, JFFS2, YAFFS, EXT/2/3/4, NFS

+

NOR, NAND, eMMC

+
+ diff --git a/en/device-dev/porting/transplant-smallchip-prepare.md b/en/device-dev/porting/transplant-smallchip-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..91c9cecaa0bb12598425d416c72a58c4b0f992c7 --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip-prepare.md @@ -0,0 +1,7 @@ +# Porting Preparations + +- **[Before You Start](transplant-smallchip-prepare-needs.md)** + +- **[Compilation and Building](transplant-smallchip-prepare-building.md)** + + diff --git a/en/device-dev/porting/transplant-smallchip.md b/en/device-dev/porting/transplant-smallchip.md new file mode 100644 index 0000000000000000000000000000000000000000..818a9af1211dce6f85ee8d5c584fa0de10dfe3ad --- /dev/null +++ b/en/device-dev/porting/transplant-smallchip.md @@ -0,0 +1,9 @@ +# Small System SoC Porting Guide + +- **[Porting Preparations](transplant-smallchip-prepare.md)** + +- **[Kernel Porting](transplant-smallchip-kernel.md)** + +- **[Driver Porting](transplant-smallchip-drive.md)** + + diff --git a/en/device-dev/porting/transplant-thirdparty-cmake.md b/en/device-dev/porting/transplant-thirdparty-cmake.md new file mode 100644 index 0000000000000000000000000000000000000000..b8a9f3590019de6a82cdfcb992452b0013077d22 --- /dev/null +++ b/en/device-dev/porting/transplant-thirdparty-cmake.md @@ -0,0 +1,435 @@ +# Porting a Library Built Using CMake + +- [Source Code Acquisition](#section1771132116245) +- [Porting Guidelines](#section9737174410328) +- [Cross-Compilation](#section38205577332) + - [Compilation Reference](#section1088111263418) + - [Cross-Compilation Settings](#section8168182883515) + +- [Library Test](#section6686144293611) +- [Adding the Compiled double-conversion Library to the OpenHarmony Project](#section1651053153715) + +The following shows how to port the double-conversion library. + +## Source Code Acquisition + +Acquire the source code of double-conversion from [https://github.com/google/double-conversion](https://github.com/google/double-conversion). The following table lists the directory structure. + +**Table 1** Directory structure of the source code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

double-conversion/cmake/

+

Template used for building with CMake

+

double-conversion/double-conversion/

+

Directory of source files

+

double-conversion/msvc/

+

-

+

double-conversion/test/

+

Source files of the test cases

+

double-conversion/.gitignore

+

-

+

double-conversion/AUTHORS

+

-

+

double-conversion/BUILD

+

-

+

double-conversion/CMakeLists.txt

+

Top-level file used for building with CMake

+

double-conversion/COPYING

+

-

+

double-conversion/Changelog

+

-

+

double-conversion/LICENSE

+

-

+

double-conversion/Makefile

+

-

+

double-conversion/README.md

+

-

+

double-conversion/SConstruct

+

-

+

double-conversion/WORKSPACE

+

-

+
+ +## Porting Guidelines + +Cross-compile the double-conversion library by modifying the toolchain to generate executable files for the OpenHarmony platform and then add these files to the OpenHarmony project by invoking CMake via GN. + +## Cross-Compilation + +### Compilation Reference + +The [README.md](https://github.com/google/double-conversion/blob/master/README.md) file in the code repository details the procedures for compiling the double-conversion library using CMake as well as the testing methods. This document focuses on the building, compilation, and testing of the library. If you have any questions during library porting, refer to the **README.md** file. For porting of other third-party libraries that can be independently built with CMake, you can refer to the compilation guides provided by the libraries. + +### Cross-Compilation Settings + +The following steps show how to configure and modify the toolchains for cross-compiling the libraries built using CMake to compile executable files for the OpenHarmony platform. + +1. Configure the toolchains. + + Add configuration of the clang toolchains to the top-level file **CMakeLists.txt** listed in [Table 1](#table824211132418). + + ``` + set(CMAKE_CROSSCOMPILING TRUE) + set(CMAKE_SYSTEM_NAME Generic) + set(CMAKE_CXX_COMPILER_ID Clang) + set(CMAKE_TOOLCHAIN_PREFIX llvm-) + # Specify the C compiler (ensure that the path of the toolchain has been added to the PATH environment variable) and its flags. To perform cross-compilation using clang, the --target flag must be specified. + set(CMAKE_C_COMPILER clang) + set(CMAKE_C_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") + # Specify the C++ compiler (ensure that the path of the toolchain has been added to the PATH environment variable) and its flags. To perform cross-compilation, the --target flag must be specified. + set(CMAKE_CXX_COMPILER clang++) + set(CMAKE_CXX_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") + # Specify the linker and its flags. --target and --sysroot must be specified. You can specify OHOS_ROOT_PATH via the suffix parameter of the cmake command. + set(MY_LINK_FLAGS "--target=arm-liteos --sysroot=${OHOS_SYSROOT_PATH}") + set(CMAKE_LINKER clang) + set(CMAKE_CXX_LINKER clang++) + set(CMAKE_C_LINKER clang) + set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINKER} + ${MY_LINK_FLAGS} -o ") + set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINKER} + ${MY_LINK_FLAGS} -o ") + # Specify the path for searching chained libraries. + set(CMAKE_SYSROOT ${OHOS_SYSROOT_PATH}) + ``` + +2. Perform the compilation. + + Run a Linux command to enter the directory \(listed in [Table 1](#table824211132418)\) for storing double-conversion source files and then run the following commands: + + ``` + mkdir build && cd build + cmake .. -DBUILD_TESTING=ON -DOHOS_SYSROOT_PATH="..." + make -j + ``` + + **OHOS\_SYSROOT\_PATH** specifies the absolute path where **sysroot** is located. Taking OpenHarmony for example, set **OHOS\_SYSROOT\_PATH** to the absolute path of **openHarmony/prebuilts/lite/sysroot**. + +3. View the result. + + After step 2 is complete, a static library file and test cases are generated in the **build** directory. + + **Table 2** Directory structure of compiled files + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

double-conversion/build/libdouble-conversion.a

+

Static library file

+

double-conversion/build/test/

+

Test cases and CMake cache files

+

double-conversion/build/CMakeCache.txt

+

Cache files during CMake building

+

double-conversion/build/CMakeFiles/

+

-

+

double-conversion/build/cmake_install.cmake

+

-

+

double-conversion/build/CTestTestfile.cmake

+

-

+

double-conversion/build/DartConfiguration.tcl

+

-

+

double-conversion/build/generated/

+

-

+

double-conversion/build/Makefile

+

-

+

double-conversion/build/Testing/

+

-

+
+ + +## Library Test + +1. Set up the OpenHarmony environment. + + Using Hi3518EV300 as an example, compile the OpenHarmony image and burn it to the development board. For details, see [Developing the First Example Program Running on Hi3518](../quick-start/quickstart-lite-steps-board3518-running.md). + + The following screen is displayed after a successful login to the OS. + + **Figure 1** Successful startup of OpenHarmony + ![](figure/successful-startup-of-openharmony.png "successful-startup-of-openharmony") + +2. Mount the **nfs** directory and put the executable file **cctest** into the **test** directory \(listed in [Table 2](#table1452412391911)\) to the **nfs** directory. +3. Perform the test cases. + + If the double-conversion library is not cross-compiled, you can execute the test cases by running the **make test** command and obtain the result via CMake. However, this command is not applicable to the library after cross-compilation. This way, you can perform the test cases by executing the generated test case files. + + - After the **nfs** directory is successfully mounted, run the following command to list all items in the test cases: + + ``` + cd nfs + ./cctest --list + ``` + + Some items are as follows: + + ``` + test-bignum/Assign< + test-bignum/ShiftLeft< + test-bignum/AddUInt64< + test-bignum/AddBignum< + test-bignum/SubtractBignum< + test-bignum/MultiplyUInt32< + test-bignum/MultiplyUInt64< + test-bignum/MultiplyPowerOfTen< + test-bignum/DivideModuloIntBignum< + test-bignum/Compare< + test-bignum/PlusCompare< + test-bignum/Square< + test-bignum/AssignPowerUInt16< + test-bignum-dtoa/BignumDtoaVariousDoubles< + test-bignum-dtoa/BignumDtoaShortestVariousFloats< + test-bignum-dtoa/BignumDtoaGayShortest< + test-bignum-dtoa/BignumDtoaGayShortestSingle< + test-bignum-dtoa/BignumDtoaGayFixed< + test-bignum-dtoa/BignumDtoaGayPrecision< + test-conversions/DoubleToShortest< + test-conversions/DoubleToShortestSingle< + ... + ``` + + - Run the following command to test **test-bignum**: + + ``` + ./cctest test-bignum + ``` + + The test is passed if the following information is displayed: + + ``` + Ran 13 tests. + ``` + + +## Adding the Compiled double-conversion Library to the OpenHarmony Project + +1. Copy the double-conversion library to the OpenHarmony project. + + Copy this library that can be cross-compiled to the **third\_party** directory of OpenHarmony. To avoid modifying the **BUILD.gn** file in the directory of the third-party library to be ported, add a directory to store adaptation files, including **BUILD.gn**, **build\_thirdparty.py**, and **config.gni**, for converting GN to CMake building. + + **Table 3** Directory structure of the ported library + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

openHarmony/third_party/double-conversion/BUILD.gn

+

GN file for adding the third-party library to the OpenHarmony project

+

openHarmony/third_party/double-conversion/build_thirdparty.py

+

Script file for GN to call the shell command to convert compilation from GN to CMake.

+

openHarmony/third_party/double-conversion/config.gni

+

Third-party library compilation configuration file, which can be modified to determine whether the test cases will be used during the building

+

openHarmony/third_party/double-conversion/double-conversion/

+

Directory of the third-party library to be ported

+
+ +2. Add the GN file to the CMake adaptation file. + + - The following shows the implementation for building using the newly added **BUILD.gn** file. For other third-party libraries that can be independently compiled using CMake, you only need to change the target paths when porting them to OpenHarmony. + + ``` + import("config.gni") + group("double-conversion") { + if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + deps = [":make"] + } + } + if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + action("make") { + script = "//third_party/double-conversion/build_thirdparty.py" + outputs = ["$root_out_dir/log_dc.txt"] + exec_path = rebase_path(rebase_path("./build", ohos_third_party_dir)) + command = "rm * .* -rf && $CMAKE_TOOLS_PATH/cmake .. $CMAKE_FLAG $CMAKE_TOOLCHAIN_FLAG && make -j" + args = [ + "--path=$exec_path", + "--command=${command}" + ] + } + } + ``` + + - The newly added **config.gni** file is used to configure the library in the following example implementation. For other third-party libraries that can be independently compiled using CMake, you only need to change the configuration of **CMAKE\_FLAG** when porting them to OpenHarmony. + + ``` + #CMAKE_FLAG: config compile feature + CMAKE_FLAG = "-DBUILD_TESTING=ON -DCMAKE_CXX_STANDARD=11" + + #toolchain: follow up-layer, depend on $ohos_build_compiler + if (ohos_build_compiler == "clang") { + CMAKE_TOOLCHAIN_FLAG = "-DOHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" + } else { + CMAKE_TOOLCHAIN_FLAG = "" + } + + #CMake tools path,no need setting if this path already joined to $PATH. + CMAKE_TOOLS_PATH = "setting CMake tools path..." + ``` + + - The following shows the implementation of the newly added **build\_thirdparty.py** file. For other third-party libraries that can be independently compiled using CMake, you can port them to OpenHarmony without modifications. + + ``` + import os + import sys + from subprocess import Popen + import argparse + import shlex + + def cmd_exec(command): + cmd = shlex.split(command) + proc = Popen(cmd) + proc.wait() + ret_code = proc.returncode + if ret_code != 0: + raise Exception("{} failed, return code is {}".format(cmd, ret_code)) + + def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--path', help='Build path.') + parser.add_argument('--command', help='Build command.') + parser.add_argument('--enable', help='enable python.', nargs='*') + args = parser.parse_args() + + if args.enable: + if args.enable[0] == 'false': + return + + if args.path: + curr_dir = os.getcwd() + os.chdir(args.path) + if args.command: + if '&&' in args.command: + command = args.command.split('&&') + for data in command: + cmd_exec(data) + else: + cmd_exec(args.command) + os.chdir(curr_dir) + + if __name__ == '__main__': + sys.exit(main()) + ``` + + - Add a configuration item in the configuration file to control compiling of the library. By default, library compilation is disabled. + + For example, add the following configuration to the **//build/lite/ohos\_var.gni** file: + + ``` + declare_args() { + ohos_build_thirdparty_migrated_from_fuchisa = true + } + ``` + +3. Build the library. + + - Manual building + + Execute the following command: + + ``` + hb build -T //third_party/double-conversion:double-conversion + ``` + + If the compilation is successful, a static library file and test cases will be generated in the [build](#li15717101715249) directory. + + diff --git a/en/device-dev/porting/transplant-thirdparty-makefile.md b/en/device-dev/porting/transplant-thirdparty-makefile.md new file mode 100644 index 0000000000000000000000000000000000000000..a6d80725a238b519b3b72950255ccfb1ed9050df --- /dev/null +++ b/en/device-dev/porting/transplant-thirdparty-makefile.md @@ -0,0 +1,309 @@ +# Porting a Library Built Using Makefile + +- [Source Code Acquisition](#section114115321416) +- [Cross-Compilation Settings](#section81263255384) +- [Library Test](#section1830015913391) +- [Adding the Compiled yxml Library to the OpenHarmony Project](#section1898016213406) + +The following shows how to port the yxml library. + +## Source Code Acquisition + +Acquire the source code of yxml from [the open-source repository](https://github.com/getdnsapi/yxml). The following table lists the directory structure. + +**Table 1** Directory structure of the source code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

yxml/bench/

+

Benchmark-related code

+

yxml/test/

+

Input and output files as well as scripts of the test cases

+

yxml/Makefile

+

File for organizing compilation

+

yxml/.gitattributes

+

-

+

yxml/.gitignore

+

-

+

yxml/COPYING

+

-

+

yxml/yxml.c

+

-

+

yxml/yxml.c.in

+

-

+

yxml/yxml-gen.pl

+

-

+

yxml/yxml.h

+

-

+

yxml/yxml.md

+

-

+

yxml/yxml-states

+

-

+
+ +## Cross-Compilation Settings + +The following steps show how to configure and modify the toolchains for cross-compiling the libraries built using CMake to compile executable files for the OpenHarmony platform. + +1. Configure the toolchains. + + Replace the original configuration of MakeFile \(listed in [Table 1](#table16520154171813)\) in the root directory of the yxml library with the following clang toolchains configuration. + + clang toolchains configuration: + + ``` + # Set the cross-compilation toolchain and ensure that the path of the toolchain has been added to the PATH environment variable. + CC:=clang + AR:=llvm-ar + # The --target and --sysroot flags must be specified. + CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g --target=arm-liteos -march=armv7-a --sysroot=$(OHOS_ROOT_PATH)prebuilts/lite/sysroot + ``` + + Original configuration: + + ``` + CC:=gcc + AR:=ar + CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g + ``` + +2. Perform the compilation. + + Run a Linux command to enter the directory \(listed in [Table 1](#table16520154171813)\) for storing yxml source files and then run the following command: + + ``` + make test OHOS_SYSROOT_PATH=... + ``` + + **OHOS\_SYSROOT\_PATH** specifies the absolute path of the directory where **sysroot** is located. Taking OpenHarmony for example, set **OHOS\_SYSROOT\_PATH** to the absolute path of **prebuilts/lite/sysroot/**. + +3. View the result. + + After step 2 is complete, a static library file and test case are generated in the **out** directory of the yxml library. + + **Table 2** Directory structure of compiled files + + + + + + + + + + + + + +

Directory

+

Description

+

openHarmony/third_party/yxml/yxml/out/lib/

+

Static library file

+

openHarmony/third_party/yxml/yxml/out/test/

+

Test cases as well as the input and output files

+
+ + +## Library Test + +The test procedure for the yxml library is similar to that for the double-conversion library. For details, see the procedure described in [Porting a Library Built Using CMake](transplant-thirdparty-cmake.md#section6686144293611). The following describes how to use the test cases of the yxml library. + +**Table 3** Directory structure of the test directory + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

openHarmony/third_party/yxml/yxml/out/test/test.sh

+

Automatic test script, which cannot be used because OpenHarmony does not support automatic script execution. However, you can refer to this script to conduct a manual test.

+

openHarmony/third_party/yxml/yxml/out/test/test

+

Executable file for testing.

+

openHarmony/third_party/yxml/yxml/out/test/*.xml

+

Input test file.

+

openHarmony/third_party/yxml/yxml/out/test/*.out

+

Expected output file.

+
+ +The content of the **test.sh** file is as follows: + +``` +#!/bin/sh +for i in *.xml; do + b=`basename $i .xml` + o=${b}.out + t=${b}.test + ./test <$i >$t + if [ -n "`diff -q $o $t`" ]; then + echo "Test failed for $i:" + diff -u $o $t + exit 1 + fi +done +echo "All tests completed successfully." +``` + +The shell of OpenHarmony does not support input and output redirection symbols \(< and \>\). During the test, you need to copy the content in the **_\*_.xml** file to the shell and press **Enter**. The output content is displayed in the shell screen. + +The following operations are performed based on the assumption that the OpenHarmony environment has been set up and the **nfs** directory has been mounted and accessed. + +1. Execute the following command: + + ``` + ./test + ``` + +2. Copy the content in the **_\*_.xml** file to shell. + + Taking the **pi01.xml** file in the [test](#table115941423164318) directory as an example, copy the following content to shell and press **Enter**: + + ``` + + ``` + +3. Check whether the output in the shell is the same as that of the **_\*_.out** file in the [test](#table115941423164318) directory. + + The output is as follows: + + ``` + pistart SomePI + picontent abc + piend + elemstart a + elemend + ok + ``` + + The output is the same as the **pi01.out** file in the [test](#table115941423164318) directory. The test is passed. + + +## Adding the Compiled yxml Library to the OpenHarmony Project + +The procedure for adding the yxml library is almost the same as that for adding the double-conversion library, except that the implementation of **build.gn** and **config.gni** files. For details, see the procedure described in [Porting a Library Built Using CMake](transplant-thirdparty-cmake.md#section1651053153715). + +- The implementation of the newly added **BUILD.gn** file in the yxml library is as follows: + +``` +import("config.gni") +group("yxml") { + if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + deps = [":make"] + } +} +if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + action("make") { + script = "//third_party/yxml/build_thirdparty.py" + outputs = ["$target_out_dir/log_yxml.txt"] + exec_path = rebase_path(rebase_path("./yxml", root_build_dir)) + command = "make clean && $MAKE_COMMAND" + args = [ + "--path=$exec_path", + "--command=${command}" + ] + } +} +``` + +- The configuration of the newly added **config.gni** file in the yxml library is as follows: + +``` +TEST_ENABLE = "YES" + +if (TEST_ENABLE == "YES") { + MAKE_COMMAND = "make test OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" +} else { + MAKE_COMMAND = "make OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" +} +``` + +- The following table lists the directory structure of the OpenHarmony project. + +**Table 4** Directory structure of the ported library + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

openHarmony/third_party/yxml/BUILD.gn

+

GN file for adding the third-party library to the OpenHarmony project

+

openHarmony/third_party/yxml/build_thirdparty.py

+

Script file for GN to call the shell command to convert compilation from GN to Makefile.

+

openHarmony/third_party/yxml/config.gni

+

Third-party library compilation configuration file, which can be modified to determine whether the test cases will be used during the building

+

openHarmony/third_party/yxml/yxml/

+

Directory of the third-party library to be ported

+
+ diff --git a/en/device-dev/porting/overview.md b/en/device-dev/porting/transplant-thirdparty-overview.md similarity index 100% rename from en/device-dev/porting/overview.md rename to en/device-dev/porting/transplant-thirdparty-overview.md diff --git a/en/device-dev/porting/transplant-thirdparty.md b/en/device-dev/porting/transplant-thirdparty.md new file mode 100644 index 0000000000000000000000000000000000000000..c8b071004faf57fb2255574649181cd04e7c12aa --- /dev/null +++ b/en/device-dev/porting/transplant-thirdparty.md @@ -0,0 +1,9 @@ +# Third-Party Library Porting Guide + +- **[Overview](transplant-thirdparty-overview.md)** + +- **[Porting a Library Built Using CMake](transplant-thirdparty-cmake.md)** + +- **[Porting a Library Built Using Makefile](transplant-thirdparty-makefile.md)** + + diff --git a/en/device-dev/porting/transplant.md b/en/device-dev/porting/transplant.md new file mode 100644 index 0000000000000000000000000000000000000000..059e5ea0f84e85155b49e626989d2585c81a56e4 --- /dev/null +++ b/en/device-dev/porting/transplant.md @@ -0,0 +1,9 @@ +# Porting + +- **[Third-Party Library Porting Guide](transplant-thirdparty.md)** + +- **[Mini System SoC Porting Guide](transplant-minichip.md)** + +- **[Small System SoC Porting Guide](transplant-smallchip.md)** + + diff --git a/en/device-dev/porting/xts.md b/en/device-dev/porting/xts.md deleted file mode 100644 index 95899d2212185d0bcad58051cc92371e42e41024..0000000000000000000000000000000000000000 --- a/en/device-dev/porting/xts.md +++ /dev/null @@ -1,63 +0,0 @@ -# XTS - -- [Introduction](#section6725155811454) - - [Adding the XTS Subsystem to the Building Component](#section46981118105417) - - [Executing ACTS Cases for the IoTLink Module](#section9489122319819) - - -## Introduction - -X Test Suite \(XTS\) is a set of OpenHarmony certification test suites. Currently, the application compatibility test suite \(ACTS\) is supported. The **test/xts** repository contains the **acts** directory and **tools** software package. - -- The **acts** directory stores the source code and configuration files of ACTS test cases. The ACTS helps device vendors detect the software incompatibility as early as possible and ensures that the software is compatible with OpenHarmony during the entire development process. -- The **tools** software package stores the test case development framework related to **acts**. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The startup of the XTS depends on the SAMGR module. - -The XTS adaptation consists of the following steps: - -1. Add the XTS subsystem to the building component. -2. Execute ACTS cases for the IoTLink module. - -### Adding the XTS Subsystem to the Building Component - -The following example shows how to add the XTS subsystem to the building component **hispark\_aries**: - -1. Add the definition of the XTS subsystem to the **vendor/hisilicon/hispark\_aries/config.json** file. - - ``` - { - "subsystem": "test", - "components": [ - { "component": "xts_acts", "features":[] }, - { "component": "xts_tools", "features":[] } - ] - }, - ``` - -2. Set the building type to the debug version so that the XTS subsystem can be built. - -### Executing ACTS Cases for the IoTLink Module - -The following example shows how to execute ACTS cases for the IoTLink module of **hispark\_aries**: - -1. Obtain the built image. - - Obtain the image from the **out/hispark\_pegasus/wifiiot\_hispark\_pegasus/** directory. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >To check whether the ACTS is integrated into the current image, check whether the corresponding **.a** file is compiled. - -2. Burn the image into the development board. -3. Execute the test by performing the following steps. - - Use a serial port tool to log in to the development board and save information about the serial port. - - - Restart the device and view serial port logs. - -4. Analyze the test result. - - View the serial port logs, whose format is as follows: - - - The log for each test suite starts with **Start to run test suite:** and ends with **xx Tests xx Failures xx Ignored**. - - diff --git a/en/device-dev/bundles/public_sys-resources/icon-caution.gif b/en/device-dev/public_sys-resources/icon-caution.gif similarity index 100% rename from en/device-dev/bundles/public_sys-resources/icon-caution.gif rename to en/device-dev/public_sys-resources/icon-caution.gif diff --git a/en/device-dev/bundles/public_sys-resources/icon-danger.gif b/en/device-dev/public_sys-resources/icon-danger.gif similarity index 100% rename from en/device-dev/bundles/public_sys-resources/icon-danger.gif rename to en/device-dev/public_sys-resources/icon-danger.gif diff --git a/en/device-dev/bundles/public_sys-resources/icon-note.gif b/en/device-dev/public_sys-resources/icon-note.gif similarity index 100% rename from en/device-dev/bundles/public_sys-resources/icon-note.gif rename to en/device-dev/public_sys-resources/icon-note.gif diff --git a/en/device-dev/bundles/public_sys-resources/icon-notice.gif b/en/device-dev/public_sys-resources/icon-notice.gif similarity index 100% rename from en/device-dev/bundles/public_sys-resources/icon-notice.gif rename to en/device-dev/public_sys-resources/icon-notice.gif diff --git a/en/device-dev/bundles/public_sys-resources/icon-tip.gif b/en/device-dev/public_sys-resources/icon-tip.gif similarity index 100% rename from en/device-dev/bundles/public_sys-resources/icon-tip.gif rename to en/device-dev/public_sys-resources/icon-tip.gif diff --git a/en/device-dev/bundles/public_sys-resources/icon-warning.gif b/en/device-dev/public_sys-resources/icon-warning.gif similarity index 100% rename from en/device-dev/bundles/public_sys-resources/icon-warning.gif rename to en/device-dev/public_sys-resources/icon-warning.gif diff --git a/en/device-dev/quick-start/Readme-EN.md b/en/device-dev/quick-start/Readme-EN.md index 7c52dded2505a5db6cd57a6614e2f3665ccf66e8..5918e119962acd7a10c1f97cc44404739148e0e9 100644 --- a/en/device-dev/quick-start/Readme-EN.md +++ b/en/device-dev/quick-start/Readme-EN.md @@ -1,42 +1,40 @@ -# Getting Started +# Getting Started -- [Overview](overview.md) -- [Mini and Small Systems](mini-and-small-systems.md) - - [Overview](overview-0.md) - - [Introduction to the Development Boards](introduction-to-the-development-boards.md) - - [Hi3861 Development Board](hi3861-development-board.md) - - [Hi3516 Development Board](hi3516-development-board.md) - - [Hi3518 Development Board](hi3518-development-board.md) +- [Mini and Small Systems](quickstart-lite.md) + - [Overview](quickstart-lite-overview.md) + - [Introduction to the Development Boards](quickstart-lite-introduction.md) + - [Hi3861 Development Board](quickstart-lite-introduction-hi3861.md) + - [Hi3516 Development Board](quickstart-lite-introduction-hi3516.md) + - [Hi3518 Development Board](quickstart-lite-introduction-hi3518.md) - - [Environment Setup](environment-setup.md) - - [Overview](overview-1.md) - - [Windows Development Environment](windows-development-environment.md) - - [Ubuntu Build Environment](ubuntu-build-environment.md) - - [FAQ](faq.md) + - [Environment Setup](quickstart-lite-env-setup.md) + - [Overview](quickstart-lite-env-setup-des.md) + - [Windows Development Environment](quickstart-lite-env-setup-win.md) + - [Ubuntu Build Environment](quickstart-lite-env-setup-lin.md) + - [FAQ](quickstart-lite-env-setup-faqs.md) - - [How to Develop](how-to-develop.md) - - [Hi3861](hi3861.md) - - [Setting Up the Environment](setting-up-the-environment.md) - - [WLAN Connection](wlan-connection.md) - - [Running a Hello World Program](running-a-hello-world-program.md) - - [FAQs](faqs.md) + - [How to Develop](quickstart-lite-steps.md) + - [Hi3861](quickstart-lite-steps-board3861.md) + - [Setting Up the Environment](quickstart-lite-steps-board3861-setting.md) + - [WLAN Connection](quickstart-lite-steps-board3861-connection.md) + - [Running a Hello World Program](quickstart-lite-steps-board3861-running.md) + - [FAQs](quickstart-lite-steps-board3861-faqs.md) - - [Hi3516](hi3516.md) - - [Setting Up the Environment](setting-up-the-environment-2.md) - - [Running a Hello OHOS Program](running-a-hello-ohos-program.md) - - [Developing a Driver](developing-a-driver.md) - - [FAQs](faqs-3.md) + - [Hi3516](quickstart-lite-steps-board3516.md) + - [Setting Up the Environment](quickstart-lite-steps-board3516-setting.md) + - [Running a Hello OHOS Program](quickstart-lite-steps-board3516-running.md) + - [Developing a Driver](quickstart-lite-steps-board3516-program.md) + - [FAQs](quickstart-lite-steps-board3516-faqs.md) - - [Hi3518](hi3518.md) - - [Setting Up the Environment](setting-up-the-environment-4.md) - - [Running a Hello OHOS Program](running-a-hello-ohos-program-5.md) - - [FAQs](faqs-6.md) - -- [Standard System](standard-system.md) - - [Introduction](introduction.md) - - [Setting Up Windows Development Environment](setting-up-windows-development-environment.md) - - [Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code](setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md) - - [Setting Up Ubuntu Development Environment with Installation Package and Building Source Code](setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md) - - [Burning Images](burning-images.md) - - [FAQs](faqs-7.md) + - [Hi3518](quickstart-lite-steps-board3518.md) + - [Setting Up the Environment](quickstart-lite-steps-board3518-setting.md) + - [Running a Hello OHOS Program](quickstart-lite-steps-board3518-running.md) + - [FAQs](quickstart-lite-steps-board3518-faqs.md) +- [Standard System](quickstart-standard.md) + - [Introduction](quickstart-standard-description.md) + - [Setting Up Windows Development Environment](quickstart-standard-windows-environment.md) + - [Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code](quickstart-standard-docker-environment.md) + - [Setting Up Ubuntu Development Environment with Installation Package and Building Source Code](quickstart-standard-package-environment.md) + - [Burning Images](quickstart-standard-burn.md) + - [FAQs](quickstart-standard-faq.md) \ No newline at end of file diff --git a/en/device-dev/quick-start/burning-images.md b/en/device-dev/quick-start/burning-images.md deleted file mode 100644 index b63966d94334be8ec473b7d641fb4f36c33b8866..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/burning-images.md +++ /dev/null @@ -1,205 +0,0 @@ -# Burning Images - -- [Next](#section5600113114323) - -Programming flash memory of a regular system requires DevEco Device Tool v2.2 Beta1 or later. - -The Hi3516DV300 of the Hi3516 series development boards supports programming flash memory of a regular system through the USB port, network port, or serial port, where: - -- **Windows system: Supports programming through the USB port, serial port, or network port** -- **Linux system: Supports programming through the serial port or network port \(Linux+Windows dual system: Also supports programming through the USB port\)** - -Except for environment setup, the operations of programming are the same for Windows and Linux. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Currently, the Hi3516D V300 development board supports system burning over the network port, USB port, or serial port. This document uses the network port as an example. For details about system burning over other ports, see [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681). - -### Prerequisites - -[Open a project](https://device.harmonyos.com/en/docs/ide/user-guides/open_project-0000001071680043) in DevEco Device Tool and select the folder where the file to be programmed is located. Select **Hi3516DV300** for the development board type and **Hb** for **Framework**. - -### Programming Flash Memory Through the Network Port - -The Hi3516DV300 supports programming through the network port in Windows or Linux. - -1. Connect the PC and the target development board through the power port, serial port, and network port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_camera_start_3516-0000001052670587). -2. Open Device Manager, then check and record the serial port number corresponding to the development board. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). - - ![](figures/en-us_image_0000001114129428.png) - -3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - - ![](figures/2021-01-27_170334-18.png) - -4. On the **Partition Configuration** tab page, enter the information about the files to be programmed, including the following. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Binary

-

Memory

-

System

-

Address

-

Length

-

Board

-

Type

-

fastboot

-

Select u-boot-hi3516dv300_emmc.bin.

-

emmc

-

none

-

0x000000

-

0x100000

-

Select hi3516dv300.

-

NA

-

boot

-

Select uImage.

-

emmc

-

none

-

0x100000

-

0xf00000

-

NA

-

updater

-

Select updater.img.

-

emmc

-

ext3/4

-

0x1000000

-

0x1400000

-

NA

-

misc

-

Leave it blank.

-

emmc

-

none

-

0x2400000

-

0x100000

-

NA

-

system

-

Select system.img.

-

emmc

-

ext3/4

-

0x2500000

-

0xceb00000

-

NA

-

vendor

-

Select vendor.img.

-

emmc

-

ext3/4

-

0xd1000000

-

0x10000000

-

NA

-

userdata

-

Select userdata.img.

-

emmc

-

ext3/4

-

0xe1000000

-

0x5b800000

-

NA

-
- - ![](figures/en-us_image_0000001160527611.png) - -5. On the **hi3516dv300** tab page, configure the programming options. - - - **upload\_port**: Select the serial port number obtained in step [2](#en-us_topic_0000001056443961_li1050616379507). - - **upload\_protocol**: Select the programming protocol **hiburn-net**. - - **upload\_partitions**: Select the file to be programmed, including the following: fastboot, boot, updater, misc, system, vendor, and userdata. - - ![](figures/en-us_image_0000001117621400.png) - -6. Check and set the IP address of the network adapter connected to the development board. For details, see [Setting the IP Address of the Network Port for Programming on Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/set_ipaddress-0000001141825075). -7. Set the IP address of the network port for programming: - - - **upload\_net\_server\_ip**: Select the IP address set in [6](en-us_topic_0000001056443961.md#li1558813168234), such as 192.168.1.2. - - **upload\_net\_client\_mask**: Set the subnet mask of the development board, such as 255.255.255.0. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. - - **upload\_net\_client\_gw**: Set the gateway of the development board, such as 192.168.1.1. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. - - **upload\_net\_client\_ip**: Set the IP address of the development board, such as 192.168.1.3. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. - - ![](figures/en-us_image_0000001117463460.png) - -8. When you finish modifying, click **Save** in the upper right corner. -9. Open the project file, go to ![](figures/2021-01-27_170334-19.png) \> **PROJECT TASKS** \> **fastboot** \> **Erase** to erase U-boot. - - ![](figures/en-us_image_0000001163045527.png) - -10. When the following message is displayed, power off the development board and then power it on. - - ![](figures/en-us_image_0000001114129432.png) - -11. Start programming. When the following message is displayed, it indicates that the programming is successful. - - ![](figures/en-us_image_0000001113969542.png) - - -## Next - -Congratulations! You have completed the quick start for the standard system. Get yourself familiar with OpenHarmony by a [Development Example for Clock App](../guide/development-example-for-clock-apps.md). - diff --git a/en/device-dev/quick-start/developing-a-driver.md b/en/device-dev/quick-start/developing-a-driver.md deleted file mode 100644 index 46e8fc8d73366f89a16d84312e418e2c0a7d60b3..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/developing-a-driver.md +++ /dev/null @@ -1,503 +0,0 @@ -# Developing a Driver - -- [Introduction to Driver](#s8efc1952ebfe4d1ea717182e108c29bb) -- [Compiling and Burning](#section660016185110) -- [Running an Image](#section333215226219) -- [Follow-up Learning](#section9712145420182) - -This section describes how to develop a driver on the board, including introduction, compilation, burning, and running of the driver. - -## Introduction to Driver - -The following operations take a HDF-based UART driver as an example to show how to add configuration files, code the driver, and compile the code for interactions between the user-space applications and the driver. The driver source code is stored in the **vendor/huawei/hdf/sample** directory. - -1. Add Configurations. - - Add driver configurations to the HDF driver configuration file \(for example, **device/hisilicon/hi3516dv300/sdk\_liteos/config/uart/uart\_config.hcs**\). - - ``` - root { - platform { - uart_sample { - num = 5; // UART device number - base = 0x120a0000; // Base address of the UART register - irqNum = 38; - baudrate = 115200; - uartClk = 24000000; - wlen = 0x60; - parity = 0; - stopBit = 0; - match_attr = "sample_uart_5"; - } - } - } - ``` - - Add the device node information to the HDF device configuration file \(for example, **vendor/hisilicon/ipcamera\_hi3516dv300\_liteos/config/device\_info/device\_info.hcs**\) - - ``` - root { - device_info { - platform :: host { - hostName = "platform_host"; - priority = 50; - device_uart :: device { - device5 :: deviceNode { - policy = 2; - priority = 10; - permission = 0660; - moduleName = "UART_SAMPLE"; - serviceName = "HDF_PLATFORM_UART_5"; - deviceMatchAttr = "sample_uart_5"; - } - } - } - } - } - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >The configuration files are in the same path as the source code of the UART driver. You need to manually add the files to the path of the Hi3516D V300 development board. - -2. Register a UART driver entry. - - Register the **HdfDriverEntry** of the UART driver with the HDF. - - ``` - // Bind the UART driver interface to the HDF. - static int32_t SampleUartDriverBind(struct HdfDeviceObject *device) - { - struct UartHost *uartHost = NULL; - - if (device == NULL) { - return HDF_ERR_INVALID_OBJECT; - } - HDF_LOGI("Enter %s:", __func__); - - uartHost = UartHostCreate(device); - if (uartHost == NULL) { - HDF_LOGE("%s: UartHostCreate failed", __func__); - return HDF_FAILURE; - } - uartHost->service.Dispatch = SampleDispatch; - return HDF_SUCCESS; - } - - // Obtain configuration information from the HCS of the UART driver. - static uint32_t GetUartDeviceResource( - struct UartDevice *device, const struct DeviceResourceNode *resourceNode) - { - struct UartResource *resource = &device->resource; - struct DeviceResourceIface *dri = NULL; - dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (dri == NULL || dri->GetUint32 == NULL) { - HDF_LOGE("DeviceResourceIface is invalid"); - return HDF_FAILURE; - } - - if (dri->GetUint32(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read num fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "base", &resource->base, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read base fail"); - return HDF_FAILURE; - } - resource->physBase = (unsigned long)OsalIoRemap(resource->base, 0x48); - if (resource->physBase == 0) { - HDF_LOGE("uart config fail to remap physBase"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "irqNum", &resource->irqNum, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read irqNum fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "baudrate", &resource->baudrate, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read baudrate fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "wlen", &resource->wlen, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read wlen fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "parity", &resource->parity, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read parity fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "stopBit", &resource->stopBit, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read stopBit fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "uartClk", &resource->uartClk, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read uartClk fail"); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - - // Attach the configuration and interface of the UART driver to the HDF. - static int32_t AttachUartDevice(struct UartHost *host, struct HdfDeviceObject *device) - { - int32_t ret; - struct UartDevice *uartDevice = NULL; - if (device->property == NULL) { - HDF_LOGE("%s: property is NULL", __func__); - return HDF_FAILURE; - } - uartDevice = (struct UartDevice *)OsalMemCalloc(sizeof(struct UartDevice)); - if (uartDevice == NULL) { - HDF_LOGE("%s: OsalMemCalloc uartDevice error", __func__); - return HDF_ERR_MALLOC_FAIL; - } - ret = GetUartDeviceResource(uartDevice, device->property); - if (ret != HDF_SUCCESS) { - (void)OsalMemFree(uartDevice); - return HDF_FAILURE; - } - host->num = uartDevice->resource.num; - host->priv = uartDevice; - AddUartDevice(host); - return InitUartDevice(uartDevice); - } - - // Initialize the UART driver. - static int32_t SampleUartDriverInit(struct HdfDeviceObject *device) - { - int32_t ret; - struct UartHost *host = NULL; - - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_OBJECT; - } - HDF_LOGI("Enter %s:", __func__); - host = UartHostFromDevice(device); - if (host == NULL) { - HDF_LOGE("%s: host is NULL", __func__); - return HDF_FAILURE; - } - ret = AttachUartDevice(host, device); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: attach error", __func__); - return HDF_FAILURE; - } - host->method = &g_sampleUartHostMethod; - return ret; - } - - static void DeinitUartDevice(struct UartDevice *device) - { - struct UartRegisterMap *regMap = (struct UartRegisterMap *)device->resource.physBase; - /* Wait for the UART to enter the idle state. */ - while (UartPl011IsBusy(regMap)); - UartPl011ResetRegisters(regMap); - uart_clk_cfg(0, false); - OsalIoUnmap((void *)device->resource.physBase); - device->state = UART_DEVICE_UNINITIALIZED; - } - - // Detach and release the UART driver. - static void DetachUartDevice(struct UartHost *host) - { - struct UartDevice *uartDevice = NULL; - - if (host->priv == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return; - } - uartDevice = host->priv; - DeinitUartDevice(uartDevice); - (void)OsalMemFree(uartDevice); - host->priv = NULL; - } - - // Release the UART driver. - static void SampleUartDriverRelease(struct HdfDeviceObject *device) - { - struct UartHost *host = NULL; - HDF_LOGI("Enter %s:", __func__); - - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return; - } - host = UartHostFromDevice(device); - if (host == NULL) { - HDF_LOGE("%s: host is NULL", __func__); - return; - } - if (host->priv != NULL) { - DetachUartDevice(host); - } - UartHostDestroy(host); - } - - struct HdfDriverEntry g_sampleUartDriverEntry = { - .moduleVersion = 1, - .moduleName = "UART_SAMPLE", - .Bind = SampleUartDriverBind, - .Init = SampleUartDriverInit, - .Release = SampleUartDriverRelease, - }; - - HDF_INIT(g_sampleUartDriverEntry); - ``` - -3. Register a UART driver interface. - - Implement the UART driver interface using the template **UartHostMethod** provided by the HDF. - - ``` - static int32_t SampleUartHostInit(struct UartHost *host) - { - HDF_LOGI("%s: Enter", __func__); - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - return HDF_SUCCESS; - } - - static int32_t SampleUartHostDeinit(struct UartHost *host) - { - HDF_LOGI("%s: Enter", __func__); - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - return HDF_SUCCESS; - } - - // Write data into the UART device. - static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size) - { - HDF_LOGI("%s: Enter", __func__); - uint32_t idx; - struct UartRegisterMap *regMap = NULL; - struct UartDevice *device = NULL; - - if (host == NULL || data == NULL || size == 0) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - device = (struct UartDevice *)host->priv; - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_PARAM; - } - regMap = (struct UartRegisterMap *)device->resource.physBase; - for (idx = 0; idx < size; idx++) { - UartPl011Write(regMap, data[idx]); - } - return HDF_SUCCESS; - } - - // Set the baud rate for the UART device. - static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate) - { - HDF_LOGI("%s: Enter", __func__); - struct UartDevice *device = NULL; - struct UartRegisterMap *regMap = NULL; - UartPl011Error err; - - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - device = (struct UartDevice *)host->priv; - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_PARAM; - } - regMap = (struct UartRegisterMap *)device->resource.physBase; - if (device->state != UART_DEVICE_INITIALIZED) { - return UART_PL011_ERR_NOT_INIT; - } - if (baudRate == 0) { - return UART_PL011_ERR_INVALID_BAUD; - } - err = UartPl011SetBaudrate(regMap, device->uartClk, baudRate); - if (err == UART_PL011_ERR_NONE) { - device->baudrate = baudRate; - } - return err; - } - - // Obtain the baud rate of the UART device. - static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate) - { - HDF_LOGI("%s: Enter", __func__); - struct UartDevice *device = NULL; - - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - device = (struct UartDevice *)host->priv; - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_PARAM; - } - *baudRate = device->baudrate; - return HDF_SUCCESS; - } - - // Bind the UART device using HdfUartSampleInit. - struct UartHostMethod g_sampleUartHostMethod = { - .Init = SampleUartHostInit, - .Deinit = SampleUartHostDeinit, - .Read = NULL, - .Write = SampleUartHostWrite, - .SetBaud = SampleUartHostSetBaud, - .GetBaud = SampleUartHostGetBaud, - .SetAttribute = NULL, - .GetAttribute = NULL, - .SetTransMode = NULL, - }; - ``` - - Add the sample module of the UART driver to the compilation script **device/hisilicon/drivers/lite.mk**. - - ``` - LITEOS_BASELIB += -lhdf_uart_sample - LIB_SUBDIRS += $(LITEOS_SOURCE_ROOT)/vendor/huawei/hdf/sample/platform/uart - ``` - -4. Implement the code for interaction between the user-space applications and driver. - - Create the **/dev/uartdev-5** node after the UART driver is initialized successfully. The following example shows how to interact with the UART driver through the node. - - ``` - #include - #include - #include - #include "hdf_log.h" - - #define HDF_LOG_TAG "hello_uart" - #define INFO_SIZE 16 - - int main(void) - { - int ret; - int fd; - const char info[INFO_SIZE] = {" HELLO UART! "}; - - fd = open("/dev/uartdev-5", O_RDWR); - if (fd < 0) { - HDF_LOGE("hello_uart uartdev-5 open failed %d", fd); - return -1; - } - ret = write(fd, info, INFO_SIZE); - if (ret != 0) { - HDF_LOGE("hello_uart write uartdev-5 ret is %d", ret); - } - ret = close(fd); - if (ret != 0) { - HDF_LOGE("hello_uart uartdev-5 close failed %d", fd); - return -1; - } - return ret; - } - ``` - - Add the **hello\_uart\_sample** component to **targets** of the **hdf\_hi3516dv300\_liteos\_a** component in the **build/lite/components/drivers.json** file. - - ``` - { - "components": [ - { - "component": "hdf_hi3516dv300_liteos_a", - ... - "targets": [ - "//vendor/huawei/hdf/sample/platform/uart:hello_uart_sample" - ] - } - ] - } - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >Preceding code snippets are for reference only. You can view the complete sample code in **vendor/huawei/hdf/sample.** - >The sample code is not automatically compiled by default. You can add it to the compilation script. - - -## Compiling and Burning - -Compile and burn images by referring to [Building](../guide/development-example-for-platform-drivers.md)and [Burning](../guide/development-example-for-platform-drivers.md). - -## Running an Image - -1. Connect to a serial port. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >If the connection fails, rectify the fault by referring to [FAQs](../quick-start/faqs-3.md). - - **Figure 1** Serial port connection - - - ![](figures/chuankou1.png) - - 1. Click **Monitor** to enable the serial port. - 2. Press **Enter** repeatedly until **hisilicon** displays. - 3. Go to [2](running-a-hello-ohos-program.md#l5b42e79a33ea4d35982b78a22913b0b1) if the board is started for the first time or the startup parameters need to be modified; go to [3](running-a-hello-ohos-program.md#ld26f18828aa44c36bfa36be150e60e49) otherwise. - -2. \(Mandatory when the board is started for the first time\) Modify the **bootcmd** and **bootargs** parameters of U-Boot. You need to perform this step only once if the parameters need not to be modified during the operation. The board automatically starts after it is reset. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The default waiting time in the U-Boot is 2s. You can press **Enter** to interrupt the waiting and run the **reset** command to restart the system after "hisilicon" is displayed. - - **Table 1** Parameters of the U-Boot - - - - - - - - - - - - - - - - - - - -

Command

-

Description

-

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

-

Run this command to read content that has a size of 0x4800 (9 MB) and a start address of 0x800 (1 MB) to the memory address 0x80000000. The file size must be the same as that of the OHOS_Image.bin file in the IDE.

-

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

-

Run this command to set the output mode to serial port output, baud rate to 115200, data bit to 8, rootfs to be mounted to the emmc component, and file system type to vfat.

-

rootaddr=10M rootsize=20M rw indicates the start address and size of the rootfs.img file to be burnt, respectively. The file size must be the same as that of the rootfs.img file in the IDE.

-

saveenv

-

saveenv means to save the current configuration.

-

reset

-

reset means to reset the board.

-
- - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >**go 0x80000000** is optional. It 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, press **Enter** in the countdown phase of the U-Boot startup to interrupt the automatic startup. - -3. Run the **reset** command and press **Enter** to restart the board. After the board is restarted, **OHOS** is displayed when you press **Enter**. - - **Figure 2** System startup - - - ![](figures/qi1.png) - -4. In the root directory, run the **./bin/hello\_uart** command line to execute the demo program. The compilation result is shown in the following example. - - ``` - OHOS # ./bin/hello_uart - OHOS # HELLO UART! - ``` - - -## Follow-up Learning - -Congratulations! You have finished all steps! You are advised to go on learning how to develop [Cameras with a Screen](../guide/cameras-without-a-screen.md). - diff --git a/en/device-dev/quick-start/environment-setup.md b/en/device-dev/quick-start/environment-setup.md deleted file mode 100644 index 289f31965d0c38aea69d9ff15c917b6df62d8019..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/environment-setup.md +++ /dev/null @@ -1,11 +0,0 @@ -# Environment Setup - -- **[Overview](overview-1.md)** - -- **[Windows Development Environment](windows-development-environment.md)** - -- **[Ubuntu Build Environment](ubuntu-build-environment.md)** - -- **[FAQ](faq.md)** - - diff --git a/en/device-dev/quick-start/faqs-3.md b/en/device-dev/quick-start/faqs-3.md deleted file mode 100644 index 12c3a207b5cb348e0fc45f60c7985eacb886e61b..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/faqs-3.md +++ /dev/null @@ -1,172 +0,0 @@ -# FAQs - -- [What should I do when the images failed to be burnt over the selected serial port?](#section627268185113) -- [What should I do when Windows-based PC failed to be connected to the board?](#section195391036568) -- [What should I do when the image failed to be burnt?](#section571164016565) -- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#section1039835245619) -- [What should I do when no command output is displayed?](#section14871149155911) - -## What should I do when the images failed to be burnt over the selected serial port? - -- **Symptom** - - **Error: Opening COMxx: Access denied** is displayed after clicking **Burn** and selecting a serial port. - - **Figure 1** Failed to open the serial port - ![](figures/failed-to-open-the-serial-port.png "failed-to-open-the-serial-port") - -- **Possible Causes** - - The serial port has been used. - -- **Solutions** - -1. Search for the terminal using serial-xx from the drop-down list in the **TERMINAL** panel. - - **Figure 2** Checking whether the serial port is used - ![](figures/checking-whether-the-serial-port-is-used.png "checking-whether-the-serial-port-is-used") - -2. Click the dustbin icon as shown in the following figure to disable the terminal using the serial port. - - **Figure 3** Disabling the terminal using the serial port - ![](figures/disabling-the-terminal-using-the-serial-port.png "disabling-the-terminal-using-the-serial-port") - -3. Click **Burn**, select the serial port, and start burning images again. - - **Figure 4** Restarting burning - - - ![](figures/changjian1.png) - - -## What should I do when Windows-based PC failed to be connected to the board? - -- **Symptom** - - The file image cannot be obtained after clicking **Burn** and selecting a serial port. - - **Figure 5** Failed to obtain the image file due to unavailable connection - ![](figures/failed-to-obtain-the-image-file-due-to-unavailable-connection.png "failed-to-obtain-the-image-file-due-to-unavailable-connection") - -- **Possible Causes** - - The board is disconnected from the Windows-based PC. - - Windows Firewall does not allow Visual Studio Code to access the network. - -- **Solutions** - -1. Check whether the network cable is properly connected. -2. Click **Windows Firewall**. - - **Figure 6** Network and firewall setting - ![](figures/network-and-firewall-setting.png "network-and-firewall-setting") - -3. Click **Firewall & network protection**, and on the displayed page, click **Allow applications to communicate through Windows Firewall**. - - **Figure 7** Firewall and network protection - ![](figures/firewall-and-network-protection.png "firewall-and-network-protection") - -4. Select the Visual Studio Code application. - - **Figure 8** Selecting the Visual Studio Code application - ![](figures/selecting-the-visual-studio-code-application.png "selecting-the-visual-studio-code-application") - -5. Select the **Private** and **Public** network access rights for the Visual Studio Code application. - - **Figure 9** Allowing the Visual Studio Code application to access the network - ![](figures/allowing-the-visual-studio-code-application-to-access-the-network.png "allowing-the-visual-studio-code-application-to-access-the-network") - - -## What should I do when the image failed to be burnt? - -- **Symptom** - - The burning status is not displayed after clicking **Burn** and selecting a serial port. - -- **Possible Causes** - - The IDE is not restarted after the DevEco plug-in is installed. - -- **Solutions** - - Restart the IDE. - - -## What should I do when the message indicating Python cannot be found is displayed during compilation and building? - -- **Symptom** - - ![](figures/en-us_image_0000001174270715.png) - - -- **Possible Cause 1**: Python is not installed. -- **Solutions** - - Install Python by referring to [Installing and Configuring Python](../quick-start/ubuntu-build-environment.md). - -- **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. - - ![](figures/en-us_image_0000001128470880.png) - -- **Solutions** - - Run the following commands: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - Example: - - ![](figures/en-us_image_0000001174270713.png) - - -## What should I do when no command output is displayed? - -- **Symptom** - - The serial port shows that the connection has been established. After the board is restarted, nothing is displayed when you press **Enter**. - -- **Possible Cause 1** - - The serial port is connected incorrectly. - -- **Solutions** - - Change the serial port number. - - Start **Device Manager** to check whether the serial port connected to the board is the same as that connected to the terminal device. If the serial ports are different, perform step [1](../quick-start/running-a-hello-ohos-program.md) in the **Running an Image** section to change the serial port number. - - -- **Possible Cause 2** - - The U-boot of the board is damaged. - -- **Solutions** - - Burn the U-boot. - - If the fault persists after you perform the preceding operations, the U-boot of the board may be damaged. You can burn the U-boot by performing the following steps: - - -1. Obtain the U-boot file. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The U-boot file of the two boards can be obtained from the following paths, respectively. - >Hi3516D V300: **device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin** - >Hi3518E V300: **device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin** - -2. Burn the U-boot file by following the procedures for burning a U-boot file over USB. - - Select the U-boot files of corresponding development boards for burning by referring to [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Programming Flash Memory on the Hi3518](https://device.harmonyos.com/en/docs/ide/user-guides/hi3518_upload-0000001057313128) - -3. Log in to the serial port after the burning is complete. - - **Figure 10** Serial port displayed after the U-boot is burnt - ![](figures/serial-port-displayed-after-the-u-boot-is-burnt.png "serial-port-displayed-after-the-u-boot-is-burnt") - - diff --git a/en/device-dev/quick-start/faqs-6.md b/en/device-dev/quick-start/faqs-6.md deleted file mode 100644 index 05d53356aed9ab16ac8fe65e19da9dbe70089533..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/faqs-6.md +++ /dev/null @@ -1,174 +0,0 @@ -# FAQs - -- [What should I do when the images failed to be burnt over the selected serial port?](#section1498892119619) -- [What should I do when Windows-based PC failed to be connected to the board?](#section8512971816) -- [What should I do when the image failed to be burnt?](#section1767804111198) -- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#en-us_topic_0000001053466255_section1039835245619) -- [What should I do when no command output is displayed?](#en-us_topic_0000001053466255_section14871149155911) - -## What should I do when the images failed to be burnt over the selected serial port? - -- **Symptom** - - **Error: Opening COMxx: Access denied** is displayed after clicking **Burn** and selecting a serial port. - - **Figure 1** Failed to open the serial port - ![](figures/failed-to-open-the-serial-port-8.png "failed-to-open-the-serial-port-8") - -- **Possible Causes** - - The serial port has been used. - -- **Solutions** - -1. Search for the terminal using serial-xx from the drop-down list in the **TERMINAL** panel. - - **Figure 2** Checking whether the serial port is used - ![](figures/checking-whether-the-serial-port-is-used-9.png "checking-whether-the-serial-port-is-used-9") - -2. Click the dustbin icon as shown in the following figure to disable the terminal using the serial port. - - **Figure 3** Disabling the terminal using the serial port - ![](figures/disabling-the-terminal-using-the-serial-port-10.png "disabling-the-terminal-using-the-serial-port-10") - -3. Click **Burn**, select the serial port, and start burning images again. - - **Figure 4** Restarting burning - - - ![](figures/changjian1-11.png) - - -## What should I do when Windows-based PC failed to be connected to the board? - -- **Symptom** - - The file image cannot be obtained after clicking **Burn** and selecting a serial port. - - **Figure 5** Failed to obtain the image file due to unavailable connection - ![](figures/failed-to-obtain-the-image-file-due-to-unavailable-connection-12.png "failed-to-obtain-the-image-file-due-to-unavailable-connection-12") - -- **Possible Causes** - - The board is disconnected from the Windows-based PC. - - Windows Firewall does not allow Visual Studio Code to access the network. - -- **Solutions** - -1. Check whether the network cable is properly connected. -2. Click **Windows Firewall**. - - **Figure 6** Network and firewall setting - ![](figures/network-and-firewall-setting-13.png "network-and-firewall-setting-13") - -3. Click **Firewall & network protection**, and on the displayed page, click **Allow applications to communicate through Windows Firewall**. - - **Figure 7** Firewall and network protection - ![](figures/firewall-and-network-protection-14.png "firewall-and-network-protection-14") - -4. Select the Visual Studio Code application - - **Figure 8** Selecting the Visual Studio Code application - ![](figures/selecting-the-visual-studio-code-application-15.png "selecting-the-visual-studio-code-application-15") - -5. Select the **Private** and **Public** network access rights for the Visual Studio Code application. - - **Figure 9** Allowing the Visual Studio Code application to access the network - ![](figures/allowing-the-visual-studio-code-application-to-access-the-network-16.png "allowing-the-visual-studio-code-application-to-access-the-network-16") - - -## What should I do when the image failed to be burnt? - -- **Symptom** - - The burning status is not displayed after clicking **Burn** and selecting a serial port. - -- **Possible Causes** - - The IDE is not restarted after the DevEco plug-in is installed. - -- **Solutions** - - Restart the IDE. - - -## What should I do when the message indicating Python cannot be found is displayed during compilation and building? - -- **Symptom** - - ![](figures/en-us_image_0000001174270743.png) - - -- **Possible Cause 1** - - Python is not installed. - -- **Solutions** - - Install Python by referring to [Installing and Configuring Python](../quick-start/ubuntu-build-environment.md). - -- **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. - - ![](figures/en-us_image_0000001174270739.png) - -- **Solutions** - - Run the following commands: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - Example: - - ![](figures/en-us_image_0000001174350661.png) - - -## What should I do when no command output is displayed? - -- **Symptom** - - The serial port shows that the connection has been established. After the board is restarted, nothing is displayed when you press **Enter**. - -- **Possible Cause 1** - - The serial port is connected incorrectly. - -- **Solutions** - - Change the serial port number. - - Start **Device Manager** to check whether the serial port connected to the board is the same as that connected to the terminal device. If the serial ports are different, perform step [1](../quick-start/running-a-hello-ohos-program.md) in the **Running an Image** section to change the serial port number. - - -- **Possible Cause 2** - - The U-boot of the board is damaged. - -- **Solutions** - - Burn the U-boot. - - If the fault persists after you perform the preceding operations, the U-boot of the board may be damaged. You can burn the U-boot by performing the following steps: - - -1. Obtain the U-boot file. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The U-boot file of the two boards can be obtained from the following paths, respectively. - >Hi3516D V300: **device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin** - >Hi3518E V300: **device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin** - -2. Burn the U-boot file by following the procedures for burning a U-boot file over USB. - - Select the U-boot files of corresponding development boards for burning by referring to [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Programming Flash Memory on the Hi3518](https://device.harmonyos.com/en/docs/ide/user-guides/hi3518_upload-0000001057313128) - -3. Log in to the serial port after the burning is complete. - - ![](figures/en-us_image_0000001174350659.png) - - diff --git a/en/device-dev/quick-start/faqs.md b/en/device-dev/quick-start/faqs.md deleted file mode 100644 index 43db6c0373612483fa0cc1e752058e256bf9665e..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/faqs.md +++ /dev/null @@ -1,286 +0,0 @@ -# FAQs - -- [What should I do when the message configure: error: no acceptable C compiler found in $PATH is displayed during Python 3 installation?](#section1221016541119) -- [What should I do when the message -bash: make: command not found is displayed during Python 3 installation?](#section1913477181213) -- [What should I do when the message zlib not available is displayed during Python 3 installation?](#section108211415131210) -- [What should I do when the message No module named '\_ctypes' is displayed during Python 3 installation?](#section2062268124) -- [What should I do when the message No module named 'Crypto' is displayed during compilation and building?](#section982315398121) -- [What should I do when the message No module named 'ecdsa' is displayed during compilation and building?](#section102035451216) -- [What should I do when the message Could not find a version that satisfies the requirement six\>=1.9.0 is displayed during compilation and building?](#section4498158162320) -- [What should I do when the message cannot find -lgcc is displayed during compilation and building?](#section11181036112615) -- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#section1571810194619) -- [What should I do when an error with lsb\_release occurs during kconfiglib installation?](#section691681635814) - -## What should I do when the message **configure: error: no acceptable C compiler found in $PATH** is displayed during Python 3 installation? - -- **Symptom** - - The following error occurs during Python 3 installation: - - ``` - configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details - ``` - -- **Possible Causes** - - **GCC** is not installed. - -- **Solutions** - - 1. Run the **apt-get install gcc** command to install **GCC** online. - - 2. After the installation, reinstall Python 3. - - -## What should I do when the message **-bash: make: command not found** is displayed during Python 3 installation? - -- **Symptom** - - The following error occurs during Python 3 installation: - - ``` - -bash: make: command not found - ``` - -- **Possible Causes** - - **Make** is not installed. - -- **Solutions** - - 1. Run the **apt-get install make** command to install **Make** online. - - 2. After the installation, reinstall Python 3. - - -## What should I do when the message **zlib not available** is displayed during Python 3 installation? - -- **Symptom** - - The following error occurs during Python 3 installation: - - ``` - zipimport.ZipImportError: can't decompress data; zlib not avaliable - ``` - -- **Possible Causes** - - **zlib** is not installed. - -- **Solutions** - - Solution 1: Run the **apt-get install zlib** command to install **zlib** online. - - Solution 2: If the software source does not contain **zlib**, download the source code from [http://www.zlib.net/](http://www.zlib.net/). - - ![](figures/10.png) - - Then run the following commands to install **zlib** offline: - - ``` - # tar xvf zlib-1.2.11.tar.gz - # cd zlib-1.2.11 - # ./configure - # make && make install - ``` - - After the installation, reinstall Python 3. - - -## What should I do when the message **No module named '\_ctypes'** is displayed during Python 3 installation? - -- **Symptom** - - The following error occurs during Python 3 installation: - - ``` - ModuleNotFoundError: No module named '_ctypes' - ``` - - -- **Possible Causes** - - **libffi** and **libffi-devel** are not installed. - - -- **Solutions** - - 1. Run the **apt-get install libffi\* -y** command to install **libffi** and **libffi-devel** online. - - 2. After the installation, reinstall Python 3. - - -## What should I do when the message **No module named 'Crypto'** is displayed during compilation and building? - -- **Symptom** - - The following error occurs during compilation and building: - - ``` - ModuleNotFoundError: No module named 'Crypto' - ``` - - -- **Possible Causes** - - **Crypto** is not installed. - - -- **Solutions** - - Solution 1: Run the **pip3 install Crypto** command to install **Crypto** online. - - Solution 2: Install **Crypto** offline. - - - Download the source code from [https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files). - - ![](figures/en-us_image_0000001128470864.png) - - - Save the source code package to the Linux server, decompress the package, and run the **python3 setup.py install** command to install **Crypto**. - - Rebuild an environment. - - -## What should I do when the message **No module named 'ecdsa'** is displayed during compilation and building? - -- **Symptom** - - The following error occurs during compilation and building: - - ``` - ModuleNotFoundError: No module named 'ecdsa' - ``` - - -- **Possible Causes** - - **ecdsa** is not installed. - - -- **Solutions** - - Solution 1: Run the **pip3 install ecdsa** command to install **ecdsa** online. - - Solution 2: Install **ecdsa** offline. - - - Download the installation package from [https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files). - - ![](figures/en-us_image_0000001128311072.png) - - - Save the installation package to the Linux server and run the **pip3 install ecdsa-0.15-py2.py3-none-any.whl** command to install **ecdsa**. - - Rebuild an environment. - - -## What should I do when the message **Could not find a version that satisfies the requirement six\>=1.9.0** is displayed during compilation and building? - -- **Symptom** - - The following error occurs during compilation and building: - - ``` - Could not find a version that satisfies the requirement six>=1.9.0 - ``` - - -- **Possible Causes** - - **six** is not installed. - - -- **Solutions** - - Solution 1: Run the **pip3 install six** command to install **six** online. - - Solution 2: Install **six** offline. - - - Download the installation package from [https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files). - - ![](figures/en-us_image_0000001174270699.png) - - - Save the source code to the Linux server and run the **pip3 install six-1.14.0-py2.py3-none-any.whl** command to install **six**. - - Rebuild an environment. - - -## What should I do when the message **cannot find -lgcc** is displayed during compilation and building? - -- **Symptom** - - The following error occurs during compilation and building: - - ``` - riscv32-unknown-elf-ld: cannot find -lgcc - ``` - - -- **Possible Causes** - - The PATH is incorrectly written by **gcc\_riscv32**. There is an extra slash \(/\). - - ``` - ~/gcc_riscv32/bin/:/data/toolchain/ - ``` - - -- **Solutions** - - Modify the PATH by deleting the slash \(/\). - - ``` - ~/gcc_riscv32/bin:/data/toolchain/ - ``` - - -## What should I do when the message indicating Python cannot be found is displayed during compilation and building? - -- **Symptom** - - The following error occurs during compilation and building: - - ``` - -bash: /usr/bin/python: No such file or directory - ``` - - -- **Possible Cause 1:** Python is not installed. -- **Solutions** - - Install Python by referring to [Installing and Configuring Python](../quick-start/ubuntu-build-environment.md). - -- **Possible Cause 2:** The soft link that points to the Python does not exist in the **usr/bin** directory. - - ![](figures/en-us_image_0000001128311070.png) - -- **Solutions** - - Run the following commands to add a soft link: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - Example: - - ![](figures/en-us_image_0000001174350623.png) - - -## What should I do when an error with **lsb\_release** occurs during **kconfiglib** installation? - -- **Symptom** - - The following error occurs during **kconfiglib** installation: - - ``` - subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1. - ``` - -- **Possible Causes** - - The Python version matched with the **lsb\_release** module is different from the current Python version. - -- **Solutions** - - Run the **find / -name lsb\_release** command, for example, **sudo rm -rf /usr/bin/lsb\_release** to locate and delete **lsb\_release**. - - diff --git a/en/device-dev/quick-start/figures/1.png b/en/device-dev/quick-start/figure/1.png similarity index 100% rename from en/device-dev/quick-start/figures/1.png rename to en/device-dev/quick-start/figure/1.png diff --git a/en/device-dev/quick-start/figures/10.png b/en/device-dev/quick-start/figure/10.png similarity index 100% rename from en/device-dev/quick-start/figures/10.png rename to en/device-dev/quick-start/figure/10.png diff --git a/en/device-dev/quick-start/figures/2.png b/en/device-dev/quick-start/figure/2.png similarity index 100% rename from en/device-dev/quick-start/figures/2.png rename to en/device-dev/quick-start/figure/2.png diff --git a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-17.png b/en/device-dev/quick-start/figure/2021-01-27_170334-17.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/2021-01-27_170334-17.png rename to en/device-dev/quick-start/figure/2021-01-27_170334-17.png diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334-19.png b/en/device-dev/quick-start/figure/2021-01-27_170334-18.png similarity index 100% rename from en/device-dev/quick-start/figures/2021-01-27_170334-19.png rename to en/device-dev/quick-start/figure/2021-01-27_170334-18.png diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334-2.png b/en/device-dev/quick-start/figure/2021-01-27_170334-2.png similarity index 100% rename from en/device-dev/quick-start/figures/2021-01-27_170334-2.png rename to en/device-dev/quick-start/figure/2021-01-27_170334-2.png diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334-5.png b/en/device-dev/quick-start/figure/2021-01-27_170334-5.png similarity index 100% rename from en/device-dev/quick-start/figures/2021-01-27_170334-5.png rename to en/device-dev/quick-start/figure/2021-01-27_170334-5.png diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334.png b/en/device-dev/quick-start/figure/2021-01-27_170334.png similarity index 100% rename from en/device-dev/quick-start/figures/2021-01-27_170334.png rename to en/device-dev/quick-start/figure/2021-01-27_170334.png diff --git a/en/device-dev/quick-start/figures/3-0.png b/en/device-dev/quick-start/figure/3-0.png similarity index 100% rename from en/device-dev/quick-start/figures/3-0.png rename to en/device-dev/quick-start/figure/3-0.png diff --git a/en/device-dev/quick-start/figures/3.png b/en/device-dev/quick-start/figure/3.png similarity index 100% rename from en/device-dev/quick-start/figures/3.png rename to en/device-dev/quick-start/figure/3.png diff --git "a/en/device-dev/quick-start/figures/3516\346\255\243\351\235\242.png" "b/en/device-dev/quick-start/figure/3516\346\255\243\351\235\242.png" similarity index 100% rename from "en/device-dev/quick-start/figures/3516\346\255\243\351\235\242.png" rename to "en/device-dev/quick-start/figure/3516\346\255\243\351\235\242.png" diff --git "a/en/device-dev/quick-start/figures/3861\346\255\243\351\235\242.png" "b/en/device-dev/quick-start/figure/3861\346\255\243\351\235\242.png" similarity index 100% rename from "en/device-dev/quick-start/figures/3861\346\255\243\351\235\242.png" rename to "en/device-dev/quick-start/figure/3861\346\255\243\351\235\242.png" diff --git a/en/device-dev/quick-start/figures/4.png b/en/device-dev/quick-start/figure/4.png similarity index 100% rename from en/device-dev/quick-start/figures/4.png rename to en/device-dev/quick-start/figure/4.png diff --git a/en/device-dev/quick-start/figures/5-1.png b/en/device-dev/quick-start/figure/5-1.png similarity index 100% rename from en/device-dev/quick-start/figures/5-1.png rename to en/device-dev/quick-start/figure/5-1.png diff --git a/en/device-dev/quick-start/figures/5.png b/en/device-dev/quick-start/figure/5.png similarity index 100% rename from en/device-dev/quick-start/figures/5.png rename to en/device-dev/quick-start/figure/5.png diff --git a/en/device-dev/quick-start/figures/6.png b/en/device-dev/quick-start/figure/6.png similarity index 100% rename from en/device-dev/quick-start/figures/6.png rename to en/device-dev/quick-start/figure/6.png diff --git a/en/device-dev/quick-start/figures/allowing-the-visual-studio-code-application-to-access-the-network-16.png b/en/device-dev/quick-start/figure/allowing-the-visual-studio-code-application-to-access-the-network-16.png similarity index 100% rename from en/device-dev/quick-start/figures/allowing-the-visual-studio-code-application-to-access-the-network-16.png rename to en/device-dev/quick-start/figure/allowing-the-visual-studio-code-application-to-access-the-network-16.png diff --git a/en/device-dev/quick-start/figures/allowing-the-visual-studio-code-application-to-access-the-network.png b/en/device-dev/quick-start/figure/allowing-the-visual-studio-code-application-to-access-the-network.png similarity index 100% rename from en/device-dev/quick-start/figures/allowing-the-visual-studio-code-application-to-access-the-network.png rename to en/device-dev/quick-start/figure/allowing-the-visual-studio-code-application-to-access-the-network.png diff --git a/en/device-dev/quick-start/figures/changjian1-11.png b/en/device-dev/quick-start/figure/changjian1-11.png similarity index 100% rename from en/device-dev/quick-start/figures/changjian1-11.png rename to en/device-dev/quick-start/figure/changjian1-11.png diff --git a/en/device-dev/quick-start/figures/changjian1.png b/en/device-dev/quick-start/figure/changjian1.png similarity index 100% rename from en/device-dev/quick-start/figures/changjian1.png rename to en/device-dev/quick-start/figure/changjian1.png diff --git a/en/device-dev/quick-start/figures/checking-whether-the-serial-port-is-used-9.png b/en/device-dev/quick-start/figure/checking-whether-the-serial-port-is-used-9.png similarity index 100% rename from en/device-dev/quick-start/figures/checking-whether-the-serial-port-is-used-9.png rename to en/device-dev/quick-start/figure/checking-whether-the-serial-port-is-used-9.png diff --git a/en/device-dev/quick-start/figures/checking-whether-the-serial-port-is-used.png b/en/device-dev/quick-start/figure/checking-whether-the-serial-port-is-used.png similarity index 100% rename from en/device-dev/quick-start/figures/checking-whether-the-serial-port-is-used.png rename to en/device-dev/quick-start/figure/checking-whether-the-serial-port-is-used.png diff --git a/en/device-dev/quick-start/figures/chuankou1-6.png b/en/device-dev/quick-start/figure/chuankou1-6.png similarity index 100% rename from en/device-dev/quick-start/figures/chuankou1-6.png rename to en/device-dev/quick-start/figure/chuankou1-6.png diff --git a/en/device-dev/quick-start/figures/chuankou1.png b/en/device-dev/quick-start/figure/chuankou1.png similarity index 100% rename from en/device-dev/quick-start/figures/chuankou1.png rename to en/device-dev/quick-start/figure/chuankou1.png diff --git a/en/device-dev/quick-start/figures/disabling-the-terminal-using-the-serial-port-10.png b/en/device-dev/quick-start/figure/disabling-the-terminal-using-the-serial-port-10.png similarity index 100% rename from en/device-dev/quick-start/figures/disabling-the-terminal-using-the-serial-port-10.png rename to en/device-dev/quick-start/figure/disabling-the-terminal-using-the-serial-port-10.png diff --git a/en/device-dev/quick-start/figures/disabling-the-terminal-using-the-serial-port.png b/en/device-dev/quick-start/figure/disabling-the-terminal-using-the-serial-port.png similarity index 100% rename from en/device-dev/quick-start/figures/disabling-the-terminal-using-the-serial-port.png rename to en/device-dev/quick-start/figure/disabling-the-terminal-using-the-serial-port.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001056814287.png b/en/device-dev/quick-start/figure/en-us_image_0000001056814287.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001056814287.png rename to en/device-dev/quick-start/figure/en-us_image_0000001056814287.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001057335403.png b/en/device-dev/quick-start/figure/en-us_image_0000001057335403.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001057335403.png rename to en/device-dev/quick-start/figure/en-us_image_0000001057335403.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001072468991.png b/en/device-dev/quick-start/figure/en-us_image_0000001072468991.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001072468991.png rename to en/device-dev/quick-start/figure/en-us_image_0000001072468991.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001072757874.png b/en/device-dev/quick-start/figure/en-us_image_0000001072757874.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001072757874.png rename to en/device-dev/quick-start/figure/en-us_image_0000001072757874.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001073840162.png b/en/device-dev/quick-start/figure/en-us_image_0000001073840162.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001073840162.png rename to en/device-dev/quick-start/figure/en-us_image_0000001073840162.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001096154076.png b/en/device-dev/quick-start/figure/en-us_image_0000001096154076.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001096154076.png rename to en/device-dev/quick-start/figure/en-us_image_0000001096154076.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001100641602.png b/en/device-dev/quick-start/figure/en-us_image_0000001100641602.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001100641602.png rename to en/device-dev/quick-start/figure/en-us_image_0000001100641602.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001113969542.png b/en/device-dev/quick-start/figure/en-us_image_0000001113969542.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001113969542.png rename to en/device-dev/quick-start/figure/en-us_image_0000001113969542.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001114129428.png b/en/device-dev/quick-start/figure/en-us_image_0000001114129428.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001114129428.png rename to en/device-dev/quick-start/figure/en-us_image_0000001114129428.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001114129432.png b/en/device-dev/quick-start/figure/en-us_image_0000001114129432.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001114129432.png rename to en/device-dev/quick-start/figure/en-us_image_0000001114129432.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001117463460.png b/en/device-dev/quick-start/figure/en-us_image_0000001117463460.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001117463460.png rename to en/device-dev/quick-start/figure/en-us_image_0000001117463460.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001117621400.png b/en/device-dev/quick-start/figure/en-us_image_0000001117621400.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001117621400.png rename to en/device-dev/quick-start/figure/en-us_image_0000001117621400.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311066.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311066.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311066.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311066.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311070.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311070.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311070.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311070.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311072.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311072.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311072.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311072.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311090.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311090.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311090.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311090.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311092.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311092.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311092.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311092.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311094.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311094.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311094.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311094.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311096.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311096.png old mode 100755 new mode 100644 similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311096.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311096.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311098.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311098.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311098.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311098.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311100.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311100.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311100.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311100.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311104.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311104.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311104.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311104.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311116.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311116.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311116.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311116.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311118.png b/en/device-dev/quick-start/figure/en-us_image_0000001128311118.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128311118.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128311118.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470864.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470864.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128470864.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470864.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470880.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470880.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128470880.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470880.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470900.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470900.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128470900.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470900.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470902.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470902.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128470902.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470902.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470904.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470904.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128470904.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470904.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470906.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470906.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128470906.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470906.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470908.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470908.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470908.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470908.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470922.png b/en/device-dev/quick-start/figure/en-us_image_0000001128470922.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001128470922.png rename to en/device-dev/quick-start/figure/en-us_image_0000001128470922.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001142794291.png b/en/device-dev/quick-start/figure/en-us_image_0000001142794291.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001142794291.png rename to en/device-dev/quick-start/figure/en-us_image_0000001142794291.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001142802505.png b/en/device-dev/quick-start/figure/en-us_image_0000001142802505.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001142802505.png rename to en/device-dev/quick-start/figure/en-us_image_0000001142802505.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001143154485.png b/en/device-dev/quick-start/figure/en-us_image_0000001143154485.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001143154485.png rename to en/device-dev/quick-start/figure/en-us_image_0000001143154485.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001160527611.png b/en/device-dev/quick-start/figure/en-us_image_0000001160527611.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001160527611.png rename to en/device-dev/quick-start/figure/en-us_image_0000001160527611.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001163045527.png b/en/device-dev/quick-start/figure/en-us_image_0000001163045527.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001163045527.png rename to en/device-dev/quick-start/figure/en-us_image_0000001163045527.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270699.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270699.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270699.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270699.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270713.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270713.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270713.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270713.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270715.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270715.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270715.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270715.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270727.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270727.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270727.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270727.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270729.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270729.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270729.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270729.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270731.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270731.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270731.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270731.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270733.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270733.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270733.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270733.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270735.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270735.png old mode 100755 new mode 100644 similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270735.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270735.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270737.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270737.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270737.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270737.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270739.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270739.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270739.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270739.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270743.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270743.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270743.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270743.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270749.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270749.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270749.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270749.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270751.png b/en/device-dev/quick-start/figure/en-us_image_0000001174270751.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174270751.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174270751.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350615.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350615.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350615.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350615.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350623.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350623.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350623.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350623.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350633.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350633.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350633.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350633.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350641.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350641.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350641.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350641.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350643.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350643.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350643.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350643.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350647.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350647.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350647.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350647.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350649.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350649.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350649.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350649.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350651.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350651.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350651.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350651.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350653.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350653.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350653.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350653.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350655.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350655.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350655.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350655.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350659.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350659.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350659.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350659.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350661.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350661.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350661.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350661.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350669.png b/en/device-dev/quick-start/figure/en-us_image_0000001174350669.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001174350669.png rename to en/device-dev/quick-start/figure/en-us_image_0000001174350669.png diff --git a/en/device-dev/quick-start/figures/failed-to-obtain-the-image-file-due-to-unavailable-connection-12.png b/en/device-dev/quick-start/figure/failed-to-obtain-the-image-file-due-to-unavailable-connection-12.png similarity index 100% rename from en/device-dev/quick-start/figures/failed-to-obtain-the-image-file-due-to-unavailable-connection-12.png rename to en/device-dev/quick-start/figure/failed-to-obtain-the-image-file-due-to-unavailable-connection-12.png diff --git a/en/device-dev/quick-start/figures/failed-to-obtain-the-image-file-due-to-unavailable-connection.png b/en/device-dev/quick-start/figure/failed-to-obtain-the-image-file-due-to-unavailable-connection.png similarity index 100% rename from en/device-dev/quick-start/figures/failed-to-obtain-the-image-file-due-to-unavailable-connection.png rename to en/device-dev/quick-start/figure/failed-to-obtain-the-image-file-due-to-unavailable-connection.png diff --git a/en/device-dev/quick-start/figures/failed-to-open-the-serial-port-8.png b/en/device-dev/quick-start/figure/failed-to-open-the-serial-port-8.png similarity index 100% rename from en/device-dev/quick-start/figures/failed-to-open-the-serial-port-8.png rename to en/device-dev/quick-start/figure/failed-to-open-the-serial-port-8.png diff --git a/en/device-dev/quick-start/figures/failed-to-open-the-serial-port.png b/en/device-dev/quick-start/figure/failed-to-open-the-serial-port.png similarity index 100% rename from en/device-dev/quick-start/figures/failed-to-open-the-serial-port.png rename to en/device-dev/quick-start/figure/failed-to-open-the-serial-port.png diff --git a/en/device-dev/quick-start/figures/firewall-and-network-protection-14.png b/en/device-dev/quick-start/figure/firewall-and-network-protection-14.png similarity index 100% rename from en/device-dev/quick-start/figures/firewall-and-network-protection-14.png rename to en/device-dev/quick-start/figure/firewall-and-network-protection-14.png diff --git a/en/device-dev/quick-start/figures/firewall-and-network-protection.png b/en/device-dev/quick-start/figure/firewall-and-network-protection.png similarity index 100% rename from en/device-dev/quick-start/figures/firewall-and-network-protection.png rename to en/device-dev/quick-start/figure/firewall-and-network-protection.png diff --git a/en/device-dev/quick-start/figures/front-view-of-the-hi3518e-v300-board.png b/en/device-dev/quick-start/figure/front-view-of-the-hi3518e-v300-board.png similarity index 100% rename from en/device-dev/quick-start/figures/front-view-of-the-hi3518e-v300-board.png rename to en/device-dev/quick-start/figure/front-view-of-the-hi3518e-v300-board.png diff --git a/en/device-dev/quick-start/figures/getting-started-for-the-standard-system.png b/en/device-dev/quick-start/figure/getting-started-for-the-standard-system.png similarity index 100% rename from en/device-dev/quick-start/figures/getting-started-for-the-standard-system.png rename to en/device-dev/quick-start/figure/getting-started-for-the-standard-system.png diff --git a/en/device-dev/quick-start/figures/hardware-connections-3.png b/en/device-dev/quick-start/figure/hardware-connections-3.png similarity index 100% rename from en/device-dev/quick-start/figures/hardware-connections-3.png rename to en/device-dev/quick-start/figure/hardware-connections-3.png diff --git a/en/device-dev/quick-start/figures/hardware-connections.png b/en/device-dev/quick-start/figure/hardware-connections.png similarity index 100% rename from en/device-dev/quick-start/figures/hardware-connections.png rename to en/device-dev/quick-start/figure/hardware-connections.png diff --git "a/en/device-dev/quick-start/figures/hi3518\346\255\243\350\203\214\351\235\242.png" "b/en/device-dev/quick-start/figure/hi3518\346\255\243\350\203\214\351\235\242.png" similarity index 100% rename from "en/device-dev/quick-start/figures/hi3518\346\255\243\350\203\214\351\235\242.png" rename to "en/device-dev/quick-start/figure/hi3518\346\255\243\350\203\214\351\235\242.png" diff --git a/en/device-dev/quick-start/figures/network-and-firewall-setting-13.png b/en/device-dev/quick-start/figure/network-and-firewall-setting-13.png similarity index 100% rename from en/device-dev/quick-start/figures/network-and-firewall-setting-13.png rename to en/device-dev/quick-start/figure/network-and-firewall-setting-13.png diff --git a/en/device-dev/quick-start/figures/network-and-firewall-setting.png b/en/device-dev/quick-start/figure/network-and-firewall-setting.png similarity index 100% rename from en/device-dev/quick-start/figures/network-and-firewall-setting.png rename to en/device-dev/quick-start/figure/network-and-firewall-setting.png diff --git a/en/device-dev/quick-start/figures/qi1.png b/en/device-dev/quick-start/figure/qi1.png similarity index 100% rename from en/device-dev/quick-start/figures/qi1.png rename to en/device-dev/quick-start/figure/qi1.png diff --git a/en/device-dev/quick-start/figures/selecting-the-visual-studio-code-application-15.png b/en/device-dev/quick-start/figure/selecting-the-visual-studio-code-application-15.png similarity index 100% rename from en/device-dev/quick-start/figures/selecting-the-visual-studio-code-application-15.png rename to en/device-dev/quick-start/figure/selecting-the-visual-studio-code-application-15.png diff --git a/en/device-dev/quick-start/figures/selecting-the-visual-studio-code-application.png b/en/device-dev/quick-start/figure/selecting-the-visual-studio-code-application.png similarity index 100% rename from en/device-dev/quick-start/figures/selecting-the-visual-studio-code-application.png rename to en/device-dev/quick-start/figure/selecting-the-visual-studio-code-application.png diff --git a/en/device-dev/quick-start/figures/serial-port-displayed-after-the-u-boot-is-burnt.png b/en/device-dev/quick-start/figure/serial-port-displayed-after-the-u-boot-is-burnt.png similarity index 100% rename from en/device-dev/quick-start/figures/serial-port-displayed-after-the-u-boot-is-burnt.png rename to en/device-dev/quick-start/figure/serial-port-displayed-after-the-u-boot-is-burnt.png diff --git a/en/device-dev/quick-start/figures/settings-4.png b/en/device-dev/quick-start/figure/settings-4.png similarity index 100% rename from en/device-dev/quick-start/figures/settings-4.png rename to en/device-dev/quick-start/figure/settings-4.png diff --git a/en/device-dev/quick-start/figures/settings.png b/en/device-dev/quick-start/figure/settings.png similarity index 100% rename from en/device-dev/quick-start/figures/settings.png rename to en/device-dev/quick-start/figure/settings.png diff --git a/en/device-dev/quick-start/figures/successful-installation-(scons-version-requirement-3-0-4-or-later).png b/en/device-dev/quick-start/figure/successful-installation-(scons-version-requirement-3-0-4-or-later).png similarity index 100% rename from en/device-dev/quick-start/figures/successful-installation-(scons-version-requirement-3-0-4-or-later).png rename to en/device-dev/quick-start/figure/successful-installation-(scons-version-requirement-3-0-4-or-later).png diff --git a/en/device-dev/quick-start/figures/successful-system-startup-and-program-execution-7.png b/en/device-dev/quick-start/figure/successful-system-startup-and-program-execution-7.png similarity index 100% rename from en/device-dev/quick-start/figures/successful-system-startup-and-program-execution-7.png rename to en/device-dev/quick-start/figure/successful-system-startup-and-program-execution-7.png diff --git a/en/device-dev/quick-start/figures/successful-system-startup-and-program-execution.png b/en/device-dev/quick-start/figure/successful-system-startup-and-program-execution.png similarity index 100% rename from en/device-dev/quick-start/figures/successful-system-startup-and-program-execution.png rename to en/device-dev/quick-start/figure/successful-system-startup-and-program-execution.png diff --git "a/en/device-dev/quick-start/figures/\346\210\252\345\233\276.png" "b/en/device-dev/quick-start/figure/\346\210\252\345\233\276.png" similarity index 100% rename from "en/device-dev/quick-start/figures/\346\210\252\345\233\276.png" rename to "en/device-dev/quick-start/figure/\346\210\252\345\233\276.png" diff --git "a/en/device-dev/quick-start/figures/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" "b/en/device-dev/quick-start/figure/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" similarity index 100% rename from "en/device-dev/quick-start/figures/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" rename to "en/device-dev/quick-start/figure/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" diff --git "a/en/device-dev/quick-start/figures/3516\346\255\243\351\235\242-17.png" "b/en/device-dev/quick-start/figures/3516\346\255\243\351\235\242-17.png" deleted file mode 100644 index 1ccb47f20022261cc291e8b435f263c00e8d4a27..0000000000000000000000000000000000000000 Binary files "a/en/device-dev/quick-start/figures/3516\346\255\243\351\235\242-17.png" and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128471042.png b/en/device-dev/quick-start/figures/en-us_image_0000001128471042.png deleted file mode 100755 index dd4fd805a602980b08d54eb2856b27253b171d8d..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001128471042.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350781.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350781.png deleted file mode 100755 index 8723967946c1f0bd471434d3422acc3bd6142535..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001174350781.png and /dev/null differ diff --git a/en/device-dev/quick-start/hi3516-development-board.md b/en/device-dev/quick-start/hi3516-development-board.md deleted file mode 100644 index 53148cbe9a1fba7264055edc9fdad8eb193c00ad..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/hi3516-development-board.md +++ /dev/null @@ -1,42 +0,0 @@ -# Hi3516 Development Board - -- [Introduction](#section26131214194212) -- [Development Board Specifications](#section15192203316533) - -## Introduction - -Hi3516D V300 is a next-generation system on chip \(SoC\) designed for the industry-dedicated smart HD IP camera. It introduces a next-generation image signal processor \(ISP\), the H.265 video compression encoder, and a high-performance NNIE engine, leading the industry in terms of low bit rate, high image quality, intelligent processing and analysis, and low power consumption. - -**Figure 1** Front view of the Hi3516D V300 board - - -![](figures/3516正面.png) - -## Development Board Specifications - -**Table 1** Specifications of the Hi3516 development board - - - - - - - - - - - - - -

Type

-

Specification

-

Processor and internal memory

-
  • Hi3516D V300
  • DDR3 1GB
  • 8 GB eMMC4.5
-

External components

-
  • Ethernet port
  • Audio and video
    • One voice input
    • One mono (AC_L) output, connected to a 3 W power amplifier (LM4871)
    • MicroHDMI (one HDMI 1.4)
    -
  • Camera
    • Sensor IMX335
    • M12 lens with a focal length of 4 mm and an aperture of 1.8
    -
  • Display
    • 2.35-inch LCD connector
    • 5.5-inch LCD connector
    -
  • External components and interfaces
    • microSD card interface
    • JTAG/I2S interface
    • ADC interface
    • Steer gear interface
    • Grove connector
    • USB2.0(Type C)
    • Three function keys: two custom keys and one update key
    • LED indicator (including green and red)
    -
-
- diff --git a/en/device-dev/quick-start/hi3516.md b/en/device-dev/quick-start/hi3516.md deleted file mode 100644 index e33aa899315932687a01de028a7f0fccba0a91b2..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/hi3516.md +++ /dev/null @@ -1,11 +0,0 @@ -# Hi3516 - -- **[Setting Up the Environment](setting-up-the-environment-2.md)** - -- **[Running a Hello OHOS Program](running-a-hello-ohos-program.md)** - -- **[Developing a Driver](developing-a-driver.md)** - -- **[FAQs](faqs-3.md)** - - diff --git a/en/device-dev/quick-start/hi3518-development-board.md b/en/device-dev/quick-start/hi3518-development-board.md deleted file mode 100644 index 262d456b50b47d8c91593999dd5a8f2d5a935d66..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/hi3518-development-board.md +++ /dev/null @@ -1,57 +0,0 @@ -# Hi3518 Development Board - -- [Introduction](#section14815247616) -- [Development Board Specifications](#section765112478446) - -## Introduction - -Hi3518E V300 is a next-generation system on chip \(SoC\) designed for the industry-dedicated smart HD IP camera. It introduces a next-generation image signal processor \(ISP\), the H.265 video compression encoder, and the advanced low-power process and architecture design, leading the industry in terms of low bit rate, high image quality, and low power consumption. - -**Figure 1** Front view of the Hi3518E V300 board -![](figures/front-view-of-the-hi3518e-v300-board.png "front-view-of-the-hi3518e-v300-board") - -**Figure 2** Rear view of the Hi3518E V300 board - - -![](figures/hi3518正背面.png) - -## Development Board Specifications - -**Table 1** Specifications of the Hi3518 development board - - - - - - - - - - - - - - - - - - - - - - -

Type

-

Description

-

Processor core

-
  • Hi3518E V300
-

Imaging device

-
  • 1/2.9 F23
-

External interfaces

-
  • External microphone
  • External 8 Ω/1.5 W speaker
-

External memory interface

-
  • TF card

    A maximum file size of 128 GB is allowed (FAT32 format).

    -
-

WLAN protocol

-
  • 802.11 b/g/n
-
- diff --git a/en/device-dev/quick-start/hi3518.md b/en/device-dev/quick-start/hi3518.md deleted file mode 100644 index 817d4c826164210f795e36503f49dded0c49529e..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/hi3518.md +++ /dev/null @@ -1,9 +0,0 @@ -# Hi3518 - -- **[Setting Up the Environment](setting-up-the-environment-4.md)** - -- **[Running a Hello OHOS Program](running-a-hello-ohos-program-5.md)** - -- **[FAQs](faqs-6.md)** - - diff --git a/en/device-dev/quick-start/hi3861-development-board.md b/en/device-dev/quick-start/hi3861-development-board.md deleted file mode 100644 index 6790ab0fe64db575950bef8225613438ccbad63a..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/hi3861-development-board.md +++ /dev/null @@ -1,157 +0,0 @@ -# Hi3861 Development Board - -- [Introduction](#section19352114194115) -- [Resources and Constraints](#section82610215014) -- [Development Board Specifications](#section169054431017) -- [Key Features](#section1317173016507) - -## Introduction - -The Hi3861 WLAN module is a development board with 2 x 5 cm form factor. It contains a 2.4 GHz WLAN SoC that highly integrates the IEEE 802.11b/g/n baseband and radio frequency \(RF\) circuit. This module provides open and easy-to-use development and debugging environments for running OpenHarmony. - -**Figure 1** Appearance of Hi3861 WLAN module - - -![](figures/3861正面.png) - -The Hi3861 WLAN module can also be connected to the Hi3861 mother board to expand its peripheral capabilities. The following figure shows the Hi3861 mother board. - -**Figure 2** Appearance of the Hi3861 mother board - - -![](figures/en-us_image_0000001174350615.png) - -- The RF circuit includes modules such as the power amplifier \(PA\), low noise amplifier \(LNA\), RF Balun, antenna switch, and power management. It supports a standard bandwidth of 20 MHz and a narrow bandwidth of 5 MHz or 10 MHz, and provides a maximum rate of 72.2 Mbit/s at the physical layer. -- The Hi3861 WLAN baseband supports the orthogonal frequency division multiplexing \(OFDM\) technology and is backward compatible with the direct sequence spread spectrum \(DSSS\) and complementary code keying \(CCK\) technologies. In addition, the Hi3861 WLAN baseband supports various data rates specified in the IEEE 802.11 b/g/n protocol. -- The Hi3861 chip integrates the high-performance 32-bit microprocessor, hardware security engine, and various peripheral interfaces. The peripheral interfaces include the Synchronous Peripheral Interface \(SPI\), Universal Asynchronous Receiver & Transmitter \(UART\), the Inter Integrated Circuit \(I2C\), Pulse Width Modulation \(PWM\), General Purpose Input/Output \(GPIO\) interface, and Analog to Digital Converter \(ADC\). The Hi3861 chip also supports the high-speed Secure Digital Input/Output \(SDIO\) 2.0 interface, with a maximum clock frequency of 50 MHz. This chip has a built-in static random access memory \(SRAM\) and flash memory, so that programs can run independently or run from a flash drive. -- The Hi3861 chip applies to Internet of Things \(IoT\) devices such as smart home appliances. - - **Figure 3** Hi3861 functions - - - ![](figures/en-us_image_0000001128311066.png) - - -## Resources and Constraints - -As the Hi3861 only offers 2 MB Flash and 352 KB RAM, use them efficiently when compiling code. - -## Development Board Specifications - -**Table 1** Hi3861 WLAN module specifications - - - - - - - - - - - - - - - - - - - - - - - - - -

Type

-

Description

-

General specifications

-
  • Operates over 1×1 2.4 GHz frequency band (ch1-ch14).
  • The physical layer (PHY) complies with the IEEE 802.11b/g/n protocol.
  • The media access control (MAC) layer complies with the IEEE802.11 d/e/h/i/k/v/w protocol.
-
  • Includes the built-in public address (PA) and local area network (LAN); integrates transmit-receive (Tx/Rx) switch and Balun.
  • Supports the station (STA) and access point (AP) modes. When the Hi3861 WLAN module functions as an AP, a maximum of six STAs are supported.
  • Supports WFA WPA, WFA WPA2 personal, and WPS2.0.
  • Supports three kinds of packet traffic arbiter (PTA) (2- , 3- , or 4-wire PTA), each of which coexists with the BT or BLE chip.
  • The input voltage ranges from 2.3 V to 3.6 V.
-
  • The input/output (I/O) power voltage can be 1.8 V or 3.3 V.
-
  • Supports self-calibration for RF hardware.
  • Performs with low power consumption:
    • Ultra deep sleep mode: 5 μA @ 3.3 V
    • DTIM1: 1.5 mA @ 3.3 V
    • DTIM3: 0.8 mA @ 3.3 V
    -
-

PHY features

-
  • Supports all data rates of the single antenna required by the IEEE802.11b/g/n protocol.
  • Supports a maximum rate of 72.2 Mbps@HT20 MCS7
  • Supports the standard bandwidth (20 MHz) and narrow bandwidth (5 MHz or 10 MHz).
  • Supports space-time block coding (STBC).
  • Supports short guard interval (Short-GI).
-

MAC features

-
  • Supports aggregate MAC service data unit (A-MPDU) and aggregate MAC protocol data unit (A-MSDU).
  • Supports block acknowledgment (Blk-ACK).
  • Supports quality of service (QoS), meeting customer's service requirements.
-

CPU subsystem

-
  • Integrates a high-performance 32-bit microprocessor with a maximum operating frequency of 160 MHz.
  • Includes built-in 352 KB SRAM and 288 KB ROM.
  • Includes a built-in 2 MB flash memory.
-

Peripheral interfaces

-
  • Include one SDIO interface, two SPI interfaces, two I2C interfaces, three UART interfaces, 15 GPIO interfaces, seven ADC inputs, six PWM interfaces, and one I2S interface (Note: These interfaces are all multiplexed.)
  • The frequency of the external primary crystal oscillator is 40 MHz or 24 MHz.
-

Other information

-
  • Package: QFN-32, 5 mm x 5 mm
  • Operating temperature: –40°C to +85°C
-
- -## Key Features - -OpenHarmony provides a series of available capabilities based on the Hi3861 platform. The following table describes the available key components. - -**Table 2** Key components - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Component

-

Description

-

wlan

-

Provides WLAN service, such as connecting to or disconnecting from a station or hotspot, and querying the state of a station or hotspot.

-

iot controller

-

Provides the capability of operating peripherals, including the I2C, I2S, ADC, UART, SPI, SDIO, GPIO, PWM and FLASH.

-

soft bus

-

Provides the capabilities of device discovery and data transmission in the distributed network.

-

hichainsdk

-

Provides the capability of securely transferring data between devices when they are interconnected.

-

huks

-

Provides capabilities of key management, encryption, and decryption.

-

system ability manager

-

Provides a unified OpenHarmony service development framework based on the service-oriented architecture.

-

bootstrap

-

Provides the entry identifier for starting a system service. When the system service management is started, the function identified by bootstrap is called to start a system service.

-

syspara

-

Provides capabilities of obtaining and setting system attributes.

-

utils

-

Provides basic and public capabilities, such as file operations and key-value (KV) storage management.

-

DFX

-

Provides the DFX capabilities, such as logging and printing.

-

XTS

-

Provides a set of OpenHarmony certification test suites.

-
- diff --git a/en/device-dev/quick-start/hi3861.md b/en/device-dev/quick-start/hi3861.md deleted file mode 100644 index 100cdfcabc277a736ed2238f4b8cd93e345624a0..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/hi3861.md +++ /dev/null @@ -1,11 +0,0 @@ -# Hi3861 - -- **[Setting Up the Environment](setting-up-the-environment.md)** - -- **[WLAN Connection](wlan-connection.md)** - -- **[Running a Hello World Program](running-a-hello-world-program.md)** - -- **[FAQs](faqs.md)** - - diff --git a/en/device-dev/quick-start/how-to-develop.md b/en/device-dev/quick-start/how-to-develop.md deleted file mode 100644 index 3e5f705cb569a6d3c7f9543dd24a75159e1682aa..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/how-to-develop.md +++ /dev/null @@ -1,9 +0,0 @@ -# How to Develop - -- **[Hi3861](hi3861.md)** - -- **[Hi3516](hi3516.md)** - -- **[Hi3518](hi3518.md)** - - diff --git a/en/device-dev/quick-start/introduction-to-the-development-boards.md b/en/device-dev/quick-start/introduction-to-the-development-boards.md deleted file mode 100644 index 3848dad5841c053f27b1b5f6280a8a34cb6b41c4..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/introduction-to-the-development-boards.md +++ /dev/null @@ -1,9 +0,0 @@ -# Introduction to the Development Boards - -- **[Hi3861 Development Board](hi3861-development-board.md)** - -- **[Hi3516 Development Board](hi3516-development-board.md)** - -- **[Hi3518 Development Board](hi3518-development-board.md)** - - diff --git a/en/device-dev/quick-start/introduction.md b/en/device-dev/quick-start/introduction.md deleted file mode 100644 index 7209c5c0f18b55e253bca942025b9d0682e390b3..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/introduction.md +++ /dev/null @@ -1,54 +0,0 @@ -# Introduction - -- [Quick Start Process](#section7825218111517) -- [Introduction to the Development Board](#en-us_topic_0000001053666242_section047719215429) -- [Development Board Specifications](#en-us_topic_0000001053666242_section15192203316533) - -This document helps you quickly understand how to set up a standard OpenHarmony system, and how to build, burn, and start the system. You can develop the standard system in Windows and build source code in Linux. - -This document uses the recommended Hi3516D V300 development board as an example. - -## Quick Start Process - -The following figure shows the process of getting started for the standard system, during which, you can set up the Ubuntu development environment in Docker mode or by using the installation package. - -**Figure 1** Getting started for the standard system -![](figures/getting-started-for-the-standard-system.png "getting-started-for-the-standard-system") - -## Introduction to the Development Board - -Hi3516D V300 is a next-generation system on chip \(SoC\) designed for the industry-dedicated smart HD IP camera. It introduces a next-generation image signal processor \(ISP\), the H.265 video compression encoder, and a high-performance NNIE engine, leading the industry in terms of low bit rate, high image quality, intelligent processing and analysis, and low power consumption. - -**Figure 2** Hi3516D V300 front view - - -![](figures/3516正面-17.png) - -## Development Board Specifications - -**Table 1** Specifications of the Hi3516 development board - - - - - - - - - - - - - -

Item

-

Description

-

Processor and internal memory

-
  • Hi3516D V300
  • 1 GB DDR3
  • 8 GB eMMC4.5
-

External components

-
  • Ethernet port
  • Audio and video
    • One voice input
    • One mono (AC_L) output, connected to a 3 W power amplifier (LM4871)
    • Micro-HDMI (one HDMI 1.4)
    -
  • Cameras
    • Sensor IMX335
    • M12 lens with a focal length of 4 mm and an aperture of 1.8
    -
  • Display
    • 2.35-inch LCD connector
    • 5.5-inch LCD connector
    -
  • External components and interfaces
    • microSD card interface
    • JTAG/I2S interface
    • ADC interface
    • Steer gear interface
    • Grove connector
    • USB 2.0 (Type C)
    • Three function keys: two custom keys and one update key
    • LED indicator (including green and red)
    -
-
- diff --git a/en/device-dev/quick-start/mini-and-small-systems.md b/en/device-dev/quick-start/mini-and-small-systems.md deleted file mode 100644 index 458c7109f928cc610f7da07069bebcafa507cda7..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/mini-and-small-systems.md +++ /dev/null @@ -1,11 +0,0 @@ -# Mini and Small Systems - -- **[Overview](overview-0.md)** - -- **[Introduction to the Development Boards](introduction-to-the-development-boards.md)** - -- **[Environment Setup](environment-setup.md)** - -- **[How to Develop](how-to-develop.md)** - - diff --git a/en/device-dev/quick-start/overview.md b/en/device-dev/quick-start/overview.md deleted file mode 100644 index 4a5832db5a9e81baccd6d4cbb4bf500c0f5a06a3..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/overview.md +++ /dev/null @@ -1,175 +0,0 @@ -# Overview - -- [System Types](#section767218232110) -- [Document Outline](#section19810171681218) - -This topic provides a panorama of all documents for you to obtain helpful information quickly. These documents are classified based on your learning progress and development scenarios of OpenHarmony. - -## System Types - -It is good practice to understand the system types for you to find useful documents that can guide your development. - -OpenHarmony is an open-source distributed operating system for all scenarios. It uses a component-based design to tailor its features to better suit devices with 128 KiB to GiB-level of RAM. You can integrate a flexible combination of system components based on the hardware capabilities of the device. - -To make the integration simple and easy on different hardware, OpenHarmony defines three basic system types. You only need to select a suitable system type and configure the mandatory component set, thereby developing a system for your device at the minimum workload. The definitions of the basic system types are provided as follows for your reference: - -- Mini system - - A mini system runs on the devices whose memory is greater than or equal to 128 KiB and that are equipped with MCU processors such as Arm Cortex-M and 32-bit RISC-V. This system provides multiple lightweight network protocols and graphics frameworks, and a wide range of read/write components for the IoT bus. Typical products include connection modules, sensors, and wearables for smart home. - -- Small system - - A small system runs on the devices whose memory is greater than or equal to 1 MiB and that are equipped with application processors such as Arm Cortex-A. This system provides higher security capabilities, standard graphics frameworks, and video encoding and decoding capabilities. Typical products include smart home IP cameras, electronic cat eyes, and routers, and event data recorders \(EDRs\) for smart travel. - -- Standard system - - A standard system runs on the devices whose memory is greater than or equal to 128 MiB and that are equipped with application processors such as Arm Cortex-A. This system provides a complete application framework supporting the enhanced interaction, 3D GPU, hardware composer, diverse components, and rich animations. This system applies to high-end refrigerator displays. - - -In addition, OpenHarmony provides a series of optional system components that can be configured as required to support feature extension and customization. These system components are combined to form a series of system capabilities that, for better understanding, are described as features or functions for you to choose. - -## Document Outline - -- [Mini and Small System Development Guidelines](#table3762949121211) -- [Standard System Development Guidelines](#table17667535516) - -**Table 1** Mini and small system development guidelines \(reference memory < 128 MB\) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Topic

-

Development Scenario

-

Documents

-

About OpenHarmony

-

Getting familiar with OpenHarmony

-
-

Development resources

-

Preparing for your development

-
-

Quick start

-

Getting started with setup, build, burning, debugging, and running of OpenHarmony

-

Getting Started for Mini and Small Systems

-

Basic capabilities

-

Using basic capabilities of OpenHarmony

-
-

Advanced development

-

Developing smart devices based on system capabilities

-
-

Porting and adaptation

-
  • Porting and adapting the OpenHarmony to an SoC
  • Porting and adapting the OpenHarmony to a third-party library
-
-

Contributing components

-

Contributing components to OpenHarmony

-
-

Reference

-

Referring to development specifications

-
-
- -**Table 2** Standard system development guidelines \(reference memory ≥ 128 MB\) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Topic

-

Development Scenario

-

Documents

-

About OpenHarmony

-

Getting familiar with OpenHarmony

-
-

Development resources

-

Preparing for your development

-
-

Quick start

-

Getting started with setup, build, burning, debugging, and running of OpenHarmony

-

Getting Started for Standard System

-

Basic capabilities

-

Using basic capabilities of OpenHarmony

-
-

Advanced development

-

Developing smart devices based on system capabilities

-
-

Porting and adaptation

-

Porting and adapting the OpenHarmony to a third-party library

-

Third-Party Library Porting Guide

-

Contributing components

-

Contributing components to OpenHarmony

-
-

Reference

-

Referring to development specifications

-
-
- diff --git a/en/device-dev/quick-start/public_sys-resources/icon-caution.gif b/en/device-dev/quick-start/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/device-dev/quick-start/public_sys-resources/icon-danger.gif b/en/device-dev/quick-start/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/device-dev/quick-start/public_sys-resources/icon-note.gif b/en/device-dev/quick-start/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/device-dev/quick-start/public_sys-resources/icon-notice.gif b/en/device-dev/quick-start/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/device-dev/quick-start/public_sys-resources/icon-tip.gif b/en/device-dev/quick-start/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/device-dev/quick-start/public_sys-resources/icon-warning.gif b/en/device-dev/quick-start/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/device-dev/quick-start/overview-1.md b/en/device-dev/quick-start/quickstart-lite-env-setup-des.md similarity index 100% rename from en/device-dev/quick-start/overview-1.md rename to en/device-dev/quick-start/quickstart-lite-env-setup-des.md diff --git a/en/device-dev/quick-start/faq.md b/en/device-dev/quick-start/quickstart-lite-env-setup-faqs.md similarity index 100% rename from en/device-dev/quick-start/faq.md rename to en/device-dev/quick-start/quickstart-lite-env-setup-faqs.md diff --git a/en/device-dev/quick-start/quickstart-lite-env-setup-lin.md b/en/device-dev/quick-start/quickstart-lite-env-setup-lin.md new file mode 100644 index 0000000000000000000000000000000000000000..a5ec9aa0dae52356baeb3ba311efe54a00742619 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-env-setup-lin.md @@ -0,0 +1,361 @@ +# Ubuntu Build Environment + +- [Obtaining Source Code and Tools](#section1897711811517) +- [Obtaining Source Code](#section1545225464016) +- [Installing and Configuring Python](#section1238412211211) +- [Installing gn](#section29216201423) +- [Installing ninja](#section8762358731) +- [Installing LLVM](#section12202192215415) +- [Installing hb](#section15794154618411) + - [Prerequisites](#section1083283711515) + - [Installation Procedure](#section11518484814) + - [Uninstalling hb](#section3512551574) + +- [Installing Other Tools](#section830511218494) + - [Installation Procedure](#section54409586499) + + +Operating system: 64-bit version of Ubuntu 16.04 or later. + +Perform the following steps to set up the build environment: + +1. Obtain source code. +2. Install and configure Python. +3. Install GN. +4. Install Ninja. +5. Install LLVM. +6. Install hb. + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>- Docker is provided for the Ubuntu build environment, which encapsulates related build tools. If you use Docker to prepare the build environment, you do not need to perform the following steps in this section. Instead, refer to [Using Docker to Prepare the Build Environment](../get-code/gettools-acquire.md). +>- By default, basic software, such as Samba and Vim, is installed in the system. Adaptation on the software is required to support file sharing between the Linux server and the Windows workstation. +>- For details about the compilation and building subsystem of OpenHarmony, see [Compilation and Building Overview](../subsystems/subsys-build-mini-lite.md). + +## Obtaining Source Code and Tools + +The following table describes the tools and source code required for setting up the general environment for a Linux server and how to obtain these tools and the source code. + +**Table 1** Source code and development tools and their obtaining methods + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Item

+

Description

+

How to Obtain

+

Source code

+

Develops functions.

+

For details, see Source Code Acquisition.

+

Python3.7+

+

Executes script compilation.

+

Internet

+

gn

+

Generates ninja compilation scripts.

+

https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz

+

ninja

+

Executes ninja compilation scripts.

+

https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar

+

+

LLVM

+

+

+

Functions as the compiler toolchain.

+

+

For the master and OpenHarmony_v2.x branches and tags, use version 10.0.1:

+

https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz

+

For the OpenHarmony_v1.x branches and tags, use version 9.0.0:

+

https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar

+

hb

+

Compiles the OpenHarmony source code.

+

Internet

+

Other tools

+

Provide functions required in compilation and building, such as packaging and creating images.

+

Internet

+
+ +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install compilation tools like **gn** and **ninja**. +>- \(Recommended\) If you obtain the source code via the mirror site or code repository, install compilation tools such as **gn**, **ninja**, and LLVM. When installing these tools, ensure that their environment variable paths are unique. + +## Obtaining Source Code + +You need to acquire [source code](../get-code/sourcecode-acquire.md), download it on a Linux server, and decompress it. + +## Installing and Configuring Python + +1. Start a Linux server. +2. Check the Python version \(Python 3.7 or later is required\). + + ``` + python3 --version + ``` + + If Python version is earlier than 3.7, reinstall Python. Do as follows to install Python, for example, Python 3.8. + + 1. Check the Ubuntu version. + + ``` + cat /etc/issue + ``` + + 1. Install Python based on the Ubuntu version. + - If the Ubuntu version is 18 or later, run the following command: + + ``` + sudo apt-get install python3.8 + ``` + + - If the Ubuntu version is 16, perform the following steps: + + a. Install dependency packages. + + ``` + sudo apt update && sudo apt install software-properties-common + ``` + + b. Add the source of deadsnakes PPA and press **Enter**. + + ``` + sudo add-apt-repository ppa:deadsnakes/ppa + ``` + + c. Install Python 3.8. + + ``` + sudo apt upgrade && sudo apt install python3.8 + ``` + + + +3. Set the soft link of **python** and **python3** to **python3.8**. + + ``` + sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1 + sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1 + ``` + +4. Install and upgrade the Python package management tool \(pip3\) using either of the following methods: + - **Command line:** + + ``` + sudo apt-get install python3-setuptools python3-pip -y + sudo pip3 install --upgrade pip + ``` + + - **Installation package:** + + ``` + curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py + python get-pip.py + ``` + + + +## Installing gn + +1. Start a Linux server. +2. Download [gn](https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz). +3. Create the **gn** folder in the root directory. + + ``` + mkdir ~/gn + ``` + +4. Decompress the gn installation package to **\~/gn**. + + ``` + tar -xvf gn-linux-x86-1717.tar.gz -C ~/gn + ``` + +5. Set an environment variable. + + ``` + vim ~/.bashrc + ``` + + Copy the following command to the last line of the **.bashrc** file, save the file, and exit. + + ``` + export PATH=~/gn:$PATH + ``` + +6. Validate the environment variable. + + ``` + source ~/.bashrc + ``` + + +## Installing ninja + +1. Start a Linux server. +2. Download [ninja](https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar). +3. Decompress the ninja installation package to **\~/ninja**. + + ``` + tar -xvf ninja.1.9.0.tar -C ~/ + ``` + +4. Set an environment variable. + + ``` + vim ~/.bashrc + ``` + + Copy the following command to the last line of the **.bashrc** file, save the file, and exit. + + ``` + export PATH=~/ninja:$PATH + ``` + +5. Validate the environment variable. + + ``` + source ~/.bashrc + ``` + + +## Installing LLVM + +1. Start a Linux server. +2. [Download LLVM](https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz). + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >For the OpenHarmony\_v1.x branches and tags, click [here](https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar) to download LLVM. + +3. Decompress the LLVM installation package to **\~/llvm**. + + ``` + tar -zxvf llvm.tar.gz -C ~/ + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >For the OpenHarmony\_v1.x branches and tags, run the following command to decompress the LLVM installation package: + >``` + >tar -xvf llvm-linux-9.0.0-36191.tar -C ~/ + >``` + +4. Set an environment variable. + + ``` + vim ~/.bashrc + ``` + + Copy the following command to the last line of the **.bashrc** file, save the file, and exit. + + ``` + export PATH=~/llvm/bin:$PATH + ``` + +5. Validate the environment variable. + + ``` + source ~/.bashrc + ``` + + +## Installing hb + +### Prerequisites + +Python 3.7.4 or later has been installed. For details, see [Installing and Configuring Python](#section1238412211211). + +### Installation Procedure + +1. Install **hb**. + + ``` + python3 -m pip install --user ohos-build + ``` + +2. Set an environment variable. + + ``` + vim ~/.bashrc + ``` + + Copy the following command to the last line of the **.bashrc** file, save the file, and exit. + + ``` + export PATH=~/.local/bin:$PATH + ``` + + Update the environment variable. + + ``` + source ~/.bashrc + ``` + +3. Run the **hb -h** command. If the following information is displayed, the installation is successful: + + ``` + usage: hb + + OHOS build system + + positional arguments: + {build,set,env,clean} + build Build source code + set OHOS build settings + env Show OHOS build env + clean Clean output + + optional arguments: + -h, --help Show this help message and exit + ``` + + +### Uninstalling hb + +``` +python3 -m pip uninstall ohos-build +``` + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>If you encounter any problem during the installation, resort to the [FAQ](quickstart-lite-env-setup-faqs.md). + +## Installing Other Tools + +### Installation Procedure + +1. Use **apt-get** to install dependent tools. + + ``` + sudo apt-get install build-essential gcc g++ make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-boot-tools mtd-utils gcc-arm-linux-gnueabi + ``` + + diff --git a/en/device-dev/quick-start/quickstart-lite-env-setup-win.md b/en/device-dev/quick-start/quickstart-lite-env-setup-win.md new file mode 100644 index 0000000000000000000000000000000000000000..5cb943bfdb1881cf0384cff15036cc6cdf7aea74 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-env-setup-win.md @@ -0,0 +1,182 @@ +# Windows Development Environment + +- [Obtaining the Software](#en-us_topic_0000001058091994_section1483143015558) +- [Installing Visual Studio Code](#en-us_topic_0000001058091994_section71401018163318) +- [Installing Python](#en-us_topic_0000001058091994_section16266553175320) +- [Installing Node.js](#en-us_topic_0000001058091994_section5353233124511) +- [Installing hpm](#en-us_topic_0000001058091994_section173054793610) +- [Installing the DevEco Device Tool Plug-in](#en-us_topic_0000001058091994_section4336315185716) + +Operating system: 64-bit version of Windows 10. + +DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedure includes five parts: + +1. Installing Visual Studio Code +2. Installing Python +3. Installing Node.js +4. Installing hpm +5. Installing the DevEco Device Tool Plug-in + +## Obtaining the Software + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Tool

+

Description

+

Version

+

Obtaining Channel

+

Visual Studio Code

+

Code editing tool

+

V1.53 or later (64-bit)

+

https://code.visualstudio.com/Download

+

Python

+

Programming tool

+

V3.7.4 to V3.8.x (64-bit)

+

Recommended: https://www.python.org/downloads/release/python-388/

+

Node.js

+

The npm environment provider

+

v12.0.0 or later (64-bit)

+

https://nodejs.org/en/download/

+

hpm

+

Package manager

+

Latest version

+

For details, see Installing hpm.

+

DevEco Device Tool

+

Plug-in for the OpenHarmony source code compilation, programming, and debugging

+

v2.2 Beta1

+

https://device.harmonyos.com/en/ide#download

+

Log in with your HUAWEI ID to download it. You can register an account here.

+
+ +## Installing Visual Studio Code + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>If you have installed Visual Studio Code, open the CLT and run **code --version** to check whether the version is 1.53 or later. If the version number is returned, it indicates that the environment variables are set correctly. + +1. Double-click the Visual Studio Code package to install it. During the installation, select **Add to PATH \(requires shell restart\)**. + + ![](figure/en-us_image_0000001174350653.png) + +2. After the installation is complete, restart the computer for the environment variables of Visual Studio Code to take effect. +3. Open the CLT and run **code --version**. If the version number can be displayed, it indicates that the installation is successful. + +## Installing Python + +1. Double-click the Python software package, select **Add Python 3.8 to PATH**, and click **Install Now**. + + ![](figure/en-us_image_0000001128470908.png) + +2. After the installation is complete, click **Close**. + + ![](figure/en-us_image_0000001128311104.png) + +3. Open the CLT, and run **python --version** to check the installation result. + + ![](figure/en-us_image_0000001174350655.png) + +4. In the CLT, run the following commands to set the pip source for downloading the dependencies required for later installation: + + ``` + pip config set global.trusted-host repo.huaweicloud.com + pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple + pip config set global.timeout 120 + ``` + + +## Installing Node.js + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>If you have installed Node.js, open the CLT and run **node -v** to check whether the version is 12.0.0 or later. + +1. Run the downloaded software package to install. Use the default settings when following the installation wizard, and click **Next** until **Finish** is displayed. During the installation, Node.js will automatically set the system Path environment variable to the installation directory of **node.exe**. +2. Open the CLT and run **node -v**. If the version number of Node.js is displayed, it indicates that Node.js has been successfully installed. + + ![](figure/en-us_image_0000001128311096.png) + + +## Installing hpm + +Before installing hpm, ensure that Node.js has been installed + +and that your network can access the Internet. If your network requires a proxy to access the Internet, [set up the npm proxy](https://device.harmonyos.com/en/docs/ide/user-guides/npm_proxy-0000001054491032) first. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>If hpm has been installed, run **npm update -g @ohos/hpm-cli** to update it to the latest version. + +1. You are advised to set the npm source to an image in China, for example, a HUAWEI CLOUD image source. + + ``` + npm config set registry https://repo.huaweicloud.com/repository/npm/ + ``` + +2. Open the CLT and run the following command to install the latest version of hpm: + + ``` + npm install -g @ohos/hpm-cli + ``` + + ![](figure/en-us_image_0000001128311100.png) + +3. After the installation is complete, run the following command to obtain the installation result: + + ``` + hpm -V + ``` + + ![](figure/en-us_image_0000001174270735.png) + + +## Installing the DevEco Device Tool Plug-in + +To install the DevEco Device Tool plug-in, ensure that the **user name of the host cannot contain Chinese characters**; otherwise, the plug-in may fail to run. + +DevEco Device Tool will automatically download and install the C/C++ and CodeLLDB plug-ins from the Visual Studio Code Marketplace during the installation process. Therefore, make sure Visual Studio Code can access the Internet. If your network requires a proxy to access the Internet, [set up the Visual Studio Code proxy](https://device.harmonyos.com/en/docs/ide/user-guides/vscode_proxy-0000001074231144) first. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Before installing DevEco Device Tool, ensure that Visual Studio Code is closed. + +1. Decompress the DevEco Device Tool plug-in package and double-click the installer to install. +2. During the installation, the dependency files \(such as C/C++ and CodeLLDB plug-ins\) and execution programs required by DevEco Device Tool are automatically installed. + + ![](figure/en-us_image_0000001128470902.png) + +3. After the installation is complete, the CLT is automatically closed. +4. Open Visual Studio Code, click the ![](figure/en-us_image_0000001174350651.png) button on the left, and check whether C/C++, CodeLLDB, and DevEco Device Tool are listed in **INSTALLED**. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >If the C/C++ and CodeLLDB plug-ins fail to be installed, DevEco Device Tool cannot run properly. To solve the issue, see [Installing the C/C++ and CodeLLDB Plug-ins Offline](https://device.harmonyos.com/en/docs/ide/user-guides/offline_plugin_install-0000001074376846). + + ![](figure/en-us_image_0000001174270727.png) + + diff --git a/en/device-dev/quick-start/quickstart-lite-env-setup.md b/en/device-dev/quick-start/quickstart-lite-env-setup.md new file mode 100644 index 0000000000000000000000000000000000000000..ae5573f8c093656b5b2dc1f91dc80ee5e9e7c4bf --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-env-setup.md @@ -0,0 +1,11 @@ +# Environment Setup + +- **[Overview](quickstart-lite-env-setup-des.md)** + +- **[Windows Development Environment](quickstart-lite-env-setup-win.md)** + +- **[Ubuntu Build Environment](quickstart-lite-env-setup-lin.md)** + +- **[FAQ](quickstart-lite-env-setup-faqs.md)** + + diff --git a/en/device-dev/quick-start/quickstart-lite-introduction-hi3516.md b/en/device-dev/quick-start/quickstart-lite-introduction-hi3516.md new file mode 100644 index 0000000000000000000000000000000000000000..69fcc82dfeba427de884a26a709551cdd50aa0b8 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-introduction-hi3516.md @@ -0,0 +1,42 @@ +# Hi3516 Development Board + +- [Introduction](#section26131214194212) +- [Development Board Specifications](#section15192203316533) + +## Introduction + +Hi3516D V300 is a next-generation system on chip \(SoC\) designed for the industry-dedicated smart HD IP camera. It introduces a next-generation image signal processor \(ISP\), the H.265 video compression encoder, and a high-performance NNIE engine, leading the industry in terms of low bit rate, high image quality, intelligent processing and analysis, and low power consumption. + +**Figure 1** Front view of the Hi3516D V300 board + + +![](figure/3516正面.png) + +## Development Board Specifications + +**Table 1** Specifications of the Hi3516 development board + + + + + + + + + + + + + +

Type

+

Specification

+

Processor and internal memory

+
  • Hi3516D V300
  • DDR3 1GB
  • 8 GB eMMC4.5
+

External components

+
  • Ethernet port
  • Audio and video
    • One voice input
    • One mono (AC_L) output, connected to a 3 W power amplifier (LM4871)
    • MicroHDMI (one HDMI 1.4)
    +
  • Camera
    • Sensor IMX335
    • M12 lens with a focal length of 4 mm and an aperture of 1.8
    +
  • Display
    • 2.35-inch LCD connector
    • 5.5-inch LCD connector
    +
  • External components and interfaces
    • microSD card interface
    • JTAG/I2S interface
    • ADC interface
    • Steer gear interface
    • Grove connector
    • USB2.0(Type C)
    • Three function keys: two custom keys and one update key
    • LED indicator (including green and red)
    +
+
+ diff --git a/en/device-dev/quick-start/quickstart-lite-introduction-hi3518.md b/en/device-dev/quick-start/quickstart-lite-introduction-hi3518.md new file mode 100644 index 0000000000000000000000000000000000000000..4e050a388c0bd04733b5b37a6849e7a1d8fbf143 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-introduction-hi3518.md @@ -0,0 +1,57 @@ +# Hi3518 Development Board + +- [Introduction](#section14815247616) +- [Development Board Specifications](#section765112478446) + +## Introduction + +Hi3518E V300 is a next-generation system on chip \(SoC\) designed for the industry-dedicated smart HD IP camera. It introduces a next-generation image signal processor \(ISP\), the H.265 video compression encoder, and the advanced low-power process and architecture design, leading the industry in terms of low bit rate, high image quality, and low power consumption. + +**Figure 1** Front view of the Hi3518E V300 board +![](figure/front-view-of-the-hi3518e-v300-board.png "front-view-of-the-hi3518e-v300-board") + +**Figure 2** Rear view of the Hi3518E V300 board + + +![](figure/hi3518正背面.png) + +## Development Board Specifications + +**Table 1** Specifications of the Hi3518 development board + + + + + + + + + + + + + + + + + + + + + + +

Type

+

Description

+

Processor core

+
  • Hi3518E V300
+

Imaging device

+
  • 1/2.9 F23
+

External interfaces

+
  • External microphone
  • External 8 Ω/1.5 W speaker
+

External memory interface

+
  • TF card

    A maximum file size of 128 GB is allowed (FAT32 format).

    +
+

WLAN protocol

+
  • 802.11 b/g/n
+
+ diff --git a/en/device-dev/quick-start/quickstart-lite-introduction-hi3861.md b/en/device-dev/quick-start/quickstart-lite-introduction-hi3861.md new file mode 100644 index 0000000000000000000000000000000000000000..3a8c051e1c78e97241c6d8407a9e7c37afe50c4b --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-introduction-hi3861.md @@ -0,0 +1,157 @@ +# Hi3861 Development Board + +- [Introduction](#section19352114194115) +- [Resources and Constraints](#section82610215014) +- [Development Board Specifications](#section169054431017) +- [Key Features](#section1317173016507) + +## Introduction + +The Hi3861 WLAN module is a development board with 2 x 5 cm form factor. It contains a 2.4 GHz WLAN SoC that highly integrates the IEEE 802.11b/g/n baseband and radio frequency \(RF\) circuit. This module provides open and easy-to-use development and debugging environments for running OpenHarmony. + +**Figure 1** Appearance of Hi3861 WLAN module + + +![](figure/3861正面.png) + +The Hi3861 WLAN module can also be connected to the Hi3861 mother board to expand its peripheral capabilities. The following figure shows the Hi3861 mother board. + +**Figure 2** Appearance of the Hi3861 mother board + + +![](figure/en-us_image_0000001174350615.png) + +- The RF circuit includes modules such as the power amplifier \(PA\), low noise amplifier \(LNA\), RF Balun, antenna switch, and power management. It supports a standard bandwidth of 20 MHz and a narrow bandwidth of 5 MHz or 10 MHz, and provides a maximum rate of 72.2 Mbit/s at the physical layer. +- The Hi3861 WLAN baseband supports the orthogonal frequency division multiplexing \(OFDM\) technology and is backward compatible with the direct sequence spread spectrum \(DSSS\) and complementary code keying \(CCK\) technologies. In addition, the Hi3861 WLAN baseband supports various data rates specified in the IEEE 802.11 b/g/n protocol. +- The Hi3861 chip integrates the high-performance 32-bit microprocessor, hardware security engine, and various peripheral interfaces. The peripheral interfaces include the Synchronous Peripheral Interface \(SPI\), Universal Asynchronous Receiver & Transmitter \(UART\), the Inter Integrated Circuit \(I2C\), Pulse Width Modulation \(PWM\), General Purpose Input/Output \(GPIO\) interface, and Analog to Digital Converter \(ADC\). The Hi3861 chip also supports the high-speed Secure Digital Input/Output \(SDIO\) 2.0 interface, with a maximum clock frequency of 50 MHz. This chip has a built-in static random access memory \(SRAM\) and flash memory, so that programs can run independently or run from a flash drive. +- The Hi3861 chip applies to Internet of Things \(IoT\) devices such as smart home appliances. + + **Figure 3** Hi3861 functions + + + ![](figure/en-us_image_0000001128311066.png) + + +## Resources and Constraints + +As the Hi3861 only offers 2 MB Flash and 352 KB RAM, use them efficiently when compiling code. + +## Development Board Specifications + +**Table 1** Hi3861 WLAN module specifications + + + + + + + + + + + + + + + + + + + + + + + + + +

Type

+

Description

+

General specifications

+
  • Operates over 1×1 2.4 GHz frequency band (ch1-ch14).
  • The physical layer (PHY) complies with the IEEE 802.11b/g/n protocol.
  • The media access control (MAC) layer complies with the IEEE802.11 d/e/h/i/k/v/w protocol.
+
  • Includes the built-in public address (PA) and local area network (LAN); integrates transmit-receive (Tx/Rx) switch and Balun.
  • Supports the station (STA) and access point (AP) modes. When the Hi3861 WLAN module functions as an AP, a maximum of six STAs are supported.
  • Supports WFA WPA, WFA WPA2 personal, and WPS2.0.
  • Supports three kinds of packet traffic arbiter (PTA) (2- , 3- , or 4-wire PTA), each of which coexists with the BT or BLE chip.
  • The input voltage ranges from 2.3 V to 3.6 V.
+
  • The input/output (I/O) power voltage can be 1.8 V or 3.3 V.
+
  • Supports self-calibration for RF hardware.
  • Performs with low power consumption:
    • Ultra deep sleep mode: 5 μA @ 3.3 V
    • DTIM1: 1.5 mA @ 3.3 V
    • DTIM3: 0.8 mA @ 3.3 V
    +
+

PHY features

+
  • Supports all data rates of the single antenna required by the IEEE802.11b/g/n protocol.
  • Supports a maximum rate of 72.2 Mbps@HT20 MCS7
  • Supports the standard bandwidth (20 MHz) and narrow bandwidth (5 MHz or 10 MHz).
  • Supports space-time block coding (STBC).
  • Supports short guard interval (Short-GI).
+

MAC features

+
  • Supports aggregate MAC service data unit (A-MPDU) and aggregate MAC protocol data unit (A-MSDU).
  • Supports block acknowledgment (Blk-ACK).
  • Supports quality of service (QoS), meeting customer's service requirements.
+

CPU subsystem

+
  • Integrates a high-performance 32-bit microprocessor with a maximum operating frequency of 160 MHz.
  • Includes built-in 352 KB SRAM and 288 KB ROM.
  • Includes a built-in 2 MB flash memory.
+

Peripheral interfaces

+
  • Include one SDIO interface, two SPI interfaces, two I2C interfaces, three UART interfaces, 15 GPIO interfaces, seven ADC inputs, six PWM interfaces, and one I2S interface (Note: These interfaces are all multiplexed.)
  • The frequency of the external primary crystal oscillator is 40 MHz or 24 MHz.
+

Other information

+
  • Package: QFN-32, 5 mm x 5 mm
  • Operating temperature: –40°C to +85°C
+
+ +## Key Features + +OpenHarmony provides a series of available capabilities based on the Hi3861 platform. The following table describes the available key components. + +**Table 2** Key components + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Component

+

Description

+

wlan

+

Provides WLAN service, such as connecting to or disconnecting from a station or hotspot, and querying the state of a station or hotspot.

+

iot controller

+

Provides the capability of operating peripherals, including the I2C, I2S, ADC, UART, SPI, SDIO, GPIO, PWM and FLASH.

+

soft bus

+

Provides the capabilities of device discovery and data transmission in the distributed network.

+

hichainsdk

+

Provides the capability of securely transferring data between devices when they are interconnected.

+

huks

+

Provides capabilities of key management, encryption, and decryption.

+

system ability manager

+

Provides a unified OpenHarmony service development framework based on the service-oriented architecture.

+

bootstrap

+

Provides the entry identifier for starting a system service. When the system service management is started, the function identified by bootstrap is called to start a system service.

+

syspara

+

Provides capabilities of obtaining and setting system attributes.

+

utils

+

Provides basic and public capabilities, such as file operations and key-value (KV) storage management.

+

DFX

+

Provides the DFX capabilities, such as logging and printing.

+

XTS

+

Provides a set of OpenHarmony certification test suites.

+
+ diff --git a/en/device-dev/quick-start/quickstart-lite-introduction.md b/en/device-dev/quick-start/quickstart-lite-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..39c2b6911dc8f1b529884b5b5e457c6e01e65c62 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-introduction.md @@ -0,0 +1,9 @@ +# Introduction to the Development Boards + +- **[Hi3861 Development Board](quickstart-lite-introduction-hi3861.md)** + +- **[Hi3516 Development Board](quickstart-lite-introduction-hi3516.md)** + +- **[Hi3518 Development Board](quickstart-lite-introduction-hi3518.md)** + + diff --git a/en/device-dev/quick-start/overview-0.md b/en/device-dev/quick-start/quickstart-lite-overview.md similarity index 100% rename from en/device-dev/quick-start/overview-0.md rename to en/device-dev/quick-start/quickstart-lite-overview.md diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3516-faqs.md b/en/device-dev/quick-start/quickstart-lite-steps-board3516-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..8c597eeca8ee9b47ac9e7592e9d7846111f4e5b1 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3516-faqs.md @@ -0,0 +1,172 @@ +# FAQs + +- [What should I do when the images failed to be burnt over the selected serial port?](#section627268185113) +- [What should I do when Windows-based PC failed to be connected to the board?](#section195391036568) +- [What should I do when the image failed to be burnt?](#section571164016565) +- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#section1039835245619) +- [What should I do when no command output is displayed?](#section14871149155911) + +## What should I do when the images failed to be burnt over the selected serial port? + +- **Symptom** + + **Error: Opening COMxx: Access denied** is displayed after clicking **Burn** and selecting a serial port. + + **Figure 1** Failed to open the serial port + ![](figure/failed-to-open-the-serial-port.png "failed-to-open-the-serial-port") + +- **Possible Causes** + + The serial port has been used. + +- **Solutions** + +1. Search for the terminal using serial-xx from the drop-down list in the **TERMINAL** panel. + + **Figure 2** Checking whether the serial port is used + ![](figure/checking-whether-the-serial-port-is-used.png "checking-whether-the-serial-port-is-used") + +2. Click the dustbin icon as shown in the following figure to disable the terminal using the serial port. + + **Figure 3** Disabling the terminal using the serial port + ![](figure/disabling-the-terminal-using-the-serial-port.png "disabling-the-terminal-using-the-serial-port") + +3. Click **Burn**, select the serial port, and start burning images again. + + **Figure 4** Restarting burning + + + ![](figure/changjian1.png) + + +## What should I do when Windows-based PC failed to be connected to the board? + +- **Symptom** + + The file image cannot be obtained after clicking **Burn** and selecting a serial port. + + **Figure 5** Failed to obtain the image file due to unavailable connection + ![](figure/failed-to-obtain-the-image-file-due-to-unavailable-connection.png "failed-to-obtain-the-image-file-due-to-unavailable-connection") + +- **Possible Causes** + + The board is disconnected from the Windows-based PC. + + Windows Firewall does not allow Visual Studio Code to access the network. + +- **Solutions** + +1. Check whether the network cable is properly connected. +2. Click **Windows Firewall**. + + **Figure 6** Network and firewall setting + ![](figure/network-and-firewall-setting.png "network-and-firewall-setting") + +3. Click **Firewall & network protection**, and on the displayed page, click **Allow applications to communicate through Windows Firewall**. + + **Figure 7** Firewall and network protection + ![](figure/firewall-and-network-protection.png "firewall-and-network-protection") + +4. Select the Visual Studio Code application. + + **Figure 8** Selecting the Visual Studio Code application + ![](figure/selecting-the-visual-studio-code-application.png "selecting-the-visual-studio-code-application") + +5. Select the **Private** and **Public** network access rights for the Visual Studio Code application. + + **Figure 9** Allowing the Visual Studio Code application to access the network + ![](figure/allowing-the-visual-studio-code-application-to-access-the-network.png "allowing-the-visual-studio-code-application-to-access-the-network") + + +## What should I do when the image failed to be burnt? + +- **Symptom** + + The burning status is not displayed after clicking **Burn** and selecting a serial port. + +- **Possible Causes** + + The IDE is not restarted after the DevEco plug-in is installed. + +- **Solutions** + + Restart the IDE. + + +## What should I do when the message indicating Python cannot be found is displayed during compilation and building? + +- **Symptom** + + ![](figure/en-us_image_0000001174270715.png) + + +- **Possible Cause 1**: Python is not installed. +- **Solutions** + + Install Python by referring to [Installing and Configuring Python](quickstart-lite-env-setup-lin.md). + +- **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. + + ![](figure/en-us_image_0000001128470880.png) + +- **Solutions** + + Run the following commands: + + ``` + # cd /usr/bin/ + # which python3 + # ln -s /usr/local/bin/python3 python + # python --version + ``` + + Example: + + ![](figure/en-us_image_0000001174270713.png) + + +## What should I do when no command output is displayed? + +- **Symptom** + + The serial port shows that the connection has been established. After the board is restarted, nothing is displayed when you press **Enter**. + +- **Possible Cause 1** + + The serial port is connected incorrectly. + +- **Solutions** + + Change the serial port number. + + Start **Device Manager** to check whether the serial port connected to the board is the same as that connected to the terminal device. If the serial ports are different, perform step [1](#section627268185113) in the **Running an Image** section to change the serial port number. + + +- **Possible Cause 2** + + The U-boot of the board is damaged. + +- **Solutions** + + Burn the U-boot. + + If the fault persists after you perform the preceding operations, the U-boot of the board may be damaged. You can burn the U-boot by performing the following steps: + + +1. Obtain the U-boot file. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >The U-boot file of the two boards can be obtained from the following paths, respectively. + >Hi3516D V300: **device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin** + >Hi3518E V300: **device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin** + +2. Burn the U-boot file by following the procedures for burning a U-boot file over USB. + + Select the U-boot files of corresponding development boards for burning by referring to [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Programming Flash Memory on the Hi3518](https://device.harmonyos.com/en/docs/ide/user-guides/hi3518_upload-0000001057313128) + +3. Log in to the serial port after the burning is complete. + + **Figure 10** Serial port displayed after the U-boot is burnt + ![](figure/serial-port-displayed-after-the-u-boot-is-burnt.png "serial-port-displayed-after-the-u-boot-is-burnt") + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3516-program.md b/en/device-dev/quick-start/quickstart-lite-steps-board3516-program.md new file mode 100644 index 0000000000000000000000000000000000000000..e541eb5237923c4715d3a4b16249360a1d06a9c3 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3516-program.md @@ -0,0 +1,503 @@ +# Developing a Driver + +- [Introduction to Driver](#s8efc1952ebfe4d1ea717182e108c29bb) +- [Compiling and Burning](#section660016185110) +- [Running an Image](#section333215226219) +- [Follow-up Learning](#section9712145420182) + +This section describes how to develop a driver on the board, including introduction, compilation, burning, and running of the driver. + +## Introduction to Driver + +The following operations take a HDF-based UART driver as an example to show how to add configuration files, code the driver, and compile the code for interactions between the user-space applications and the driver. The driver source code is stored in the **vendor/huawei/hdf/sample** directory. + +1. Add Configurations. + + Add driver configurations to the HDF driver configuration file \(for example, **device/hisilicon/hi3516dv300/sdk\_liteos/config/uart/uart\_config.hcs**\). + + ``` + root { + platform { + uart_sample { + num = 5; // UART device number + base = 0x120a0000; // Base address of the UART register + irqNum = 38; + baudrate = 115200; + uartClk = 24000000; + wlen = 0x60; + parity = 0; + stopBit = 0; + match_attr = "sample_uart_5"; + } + } + } + ``` + + Add the device node information to the HDF device configuration file \(for example, **vendor/hisilicon/ipcamera\_hi3516dv300\_liteos/config/device\_info/device\_info.hcs**\) + + ``` + root { + device_info { + platform :: host { + hostName = "platform_host"; + priority = 50; + device_uart :: device { + device5 :: deviceNode { + policy = 2; + priority = 10; + permission = 0660; + moduleName = "UART_SAMPLE"; + serviceName = "HDF_PLATFORM_UART_5"; + deviceMatchAttr = "sample_uart_5"; + } + } + } + } + } + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >The configuration files are in the same path as the source code of the UART driver. You need to manually add the files to the path of the Hi3516D V300 development board. + +2. Register a UART driver entry. + + Register the **HdfDriverEntry** of the UART driver with the HDF. + + ``` + // Bind the UART driver interface to the HDF. + static int32_t SampleUartDriverBind(struct HdfDeviceObject *device) + { + struct UartHost *uartHost = NULL; + + if (device == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + HDF_LOGI("Enter %s:", __func__); + + uartHost = UartHostCreate(device); + if (uartHost == NULL) { + HDF_LOGE("%s: UartHostCreate failed", __func__); + return HDF_FAILURE; + } + uartHost->service.Dispatch = SampleDispatch; + return HDF_SUCCESS; + } + + // Obtain configuration information from the HCS of the UART driver. + static uint32_t GetUartDeviceResource( + struct UartDevice *device, const struct DeviceResourceNode *resourceNode) + { + struct UartResource *resource = &device->resource; + struct DeviceResourceIface *dri = NULL; + dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (dri == NULL || dri->GetUint32 == NULL) { + HDF_LOGE("DeviceResourceIface is invalid"); + return HDF_FAILURE; + } + + if (dri->GetUint32(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read num fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "base", &resource->base, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read base fail"); + return HDF_FAILURE; + } + resource->physBase = (unsigned long)OsalIoRemap(resource->base, 0x48); + if (resource->physBase == 0) { + HDF_LOGE("uart config fail to remap physBase"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "irqNum", &resource->irqNum, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read irqNum fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "baudrate", &resource->baudrate, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read baudrate fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "wlen", &resource->wlen, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read wlen fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "parity", &resource->parity, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read parity fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "stopBit", &resource->stopBit, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read stopBit fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "uartClk", &resource->uartClk, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read uartClk fail"); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + // Attach the configuration and interface of the UART driver to the HDF. + static int32_t AttachUartDevice(struct UartHost *host, struct HdfDeviceObject *device) + { + int32_t ret; + struct UartDevice *uartDevice = NULL; + if (device->property == NULL) { + HDF_LOGE("%s: property is NULL", __func__); + return HDF_FAILURE; + } + uartDevice = (struct UartDevice *)OsalMemCalloc(sizeof(struct UartDevice)); + if (uartDevice == NULL) { + HDF_LOGE("%s: OsalMemCalloc uartDevice error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + ret = GetUartDeviceResource(uartDevice, device->property); + if (ret != HDF_SUCCESS) { + (void)OsalMemFree(uartDevice); + return HDF_FAILURE; + } + host->num = uartDevice->resource.num; + host->priv = uartDevice; + AddUartDevice(host); + return InitUartDevice(uartDevice); + } + + // Initialize the UART driver. + static int32_t SampleUartDriverInit(struct HdfDeviceObject *device) + { + int32_t ret; + struct UartHost *host = NULL; + + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_OBJECT; + } + HDF_LOGI("Enter %s:", __func__); + host = UartHostFromDevice(device); + if (host == NULL) { + HDF_LOGE("%s: host is NULL", __func__); + return HDF_FAILURE; + } + ret = AttachUartDevice(host, device); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: attach error", __func__); + return HDF_FAILURE; + } + host->method = &g_sampleUartHostMethod; + return ret; + } + + static void DeinitUartDevice(struct UartDevice *device) + { + struct UartRegisterMap *regMap = (struct UartRegisterMap *)device->resource.physBase; + /* Wait for the UART to enter the idle state. */ + while (UartPl011IsBusy(regMap)); + UartPl011ResetRegisters(regMap); + uart_clk_cfg(0, false); + OsalIoUnmap((void *)device->resource.physBase); + device->state = UART_DEVICE_UNINITIALIZED; + } + + // Detach and release the UART driver. + static void DetachUartDevice(struct UartHost *host) + { + struct UartDevice *uartDevice = NULL; + + if (host->priv == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return; + } + uartDevice = host->priv; + DeinitUartDevice(uartDevice); + (void)OsalMemFree(uartDevice); + host->priv = NULL; + } + + // Release the UART driver. + static void SampleUartDriverRelease(struct HdfDeviceObject *device) + { + struct UartHost *host = NULL; + HDF_LOGI("Enter %s:", __func__); + + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return; + } + host = UartHostFromDevice(device); + if (host == NULL) { + HDF_LOGE("%s: host is NULL", __func__); + return; + } + if (host->priv != NULL) { + DetachUartDevice(host); + } + UartHostDestroy(host); + } + + struct HdfDriverEntry g_sampleUartDriverEntry = { + .moduleVersion = 1, + .moduleName = "UART_SAMPLE", + .Bind = SampleUartDriverBind, + .Init = SampleUartDriverInit, + .Release = SampleUartDriverRelease, + }; + + HDF_INIT(g_sampleUartDriverEntry); + ``` + +3. Register a UART driver interface. + + Implement the UART driver interface using the template **UartHostMethod** provided by the HDF. + + ``` + static int32_t SampleUartHostInit(struct UartHost *host) + { + HDF_LOGI("%s: Enter", __func__); + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + return HDF_SUCCESS; + } + + static int32_t SampleUartHostDeinit(struct UartHost *host) + { + HDF_LOGI("%s: Enter", __func__); + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + return HDF_SUCCESS; + } + + // Write data into the UART device. + static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size) + { + HDF_LOGI("%s: Enter", __func__); + uint32_t idx; + struct UartRegisterMap *regMap = NULL; + struct UartDevice *device = NULL; + + if (host == NULL || data == NULL || size == 0) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + device = (struct UartDevice *)host->priv; + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_PARAM; + } + regMap = (struct UartRegisterMap *)device->resource.physBase; + for (idx = 0; idx < size; idx++) { + UartPl011Write(regMap, data[idx]); + } + return HDF_SUCCESS; + } + + // Set the baud rate for the UART device. + static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate) + { + HDF_LOGI("%s: Enter", __func__); + struct UartDevice *device = NULL; + struct UartRegisterMap *regMap = NULL; + UartPl011Error err; + + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + device = (struct UartDevice *)host->priv; + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_PARAM; + } + regMap = (struct UartRegisterMap *)device->resource.physBase; + if (device->state != UART_DEVICE_INITIALIZED) { + return UART_PL011_ERR_NOT_INIT; + } + if (baudRate == 0) { + return UART_PL011_ERR_INVALID_BAUD; + } + err = UartPl011SetBaudrate(regMap, device->uartClk, baudRate); + if (err == UART_PL011_ERR_NONE) { + device->baudrate = baudRate; + } + return err; + } + + // Obtain the baud rate of the UART device. + static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate) + { + HDF_LOGI("%s: Enter", __func__); + struct UartDevice *device = NULL; + + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + device = (struct UartDevice *)host->priv; + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_PARAM; + } + *baudRate = device->baudrate; + return HDF_SUCCESS; + } + + // Bind the UART device using HdfUartSampleInit. + struct UartHostMethod g_sampleUartHostMethod = { + .Init = SampleUartHostInit, + .Deinit = SampleUartHostDeinit, + .Read = NULL, + .Write = SampleUartHostWrite, + .SetBaud = SampleUartHostSetBaud, + .GetBaud = SampleUartHostGetBaud, + .SetAttribute = NULL, + .GetAttribute = NULL, + .SetTransMode = NULL, + }; + ``` + + Add the sample module of the UART driver to the compilation script **device/hisilicon/drivers/lite.mk**. + + ``` + LITEOS_BASELIB += -lhdf_uart_sample + LIB_SUBDIRS += $(LITEOS_SOURCE_ROOT)/vendor/huawei/hdf/sample/platform/uart + ``` + +4. Implement the code for interaction between the user-space applications and driver. + + Create the **/dev/uartdev-5** node after the UART driver is initialized successfully. The following example shows how to interact with the UART driver through the node. + + ``` + #include + #include + #include + #include "hdf_log.h" + + #define HDF_LOG_TAG "hello_uart" + #define INFO_SIZE 16 + + int main(void) + { + int ret; + int fd; + const char info[INFO_SIZE] = {" HELLO UART! "}; + + fd = open("/dev/uartdev-5", O_RDWR); + if (fd < 0) { + HDF_LOGE("hello_uart uartdev-5 open failed %d", fd); + return -1; + } + ret = write(fd, info, INFO_SIZE); + if (ret != 0) { + HDF_LOGE("hello_uart write uartdev-5 ret is %d", ret); + } + ret = close(fd); + if (ret != 0) { + HDF_LOGE("hello_uart uartdev-5 close failed %d", fd); + return -1; + } + return ret; + } + ``` + + Add the **hello\_uart\_sample** component to **targets** of the **hdf\_hi3516dv300\_liteos\_a** component in the **build/lite/components/drivers.json** file. + + ``` + { + "components": [ + { + "component": "hdf_hi3516dv300_liteos_a", + ... + "targets": [ + "//vendor/huawei/hdf/sample/platform/uart:hello_uart_sample" + ] + } + ] + } + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >Preceding code snippets are for reference only. You can view the complete sample code in **vendor/huawei/hdf/sample.** + >The sample code is not automatically compiled by default. You can add it to the compilation script. + + +## Compiling and Burning + +Perform the [building](quickstart-lite-steps-board3516-running.md#section1077671315253) and [burning](quickstart-lite-steps-board3516-running.md#section1347011412201) as instructed in **Running a Hello OHOS Program**. + +## Running an Image + +1. Connect to a serial port. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >If the connection fails, rectify the fault by referring to [FAQs](quickstart-lite-steps-board3516-faqs.md). + + **Figure 1** Serial port connection + + + ![](figure/chuankou1.png) + + 1. Click **Monitor** to enable the serial port. + 2. Press **Enter** repeatedly until **hisilicon** displays. + 3. Go to [2](quickstart-lite-steps-board3516-running.md#l5b42e79a33ea4d35982b78a22913b0b1) if the board is started for the first time or the startup parameters need to be modified; go to [3](quickstart-lite-steps-board3516-running.md#ld26f18828aa44c36bfa36be150e60e49) otherwise. + +2. \(Mandatory when the board is started for the first time\) Modify the **bootcmd** and **bootargs** parameters of U-Boot. You need to perform this step only once if the parameters need not to be modified during the operation. The board automatically starts after it is reset. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >The default waiting time in the U-Boot is 2s. You can press **Enter** to interrupt the waiting and run the **reset** command to restart the system after "hisilicon" is displayed. + + **Table 1** Parameters of the U-Boot + + + + + + + + + + + + + + + + + + + +

Command

+

Description

+

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

+

Run this command to read content that has a size of 0x4800 (9 MB) and a start address of 0x800 (1 MB) to the memory address 0x80000000. The file size must be the same as that of the OHOS_Image.bin file in the IDE.

+

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

+

Run this command to set the output mode to serial port output, baud rate to 115200, data bit to 8, rootfs to be mounted to the emmc component, and file system type to vfat.

+

rootaddr=10M rootsize=20M rw indicates the start address and size of the rootfs.img file to be burnt, respectively. The file size must be the same as that of the rootfs.img file in the IDE.

+

saveenv

+

saveenv means to save the current configuration.

+

reset

+

reset means to reset the board.

+
+ + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >**go 0x80000000** is optional. It 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, press **Enter** in the countdown phase of the U-Boot startup to interrupt the automatic startup. + +3. Run the **reset** command and press **Enter** to restart the board. After the board is restarted, **OHOS** is displayed when you press **Enter**. + + **Figure 2** System startup + + + ![](figure/qi1.png) + +4. In the root directory, run the **./bin/hello\_uart** command line to execute the demo program. The compilation result is shown in the following example. + + ``` + OHOS # ./bin/hello_uart + OHOS # HELLO UART! + ``` + + +## Follow-up Learning + +Congratulations! You have finished all steps! You are advised to go on learning how to develop [Cameras with a Screen](../guide/device-camera.md). + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3516-running.md b/en/device-dev/quick-start/quickstart-lite-steps-board3516-running.md new file mode 100644 index 0000000000000000000000000000000000000000..9b33afae1965ec4b0dd056280dab5eaf24deffc1 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3516-running.md @@ -0,0 +1,269 @@ +# Running a Hello OHOS Program + +- [Creating a Program](#section204672145202) +- [Building](#section1077671315253) +- [Burning](#section1347011412201) +- [Running an Image](#section24721014162010) +- [Running a Program](#section5276734182615) + +This section describes how to create, compile, burn, and run the first program, and finally print **Hello OHOS!** on the develop board. + +## Creating a Program + +1. Create a directory and the program source code. + + Create the **applications/sample/camera/apps/src/helloworld.c** directory and file whose code is shown in the following example. You can customize the content to be printed. For example, you can change **OHOS** to **World**. You can use either C or C++ to develop a program. + + ``` + #include + + int main(int argc, char **argv) + { + printf("\n************************************************\n"); + printf("\n\t\tHello OHOS!\n"); + printf("\n************************************************\n\n"); + + return 0; + } + ``` + +2. Create a build file. + + Create the **applications/sample/camera/apps/BUILD.gn** file. The file content is as follows: + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("hello-OHOS") { + features = [ ":helloworld" ] + } + executable("helloworld") { + output_name = "helloworld" + sources = [ "src/helloworld.c" ] + include_dirs = [] + defines = [] + cflags_c = [] + ldflags = [] + } + ``` + +3. Add a new component. + + Add the configuration of the **hello\_world\_app** component to the **build/lite/components/applications.json** file. The sample code below shows some configurations defined in the **applications.json** file, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) + + ``` + { + "components": [ + { + "component": "camera_sample_communication", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/communication" + ], + "targets": [ + "//applications/sample/camera/communication:sample" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##start## + { + "component": "hello_world_app", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/apps" + ], + "targets": [ + "//applications/sample/camera/apps:hello-OHOS" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##end## + { + "component": "camera_sample_app", + "description": "Camera related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/launcher", + "applications/sample/camera/cameraApp", + "applications/sample/camera/setting", + "applications/sample/camera/gallery", + "applications/sample/camera/media" + ], + ``` + +4. Modify the board configuration file. + + Add the **hello\_world\_app** component to the **vendor/hisilicon/hispark\_taurus/config.json** file. The sample code below shows the configurations of the **applications** subsystem, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) + + ``` + { + "subsystem": "applications", + "components": [ + { "component": "camera_sample_app", "features":[] }, + { "component": "camera_sample_ai", "features":[] }, + ##start## + { "component": "hello_world_app", "features":[] }, + ##end## + { "component": "camera_screensaver_app", "features":[] } + ] + }, + ``` + + +## Building + +If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/gettools-acquire.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: + +``` +hb set (Set the building path.) +. (Select the current path.) +Select ipcamera_hispark_taurus@hisilicon and press Enter. +hb build -f (Start building.) +``` + +**Figure 1** Settings +![](figure/settings.png "settings") + +The result files are generated in the **out/hispark\_taurus/ipcamera\_hispark\_taurus** directory. + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>The U-Boot file of the Hi3516D V300 development board can be obtained from the following path: device/hisilicon/hispark\_taurus/sdk\_liteos/uboot/out/boot/u-boot-hi3516dv300.bin + +## Burning + +The Hi3516 development board allows you to burn flash memory over the USB port, serial port, or network port. The following uses the network port burning as an example. + +1. Connect the PC and the target development board through the power port, serial port, and network port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](quickstart-lite-introduction-hi3516.md). +2. Open Device Manager, then check and record the serial port number corresponding to the development board. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). + + ![](figure/en-us_image_0000001174350647.png) + +3. Open DevEco Device Tool and go to **Projects** \> **Settings**. + + ![](figure/2021-01-27_170334.png) + +4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. +5. On the **hi3516dv300** tab page, set the programming options. + + - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001056443961_li142386399535). + - **upload\_protocol**: Select the programming protocol **hiburn-net**. + - **upload\_partitions**: Select the file to be programmed. By default, the **fastboot**, **kernel**, **rootfs**, and **userfs** files are programmed at the same time. + + ![](figure/en-us_image_0000001128470904.png) + +6. Check and set the IP address of the network adapter connected to the development board. For details, see [Setting the IP Address of the Network Port for Programming on Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/set_ipaddress-0000001141825075). +7. Set the IP address of the network port for programming: + + - **upload\_net\_server\_ip**: Select the IP address set in [6](#en-us_topic_0000001056443961_li1558813168234). Example: 192.168.1.2. + - **upload\_net\_client\_mask**: Set the subnet mask of the development board, such as 255.255.255.0. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 255.255.255.0. + - **upload\_net\_client\_gw**: Set the gateway of the development board, such as 192.168.1.1. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 192.168.1.1. + - **upload\_net\_client\_ip**: Set the IP address of the development board, such as 192.168.1.3. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 192.168.1.3. + + ![](figure/en-us_image_0000001174270733.png) + +8. When you finish modifying, click **Save** in the upper right corner. +9. Open the project file and click ![](figure/2021-01-27_170334-2.png). In the DevEco Device Tool window, choose **PROJECT TASKS** \> **hi3516dv300** \> **Upload** to start programming. + + ![](figure/en-us_image_0000001174270729.png) + +10. When the following message is displayed, power off the development board and then power it on. + + ![](figure/en-us_image_0000001128470906.png) + +11. Start burning. When the following message is displayed, the burning is successful. + + ![](figure/en-us_image_0000001128311098.png) + + +## Running an Image + +1. Connect to a serial port. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >If the connection fails, rectify the fault by referring to [FAQs](quickstart-lite-steps-board3516-faqs.md). + + **Figure 2** Serial port connection + + + ![](figure/chuankou1.png) + + 1. Click **Monitor** to enable the serial port. + 2. Press **Enter** repeatedly until **hisilicon** displays. + 3. Go to step [2](#l5b42e79a33ea4d35982b78a22913b0b1) if the board is started for the first time or the startup parameters need to be modified; go to step [3](#ld26f18828aa44c36bfa36be150e60e49) otherwise. + +2. \(Mandatory when the board is started for the first time\) Modify the bootcmd and bootargs parameters of U-Boot. You need to perform this step only once if the parameters need not to be modified during the operation. The board automatically starts after it is reset. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >The default waiting time in the U-Boot is 2s. You can press **Enter** to interrupt the waiting and run the **reset** command to restart the system after "hisilicon" is displayed. + + **Table 1** Parameters of the U-Boot + + + + + + + + + + + + + + + + + + + +

Command

+

Description

+

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

+

Run this command to read content that has a size of 0x4800 (9 MB) and a start address of 0x800 (1 MB) to the memory address 0x80000000. The file size must be the same as that of the OHOS_Image.bin file in the IDE.

+

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

+

Run this command to set the output mode to serial port output, baud rate to 115200, data bit to 8, rootfs to be mounted to the emmc component, and file system type to vfat.

+

rootaddr=10M rootsize=20M rw indicates the start address and size of the rootfs.img file to be burnt, respectively. The file size must be the same as that of the rootfs.img file in the IDE.

+

saveenv

+

saveenv means to save the current configuration.

+

reset

+

reset means to reset the board.

+
+ + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >**go 0x80000000** \(optional\) 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, press **Enter** in the countdown phase of the U-Boot startup to interrupt the automatic startup. + +3. Run the **reset** command and press **Enter** to restart the board. After the board is restarted, **OHOS** is displayed when you press **Enter**. + + **Figure 3** System startup + + + ![](figure/qi1.png) + + +## Running a Program + +In the root directory, run the **./bin/helloworld** command to operate the demo program. The compilation result is shown in the following example. + +**Figure 4** Successful system startup and program execution +![](figure/successful-system-startup-and-program-execution.png "successful-system-startup-and-program-execution") + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3516-setting.md b/en/device-dev/quick-start/quickstart-lite-steps-board3516-setting.md new file mode 100644 index 0000000000000000000000000000000000000000..bb8595701a4f83270ac876a83f2846ce51d3e863 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3516-setting.md @@ -0,0 +1,122 @@ +# Setting Up the Environment + +- [Environment Requirements](#section179175261196) + - [Hardware](#section5840424125014) + - [Software](#section965634210501) + +- [Installing Linux Build Tools](#section182916865219) + - [Changing Linux Shell to Bash](#section1715027152617) + - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section45512412251) + - [Installing File Packing Tools and JVM](#section16199102083717) + + +## Environment Requirements + +### Hardware + +- Hi3516D V300 IoT camera development board +- USB-to-serial cable and network cable \(The Windows workstation is connected to the Hi3516D V300 development board through the USB-to-serial cable and network cable.\) + +The following figure shows the hardware connections. + +**Figure 1** Hardware connections + + +![](figure/矩形备份-292.png) + +### Software + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>This section describes how to use an installation package to set up the compilation and development environment. If you are going to use Docker to set up the environment, skip this section and [Installing Linux Build Tools](#section182916865219). + +The following table describes the tools required for setting up the general environment for a Linux server of the Hi3516 development board and how to obtain these tools. + +**Table 1** Development tools and obtaining methods + + + + + + + + + + + + + + + + + + + + + + + + +

Development Tool

+

Description

+

How to Obtain

+

bash

+

Processes CLI commands.

+

System configuration

+

Basic software package for compilation and building (required only for Ubuntu 20+)

+

Provides a basic software package for compilation and building.

+

Internet

+

dosfstools, mtools, and mtd-utils

+

Pack files.

+

apt-get install

+

Java virtual machine (JVM)

+

Compiles, debugs, and runs Java programs.

+

apt-get install

+
+ +## Installing Linux Build Tools + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install compilation tools like **LLVM** and **hc-gen**. +>- \(Recommended\) If you obtain the source code via the mirror site or code repository, install **hc-gen**. When installing the compilation tool, ensure that its environment variable path is unique. + +### Changing Linux Shell to Bash + +Check whether bash is used as the shell. + +``` +ls -l /bin/sh +``` + +If **/bin/sh -\> bash** is not displayed, do as follows to change shell to bash. + +**Method 1:** Run the following command on the device and then click **No**. + +``` +sudo dpkg-reconfigure dash +``` + +**Method 2:** Run the first command to delete **sh** and then run the second command to create a new soft link. + +``` +sudo rm -rf /bin/sh +sudo ln -s /bin/bash /bin/sh +``` + +### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) + +Install the software. + +``` +sudo apt-get install build-essential gcc g++ make zlib* libffi-dev +``` + +### Installing File Packing Tools and JVM + +1. Start a Linux server. +2. Install the dosfstools, mtools, mtd-utils, Java Runtime Environment \(JRE\), and Java SDK. + + ``` + sudo apt-get install dosfstools mtools mtd-utils default-jre default-jdk + ``` + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3516.md b/en/device-dev/quick-start/quickstart-lite-steps-board3516.md new file mode 100644 index 0000000000000000000000000000000000000000..97db943fc49eedc60d2a1409ed319390b0df9624 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3516.md @@ -0,0 +1,11 @@ +# Hi3516 + +- **[Setting Up the Environment](quickstart-lite-steps-board3516-setting.md)** + +- **[Running a Hello OHOS Program](quickstart-lite-steps-board3516-running.md)** + +- **[Developing a Driver](quickstart-lite-steps-board3516-program.md)** + +- **[FAQs](quickstart-lite-steps-board3516-faqs.md)** + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3518-faqs.md b/en/device-dev/quick-start/quickstart-lite-steps-board3518-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..384eac7cdccbc83828ce8259efcafad4fb29cc3d --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3518-faqs.md @@ -0,0 +1,174 @@ +# FAQs + +- [What should I do when the images failed to be burnt over the selected serial port?](#section1498892119619) +- [What should I do when Windows-based PC failed to be connected to the board?](#section8512971816) +- [What should I do when the image failed to be burnt?](#section1767804111198) +- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#en-us_topic_0000001053466255_section1039835245619) +- [What should I do when no command output is displayed?](#en-us_topic_0000001053466255_section14871149155911) + +## What should I do when the images failed to be burnt over the selected serial port? + +- **Symptom** + + **Error: Opening COMxx: Access denied** is displayed after clicking **Burn** and selecting a serial port. + + **Figure 1** Failed to open the serial port + ![](figure/failed-to-open-the-serial-port-8.png "failed-to-open-the-serial-port-8") + +- **Possible Causes** + + The serial port has been used. + +- **Solutions** + +1. Search for the terminal using serial-xx from the drop-down list in the **TERMINAL** panel. + + **Figure 2** Checking whether the serial port is used + ![](figure/checking-whether-the-serial-port-is-used-9.png "checking-whether-the-serial-port-is-used-9") + +2. Click the dustbin icon as shown in the following figure to disable the terminal using the serial port. + + **Figure 3** Disabling the terminal using the serial port + ![](figure/disabling-the-terminal-using-the-serial-port-10.png "disabling-the-terminal-using-the-serial-port-10") + +3. Click **Burn**, select the serial port, and start burning images again. + + **Figure 4** Restarting burning + + + ![](figure/changjian1-11.png) + + +## What should I do when Windows-based PC failed to be connected to the board? + +- **Symptom** + + The file image cannot be obtained after clicking **Burn** and selecting a serial port. + + **Figure 5** Failed to obtain the image file due to unavailable connection + ![](figure/failed-to-obtain-the-image-file-due-to-unavailable-connection-12.png "failed-to-obtain-the-image-file-due-to-unavailable-connection-12") + +- **Possible Causes** + + The board is disconnected from the Windows-based PC. + + Windows Firewall does not allow Visual Studio Code to access the network. + +- **Solutions** + +1. Check whether the network cable is properly connected. +2. Click **Windows Firewall**. + + **Figure 6** Network and firewall setting + ![](figure/network-and-firewall-setting-13.png "network-and-firewall-setting-13") + +3. Click **Firewall & network protection**, and on the displayed page, click **Allow applications to communicate through Windows Firewall**. + + **Figure 7** Firewall and network protection + ![](figure/firewall-and-network-protection-14.png "firewall-and-network-protection-14") + +4. Select the Visual Studio Code application. + + **Figure 8** Selecting the Visual Studio Code application + ![](figure/selecting-the-visual-studio-code-application-15.png "selecting-the-visual-studio-code-application-15") + +5. Select the **Private** and **Public** network access rights for the Visual Studio Code application. + + **Figure 9** Allowing the Visual Studio Code application to access the network + ![](figure/allowing-the-visual-studio-code-application-to-access-the-network-16.png "allowing-the-visual-studio-code-application-to-access-the-network-16") + + +## What should I do when the image failed to be burnt? + +- **Symptom** + + The burning status is not displayed after clicking **Burn** and selecting a serial port. + +- **Possible Causes** + + The IDE is not restarted after the DevEco plug-in is installed. + +- **Solutions** + + Restart the IDE. + + +## What should I do when the message indicating Python cannot be found is displayed during compilation and building? + +- **Symptom** + + ![](figure/en-us_image_0000001174270743.png) + + +- **Possible Cause 1** + + Python is not installed. + +- **Solutions** + + Install Python by referring to [Installing and Configuring Python](quickstart-lite-env-setup-lin.md). + +- **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. + + ![](figure/en-us_image_0000001174270739.png) + +- **Solutions** + + Run the following commands: + + ``` + # cd /usr/bin/ + # which python3 + # ln -s /usr/local/bin/python3 python + # python --version + ``` + + Example: + + ![](figure/en-us_image_0000001174350661.png) + + +## What should I do when no command output is displayed? + +- **Symptom** + + The serial port shows that the connection has been established. After the board is restarted, nothing is displayed when you press **Enter**. + +- **Possible Cause 1** + + The serial port is connected incorrectly. + +- **Solutions** + + Change the serial port number. + + Start **Device Manager** to check whether the serial port connected to the board is the same as that connected to the terminal device. If the serial ports are different, perform step [1](quickstart-lite-steps-board3518-running.md) in the **Running an Image** section to change the serial port number. + + +- **Possible Cause 2** + + The U-boot of the board is damaged. + +- **Solutions** + + Burn the U-boot. + + If the fault persists after you perform the preceding operations, the U-boot of the board may be damaged. You can burn the U-boot by performing the following steps: + + +1. Obtain the U-boot file. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >The U-boot file of the two boards can be obtained from the following paths, respectively. + >Hi3516D V300: **device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin** + >Hi3518E V300: **device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin** + +2. Burn the U-boot file by following the procedures for burning a U-boot file over USB. + + Select the U-boot files of corresponding development boards for burning by referring to [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Programming Flash Memory on the Hi3518](https://device.harmonyos.com/en/docs/ide/user-guides/hi3518_upload-0000001057313128) + +3. Log in to the serial port after the burning is complete. + + ![](figure/en-us_image_0000001174350659.png) + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3518-running.md b/en/device-dev/quick-start/quickstart-lite-steps-board3518-running.md new file mode 100644 index 0000000000000000000000000000000000000000..7b8ec4ecd0d6d0541dbe37430a8aa05cf02f9cd1 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3518-running.md @@ -0,0 +1,262 @@ +# Running a Hello OHOS Program + +- [Creating a Program](#section1550972416485) +- [Building](#section234175193114) +- [Burning](#section7609155824819) +- [Running an Image](#section17612105814480) +- [Follow-up Learning](#section9712145420182) + +This section describes how to create, compile, burn, and run the first program, and finally print **Hello OHOS!** on the develop board. + +## Creating a Program + +1. Create a directory and the program source code. + + Create the **applications/sample/camera/apps/src/helloworld.c** directory and file whose code is shown in the following example. You can customize the content to be printed. For example, you can change **OHOS** to **World**. You can use either C or C++ to develop a program. + + ``` + #include + + int main(int argc, char **argv) + { + printf("\n************************************************\n"); + printf("\n\t\tHello OHOS!\n"); + printf("\n************************************************\n\n"); + + return 0; + } + ``` + +2. Create a build file. + + Create the **applications/sample/camera/apps/BUILD.gn** file. The file content is as follows: + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("hello-OHOS") { + features = [ ":helloworld" ] + } + executable("helloworld") { + output_name = "helloworld" + sources = [ "src/helloworld.c" ] + include_dirs = [] + defines = [] + cflags_c = [] + ldflags = [] + } + ``` + +3. Add a component. + + Add the configuration of the **hello\_world\_app** component to the **build/lite/components/applications.json** file. The sample code below shows some configurations defined in the **applications.json** file, and the code between **"\#\#start\#\#"** and **"\#\#end\#\#"** is the new configuration \(Delete the rows where **"\#\#start\#\#"** and **"\#\#end\#\#"** are located after the configurations are added.\) + + ``` + { + "components": [ + { + "component": "camera_sample_communication", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/communication" + ], + "targets": [ + "//applications/sample/camera/communication:sample" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##start## + { + "component": "hello_world_app", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/apps" + ], + "targets": [ + "//applications/sample/camera/apps:hello-OHOS" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##end## + { + "component": "camera_sample_app", + "description": "Camera related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/launcher", + "applications/sample/camera/cameraApp", + "applications/sample/camera/setting", + "applications/sample/camera/gallery", + "applications/sample/camera/media" + ], + ``` + +4. Modify the board configuration file. + + Add the **hello\_world\_app** component to the **vendor/hisilicon/hispark\_aries/config.json** file. The sample code below shows the configurations of the **applications** subsystem, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) + + ``` + { + "subsystem": "applications", + "components": [ + ##start## + { "component": "hello_world_app", "features":[] }, + ##end## + { "component": "camera_sample_app", "features":[] } + + ] + }, + ``` + + +## Building + +If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/gettools-acquire.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: + +``` +hb set (Set the building path.) +. (Select the current path.) +Select ipcamera_hispark_aries@hisilicon and press Enter. +hb build -f (Start building.) +``` + +The result files are generated in the **out/hispark\_aries/ipcamera\_hispark\_aries** directory. + +**Figure 1** Settings +![](figure/settings-4.png "settings-4") + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>The U-Boot file of the Hi3518E V300 development board can be obtained from the following path: device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin + +## Burning + +The USB port is the only burning mode supported by the Hi3518 development board. + +1. Connect the PC and the target development board through the serial port and USB port. In this section, the Hi3518EV300 is used as an example. For details, see [Introduction to the Hi3518 Development Board](quickstart-lite-introduction-hi3518.md). +2. Open Device Manager, then check and record the serial port number corresponding to the development board. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). + + ![](figure/en-us_image_0000001128470900.png) + +3. Open DevEco Device Tool and go to **Projects** \> **Settings**. + + ![](figure/en-us_image_0000001174350649.png) + +4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. +5. On the **hi3518ev300** tab page, set the programming options. + + - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001057313128_li46411811196). + - **upload\_protocol**: Select the programming protocol **hiburn-usb**. + - **upload\_partitions**: Select the file to be programmed. By default, the **fastboot**, **kernel**, **rootfs**, and **userfs** files are programmed at the same time. + + ![](figure/en-us_image_0000001128311090.png) + +6. When you finish modifying, click **Save** in the upper right corner. +7. Open the project file and click ![](figure/2021-01-27_170334-5.png). In the DevEco Device Tool window, choose **PROJECT TASKS** \> **hi3518ev300\_fastboot** \> **Erase** to erase U-Boot. + + ![](figure/en-us_image_0000001174270731.png) + +8. When the following message is displayed, power off the development board and then power it on. + + ![](figure/en-us_image_0000001128311092.png) + +9. If the following message is displayed, it indicates that U-Boot is erased successfully. + + ![](figure/en-us_image_0000001128311094.png) + +10. Go to **hi3518ev300** \> **Upload** to start programming. + + ![](figure/en-us_image_0000001174350641.png) + +11. If the following message is displayed, it indicates that the programming is successful. + + ![](figure/en-us_image_0000001174350643.png) + + +## Running an Image + +1. Connect to a serial port. + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >If the connection fails, rectify the fault by referring to [FAQs](quickstart-lite-steps-board3518-faqs.md). + + **Figure 2** Serial port connection + + + ![](figure/chuankou1-6.png) + + 1. Click **Monitor** to enable the serial port. The **TERMINAL** window is displayed. + 2. Press **Enter** repeatedly until **hisilicon** displays. + 3. Go to [step 2](#li9441185382314) if the board is started for the first time or the startup parameters need to be modified; go to [step 3](#li6442853122312) otherwise. + +2. \(Mandatory for first-time burning\) Modify the **bootcmd** and **bootargs** parameters of U-Boot. This step is a fixed operation and the result can be saved. However, you need to perform the following steps again if U-Boot needs to be reburnt. + + **Table 1** Parameters of the U-Boot + + + + + + + + + + + + + + + + + + + + + + +

Command

+

Description

+

setenv bootcmd "sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000";

+

Run this command to set the content of bootcmd. Select the flash whose number is 0, and read content that has a size of 0x600000 (6 MB) and a start address of 0x100000 to memory address 0x40000000. The size must be the same as that of the OHOS_Image.bin file in the IDE.

+

setenv bootargs "console=ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7M rootsize=8M";

+

In this command, bootargs is set to the serial port output, the baud rate is 115200, the data bit is 8, and the rootfs is mounted to the flash memory. The file system type is set to jffs2 rw, which provides the read-write attribute for the JFFS2 file system. rootaddr=7M rootsize=8M indicates the actual start address and length of the rootfs.img file to be burnt, respectively. The file size must be the same as that of the rootfs.img file in the IDE.

+

saveenv

+

saveenv means to save the current configuration.

+

reset

+

reset means to reset the board.

+

pri

+

pri means to view the displayed parameters.

+
+ + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >**go 0x40000000** \(optional\) 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, press **Enter** in the countdown phase of the U-Boot startup to interrupt the automatic startup. + +3. If **hisilicon \#** is displayed during the startup, run the **reset** command. After the system automatically starts and **OHOS** is displayed, run the **./bin/helloworld** command and then press **Enter**. The system is started successfully if information shown in the following figure is displayed. + + **Figure 3** Successful system startup and program execution + ![](figure/successful-system-startup-and-program-execution-7.png "successful-system-startup-and-program-execution-7") + + +## Follow-up Learning + +Congratulations! You have finished all steps! You are advised to go on learning how to develop [Cameras with a Screen](../guide/device-iotcamera.md). + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3518-setting.md b/en/device-dev/quick-start/quickstart-lite-steps-board3518-setting.md new file mode 100644 index 0000000000000000000000000000000000000000..9bc63015a4c5956197248d223e54de4bc1df1c1b --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3518-setting.md @@ -0,0 +1,114 @@ +# Setting Up the Environment + +- [Environment Requirements](#section1724111409282) + - [Hardware](#section487353718276) + - [Software Requirements](#section17315193935817) + +- [Installing Linux Build Tools](#section8831868501) + - [Changing Linux Shell to Bash](#section434110241084) + - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section25911132141020) + - [Installing File Packing Tools](#section390214473129) + + +## Environment Requirements + +### Hardware + +- Hi3518E V300 IoT camera development board +- USB-to-serial cable and network cable \(The Windows workstation is connected to the Hi3518E V300 development board through the USB-to-serial cable and network cable.\) + + The following figure shows the hardware connections. + + +**Figure 1** Hardware connections +![](figure/hardware-connections-3.png "hardware-connections-3") + +### Software Requirements + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>This section describes how to use an installation package to set up the compilation and development environment. If you are going to use Docker to set up the environment, skip this section and [Installing Linux Build Tools](#section8831868501). + +The following table describes the tools required for setting up the general environment for a Linux server of the Hi3518 development board and how to obtain these tools. + +**Table 1** Development tools and obtaining methods + + + + + + + + + + + + + + + + + + + + +

Development Tool

+

Description

+

How to Obtain

+

bash

+

Processes CLI commands.

+

System configuration

+

Basic software package for compilation and building (required only for Ubuntu 20+)

+

Provides a basic software package for compilation and building.

+

Internet

+

dosfstools, mtools, and mtd-utils

+

Pack files.

+

apt-get install

+
+ +## Installing Linux Build Tools + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install **hc-gen**. +>- \(Recommended\) If you obtain the source code via the mirror site or code repository, install **hc-gen**. When installing the compilation tool, ensure that its environment variable path is unique. + +### Changing Linux Shell to Bash + +Check whether bash is used as the shell. + +``` +ls -l /bin/sh +``` + +If **/bin/sh -\> bash** is not displayed, do as follows to change shell to bash. + +**Method 1:** Run the following command on the device and then click **No**. + +``` +sudo dpkg-reconfigure dash +``` + +**Method 2:** Run the first command to delete **sh** and then run the second command to create a new soft link. + +``` +sudo rm -rf /bin/sh +sudo ln -s /bin/bash /bin/sh +``` + +### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) + +Install the software. + +``` +sudo apt-get install build-essential gcc g++ make zlib* libffi-dev +``` + +### Installing File Packing Tools + +1. Start a Linux server. +2. Install dosfstools, mtools, and mtd-utils. + + ``` + sudo apt-get install dosfstools mtools mtd-utils + ``` + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3518.md b/en/device-dev/quick-start/quickstart-lite-steps-board3518.md new file mode 100644 index 0000000000000000000000000000000000000000..e9f239a0ee8bcf928fe46dc35ba11fb2a48b31e1 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3518.md @@ -0,0 +1,9 @@ +# Hi3518 + +- **[Setting Up the Environment](quickstart-lite-steps-board3518-setting.md)** + +- **[Running a Hello OHOS Program](quickstart-lite-steps-board3518-running.md)** + +- **[FAQs](quickstart-lite-steps-board3518-faqs.md)** + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3861-connection.md b/en/device-dev/quick-start/quickstart-lite-steps-board3861-connection.md new file mode 100644 index 0000000000000000000000000000000000000000..2ce585ea88b513619177b24358cc3f82e0442b86 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3861-connection.md @@ -0,0 +1,142 @@ +# WLAN Connection + +- [Building](#section191121332125319) +- [Burning Images](#section19458165166) +- [Connecting WLAN Module to the Internet.](#section194671619167) + +This example shows how to connect the WLAN module to the gateway using attention \(AT\) commands. + +## Building + +This section describes how to perform the WLAN module building on a Linux server. + +If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/sourcecode-acquire.md). If the Linux environment is installed using a software package, perform the following steps: + +1. Open the HUAWEI DevEco Device Tool and choose **View** \> **Terminal**. + + **Figure 1** Starting the IDE terminal tool + + + ![](figure/1.png) + + On the **TERMINAL** panel, run the ssh command, for example, **ssh** **_user_@_ipaddr_**, to connect to the Linux server. + + **Figure 2** TERMINAL panel + + + ![](figure/2.png) + +2. Go to the root directory of the code, run the **hb set** and **.** commands on the **TERMINAL** panel, and select the **wifiiot\_hispark\_pegasus** version. + + **Figure 3** Selecting the target build version + + + ![](figure/3.png) + +3. Run the **hb build** command to start building. + + **Figure 4** Running commands on the TERMINAL panel + + + ![](figure/4.png) + +4. Check whether the building is successful. If yes, **wifiiot\_hispark\_pegasus build success** will be displayed, as shown in the following figure. + + **Figure 5** Successful building + + + ![](figure/5.png) + +5. Check whether the following files are generated in the **./out/wifiiot/** directory. + + ``` + ls -l out/hispark_pegasus/wifiiot_hispark_pegasus/ + ``` + + **Figure 6** Directory for storing the generated files + + + ![](figure/3-0.png) + + +## Burning Images + +You can use the DevEco tool to perform the image burning of the Hi3861 WLAN module. For details about how to use the tool, see [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). + +1. Connect the PC and the target development board through the USB port. For details, see [Introduction to the Hi3861 Development Board](quickstart-lite-introduction-hi3861.md). +2. Open Device Manager, then check and record the serial port number corresponding to the development board. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3861 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3861-drivers-0000001058153433). + + ![](figure/en-us_image_0000001128311118.png) + +3. Open DevEco Device Tool and go to **Projects** \> **Settings**. + + ![](figure/en-us_image_0000001128311116.png) + +4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. +5. On the **hi3861** tab page, set the programming options. + + - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001056563976_li848662117291). + - **upload\_protocol**: Select the burning protocol **burn-serial**. + - **upload\_partitions**: Select the file to be burned. **hi3861\_app** is selected by default. + + ![](figure/en-us_image_0000001128470922.png) + +6. When you finish modifying, click **Save** in the upper right corner. +7. Open the project file. In the DevEco Device Tool window, go to **PROJECT TASKS** \> **hi3861** \> **Upload** to start programming. + + ![](figure/en-us_image_0000001174270749.png) + +8. When the following information is displayed, press the RST button on the development board to restart it. + + ![](figure/en-us_image_0000001174270751.png) + +9. Start burning. When the following message is displayed, the burning is successful. + + ![](figure/en-us_image_0000001174350669.png) + + +## Connecting WLAN Module to the Internet. + +After completing version building and burning, do as follows to connect the WLAN module to the Internet using AT commands. + +1. Click the icon of **DevEco: Serial Monitor** at the bottom of DevEco Studio to keep the connection between the Windows workstation and the WLAN module. + + **Figure 7** Opening the DevEco serial port + + + ![](figure/5-1.png) + +2. Reset the WLAN module. The message **ready to OS start** is displayed on the **TERMINAL** panel, indicating that the WLAN module is started successfully. + + **Figure 8** Successful resetting of the WLAN module + + + ![](figure/6.png) + +3. Run the following AT commands in sequence via the DevEco serial port terminal to start the STA mode, connect to the specified AP, and enable Dynamic Host Configuration Protocol \(DHCP\). + + ``` + AT+STARTSTA # Start the STA mode. + AT+SCAN # Scan for available APs. + AT+SCANRESULT # Display the scanning result. + AT+CONN="SSID",,2,"PASSWORD" # Connect to the specified AP. (SSID and PASSWORD represent the name and password of the hotspot to be connected, respectively.) + AT+STASTAT # View the connection result. + AT+DHCP=wlan0,1 # Request the IP address of wlan0 from the AP using DHCP. + ``` + +4. Check whether the WLAN module is properly connected to the gateway, as shown in the following figure. + + ``` + AT+IFCFG # View the IP address assigned to an interface of the module. + AT+PING=X.X.X.X # Check the connectivity between the module and the gateway. Replace X.X.X.X with the actual gateway address. + ``` + + **Figure 9** Successful networking of the WLAN module + + + ![](figure/截图.png) + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3861-faqs.md b/en/device-dev/quick-start/quickstart-lite-steps-board3861-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..9f4f5b1583e64ed802a7b076f008b31a89e7c2ac --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3861-faqs.md @@ -0,0 +1,286 @@ +# FAQs + +- [What should I do when the message configure: error: no acceptable C compiler found in $PATH is displayed during Python 3 installation?](#section1221016541119) +- [What should I do when the message -bash: make: command not found is displayed during Python 3 installation?](#section1913477181213) +- [What should I do when the message zlib not available is displayed during Python 3 installation?](#section108211415131210) +- [What should I do when the message No module named '\_ctypes' is displayed during Python 3 installation?](#section2062268124) +- [What should I do when the message No module named 'Crypto' is displayed during compilation and building?](#section982315398121) +- [What should I do when the message No module named 'ecdsa' is displayed during compilation and building?](#section102035451216) +- [What should I do when the message Could not find a version that satisfies the requirement six\>=1.9.0 is displayed during compilation and building?](#section4498158162320) +- [What should I do when the message cannot find -lgcc is displayed during compilation and building?](#section11181036112615) +- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#section1571810194619) +- [What should I do when an error with lsb\_release occurs during kconfiglib installation?](#section691681635814) + +## What should I do when the message **configure: error: no acceptable C compiler found in $PATH** is displayed during Python 3 installation? + +- **Symptom** + + The following error occurs during Python 3 installation: + + ``` + configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details + ``` + +- **Possible Causes** + + **GCC** is not installed. + +- **Solutions** + + 1. Run the **apt-get install gcc** command to install **GCC** online. + + 2. After the installation, reinstall Python 3. + + +## What should I do when the message **-bash: make: command not found** is displayed during Python 3 installation? + +- **Symptom** + + The following error occurs during Python 3 installation: + + ``` + -bash: make: command not found + ``` + +- **Possible Causes** + + **Make** is not installed. + +- **Solutions** + + 1. Run the **apt-get install make** command to install **Make** online. + + 2. After the installation, reinstall Python 3. + + +## What should I do when the message **zlib not available** is displayed during Python 3 installation? + +- **Symptom** + + The following error occurs during Python 3 installation: + + ``` + zipimport.ZipImportError: can't decompress data; zlib not avaliable + ``` + +- **Possible Causes** + + **zlib** is not installed. + +- **Solutions** + + Solution 1: Run the **apt-get install zlib** command to install **zlib** online. + + Solution 2: If the software source does not contain **zlib**, download the source code from [http://www.zlib.net/](http://www.zlib.net/). + + ![](figure/10.png) + + Then run the following commands to install **zlib** offline: + + ``` + # tar xvf zlib-1.2.11.tar.gz + # cd zlib-1.2.11 + # ./configure + # make && make install + ``` + + After the installation, reinstall Python 3. + + +## What should I do when the message **No module named '\_ctypes'** is displayed during Python 3 installation? + +- **Symptom** + + The following error occurs during Python 3 installation: + + ``` + ModuleNotFoundError: No module named '_ctypes' + ``` + + +- **Possible Causes** + + **libffi** and **libffi-devel** are not installed. + + +- **Solutions** + + 1. Run the **apt-get install libffi\* -y** command to install **libffi** and **libffi-devel** online. + + 2. After the installation, reinstall Python 3. + + +## What should I do when the message **No module named 'Crypto'** is displayed during compilation and building? + +- **Symptom** + + The following error occurs during compilation and building: + + ``` + ModuleNotFoundError: No module named 'Crypto' + ``` + + +- **Possible Causes** + + **Crypto** is not installed. + + +- **Solutions** + + Solution 1: Run the **pip3 install Crypto** command to install **Crypto** online. + + Solution 2: Install **Crypto** offline. + + - Download the source code from [https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files). + + ![](figure/en-us_image_0000001128470864.png) + + - Save the source code package to the Linux server, decompress the package, and run the **python3 setup.py install** command to install **Crypto**. + - Rebuild an environment. + + +## What should I do when the message **No module named 'ecdsa'** is displayed during compilation and building? + +- **Symptom** + + The following error occurs during compilation and building: + + ``` + ModuleNotFoundError: No module named 'ecdsa' + ``` + + +- **Possible Causes** + + **ecdsa** is not installed. + + +- **Solutions** + + Solution 1: Run the **pip3 install ecdsa** command to install **ecdsa** online. + + Solution 2: Install **ecdsa** offline. + + - Download the installation package from [https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files). + + ![](figure/en-us_image_0000001128311072.png) + + - Save the installation package to the Linux server and run the **pip3 install ecdsa-0.15-py2.py3-none-any.whl** command to install **ecdsa**. + - Rebuild an environment. + + +## What should I do when the message **Could not find a version that satisfies the requirement six\>=1.9.0** is displayed during compilation and building? + +- **Symptom** + + The following error occurs during compilation and building: + + ``` + Could not find a version that satisfies the requirement six>=1.9.0 + ``` + + +- **Possible Causes** + + **six** is not installed. + + +- **Solutions** + + Solution 1: Run the **pip3 install six** command to install **six** online. + + Solution 2: Install **six** offline. + + - Download the installation package from [https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files). + + ![](figure/en-us_image_0000001174270699.png) + + - Save the source code to the Linux server and run the **pip3 install six-1.14.0-py2.py3-none-any.whl** command to install **six**. + - Rebuild an environment. + + +## What should I do when the message **cannot find -lgcc** is displayed during compilation and building? + +- **Symptom** + + The following error occurs during compilation and building: + + ``` + riscv32-unknown-elf-ld: cannot find -lgcc + ``` + + +- **Possible Causes** + + The PATH is incorrectly written by **gcc\_riscv32**. There is an extra slash \(/\). + + ``` + ~/gcc_riscv32/bin/:/data/toolchain/ + ``` + + +- **Solutions** + + Modify the PATH by deleting the slash \(/\). + + ``` + ~/gcc_riscv32/bin:/data/toolchain/ + ``` + + +## What should I do when the message indicating Python cannot be found is displayed during compilation and building? + +- **Symptom** + + The following error occurs during compilation and building: + + ``` + -bash: /usr/bin/python: No such file or directory + ``` + + +- **Possible Cause 1:** Python is not installed. +- **Solutions** + + Install Python by referring to [Installing and Configuring Python](quickstart-lite-env-setup-lin.md). + +- **Possible Cause 2:** The soft link that points to the Python does not exist in the **usr/bin** directory. + + ![](figure/en-us_image_0000001128311070.png) + +- **Solutions** + + Run the following commands to add a soft link: + + ``` + # cd /usr/bin/ + # which python3 + # ln -s /usr/local/bin/python3 python + # python --version + ``` + + Example: + + ![](figure/en-us_image_0000001174350623.png) + + +## What should I do when an error with **lsb\_release** occurs during **kconfiglib** installation? + +- **Symptom** + + The following error occurs during **kconfiglib** installation: + + ``` + subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1. + ``` + +- **Possible Causes** + + The Python version matched with the **lsb\_release** module is different from the current Python version. + +- **Solutions** + + Run the **find / -name lsb\_release** command, for example, **sudo rm -rf /usr/bin/lsb\_release** to locate and delete **lsb\_release**. + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3861-running.md b/en/device-dev/quick-start/quickstart-lite-steps-board3861-running.md new file mode 100644 index 0000000000000000000000000000000000000000..d33056d84f2597bcabd5c97a8244ee4bcf3501a3 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3861-running.md @@ -0,0 +1,156 @@ +# Running a Hello World Program + +- [Modifying Source Code](#section79601457101015) +- [Debugging and Verification](#section1621064881419) +- [printf](#section1246911301217) +- [Locating Exceptions Using the asm File](#section199621957141014) +- [Viewing Execution Result](#section18115713118) +- [Follow-up Learning](#section9712145420182) + +This example shows how to compile a simple service and print **Hello World** to help you preliminarily understand how to run OpenHarmony on Hi3861. + +## Modifying Source Code + +The source code needs to be modified when fixing bugs or compiling a new service. The following describes how to modify the source code when compiling a new service, for example, **my\_first\_app**. + +1. Determine the directory structure. + + Before compiling a service, you must create a directory \(or a directory structure\) in **./applications/sample/wifi-iot/app** to store source code files. + + For example, add the **my\_first\_app** service to the **app** directory, where **hello\_world.c** is the service code and **BUILD.gn** is the compilation script. The directory structure is shown as follows: + + ``` + . + └── applications + └── sample + └── wifi-iot + └── app + │── my_first_app + │ │── hello_world.c + │ └── BUILD.gn + └── BUILD.gn + ``` + +2. Compile the service code. + + Create the **hello\_world.c** file in **./applications/sample/wifi-iot/app/my\_first\_app**. Then, create the service entry function **HelloWorld** in **hello\_world.c** and implement service logic. Use the SYS\_RUN\(\) of the OpenHarmony **bootstrap** module to start services. \(**SYS\_RUN** is defined in the **ohos\_init.h** file.\) + + ``` + #include + #include "ohos_init.h" + #include "ohos_types.h" + + void HelloWorld(void) + { + printf("[DEMO] Hello world.\n"); + } + SYS_RUN(HelloWorld); + ``` + +3. Add the **BUILD.gn** file for building services into a static library. + + Create the **BUILD.gn** file in **./applications/sample/wifi-iot/app/my\_first\_app** and fill in three parts \(target, source file, and header file path\) of the **BUILD.gn** file. + + ``` + static_library("myapp") { + sources = [ + "hello_world.c" + ] + include_dirs = [ + "//utils/native/lite/include" + ] + } + ``` + + - Specify the compilation result named libmyapp.a in **static\_library**. You can fill in this part based on your need. + - Specify the .c file on which a file depends and its path in **sources**. The path that contains **//** represents an absolute path \(the code root path\), otherwise it is a relative path. + - Specify the path of .h file on which **sources** depends in **include\_dirs**. + +4. Modify the **BUILD.gn** file and specify the feature modules to be built. + + Configure the **./applications/sample/wifi-iot/app/BUILD.gn** file and add an index to the **features** field to enable the target to be involved in compilation. Specify the path and target of a service module in **features**. The following uses **my\_first\_app** as an example and the **features** is configured as follows: + + ``` + import("//build/lite/config/component/lite_component.gni") + + lite_component("app") { + features = [ + "my_first_app:myapp", + ] + } + ``` + + - **my\_first\_app** is a relative path that points to **./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn**. + - **myapp** represents the **static\_library\("myapp"\)** in **./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn**. + + +## Debugging and Verification + +Currently, there are two debugging and verification methods: using printf to print logs and using asm files to locate **panic** problems. You can select one of them based on your need. + +As the service shown is simple, use the printf method. The following describes the two debugging methods. + +## printf + +Add **printf** function to the code, which helps print data to the serial port. You can add log printing in key service paths or service exception locations, as shown in the following figure. + +``` +void HelloWorld(void) +{ + printf("[DEMO] Hello world.\n"); +} +``` + +## Locating Exceptions Using the asm File + +When the system exits abnormally, the call stack information about the abnormal exit is displayed on the serial port. The following is an example: You can locate the exception by parsing the exception stack information. + +``` +=======KERNEL PANIC======= +**********************Call Stack********************* +Call Stack 0 -- 4860d8 addr:f784c +Call Stack 1 -- 47b2b2 addr:f788c +Call Stack 2 -- 3e562c addr:f789c +Call Stack 3 -- 4101de addr:f78ac +Call Stack 4 -- 3e5f32 addr:f78cc +Call Stack 5 -- 3f78c0 addr:f78ec +Call Stack 6 -- 3f5e24 addr:f78fc +********************Call Stack end******************* +``` + +To parse the call stack information, the **Hi3861\_wifiiot\_app.asm** file is required. This file records the symbol addresses of the functions in the code in the flash memory and the disassembly information. The asm file is built and output together with the version software package and is stored in the **./out/wifiiot/** directory. + +1. \(Optional\) Save the **CallStack** information to a TXT file for editing. +2. Open the asm file, search for the function address in each call stack, and list the corresponding function. Generally, you only need to find the functions matching the first several stacks to locate exceptions. + + ``` + Call Stack 0 -- 4860d8 addr:f784c -- WadRecvCB + Call Stack 1 -- 47b2b2 addr:f788c -- wal_sdp_process_rx_data + Call Stack 2 -- 3e562c addr:f789c + Call Stack 3 -- 4101de addr:f78ac + Call Stack 4 -- 3e5f32 addr:f78cc + Call Stack 5 -- 3f78c0 addr:f78ec + Call Stack 6 -- 3f5e24 addr:f78fc + ``` + +3. Determine that an exception occurs in the **WadRecvCB** function based on the call stack information. + + ![](figure/en-us_image_0000001174270737.png) + +4. Check and modify the code. + +## Viewing Execution Result + +After the sample code is compiled, burnt, run, and debugged, the following information is displayed on the serial port interface: + +``` +ready to OS start +FileSystem mount ok. +wifi init success! +[DEMO] Hello world. +``` + +## Follow-up Learning + +Congratulations! You have finished all steps! You are advised to go on learning how to develop [WLAN-connected products](../guide/device-wifi.md). + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3861-setting.md b/en/device-dev/quick-start/quickstart-lite-steps-board3861-setting.md new file mode 100644 index 0000000000000000000000000000000000000000..92d567cd5d954a195ccde7826cbfc997f585505f --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3861-setting.md @@ -0,0 +1,367 @@ +# Setting Up the Environment + +- [Environment Requirements](#section466851916410) + - [Hardware](#section19202111020215) + - [Software](#section727451210318) + +- [Installing Linux Build Tools](#section497484245614) + - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section45512412251) + - [Installing Scons](#section7438245172514) + - [Installing Python Modules](#section88701892341) + - [Installing gcc\_riscv32 \(Compilation Toolchain for WLAN Module\)](#section34435451256) + +- [Installing the USB-to-Serial Driver](#section1027732411513) + +## Environment Requirements + +### Hardware + +- Linux compile server +- Windows workstation \(host computer\) +- Hi3861 WLAN module +- USB Type-C cable used to connect the Windows workstation to Hi3861 WLAN module + +The following figure shows the hardware connections. + +**Figure 1** Hardware connections +![](figure/hardware-connections.png "hardware-connections") + +### Software + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>The following part describes how to install tools using installation packages. If you use Docker to set up the build environment, you only need to install the Windows workstation described in [Table 1](#table6299192712513). + +The following table lists the tools required for the Hi3861 development board. + +**Table 1** Required tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Platform

+

Development Tool

+

Description

+

How to Obtain

+

Linux server

+

Basic software package for compilation and building (required only for Ubuntu 20+)

+

Provides a basic software package for compilation and building.

+

Internet

+

Linux server

+

SCons 3.0.4+

+

Executes script compilation.

+

Internet

+

Linux server

+

Python modules: setuptools, Kconfiglib, PyCryptodome, six, and ecdsa

+

Executes script compilation.

+

Internet

+

Linux server

+

gcc riscv32

+

Executes script compilation.

+

Internet

+

Windows workstation

+

CH341SER.EXE

+

USB-to-Serial adapter driver

+

http://www.wch-ic.com/search?t=downloads&q=ch340g

+
+ +## Installing Linux Build Tools + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install **gcc\_riscv32**. +>- \(Recommended\) If you obtain the source code via the mirror site or code repository, install **gcc\_riscv32**. When installing the compilation tool, ensure that its environment variable path is unique. + +### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) + +Install the software. + +``` +sudo apt-get install build-essential gcc g++ make zlib* libffi-dev +``` + +### Installing Scons + +1. Start a Linux server. +2. Install the SCons installation package. + + ``` + python3 -m pip install scons + ``` + +3. Check whether the installation is successful. + + ``` + scons -v + ``` + + **Figure 2** Successful installation \(SCons version requirement: 3.0.4 or later\) + ![](figure/successful-installation-(scons-version-requirement-3-0-4-or-later).png "successful-installation-(scons-version-requirement-3-0-4-or-later)") + + +### Installing Python Modules + +1. Install setuptools. + + ``` + pip3 install setuptools + ``` + +2. Install the GUI menuconfig tool \(Kconfiglib\). You are advised to install Kconfiglib 13.2.0 or later. + - **Command line:** + + ``` + sudo pip3 install kconfiglib + ``` + + + - **Installation package:** + 1. Download the **.whl** file \(for example, **kconfiglib-13.2.0-py2.py3-none-any.whl**\). + + Download path: [https://pypi.org/project/kconfiglib\#files](https://pypi.org/project/kconfiglib#files) + + + 1. Install the **.whl** file. + + ``` + sudo pip3 install kconfiglib-13.2.0-py2.py3-none-any.whl + ``` + + + +3. Install **PyCryptodome** using either of the following methods: + + Install the Python component packages on which the file signature depends, including PyCryptodome, six, and ecdsa. As the installation of **ecdsa** depends on that of **six**, install **six** first. + + - **Command line:** + + ``` + sudo pip3 install pycryptodome + ``` + + - **Installation package:** + 1. Download the **.whl** file \(for example, **pycryptodome-3.9.9-cp38-cp38-manylinux1\_x86\_64.whl**\). + + Download path: [https://pypi.org/project/pycryptodome/\#files](https://pypi.org/project/pycryptodome/#files) + + + 1. Install the **.whl** file. + + ``` + sudo pip3 install pycryptodome-3.9.9-cp38-cp38-manylinux1_x86_64.whl + ``` + + + +4. Install **six** using either of the following methods: + - **Command line:** + + ``` + sudo pip3 install six --upgrade --ignore-installed six + ``` + + + - **Installation package:** + 1. Download the **.whl** file, for example, **six-1.12.0-py2.py3-none-any.whl**. + + Download path: [https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files) + + + 1. Install the **.whl** file. + + ``` + sudo pip3 install six-1.12.0-py2.py3-none-any.whl + ``` + + + +5. Install **ecdsa** using either of the following methods: + - **Command line:** + + ``` + sudo pip3 install ecdsa + ``` + + - **Installation package:** + 1. Download the **.whl** file, for example, **ecdsa-0.14.1-py2.py3-none-any.whl**. + + Download path: [https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files) + + + 1. Install the **.whl** file. + + ``` + sudo pip3 install ecdsa-0.14.1-py2.py3-none-any.whl + ``` + + + + +### Installing gcc\_riscv32 \(Compilation Toolchain for WLAN Module\) + +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>- The Hi3861 platform supports only the static link of the libgcc library. The dynamic link is not recommended because version 3 of the GNU General Public License \(GPLv3\) will be polluted during commercial distribution. +>- Steps 2 to 15 of the following procedure are used to build the **gcc\_riscv32** image. You can simply [download the image](https://repo.huaweicloud.com/harmonyos/compiler/gcc_riscv32/7.3.0/linux/gcc_riscv32-linux-7.3.0.tar.gz) and skip these steps. + +1. Start a Linux server. +2. Install the **GCC**, **G++**, **Bison**, **Flex**, **Makeinfo** tools to ensure that the toolchain can be correctly compiled. + + ``` + sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install flex bison && sudo apt-get install texinfo + ``` + +3. Download the RISC-V GNU toolchain. + + ``` + git clone --recursive https://gitee.com/mirrors/riscv-gnu-toolchain.git + ``` + +4. Open the **riscv-gnu-toolchain** folder and delete empty folders to prevent conflicts during the download of **Newlib**, **Binutils**, and **GCC**. + + ``` + cd riscv-gnu-toolchain && rm -rf riscv-newlib && rm -rf riscv-binutils && rm -rf riscv-gcc + ``` + +5. Download RISC-V Newlib 3.0.0. + + ``` + git clone -b riscv-newlib-3.0.0 https://github.com/riscv/riscv-newlib.git + ``` + +6. Download RISC-V Binutils 2.31.1. + + ``` + git clone -b riscv-binutils-2.31.1 https://github.com/riscv/riscv-binutils-gdb.git + ``` + +7. Download RISC-V GCC 7.3.0. + + ``` + git clone -b riscv-gcc-7.3.0 https://github.com/riscv/riscv-gcc + ``` + +8. Add the RISC-V GCC 7.3.0 patch. + + Visit the GCC official patch links [89411](https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=026216a753ef0a757a9e368a59fa667ea422cf09;hp=2a23a1c39fb33df0277abd4486a3da64ae5e62c2) and [86724](https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff;f=gcc/graphite.h;h=be0a22b38942850d88feb159603bb846a8607539;hp=4e0e58c60ab83f1b8acf576e83330466775fac17;hb=b1761565882ed6a171136c2c89e597bc4dd5b6bf;hpb=fbd5f023a03f9f60c6ae36133703af5a711842a3), and manually add the changes to the .c and .h files based on the requirements in the patch links. Note that the number of rows may not match because of different versions of the patch and GCC. You need to search for the keyword in the patch to locate the corresponding row. + +9. Download, decompress, and install [GMP 6.1.2](https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2). + + ``` + tar -xvf gmp-6.1.2.tar.bz2 && mkdir build_gmp && cd build_gmp && ../gmp-6.1.2/configure --prefix=/usr/local/gmp-6.1.2 --disable-shared --enable-cxx && make && make install + ``` + +10. Download, decompress, and install [mpfr-4.0.2](https://www.mpfr.org/mpfr-4.0.2/mpfr-4.0.2.tar.gz). + + ``` + tar -xvf mpfr-4.0.2.tar.gz && mkdir build_mpfr && cd build_mpfr && ../mpfr-4.0.2/configure --prefix=/usr/local/mpfr-4.0.2 --with-gmp=/usr/local/gmp-6.1.2 --disable-shared && make && make install + ``` + +11. Download, decompress, and install [mpc-1.1.0](https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz). + + ``` + tar -xvf mpc-1.1.0.tar.gz && mkdir build_mpc && cd build_mpc && ../mpc-1.1.0/configure --prefix=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 --disable-shared && make && make install + ``` + +12. Open the **riscv-gnu-toolchain** folder and create a directory for toolchain output. + + ``` + cd /opt && mkdir gcc_riscv32 + ``` + +13. Compile **binutils**. + + ``` + mkdir build_binutils && cd build_binutils && ../riscv-binutils-gdb/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32/riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. + ``` + +14. Build **Newlib**. + + ``` + mkdir build_newlib && cd build_newlib && ../riscv-newlib/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" \CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. + ``` + +15. Build **GCC**. + + ``` + mkdir build_gcc && cd build_gcc && ../riscv-gcc/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" LDFLAGS="-Wl,-z,relro,-z,now,-z,noexecstack" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --with-headers="/opt/gcc-riscv32/riscv32-unknown-elf/include" --with-mpc=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 && make -j16 && make install + ``` + +16. Set an environment variable. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >If you use the compiled **riscv32 gcc** package, perform the following steps to set environment variables: + >1. Decompress the package to the root directory. + > ``` + > tar -xvf gcc_riscv32-linux-7.3.0.tar.gz -C ~ + > ``` + >2. Set an environment variable. + > ``` + > vim ~/.bashrc + > ``` + >3. Copy the following command to the last line of the **.bashrc** file, save the file, and exit. + > ``` + > export PATH=~/gcc_riscv32/bin:$PATH + > ``` + + ``` + vim ~/.bashrc + ``` + + Copy the following command to the last line of the **.bashrc** file, save the file, and exit. + + ``` + export PATH=~/gcc_riscv32/bin:$PATH + ``` + +17. Validate the environment variable. + + ``` + source ~/.bashrc + ``` + +18. Check whether the compiler is successfully installed. If the compiler version number is correctly displayed, the installation is successful. + + ``` + riscv32-unknown-elf-gcc -v + ``` + + +## Installing the USB-to-Serial Driver + +Perform the following operations on the Windows station. + +1. Download the USB-to-serial driver: [CH341SER USB-to-serial driver](http://www.hihope.org/en/download/download.aspx). +2. Install the driver. +3. After the driver is installed, remove and then insert the USB cable. The serial port entry should be displayed as shown in the following figure. + + ![](figure/en-us_image_0000001174350633.png) + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps-board3861.md b/en/device-dev/quick-start/quickstart-lite-steps-board3861.md new file mode 100644 index 0000000000000000000000000000000000000000..a0b8821b092c2b1e524a1f027c82eede39f8627b --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps-board3861.md @@ -0,0 +1,11 @@ +# Hi3861 + +- **[Setting Up the Environment](quickstart-lite-steps-board3861-setting.md)** + +- **[WLAN Connection](quickstart-lite-steps-board3861-connection.md)** + +- **[Running a Hello World Program](quickstart-lite-steps-board3861-running.md)** + +- **[FAQs](quickstart-lite-steps-board3861-faqs.md)** + + diff --git a/en/device-dev/quick-start/quickstart-lite-steps.md b/en/device-dev/quick-start/quickstart-lite-steps.md new file mode 100644 index 0000000000000000000000000000000000000000..cd4b82e4fd43c3494e6c0f16a5773b13b4c262e0 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite-steps.md @@ -0,0 +1,9 @@ +# How to Develop + +- **[Hi3861](quickstart-lite-steps-board3861.md)** + +- **[Hi3516](quickstart-lite-steps-board3516.md)** + +- **[Hi3518](quickstart-lite-steps-board3518.md)** + + diff --git a/en/device-dev/quick-start/quickstart-lite.md b/en/device-dev/quick-start/quickstart-lite.md new file mode 100644 index 0000000000000000000000000000000000000000..064e2ef51e72d289ab48512e29e01909530a6472 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-lite.md @@ -0,0 +1,11 @@ +# Mini and Small Systems + +- **[Overview](quickstart-lite-overview.md)** + +- **[Introduction to the Development Boards](quickstart-lite-introduction.md)** + +- **[Environment Setup](quickstart-lite-env-setup.md)** + +- **[How to Develop](quickstart-lite-steps.md)** + + diff --git a/en/device-dev/quick-start/quickstart-standard-burn.md b/en/device-dev/quick-start/quickstart-standard-burn.md new file mode 100644 index 0000000000000000000000000000000000000000..5cfe9fccf987772fa26e2d64144c0416f7897dcc --- /dev/null +++ b/en/device-dev/quick-start/quickstart-standard-burn.md @@ -0,0 +1,205 @@ +# Burning Images + +- [Next](#section5600113114323) + +Programming flash memory of a regular system requires DevEco Device Tool v2.2 Beta1 or later. + +The Hi3516DV300 of the Hi3516 series development boards supports programming flash memory of a regular system through the USB port, network port, or serial port, where: + +- **Windows system: Supports programming through the USB port, serial port, or network port** +- **Linux system: Supports programming through the serial port or network port \(Linux+Windows dual system: Also supports programming through the USB port\)** + +Except for environment setup, the operations of programming are the same for Windows and Linux. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Currently, the Hi3516D V300 development board supports system burning over the network port, USB port, or serial port. This document uses the network port as an example. For details about system burning over other ports, see [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681). + +### Prerequisites + +[Open a project](https://device.harmonyos.com/en/docs/ide/user-guides/open_project-0000001071680043) in DevEco Device Tool and select the folder where the file to be programmed is located. Select **Hi3516DV300** for the development board type and **Hb** for **Framework**. + +### Programming Flash Memory Through the Network Port + +The Hi3516DV300 supports programming through the network port in Windows or Linux. + +1. Connect the PC and the target development board through the power port, serial port, and network port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_camera_start_3516-0000001052670587). +2. Open Device Manager, then check and record the serial port number corresponding to the development board. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). + + ![](figure/en-us_image_0000001114129428.png) + +3. Open DevEco Device Tool and go to **Projects** \> **Settings**. + + ![](figure/2021-01-27_170334-17.png) + +4. On the **Partition Configuration** tab page, enter the information about the files to be programmed, including the following. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Binary

+

Memory

+

System

+

Address

+

Length

+

Board

+

Type

+

fastboot

+

Select u-boot-hi3516dv300_emmc.bin.

+

emmc

+

none

+

0x000000

+

0x100000

+

Select hi3516dv300.

+

NA

+

boot

+

Select uImage.

+

emmc

+

none

+

0x100000

+

0xf00000

+

NA

+

updater

+

Select updater.img.

+

emmc

+

ext3/4

+

0x1000000

+

0x1400000

+

NA

+

misc

+

Leave it blank.

+

emmc

+

none

+

0x2400000

+

0x100000

+

NA

+

system

+

Select system.img.

+

emmc

+

ext3/4

+

0x2500000

+

0xceb00000

+

NA

+

vendor

+

Select vendor.img.

+

emmc

+

ext3/4

+

0xd1000000

+

0x10000000

+

NA

+

userdata

+

Select userdata.img.

+

emmc

+

ext3/4

+

0xe1000000

+

0x5b800000

+

NA

+
+ + ![](figure/en-us_image_0000001160527611.png) + +5. On the **hi3516dv300** tab page, configure the programming options. + + - **upload\_port**: Select the serial port number obtained in step [2](#en-us_topic_0000001056443961_li1050616379507). + - **upload\_protocol**: Select the programming protocol **hiburn-net**. + - **upload\_partitions**: Select the file to be programmed, including the following: fastboot, boot, updater, misc, system, vendor, and userdata. + + ![](figure/en-us_image_0000001117621400.png) + +6. Check and set the IP address of the network adapter connected to the development board. For details, see [Setting the IP Address of the Network Port for Programming on Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/set_ipaddress-0000001141825075). +7. Set the IP address of the network port for programming: + + - **upload\_net\_server\_ip**: Select the IP address set in [6](en-us_topic_0000001056443961.md#li1558813168234), such as 192.168.1.2. + - **upload\_net\_client\_mask**: Set the subnet mask of the development board, such as 255.255.255.0. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. + - **upload\_net\_client\_gw**: Set the gateway of the development board, such as 192.168.1.1. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. + - **upload\_net\_client\_ip**: Set the IP address of the development board, such as 192.168.1.3. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. + + ![](figure/en-us_image_0000001117463460.png) + +8. When you finish modifying, click **Save** in the upper right corner. +9. Open the project file, go to ![](figure/2021-01-27_170334-18.png) \> **PROJECT TASKS** \> **fastboot** \> **Erase** to erase U-boot. + + ![](figure/en-us_image_0000001163045527.png) + +10. When the following message is displayed, power off the development board and then power it on. + + ![](figure/en-us_image_0000001114129432.png) + +11. Start programming. When the following message is displayed, it indicates that the programming is successful. + + ![](figure/en-us_image_0000001113969542.png) + + +## Next + +Congratulations! You have completed the quick start for the standard system. Get yourself familiar with OpenHarmony by a [Development Example for Clock App](../guide/oem_device_clockapp_des.md). + diff --git a/en/device-dev/quick-start/quickstart-standard-description.md b/en/device-dev/quick-start/quickstart-standard-description.md new file mode 100644 index 0000000000000000000000000000000000000000..75e796ec2168131936342f92c6247a2478a8ba24 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-standard-description.md @@ -0,0 +1,54 @@ +# Introduction + +- [Quick Start Process](#section7825218111517) +- [Introduction to the Development Board](#en-us_topic_0000001053666242_section047719215429) +- [Development Board Specifications](#en-us_topic_0000001053666242_section15192203316533) + +This document helps you quickly understand how to set up a standard OpenHarmony system, and how to build, burn, and start the system. You can develop the standard system in Windows and build source code in Linux. + +This document uses the recommended Hi3516D V300 development board as an example. + +## Quick Start Process + +The following figure shows the process of getting started for the standard system, during which, you can set up the Ubuntu development environment in Docker mode or by using the installation package. + +**Figure 1** Getting started for the standard system +![](figure/getting-started-for-the-standard-system.png "getting-started-for-the-standard-system") + +## Introduction to the Development Board + +Hi3516D V300 is a next-generation system on chip \(SoC\) designed for the industry-dedicated smart HD IP camera. It introduces a next-generation image signal processor \(ISP\), the H.265 video compression encoder, and a high-performance NNIE engine, leading the industry in terms of low bit rate, high image quality, intelligent processing and analysis, and low power consumption. + +**Figure 2** Hi3516D V300 front view + + +![](figure/3516正面.png) + +## Development Board Specifications + +**Table 1** Specifications of the Hi3516 development board + + + + + + + + + + + + + +

Item

+

Description

+

Processor and internal memory

+
  • Hi3516D V300
  • 1 GB DDR3
  • 8 GB eMMC4.5
+

External components

+
  • Ethernet port
  • Audio and video
    • One voice input
    • One mono (AC_L) output, connected to a 3 W power amplifier (LM4871)
    • Micro-HDMI (one HDMI 1.4)
    +
  • Cameras
    • Sensor IMX335
    • M12 lens with a focal length of 4 mm and an aperture of 1.8
    +
  • Display
    • 2.35-inch LCD connector
    • 5.5-inch LCD connector
    +
  • External components and interfaces
    • microSD card interface
    • JTAG/I2S interface
    • ADC interface
    • Steer gear interface
    • Grove connector
    • USB 2.0 (Type C)
    • Three function keys: two custom keys and one update key
    • LED indicator (including green and red)
    +
+
+ diff --git a/en/device-dev/quick-start/quickstart-standard-docker-environment.md b/en/device-dev/quick-start/quickstart-standard-docker-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..c9f27fb455f3de13052fbdf2e7454ff88d280fc7 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-standard-docker-environment.md @@ -0,0 +1,118 @@ +# Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code + +- [Obtaining Standard-System Source Code](#section8761819202511) + - [Prerequisites](#section102871547153314) + - [Procedure](#section429012478331) + +- [Obtaining the Docker Environment](#section181431248132513) +- [Building Source Code](#section92391739152318) + +The standard OpenHarmony system provides a Docker environment which encapsulates build tools. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- Before using Docker, install it by following instructions in [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/). +>- You can also use the [installation package](quickstart-standard-package-environment.md) to set up the Ubuntu development environment. + +## Obtaining Standard-System Source Code + +### Prerequisites + +1. Register your account with Gitee. +2. Register an SSH public key for access to Gitee. +3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)), and configure basic user information. + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. Run the following commands to install the **repo** tool: + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### Procedure + +Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +Method 2: Use the **repo** tool to download the source code over HTTPS. + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## Obtaining the Docker Environment + +**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** + +1. Obtain the Docker image. + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**Method 2: Using the Dockerfile to build a local docker image** + +1. Obtain the Dockerfile script for a local Docker image. + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +## Building Source Code + +1. Run the preprocessing script in the root directory of the source code. + + ``` + ../scripts/prepare.sh + ``` + +2. Run the following script to start building for Standard-System Devices \(reference memory ≥ 128 MB\): + + ``` + ./build.sh --product-name {product_name} + ``` + + **product\_name** indicates the product supported by the current distribution, for example, **Hi3516DV300**. + + Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + +3. Burn the image. For details, see [Burning Images](quickstart-standard-burn.md). + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>You can exit Docker by simply running the **exit** command. + diff --git a/en/device-dev/quick-start/faqs-7.md b/en/device-dev/quick-start/quickstart-standard-faq.md similarity index 100% rename from en/device-dev/quick-start/faqs-7.md rename to en/device-dev/quick-start/quickstart-standard-faq.md diff --git a/en/device-dev/quick-start/quickstart-standard-package-environment.md b/en/device-dev/quick-start/quickstart-standard-package-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..ee9049108fbefa96530e67bdc8ecb2211296cd21 --- /dev/null +++ b/en/device-dev/quick-start/quickstart-standard-package-environment.md @@ -0,0 +1,98 @@ +# Setting Up Ubuntu Development Environment with Installation Package and Building Source Code + +- [Installing Dependent Tools](#section18431165519244) +- [Obtaining Standard-System Source Code](#section113751052102517) + - [Prerequisites](#section102871547153314) + - [Procedure](#section429012478331) + +- [Running prebuilts](#section0495320152619) +- [Building Source Code](#section1664835963517) + +## Installing Dependent Tools + +The installation command is as follows: + +``` +sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The preceding command is applicable to Ubuntu 18.04. For other Ubuntu versions, modify the preceding installation command based on the installation package name. + +## Obtaining Standard-System Source Code + +### Prerequisites + +1. Register your account with Gitee. +2. Register an SSH public key for access to Gitee. +3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)), and configure basic user information. + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. Run the following commands to install the **repo** tool: + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### Procedure + +Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +Method 2: Use the **repo** tool to download the source code over HTTPS. + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## Running prebuilts + +Go to the root directory of the source code and run the following script to install the compiler and binary tool: + +``` +bash build/prebuilts_download.sh +``` + +By default, the downloaded prebuilts binary file is stored in **OpenHarmony\_2.0\_canary\_prebuilts** \(which is in the same directory as **OpenHarmony**\). + +## Building Source Code + +Perform the following operations in the Linux environment: + +1. Go to the root directory of the source code and run the following command to build the distribution. + + ``` + ./build.sh --product-name {product_name} + ``` + + **product\_name** indicates the product supported by the current distribution, for example, **Hi3516DV300**. + +2. Check the build result. After the build is complete, the following information is displayed in the log: + + ``` + build system image successful. + =====build Hi3516DV300 successful. + ``` + + Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >For details about module-specific build operations, see [Building Guidelines](../subsystems/subsys-build-standard-large.md). + +3. Burn the image. For details, see [Burning Images](quickstart-standard-burn.md). + diff --git a/en/device-dev/quick-start/quickstart-standard-windows-environment.md b/en/device-dev/quick-start/quickstart-standard-windows-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..c07334b53835411881e5373437a96974b43e175c --- /dev/null +++ b/en/device-dev/quick-start/quickstart-standard-windows-environment.md @@ -0,0 +1,183 @@ +# Setting Up Windows Development Environment + +- [Obtaining the Software](#en-us_topic_0000001058091994_section1483143015558) +- [Installing Visual Studio Code](#en-us_topic_0000001058091994_section71401018163318) +- [Installing Python](#en-us_topic_0000001058091994_section16266553175320) +- [Installing Node.js](#en-us_topic_0000001058091994_section5353233124511) +- [Installing hpm](#en-us_topic_0000001058091994_section173054793610) +- [Installing the DevEco Device Tool Plug-in](#en-us_topic_0000001058091994_section4336315185716) + +Operating system: 64-bit version of Windows 10. + +DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedure includes five parts: + +1. Installing Visual Studio Code +2. Installing Python +3. Installing Node.js +4. Installing hpm +5. Installing the DevEco Device Tool Plug-in + +## Obtaining the Software + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Tool

+

Description

+

Version

+

Obtaining Channel

+

Visual Studio Code

+

Code editing tool

+

V1.53 or later (64-bit)

+

https://code.visualstudio.com/Download

+

Python

+

Programming tool

+

v3.7.4–3.8.x (64-bit)

+

https://www.python.org/downloads/

+

Node.js

+

The npm environment provider

+

v12.0.0 or later (64-bit)

+

https://nodejs.org/en/download/

+

hpm

+

Package manager

+

Latest version

+

Run the following command:

+
npm install -g @ohos/hpm-cli
+

DevEco Device Tool

+

Plug-in for the OpenHarmony source code compilation, programming, and debugging

+

v2.2 Beta1

+

https://device.harmonyos.com/en/ide#download

+

Log in with your HUAWEI ID to download it. You can register an account here.

+
+ +## Installing Visual Studio Code + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>If you have installed Visual Studio Code, open the CLT and run **code --version** to check whether the version is 1.53 or later. If the version number is returned, it indicates that the environment variables are set correctly. + +1. Double-click the Visual Studio Code package to install it. During the installation, select **Add to PATH \(requires shell restart\)**. + + ![](figure/en-us_image_0000001057335403.png) + +2. After the installation is complete, restart the computer for the environment variables of Visual Studio Code to take effect. +3. Open the CLT and run **code --version**. If the version number can be displayed, it indicates that the installation is successful. + +## Installing Python + +1. Double-click the Python software package, select **Add Python xx to PATH**, and click **Install Now**. + + ![](figure/en-us_image_0000001096154076.png) + +2. After the installation is complete, click **Close**. + + ![](figure/en-us_image_0000001142794291.png) + +3. Open the CLT, and run **python --version** to check the installation result. + + ![](figure/en-us_image_0000001143154485.png) + +4. In the CLT, run the following commands to set the pip source for downloading the dependencies required for later installation: + + ``` + pip config set global.trusted-host repo.huaweicloud.com + pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple + pip config set global.timeout 120 + ``` + + +## Installing Node.js + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>If you have installed Node.js, open the CLT and run **node -v** to check whether the version is 12.0.0 or later. + +1. Run the downloaded software package to install. Use the default settings when following the installation wizard, and click **Next** until **Finish** is displayed. During the installation, Node.js will automatically set the system Path environment variable to the installation directory of **node.exe**. +2. Open the CLT and run **node -v**. If the version number of Node.js is displayed, it indicates that Node.js has been successfully installed. + + ![](figure/en-us_image_0000001056814287.png) + + +## Installing hpm + +Before installing hpm, ensure that Node.js has been installed + +and that your network can access the Internet. If your network requires a proxy to access the Internet, [set up the npm proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032) first. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>If hpm has been installed, run **npm update -g @ohos/hpm-cli** to update it to the latest version. + +1. You are advised to set the npm source to an image in China, for example, a HUAWEI CLOUD image source. + + ``` + npm config set registry https://repo.huaweicloud.com/repository/npm/ + ``` + +2. Open the CLT and run the following command to install the latest version of hpm: + + ``` + npm install -g @ohos/hpm-cli + ``` + + ![](figure/en-us_image_0000001073840162.png) + +3. After the installation is complete, run the following command to obtain the installation result: + + ``` + hpm -V + ``` + + ![](figure/en-us_image_0000001100641602.png) + + +## Installing the DevEco Device Tool Plug-in + +To install the DevEco Device Tool plug-in, ensure that the **user name of the host cannot contain Chinese characters**; otherwise, the plug-in may fail to run. + +DevEco Device Tool will automatically download and install the C/C++ and CodeLLDB plug-ins from the Visual Studio Code Marketplace during the installation process. Therefore, make sure Visual Studio Code can access the Internet. If your network requires a proxy to access the Internet, [set up the Visual Studio Code proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144) first. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Before installing DevEco Device Tool, ensure that Visual Studio Code is closed. + +1. Decompress the DevEco Device Tool plug-in package and double-click the installer to install. +2. During the installation, the dependency files \(such as C/C++ and CodeLLDB plug-ins\) and execution programs required by DevEco Device Tool are automatically installed. + + ![](figure/en-us_image_0000001072468991.png) + +3. After the installation is complete, the CLT is automatically closed. +4. Open Visual Studio Code, click the ![](figure/en-us_image_0000001072757874.png) button on the left, and check whether C/C++, CodeLLDB, and DevEco Device Tool are listed in **INSTALLED**. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >If the C/C++ and CodeLLDB plug-ins fail to be installed, DevEco Device Tool cannot run properly. To solve the issue, see [Installing the C/C++ and CodeLLDB Plug-ins Offline](https://device.harmonyos.com/en/docs/ide/user-guides/offline_plugin_install-0000001074376846). + + ![](figure/en-us_image_0000001142802505.png) + + diff --git a/en/device-dev/quick-start/quickstart-standard.md b/en/device-dev/quick-start/quickstart-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..ece9c36cc5918da7b8613e5d0ec9f68a6071b8ce --- /dev/null +++ b/en/device-dev/quick-start/quickstart-standard.md @@ -0,0 +1,15 @@ +# Standard System + +- **[Introduction](quickstart-standard-description.md)** + +- **[Setting Up Windows Development Environment](quickstart-standard-windows-environment.md)** + +- **[Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code](quickstart-standard-docker-environment.md)** + +- **[Setting Up Ubuntu Development Environment with Installation Package and Building Source Code](quickstart-standard-package-environment.md)** + +- **[Burning Images](quickstart-standard-burn.md)** + +- **[FAQs](quickstart-standard-faq.md)** + + diff --git a/en/device-dev/quick-start/quickstart.md b/en/device-dev/quick-start/quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..3f82098be9f28557fc6a223f770197f21ee07c31 --- /dev/null +++ b/en/device-dev/quick-start/quickstart.md @@ -0,0 +1,7 @@ +# Getting Started + +- **[Mini and Small Systems](quickstart-lite.md)** + +- **[Standard System](quickstart-standard.md)** + + diff --git a/en/device-dev/quick-start/running-a-hello-ohos-program-5.md b/en/device-dev/quick-start/running-a-hello-ohos-program-5.md deleted file mode 100644 index e3f5d5e2955b1b44c9999d567a171ca426f5104b..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/running-a-hello-ohos-program-5.md +++ /dev/null @@ -1,262 +0,0 @@ -# Running a Hello OHOS Program - -- [Creating a Program](#section1550972416485) -- [Building](#section234175193114) -- [Burning](#section7609155824819) -- [Running an Image](#section17612105814480) -- [Follow-up Learning](#section9712145420182) - -This section describes how to create, compile, burn, and run the first program, and finally print **Hello OHOS!** on the develop board. - -## Creating a Program - -1. Create a directory and the program source code. - - Create the **applications/sample/camera/apps/src/helloworld.c** directory and file whose code is shown in the following example. You can customize the content to be printed. For example, you can change **OHOS** to **World**. You can use either C or C++ to develop a program. - - ``` - #include - - int main(int argc, char **argv) - { - printf("\n************************************************\n"); - printf("\n\t\tHello OHOS!\n"); - printf("\n************************************************\n\n"); - - return 0; - } - ``` - -2. Create a build file. - - Create the **applications/sample/camera/apps/BUILD.gn** file. The file content is as follows: - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("hello-OHOS") { - features = [ ":helloworld" ] - } - executable("helloworld") { - output_name = "helloworld" - sources = [ "src/helloworld.c" ] - include_dirs = [] - defines = [] - cflags_c = [] - ldflags = [] - } - ``` - -3. Add a component. - - Add the configuration of the **hello\_world\_app** component to the **build/lite/components/applications.json** file. The sample code below shows some configurations defined in the **applications.json** file, and the code between **"\#\#start\#\#"** and **"\#\#end\#\#"** is the new configuration \(Delete the rows where **"\#\#start\#\#"** and **"\#\#end\#\#"** are located after the configurations are added.\) - - ``` - { - "components": [ - { - "component": "camera_sample_communication", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/communication" - ], - "targets": [ - "//applications/sample/camera/communication:sample" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##start## - { - "component": "hello_world_app", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/apps" - ], - "targets": [ - "//applications/sample/camera/apps:hello-OHOS" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##end## - { - "component": "camera_sample_app", - "description": "Camera related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/launcher", - "applications/sample/camera/cameraApp", - "applications/sample/camera/setting", - "applications/sample/camera/gallery", - "applications/sample/camera/media" - ], - ``` - -4. Modify the board configuration file. - - Add the **hello\_world\_app** component to the **vendor/hisilicon/hispark\_aries/config.json** file. The sample code below shows the configurations of the **applications** subsystem, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) - - ``` - { - "subsystem": "applications", - "components": [ - ##start## - { "component": "hello_world_app", "features":[] }, - ##end## - { "component": "camera_sample_app", "features":[] } - - ] - }, - ``` - - -## Building - -If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: - -``` -hb set (Set the building path.) -. (Select the current path.) -Select ipcamera_hispark_aries@hisilicon and press Enter. -hb build -f (Start building.) -``` - -The result files are generated in the **out/hispark\_aries/ipcamera\_hispark\_aries** directory. - -**Figure 1** Settings -![](figures/settings-4.png "settings-4") - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->The U-Boot file of the Hi3518E V300 development board can be obtained from the following path: device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin - -## Burning - -The USB port is the only burning mode supported by the Hi3518 development board. - -1. Connect the PC and the target development board through the serial port and USB port. In this section, the Hi3518EV300 is used as an example. For details, see [Introduction to the Hi3518 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des_3518-0000001105201138). -2. Open Device Manager, then check and record the serial port number corresponding to the development board. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). - - ![](figures/en-us_image_0000001128470900.png) - -3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - - ![](figures/en-us_image_0000001174350649.png) - -4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. -5. On the **hi3518ev300** tab page, set the programming options. - - - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001057313128_li46411811196). - - **upload\_protocol**: Select the programming protocol **hiburn-usb**. - - **upload\_partitions**: Select the file to be programmed. By default, the **fastboot**, **kernel**, **rootfs**, and **userfs** files are programmed at the same time. - - ![](figures/en-us_image_0000001128311090.png) - -6. When you finish modifying, click **Save** in the upper right corner. -7. Open the project file and click ![](figures/2021-01-27_170334-5.png). In the DevEco Device Tool window, choose **PROJECT TASKS** \> **hi3518ev300\_fastboot** \> **Erase** to erase U-Boot. - - ![](figures/en-us_image_0000001174270731.png) - -8. When the following message is displayed, power off the development board and then power it on. - - ![](figures/en-us_image_0000001128311092.png) - -9. If the following message is displayed, it indicates that U-Boot is erased successfully. - - ![](figures/en-us_image_0000001128311094.png) - -10. Go to **hi3518ev300** \> **Upload** to start programming. - - ![](figures/en-us_image_0000001174350641.png) - -11. If the following message is displayed, it indicates that the programming is successful. - - ![](figures/en-us_image_0000001174350643.png) - - -## Running an Image - -1. Connect to a serial port. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >If the connection fails, rectify the fault by referring to [FAQs](../quick-start/faqs-6.md). - - **Figure 2** Serial port connection - - - ![](figures/chuankou1-6.png) - - 1. Click **Monitor** to enable the serial port. The **TERMINAL** window is displayed. - 2. Press **Enter** repeatedly until **hisilicon** displays. - 3. Go to [step 2](#li9441185382314) if the board is started for the first time or the startup parameters need to be modified; go to [step 3](#li6442853122312) otherwise. - -2. \(Mandatory for first-time burning\) Modify the **bootcmd** and **bootargs** parameters of U-Boot. This step is a fixed operation and the result can be saved. However, you need to perform the following steps again if U-Boot needs to be reburnt. - - **Table 1** Parameters of the U-Boot - - - - - - - - - - - - - - - - - - - - - - -

Command

-

Description

-

setenv bootcmd "sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000";

-

Run this command to set the content of bootcmd. Select the flash whose number is 0, and read content that has a size of 0x600000 (6 MB) and a start address of 0x100000 to memory address 0x40000000. The size must be the same as that of the OHOS_Image.bin file in the IDE.

-

setenv bootargs "console=ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7M rootsize=8M";

-

In this command, bootargs is set to the serial port output, the baud rate is 115200, the data bit is 8, and the rootfs is mounted to the flash memory. The file system type is set to jffs2 rw, which provides the read-write attribute for the JFFS2 file system. rootaddr=7M rootsize=8M indicates the actual start address and length of the rootfs.img file to be burnt, respectively. The file size must be the same as that of the rootfs.img file in the IDE.

-

saveenv

-

saveenv means to save the current configuration.

-

reset

-

reset means to reset the board.

-

pri

-

pri means to view the displayed parameters.

-
- - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >**go 0x40000000** \(optional\) 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, press **Enter** in the countdown phase of the U-Boot startup to interrupt the automatic startup. - -3. If **hisilicon \#** is displayed during the startup, run the **reset** command. After the system automatically starts and **OHOS** is displayed, run the **./bin/helloworld** command and then press **Enter**. The system is started successfully if information shown in the following figure is displayed. - - **Figure 3** Successful system startup and program execution - ![](figures/successful-system-startup-and-program-execution-7.png "successful-system-startup-and-program-execution-7") - - -## Follow-up Learning - -Congratulations! You have finished all steps! You are advised to go on learning how to develop [Cameras with a Screen](../guide/cameras-with-a-screen.md). - diff --git a/en/device-dev/quick-start/running-a-hello-ohos-program.md b/en/device-dev/quick-start/running-a-hello-ohos-program.md deleted file mode 100644 index 1bc2f5daad267626fea4ccda977975597197e26e..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/running-a-hello-ohos-program.md +++ /dev/null @@ -1,269 +0,0 @@ -# Running a Hello OHOS Program - -- [Creating a Program](#section204672145202) -- [Building](#section1077671315253) -- [Burning](#section1347011412201) -- [Running an Image](#section24721014162010) -- [Running a Program](#section5276734182615) - -This section describes how to create, compile, burn, and run the first program, and finally print **Hello OHOS!** on the develop board. - -## Creating a Program - -1. Create a directory and the program source code. - - Create the **applications/sample/camera/apps/src/helloworld.c** directory and file whose code is shown in the following example. You can customize the content to be printed. For example, you can change **OHOS** to **World**. You can use either C or C++ to develop a program. - - ``` - #include - - int main(int argc, char **argv) - { - printf("\n************************************************\n"); - printf("\n\t\tHello OHOS!\n"); - printf("\n************************************************\n\n"); - - return 0; - } - ``` - -2. Create a build file. - - Create the **applications/sample/camera/apps/BUILD.gn** file. The file content is as follows: - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("hello-OHOS") { - features = [ ":helloworld" ] - } - executable("helloworld") { - output_name = "helloworld" - sources = [ "src/helloworld.c" ] - include_dirs = [] - defines = [] - cflags_c = [] - ldflags = [] - } - ``` - -3. Add a new component. - - Add the configuration of the **hello\_world\_app** component to the **build/lite/components/applications.json** file. The sample code below shows some configurations defined in the **applications.json** file, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) - - ``` - { - "components": [ - { - "component": "camera_sample_communication", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/communication" - ], - "targets": [ - "//applications/sample/camera/communication:sample" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##start## - { - "component": "hello_world_app", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/apps" - ], - "targets": [ - "//applications/sample/camera/apps:hello-OHOS" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##end## - { - "component": "camera_sample_app", - "description": "Camera related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/launcher", - "applications/sample/camera/cameraApp", - "applications/sample/camera/setting", - "applications/sample/camera/gallery", - "applications/sample/camera/media" - ], - ``` - -4. Modify the board configuration file. - - Add the **hello\_world\_app** component to the **vendor/hisilicon/hispark\_taurus/config.json** file. The sample code below shows the configurations of the **applications** subsystem, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) - - ``` - { - "subsystem": "applications", - "components": [ - { "component": "camera_sample_app", "features":[] }, - { "component": "camera_sample_ai", "features":[] }, - ##start## - { "component": "hello_world_app", "features":[] }, - ##end## - { "component": "camera_screensaver_app", "features":[] } - ] - }, - ``` - - -## Building - -If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: - -``` -hb set (Set the building path.) -. (Select the current path.) -Select ipcamera_hispark_taurus@hisilicon and press Enter. -hb build -f (Start building.) -``` - -**Figure 1** Settings -![](figures/settings.png "settings") - -The result files are generated in the **out/hispark\_taurus/ipcamera\_hispark\_taurus** directory. - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->The U-Boot file of the Hi3516D V300 development board can be obtained from the following path: device/hisilicon/hispark\_taurus/sdk\_liteos/uboot/out/boot/u-boot-hi3516dv300.bin - -## Burning - -The Hi3516 development board allows you to burn flash memory over the USB port, serial port, or network port. The following uses the network port burning as an example. - -1. Connect the PC and the target development board through the power port, serial port, and network port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des_3516-0000001152041033). -2. Open Device Manager, then check and record the serial port number corresponding to the development board. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). - - ![](figures/en-us_image_0000001174350647.png) - -3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - - ![](figures/2021-01-27_170334.png) - -4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. -5. On the **hi3516dv300** tab page, set the programming options. - - - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001056443961_li142386399535). - - **upload\_protocol**: Select the programming protocol **hiburn-net**. - - **upload\_partitions**: Select the file to be programmed. By default, the **fastboot**, **kernel**, **rootfs**, and **userfs** files are programmed at the same time. - - ![](figures/en-us_image_0000001128470904.png) - -6. Check and set the IP address of the network adapter connected to the development board. For details, see [Setting the IP Address of the Network Port for Programming on Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/set_ipaddress-0000001141825075). -7. Set the IP address of the network port for programming: - - - **upload\_net\_server\_ip**: Select the IP address set in [6](#en-us_topic_0000001056443961_li1558813168234). Example: 192.168.1.2. - - **upload\_net\_client\_mask**: Set the subnet mask of the development board, such as 255.255.255.0. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 255.255.255.0. - - **upload\_net\_client\_gw**: Set the gateway of the development board, such as 192.168.1.1. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 192.168.1.1. - - **upload\_net\_client\_ip**: Set the IP address of the development board, such as 192.168.1.3. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 192.168.1.3. - - ![](figures/en-us_image_0000001174270733.png) - -8. When you finish modifying, click **Save** in the upper right corner. -9. Open the project file and click ![](figures/2021-01-27_170334-2.png). In the DevEco Device Tool window, choose **PROJECT TASKS** \> **hi3516dv300** \> **Upload** to start programming. - - ![](figures/en-us_image_0000001174270729.png) - -10. When the following message is displayed, power off the development board and then power it on. - - ![](figures/en-us_image_0000001128470906.png) - -11. Start burning. When the following message is displayed, the burning is successful. - - ![](figures/en-us_image_0000001128311098.png) - - -## Running an Image - -1. Connect to a serial port. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >If the connection fails, rectify the fault by referring to [FAQs](../quick-start/faqs-3.md). - - **Figure 2** Serial port connection - - - ![](figures/chuankou1.png) - - 1. Click **Monitor** to enable the serial port. - 2. Press **Enter** repeatedly until **hisilicon** displays. - 3. Go to step [2](#l5b42e79a33ea4d35982b78a22913b0b1) if the board is started for the first time or the startup parameters need to be modified; go to step [3](#ld26f18828aa44c36bfa36be150e60e49) otherwise. - -2. \(Mandatory when the board is started for the first time\) Modify the bootcmd and bootargs parameters of U-Boot. You need to perform this step only once if the parameters need not to be modified during the operation. The board automatically starts after it is reset. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The default waiting time in the U-Boot is 2s. You can press **Enter** to interrupt the waiting and run the **reset** command to restart the system after "hisilicon" is displayed. - - **Table 1** Parameters of the U-Boot - - - - - - - - - - - - - - - - - - - -

Command

-

Description

-

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

-

Run this command to read content that has a size of 0x4800 (9 MB) and a start address of 0x800 (1 MB) to the memory address 0x80000000. The file size must be the same as that of the OHOS_Image.bin file in the IDE.

-

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

-

Run this command to set the output mode to serial port output, baud rate to 115200, data bit to 8, rootfs to be mounted to the emmc component, and file system type to vfat.

-

rootaddr=10M rootsize=20M rw indicates the start address and size of the rootfs.img file to be burnt, respectively. The file size must be the same as that of the rootfs.img file in the IDE.

-

saveenv

-

saveenv means to save the current configuration.

-

reset

-

reset means to reset the board.

-
- - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >**go 0x80000000** \(optional\) 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, press **Enter** in the countdown phase of the U-Boot startup to interrupt the automatic startup. - -3. Run the **reset** command and press **Enter** to restart the board. After the board is restarted, **OHOS** is displayed when you press **Enter**. - - **Figure 3** System startup - - - ![](figures/qi1.png) - - -## Running a Program - -In the root directory, run the **./bin/helloworld** command to operate the demo program. The compilation result is shown in the following example. - -**Figure 4** Successful system startup and program execution -![](figures/successful-system-startup-and-program-execution.png "successful-system-startup-and-program-execution") - diff --git a/en/device-dev/quick-start/running-a-hello-world-program.md b/en/device-dev/quick-start/running-a-hello-world-program.md deleted file mode 100644 index 80f8aacc5a4c79efa00cfd03e4de8d07dcb43d82..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/running-a-hello-world-program.md +++ /dev/null @@ -1,156 +0,0 @@ -# Running a Hello World Program - -- [Modifying Source Code](#section79601457101015) -- [Debugging and Verification](#section1621064881419) -- [printf](#section1246911301217) -- [Locating Exceptions Using the asm File](#section199621957141014) -- [Viewing Execution Result](#section18115713118) -- [Follow-up Learning](#section9712145420182) - -This example shows how to compile a simple service and print **Hello World** to help you preliminarily understand how to run OpenHarmony on Hi3861. - -## Modifying Source Code - -The source code needs to be modified when fixing bugs or compiling a new service. The following describes how to modify the source code when compiling a new service, for example, **my\_first\_app**. - -1. Determine the directory structure. - - Before compiling a service, you must create a directory \(or a directory structure\) in **./applications/sample/wifi-iot/app** to store source code files. - - For example, add the **my\_first\_app** service to the **app** directory, where **hello\_world.c** is the service code and **BUILD.gn** is the compilation script. The directory structure is shown as follows: - - ``` - . - └── applications - └── sample - └── wifi-iot - └── app - │── my_first_app - │ │── hello_world.c - │ └── BUILD.gn - └── BUILD.gn - ``` - -2. Compile the service code. - - Create the **hello\_world.c** file in **./applications/sample/wifi-iot/app/my\_first\_app**. Then, create the service entry function **HelloWorld** in **hello\_world.c** and implement service logic. Use the SYS\_RUN\(\) of the OpenHarmony **bootstrap** module to start services. \(**SYS\_RUN** is defined in the **ohos\_init.h** file.\) - - ``` - #include - #include "ohos_init.h" - #include "ohos_types.h" - - void HelloWorld(void) - { - printf("[DEMO] Hello world.\n"); - } - SYS_RUN(HelloWorld); - ``` - -3. Add the **BUILD.gn** file for building services into a static library. - - Create the **BUILD.gn** file in **./applications/sample/wifi-iot/app/my\_first\_app** and fill in three parts \(target, source file, and header file path\) of the **BUILD.gn** file. - - ``` - static_library("myapp") { - sources = [ - "hello_world.c" - ] - include_dirs = [ - "//utils/native/lite/include" - ] - } - ``` - - - Specify the compilation result named libmyapp.a in **static\_library**. You can fill in this part based on your need. - - Specify the .c file on which a file depends and its path in **sources**. The path that contains **//** represents an absolute path \(the code root path\), otherwise it is a relative path. - - Specify the path of .h file on which **sources** depends in **include\_dirs**. - -4. Modify the **BUILD.gn** file and specify the feature modules to be built. - - Configure the **./applications/sample/wifi-iot/app/BUILD.gn** file and add an index to the **features** field to enable the target to be involved in compilation. Specify the path and target of a service module in **features**. The following uses **my\_first\_app** as an example and the **features** is configured as follows: - - ``` - import("//build/lite/config/component/lite_component.gni") - - lite_component("app") { - features = [ - "my_first_app:myapp", - ] - } - ``` - - - **my\_first\_app** is a relative path that points to **./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn**. - - **myapp** represents the **static\_library\("myapp"\)** in **./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn**. - - -## Debugging and Verification - -Currently, there are two debugging and verification methods: using printf to print logs and using asm files to locate **panic** problems. You can select one of them based on your need. - -As the service shown is simple, use the printf method. The following describes the two debugging methods. - -## printf - -Add **printf** function to the code, which helps print data to the serial port. You can add log printing in key service paths or service exception locations, as shown in the following figure. - -``` -void HelloWorld(void) -{ - printf("[DEMO] Hello world.\n"); -} -``` - -## Locating Exceptions Using the asm File - -When the system exits abnormally, the call stack information about the abnormal exit is displayed on the serial port. The following is an example: You can locate the exception by parsing the exception stack information. - -``` -=======KERNEL PANIC======= -**********************Call Stack********************* -Call Stack 0 -- 4860d8 addr:f784c -Call Stack 1 -- 47b2b2 addr:f788c -Call Stack 2 -- 3e562c addr:f789c -Call Stack 3 -- 4101de addr:f78ac -Call Stack 4 -- 3e5f32 addr:f78cc -Call Stack 5 -- 3f78c0 addr:f78ec -Call Stack 6 -- 3f5e24 addr:f78fc -********************Call Stack end******************* -``` - -To parse the call stack information, the **Hi3861\_wifiiot\_app.asm** file is required. This file records the symbol addresses of the functions in the code in the flash memory and the disassembly information. The asm file is built and output together with the version software package and is stored in the **./out/wifiiot/** directory. - -1. \(Optional\) Save the **CallStack** information to a TXT file for editing. -2. Open the asm file, search for the function address in each call stack, and list the corresponding function. Generally, you only need to find the functions matching the first several stacks to locate exceptions. - - ``` - Call Stack 0 -- 4860d8 addr:f784c -- WadRecvCB - Call Stack 1 -- 47b2b2 addr:f788c -- wal_sdp_process_rx_data - Call Stack 2 -- 3e562c addr:f789c - Call Stack 3 -- 4101de addr:f78ac - Call Stack 4 -- 3e5f32 addr:f78cc - Call Stack 5 -- 3f78c0 addr:f78ec - Call Stack 6 -- 3f5e24 addr:f78fc - ``` - -3. Determine that an exception occurs in the **WadRecvCB** function based on the call stack information. - - ![](figures/en-us_image_0000001174270737.png) - -4. Check and modify the code. - -## Viewing Execution Result - -After the sample code is compiled, burnt, run, and debugged, the following information is displayed on the serial port interface: - -``` -ready to OS start -FileSystem mount ok. -wifi init success! -[DEMO] Hello world. -``` - -## Follow-up Learning - -Congratulations! You have finished all steps! You are advised to go on learning how to develop [WLAN-connected products](../guide/wlan-connected-products.md). - diff --git a/en/device-dev/quick-start/setting-up-the-environment-2.md b/en/device-dev/quick-start/setting-up-the-environment-2.md deleted file mode 100644 index 0e8430d75a7fa0bfe54420a0fcb8638108732710..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-the-environment-2.md +++ /dev/null @@ -1,122 +0,0 @@ -# Setting Up the Environment - -- [Environment Requirements](#section179175261196) - - [Hardware](#section5840424125014) - - [Software](#section965634210501) - -- [Installing Linux Build Tools](#section182916865219) - - [Changing Linux Shell to Bash](#section1715027152617) - - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section45512412251) - - [Installing File Packing Tools and JVM](#section16199102083717) - - -## Environment Requirements - -### Hardware - -- Hi3516D V300 IoT camera development board -- USB-to-serial cable and network cable \(The Windows workstation is connected to the Hi3516D V300 development board through the USB-to-serial cable and network cable.\) - -The following figure shows the hardware connections. - -**Figure 1** Hardware connections - - -![](figures/矩形备份-292.png) - -### Software - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->This section describes how to use an installation package to set up the compilation and development environment. If you are going to use Docker to set up the environment, skip this section and [Installing Linux Build Tools](#section182916865219). - -The following table describes the tools required for setting up the general environment for a Linux server of the Hi3516 development board and how to obtain these tools. - -**Table 1** Development tools and obtaining methods - - - - - - - - - - - - - - - - - - - - - - - - -

Development Tool

-

Description

-

How to Obtain

-

bash

-

Processes CLI commands.

-

System configuration

-

Basic software package for compilation and building (required only for Ubuntu 20+)

-

Provides a basic software package for compilation and building.

-

Internet

-

dosfstools, mtools, and mtd-utils

-

Pack files.

-

apt-get install

-

Java virtual machine (JVM)

-

Compiles, debugs, and runs Java programs.

-

apt-get install

-
- -## Installing Linux Build Tools - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install compilation tools like **LLVM** and **hc-gen**. ->- \(Recommended\) If you obtain the source code via the mirror site or code repository, install **hc-gen**. When installing the compilation tool, ensure that its environment variable path is unique. - -### Changing Linux Shell to Bash - -Check whether bash is used as the shell. - -``` -ls -l /bin/sh -``` - -If **/bin/sh -\> bash** is not displayed, do as follows to change shell to bash. - -**Method 1:** Run the following command on the device and then click **No**. - -``` -sudo dpkg-reconfigure dash -``` - -**Method 2:** Run the first command to delete **sh** and then run the second command to create a new soft link. - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) - -Install the software. - -``` -sudo apt-get install build-essential gcc g++ make zlib* libffi-dev -``` - -### Installing File Packing Tools and JVM - -1. Start a Linux server. -2. Install the dosfstools, mtools, mtd-utils, Java Runtime Environment \(JRE\), and Java SDK. - - ``` - sudo apt-get install dosfstools mtools mtd-utils default-jre default-jdk - ``` - - diff --git a/en/device-dev/quick-start/setting-up-the-environment-4.md b/en/device-dev/quick-start/setting-up-the-environment-4.md deleted file mode 100644 index 606871622b0805662544e092fd9c1e64e4f1cb27..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-the-environment-4.md +++ /dev/null @@ -1,114 +0,0 @@ -# Setting Up the Environment - -- [Environment Requirements](#section1724111409282) - - [Hardware](#section487353718276) - - [Software Requirements](#section17315193935817) - -- [Installing Linux Build Tools](#section8831868501) - - [Changing Linux Shell to Bash](#section434110241084) - - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section25911132141020) - - [Installing File Packing Tools](#section390214473129) - - -## Environment Requirements - -### Hardware - -- Hi3518E V300 IoT camera development board -- USB-to-serial cable and network cable \(The Windows workstation is connected to the Hi3518E V300 development board through the USB-to-serial cable and network cable.\) - - The following figure shows the hardware connections. - - -**Figure 1** Hardware connections -![](figures/hardware-connections-3.png "hardware-connections-3") - -### Software Requirements - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->This section describes how to use an installation package to set up the compilation and development environment. If you are going to use Docker to set up the environment, skip this section and [Installing Linux Build Tools](#section8831868501). - -The following table describes the tools required for setting up the general environment for a Linux server of the Hi3518 development board and how to obtain these tools. - -**Table 1** Development tools and obtaining methods - - - - - - - - - - - - - - - - - - - - -

Development Tool

-

Description

-

How to Obtain

-

bash

-

Processes CLI commands.

-

System configuration

-

Basic software package for compilation and building (required only for Ubuntu 20+)

-

Provides a basic software package for compilation and building.

-

Internet

-

dosfstools, mtools, and mtd-utils

-

Pack files.

-

apt-get install

-
- -## Installing Linux Build Tools - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install **hc-gen**. ->- \(Recommended\) If you obtain the source code via the mirror site or code repository, install **hc-gen**. When installing the compilation tool, ensure that its environment variable path is unique. - -### Changing Linux Shell to Bash - -Check whether bash is used as the shell. - -``` -ls -l /bin/sh -``` - -If **/bin/sh -\> bash** is not displayed, do as follows to change shell to bash. - -**Method 1:** Run the following command on the device and then click **No**. - -``` -sudo dpkg-reconfigure dash -``` - -**Method 2:** Run the first command to delete **sh** and then run the second command to create a new soft link. - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) - -Install the software. - -``` -sudo apt-get install build-essential gcc g++ make zlib* libffi-dev -``` - -### Installing File Packing Tools - -1. Start a Linux server. -2. Install dosfstools, mtools, and mtd-utils. - - ``` - sudo apt-get install dosfstools mtools mtd-utils - ``` - - diff --git a/en/device-dev/quick-start/setting-up-the-environment.md b/en/device-dev/quick-start/setting-up-the-environment.md deleted file mode 100644 index 9eb8b040c6320fb44813778e45d0cfe647623a74..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-the-environment.md +++ /dev/null @@ -1,367 +0,0 @@ -# Setting Up the Environment - -- [Environment Requirements](#section466851916410) - - [Hardware](#section19202111020215) - - [Software](#section727451210318) - -- [Installing Linux Build Tools](#section497484245614) - - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section45512412251) - - [Installing Scons](#section7438245172514) - - [Installing Python Modules](#section88701892341) - - [Installing gcc\_riscv32 \(Compilation Toolchain for WLAN Module\)](#section34435451256) - -- [Installing the USB-to-Serial Driver](#section1027732411513) - -## Environment Requirements - -### Hardware - -- Linux compile server -- Windows workstation \(host computer\) -- Hi3861 WLAN module -- USB Type-C cable used to connect the Windows workstation to Hi3861 WLAN module - -The following figure shows the hardware connections. - -**Figure 1** Hardware connections -![](figures/hardware-connections.png "hardware-connections") - -### Software - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->The following part describes how to install tools using installation packages. If you use Docker to set up the build environment, you only need to install the Windows workstation described in [Table 1](#table6299192712513). - -The following table lists the tools required for the Hi3861 development board. - -**Table 1** Required tools - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Platform

-

Development Tool

-

Description

-

How to Obtain

-

Linux server

-

Basic software package for compilation and building (required only for Ubuntu 20+)

-

Provides a basic software package for compilation and building.

-

Internet

-

Linux server

-

SCons 3.0.4+

-

Executes script compilation.

-

Internet

-

Linux server

-

Python modules: setuptools, Kconfiglib, PyCryptodome, six, and ecdsa

-

Executes script compilation.

-

Internet

-

Linux server

-

gcc riscv32

-

Executes script compilation.

-

Internet

-

Windows workstation

-

CH341SER.EXE

-

USB-to-Serial adapter driver

-

http://www.wch-ic.com/search?t=downloads&q=ch340g

-
- -## Installing Linux Build Tools - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install **gcc\_riscv32**. ->- \(Recommended\) If you obtain the source code via the mirror site or code repository, install **gcc\_riscv32**. When installing the compilation tool, ensure that its environment variable path is unique. - -### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) - -Install the software. - -``` -sudo apt-get install build-essential gcc g++ make zlib* libffi-dev -``` - -### Installing Scons - -1. Start a Linux server. -2. Install the SCons installation package. - - ``` - python3 -m pip install scons - ``` - -3. Check whether the installation is successful. - - ``` - scons -v - ``` - - **Figure 2** Successful installation \(SCons version requirement: 3.0.4 or later\) - ![](figures/successful-installation-(scons-version-requirement-3-0-4-or-later).png "successful-installation-(scons-version-requirement-3-0-4-or-later)") - - -### Installing Python Modules - -1. Install setuptools. - - ``` - pip3 install setuptools - ``` - -2. Install the GUI menuconfig tool \(Kconfiglib\). You are advised to install Kconfiglib 13.2.0 or later. - - **Command line:** - - ``` - sudo pip3 install kconfiglib - ``` - - - - **Installation package:** - 1. Download the **.whl** file \(for example, **kconfiglib-13.2.0-py2.py3-none-any.whl**\). - - Download path: [https://pypi.org/project/kconfiglib\#files](https://pypi.org/project/kconfiglib#files) - - - 1. Install the **.whl** file. - - ``` - sudo pip3 install kconfiglib-13.2.0-py2.py3-none-any.whl - ``` - - - -3. Install **PyCryptodome** using either of the following methods: - - Install the Python component packages on which the file signature depends, including PyCryptodome, six, and ecdsa. As the installation of **ecdsa** depends on that of **six**, install **six** first. - - - **Command line:** - - ``` - sudo pip3 install pycryptodome - ``` - - - **Installation package:** - 1. Download the **.whl** file \(for example, **pycryptodome-3.9.9-cp38-cp38-manylinux1\_x86\_64.whl**\). - - Download path: [https://pypi.org/project/pycryptodome/\#files](https://pypi.org/project/pycryptodome/#files) - - - 1. Install the **.whl** file. - - ``` - sudo pip3 install pycryptodome-3.9.9-cp38-cp38-manylinux1_x86_64.whl - ``` - - - -4. Install **six** using either of the following methods: - - **Command line:** - - ``` - sudo pip3 install six --upgrade --ignore-installed six - ``` - - - - **Installation package:** - 1. Download the **.whl** file, for example, **six-1.12.0-py2.py3-none-any.whl**. - - Download path: [https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files) - - - 1. Install the **.whl** file. - - ``` - sudo pip3 install six-1.12.0-py2.py3-none-any.whl - ``` - - - -5. Install **ecdsa** using either of the following methods: - - **Command line:** - - ``` - sudo pip3 install ecdsa - ``` - - - **Installation package:** - 1. Download the **.whl** file, for example, **ecdsa-0.14.1-py2.py3-none-any.whl**. - - Download path: [https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files) - - - 1. Install the **.whl** file. - - ``` - sudo pip3 install ecdsa-0.14.1-py2.py3-none-any.whl - ``` - - - - -### Installing gcc\_riscv32 \(Compilation Toolchain for WLAN Module\) - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- The Hi3861 platform supports only the static link of the libgcc library. The dynamic link is not recommended because version 3 of the GNU General Public License \(GPLv3\) will be polluted during commercial distribution. ->- Steps 2 to 15 of the following procedure are used to build the **gcc\_riscv32** image. You can simply [download the image](https://repo.huaweicloud.com/harmonyos/compiler/gcc_riscv32/7.3.0/linux/gcc_riscv32-linux-7.3.0.tar.gz) and skip these steps. - -1. Start a Linux server. -2. Install the **GCC**, **G++**, **Bison**, **Flex**, **Makeinfo** tools to ensure that the toolchain can be correctly compiled. - - ``` - sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install flex bison && sudo apt-get install texinfo - ``` - -3. Download the RISC-V GNU toolchain. - - ``` - git clone --recursive https://gitee.com/mirrors/riscv-gnu-toolchain.git - ``` - -4. Open the **riscv-gnu-toolchain** folder and delete empty folders to prevent conflicts during the download of **Newlib**, **Binutils**, and **GCC**. - - ``` - cd riscv-gnu-toolchain && rm -rf riscv-newlib && rm -rf riscv-binutils && rm -rf riscv-gcc - ``` - -5. Download RISC-V Newlib 3.0.0. - - ``` - git clone -b riscv-newlib-3.0.0 https://github.com/riscv/riscv-newlib.git - ``` - -6. Download RISC-V Binutils 2.31.1. - - ``` - git clone -b riscv-binutils-2.31.1 https://github.com/riscv/riscv-binutils-gdb.git - ``` - -7. Download RISC-V GCC 7.3.0. - - ``` - git clone -b riscv-gcc-7.3.0 https://github.com/riscv/riscv-gcc - ``` - -8. Add the RISC-V GCC 7.3.0 patch. - - Visit the GCC official patch links [89411](https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=026216a753ef0a757a9e368a59fa667ea422cf09;hp=2a23a1c39fb33df0277abd4486a3da64ae5e62c2) and [86724](https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff;f=gcc/graphite.h;h=be0a22b38942850d88feb159603bb846a8607539;hp=4e0e58c60ab83f1b8acf576e83330466775fac17;hb=b1761565882ed6a171136c2c89e597bc4dd5b6bf;hpb=fbd5f023a03f9f60c6ae36133703af5a711842a3), and manually add the changes to the .c and .h files based on the requirements in the patch links. Note that the number of rows may not match because of different versions of the patch and GCC. You need to search for the keyword in the patch to locate the corresponding row. - -9. Download, decompress, and install [GMP 6.1.2](https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2). - - ``` - tar -xvf gmp-6.1.2.tar.bz2 && mkdir build_gmp && cd build_gmp && ../gmp-6.1.2/configure --prefix=/usr/local/gmp-6.1.2 --disable-shared --enable-cxx && make && make install - ``` - -10. Download, decompress, and install [mpfr-4.0.2](https://www.mpfr.org/mpfr-4.0.2/mpfr-4.0.2.tar.gz). - - ``` - tar -xvf mpfr-4.0.2.tar.gz && mkdir build_mpfr && cd build_mpfr && ../mpfr-4.0.2/configure --prefix=/usr/local/mpfr-4.0.2 --with-gmp=/usr/local/gmp-6.1.2 --disable-shared && make && make install - ``` - -11. Download, decompress, and install [mpc-1.1.0](https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz). - - ``` - tar -xvf mpc-1.1.0.tar.gz && mkdir build_mpc && cd build_mpc && ../mpc-1.1.0/configure --prefix=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 --disable-shared && make && make install - ``` - -12. Open the **riscv-gnu-toolchain** folder and create a directory for toolchain output. - - ``` - cd /opt && mkdir gcc_riscv32 - ``` - -13. Compile **binutils**. - - ``` - mkdir build_binutils && cd build_binutils && ../riscv-binutils-gdb/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32/riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. - ``` - -14. Build **Newlib**. - - ``` - mkdir build_newlib && cd build_newlib && ../riscv-newlib/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" \CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. - ``` - -15. Build **GCC**. - - ``` - mkdir build_gcc && cd build_gcc && ../riscv-gcc/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" LDFLAGS="-Wl,-z,relro,-z,now,-z,noexecstack" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --with-headers="/opt/gcc-riscv32/riscv32-unknown-elf/include" --with-mpc=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 && make -j16 && make install - ``` - -16. Set an environment variable. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If you use the compiled **riscv32 gcc** package, perform the following steps to set environment variables: - >1. Decompress the package to the root directory. - > ``` - > tar -xvf gcc_riscv32-linux-7.3.0.tar.gz -C ~ - > ``` - >2. Set an environment variable. - > ``` - > vim ~/.bashrc - > ``` - >3. Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - > ``` - > export PATH=~/gcc_riscv32/bin:$PATH - > ``` - - ``` - vim ~/.bashrc - ``` - - Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - - ``` - export PATH=~/gcc_riscv32/bin:$PATH - ``` - -17. Validate the environment variable. - - ``` - source ~/.bashrc - ``` - -18. Check whether the compiler is successfully installed. If the compiler version number is correctly displayed, the installation is successful. - - ``` - riscv32-unknown-elf-gcc -v - ``` - - -## Installing the USB-to-Serial Driver - -Perform the following operations on the Windows station. - -1. Download the USB-to-serial driver: [CH341SER USB-to-serial driver](http://www.wch-ic.com/search?t=all&q=CH340g). -2. Install the driver. -3. After the driver is installed, remove and then insert the USB cable. The serial port entry should be displayed as shown in the following figure. - - ![](figures/en-us_image_0000001174350633.png) - - diff --git a/en/device-dev/quick-start/setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md b/en/device-dev/quick-start/setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md deleted file mode 100644 index 0a3ca86c3294e3af31e06cd636d3c886c897ce94..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md +++ /dev/null @@ -1,118 +0,0 @@ -# Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code - -- [Obtaining Standard-System Source Code](#section8761819202511) - - [Prerequisites](#section102871547153314) - - [Procedure](#section429012478331) - -- [Obtaining the Docker Environment](#section181431248132513) -- [Building Source Code](#section92391739152318) - -The standard OpenHarmony system provides a Docker environment which encapsulates build tools. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->- Before using Docker, install it by following instructions in [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/). ->- You can also use the [installation package](setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md) to set up the Ubuntu development environment. - -## Obtaining Standard-System Source Code - -### Prerequisites - -1. Register your account with Gitee. -2. Register an SSH public key for access to Gitee. -3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)), and configure basic user information. - - ``` - git config --global user.name "yourname" - git config --global user.email "your-email-address" - git config --global credential.helper store - ``` - -4. Run the following commands to install the **repo** tool: - - ``` - curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. - chmod a+x /usr/local/bin/repo - pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests - ``` - - -### Procedure - -Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) - -``` -repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -Method 2: Use the **repo** tool to download the source code over HTTPS. - -``` -repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -## Obtaining the Docker Environment - -**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** - -1. Obtain the Docker image. - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - -2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - - -**Method 2: Using the Dockerfile to build a local docker image** - -1. Obtain the Dockerfile script for a local Docker image. - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: - - ``` - cd docs/docker/standard - ./build.sh - ``` - -3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 - ``` - - -## Building Source Code - -1. Run the preprocessing script in the root directory of the source code. - - ``` - ../scripts/prepare.sh - ``` - -2. Run the following script to start building for Standard-System Devices \(reference memory ≥ 128 MB\): - - ``` - ./build.sh --product-name {product_name} - ``` - - **product\_name** indicates the product supported by the current distribution, for example, **Hi3516DV300**. - - Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - -3. Burn the image. For details, see [Burning Images](burning-images.md). - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->You can exit Docker by simply running the **exit** command. - diff --git a/en/device-dev/quick-start/setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md b/en/device-dev/quick-start/setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md deleted file mode 100644 index 0aaa9188a038d1279efdb270e4ffc2ac04ea2273..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md +++ /dev/null @@ -1,98 +0,0 @@ -# Setting Up Ubuntu Development Environment with Installation Package and Building Source Code - -- [Installing Dependent Tools](#section18431165519244) -- [Obtaining Standard-System Source Code](#section113751052102517) - - [Prerequisites](#section102871547153314) - - [Procedure](#section429012478331) - -- [Running prebuilts](#section0495320152619) -- [Building Source Code](#section1664835963517) - -## Installing Dependent Tools - -The installation command is as follows: - -``` -sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The preceding command is applicable to Ubuntu 18.04. For other Ubuntu versions, modify the preceding installation command based on the installation package name. - -## Obtaining Standard-System Source Code - -### Prerequisites - -1. Register your account with Gitee. -2. Register an SSH public key for access to Gitee. -3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)), and configure basic user information. - - ``` - git config --global user.name "yourname" - git config --global user.email "your-email-address" - git config --global credential.helper store - ``` - -4. Run the following commands to install the **repo** tool: - - ``` - curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. - chmod a+x /usr/local/bin/repo - pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests - ``` - - -### Procedure - -Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) - -``` -repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -Method 2: Use the **repo** tool to download the source code over HTTPS. - -``` -repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -## Running prebuilts - -Go to the root directory of the source code and run the following script to install the compiler and binary tool: - -``` -bash build/prebuilts_download.sh -``` - -By default, the downloaded prebuilts binary file is stored in **OpenHarmony\_2.0\_canary\_prebuilts** \(which is in the same directory as **OpenHarmony**\). - -## Building Source Code - -Perform the following operations in the Linux environment: - -1. Go to the root directory of the source code and run the following command to build the distribution. - - ``` - ./build.sh --product-name {product_name} - ``` - - **product\_name** indicates the product supported by the current distribution, for example, **Hi3516DV300**. - -2. Check the build result. After the build is complete, the following information is displayed in the log: - - ``` - build system image successful. - =====build Hi3516DV300 successful. - ``` - - Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >For details about module-specific build operations, see [Compilation and Building Overview](../subsystems/building-guidelines-for-the-standard-system.md). - -3. Burn the image. For details, see [Burning Images](burning-images.md). - diff --git a/en/device-dev/quick-start/setting-up-windows-development-environment.md b/en/device-dev/quick-start/setting-up-windows-development-environment.md deleted file mode 100644 index 4308389e169c415c5a502738359d0eed094fd3fc..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-windows-development-environment.md +++ /dev/null @@ -1,183 +0,0 @@ -# Setting Up Windows Development Environment - -- [Obtaining the Software](#en-us_topic_0000001058091994_section1483143015558) -- [Installing Visual Studio Code](#en-us_topic_0000001058091994_section71401018163318) -- [Installing Python](#en-us_topic_0000001058091994_section16266553175320) -- [Installing Node.js](#en-us_topic_0000001058091994_section5353233124511) -- [Installing hpm](#en-us_topic_0000001058091994_section173054793610) -- [Installing the DevEco Device Tool Plug-in](#en-us_topic_0000001058091994_section4336315185716) - -Operating system: 64-bit version of Windows 10. - -DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedure includes five parts: - -1. Installing Visual Studio Code -2. Installing Python -3. Installing Node.js -4. Installing hpm -5. Installing the DevEco Device Tool Plug-in - -## Obtaining the Software - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Tool

-

Description

-

Version

-

Obtaining Channel

-

Visual Studio Code

-

Code editing tool

-

V1.53 or later (64-bit)

-

https://code.visualstudio.com/Download

-

Python

-

Programming tool

-

v3.7.4–3.8.x (64-bit)

-

https://www.python.org/downloads/

-

Node.js

-

The npm environment provider

-

v12.0.0 or later (64-bit)

-

https://nodejs.org/en/download/

-

hpm

-

Package manager

-

Latest version

-

Run the following command:

-
npm install -g @ohos/hpm-cli
-

DevEco Device Tool

-

Plug-in for the OpenHarmony source code compilation, programming, and debugging

-

v2.2 Beta1

-

https://device.harmonyos.com/en/ide#download

-

Log in with your HUAWEI ID to download it. You can register an account here.

-
- -## Installing Visual Studio Code - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If you have installed Visual Studio Code, open the CLT and run **code --version** to check whether the version is 1.53 or later. If the version number is returned, it indicates that the environment variables are set correctly. - -1. Double-click the Visual Studio Code package to install it. During the installation, select **Add to PATH \(requires shell restart\)**. - - ![](figures/en-us_image_0000001057335403.png) - -2. After the installation is complete, restart the computer for the environment variables of Visual Studio Code to take effect. -3. Open the CLT and run **code --version**. If the version number can be displayed, it indicates that the installation is successful. - -## Installing Python - -1. Double-click the Python software package, select **Add Python xx to PATH**, and click **Install Now**. - - ![](figures/en-us_image_0000001096154076.png) - -2. After the installation is complete, click **Close**. - - ![](figures/en-us_image_0000001142794291.png) - -3. Open the CLT, and run **python --version** to check the installation result. - - ![](figures/en-us_image_0000001143154485.png) - -4. In the CLT, run the following commands to set the pip source for downloading the dependencies required for later installation: - - ``` - pip config set global.trusted-host repo.huaweicloud.com - pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple - pip config set global.timeout 120 - ``` - - -## Installing Node.js - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If you have installed Node.js, open the CLT and run **node -v** to check whether the version is 12.0.0 or later. - -1. Run the downloaded software package to install. Use the default settings when following the installation wizard, and click **Next** until **Finish** is displayed. During the installation, Node.js will automatically set the system Path environment variable to the installation directory of **node.exe**. -2. Open the CLT and run **node -v**. If the version number of Node.js is displayed, it indicates that Node.js has been successfully installed. - - ![](figures/en-us_image_0000001056814287.png) - - -## Installing hpm - -Before installing hpm, ensure that Node.js has been installed - -and that your network can access the Internet. If your network requires a proxy to access the Internet, [set up the npm proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032) first. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If hpm has been installed, run **npm update -g @ohos/hpm-cli** to update it to the latest version. - -1. You are advised to set the npm source to an image in China, for example, a HUAWEI CLOUD image source. - - ``` - npm config set registry https://repo.huaweicloud.com/repository/npm/ - ``` - -2. Open the CLT and run the following command to install the latest version of hpm: - - ``` - npm install -g @ohos/hpm-cli - ``` - - ![](figures/en-us_image_0000001073840162.png) - -3. After the installation is complete, run the following command to obtain the installation result: - - ``` - hpm -V - ``` - - ![](figures/en-us_image_0000001100641602.png) - - -## Installing the DevEco Device Tool Plug-in - -To install the DevEco Device Tool plug-in, ensure that the **user name of the host cannot contain Chinese characters**; otherwise, the plug-in may fail to run. - -DevEco Device Tool will automatically download and install the C/C++ and CodeLLDB plug-ins from the Visual Studio Code Marketplace during the installation process. Therefore, make sure Visual Studio Code can access the Internet. If your network requires a proxy to access the Internet, [set up the Visual Studio Code proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144) first. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Before installing DevEco Device Tool, ensure that Visual Studio Code is closed. - -1. Decompress the DevEco Device Tool plug-in package and double-click the installer to install. -2. During the installation, the dependency files \(such as C/C++ and CodeLLDB plug-ins\) and execution programs required by DevEco Device Tool are automatically installed. - - ![](figures/en-us_image_0000001072468991.png) - -3. After the installation is complete, the CLT is automatically closed. -4. Open Visual Studio Code, click the ![](figures/en-us_image_0000001072757874.png) button on the left, and check whether C/C++, CodeLLDB, and DevEco Device Tool are listed in **INSTALLED**. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the C/C++ and CodeLLDB plug-ins fail to be installed, DevEco Device Tool cannot run properly. To solve the issue, see [Installing the C/C++ and CodeLLDB Plug-ins Offline](https://device.harmonyos.com/en/docs/ide/user-guides/offline_plugin_install-0000001074376846). - - ![](figures/en-us_image_0000001142802505.png) - - diff --git a/en/device-dev/quick-start/standard-system.md b/en/device-dev/quick-start/standard-system.md deleted file mode 100644 index f0aa95fdac24012324baa361c8958305bcfd436f..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/standard-system.md +++ /dev/null @@ -1,15 +0,0 @@ -# Standard System - -- **[Introduction](introduction.md)** - -- **[Setting Up Windows Development Environment](setting-up-windows-development-environment.md)** - -- **[Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code](setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md)** - -- **[Setting Up Ubuntu Development Environment with Installation Package and Building Source Code](setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md)** - -- **[Burning Images](burning-images.md)** - -- **[FAQs](faqs-7.md)** - - diff --git a/en/device-dev/quick-start/ubuntu-build-environment.md b/en/device-dev/quick-start/ubuntu-build-environment.md deleted file mode 100644 index 50c25fe1ea26c3f94dae8ce906c188d01e604850..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/ubuntu-build-environment.md +++ /dev/null @@ -1,361 +0,0 @@ -# Ubuntu Build Environment - -- [Obtaining Source Code and Tools](#section1897711811517) -- [Obtaining Source Code](#section1545225464016) -- [Installing and Configuring Python](#section1238412211211) -- [Installing gn](#section29216201423) -- [Installing ninja](#section8762358731) -- [Installing LLVM](#section12202192215415) -- [Installing hb](#section15794154618411) - - [Prerequisites](#section1083283711515) - - [Installation Procedure](#section11518484814) - - [Uninstalling hb](#section3512551574) - -- [Installing Other Tools](#section830511218494) - - [Installation Procedure](#section54409586499) - - -Operating system: 64-bit version of Ubuntu 16.04 or later. - -Perform the following steps to set up the build environment: - -1. Obtain source code. -2. Install and configure Python. -3. Install GN. -4. Install Ninja. -5. Install LLVM. -6. Install hb. - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- Docker is provided for the Ubuntu build environment, which encapsulates related build tools. If you use Docker to prepare the build environment, you do not need to perform the following steps in this section. Instead, refer to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). ->- By default, basic software, such as Samba and Vim, is installed in the system. Adaptation on the software is required to support file sharing between the Linux server and the Windows workstation. ->- For details about the compilation and building subsystem of OpenHarmony, see the [Compilation and Building Overview](../subsystems/building-guidelines-for-mini-and-small-systems.md). - -## Obtaining Source Code and Tools - -The following table describes the tools and source code required for setting up the general environment for a Linux server and how to obtain these tools and the source code. - -**Table 1** Source code and development tools and their obtaining methods - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Item

-

Description

-

How to Obtain

-

Source code

-

Develops functions.

-

For details, see Source Code Acquisition.

-

Python3.7+

-

Executes script compilation.

-

Internet

-

gn

-

Generates ninja compilation scripts.

-

https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz

-

ninja

-

Executes ninja compilation scripts.

-

https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar

-

-

LLVM

-

-

-

Functions as the compiler toolchain.

-

-

For the master and OpenHarmony_v2.x branches and tags, use version 10.0.1:

-

https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz

-

For the OpenHarmony_v1.x branches and tags, use version 9.0.0:

-

https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar

-

hb

-

Compiles the OpenHarmony source code.

-

Internet

-

Other tools

-

Provide functions required in compilation and building, such as packaging and creating images.

-

Internet

-
- ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install compilation tools like **gn** and **ninja**. ->- \(Recommended\) If you obtain the source code via the mirror site or code repository, install compilation tools such as **gn**, **ninja**, and LLVM. When installing these tools, ensure that their environment variable paths are unique. - -## Obtaining Source Code - -You need to acquire [source code](../get-code/source-code-acquisition.md), download it on a Linux server, and decompress it. - -## Installing and Configuring Python - -1. Start a Linux server. -2. Check the Python version \(Python 3.7 or later is required\). - - ``` - python3 --version - ``` - - If Python version is earlier than 3.7, reinstall Python. Do as follows to install Python, for example, Python 3.8. - - 1. Check the Ubuntu version. - - ``` - cat /etc/issue - ``` - - 1. Install Python based on the Ubuntu version. - - If the Ubuntu version is 18 or later, run the following command: - - ``` - sudo apt-get install python3.8 - ``` - - - If the Ubuntu version is 16, perform the following steps: - - a. Install dependency packages. - - ``` - sudo apt update && sudo apt install software-properties-common - ``` - - b. Add the source of deadsnakes PPA and press **Enter**. - - ``` - sudo add-apt-repository ppa:deadsnakes/ppa - ``` - - c. Install Python 3.8. - - ``` - sudo apt upgrade && sudo apt install python3.8 - ``` - - - -3. Set the soft link of **python** and **python3** to **python3.8**. - - ``` - sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1 - sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1 - ``` - -4. Install and upgrade the Python package management tool \(pip3\) using either of the following methods: - - **Command line:** - - ``` - sudo apt-get install python3-setuptools python3-pip -y - sudo pip3 install --upgrade pip - ``` - - - **Installation package:** - - ``` - curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py - python get-pip.py - ``` - - - -## Installing gn - -1. Start a Linux server. -2. Download [gn](https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz). -3. Create the **gn** folder in the root directory. - - ``` - mkdir ~/gn - ``` - -4. Decompress the gn installation package to **\~/gn**. - - ``` - tar -xvf gn-linux-x86-1717.tar.gz -C ~/gn - ``` - -5. Set an environment variable. - - ``` - vim ~/.bashrc - ``` - - Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - - ``` - export PATH=~/gn:$PATH - ``` - -6. Validate the environment variable. - - ``` - source ~/.bashrc - ``` - - -## Installing ninja - -1. Start a Linux server. -2. Download [ninja](https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar). -3. Decompress the ninja installation package to **\~/ninja**. - - ``` - tar -xvf ninja.1.9.0.tar -C ~/ - ``` - -4. Set an environment variable. - - ``` - vim ~/.bashrc - ``` - - Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - - ``` - export PATH=~/ninja:$PATH - ``` - -5. Validate the environment variable. - - ``` - source ~/.bashrc - ``` - - -## Installing LLVM - -1. Start a Linux server. -2. [Download LLVM](https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz). - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >For the OpenHarmony\_v1.x branches and tags, click [here](https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar) to download LLVM. - -3. Decompress the LLVM installation package to **\~/llvm**. - - ``` - tar -zxvf llvm.tar.gz -C ~/ - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >For the OpenHarmony\_v1.x branches and tags, run the following command to decompress the LLVM installation package: - >``` - >tar -xvf llvm-linux-9.0.0-36191.tar -C ~/ - >``` - -4. Set an environment variable. - - ``` - vim ~/.bashrc - ``` - - Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - - ``` - export PATH=~/llvm/bin:$PATH - ``` - -5. Validate the environment variable. - - ``` - source ~/.bashrc - ``` - - -## Installing hb - -### Prerequisites - -Python 3.7.4 or later has been installed. For details, see [Installing and Configuring Python](#section1238412211211). - -### Installation Procedure - -1. Install **hb**. - - ``` - python3 -m pip install --user ohos-build - ``` - -2. Set an environment variable. - - ``` - vim ~/.bashrc - ``` - - Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - - ``` - export PATH=~/.local/bin:$PATH - ``` - - Update the environment variable. - - ``` - source ~/.bashrc - ``` - -3. Run the **hb -h** command. If the following information is displayed, the installation is successful: - - ``` - usage: hb - - OHOS build system - - positional arguments: - {build,set,env,clean} - build Build source code - set OHOS build settings - env Show OHOS build env - clean Clean output - - optional arguments: - -h, --help Show this help message and exit - ``` - - -### Uninstalling hb - -``` -python3 -m pip uninstall ohos-build -``` - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->If you encounter any problem during the installation, resort to the [FAQ](faq.md). - -## Installing Other Tools - -### Installation Procedure - -1. Use **apt-get** to install dependent tools. - - ``` - sudo apt-get install build-essential gcc g++ make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-boot-tools mtd-utils - ``` - - diff --git a/en/device-dev/quick-start/windows-development-environment.md b/en/device-dev/quick-start/windows-development-environment.md deleted file mode 100644 index d0824ce00ea9573806c2a4c75f1df00a2de9aa0e..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/windows-development-environment.md +++ /dev/null @@ -1,183 +0,0 @@ -# Windows Development Environment - -- [Obtaining the Software](#en-us_topic_0000001058091994_section1483143015558) -- [Installing Visual Studio Code](#en-us_topic_0000001058091994_section71401018163318) -- [Installing Python](#en-us_topic_0000001058091994_section16266553175320) -- [Installing Node.js](#en-us_topic_0000001058091994_section5353233124511) -- [Installing hpm](#en-us_topic_0000001058091994_section173054793610) -- [Installing the DevEco Device Tool Plug-in](#en-us_topic_0000001058091994_section4336315185716) - -Operating system: 64-bit version of Windows 10. - -DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedure includes five parts: - -1. Installing Visual Studio Code -2. Installing Python -3. Installing Node.js -4. Installing hpm -5. Installing the DevEco Device Tool Plug-in - -## Obtaining the Software - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Tool

-

Description

-

Version

-

Obtaining Channel

-

Visual Studio Code

-

Code editing tool

-

V1.53 or later (64-bit)

-

https://code.visualstudio.com/Download

-

Python

-

Programming tool

-

v3.7.4–3.8.x (64-bit)

-

https://www.python.org/downloads/

-

Node.js

-

The npm environment provider

-

v12.0.0 or later (64-bit)

-

https://nodejs.org/en/download/

-

hpm

-

Package manager

-

Latest version

-

Run the following command:

-
npm install -g @ohos/hpm-cli
-

DevEco Device Tool

-

Plug-in for the OpenHarmony source code compilation, programming, and debugging

-

v2.2 Beta1

-

https://device.harmonyos.com/en/ide#download

-

Log in with your HUAWEI ID to download it. You can register an account here.

-
- -## Installing Visual Studio Code - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If you have installed Visual Studio Code, open the CLT and run **code --version** to check whether the version is 1.53 or later. If the version number is returned, it indicates that the environment variables are set correctly. - -1. Double-click the Visual Studio Code package to install it. During the installation, select **Add to PATH \(requires shell restart\)**. - - ![](figures/en-us_image_0000001174350653.png) - -2. After the installation is complete, restart the computer for the environment variables of Visual Studio Code to take effect. -3. Open the CLT and run **code --version**. If the version number can be displayed, it indicates that the installation is successful. - -## Installing Python - -1. Double-click the Python software package, select **Add Python xx to PATH**, and click **Install Now**. - - ![](figures/en-us_image_0000001128471042.png) - -2. After the installation is complete, click **Close**. - - ![](figures/en-us_image_0000001128311104.png) - -3. Open the CLT, and run **python --version** to check the installation result. - - ![](figures/en-us_image_0000001174350781.png) - -4. In the CLT, run the following commands to set the pip source for downloading the dependencies required for later installation: - - ``` - pip config set global.trusted-host repo.huaweicloud.com - pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple - pip config set global.timeout 120 - ``` - - -## Installing Node.js - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If you have installed Node.js, open the CLT and run **node -v** to check whether the version is 12.0.0 or later. - -1. Run the downloaded software package to install. Use the default settings when following the installation wizard, and click **Next** until **Finish** is displayed. During the installation, Node.js will automatically set the system Path environment variable to the installation directory of **node.exe**. -2. Open the CLT and run **node -v**. If the version number of Node.js is displayed, it indicates that Node.js has been successfully installed. - - ![](figures/en-us_image_0000001128311096.png) - - -## Installing hpm - -Before installing hpm, ensure that Node.js has been installed - -and that your network can access the Internet. If your network requires a proxy to access the Internet, [set up the npm proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032) first. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If hpm has been installed, run **npm update -g @ohos/hpm-cli** to update it to the latest version. - -1. You are advised to set the npm source to an image in China, for example, a HUAWEI CLOUD image source. - - ``` - npm config set registry https://repo.huaweicloud.com/repository/npm/ - ``` - -2. Open the CLT and run the following command to install the latest version of hpm: - - ``` - npm install -g @ohos/hpm-cli - ``` - - ![](figures/en-us_image_0000001128311100.png) - -3. After the installation is complete, run the following command to obtain the installation result: - - ``` - hpm -V - ``` - - ![](figures/en-us_image_0000001174270735.png) - - -## Installing the DevEco Device Tool Plug-in - -To install the DevEco Device Tool plug-in, ensure that the **user name of the host cannot contain Chinese characters**; otherwise, the plug-in may fail to run. - -DevEco Device Tool will automatically download and install the C/C++ and CodeLLDB plug-ins from the Visual Studio Code Marketplace during the installation process. Therefore, make sure Visual Studio Code can access the Internet. If your network requires a proxy to access the Internet, [set up the Visual Studio Code proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144) first. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Before installing DevEco Device Tool, ensure that Visual Studio Code is closed. - -1. Decompress the DevEco Device Tool plug-in package and double-click the installer to install. -2. During the installation, the dependency files \(such as C/C++ and CodeLLDB plug-ins\) and execution programs required by DevEco Device Tool are automatically installed. - - ![](figures/en-us_image_0000001128470902.png) - -3. After the installation is complete, the CLT is automatically closed. -4. Open Visual Studio Code, click the ![](figures/en-us_image_0000001174350651.png) button on the left, and check whether C/C++, CodeLLDB, and DevEco Device Tool are listed in **INSTALLED**. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the C/C++ and CodeLLDB plug-ins fail to be installed, DevEco Device Tool cannot run properly. To solve the issue, see [Installing the C/C++ and CodeLLDB Plug-ins Offline](https://device.harmonyos.com/en/docs/ide/user-guides/offline_plugin_install-0000001074376846). - - ![](figures/en-us_image_0000001174270727.png) - - diff --git a/en/device-dev/quick-start/wlan-connection.md b/en/device-dev/quick-start/wlan-connection.md deleted file mode 100644 index 6869012b733851e1555efbf1cce23ea5c51f7317..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/wlan-connection.md +++ /dev/null @@ -1,142 +0,0 @@ -# WLAN Connection - -- [Building](#section191121332125319) -- [Burning Images](#section19458165166) -- [Connecting WLAN Module to the Internet.](#section194671619167) - -This example shows how to connect the WLAN module to the gateway using attention \(AT\) commands. - -## Building - -This section describes how to perform the WLAN module building on a Linux server. - -If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). If the Linux environment is installed using a software package, perform the following steps: - -1. Open the HUAWEI DevEco Device Tool and choose **View** \> **Terminal**. - - **Figure 1** Starting the IDE terminal tool - - - ![](figures/1.png) - - On the **TERMINAL** panel, run the ssh command, for example, **ssh** **_user_@_ipaddr_**, to connect to the Linux server. - - **Figure 2** TERMINAL panel - - - ![](figures/2.png) - -2. Go to the root directory of the code, run the **hb set** and **.** commands on the **TERMINAL** panel, and select the **wifiiot\_hispark\_pegasus** version. - - **Figure 3** Selecting the target build version - - - ![](figures/3.png) - -3. Run the **hb build** command to start building. - - **Figure 4** Running commands on the TERMINAL panel - - - ![](figures/4.png) - -4. Check whether the building is successful. If yes, **wifiiot\_hispark\_pegasus build success** will be displayed, as shown in the following figure. - - **Figure 5** Successful building - - - ![](figures/5.png) - -5. Check whether the following files are generated in the **./out/wifiiot/** directory. - - ``` - ls -l out/hispark_pegasus/wifiiot_hispark_pegasus/ - ``` - - **Figure 6** Directory for storing the generated files - - - ![](figures/3-0.png) - - -## Burning Images - -You can use the DevEco tool to perform the image burning of the Hi3861 WLAN module. For details about how to use the tool, see [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). - -1. Connect the PC and the target development board through the USB port. For details, please refer to [Introduction to the Hi3861 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des_3861-0000001105041324). -2. Open Device Manager, then check and record the serial port number corresponding to the development board. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3861 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3861-drivers-0000001058153433). - - ![](figures/en-us_image_0000001128311118.png) - -3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - - ![](figures/en-us_image_0000001128311116.png) - -4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. -5. On the **hi3861** tab page, set the programming options. - - - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001056563976_li848662117291). - - **upload\_protocol**: Select the burning protocol **burn-serial**. - - **upload\_partitions**: Select the file to be burned. **hi3861\_app** is selected by default. - - ![](figures/en-us_image_0000001128470922.png) - -6. When you finish modifying, click **Save** in the upper right corner. -7. Open the project file. In the DevEco Device Tool window, go to **PROJECT TASKS** \> **hi3861** \> **Upload** to start programming. - - ![](figures/en-us_image_0000001174270749.png) - -8. When the following information is displayed, press the RST button on the development board to restart it. - - ![](figures/en-us_image_0000001174270751.png) - -9. Start burning. When the following message is displayed, the burning is successful. - - ![](figures/en-us_image_0000001174350669.png) - - -## Connecting WLAN Module to the Internet. - -After completing version building and burning, do as follows to connect the WLAN module to the Internet using AT commands. - -1. Click the icon of **DevEco: Serial Monitor** at the bottom of DevEco Studio to keep the connection between the Windows workstation and the WLAN module. - - **Figure 7** Opening the DevEco serial port - - - ![](figures/5-1.png) - -2. Reset the WLAN module. The message **ready to OS start** is displayed on the **TERMINAL** panel, indicating that the WLAN module is started successfully. - - **Figure 8** Successful resetting of the WLAN module - - - ![](figures/6.png) - -3. Run the following AT commands in sequence via the DevEco serial port terminal to start the STA mode, connect to the specified AP, and enable Dynamic Host Configuration Protocol \(DHCP\). - - ``` - AT+STARTSTA # Start the STA mode. - AT+SCAN # Scan for available APs. - AT+SCANRESULT # Display the scanning result. - AT+CONN="SSID",,2,"PASSWORD" # Connect to the specified AP. (SSID and PASSWORD represent the name and password of the hotspot to be connected, respectively.) - AT+STASTAT # View the connection result. - AT+DHCP=wlan0,1 # Request the IP address of wlan0 from the AP using DHCP. - ``` - -4. Check whether the WLAN module is properly connected to the gateway, as shown in the following figure. - - ``` - AT+IFCFG # View the IP address assigned to an interface of the module. - AT+PING=X.X.X.X # Check the connectivity between the module and the gateway. Replace X.X.X.X with the actual gateway address. - ``` - - **Figure 9** Successful networking of the WLAN module - - - ![](figures/截图.png) - - diff --git a/en/device-dev/security/Readme-EN.md b/en/device-dev/security/Readme-EN.md index 03e75d7a357e34f3974eb34839b23992d2b998d6..09b0d20c4425a17dd609cffa530aaf54d0691c01 100644 --- a/en/device-dev/security/Readme-EN.md +++ b/en/device-dev/security/Readme-EN.md @@ -1,5 +1,5 @@ # Privacy and Security -- [Privacy Protection](privacy-protection.md) -- [Security Guidelines](security-guidelines.md) +- [Privacy Protection](oem_security_privacy.md) +- [Security Guidelines](safety-safeguide-security.md) diff --git "a/en/device-dev/security/figures/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" "b/en/device-dev/security/figure/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" similarity index 100% rename from "en/device-dev/security/figures/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" rename to "en/device-dev/security/figure/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" diff --git "a/en/device-dev/security/figures/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" "b/en/device-dev/security/figure/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" similarity index 100% rename from "en/device-dev/security/figures/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" rename to "en/device-dev/security/figure/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" diff --git "a/en/device-dev/security/figures/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" "b/en/device-dev/security/figure/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" similarity index 100% rename from "en/device-dev/security/figures/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" rename to "en/device-dev/security/figure/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" diff --git "a/en/device-dev/security/figures/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" "b/en/device-dev/security/figure/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" similarity index 100% rename from "en/device-dev/security/figures/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" rename to "en/device-dev/security/figure/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" diff --git "a/en/device-dev/security/figures/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" "b/en/device-dev/security/figure/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" similarity index 100% rename from "en/device-dev/security/figures/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" rename to "en/device-dev/security/figure/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" diff --git "a/en/device-dev/security/figures/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" "b/en/device-dev/security/figure/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" similarity index 100% rename from "en/device-dev/security/figures/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" rename to "en/device-dev/security/figure/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" diff --git "a/en/device-dev/security/figures/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" "b/en/device-dev/security/figure/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" similarity index 100% rename from "en/device-dev/security/figures/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" rename to "en/device-dev/security/figure/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" diff --git a/en/device-dev/security/figures/how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship.png b/en/device-dev/security/figure/how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship.png similarity index 100% rename from en/device-dev/security/figures/how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship.png rename to en/device-dev/security/figure/how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship.png diff --git a/en/device-dev/security/figures/how-dac-works.png b/en/device-dev/security/figure/how-dac-works.png similarity index 100% rename from en/device-dev/security/figures/how-dac-works.png rename to en/device-dev/security/figure/how-dac-works.png diff --git a/en/device-dev/security/figures/huks-functions.png b/en/device-dev/security/figure/huks-functions.png similarity index 100% rename from en/device-dev/security/figures/huks-functions.png rename to en/device-dev/security/figure/huks-functions.png diff --git a/en/device-dev/security/figures/security-assurance-framework.png b/en/device-dev/security/figure/security-assurance-framework.png similarity index 100% rename from en/device-dev/security/figures/security-assurance-framework.png rename to en/device-dev/security/figure/security-assurance-framework.png diff --git a/en/device-dev/security/oem_security_privacy.md b/en/device-dev/security/oem_security_privacy.md new file mode 100644 index 0000000000000000000000000000000000000000..0a3e53c1d8258693bb07dfe0637e3ea40f6e08ae --- /dev/null +++ b/en/device-dev/security/oem_security_privacy.md @@ -0,0 +1,264 @@ +# Privacy Protection + +- [Overview](#section13200134331414) +- [Data Classification](#section2371104991511) +- [General Privacy Design Rules](#section10354102411162) +- [Privacy Protection Requirements for Special Categories](#section118861450201618) + +## Overview + +Personal data plays an increasingly important role in social economy and daily life along with the development of the Internet and informatization. Meanwhile, personal data leakage risks are increasing. As consumer product developers, you shall take more effective measures to protect users' personal data and improve their trust in your products. To protect consumers' privacy and improve their experience on privacy, you should set high-level privacy protection policies for your product. + +**Basic Concepts** + +- **Personal data** + + Any information relating to an identified or identifiable natural person \("Data Subject"\) who can be identified, directly or indirectly, in particular by reference to an identifier such as a name, an identification number, location data, an online identifier or to one or more factors specific to the physical, physiological, genetic, mental, commercial, cultural, or social identity of that natural person. Personal data includes a natural person's email address, phone number, biometric information \(such as a fingerprint\), location data, IP address, healthcare information, religious belief, social security number, marital status, and so on. + +- **Sensitive personal data** + + Sensitive personal data, a critical subset of personal data, refers to the most private information of a data subject or information that may cause severe adverse impacts on a data subject once disclosed. Sensitive personal data defined in laws and regulations of EU and its members includes personal data revealing racial or ethnic origin, political opinions, religious or philosophical beliefs, trade-union membership, genetic data, biometric information, and data concerning health or sex life and sexual orientation. + + With reference to industry best practices, we also define the following data related to a natural person's identity as sensitive: bank card number, identification number, passport number, and passwords. More strict protection measures are usually required for processing sensitive personal data. + +- **Public available personal data** + + Personal data that is proactively disclosed by a data subject or that can be accessed on public web pages or applications, including posts and comments made on forums. + +- **User profile** + + Any form of automated processing of personal data to assess a natural person in specific aspects, and in particular to analyze and predict the natural person's work performance, financial situation, health, personal preference, interest, creditability, behavior, and location or trace. + +- **Data controller** + + A natural or legal person, public authority, agency, or any other body that, alone or jointly with others, determines the purposes and means of personal data processing. + +- **Data processor** + + A natural or legal person, public authority, agency, or any other body that processes personal data on behalf of a data controller. A data processor must provide adequate protection following the data controller's requirements. + +- **Explicit consent** + + Explicit consent applies to the following scenarios where the General Data Protection Regulation \(GDPR\) allows the legitimate processing of personal data based on data subjects' explicit consent: + + - Processing of sensitive personal data + - Automated decision-making, including user profiles + - Transfer of personal data to countries without an adequate level of protection, which uses consent as the legal basis + + Explicit consent can be implemented as follows: + + - In the collection of specific data, display a privacy statement to notify data subjects of matters related to the processing of personal data, provide a check box which is deselected by default, and prompt data subjects to proactively select the option indicating that "I agree to process my personal data in the above manner" or click the "I agree" button. + - Expressly present consent in writing and request data subjects to sign it. + - Ask data subjects to upload an electronic form with their signature in the system. + - Adopt the double verification method by requesting data subjects to consent via an email and then re-click the email link for verification or enter the SMS verification code. + - Users provide information proactively, such as scenarios where a user enters their identification number and bank card number to bind the bank card. + + +## Data Classification + +Data is classified into five levels: very high, high, moderate, low, and public based on the data protection objectives and consequences \(the impact of legal risks caused by data leakage or damage on individuals, organizations, or the public\). + +**Table 1** Standards for data classification + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Level

+

Privacy Risk

+

Privacy Attribute

+

Typical Example

+

Very high

+

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a catastrophic negative impact on that individual or group of individuals.

+

Sensitive personal data

+

DNA, race, religious belief, and sexual orientation; biometric information; original communication content; bank account password and magnetic track data

+

High

+

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a severe negative impact on that individual or group of individuals.

+

Sensitive personal data

+

Social identity (such as ID card and passport number); web browsing history; tracks; content (such as images, audio, and video) uploaded to the cloud

+

Moderate

+

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a significant negative impact on that individual or group of individuals.

+

General personal data

+

Device ID (such as IMEI, SN, and OAID) and user ID; basic personal information (name and address); mobile number and email address

+

Low

+

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a limited negative impact on that individual or group of individuals.

+

General personal data

+

OS settings (including the OS version and country/region); device hardware information (device model, screen size, and screen resolution); network information (network connection status and access network information); device status (login time/duration)

+

Public

+

Public data has no adverse impact on individuals or organizations.

+

Non-personal data

+

Publicly released product introduction, public meeting information, and external open-source code

+
+ +Note: For details about the definitions of privacy protection and data classification, see GDPR. + +## General Privacy Design Rules + +To help you better complete privacy design for OpenHarmony products, we sort out general privacy design requirements. + +**Openness and Transparency in Data Collection and Use** + +When collecting personal data, clearly and explicitly notify users of the data to collect and how their personal data will be used. + +- Develop specific privacy processing policies for personal data at different levels. + - Explicit consent shall be obtained from the data subject before your product attempts to collect sensitive personal data. + - Generally, the collection of personal data requires the consent of the data subject or other legal authorizations. + - If non-personal data is to be collected in association with personal data at the moderate, high, or very high level, the data subject's consent or other legal authorization is required, and the consent or authorization shall be presented in the privacy statement. + +- Develop and follow appropriate privacy policies. Comply with all applicable laws, policies, and regulations when collecting, using, retaining, and sharing users' personal data with any third parties. For example, prior to data collection, fully inform users of the types, purposes, processing methods, and retention periods of personal data to meet the requirements of data subjects' rights. + + Guided by the preceding principles, we have designed some examples for your reference. The figures below are examples of a privacy notice and a privacy statement, respectively. + + **Figure 1** Examples of a privacy notice and a privacy statement + + + ![](figure/2-应用启动预授权.png)![](figure/3-应用隐私声明.png) + +- Personal data shall be collected for specified, explicit, and legitimate purposes and not further processed in a manner that is incompatible with those purposes. If the purposes are changed or a user withdraws their consent, you shall obtain user consent again before using the data. The figures below are examples of a privacy statement update and content withdrawal, respectively. + + **Figure 2** Example dialog showing a privacy statement update + + + ![](figure/4-隐私声明变更通知.png) + + **Figure 3** Example dialog showing consent withdrawal + + + ![](figure/6-1-隐私声明撤销.png)![](figure/6-2-隐私声明撤销.png) + +- You shall provide an entry for users to view the privacy statement. For example, you can provide an entry on the **About** page of your application to view the privacy statement, as shown in the following figure. + + **Figure 4** Example of About page providing an entry to the privacy statement + + + ![](figure/5-应用隐私声明入口.png) + + +**Minimization in Data Collection and Use** + +Collect personal data only when they are adequate, relevant, and limited to what is necessary in relation to the purposes for which they are processed. Apply anonymization or pseudonymization to personal data if possible to reduce the risks to the data subjects concerned. Data shall only be collected and processed for a specified purpose, and no further unnecessary operations shall be conducted on them. + +- When applying for sensitive permissions, adhere to permission minimization and apply for only the permissions required for obtaining necessary information or resources. For example, if your application can implement its functions without access to the camera, then it shall not request the user for the camera permission. +- Comply with data collection minimization, and do not collect data irrelevant to services provided by the product. For example, a product that provides location services shall not collect users' web browsing history. +- The functions that use personal data shall be able to benefit users. The collected data shall not be used for functions irrelevant to users' normal use. No data shall be collected for any functions irrelevant to user operations. For example, sensitive personal data, such as biometric features and health data, shall not be used for non-core service functions like service improvement, advertising, and marketing. +- Printing sensitive personal data in logs is prohibited. If common personal data needs to be printed in logs, make sure the data is anonymized or pseudonymized. + + Preferentially use identifiers that are resettable. For example, use the NetworkID and DVID as the device identifier in the distributed scenario; use the [OAID](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/oaid-0000001050783198) in the advertising scenario; use the [ODID](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/odid-0000001051063255) and [AAID](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/aaid-0000001051142988) in the application-based analysis scenario; and use the UUID in other scenarios where a unique identifier is required. Use permanent identifiers such as the sequence number and MAC address only when resettable identifiers cannot meet your service requirements. + + +**Data Processing Selection and Control** + +You shall obtain consent from users and comply with applicable laws and regulations for processing personal data and give users full control over their data. + +- When applying for a certain sensitive permission, your product shall display a pop-up dialog to notify the user of the requested permission and the purpose of using the permission. The user shall be able to choose whether to grant the permission and how they would like to grant the permission. This ensures that permission granting and use are transparent, perceivable, and controllable. The following figure is an example dialog for requesting a sensitive permission. + + **Figure 5** Example dialog for requesting a sensitive permission + + + ![](figure/1-敏感权限弹窗.png) + +- Users shall have the right to modify or withdraw the permissions granted to your product. When a user does not agree to a permission or data collection, the user shall be allowed to use the functions irrelevant to the permission or data collection. For example, the user can refuse to grant the camera permission to social or communication apps on Smart TVs, when using product functions irrelevant to the camera, such as voice calls. +- In scenarios where personal data is recorded, users shall be provided with the functions of adding, deleting, modifying, and viewing personal data. +- Your products shall provide a mechanism or method for securely deleting personal data when hardware is recycled or returned to the factory. +- The download or upgrade of user system software or application software may involve the modification of users' private space. Users shall have the right to know and control such behavior. They shall be informed of such behavior and be given the option to agree or disagree with such behavior. + +**Data Security** + +Data processing security shall be ensured in technical terms, which include encrypted data storage and secure data transfer. Security mechanisms or measures shall be enabled by default for a system. + +- A protection mechanism shall be available for personal data access, including identity authentication and access control. Identity authentication \(such as username and password\) allows only authenticated users to access data in multi-user scenarios. Access control \(for example, [permission control](security/safety-safeguide-security.md#li201725506375)\) can be applied to restrict access to applications. +- Secure storage of personal data on distributed devices must meet Huawei Universal Keystore \(HUKS\) requirements, including secure storage of keys and data. +- The transfer of personal data between distributed devices must meet the trust binding relationship between devices and security requirements of data transmission channels. For details, see [Security Guidelines](security/safety-safeguide-security.md#section26153183616). +- Authentication data \(such as passwords and fingerprints\) shall be encrypted before being stored. + +**Localization** + +User data shall be preferentially processed on the local device. Data that cannot be processed on the local device shall be preferentially processed on Device+ \(super device in the distributed scenario\). If any data cannot be processed on Device+, the data shall be anonymized before being transferred out of Device+ for processing. + +**Minors' Data Protection** + +If your product is designed for minors or you can identify, based on the collected user age data, that the end user is a minor, you shall particularly analyze issues related to minors' personal data protection based on relevant national laws in the target market. Your product shall obtain explicit consent from the holders of parental responsibility over minors. + +## **Privacy Protection Requirements for Special Categories** + +In addition to these general privacy requirements, consumer hardware products have the following requirements for special categories. You shall comply with these requirements during product design. + +**Table 2** Privacy protection requirements for special categories + + + + + + + + + + + + + + + + + + + + + + + + + +

Product Category

+

Privacy Protection Requirements

+

Smart home

+

Biometric information (such as fingerprints, voiceprints, facial recognition, and irises) and user passwords involved in security products are sensitive personal data. They shall be processed using technical measures (for example, extracting the digest of biometric information) before being encrypted and stored in the products.

+

Smart home

+

For security products that involve audio, video, and images, their manufacturers, functioning as the data controller, shall provide an independent privacy notification and a brand log on their application UI. Transfer and storage of audio and video data shall be encrypted. Access to audio and video data of security products is permitted only after being authorized by the data subject.

+

Smart home/Entertainment

+

Cameras on products should be able to be physically disabled. For example, cameras can be hidden, shuttered, or re-oriented so that consumers can perceive that the cameras are disabled.

+

Smart home/Entertainment

+

Products with a microphone should provide an explicit display of the recording status. For example, the products can provide a status indicator that blinks when recording is started and turns off when recording is stopped.

+

Mobile office

+

In scenarios such as cross-device display and transfer of user data, your products shall obtain explicit consent from users and give them full control over their personal data.

+

In-vehicle infotainment (IVI)

+

1. Privacy notice and permission settings

+

Do not let users read privacy policies and permission settings in the driving state.

+

IVI applications shall consider the safety of vehicle use. The applications shall not require complex permission settings or reading of privacy policies when users are driving. For example, HiCar is usable only after users have set basic permissions and read privacy policies on their mobile phone.

+

The privacy statement shall be notified after the user identity is confirmed.

+

Vehicle data involves vehicle owners, drivers, and passengers. The data subject shall be notified of the privacy statement. The recommended practice is to make a privacy statement after confirming the user identity. For an application that requires login, the privacy statement should be displayed after, instead of before, a user is logged in.

+

2. Personal data protection for sharing applications

+

Shared applications shall exit after the IVI is restarted, and the personal data of the current user shall be cleared or encrypted. The applications shall also provide the function to permanently delete historical data.

+

3. Notifications

+

As the IVI is used in an open environment, applications shall not directly display the message content on the IVI. Instead, the applications shall only notify users that there is an incoming message.

+
+ diff --git a/en/device-dev/security/privacy-protection.md b/en/device-dev/security/privacy-protection.md deleted file mode 100644 index c386470726ad799da888fd14bc371b95a9eaa82f..0000000000000000000000000000000000000000 --- a/en/device-dev/security/privacy-protection.md +++ /dev/null @@ -1,264 +0,0 @@ -# Privacy Protection - -- [Overview](#section13200134331414) -- [Data Classification](#section2371104991511) -- [General Privacy Design Rules](#section10354102411162) -- [Privacy Protection Requirements for Special Categories](#section118861450201618) - -## Overview - -Personal data plays an increasingly important role in social economy and daily life along with the development of the Internet and informatization. Meanwhile, personal data leakage risks are increasing. As consumer product developers, you shall take more effective measures to protect users' personal data and improve their trust in your products. To protect consumers' privacy and improve their experience on privacy, you should set high-level privacy protection policies for your product. - -**Basic Concepts** - -- **Personal data** - - Any information relating to an identified or identifiable natural person \("Data Subject"\) who can be identified, directly or indirectly, in particular by reference to an identifier such as a name, an identification number, location data, an online identifier or to one or more factors specific to the physical, physiological, genetic, mental, commercial, cultural, or social identity of that natural person. Personal data includes a natural person's email address, phone number, biometric information \(such as a fingerprint\), location data, IP address, healthcare information, religious belief, social security number, marital status, and so on. - -- **Sensitive personal data** - - Sensitive personal data, a critical subset of personal data, refers to the most private information of a data subject or information that may cause severe adverse impacts on a data subject once disclosed. Sensitive personal data defined in laws and regulations of EU and its members includes personal data revealing racial or ethnic origin, political opinions, religious or philosophical beliefs, trade-union membership, genetic data, biometric information, and data concerning health or sex life and sexual orientation. - - With reference to industry best practices, we also define the following data related to a natural person's identity as sensitive: bank card number, identification number, passport number, and passwords. More strict protection measures are usually required for processing sensitive personal data. - -- **Public available personal data** - - Personal data that is proactively disclosed by a data subject or that can be accessed on public web pages or applications, including posts and comments made on forums. - -- **User profile** - - Any form of automated processing of personal data to assess a natural person in specific aspects, and in particular to analyze and predict the natural person's work performance, financial situation, health, personal preference, interest, creditability, behavior, and location or trace. - -- **Data controller** - - A natural or legal person, public authority, agency, or any other body that, alone or jointly with others, determines the purposes and means of personal data processing. - -- **Data processor** - - A natural or legal person, public authority, agency, or any other body that processes personal data on behalf of a data controller. A data processor must provide adequate protection following the data controller's requirements. - -- **Explicit consent** - - Explicit consent applies to the following scenarios where the General Data Protection Regulation \(GDPR\) allows the legitimate processing of personal data based on data subjects' explicit consent: - - - Processing of sensitive personal data - - Automated decision-making, including user profiles - - Transfer of personal data to countries without an adequate level of protection, which uses consent as the legal basis - - Explicit consent can be implemented as follows: - - - In the collection of specific data, display a privacy statement to notify data subjects of matters related to the processing of personal data, provide a check box which is deselected by default, and prompt data subjects to proactively select the option indicating that "I agree to process my personal data in the above manner" or click the "I agree" button. - - Expressly present consent in writing and request data subjects to sign it. - - Ask data subjects to upload an electronic form with their signature in the system. - - Adopt the double verification method by requesting data subjects to consent via an email and then re-click the email link for verification or enter the SMS verification code. - - Users provide information proactively, such as scenarios where a user enters their identification number and bank card number to bind the bank card. - - -## Data Classification - -Data is classified into five levels: very high, high, moderate, low, and public based on the data protection objectives and consequences \(the impact of legal risks caused by data leakage or damage on individuals, organizations, or the public\). - -**Table 1** Standards for data classification - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Level

-

Privacy Risk

-

Privacy Attribute

-

Typical Example

-

Very high

-

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a catastrophic negative impact on that individual or group of individuals.

-

Sensitive personal data

-

DNA, race, religious belief, and sexual orientation; biometric information; original communication content; bank account password and magnetic track data

-

High

-

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a severe negative impact on that individual or group of individuals.

-

Sensitive personal data

-

Social identity (such as ID card and passport number); web browsing history; tracks; content (such as images, audio, and video) uploaded to the cloud

-

Moderate

-

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a significant negative impact on that individual or group of individuals.

-

General personal data

-

Device ID (such as IMEI, SN, and OAID) and user ID; basic personal information (name and address); mobile number and email address

-

Low

-

Once data is identified or associated with an individual or group of individuals, its disclosure or improper use may have a limited negative impact on that individual or group of individuals.

-

General personal data

-

OS settings (including the OS version and country/region); device hardware information (device model, screen size, and screen resolution); network information (network connection status and access network information); device status (login time/duration)

-

Public

-

Public data has no adverse impact on individuals or organizations.

-

Non-personal data

-

Publicly released product introduction, public meeting information, and external open-source code

-
- -Note: For details about the definitions of privacy protection and data classification, see GDPR. - -## General Privacy Design Rules - -To help you better complete privacy design for OpenHarmony products, we sort out general privacy design requirements. - -**Openness and Transparency in Data Collection and Use** - -When collecting personal data, clearly and explicitly notify users of the data to collect and how their personal data will be used. - -- Develop specific privacy processing policies for personal data at different levels. - - Explicit consent shall be obtained from the data subject before your product attempts to collect sensitive personal data. - - Generally, the collection of personal data requires the consent of the data subject or other legal authorizations. - - If non-personal data is to be collected in association with personal data at the moderate, high, or very high level, the data subject's consent or other legal authorization is required, and the consent or authorization shall be presented in the privacy statement. - -- Develop and follow appropriate privacy policies. Comply with all applicable laws, policies, and regulations when collecting, using, retaining, and sharing users' personal data with any third parties. For example, prior to data collection, fully inform users of the types, purposes, processing methods, and retention periods of personal data to meet the requirements of data subjects' rights. - - Guided by the preceding principles, we have designed some examples for your reference. The figures below are examples of a privacy notice and a privacy statement, respectively. - - **Figure 1** Examples of a privacy notice and a privacy statement - - - ![](figures/2-应用启动预授权.png)![](figures/3-应用隐私声明.png) - -- Personal data shall be collected for specified, explicit, and legitimate purposes and not further processed in a manner that is incompatible with those purposes. If the purposes are changed or a user withdraws their consent, you shall obtain user consent again before using the data. The figures below are examples of a privacy statement update and content withdrawal, respectively. - - **Figure 2** Example dialog showing a privacy statement update - - - ![](figures/4-隐私声明变更通知.png) - - **Figure 3** Example dialog showing consent withdrawal - - - ![](figures/6-1-隐私声明撤销.png)![](figures/6-2-隐私声明撤销.png) - -- You shall provide an entry for users to view the privacy statement. For example, you can provide an entry on the **About** page of your application to view the privacy statement, as shown in the following figure. - - **Figure 4** Example of About page providing an entry to the privacy statement - - - ![](figures/5-应用隐私声明入口.png) - - -**Minimization in Data Collection and Use** - -Collect personal data only when they are adequate, relevant, and limited to what is necessary in relation to the purposes for which they are processed. Apply anonymization or pseudonymization to personal data if possible to reduce the risks to the data subjects concerned. Data shall only be collected and processed for a specified purpose, and no further unnecessary operations shall be conducted on them. - -- When applying for sensitive permissions, adhere to permission minimization and apply for only the permissions required for obtaining necessary information or resources. For example, if your application can implement its functions without access to the camera, then it shall not request the user for the camera permission. -- Comply with data collection minimization, and do not collect data irrelevant to services provided by the product. For example, a product that provides location services shall not collect users' web browsing history. -- The functions that use personal data shall be able to benefit users. The collected data shall not be used for functions irrelevant to users' normal use. No data shall be collected for any functions irrelevant to user operations. For example, sensitive personal data, such as biometric features and health data, shall not be used for non-core service functions like service improvement, advertising, and marketing. -- Printing sensitive personal data in logs is prohibited. If common personal data needs to be printed in logs, make sure the data is anonymized or pseudonymized. - - Preferentially use identifiers that are resettable. For example, use the NetworkID and DVID as the device identifier in the distributed scenario; use the [OAID](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/oaid-0000001050783198) in the advertising scenario; use the [ODID](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/odid-0000001051063255) and [AAID](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/aaid-0000001051142988) in the application-based analysis scenario; and use the UUID in other scenarios where a unique identifier is required. Use permanent identifiers such as the sequence number and MAC address only when resettable identifiers cannot meet your service requirements. - - -**Data Processing Selection and Control** - -You shall obtain consent from users and comply with applicable laws and regulations for processing personal data and give users full control over their data. - -- When applying for a certain sensitive permission, your product shall display a pop-up dialog to notify the user of the requested permission and the purpose of using the permission. The user shall be able to choose whether to grant the permission and how they would like to grant the permission. This ensures that permission granting and use are transparent, perceivable, and controllable. The following figure is an example dialog for requesting a sensitive permission. - - **Figure 5** Example dialog for requesting a sensitive permission - - - ![](figures/1-敏感权限弹窗.png) - -- Users shall have the right to modify or withdraw the permissions granted to your product. When a user does not agree to a permission or data collection, the user shall be allowed to use the functions irrelevant to the permission or data collection. For example, the user can refuse to grant the camera permission to social or communication apps on Smart TVs, when using product functions irrelevant to the camera, such as voice calls. -- In scenarios where personal data is recorded, users shall be provided with the functions of adding, deleting, modifying, and viewing personal data. -- Your products shall provide a mechanism or method for securely deleting personal data when hardware is recycled or returned to the factory. -- The download or upgrade of user system software or application software may involve the modification of users' private space. Users shall have the right to know and control such behavior. They shall be informed of such behavior and be given the option to agree or disagree with such behavior. - -**Data Security** - -Data processing security shall be ensured in technical terms, which include encrypted data storage and secure data transfer. Security mechanisms or measures shall be enabled by default for a system. - -- A protection mechanism shall be available for personal data access, including identity authentication and access control. Identity authentication \(such as username and password\) allows only authenticated users to access data in multi-user scenarios. Access control \(for example, [permission control](security-guidelines.md#li201725506375)\) can be applied to restrict access to applications. -- Secure storage of personal data on distributed devices must meet Huawei Universal Keystore \(HUKS\) requirements, including secure storage of keys and data. -- The transfer of personal data between distributed devices must meet the trust binding relationship between devices and security requirements of data transmission channels. For details, see [Security Guidelines](security-guidelines.md#section26153183616). -- Authentication data \(such as passwords and fingerprints\) shall be encrypted before being stored. - -**Localization** - -User data shall be preferentially processed on the local device. Data that cannot be processed on the local device shall be preferentially processed on Device+ \(super device in the distributed scenario\). If any data cannot be processed on Device+, the data shall be anonymized before being transferred out of Device+ for processing. - -**Minors' Data Protection** - -If your product is designed for minors or you can identify, based on the collected user age data, that the end user is a minor, you shall particularly analyze issues related to minors' personal data protection based on relevant national laws in the target market. Your product shall obtain explicit consent from the holders of parental responsibility over minors. - -## **Privacy Protection Requirements for Special Categories** - -In addition to these general privacy requirements, consumer hardware products have the following requirements for special categories. You shall comply with these requirements during product design. - -**Table 2** Privacy protection requirements for special categories - - - - - - - - - - - - - - - - - - - - - - - - - -

Product Category

-

Privacy Protection Requirements

-

Smart home

-

Biometric information (such as fingerprints, voiceprints, facial recognition, and irises) and user passwords involved in security products are sensitive personal data. They shall be processed using technical measures (for example, extracting the digest of biometric information) before being encrypted and stored in the products.

-

Smart home

-

For security products that involve audio, video, and images, their manufacturers, functioning as the data controller, shall provide an independent privacy notification and a brand log on their application UI. Transfer and storage of audio and video data shall be encrypted. Access to audio and video data of security products is permitted only after being authorized by the data subject.

-

Smart home/Entertainment

-

Cameras on products should be able to be physically disabled. For example, cameras can be hidden, shuttered, or re-oriented so that consumers can perceive that the cameras are disabled.

-

Smart home/Entertainment

-

Products with a microphone should provide an explicit display of the recording status. For example, the products can provide a status indicator that blinks when recording is started and turns off when recording is stopped.

-

Mobile office

-

In scenarios such as cross-device display and transfer of user data, your products shall obtain explicit consent from users and give them full control over their personal data.

-

In-vehicle infotainment (IVI)

-

1. Privacy notice and permission settings

-

Do not let users read privacy policies and permission settings in the driving state.

-

IVI applications shall consider the safety of vehicle use. The applications shall not require complex permission settings or reading of privacy policies when users are driving. For example, HiCar is usable only after users have set basic permissions and read privacy policies on their mobile phone.

-

The privacy statement shall be notified after the user identity is confirmed.

-

Vehicle data involves vehicle owners, drivers, and passengers. The data subject shall be notified of the privacy statement. The recommended practice is to make a privacy statement after confirming the user identity. For an application that requires login, the privacy statement should be displayed after, instead of before, a user is logged in.

-

2. Personal data protection for sharing applications

-

Shared applications shall exit after the IVI is restarted, and the personal data of the current user shall be cleared or encrypted. The applications shall also provide the function to permanently delete historical data.

-

3. Notifications

-

As the IVI is used in an open environment, applications shall not directly display the message content on the IVI. Instead, the applications shall only notify users that there is an incoming message.

-
- diff --git a/en/device-dev/security/public_sys-resources/icon-caution.gif b/en/device-dev/security/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/security/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/device-dev/security/public_sys-resources/icon-danger.gif b/en/device-dev/security/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/security/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/device-dev/security/public_sys-resources/icon-note.gif b/en/device-dev/security/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/device-dev/security/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/device-dev/security/public_sys-resources/icon-notice.gif b/en/device-dev/security/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/device-dev/security/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/device-dev/security/public_sys-resources/icon-tip.gif b/en/device-dev/security/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/device-dev/security/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/device-dev/security/public_sys-resources/icon-warning.gif b/en/device-dev/security/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/security/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/device-dev/security/safety-safeguide-security.md b/en/device-dev/security/safety-safeguide-security.md new file mode 100644 index 0000000000000000000000000000000000000000..bc0933021d484d046df7d54fa1de239b99deb195 --- /dev/null +++ b/en/device-dev/security/safety-safeguide-security.md @@ -0,0 +1,275 @@ +# Security Guidelines + +- [Overview](#section1521410017353) +- [Hardware Security](#section2558121318351) + - [Mechanism](#section1399511541896) + - [Recommended Practices](#section948519243104) + +- [System Security](#section87802111361) + - [Mechanism](#section149107611118) + - [Recommended Practices](#section1364122019112) + +- [Data Security](#section2468927364) + - [Mechanism](#section1378993720111) + - [Recommended Practices](#section1531735481112) + +- [Device Interconnection Security](#section26153183616) +- [Application Security](#section852593153614) + - [Mechanism](#section55012136125) + - [Recommended Practices](#section6341102610123) + + +## Overview + +OpenHarmony is an open OS that allows you to easily develop services and applications. It provides an execution environment to ensure security of application data and user data. + +This environment combines chip security and system security features with upper-layer security services to secure hardware, the system, data, device interconnection, applications, and updates. + +**Figure 1** Security assurance framework +![](figure/security-assurance-framework.png "security-assurance-framework") + +## Hardware Security + +### Mechanism + +- Boot root of trust + + OpenHarmony devices use the public key infrastructure \(PKI\) to protect software integrity and ensure that the software source is valid and the software is not tampered with. + + In the device boot process, software signature verification is performed at each phase to form a secure boot chain. If signature verification fails at any phase, the device boot will be terminated. The hardware or software entity that initially performs signature verification in the secure boot chain is the boot root of trust. It must be valid and should not be tampered with. The boot root of trust can be a built-in code segment in the read-only memory \(ROM\). This code segment is written in the chip during the chip manufacturing and cannot be modified later. When the device is powered on and initialized, this code segment is executed first and used to verify software signatures. + + When you use the code for signature verification, ensure the validity of the PKI public keys. OpenHarmony devices use a storage medium such as eFUSE and one-time password \(OTP\) to store the public keys \(for example, their hash values\) and guarantee their validity. A public key is usually programed into the eFuse or OTP of a device during device manufacturing. + +- Hardware-isolated trusted environment + + The hardware-isolated trusted environment complies with the design concept of the trusted computing system. There is a clear boundary between the trusted environment and untrusted one. OpenHarmony devices protect core sensitive data in the trusted environment. Even if OS vulnerabilities in the untrusted environment are exploited, sensitive data in the trusted environment is secure. + + The trusted environment of OpenHarmony devices is built based on a hardware security isolation mechanism. The chip isolation mechanism varies slightly on different OpenHarmony devices, and the most common mechanism is Arm TrustZone. On some RISC-V chip platforms, independent security cores may also be used to build a trusted environment. + + A specific, simplified OS iTrustee lite runs in the trusted environment to manage resources and schedule tasks in the environment and provide security services for OpenHarmony devices. Key management and data security are the most common security services in the trusted environment. A device has a unique hardware root key in the eFuse/OTP. Based on this root key and service context, the trusted environment generates multiple keys that provide key management and data encryption/decryption services for applications. During their whole lifecycle, core keys of devices stay in the trusted environment. The trusted environment also provides security services such as identity authentication, system status monitoring, and secure data storage to enhance device security. + +- Hardware key engine + + Cryptography is the basis of information security. Data encryption/decryption requires high efficiency and security of computing devices. Hardware encryption/decryption technologies use computer hardware to assist or even replace software to encrypt or decrypt data. Hardware-based encryption/decryption is more efficient and secure than software-based encryption/decryption. + + Since some dedicated hardware resources are used for data encryption/decryption, the CPU can concurrently execute other computing tasks, which greatly improves performance and reduces the CPU load. In addition, a well-designed hardware key engine protects keys from leak even if the software is cracked and even defends against electromagnetic and radiation attacks from physical channels. + + OpenHarmony devices support the hardware key engine, which allows OpenHarmony to perform computing tasks such as data encryption and decryption, certificate signature verification, and hash value calculation. The hardware key engine supports popular algorithms such as Advanced Encryption Standard \(AES\) and Rivest-Shamir-Adleman \(RSA\). + + +### Recommended Practices + +- The boot root of trust consists of a built-in code segment in the chip and the root key of the device. The root of trust is written into the chip during manufacturing and cannot be modified in the device lifecycle. It is used to verify software certificates in the device boot process. The root key is the public key matching the private key of the device certificate signature. The private key is maintained on the PKI signature server and the public key is written to the device. To prevent attackers from tampering with the public key to bypass signature authentication, you can write the public key to media such as fuses on OpenHarmony devices. Considering that the fuse space is limited, you can store only the hash value of the public key in the fuse and verify the validity of the public key using the boot code. +- Generally, a trusted execution environment \(TEE\) is built based on the Arm TrustZone technology, and can also adopt other isolation mechanisms, such as TrustZone-M and independent security cores, depending on the device form. A TEE OS must be deployed in the TEE to manage resources and schedule tasks. OpenHarmony provides iTrustee as the TEE OS. You can develop and deploy security services based on iTrustee. + + Not all OpenHarmony devices need to support the TEE, for example, some devices with thin resources that run less sensitive services may not need the TEE. You can choose whether to support the TEE and how to implement the TEE based on service requirements. + +- The hardware key engine must provide key algorithms related to true random numbers, public keys, symmetric keys, and hash values. By deploying required drivers in OpenHarmony, you can provide unified key management and key algorithms for applications. + +## System Security + +### Mechanism + +For devices with 128 KB to 128 MB of memory, the OpenHarmony lite kernel is recommended. It provides the following features: + +- Process isolation + + Process isolation prevents processes from reading and writing memory data of each other. Generally, virtual address space mapping is used for process isolation. The virtual addresses of two processes are mapped to physical address segments using the memory management unit \(MMU\). In this way, the non-shared memory data that can be accessed by one of the two processes through the virtual address is inaccessible to the other process. + + Due to limited resources, OpenHarmony adopts different mechanisms for kernel-level and user-level processes. All kernel-level processes share the same VMM space, that is, kernel-level processes are not isolated from each other. When the OS is booted, two basic kernel-level processes KProcess and KIdle are created. KProcess is the root process of kernel-level process, and KIdle is the subprocess of KProcess. Each user-level process has its own VMM space that is invisible to other processes, and user-level processes are isolated from each other. + +- Discretionary access control + + Discretionary access control \(DAC\) means that the file owner determines access permissions of other roles. There are three granularities of permission control: user, group, and other \(UGO\). The file owner can classify any user into one of the three dimensions and adopt a control policy to perform DAC permission verification. + + DAC depends on the attributes of processes, such as the UID and GID, which are used as feature IDs during file creation and access. When creating a file, the creator writes its UID into the file. When a file is accessed, the UID is used for classifying the file. + + Each application has a UID. When creating a file, an application adds its UID to the metadata of the file and sets permissions of the user, group, and other. When an application tries to access the file, the UID and permissions in the metadata of the file are used to verify the application UID. + + The following figure shows how DAC works when a process accesses a file. The DAC first matches the process UID with the file UID, and then the process GID with the file GID. If the UID and GID both fail to match, DAC checks the **other** attribute of the file to determine whether the process is allowed to read, write, or execute the file. In addition, the system supports a privileged capability that is not subject to DAC mechanism \(read, write, and execute\) and can access files directly. Services with high permissions \(such as system services\) can manage files of applications with low permissions \(such as third-party applications\). + + **Figure 2** How DAC works + ![](figure/how-dac-works.png "how-dac-works") + +- Capability mechanism + + The capability mechanism is a subdivision of the root permission. A multi-user computer system usually has a special role that has all system permissions, that is, the system administrator with the root permission. OpenHarmony needs to support kernels of the third-party application ecosystem, and privileged access to the system must be controlled. The system needs to restrict privileged system calls made by users to access the kernel. Only some applications with high-level permissions are allowed to perform privileged operations. To be specific, the kernel spawns the first user program INIT that has all privileged permissions. Then INIT starts other application framework services and retains only privileged permissions necessary for each application. When an application requests to call a privileged API, the kernel checks whether the application has the permission to access the API based on the process ID. + +- Secure boot + + Secure boot is the basis of system security. A digital signature and integrity verification mechanism is used to verify the integrity and validity of software at each layer, starting from the boot root of trust in the chip. This ensures that a correct and valid OS is booted, preventing attackers from tampering with or implanting system software and providing a secure, basic running environment. + + The chip does not need to be verified after it is powered on because the on-chip ROM code cannot be modified. The on-chip ROM verifies the bootloader based on the public key hash value which is calculated using the asymmetric algorithm in eFuse. The verification is performed based on the hardware trust root and is fully trusted. The bootloader that passes this verification is deemed to be trusted for subsequent use. This is the process of constructing a trust chain. Bootloader initializes the execution environment, including initializing the double data rate \(DDR\) and reading and writing the flash memory, to prepare for loading modules and executing more complex logic. After the bootloader is initialized, it verifies the integrity of the X.509 certificate and verifies image packages \(**kernel.bin**, **teeOS.bin**, and **rootfs.bin**\) using the public key of the X.509 certificate. + + +### Recommended Practices + +- DAC and the capability mechanism are used to control who can access resources. It is recommended that the minimum permissions are granted. +- Secure boot must be enabled, and the trusted root must be in the chip and cannot be modified. In addition, you must consider the impact of secure upgrade \(if available\) on secure boot, that is, the signature or hash value of an image file must be updated after a secure upgrade. + +## Data Security + +### Mechanism + +Huawei Universal Keystore Service \(HUKS\) provides key and certificate management. For OpenHarmony, it mainly provides key management for HiChain \(the device identity authentication platform\). The following figure shows the functions of HUKS + +**Figure 3** HUKS functions +![](figure/huks-functions.png "huks-functions") + +The following algorithms are supported: + +- Authentication and encryption: AES-128/192/256-GCM +- Signature verification: ED25519 +- Key negotiation: X25519 +- Message authentication: HMAC-SHA256/512 +- Data digest: SHA256/512 + +HUKS has the following restrictions: + +- Secure storage of keys: Keys must be stored in a secure area and cannot be modified. When factory settings are restored, preset keys are not deleted. +- Key access security: OpenHarmony stores different data of an application separately to implement data isolation in the application, and includes the UID and process ID in the parameter structure to implement data isolation between different applications. +- Concurrent access is not supported, that is, multiple applications cannot invoke HUKS simultaneously. As HUKS is a single library, resource exclusion is not a concern. If multiple applications need to use HUKS, each of them needs to connect to a HUKS library and pass a path for storing data. Data is stored in the directory of each application. + +### Recommended Practices + +To use the device certification function, it is recommended that you use HiChain to interconnect with HUKS. HUKS provides applications such as HiChain with key generation, import, export, encryption/decryption, storage, and destruction, certificate import and query, and secret information storage. + +## Device Interconnection Security + +To transmit user data securely between devices, ensure that the devices are trusted by each other. A trust relationship and a secure data transmission channel must be established between the devices. This section describes how an IoT controller and IoT device establish a trust relationship. The following figure shows how an IoT controller and an IoT device establish a trust relationship. + +**Figure 4** How an IoT controller and an IoT device establish a trust relationship +![](figure/how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship.png "how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship") + +- **IoT device interconnection security** + + A trust relationship can be established between an IoT device that runs OpenHarmony \(such as an AI speaker, smart home device, and wearable\) and an IoT controller. Encrypted user data is transmitted between the IoT device and IoT controller through a secure connection. + + +- **IoT service identifier of the IoT controller** + + An IoT controller generates different identifiers for different IoT device management services to isolate these services. The identifier can be used for authentication and communication between an IoT controller and an IoT device. It is an Ed25519 public/private key pair generated using the elliptic curve cryptography. + + +- **IoT device identifier** + + An IoT device can generate its own device identifier for communicating with the IoT controller. It is also an Ed25519 public/private key pair generated using elliptic curve cryptography, with the private key stored on the IoT device. Each time the device is restored to factory settings, the public/private key pair will be reset. + + The identifier can be used for secure communication between the IoT controller and IoT device. After the devices exchange the service identifier or device identifier, they can negotiate the key and establish a secure communication channel. + + +- **P2P trusted binding between devices** + + When an IoT controller and an IOT device establish a trust relationship, they exchange identifiers. + + During this process, the user needs to enter or scan the PIN provided by the IoT device on the IoT controller. PIN is either dynamically generated if the IoT device has a screen, or preset by the manufacturer if it does not have a screen. A PIN can be a number or a QR code. Then the IoT controller and IoT device perform authentication and session key exchange based on password authenticated key exchange \(PAKE\), and use the session key to encrypt the channel for exchanging identity public keys. + + +- **Secure communication between the IoT controller and IoT device** + + When an IoT controller and an IoT device communicate with each other after establishing a trust relationship, they authenticate each other by using the locally stored identity public key of the peer. Bidirectional identity authentication and session key exchange are performed using the Station-to-Station \(STS\) protocol during each communication. The session key is used to encrypt the data transmission channel between the devices. + + +## Application Security + +### Mechanism + +- Application signature management + + After developing and debugging an OpenHarmony application, sign the application installation package using a private key, which matches a public key. Generally, the OEM generates a public/private key pair, presets the public key in the device, and stores the private key on a local server that is not connected to the Internet to prevent private key leakage. After you finish developing an application, you can use an external device \(such as a USB flash drive\) to upload the installation package to the server where the private key is stored, calculate the signature, and download the signature to the external device. During application installation, the hash value of the bundle is calculated using the SHA-256 algorithm. The hash value, together with the signature and preset public key, is used for authentication. The application can be installed only after the authentication is successful. + + In addition, the application source must be verified to ensure that the application is from a valid developer. As a developer, you must apply for a development certificate and use it to sign the application you have developed. During application installation, the upper-level certificate stored on the device is used to verify the signature to ensure validity of the developer. + +- Application permission control + + OpenHarmony allows users to install third-party applications and controls calls made by third-party applications to sensitive permissions. When developing an application, you need to declare the sensitive permissions that the application may invoke in the **profile.json** file. The permissions include static and dynamic ones. Static permissions need to be registered during application installation, and dynamic permissions can be invoked only upon user authorization. Authorization modes include system settings, manual authorization by applications, and others. In addition, application signature control is used to ensure that the application installation package has been confirmed by the device vendor. + + **Table 1** OpenHarmony system permissions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

OpenHarmony System Permission

+

Authorization Mode

+

Description

+

ohos.permission.LISTEN_BUNDLE_CHANGE

+

system_grant (static permission)

+

Allows an application to listen for application changes.

+

ohos.permission.GET_BUNDLE_INFO

+

system_grant (static permission)

+

Allows an application to obtain application information.

+

ohos.permission.INSTALL_BUNDLE

+

system_grant (static permission)

+

Allows an application to install applications.

+

ohos.permission.CAMERA

+

user_grant (dynamic permission)

+

Allows an application to use the camera to take photos and record videos at any time.

+

ohos.permission.MODIFY_AUDIO_SETTINGS

+

system_grant (static permission)

+

Allows an application to modify global audio settings, such as the volume and speaker for output.

+

ohos.permission.READ_MEDIA

+

user_grant (dynamic permission)

+

Allows an application to read users' favorite videos.

+

ohos.permission.MICROPHONE

+

user_grant (dynamic permission)

+

Allows an application to use the microphone for audio recording at any time.

+

ohos.permission.WRITE_MEDIA

+

user_grant (dynamic permission)

+

Allows an application to write users' favorite music.

+

ohos.permission.DISTRIBUTED_DATASYNC

+

user_grant (dynamic permission)

+

Allows an application to manage distributed data transmission.

+

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

+

user_grant (dynamic permission)

+

Allows an application to use distributed virtualization features.

+
+ + +### Recommended Practices + +When developing an application, determine what permissions your application needs and register the permissions in the **profile.json** file. Sign the application to ensure that the devices on which the application will be installed can verify its integrity and source. + diff --git a/en/device-dev/security/security-guidelines.md b/en/device-dev/security/security-guidelines.md deleted file mode 100644 index e82aa5c28bd2b6816bc7226b14680cd45a899457..0000000000000000000000000000000000000000 --- a/en/device-dev/security/security-guidelines.md +++ /dev/null @@ -1,271 +0,0 @@ -# Security Guidelines - -- [Overview](#section1521410017353) -- [Hardware Security](#section2558121318351) -- [Mechanism](#section1312953842210) -- [Recommended Practices](#section37901319112311) -- [System Security](#section87802111361) -- [Mechanism](#section1654963052914) -- [Recommended Practices](#section45821048173613) -- [Data Security](#section2468927364) -- [Mechanism](#section11192175813293) -- [Recommended Practices](#section174640713306) -- [Device Interconnection Security](#section26153183616) -- [Application Security](#section852593153614) -- [Mechanism](#section12125105014377) -- [Recommended Practices](#section1641420155381) - -## Overview - -OpenHarmony is an open OS that allows you to easily develop services and applications. It provides an execution environment to ensure security of application data and user data. - -This environment combines chip security and system security features with upper-layer security services to secure hardware, the system, data, device interconnection, applications, and updates. - -**Figure 1** Security assurance framework -![](figures/security-assurance-framework.png "security-assurance-framework") - -## Hardware Security - -## Mechanism - -- Boot root of trust - - OpenHarmony devices use the public key infrastructure \(PKI\) to protect software integrity and ensure that the software source is valid and the software is not tampered with. - - In the device boot process, software signature verification is performed at each phase to form a secure boot chain. If signature verification fails at any phase, the device boot will be terminated. The hardware or software entity that initially performs signature verification in the secure boot chain is the boot root of trust. It must be valid and should not be tampered with. The boot root of trust can be a built-in code segment in the read-only memory \(ROM\). This code segment is written in the chip during the chip manufacturing and cannot be modified later. When the device is powered on and initialized, this code segment is executed first and used to verify software signatures. - - When you use the code for signature verification, ensure the validity of the PKI public keys. OpenHarmony devices use a storage medium such as eFUSE and one-time password \(OTP\) to store the public keys \(for example, their hash values\) and guarantee their validity. A public key is usually programed into the eFuse or OTP of a device during device manufacturing. - -- Hardware-isolated trusted environment - - The hardware-isolated trusted environment complies with the design concept of the trusted computing system. There is a clear boundary between the trusted environment and untrusted one. OpenHarmony devices protect core sensitive data in the trusted environment. Even if OS vulnerabilities in the untrusted environment are exploited, sensitive data in the trusted environment is secure. - - The trusted environment of OpenHarmony devices is built based on a hardware security isolation mechanism. The chip isolation mechanism varies slightly on different OpenHarmony devices, and the most common mechanism is Arm TrustZone. On some RISC-V chip platforms, independent security cores may also be used to build a trusted environment. - - A specific, simplified OS iTrustee lite runs in the trusted environment to manage resources and schedule tasks in the environment and provide security services for OpenHarmony devices. Key management and data security are the most common security services in the trusted environment. A device has a unique hardware root key in the eFuse/OTP. Based on this root key and service context, the trusted environment generates multiple keys that provide key management and data encryption/decryption services for applications. During their whole lifecycle, core keys of devices stay in the trusted environment. The trusted environment also provides security services such as identity authentication, system status monitoring, and secure data storage to enhance device security. - -- Hardware key engine - - Cryptography is the basis of information security. Data encryption/decryption requires high efficiency and security of computing devices. Hardware encryption/decryption technologies use computer hardware to assist or even replace software to encrypt or decrypt data. Hardware-based encryption/decryption is more efficient and secure than software-based encryption/decryption. - - Since some dedicated hardware resources are used for data encryption/decryption, the CPU can concurrently execute other computing tasks, which greatly improves performance and reduces the CPU load. In addition, a well-designed hardware key engine protects keys from leak even if the software is cracked and even defends against electromagnetic and radiation attacks from physical channels. - - OpenHarmony devices support the hardware key engine, which allows OpenHarmony to perform computing tasks such as data encryption and decryption, certificate signature verification, and hash value calculation. The hardware key engine supports popular algorithms such as Advanced Encryption Standard \(AES\) and Rivest-Shamir-Adleman \(RSA\). - - -## Recommended Practices - -- The boot root of trust consists of a built-in code segment in the chip and the root key of the device. The root of trust is written into the chip during manufacturing and cannot be modified in the device lifecycle. It is used to verify software certificates in the device boot process. The root key is the public key matching the private key of the device certificate signature. The private key is maintained on the PKI signature server and the public key is written to the device. To prevent attackers from tampering with the public key to bypass signature authentication, you can write the public key to media such as fuses on OpenHarmony devices. Considering that the fuse space is limited, you can store only the hash value of the public key in the fuse and verify the validity of the public key using the boot code. -- Generally, a trusted execution environment \(TEE\) is built based on the Arm TrustZone technology, and can also adopt other isolation mechanisms, such as TrustZone-M and independent security cores, depending on the device form. A TEE OS must be deployed in the TEE to manage resources and schedule tasks. OpenHarmony provides iTrustee as the TEE OS. You can develop and deploy security services based on iTrustee. - - Not all OpenHarmony devices need to support the TEE, for example, some devices with thin resources that run less sensitive services may not need the TEE. You can choose whether to support the TEE and how to implement the TEE based on service requirements. - -- The hardware key engine must provide key algorithms related to true random numbers, public keys, symmetric keys, and hash values. By deploying required drivers in OpenHarmony, you can provide unified key management and key algorithms for applications. - -## System Security - -## Mechanism - -For devices with 128 KB to 128 MB of memory, the OpenHarmony lite kernel is recommended. It provides the following features: - -- Process isolation - - Process isolation prevents processes from reading and writing memory data of each other. Generally, virtual address space mapping is used for process isolation. The virtual addresses of two processes are mapped to physical address segments using the memory management unit \(MMU\). In this way, the non-shared memory data that can be accessed by one of the two processes through the virtual address is inaccessible to the other process. - - Due to limited resources, OpenHarmony adopts different mechanisms for kernel-level and user-level processes. All kernel-level processes share the same VMM space, that is, kernel-level processes are not isolated from each other. When the OS is booted, two basic kernel-level processes KProcess and KIdle are created. KProcess is the root process of kernel-level process, and KIdle is the subprocess of KProcess. Each user-level process has its own VMM space that is invisible to other processes, and user-level processes are isolated from each other. - -- Discretionary access control - - Discretionary access control \(DAC\) means that the file owner determines access permissions of other roles. There are three granularities of permission control: user, group, and other \(UGO\). The file owner can classify any user into one of the three dimensions and adopt a control policy to perform DAC permission verification. - - DAC depends on the attributes of processes, such as the UID and GID, which are used as feature IDs during file creation and access. When creating a file, the creator writes its UID into the file. When a file is accessed, the UID is used for classifying the file. - - Each application has a UID. When creating a file, an application adds its UID to the metadata of the file and sets permissions of the user, group, and other. When an application tries to access the file, the UID and permissions in the metadata of the file are used to verify the application UID. - - The following figure shows how DAC works when a process accesses a file. The DAC first matches the process UID with the file UID, and then the process GID with the file GID. If the UID and GID both fail to match, DAC checks the **other** attribute of the file to determine whether the process is allowed to read, write, or execute the file. In addition, the system supports a privileged capability that is not subject to DAC mechanism \(read, write, and execute\) and can access files directly. Services with high permissions \(such as system services\) can manage files of applications with low permissions \(such as third-party applications\). - - **Figure 2** How DAC works - ![](figures/how-dac-works.png "how-dac-works") - -- Capability mechanism - - The capability mechanism is a subdivision of the root permission. A multi-user computer system usually has a special role that has all system permissions, that is, the system administrator with the root permission. OpenHarmony needs to support kernels of the third-party application ecosystem, and privileged access to the system must be controlled. The system needs to restrict privileged system calls made by users to access the kernel. Only some applications with high-level permissions are allowed to perform privileged operations. To be specific, the kernel spawns the first user program INIT that has all privileged permissions. Then INIT starts other application framework services and retains only privileged permissions necessary for each application. When an application requests to call a privileged API, the kernel checks whether the application has the permission to access the API based on the process ID. - -- Secure boot - - Secure boot is the basis of system security. A digital signature and integrity verification mechanism is used to verify the integrity and validity of software at each layer, starting from the boot root of trust in the chip. This ensures that a correct and valid OS is booted, preventing attackers from tampering with or implanting system software and providing a secure, basic running environment. - - The chip does not need to be verified after it is powered on because the on-chip ROM code cannot be modified. The on-chip ROM verifies the bootloader based on the public key hash value which is calculated using the asymmetric algorithm in eFuse. The verification is performed based on the hardware trust root and is fully trusted. The bootloader that passes this verification is deemed to be trusted for subsequent use. This is the process of constructing a trust chain. Bootloader initializes the execution environment, including initializing the double data rate \(DDR\) and reading and writing the flash memory, to prepare for loading modules and executing more complex logic. After the bootloader is initialized, it verifies the integrity of the X.509 certificate and verifies image packages \(**kernel.bin**, **teeOS.bin**, and **rootfs.bin**\) using the public key of the X.509 certificate. - - -## Recommended Practices - -- DAC and the capability mechanism are used to control who can access resources. It is recommended that the minimum permissions are granted. -- Secure boot must be enabled, and the trusted root must be in the chip and cannot be modified. In addition, you must consider the impact of secure upgrade \(if available\) on secure boot, that is, the signature or hash value of an image file must be updated after a secure upgrade. - -## Data Security - -## Mechanism - -Huawei Universal Keystore Service \(HUKS\) provides key and certificate management. For OpenHarmony, it mainly provides key management for HiChain \(the device identity authentication platform\). The following figure shows the functions of HUKS - -**Figure 3** HUKS functions -![](figures/huks-functions.png "huks-functions") - -The following algorithms are supported: - -- Authentication and encryption: AES-128/192/256-GCM -- Signature verification: ED25519 -- Key negotiation: X25519 -- Message authentication: HMAC-SHA256/512 -- Data digest: SHA256/512 - -HUKS has the following restrictions: - -- Secure storage of keys: Keys must be stored in a secure area and cannot be modified. When factory settings are restored, preset keys are not deleted. -- Key access security: OpenHarmony stores different data of an application separately to implement data isolation in the application, and includes the UID and process ID in the parameter structure to implement data isolation between different applications. -- Concurrent access is not supported, that is, multiple applications cannot invoke HUKS simultaneously. As HUKS is a single library, resource exclusion is not a concern. If multiple applications need to use HUKS, each of them needs to connect to a HUKS library and pass a path for storing data. Data is stored in the directory of each application. - -## Recommended Practices - -To use the device certification function, it is recommended that you use HiChain to interconnect with HUKS. HUKS provides applications such as HiChain with key generation, import, export, encryption/decryption, storage, and destruction, certificate import and query, and secret information storage. - -## Device Interconnection Security - -To transmit user data securely between devices, ensure that the devices are trusted by each other. A trust relationship and a secure data transmission channel must be established between the devices. This section describes how an IoT controller and IoT device establish a trust relationship. The following figure shows how an IoT controller and an IoT device establish a trust relationship. - -**Figure 4** How an IoT controller and an IoT device establish a trust relationship -![](figures/how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship.png "how-an-iot-controller-and-an-iot-device-establish-a-trust-relationship") - -- **IoT device interconnection security** - - A trust relationship can be established between an IoT device that runs OpenHarmony \(such as an AI speaker, smart home device, and wearable\) and an IoT controller. Encrypted user data is transmitted between the IoT device and IoT controller through a secure connection. - - -- **IoT service identifier of the IoT controller** - - An IoT controller generates different identifiers for different IoT device management services to isolate these services. The identifier can be used for authentication and communication between an IoT controller and an IoT device. It is an Ed25519 public/private key pair generated using the elliptic curve cryptography. - - -- **IoT device identifier** - - An IoT device can generate its own device identifier for communicating with the IoT controller. It is also an Ed25519 public/private key pair generated using elliptic curve cryptography, with the private key stored on the IoT device. Each time the device is restored to factory settings, the public/private key pair will be reset. - - The identifier can be used for secure communication between the IoT controller and IoT device. After the devices exchange the service identifier or device identifier, they can negotiate the key and establish a secure communication channel. - - -- **P2P trusted binding between devices** - - When an IoT controller and an IOT device establish a trust relationship, they exchange identifiers. - - During this process, the user needs to enter or scan the PIN provided by the IoT device on the IoT controller. PIN is either dynamically generated if the IoT device has a screen, or preset by the manufacturer if it does not have a screen. A PIN can be a number or a QR code. Then the IoT controller and IoT device perform authentication and session key exchange based on password authenticated key exchange \(PAKE\), and use the session key to encrypt the channel for exchanging identity public keys. - - -- **Secure communication between the IoT controller and IoT device** - - When an IoT controller and an IoT device communicate with each other after establishing a trust relationship, they authenticate each other by using the locally stored identity public key of the peer. Bidirectional identity authentication and session key exchange are performed using the Station-to-Station \(STS\) protocol during each communication. The session key is used to encrypt the data transmission channel between the devices. - - -## Application Security - -## Mechanism - -- Application signature management - - After developing and debugging an OpenHarmony application, sign the application installation package using a private key, which matches a public key. Generally, the OEM generates a public/private key pair, presets the public key in the device, and stores the private key on a local server that is not connected to the Internet to prevent private key leakage. After you finish developing an application, you can use an external device \(such as a USB flash drive\) to upload the installation package to the server where the private key is stored, calculate the signature, and download the signature to the external device. During application installation, the hash value of the bundle is calculated using the SHA-256 algorithm. The hash value, together with the signature and preset public key, is used for authentication. The application can be installed only after the authentication is successful. - - In addition, the application source must be verified to ensure that the application is from a valid developer. As a developer, you must apply for a development certificate and use it to sign the application you have developed. During application installation, the upper-level certificate stored on the device is used to verify the signature to ensure validity of the developer. - -- Application permission control - - OpenHarmony allows users to install third-party applications and controls calls made by third-party applications to sensitive permissions. When developing an application, you need to declare the sensitive permissions that the application may invoke in the **profile.json** file. The permissions include static and dynamic ones. Static permissions need to be registered during application installation, and dynamic permissions can be invoked only upon user authorization. Authorization modes include system settings, manual authorization by applications, and others. In addition, application signature control is used to ensure that the application installation package has been confirmed by the device vendor. - - **Table 1** OpenHarmony system permissions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

OpenHarmony System Permission

-

Authorization Mode

-

Description

-

ohos.permission.LISTEN_BUNDLE_CHANGE

-

system_grant (static permission)

-

Allows an application to listen for application changes.

-

ohos.permission.GET_BUNDLE_INFO

-

system_grant (static permission)

-

Allows an application to obtain application information.

-

ohos.permission.INSTALL_BUNDLE

-

system_grant (static permission)

-

Allows an application to install applications.

-

ohos.permission.CAMERA

-

user_grant (dynamic permission)

-

Allows an application to use the camera to take photos and record videos at any time.

-

ohos.permission.MODIFY_AUDIO_SETTINGS

-

system_grant (static permission)

-

Allows an application to modify global audio settings, such as the volume and speaker for output.

-

ohos.permission.READ_MEDIA

-

user_grant (dynamic permission)

-

Allows an application to read users' favorite videos.

-

ohos.permission.MICROPHONE

-

user_grant (dynamic permission)

-

Allows an application to use the microphone for audio recording at any time.

-

ohos.permission.WRITE_MEDIA

-

user_grant (dynamic permission)

-

Allows an application to write users' favorite music.

-

ohos.permission.DISTRIBUTED_DATASYNC

-

user_grant (dynamic permission)

-

Allows an application to manage distributed data transmission.

-

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

-

user_grant (dynamic permission)

-

Allows an application to use distributed virtualization features.

-
- - -## Recommended Practices - -When developing an application, determine what permissions your application needs and register the permissions in the **profile.json** file. Sign the application to ensure that the devices on which the application will be installed can verify its integrity and source. - diff --git a/en/device-dev/subsystems/Readme-EN.md b/en/device-dev/subsystems/Readme-EN.md index 4af4610ea81173dbfb4ee9b937151a95834b5575..0b5b089be53af344a0d020fcb114ed8d829c76fd 100644 --- a/en/device-dev/subsystems/Readme-EN.md +++ b/en/device-dev/subsystems/Readme-EN.md @@ -1,95 +1,74 @@ -# Subsystems - -- [Compilation and Building](compilation-and-building.md) - - [Building Guidelines for Mini and Small Systems](building-guidelines-for-mini-and-small-systems.md) - - [Compilation and Building Overview](compilation-and-building-overview.md) - - [Compilation and Building Guidelines](compilation-and-building-guidelines.md) - - [Compilation and Building FAQ](compilation-and-building-faq.md) - - - [Building Guidelines for the Standard System](building-guidelines-for-the-standard-system.md) - - [Compilation and Building Overview](compilation-and-building-overview-0.md) - - [Compilation and Building Guidelines](compilation-and-building-guidelines-1.md) - -- [Distributed Remote Startup](distributed-remote-startup.md) -- [Graphics](graphics.md) - - [Graphics](graphics-2.md) - - [Development Guidelines on Container Components](development-guidelines-on-container-components.md) - - [Development Guidelines on Layout Container Components](development-guidelines-on-layout-container-components.md) - - [Development Guidelines on Common Components](development-guidelines-on-common-components.md) - - [Development Guidelines on Animators](development-guidelines-on-animators.md) - -- [Multimedia](multimedia.md) - - [Camera](camera.md) - - [Overview](overview.md) - - [Development Guidelines on Photographing](development-guidelines-on-photographing.md) - - [Development Guidelines on Video Recording](development-guidelines-on-video-recording.md) - - [Development Guidelines on Previewing](development-guidelines-on-previewing.md) - - - [Audio/Video](audio-video.md) - - [Overview](overview-3.md) - - [Development Guidelines on Media Playback](development-guidelines-on-media-playback.md) - - [Development Guidelines on Media Recording](development-guidelines-on-media-recording.md) - -- [Utils](utils.md) - - [Utils Overview](utils-overview.md) - - [Utils Development Guidelines](utils-development-guidelines.md) - - [Utils FAQ](utils-faq.md) - -- [AI Framework](ai-framework.md) - - [AI Engine Framework](ai-engine-framework.md) - - [Development Environment](development-environment.md) - - [Technical Specifications](technical-specifications.md) - - [Code Management](code-management.md) - - [Naming](naming.md) - - [API Development](api-development.md) - - - [Development Guidelines](development-guidelines.md) - - [SDK](sdk.md) - - [Plug-in](plug-in.md) - - [Configuration File](configuration-file.md) - - - [Development Examples](development-examples.md) - - [KWS SDK](kws-sdk.md) - - [KWS Plug-in](kws-plug-in.md) - - [KWS Configuration File](kws-configuration-file.md) - -- [Sensors](sensors.md) - - [Sensors Overview](sensors-overview.md) - - [Sensors Usage Guidelines](sensors-usage-guidelines.md) - - [Sensors Usage Example](sensors-usage-example.md) - -- [Application Framework](application-framework.md) - - [Overview](overview-4.md) - - [Setting Up a Development Environment](setting-up-a-development-environment.md) - - [Development Guidelines](development-guidelines-5.md) - - [Development Example](development-example.md) - -- [OTA Upgrade](ota-upgrade.md) -- [Security](security.md) - - [Overview](overview-9.md) - - [Development Guidelines on Application Signature Verification](development-guidelines-on-application-signature-verification.md) - - [Development Guidelines on Application Permission Management](development-guidelines-on-application-permission-management.md) - - [Development Guidelines on IPC Authentication](development-guidelines-on-ipc-authentication.md) - -- [Startup](startup.md) - - [Startup](startup-10.md) - - [init Module](init-module.md) - - [appspawn Module](appspawn-module.md) - - [bootstrap Module](bootstrap-module.md) - - [syspara Module](syspara-module.md) - - [FAQs](faqs.md) - - [Reference](reference.md) - -- [Testing](testing.md) -- [DFX](dfx.md) - - [DFX](dfx-11.md) - - [Development Guidelines on HiLog ](development-guidelines-on-hilog.md) - - [Development Guidelines on HiLog\_Lite](development-guidelines-on-hilog_lite.md) - - [Development Guidelines on HiSysEvent](development-guidelines-on-hisysevent.md) - -- [R&D Tools](r-d-tools.md) - - [bytrace Usage Guidelines](bytrace-usage-guidelines.md) - - [hdc\_std Usage Guidelines](hdc_std-usage-guidelines.md) - -- [XTS](xts.md) - +# Subsystems + +- [Compilation and Building](subsys-build.md) + - [Building Guidelines for Mini and Small Systems](subsys-build-mini-lite.md) + - [Building Guidelines for Standard Systems](subsys-build-standard-large.md) +- [Distributed Remote Startup](subsys-remote-start.md) +- [Graphics](subsys-graphics.md) + - [Graphics](subsys-graphics-overview.md) + - [Development Guidelines on Container Components](subsys-graphics-bundle-guide1.md) + - [Development Guidelines on Layout Container Components](subsys-graphics-bundle-guide2.md) + - [Development Guidelines on Common Components](subsys-graphics-bundle-guide3.md) + - [Development Guidelines on Animators](subsys-graphics-animation-guide.md) +- [Multimedia](subsys-multimedia.md) + - [Camera](subsys-multimedia-camera.md) + - [Overview](subsys-multimedia-camera-overview.md) + - [Development Guidelines on Photographing](subsys-multimedia-camera-photo-guide.md) + - [Development Guidelines on Video Recording](subsys-multimedia-camera-record-guide.md) + - [Development Guidelines on Previewing](subsys-multimedia-camera-preview-guide.md) + - [Audio/Video](subsys-multimedia-video.md) + - [Overview](subsys-multimedia-video-overview.md) + - [Development Guidelines on Media Playback](subsys-multimedia-video-play-guide.md) + - [Development Guidelines on Media Recording](subsys-multimedia-video-record-guide.md) +- [Utils](subsys-utils.md) + - [Utils Overview](oem_subsys_utils_des.md) + - [Utils Development Guidelines](oem_subsys_utils_guide.md) + - [Utils FAQ](oem_subsys_utils_faq.md) +- [AI Framework](subsys-aiframework.md) + - [AI Engine Framework](subsys-aiframework-guide.md) + - [Development Environment](subsys-aiframework-envbuild.md) + - [Technical Specifications](subsys-aiframework-tech.md) + - [Code Management](subsys-aiframework-tech-codemanage.md) + - [Naming](subsys-aiframework-tech-name.md) + - [API Development](subsys-aiframework-tech-interface.md) + - [Development Guidelines](subsys-aiframework-devguide.md) + - [SDK](subsys-aiframework-devguide-sdk.md) + - [Plug-in](subsys-aiframework-devguide-plugin.md) + - [Configuration File](subsys-aiframework-devguide-conf.md) + - [Development Examples](subsys-aiframework-demo.md) + - [KWS SDK](subsys-aiframework-demo-sdk.md) + - [KWS Plug-in](subsys-aiframework-demo-plugin.md) + - [KWS Configuration File](subsys-aiframework-demo-conf.md) +- [Sensors](subsys-sensor.md) + - [Sensors Overview](subsys-sensor-overview.md) + - [Sensors Usage Guidelines](subsys-sensor-guide.md) + - [Sensors Usage Example](subsys-sensor-demo.md) +- [Application Framework](subsys-application-framework.md) + - [Overview](subsys-application-framework-overview.md) + - [Setting Up a Development Environment](subsys-application-framework-builden.md) + - [Development Guidelines](subsys-application-framework-guide.md) + - [Development Example](subsys-application-framework-demo.md) +- [OTA Upgrade](subsys-ota-guide.md) +- [Security](subsys-security.md) + - [Overview](subsys-security-overview.md) + - [Development Guidelines on Application Signature Verification](subsys-security-sigverify.md) + - [Development Guidelines on Application Permission Management](subsys-security-rightmanagement.md) + - [Development Guidelines on IPC Authentication](subsys-security-communicationverify.md) +- [Startup](subsys-boot.md) + - [Startup](subsys-boot-overview.md) + - [init Module](subsys-boot-init.md) + - [appspawn Module](subsys-boot-appspawn.md) + - [bootstrap Module](subsys-boot-bootstrap.md) + - [syspara Module](subsys-boot-syspara.md) + - [FAQs](subsys-boot-faqs.md) + - [Reference](subsys-boot-ref.md) +- [Testing](subsys-testguide-test.md) +- [DFX](subsys-dfx.md) + - [DFX](subsys-dfx-overview.md) + - [Development Guidelines on HiLog ](subsys-dfx-hilog-rich.md) + - [Development Guidelines on HiLog\_Lite](subsys-dfx-hilog-lite.md) + - [Development Guidelines on HiSysEvent](subsys-dfx-hisysevent.md) +- [R&D Tools](subsys-toolchain.md) + - [bytrace Usage Guidelines](subsys-toolchain-bytrace-guide.md) + - [hdc\_std Usage Guidelines](oem_subsys_toolchain_hdc_guide.md) +- [XTS](subsys-xts-guide.md) \ No newline at end of file diff --git a/en/device-dev/subsystems/ai-engine-framework.md b/en/device-dev/subsystems/ai-engine-framework.md deleted file mode 100644 index e5e3a40291288b075be04cb4d88f61e3dcabfd7f..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/ai-engine-framework.md +++ /dev/null @@ -1,9 +0,0 @@ -# AI Engine Framework - -The AI subsystem of OpenHarmony provides native distributed AI capabilities. At the heart of the subsystem is a unified AI engine framework, which implements quick integration of AI algorithm plug-ins. The framework consists of the plug-in management, module management, and communication management modules, fulfilling lifecycle management and on-demand deployment of AI algorithms. Plug-in management implements lifecycle management, on-demand deployment, and quick integration of AI algorithm plug-ins. Module management implements task scheduling and client instance management. Communication management implements inter-process communication \(IPC\) between the client and server and data transmission between the AI engine and plug-ins. Under this framework, AI algorithm APIs will be standardized to facilitate distributed calling of AI capabilities. In addition, unified inference APIs will be provided to adapt to different inference framework hierarchies. [Figure 1](#fig143186187187) shows the AI engine framework. - -**Figure 1** AI engine framework - - -![](figures/en-us_image_0000001077727032.png) - diff --git a/en/device-dev/subsystems/ai-framework.md b/en/device-dev/subsystems/ai-framework.md deleted file mode 100644 index 87f4c6a5f2656a15b063933d1556c90942520fd0..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/ai-framework.md +++ /dev/null @@ -1,13 +0,0 @@ -# AI Framework - -- **[AI Engine Framework](ai-engine-framework.md)** - -- **[Development Environment](development-environment.md)** - -- **[Technical Specifications](technical-specifications.md)** - -- **[Development Guidelines](development-guidelines.md)** - -- **[Development Examples](development-examples.md)** - - diff --git a/en/device-dev/subsystems/application-framework.md b/en/device-dev/subsystems/application-framework.md deleted file mode 100644 index d58ed3003a09c0d1e1194097353e454d85afa061..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/application-framework.md +++ /dev/null @@ -1,11 +0,0 @@ -# Application Framework - -- **[Overview](overview-4.md)** - -- **[Setting Up a Development Environment](setting-up-a-development-environment.md)** - -- **[Development Guidelines](development-guidelines-5.md)** - -- **[Development Example](development-example.md)** - - diff --git a/en/device-dev/subsystems/audio-video.md b/en/device-dev/subsystems/audio-video.md deleted file mode 100644 index 16e2f5b0835dbade41d9c722ab0ff5de90d93b1f..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/audio-video.md +++ /dev/null @@ -1,9 +0,0 @@ -# Audio/Video - -- **[Overview](overview-3.md)** - -- **[Development Guidelines on Media Playback](development-guidelines-on-media-playback.md)** - -- **[Development Guidelines on Media Recording](development-guidelines-on-media-recording.md)** - - diff --git a/en/device-dev/subsystems/building-guidelines-for-mini-and-small-systems.md b/en/device-dev/subsystems/building-guidelines-for-mini-and-small-systems.md deleted file mode 100644 index d19baae14741babb44e57557e6b94a6e47401d91..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/building-guidelines-for-mini-and-small-systems.md +++ /dev/null @@ -1,9 +0,0 @@ -# Building Guidelines for Mini and Small Systems - -- **[Compilation and Building Overview](compilation-and-building-overview.md)** - -- **[Compilation and Building Guidelines](compilation-and-building-guidelines.md)** - -- **[Compilation and Building FAQ](compilation-and-building-faq.md)** - - diff --git a/en/device-dev/subsystems/building-guidelines-for-the-standard-system.md b/en/device-dev/subsystems/building-guidelines-for-the-standard-system.md deleted file mode 100644 index bbc92d83896d1912837d2d34b0791a4e47e46004..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/building-guidelines-for-the-standard-system.md +++ /dev/null @@ -1,7 +0,0 @@ -# Building Guidelines for the Standard System - -- **[Compilation and Building Overview](compilation-and-building-overview-0.md)** - -- **[Compilation and Building Guidelines](compilation-and-building-guidelines-1.md)** - - diff --git a/en/device-dev/subsystems/bytrace-usage-guidelines.md b/en/device-dev/subsystems/bytrace-usage-guidelines.md deleted file mode 100644 index 8219a014385d8d29fc7eecc7c5fbb6ac9671f6c3..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/bytrace-usage-guidelines.md +++ /dev/null @@ -1,119 +0,0 @@ -# bytrace Usage Guidelines - -- [Overview](#section11388623181619) -- [Development Guidelines](#section1595564317164) - - [bytrace Commands](#section2344125731617) - - [Example Commands](#section5402591174) - - -## Overview - -bytrace is a tool for you to trace processes and analyze performance. It encapsulates and extends the kernel ftrace and supports event tracking in the user space. With bytrace, you can open a user-space or kernel-space label you want to view \(run the **bytrace -l** command to query all the supported labels\) and run the **--trace\_begin** and **-o filename** \(or **--output filename**\) commands to capture traces and dump them to a specified file. - -## Development Guidelines - -### bytrace Commands - -bytrace supports the following commands: - -**Table 1** Commands - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Option

-

Description

-

-h, --help

-

Views the help text for bytrace.

-

-b n, --buffer_size n

-

Sets the size of the buffer (KB) for storing and reading traces. The default buffer size is 2048 KB.

-

-t n, --time n

-

Sets the bytrace uptime in seconds, which depends on the time required for analysis.

-

--trace_clock clock

-

Sets the type of the clock for adding a timestamp to a trace, which can be boot (default), global, mono, uptime, or perf.

-

--trace_begin

-

Starts capturing traces.

-

--trace_dump

-

Dumps traces to a specified position (console where you run this command by default).

-

--trace_finish

-

Stops capturing traces and dumps traces to a specified position (console where you run this command by default).

-

-l, --list_categories

-

Lists the bytrace categories supported by the device.

-

--overwrite

-

Sets the action to take when the buffer is full. If this option is used, the latest traces are discarded; if this option is not used, the earliest traces are discarded (default).

-

-o filename, --output filename

-

Outputs traces to a specified file.

-

-z

-

Compresses a captured trace.

-
- -### Example Commands - -The following are some examples of bytrace commands: - -- Run the following command to query supported labels: - -``` -bytrace -l -``` - -Alternatively, you can run the following command: - -``` -bytrace --list_categories -``` - -- Run the following command to capture traces whose label is ability, with the buffer size set to 4096 KB and bytrace uptime set to 10s: - -``` -bytrace -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace -``` - -- Run the following command to set the clock type for traces to **mono**: - -``` -bytrace --trace_clock mono -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace -``` - -- Run the following command to compress the captured trace: - -``` -bytrace -z -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace -``` - diff --git a/en/device-dev/subsystems/camera.md b/en/device-dev/subsystems/camera.md deleted file mode 100644 index 4d38a63f4b587145b7d3fd953ae217a6576393dc..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/camera.md +++ /dev/null @@ -1,11 +0,0 @@ -# Camera - -- **[Overview](overview.md)** - -- **[Development Guidelines on Photographing](development-guidelines-on-photographing.md)** - -- **[Development Guidelines on Video Recording](development-guidelines-on-video-recording.md)** - -- **[Development Guidelines on Previewing](development-guidelines-on-previewing.md)** - - diff --git a/en/device-dev/subsystems/code-management.md b/en/device-dev/subsystems/code-management.md deleted file mode 100644 index 6dde40c04806b61c22c53c8192ac869fa505f094..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/code-management.md +++ /dev/null @@ -1,40 +0,0 @@ -# Code Management - -- [Recommendation: Develop plug-ins and northbound SDKs in the directories specified by the AI engine.](#section17176374131) -- [Rule: Store all external APIs provided by plug-ins in the interfaces/kits directory of the AI subsystem.](#section2551029111312) -- [Rule: Make sure that plug-in compilation results are stored in the /usr/lib directory.](#section97021558121310) - -Code of the AI engine framework consists of three parts: **client**, **server**, and **common**. The client module provides the server connection management function. The northbound SDK needs to encapsulate and call the public APIs provided by the client in the algorithm's external APIs. The server module provides functions such as plug-in loading and task management. Plug-ins are integrated using the plug-in APIs provided by the server. The common module provides platform-related operation methods, engine protocols, and tool classes for other modules. - -[Figure 1](#fig171811112818) shows the code dependency between modules of the AI engine framework. - -**Figure 1** Code dependency - - -![](figures/插件依赖-(2).jpg) - -## Recommendation: Develop plug-ins and northbound SDKs in the directories specified by the AI engine. - -In the overall planning of the AI engine framework, northbound SDKs are a part of the client, and plug-ins are called by the server and are considered a part of the server. Therefore, the following directories have been planned for plug-in and northbound SDK development in the AI engine framework: - -- SDK code directory: //foundation/ai/engine/services/client/algorithm\_sdk - - e.g. //foundation/ai/engine/services/client/algorithm\_sdk/cv - - e.g. //foundation/ai/engine/services/client/algorithm\_sdk/nlu - -- Plug-in code directory: //foundation/ai/engine/services/server/plugin - - e.g. //foundation/ai/engine/services/server/plugin/cv - - e.g. //foundation/ai/engine/services/server/plugin/nlu - - -## Rule: Store all external APIs provided by plug-ins in the **interfaces/kits** directory of the AI subsystem. - -The AI subsystem exposes its capabilities through external APIs of northbound SDKs. According to API management requirements of OpenHarmony, store all external APIs of northbound SDKs in the **interfaces/kits** directory of the subsystem. Currently, the external APIs of plug-ins of the AI subsystem are stored in the following directory: **//foundation/ai/engine/interface/kits**. You can add a sub-directory for each newly added plug-in in this directory. For example, if you add a CV plug-in, then store its external APIs in the **//foundation/ai/engine/interfaces/kits/cv** directory. - -## Rule: Make sure that plug-in compilation results are stored in the **/usr/lib** directory. - -Plug-in loading on the server uses the dlopen mode and can only be performed in the **/usr/lib** directory. Therefore, when compiling the **.so** file of a plug-in, set the output directory as **/usr/lib** in the compilation configuration file. - diff --git a/en/device-dev/subsystems/compilation-and-building-faq.md b/en/device-dev/subsystems/compilation-and-building-faq.md deleted file mode 100644 index 7c90a77cafe15b19f2bdcfbbc9d976158b83be9c..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-faq.md +++ /dev/null @@ -1,121 +0,0 @@ -# Compilation and Building FAQ - -- [Invalid -- w option](#section1019152312222) -- [Ncurses library not found](#section21449422618) -- [Mcopy not found](#section12477184992615) -- [No riscv file or directory](#section178451337202716) -- [No Crypto](#section1241481172819) -- [Unexpected operator](#section3691222152919) - -## Invalid -- w option - -- **Problem** - - The compilation fails, and **usr/sbin/ninja: invalid option -- w** is displayed. - -- **Cause** - - The Ninja version in the compilation environment is outdated and does not support the **--w** option. - -- **Solution** - - Uninstall Ninja and GN and follow the instructions provided in [Acquiring Tools](../get-code/tool-acquisition.md) to obtain the provided compilation toolchain. - - -## Ncurses library not found - -- **Problem** - - The compilation fails, and **/usr/bin/ld: cannot find -lncurses** is displayed. - -- **Cause** - - The ncurses library is not installed. - -- **Solution** - - ``` - sudo apt-get install lib32ncurses5-dev - ``` - - -## Mcopy not found - -- **Problem** - - The compilation fails, and **line 77: mcopy: command not found** is displayed. - -- **Cause** - - Mcopy is not installed. - -- **Solution** - - ``` - ​sudo apt-get install dosfstools mtools - ``` - - -## No riscv file or directory - -- **Problem** - - The compilation fails, and the following information is displayed: **riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory**. - -- **Cause** - - Permission is required to access files in the **riscv** compiler path. - -- **Solution** - 1. Run the following command to query the directory where **gcc\_riscv32** is located: - - ``` - which riscv32-unknown-elf-gcc - ``` - - 2. Run the **chmod** command to change the directory permission to **755**. - - -## No Crypto - -- **Problem** - - The compilation fails, and **No module named'Crypto loaded** is displayed. - -- **Cause** - - Crypto is not installed in Python 3. - -- **Solution** - 1. Run the following command to query the Python version: - - ``` - python3 --version - ``` - - 2. Ensure that Python 3.7 or later is installed, and then run the following command to install pycryptodome: - - ``` - sudo pip3 install pycryptodome - ``` - - - -## Unexpected operator - -- **Problem** - - The compilation fails, and **xx.sh \[: xx unexpected operator** is displayed. - -- **Cause** - - The compilation environment is shell instead of bash. - -- **Solution** - - ``` - sudo rm -rf /bin/sh - sudo ln -s /bin/bash /bin/sh - ``` - - diff --git a/en/device-dev/subsystems/compilation-and-building-guidelines-1.md b/en/device-dev/subsystems/compilation-and-building-guidelines-1.md deleted file mode 100644 index eddc2c96aaefe399e0c46c7d47eb3810ab59f67a..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-guidelines-1.md +++ /dev/null @@ -1,174 +0,0 @@ -# Compilation and Building Guidelines - -- [Directory Structure](#section56731811102915) -- [Building](#section1069873833818) - - [Build Command](#section2740182614395) - -- [How to Develop](#section4207112818418) - -## Directory Structure - -``` -/build # Primary directory -├── config # Build configuration items -├── core -│ └── gn # Build entry configuration -├── loader # Loader of module configuration, which also generates a template for the module -├── ohos # Configuration of the process for building and packaging OpenHarmony -│ ├── kits # Build and packaging templates and processing flow for kits -│ ├── ndk # NDK template and processing flow -│ ├── notice # Notice template and processing flow -│ ├── packages # Distribution packaging template and processing flow -│ ├── sa_profile # SA template and processing flow -│ ├── sdk # SDK template and processing flow, which contains the module configuration in the SDK -│ └── testfwk # Processing flow related to the test -├── scripts # Build-related Python script -├── templates # C/C++ build templates -└── toolchain # Toolchain configuration -``` - -## Building - -### Build Command - -- Run the following command in the root directory of the source code to build the full distribution: - - ``` - ./build.sh --product-name {product_name} - ``` - - **product\_name** indicates the product supported by the current distribution, for example, Hi3516D V300. - - The image generated after build is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - -- The build command supports the following options: - - ``` - --product-name # (Mandatory) Name of the product to build, for example, Hi3516D V300 - --build-target # (Optional) One or more build targets - --gn-args # (Optional) One or more gn parameters - --ccache # (Optional) Use of Ccache for build. This option takes effect only when Ccache is installed on the local PC. - ``` - - -## How to Develop - -1. Add a module. - - The following steps use a custom module as an example to describe how to build the module, including build a library, an executable file, and a configuration file. - - The example module **partA** consists of **feature1**, **feature2**, and **feature3**. The target of **feature1** is a dynamic library, that of **feature2** is an executable file, and that of **feature3** is an etc configuration file. - - Add **partA** to a subsystem, for example, **subsystem\_examples** \(defined in the **test/examples/** directory\). - - The complete directory structure of **partA** is as follows: - - ``` - test/examples/partA - ├── feature1 - │ ├── BUILD.gn - │ ├── include - │ │ └── helloworld1.h - │ └── src - │ └── helloworld1.cpp - ├── feature2 - │ ├── BUILD.gn - │ ├── include - │ │ └── helloworld2.h - │ └── src - │ └── helloworld2.cpp - └── feature3 - ├── BUILD.gn - └── src - └── config.conf - ``` - - Example 1: GN script \(**test/examples/partA/feature1/BUILD.gn**\) for building a dynamic library - - ``` - config("helloworld_lib_config") { - include_dirs = [ "include" ] - } - - ohos_shared_library("helloworld_lib") { - sources = [ - "include/helloworld1.h", - "src/helloworld1.cpp", - ] - public_configs = [ ":helloworld_lib_config" ] - part_name = "partA" - } - ``` - - Example 2: GN script \(**test/examples/partA/feature2/BUILD.gn**\) for building an executable file - - ``` - ohos_executable("helloworld_bin") { - sources = [ - "src/helloworld2.cpp" - ] - include_dirs = [ "include" ] - deps = [ # Dependent submodule - "../feature1:helloworld_lib" - ] - external_deps = [ "partB:module1" ] # (Optional) If there is a cross-module dependency, the format is "module name: submodule name" - install_enable = true # By default, the executable file is not installed. You need to set this parameter to true for installation. - part_name = "partA" - } - ``` - - Example 3: GN script \(**test/examples/partA/feature3/BUILD.gn**\) for building the etc configuration file \(submodule\). - - ``` - ohos_prebuilt_etc("feature3_etc") { - source = "src/config.conf" - relative_install_dir = "init" # (Optional) Directory for installing the submodule, which is relative to the default installation directory (/system/etc) - part_name = "partA" - } - ``` - - Example 4: Adding the module configuration file **test/examples/ohos.build** to the **ohos.build** file of this subsystem. Each subsystem has an **ohos.build** file in its root directory. - - ``` - "partA": { - "module_list": [ - "//test/examples/partA/feature1:helloworld_lib", - "//test/examples/partA/feature2:helloworld_bin", - "//test/examples/partA/feature3:feature3_etc", - ], - "inner_kits": [ - - ], - "system_kits": [ - - ], - "test_list": [ - - ] - } - ``` - - The declaration of a module contains the following parts: - - - **module\_list**: submodule list of the module - - **inner\_kits**: APIs for other modules that depend on this module through **external\_deps** - - **system\_kits**: APIs for developers - - **test\_list**: test cases for the submodules of the module - -2. Add the module to the product configuration file. - - Add **"subsystem\_examples:partA"** to the configuration file **productdefine/common/products/\{product-name\}.json** to build and package **partA** into the distribution. - -3. Build the module, including the library, executable file, and etc configuration file. - - For example, run the following command to build Hi3516D V300: - - ``` - ./build.sh --product-name Hi3516DV300 --ccache - ``` - -4. Obtain the build result. - - Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - - diff --git a/en/device-dev/subsystems/compilation-and-building-guidelines.md b/en/device-dev/subsystems/compilation-and-building-guidelines.md deleted file mode 100644 index e89b07bebaaba173dafd27affe843b42d4e0e3f2..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-guidelines.md +++ /dev/null @@ -1,430 +0,0 @@ -# Compilation and Building Guidelines - -- [Prerequisites](#section13333171022312) -- [How to Use the hb Command Line Tool](#section477242204612) -- [Adding a Module](#section4207112818418) -- [Adding a Chipset Solution](#section2737141421917) -- [Adding a Product Solution](#section720881917199) - -## Prerequisites - -Ensure that the development environment has GN, Ninja, Python 3.7.4 or later, and hb commands. For details about installation methods, see [Basic OS Environment Setup](../quick-start/environment-setup.md). - -## How to Use the hb Command Line Tool - -hb is a command line tool for OpenHarmony to execute build commands. Common hb commands are described as follows: - -1. **hb set** - - ``` - hb set -h - usage: hb set [-h] [-root [ROOT_PATH]] [-p] - - optional arguments: - -h, --help show this help message and exit - -root [ROOT_PATH], --root_path [ROOT_PATH] - Set OHOS root path - -p, --product Set OHOS board and kernel - ``` - - - If you run **hb set** with no argument, the default setting process starts. - - You can run **hb set -root** _dir_ to set the root directory of the source code. - - **hb set -p** is used to set the product to build. - -2. **hb env** - - View the current configuration. - - ``` - hb env - [OHOS INFO] root path: xxx - [OHOS INFO] board: hispark_taurus - [OHOS INFO] kernel: liteos - [OHOS INFO] product: ipcamera - [OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera - [OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 - ``` - -3. **hb build** - - ``` - hb build -h - usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] - [--dmverity] [-p PRODUCT] [-f] [-n] - [component [component ...]] - - positional arguments: - component name of the component - - optional arguments: - -h, --help show this help message and exit - -b BUILD_TYPE, --build_type BUILD_TYPE - release or debug version - -t [TEST [TEST ...]], --test [TEST [TEST ...]] - compile test suit - --dmverity Enable dmverity - -p PRODUCT, --product PRODUCT - build a specified product with - {product_name}@{company}, eg: ipcamera@hisilcon - -f, --full full code compilation - -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] - Compile single target - ``` - - - If you run **hb build** with no argument, the previously configured code directory, product, and options are used for the build. The **-f** option will delete all products to be built, which is equivalent to running **hb clean** and **hb build**. - - You can run **hb build** _\{module\_name\}_ to build product modules separately based on the development board and kernel set for the product, for example, **hb build kv\_store**. - - You can run **hb build -p ipcamera@hisilicon** to skip the setting step and compile the product directly. - - You can run **hb build** in **device/device\_company/board** to select the kernel and start the build based on the current development board and the selected kernel to generate an image that contains the kernel and driver only. - -4. **hb clean** - - Clear the build result of the product in the **out** directory, and retain the **args.gn** and **build.log** files only. To clear files in a specified directory, add the directory parameter to the command, for example, **hb clean out/xxx/xxx**. - - ``` - hb clean - usage: hb clean [-h] [out_path] - - positional arguments: - out_path clean a specified path. - - optional arguments: - -h, --help show this help message and exit - ``` - - -## Adding a Module - -To add a module, determine the subsystem to which the module belongs and the module name, and then perform the following steps: - -1. Add the module build script after the source code development is complete. - - The following example adds the **BUILD.gn** script \(stored in the **applications/sample/hello\_world** directory\) to build the **hello\_world** module \(as an executable file\). - - ``` - executable("hello_world") { - include_dirs = [ - "include", - ] - sources = [ - "src/hello_world.c" - ] - } - ``` - - The added script is used to build **hello\_world** that can run on OpenHarmony. - - To build the preceding module separately, select a product via the **hb set** command and run the **-T** command. - - ``` - hb build -f -T //applications/sample/hello_world - ``` - - After the module functions are verified based on the development board, perform steps 2 to 5 to configure the module for the product. - -2. Add the module description. - - The module description is stored in the **build/lite/components** directory. New modules must be added to the JSON file of the corresponding subsystem. A module description must contain the following fields: - - - **module**: name of the module - - **description**: brief description of the module - - **optional**: whether the module is optional - - **dirs**: source code directory of the module - - **targets**: module build entry - - For example, to add the **hello\_world** module to the application subsystem, add the **hello\_world** object to the **applications.json** file. - - ``` - { - "components": [ - { - "component": "hello_world", - "description": "Hello world.", - "optional": "true", - "dirs": [ - "applications/sample/hello_world" - ], - "targets": [ - "//applications/sample/hello_world" - ] - }, - ... - ] - } - ``` - -3. Configure the module for the product. - - The **config.json** file is stored in the **vendor/company/product/** directory. The file must contain the product name, OpenHarmony version, device vendor, development board, kernel type, kernel version, and the subsystem and module to configure. The following example adds the **hello\_world** module to the **my\_product.json** configuration file: - - ``` - { - "product_name": "hello_world_test", - "ohos_version": "OpenHarmony 1.0", - "device_company": "hisilicon", - "board": "hispark_taurus", - "kernel_type": "liteos_a", - "kernel_version": "1.0.0", - "subsystems": [ - { - "subsystem": "applications", - "components": [ - { "component": "hello_world", "features":[] } - ] - }, - ... - ] - } - ``` - -4. Build the product. - - 1. Run the **hb set** command in the root code directory to select the corresponding product. - - 2. Run the **hb build** command. - - -## Adding a Chipset Solution - -The Compilation and Building subsystem allows you to add a chipset solution. Detailed operations are as follows: - -1. Create a directory for the chipset solution. - - Taking the RTL8720 development board of chipset provider Realtek for example, you need to run the following command in the root code directory to create a directory for the chipset solution based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](compilation-and-building-overview.md#section1625463413327). - - ``` - mkdir -p device/realtek/rtl8720 - ``` - -2. Create a directory for kernel adaptation and build the **config.gni** file of the development board. - - The following example adapts the LiteOS Cortex-M kernel to the RTL8720 development board of Realtek. The **device/realtek/rtl8720/liteos\_a/config.gni** file is configured as follows: - - ``` - # Kernel type, e.g. "linux", "liteos_a", "liteos_m". - kernel_type = "liteos_a" - - # Kernel version. - kernel_version = "3.0.0" - - # Board CPU type, e.g. "cortex-a7", "riscv32". - board_cpu = "real-m300" - - # Board arch, e.g. "armv7-a", "rv32imac". - board_arch = "" - - # Toolchain name used for system compiling. - # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. - # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. - board_toolchain = "gcc-arm-none-eabi" - - # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. - board_toolchain_path = - rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", - root_build_dir) - - # Compiler prefix. - board_toolchain_prefix = "gcc-arm-none-eabi-" - - # Compiler type, "gcc" or "clang". - board_toolchain_type = "gcc" - - # Board related common compile flags. - board_cflags = [] - board_cxx_flags = [] - board_ld_flags = [] - ``` - -3. Build the script. - - Create the **BUILD.gn** file in the development board directory. The target name must be the same as that of the development board. Taking the RTL8720 development board of Realtek as an example, the content in the **device/realtek/rtl8720/BUILD.gn** file is configured as follows: - - ``` - group("rtl8720") { # The target can be shared_library, static_library, or an executable file. - # Content - ...... - } - ``` - -4. Build the chipset solution. - - Run the **hb build** command in the development board directory to start the build. - - -## Adding a Product Solution - -The Compilation and Building subsystem supports flexible assembly of chipset solutions and modules to customize desired product solutions. The operation procedure is as follows: - -1. Create a product directory. - - Taking the Wi-Fi IoT module based on the RTL8720 development board as an example, you need to run the following command in the root code directory to create a product directory based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](compilation-and-building-overview.md#section1625463413327). - - ``` - mkdir -p vendor/my_company/wifiiot - ``` - -2. Assemble the product. - - Create the **config.json** file in the product directory. Taking the Wi-Fi IoT module as an example, the **vendor/my\_company/wifiiot/config.json** file is as follows: - - ``` - { - "product_name": "wifiiot", # Product name - "ohos_version": "OpenHarmony 1.0", # In-use OS version - "device_company": "realtek", # Name of the chipset solution vendor - "board": "rtl8720", # Name of the development board - "kernel_type": "liteos_m", # Selected kernel type - "kernel_version": "3.0.0", # Selected kernel version - "subsystems": [ - { - "subsystem": "kernel", # Selected subsystem - "components": [ - { "component": "liteos_m", "features":[] } # Selected module and its features - ] - }, - ... - { - More subsystems and modules - } - ] - } - ``` - - Before the build, the Compilation and Building subsystem will check the validity of fields, including **device\_company**, **board**, **kernel\_type**, **kernel\_version**, **subsystem**, and **component**. The first four fields and the latter two fields must match the current chipset solution and the module description in the **build/lite/components** file, respectively. - -3. Implement adaptation of OS APIs. - - Create the **hals** directory in the product directory and store the source code as well as the build script for OS adaptation in this directory. - -4. Configure the system service. - - Create the **init\_configs** directory in the product directory and then the **init.cfg** file in the newly created directory. You can configure the system service to be started on demand. - -5. Configure the init process \(only for the Linux kernel\). - - You need to create the **etc** directory in the **init\_configs** directory, and then the **init.d** folder as well as the **fstab** file in the newly created directory. In addition, you need to create the **rcS** and **Sxxx** files in the **init.d** file and edit them based on product requirements. - -6. Configure the file system image \(required only for the development board that supports the file system\). - - Create the **fs.yml** file in the product directory and configure it as required. A typical **fs.yml** file is configured as follows: - - ``` - - - fs_dir_name: rootfs # Image name - fs_dirs: - - - # Copy the files in the out/my_board/my_product/bin directory to the rootfs/bin directory and ignore the .bin files related to testing. - source_dir: bin - target_dir: bin - ignore_files: - - Test.bin - - TestSuite.bin - - - # Copy the files in the out/my_board/my_product/libs directory to the rootfs/lib directory, ignore all .a files, and set the permissions on the files and folders to 644 and 755, respectively. - source_dir: libs - target_dir: lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: usr/lib - target_dir: usr/lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: config - target_dir: etc - - - source_dir: system - target_dir: system - - - source_dir: sbin - target_dir: sbin - - - source_dir: usr/bin - target_dir: usr/bin - - - source_dir: usr/sbin - target_dir: usr/sbin - - - # Create an empty proc directory. - target_dir: proc - - - target_dir: mnt - - - target_dir: opt - - - target_dir: tmp - - - target_dir: var - - - target_dir: sys - - - source_dir: etc - target_dir: etc - - - source_dir: vendor - target_dir: vendor - - - target_dir: storage - - fs_filemode: - - - file_dir: lib/ld-uClibc-0.9.33.2.so - file_mode: 555 - - - file_dir: lib/ld-2.24.so - file_mode: 555 - - - file_dir: etc/init.cfg - file_mode: 400 - fs_symlink: - - - # Create the soft link ld-musl-arm.so.1 -> libc.so in the rootfs/lib directory. - source: libc.so - link_name: ${fs_dir}/lib/ld-musl-arm.so.1 - - - source: mksh - link_name: ${fs_dir}/bin/sh - - - source: mksh - link_name: ${fs_dir}/bin/shell - fs_make_cmd: - # Create an ext4 image for the rootfs directory using the script. - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - - - fs_dir_name: userfs - fs_dirs: - - - source_dir: storage/etc - target_dir: etc - - - source_dir: data - target_dir: data - fs_make_cmd: - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - ``` - -7. Build the script. - - Create the **BUILD.gn** file in the product directory and build the script based on your requirements. Taking the Wi-Fi IoT module in step 1 as an example, the **BUILD.gn** is configured as follows: - - ``` - group("wifiiot") { # The target name must be the same as the product name. - deps = [] - # Copy the init configuration. - deps += [ "init_configs" ] - # Build the hals directory. - deps += [ "hals" ] - # Others - ...... - } - ``` - -8. Build the product. - - Run the **hb set** command in the root code directory to select the new product as prompted, and then run the **hb build** command to start the build. - - diff --git a/en/device-dev/subsystems/compilation-and-building-overview-0.md b/en/device-dev/subsystems/compilation-and-building-overview-0.md deleted file mode 100644 index de4d2beab9d8c3f91f9d1ff841af68e9311b0fb6..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-overview-0.md +++ /dev/null @@ -1,60 +0,0 @@ -# Compilation and Building Overview - -- [Basic Concepts](#section175012297491) -- [Working Principles](#section193961322175011) -- [Limitations and Constraints](#section2029921310472) - -The compilation and building subsystem provides a framework based on Generate Ninja \(GN\) and Ninja. This subsystem allows you to: - -- Build products based on different chipset platforms, for example, Hi3516D V300. - -- Package capabilities required by a product by assembling modules based on the product configuration. - -## Basic Concepts - -It is considered best practice to learn the following basic concepts before you start building: - -- **Platform** - - A platform is a combination of development boards and kernels. - - Supported subsystems and modules vary according to the platform. - -- **Subsystems** - - OpenHarmony is designed with a layered architecture, which from bottom to top consists of the kernel layer, system service layer, framework layer, and application layer. System functions are expanded by levels, from system to subsystem, and further to module. In a multi-device deployment scenario, unnecessary subsystems and modules can be excluded from the system as required. A subsystem is a logical concept and is a flexible combination of functions. - -- **Module** - - A module is a reusable software binary unit that contains source code, configuration files, resource files, and build scripts. A module can be built independently, integrated in binary mode, and then tested independently. - -- **GN** - - GN is short for Generate Ninja, which is used to generate Ninja files. - -- **Ninja** - - Ninja is a small high-speed build system. - - -## Working Principles - -The process to build OpenHarmony is as follows: - -- Parsing commands: Parse the name of the product to build and load related configurations. -- Running GN: Configure toolchains and global options based on the parsed product name and compilation type. -- Running Ninja: Start building and generate a product distribution. - -## Limitations and Constraints - -- You must download the source code using method 3 described in [Source Code Acquisition](../get-code/source-code-acquisition.md). -- The build environment must be Ubuntu 18.04 or later. -- You must install the software package required for build. - - The installation command is as follows: - - ``` - sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 - ``` - - diff --git a/en/device-dev/subsystems/compilation-and-building-overview.md b/en/device-dev/subsystems/compilation-and-building-overview.md deleted file mode 100644 index 8cf7a6a1c1459288b1430f022740ef3a229663dd..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-overview.md +++ /dev/null @@ -1,132 +0,0 @@ -# Compilation and Building Overview - -- [Basic Concepts](#section175012297491) -- [Usage Guidelines](#section193961322175011) -- [Limitations and Constraints](#section2029921310472) - -The compilation and building subsystem is a building framework based on Generate Ninja \(GN\) and Ninja, which supports component-based OpenHarmony development. This subsystem can be used to: - -- Build existing products. - -- Build chipset source code independently. -- Build a single component independently. - -## Basic Concepts - -It is considered best practice to learn the following basic concepts before you start development and building: - -- **Component** - - A component is a reusable software unit that can contain source code, configuration files, resource files, and compilation scripts. - -- **GN** - - GN is short for Generate Ninja, which is used to generate Ninja files. - -- **Ninja** - - Ninja is a small high-speed building system. - - -## Usage Guidelines - -1. **Building Process** - - [Figure 1](#fig9744112715161) shows the building process. - - **Figure 1** Building process - ![](figures/building-process.jpg "building-process") - - 1. **hb set**: Set the OpenHarmony source code directory and the product to build. - 2. **hb build**: Build the product, development board, or component. The process to build the solution is as follows: - - **Reading configuration**: Read the development board configuration, which covers the toolchain, linking commands, and compilation options. - - **Running gn**: Run the **gn gen** command to read the product configuration \(related to the development board, kernel, and system components\) and generate the **out** directory and **ninja** files for the solution. - - **Running Ninja**: Run **ninja -C out/company/product** to start compilation. - - **Packaging**: Package the compilation result to create a file system image. - - -2. **Building Commands** - - 1. **hb set** - - ``` - hb set -h - usage: hb set [-h] [-root [ROOT_PATH]] [-p] - - optional arguments: - -h, --help show this help message and exit - -root [ROOT_PATH], --root_path [ROOT_PATH] - Set OHOS root path - -p, --product Set OHOS board and kernel - ``` - - - If you run **hb set** with no argument, the default setting process starts. - - You can run **hb set -root** _dir_ to set the root directory of the source code. - - **hb set -p** is used to set the product to compile. - - 2. **hb env** - - View the current configuration. - - ``` - hb env - [OHOS INFO] root path: xxx - [OHOS INFO] board: hispark_taurus - [OHOS INFO] kernel: liteos - [OHOS INFO] product: ipcamera - [OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera - [OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 - ``` - - 3. **hb build** - - ``` - hb build -h - usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] - [--dmverity] [-p PRODUCT] [-f] [-n] - [component [component ...]] - - positional arguments: - component name of the component - - optional arguments: - -h, --help show this help message and exit - -b BUILD_TYPE, --build_type BUILD_TYPE - release or debug version - -c COMPILER, --compiler COMPILER - specify compiler - -t [TEST [TEST ...]], --test [TEST [TEST ...]] - compile test suite - --dmverity Enable dmverity - -p PRODUCT, --product PRODUCT - build a specified product with - {product_name}@{company}, eg: ipcamera@hisilcon - -f, --full full code compilation - ``` - - - If you run **hb build** with no argument, the previously configured code directory, product, and options are used for the compilation. The **-f** option will delete all products to be compiled, which is equivalent to running **hb clean** and **hb build**. - - You can run **hb build** _\{component\_name\}_ to compile product components separately based on the development board and kernel set for the product, for example, **hb build kv\_store**. - - You can run **hb build -p ipcamera@hisilicon** to skip the setting step and compile the product directly. - - You can run **hb build** in **device/device\_company/board** to select the kernel and start compilation based on the current development board and the selected kernel to generate an image that contains the kernel and driver only. - - 4. **hb clean** - - Clear the compilation result of the product in the **out** directory, and retain the **args.gn** and **build.log** files only. To clear files in a specified directory, add the directory parameter to the command, for example, **hb clean** _xxx_**/out/**_xxx_. - - - ``` - hb clean - usage: hb clean [-h] [out_path] - - positional arguments: - out_path clean a specified path. - - optional arguments: - -h, --help show this help message and exit - ``` - - -## Limitations and Constraints - -Ensure that the development environment has GN and Ninja, Python 3.7.4 and later, and hb commands. You must download the complete code before you start. - diff --git a/en/device-dev/subsystems/compilation-and-building.md b/en/device-dev/subsystems/compilation-and-building.md deleted file mode 100644 index 54f18a521ee33440589cbeab2622d0969d1fb5a6..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building.md +++ /dev/null @@ -1,7 +0,0 @@ -# Compilation and Building - -- **[Building Guidelines for Mini and Small Systems](building-guidelines-for-mini-and-small-systems.md)** - -- **[Building Guidelines for the Standard System](building-guidelines-for-the-standard-system.md)** - - diff --git a/en/device-dev/subsystems/development-environment.md b/en/device-dev/subsystems/development-environment.md deleted file mode 100644 index d8a387f47835f43689d8447fdec9a6f52d4875d3..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-environment.md +++ /dev/null @@ -1,5 +0,0 @@ -# Development Environment - -1. Prepare development boards Hi3516D V300 and Hi3518E V300. -2. [Download the source code](https://device.harmonyos.com/en/docs/start/get-code/oem_sourcecode_guide-0000001050769927#EN-US_TOPIC_0000001050769927__section1186691118430). - diff --git a/en/device-dev/subsystems/development-examples.md b/en/device-dev/subsystems/development-examples.md deleted file mode 100644 index 8c5964da0133ad046694a091a19e95eaad409ed8..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-examples.md +++ /dev/null @@ -1,13 +0,0 @@ -# Development Examples - -For your better understanding, a KWS application is used as an example to walk you through the development process. You can develop the KWS SDK and plug-in based on the AI engine framework on the Hi3516D V300 development board, compile an image for the new version, and burn the image into the version. Then, develop an application with the KWS function. The application can receive external audio and pass the audio to the SDK API. If the audio contains specified keywords, the application will be able to recognize these keywords and print them in the command line. - -This example uses a fixed keyword **Hi, xiaowen** for illustration. If the input audio contains **Hi, xiaowen**, the application prints **\[Hi, xiaowen\]**; otherwise, the application prints **\[UNKNOWN\]**. - -- **[KWS SDK](kws-sdk.md)** - -- **[KWS Plug-in](kws-plug-in.md)** - -- **[KWS Configuration File](kws-configuration-file.md)** - - diff --git a/en/device-dev/subsystems/development-guidelines-5.md b/en/device-dev/subsystems/development-guidelines-5.md deleted file mode 100644 index c86bd7b452bef75e1eeac280e801d80e36ed0d7f..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-5.md +++ /dev/null @@ -1,711 +0,0 @@ -# Development Guidelines - -- [When to Use](#section93012287133) -- [Available APIs](#section11821047161319) -- [How to Develop](#section10514141679) - - [Creating a Service Ability](#section19921154214315) - - [Development Guidelines on Bundle Management](#section1724016743217) - - [Packing a HAP File](#section171771212328) - - -## When to Use - -- Develop Page abilities for applications that have a UI for human-machine interaction, such as news applications, video players, navigation applications, and payment applications. Most applications we use in our daily lives are such type of applications. - -- Develop Service abilities for applications so that they can run particular services in the background, such as music playing, computing, and navigation services. - -- Pack both Page and Service abilities into HarmonyOS Ability Packages \(HAPs\). All applications must be packed into HAP files before being published to the application market. Once published, users can then download the applications from the application market. - -## Available APIs - -**Table 1** APIs of the ability management framework - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

Want *WantParseUri(const char *uri)

-

Converts a specified character string into a Want object.

-

const char *WantToUri(Want want)

-

Converts a specified Want object into a character string.

-

void SetWantElement(Want *want, ElementName element);

-

Sets the element variable for a specified Want object.

-

void SetWantData(Want *want, const void *data, uint16_t dataLength)

-

Sets data to carry in a specified Want object for starting a particular ability.

-

bool SetWantSvcIdentity(Want *want, SvcIdentity sid)

-

Sets the sid member variable for a specified Want object.

-

void ClearWant(Want *want)

-

Clears the memory of a specified Want object.

-

void SetMainRoute(const std::string &entry)

-

Sets the main route for the ability.

-

void SetUIContent(RootView *rootView)

-

Sets the UI layout for the ability.

-

void OnStart(const Want& intent)

-

Called when the ability is started. This callback is invoked to handle transitions between ability lifecycle states.

-

void OnStop()

-

Called when the ability is being destroyed. This callback is invoked to handle transitions between ability lifecycle states.

-

void OnActive(const Want& intent)

-

Called when the ability is visible to users. This callback is invoked to handle transitions between ability lifecycle states.

-

void OnInactive()

-

Called when the ability is invisible to users. This callback is invoked to handle transitions between ability lifecycle states.

-

void OnBackground()

-

Called when the ability is moved to the background. This callback is invoked to handle transitions between ability lifecycle states.

-

const SvcIdentity *OnConnect(const Want &want)

-

Called when the Service ability is connected for the first time.

-

void OnDisconnect(const Want &want);

-

Called when all abilities connected to the Service ability are disconnected.

-

void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply);

-

Handles a message sent by the client to the Service ability.

-

void Dump(const std::string &extra)

-

Prints ability information to the console.

-

void Present(AbilitySlice *abilitySlice, const Want &want)

-

Presents another ability slice.

-

void Terminate()

-

Destroys the ability slice.

-

void SetUIContent(RootView *rootView)

-

Sets the UI layout for the host ability of the ability slice.

-

void OnStart(const Want& want)

-

Called when the ability slice is started. This callback is invoked to handle transitions between ability slice lifecycle states.

-

void OnStop()

-

Called when the ability slice is being destroyed. This callback is invoked to handle transitions between ability slice lifecycle states.

-

void OnActive(const Want& want)

-

Called when the ability slice is visible to users. This callback is invoked to handle transitions between ability slice lifecycle states.

-

void OnInactive()

-

Called when the ability slice is invisible to users. This callback is invoked to handle transitions between ability slice lifecycle states.

-

void OnBackground()

-

Called when the ability slice is moved to the background. This callback is invoked to handle transitions between ability slice lifecycle states.

-

int StartAbility(const Want &want)

-

Starts an ability based on the specified Want information.

-

int StopAbility(const Want &want)

-

Stops a Service ability based on the specified Want information.

-

int TerminateAbility()

-

Destroys the ability.

-

int ConnectAbility(const Want &want, const IAbilityConnection &conn, void *data);

-

Connects to a Service ability based on the specified Want information.

-

int DisconnectAbility(const IAbilityConnection &conn)

-

Disconnects from a Service ability.

-

const char *GetBundleName()

-

Obtains the bundle name of the application to which the ability belongs.

-

const char *GetSrcPath()

-

Obtains the source code path of the ability.

-

const char *GetDataPath()

-

Obtains the data path of the ability.

-

int StartAbility(const Want *want)

-

Starts an Ability. This function does not need to be used in applications developed based on Ability.

-

int ConnectAbility(const Want *want, const IAbilityConnection *conn, void *data);

-

Connects to a Service ability based on the specified Want information. This function does not need to be used in applications developed based on Ability.

-

int DisconnectAbility(const IAbilityConnection *conn);

-

Disconnects from a Service ability. This function does not need to be used in applications developed based on Ability.

-

int StopAbility(const Want *want)

-

Stops a Service ability based on the specified Want information. This function does not need to be used in applications developed based on Ability.

-

void (*OnAbilityConnectDone)(ElementName *elementName, SvcIdentity *serviceSid, int resultCode, void *data)

-

Called when a client is connected to a Service ability.

-

void (*OnAbilityDisconnectDone)(ElementName *elementName, int resultCode, void *data)

-

Called after all connections to a Service ability are disconnected.

-

void PostTask(const Task& task)

-

Posts a task to an asynchronous thread.

-

void PostQuit()

-

Quits the event loop of the current thread.

-

static AbilityEventHandler* GetCurrentHandler()

-

Obtains the event handler of the current thread.

-

void Run()

-

Starts running the event loop of the current thread.

-

#define REGISTER_AA(className)

-

Registers the class name of an Ability child class.

-

#define REGISTER_AS(className)

-

Registers the class name of an AbilitySlice child class.

-
- -## How to Develop - -### Creating a Service Ability - -1. Create the **MyServiceAbility** child class from **Ability** in **my\_service\_ability.h**. - - ``` - class MyServiceAbility: public Ability { - protected: - void OnStart(const Want& want); - const SvcIdentity *OnConnect(const Want &want) override; - void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) override; - }; - ``` - -2. Call the **REGISTER\_AA** macro to register the **ServiceAbility** class with the application framework so that the framework can instantiate the **MyServiceAbility** class you have created. - - ``` - #include "my_service_ability.h" - - REGISTER_AA(ServiceAbility) - - void MyServiceAbility::OnStart(const Want& want) - { - printf("ServiceAbility::OnStart\n"); - Ability::OnStart(want); - } - - const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) - { - printf("ServiceAbility::OnConnect\n"); - return Ability::OnConnect(want); - } - - void MyServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) - { - printf("ServiceAbility::MsgHandle, funcId is %u\n", funcId); - int result = 0; - if (funcId == 0) { - result = IpcIoPopInt32(request) + IpcIoPopInt32(request); - } - // push data - IpcIoPushInt32(reply, result); - } - ``` - -3. Override the following lifecycle callbacks for Service abilities to implement your own logic for your Service ability. When overriding a lifecycle callback, you must call the corresponding function from the parent class. - - OnStart\(\) - - This callback is invoked when a Service ability is being created to perform Service ability initialization operations that take a short time. This callback is invoked only once in the entire lifecycle of a Service ability. - - ``` - void MyServiceAbility::OnStart(const Want& want) - { - printf("ServiceAbility::OnStart\n"); - Ability::OnStart(want); - } - ``` - - - OnConnect\(\) - - This callback is invoked when another ability is connected to the Service ability. This callback returns an **SvcIdentity** object for the other ability to interact with the Service ability. - - ``` - const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) - { - printf("ServiceAbility::OnConnect\n"); - return Ability::OnConnect(want); - } - ``` - - - OnDisconnect​\(\) - - This callback is invoked when another ability is disconnected from the Service ability. - - - OnStop\(\) - - This callback is invoked when a Service ability is destroyed. You should override this callback for your Service ability to clear its resources, such as threads and registered listeners. - - -4. Override the message handling function. - - The **MsgHandle** function is used by Service abilities to handle messages sent from clients. **funcId** indicates the type of the message sent from the client, and **request** indicates the pointer to the serialized request parameters sent from the client. If you want to send the result back after the message is handled, serialize the result and write it into **reply**. - - ``` - void ServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) - { - printf("ServiceAbility::MsgHandle, funcId is %d\n", funcId); - int result = 0; - if (funcId == PLUS) { - result = IpcIoPopInt32(request) + IpcIoPopInt32(request); - } - // push data - IpcIoPushInt32(reply, result); - } - ``` - -5. Register a Service ability. - - Declare your Service ability in the **config.json** file by setting its **type** attribute to **service**. - - ``` - "abilities": [{ - "name": "ServiceAbility", - "icon": "res/drawable/phone.png", - "label": "test app 2", - "launchType": "standard", - "type": "service", - "visible": true - } - ] - ``` - -6. Start a Service ability. - - The **Ability** class provides the **StartAbility\(\)** function to start another ability. You can pass a **Want** object to this function to start a Service ability. - - You can use the **SetWantElement\(\)** function provided in the **AbilityKit** to set information about the target Service ability to start. The **element** parameter of the **SetWantElement\(\)** function indicates the **ElementName** structure that contains the bundle name and target ability name required for starting an ability. - - ``` - { - Want want = { nullptr }; - ElementName element = { nullptr }; - SetElementBundleName(&element, "com.company.appname"); - SetElementAbilityName(&element, "ServiceAbility"); - SetWantElement(&want, element); - StartAbility(want); - ClearElement(&element); - ClearWant(&want); - } - ``` - - The **StartAbility\(\)** function is executed immediately. If the Service ability is not running while the function is called, the system invokes **OnStart\(\)** first. - - - Stops a Service ability. - - Once created, the Service ability keeps running in the background. You can call **StopAbility\(\)** to stop the Service ability. - - -7. Connect to a Service ability. - - If you need to connect a Service ability to a Page ability or to a Service ability in another application, you should first create a Service ability for connection. A Service ability allows other abilities to connect to it through **ConnectAbility\(\)** by passing a **Want** object that contains information about the target Service ability to the function. You can implement callbacks in **IAbilityConnection** to be invoked when a Service ability is connected or disconnected. The **OnAbilityConnectDone\(\)** callback is invoked when an ability is connected, and **OnAbilityDisconnectDone\(\)** is invoked when an ability is disconnected. - - ``` - { - // Create an IAbilityConnection object and implement the two callbacks. - IAbilityConnection abilityConnection = new IAbilityConnection(); - abilityConnection->OnAbilityConnectDone = OnAbilityConnectDone; - abilityConnection->OnAbilityDisconnectDone = OnAbilityDisconnectDone; - - void OnAbilityConnectDone(ElementName *elementName, SvcIdentity *serviceSid, - int resultCode, void *data) - { - if (resultCode != 0) { - return; - } - // Push data. - IpcIo request; - char dataBuffer[IPC_IO_DATA_MAX]; - IpcIoInit(&request, dataBuffer, IPC_IO_DATA_MAX, 0); - IpcIoPushInt32(&request, 10); - IpcIoPushInt32(&request, 6); - - // Send and receive the reply. - IpcIo reply; - uintptr_t ptr = 0; - if (Transact(nullptr, *serviceSid, 0, &request, &reply, - LITEIPC_FLAG_DEFAULT, &ptr) != LITEIPC_OK) { - printf("transact error\n"); - return; - } - int result = IpcIoPopInt32(&reply); - printf("execute add method, result is %d\n", result); - if (ptr != 0) { - FreeBuffer(nullptr, reinterpret_cast(ptr)); - } - } - - void OnAbilityDisconnectDone(ElementName *elementName, - int resultCode, void *data) - { - printf("elementName is %s, %s\n", - elementName->bundleName, elementName->abilityName); - } - } - ``` - - - The following sample code snippet shows how to initiate ability connection and disconnection: - - ``` - { - // Connect an ability to a specified Service ability. - Want want = { nullptr }; - ElementName element = { nullptr }; - SetElementBundleName(&element, "com.company.appname"); - SetElementAbilityName(&element, "ServiceAbility"); - SetWantElement(&want, element); - ConnectAbility(want, *abilityConnection, this); - - // Disconnect from a Service ability. - DisconnectAbility(*abilityConnection); - } - ``` - - - -### Development Guidelines on Bundle Management - -**Installing an Application** - -The installation API can only be used by built-in system applications. Applications can be installed in either of the following paths: - -- Default installation directory **/storage/app/** in the system -- Particular directory on the external storage, for example, a microSD card - -You can specify the installation path when creating an **InstallParam** instance. To install the application in the **/storage/app/** directory, set the **installLocation** member variable in the **InstallParam** instance to **INSTALL\_LOCATION\_INTERNAL\_ONLY**. To install the application in the **/sdcard/app/** directory of the external storage, set **installLocation** to **INSTALL\_LOCATION\_PREFER\_EXTERNAL**. The application installation process is asynchronous, and a semaphore-like mechanism is required to ensure that the installation callback can be executed. - -The procedure for installing an application is as follows \(the system directory is used as an example\): - -1. Place the signed HAP file in a specified directory. -2. Create an **InstallParam** instance and define the semaphore. - - ``` - InstallParam installParam = { - .installLocation = INSTALL_LOCATION_INTERNAL_ONLY, // Install the application in the system directory. - .keepData = false - }; - static sem_t g_sem; - ``` - -3. Define the callback function. - - ``` - static void InstallCallback(const uint8_t resultCode, const void *resultMessage) - { - std::string strMessage = reinterpret_cast(resultMessage); - if (!strMessage.empty()) { - printf("install resultMessage is %s, %d\n", strMessage.c_str(),resultCode); - } - sem_post(&g_sem); - } - ``` - -4. Call the **Install** function. - - ``` - const uint32_t WAIT_TIMEOUT = 30; - sem_init(&g_sem, 0, 0); - std::string installPath = "/storage/bundle/demo.hap"; // Specify the path where the HAP file is stored. - bool result = Install(installPath.c_str(), &installParam, InstallCallback); - struct timespec ts = {}; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += WAIT_TIMEOUT; // Release the semaphore upon timeout. - sem_timedwait(&g_sem, &ts); - ``` - - -**Uninstalling an Application** - -When uninstalling an application, you can specify whether to retain application data using the **keepData** member variable in the created **InstallParam** instance. If **keepData** is set to **true**, the application data will be retained after the application is uninstalled. If the variable is set to **false**, the application data will be removed during application installation. - -1. Create an **InstallParam** instance and define the semaphore. - - ``` - static sem_t g_sem; - InstallParam installParam = { - .installLocation = 1, - .keepData = false // Remove application data. - }; - ``` - -2. Define the callback function. - - ``` - static void UninstallCallback(const uint8_t resultCode, const void *resultMessage) - { - std::string strMessage = reinterpret_cast(resultMessage); - if (!strMessage.empty()) { - printf("uninstall resultMessage is %s\n", strMessage.c_str()); - g_resultMessage = strMessage; - } - g_resultCode = resultCode; - sem_post(&g_sem); - } - ``` - -3. Call the **Uninstall** function. - - ``` - sem_init(&g_sem, 0, 0); - const uint32_t WAIT_TIMEOUT = 30; - std::string BUNDLE_NAME = "com.huawei.demo"; // Bundle name of the application to be uninstalled - Uninstall(BUNDLE_NAME.c_str(), &installParam, UninstallCallback); - struct timespec ts = {}; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += WAIT_TIMEOUT; - sem_timedwait(&g_sem, &ts); - ``` - - -**Querying Bundle Information About an Installed Application** - -You can use the **GetBundleInfo** function provided by **BundleManager** to query the bundle information about installed applications in the system. - -1. Create and initialize a **BundleInfo** object. - - ``` - BundleInfo bundleInfo; - (void) memset_s(&bundleInfo, sizeof(BundleInfo), 0, sizeof(BundleInfo)); - ``` - -2. Call **GetBundleInfo** to obtain bundle information about a specified application. The **bundleName** parameter indicates the pointer to the application bundle name, and the **flags** parameter specifies whether the obtained **BundleInfo** object can contain **AbilityInfo**. - - ``` - std::string BUNDLE_NAME = "com.huawei.demo"; - uint8_t ret = GetBundleInfo(BUNDLE_NAME.c_str(), 1, &bundleInfo); // When flags is set to 1, the obtained BundleInfo object contains AbilityInfo. - ``` - -3. After you finish using the obtained **BundleInfo** object, clear the memory space occupied by the object in a timely manner to prevent memory leakage. - - ``` - ClearBundleInfo(&bundleInfo); - ``` - - -### Packing a HAP File - -The packing tool is generally integrated into the development tool or IDE, and you rarely have the occasion to use it directly. This section is provided for you to have a general knowledge of the packing tool. The JAR file of the packing tool is stored in the **developtools/packing\_tool/jar** directory of the open-source code. - -- CLI command parameters for packing a HAP file - - **Table 2** Description of resource files required for packing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Command Parameter

-

Resource File

-

Description

-

Initial Value Allowed

-

--mode

-

-

-

This parameter is set to hap for packing the resource files into a HAP file.

-

No

-

--json-path

-

Configuration file config.json

-

-

-

No

-

--resources-path

-

Resource file resources

-

-

-

Yes

-

--assets-path

-

Resource file assets

-

-

-

Yes

-

--lib-path

-

Dependent library file

-

-

-

Yes

-

--shared-libs-path

-

Shared library file

-

The shared library is used by system applications in special cases.

-

Yes

-

--ability-so-path

-

SO file providing main functionality

-

-

-

Yes

-

--index-path

-

Resource index

-

The resource index file is generated by the resource generation tool and integrated by the resource pipeline.

-

Yes

-

--out-path

-

-

-

This parameter indicates the output path of the generated HAP file. The default value is the current directory.

-

Yes

-

--force

-

-

-

This parameter specifies whether to overwrite an existing file with the same name. The default value is false.

-

Yes

-
- -- Example HAP File Structure - - Development view - - ![](figures/en-us_image_0000001062942690.png) - - - Compilation view - - ![](figures/en-us_image_0000001062334618.png) - - - Run the following commands to pack a HAP file using the packing tool. - - ![](figures/en-us_image_0000001062476933.png) - - ``` - $ java -jar hmos_app_packing_tool.jar --mode hap --json-path ./config.json --assets-path ./assets/ --ability-so-path ./libentry.so --index-path ./resources.index --out-path out/entry.hap --force true - ``` - - - diff --git a/en/device-dev/subsystems/development-guidelines-on-animators.md b/en/device-dev/subsystems/development-guidelines-on-animators.md deleted file mode 100644 index 0065d820ba5bfe7bd36471475366e9a335908c26..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-animators.md +++ /dev/null @@ -1,190 +0,0 @@ -# Development Guidelines on Animators - -- [When to Use](#section726685714018) -- [Available APIs](#section85794718418) -- [How to Develop](#section14101161317435) - -## When to Use - -A UI animator is implemented by calling the callback function you set for each tick using the task processing mechanism. The following classes are provided for you to implement an animator: - -- **AnimatorManager**: Manages Animator instances. This is a singleton class, which is registered with the system task callback when the **Init** function is executed. The system task mechanism ensures that each tick invokes the callback function of **AnimatorManager**. -- **Animator**: Represents animator-related attributes, including the start and end time of an animator. It also provides animator-specific functions, for example, to start and stop an animator, to set the animator state, and to obtain the animator. -- **AnimatorCallback**: Implements the content of each tick. You need to implement your own logic in this callback class so that the desired operation is executed upon the corresponding callback is invoked. - -## Available APIs - -**Table 1** Available functions for an animator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Module

-

Function

-

Description

-

Animator

-

void Start ()

-

Starts an animator.

-

Animator

-

void Stop ()

-

Stops the animator.

-

Animator

-

void Pause ()

-

Pauses the animator.

-

Animator

-

void Resume ()

-

Resumes the animator.

-

Animator

-

uint8_t GetState () const

-

Obtains the current state of the animator.

-

Animator

-

void SetState (uint8_t state)

-

Sets the current state for the animator.

-

Animator

-

uint32_t GetTime () const

-

Obtains the total duration of the animator.

-

Animator

-

void SetTime (uint32_t time)

-

Sets the total duration for the animator.

-

Animator

-

uint32_t GetRunTime () const

-

Obtains the running time of the animator.

-

Animator

-

void SetRunTime (uint32_t runTime)

-

Sets the running time for the animator.

-

Animator

-

bool IsRepeat () const

-

Checks whether the animator is repeated.

-

AnimatorCallback

-

virtual void Callback (UIView *view)=0

-

Represents the animator callback. You can implement your own logic in this callback.

-

AnimatorCallback

-

virtual void OnStop(UIView& view) {}

-

Called after the animator stops. You can implement your own logic in this callback.

-

AnimatorManager

-

static AnimatorManager* GetInstance()

-

Obtains an AnimatorManager instance.

-

AnimatorManager

-

void Add (Animator *animator)

-

Adds an animator.

-

AnimatorManager

-

void Remove(const Animator* animator);

-

Removes the animator.

-
- -## How to Develop - -1. Implement the callback in **AnimatorCallback**. - - ``` - class AnimatorCallbackDemo : public OHOS::AnimatorCallback { - public: - AnimatorCallbackDemo(int16_t startPos, int16_t endPos, uint16_t time) - : start_(startPos), end_(endPos), time_(time), curTime_(0) {} - - virtual void Callback(OHOS::UIView* view) - { - curTime_++; - int16_t pos = EasingEquation::CubicEaseIn(start_, end_, curTime_, time_); - view->Invalidate(); - view->SetPosition(pos, view->GetY()); - view->Invalidate(); - } - protected: - int16_t start_; - int16_t end_; - uint16_t time_; - uint16_t curTime_; - }; - ``` - -2. Register **AnimatorCallback** to the animator. - - ``` - UIImageView* image = new UIImageView(); - image->SetSrc("..\\config\\images\\A021_001.bin"); - image->SetPosition(0, 50); - AnimatorCallbackDemo* callback = new AnimatorCallbackDemo(0, 338, 60); - Animator* animator = new Animator(callback, image, 0, true); - ``` - -3. Add the animator to **AnimatorManager**. - - ``` - AnimatorManager::GetInstance()->Add(animator); - ``` - -4. Click the buttons in the lower part of the following figure to verify that the animation effects are as expected. - - **Figure 1** Animator effect - ![](figures/animator-effect.gif "animator-effect") - - diff --git a/en/device-dev/subsystems/development-guidelines-on-application-permission-management.md b/en/device-dev/subsystems/development-guidelines-on-application-permission-management.md deleted file mode 100644 index a72a6f889379575bf8b00bf351a3b0a6e539dd9b..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-application-permission-management.md +++ /dev/null @@ -1,228 +0,0 @@ -# Development Guidelines on Application Permission Management - -- [How Application Permission Management Works](#section193961322175011) -- [When to Use](#section18502174174019) -- [Available APIs](#section1633115419401) -- [How to Develop](#section022611498210) - -## How Application Permission Management Works - -OpenHarmony allows users to install third-party applications and controls calls made by third-party applications to sensitive permissions. When developing an application, you need to declare the sensitive permissions that the application may require in the **profile.json** file. The permissions include static and dynamic ones. Static permissions need to be registered during application installation, and dynamic permissions can be obtained only upon user authorization. Authorization modes include system settings, manual authorization by applications, and others. In addition, application signature control is used to ensure that the application installation package has been confirmed by the device vendor. - -**Table 1** OpenHarmony permissions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

OpenHarmony Permission

-

Grant Mode

-

Description

-

ohos.permission.LISTEN_BUNDLE_CHANGE

-

system_grant (static permission)

-

Allows an application to listen for application changes.

-

ohos.permission.GET_BUNDLE_INFO

-

system_grant (static permission)

-

Allows an application to obtain information about other applications.

-

ohos.permission.INSTALL_BUNDLE

-

system_grant (static permission)

-

Allows an application to install other applications.

-

ohos.permission.CAMERA

-

user_grant (dynamic permission)

-

Allows an application to use the camera to take photos and record videos at any time.

-

ohos.permission.MODIFY_AUDIO_SETTINGS

-

system_grant (static permission)

-

Allows an application to modify global audio settings, such as the volume and speaker for output.

-

ohos.permission.READ_MEDIA

-

user_grant (dynamic permission)

-

Allows an application to read users' favorite videos.

-

ohos.permission.MICROPHONE

-

user_grant (dynamic permission)

-

Allows an application to use the microphone for audio recording at any time.

-

ohos.permission.WRITE_MEDIA

-

user_grant (dynamic permission)

-

Allows an application to write users' favorite music.

-

ohos.permission.DISTRIBUTED_DATASYNC

-

user_grant (dynamic permission)

-

Allows an application to manage distributed data transmission.

-

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

-

user_grant (dynamic permission)

-

Allows an application to use distributed virtualization features.

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Static permission: a permission granted by the system during application installation. The sensitivity level of this type of permission is **system\_grant**. ->Dynamic permission: a permission granted by users during application running. The sensitivity level of this type of permission is **user\_grant**. - -## When to Use - -Application permissions are used to control access to system resources and features. In scenarios where an application wants to access features or data related to users' privacy, such as accessing hardware features of personal devices like cameras and microphones, and reading and writing media files, OpenHarmony uses the application permission management component to protect such features and data. - -When developing a system application that requires a sensitive permission, you can call the corresponding API of the application permission management component to check whether the required permission is granted. If the permission is not granted, the application cannot use it. - -## Available APIs - -The following table lists the APIs available for application permission management. These APIs are only intended for system applications and services. - -**Table 2** APIs available for application permission management - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

int CheckPermission(int uid, const char *permissionName)

-

Checks whether the application with a specified UID has the permission to access system service APIs.

-

int CheckSelfPermission(const char *permissionName)

-

Checks whether the caller has the permission to access system service APIs.

-

int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)

-

Queries all permissions requested by the application and checks whether the requested permissions have been granted.

-

int GrantPermission(const char *identifier, const char *permName)

-

Grants a specified permission to the application.

-

int RevokePermission(const char *identifier, const char *permName)

-

Revokes a specified permission from the application.

-

int GrantRuntimePermission(int uid, const char *permissionName)

-

Grants a specified runtime permission to the application.

-

int RevokeRuntimePermission(int uid, const char *permissionName)

-

Revokes a specified runtime permission from the application.

-
- -## How to Develop - -This section uses the BMS as an example to describe the application permission development. Before starting development, you need to declare the required sensitive permissions in the **config.json** file. During application installation, the BMS calls APIs of the application permission management component to check whether the required permissions have been granted. If yes, the installation proceeds; if not, the installation fails. - -1. Declare the required permission \(**ohos.permission.INSTALL\_BUNDLE**\) in the **config.json** file. - - ``` - { - ... - "module": { - "package": "com.huawei.kitframework", - "deviceType": [ - "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera", "smartVision" - ], - "reqPermissions": [{ - // Declare the ohos.permission.INSTALL_BUNDLE permission required for installing the application. - "name": "ohos.permission.INSTALL_BUNDLE", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - }, - { - "name": "ohos.permission.LISTEN_BUNDLE_CHANGE", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - }, - { - "name": "ohos.permission.GET_BUNDLE_INFO", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - } - ], - ... - } - ``` - -2. The BMS calls the corresponding API of the application permission management component \(for example, the **CheckPermission** function with **ohos.permission.INSTALL\_BUNDLE** as an input parameter\) to check whether the BMS has the permission to install the application. If yes, the installation proceeds; if not, the installation fails. - - ``` - constexpr static char PERMISSION_INSTALL_BUNDLE[] = "ohos.permission.INSTALL_BUNDLE"; - - bool Install(const char *hapPath, const InstallParam *installParam, InstallerCallback installerCallback) - { - if ((hapPath == nullptr) || (installerCallback == nullptr) || (installParam == nullptr)) { - HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to nullptr parameters"); - return false; - } - // Check whether the ohos.permission.INSTALL_BUNDLE permission has been granted. - if (CheckPermission(0, static_cast(PERMISSION_INSTALL_BUNDLE)) != GRANTED) { - HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to permission denied"); - return false; // Application installation fails. - } - // Application installation process - ... - } - ``` - - diff --git a/en/device-dev/subsystems/development-guidelines-on-application-signature-verification.md b/en/device-dev/subsystems/development-guidelines-on-application-signature-verification.md deleted file mode 100644 index 8c477a78d351c4f2622dd27dc6b065bcbdfad98a..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-application-signature-verification.md +++ /dev/null @@ -1,272 +0,0 @@ -# Development Guidelines on Application Signature Verification - -- [When to Use](#section18502174174019) -- [Signature Verification Process](#section554632717226) -- [Available APIs](#section1633115419401) -- [Development Procedure \(Scenario 1\)](#section4207112818418) - - [Signature Verification](#section11470123816297) - - [OpenHarmony Self-signed Application Generation](#section167151429133312) - - [Development Examples](#section174318361353) - -- [Development Procedure \(Scenario 2\)](#section81272563427) - - [Signature Verification](#section07028210442) - - [Development Examples](#section1930711345445) - -- [Debugging and Verification](#section427316292411) - -## When to Use - -You can call the APIs provided by the signature verification component to check integrity of a debugging, released, or OpenHarmony self-signed application. You can also call APIs of the signature verification component to obtain some information in the profile, for example, **appid**. In addition, you can call APIs to check whether the UDID of a debugging application matches that of the device to ensure that the application is installed on the right device. - -## Signature Verification Process - -An unsigned HAP is in **.zip** format and consists of a file block, central directory, and end of central directory \(EOCD\). - -After the HAP is signed, a signature block is added between the file block and the central directory. The signature block consists of a file signature block, profile signature block, and signature header. The following figure shows the structure of a signed HAP. - -**Figure 1** Structure of a signed HAP - - -![](figures/安全子系统.png) - -The signature verification process consists of three steps: HAP signature verification, signature verification for the profile signature block, and profile content verification. - -**HAP signature verification** - -Use the preset root certificate of the device and the certificate chain to prove that the leaf certificate is trusted. Then use the digest obtained by decrypting the public key of the leaf certificate to prove that the HAP is not tampered with. - -The process is as follows: - -1. Use the preset root certificate of the device to verify the certificate chain in the file signature block and prove that the leaf certificate is trusted. -2. Use the public key in the leaf certificate to verify the file signature block and prove that this block is not tampered with. -3. Calculate and merge the digests of the file block, central directory, and EOCD. Merge the calculation result with the digest of the profile signature block in the signature block. Then compare the merge result with the digest of the file signature block. If they are the same, the HAP signature verification is successful. - -**Signature verification for the profile signature block** - -First of all, check who issued the signature of the profile signature block. If the signature was issued by the application market, the signature is trusted and does not need to be verified. Otherwise, the signature needs to be verified. Next, verify the certificate chain and then use the leaf certificate to verify the signature of the profile signature block to prove that it is not tampered with. - -**Profile content verification** - -Obtain the profile and check the validity of its content. If the HAP is a debugging application, check whether the UDID of the current device is contained in the UDID list in the profile. If yes, the verification is successful. Then compare the certificate in the profile with the leaf certificate used for HAP verification \(this is not required for a released or OpenHarmony self-signed application\). If they are the same, the entire signature verification process is complete. - -## Available APIs - -The following table lists the innerkits APIs provided by the signature verification component. These APIs are available only for system applications. - -**Table 1** APIs provided by the signature verification component - - - - - - - - - - - - - - - - -

Function

-

Description

-

int APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)

-

Verifies a signature by specifying the file path and returns the data obtained from the profile to the caller through verifyRst. This is the main entry function.

-

int APPVERI_SetDebugMode(bool mode)

-

Sets the debugging mode. If mode is set to true, certificate chain verification based on the debugging root key is enabled; if mode is set to false, it is disabled.

-

Note: Currently, no certificate based on the existing debugging root key is available. You can replace the debugging root key and perform related verification as required.

-

void APPVERI_FreeVerifyRst(VerifyResult *verifyRst)

-

Releases memory in verifyRst.

-
- -## Development Procedure \(Scenario 1\) - -### Signature Verification - -To verify applications released in the application market, debugging applications signed with debugging certificates of the application market, and OpenHarmony self-signed applications, perform the following steps: - -1. Construct the VerifyResult structure. - - ``` - VerifyResult verifyResult = {0}; - ``` - -2. Call the APPVERI\_AppVerify function by specifying the file path and VerifyResult to verify the application signature. - - ``` - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - ``` - -3. Check the returned result. If the verification is successful, obtain and process the data in VerifyResult. - - ``` - signatureInfo.appId = verifyResult.profile.appid; - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - ``` - -4. Call the APPVERI\_FreeVerifyRst function to release memory in VerifyResult. - - ``` - APPVERI_FreeVerifyRst(&verifyResult); - ``` - - -### OpenHarmony Self-signed Application Generation - -The procedure is as follows: - -1. Prepare required materials. - - Prepare the signature tool, system application HAP, system application profile \(\*.p7b\), signing certificate \(\*.cer\), and signing public/private key pair \(\*.jks\). - -2. Place all the materials in the same directory and start the shell. -3. Run the following command in the shell to sign the application: - - ``` - java -jar hapsigntoolv2.jar sign -mode localjks -privatekey "OpenHarmony Software Signature" -inputFile camera.hap -outputFile signed_camera.hap -signAlg SHA256withECDSA -keystore OpenHarmony.jks -keystorepasswd 123456 -keyaliaspasswd 123456 -profile camera_release.p7b -certpath OpenHarmony.cer -profileSigned 1 - ``` - - Key fields: - - **-jar**: signature tool, which is **[hapsigntool](https://repo.huaweicloud.com/harmonyos/develop_tools/hapsigntoolv2.jar)** - - **-mode**: local signature flag, which is fixed at **localjks** - - **-privatekey**: alias of the public/private key pair, which is **OpenHarmony Software Signature** - - **-inputFile**: application to be signed, which is generated through compilation - - **-outputFile**: signed application - - **-signAlg**: signing algorithm, which is fixed at **SHA256withECDSA** - - **-keystore**: public/private key pair, which is [OpenHarmony.jks](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.jks) in the **OpenHarmonyCer** directory of the **security\_services\_app\_verify** repository. The default password is **123456**. You can use a tool \(such as keytool\) to change the password. - - **-keystorepasswd**: password of the public/private key pair, which is **123456** by default - - **-keyaliaspasswd**: password of the public/private key pair alias, which is **123456** by default - - **-profile**: application profile, which is stored in the code directory - - **-certpath**: signing certificate, which is [OpenHarmony.cer](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.cer) in the **OpenHarmonyCer** directory of the **security\_services\_app\_verify** repository. - - **-profileSigned**: whether the signature block contains the profile. The value is fixed at **1**, indicating that the signature block contains the profile. - - -### Development Examples - -The following example describes how the application management framework component verifies the signature of an application during its installation. - -``` -uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) -{ - bool mode = ManagerService::GetInstance().IsDebugMode(); - HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); - // Construct the VerifyResult structure. - VerifyResult verifyResult = {0}; - // Verify the signature by specifying the file path. - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - uint8_t errorCode = SwitchErrorCode(ret); - if (errorCode != ERR_OK) { - return errorCode; - } - // Obtain appid from the VerifyResult structure. - signatureInfo.appId = verifyResult.profile.appid; - // Obtain the application name written in the profile from the VerifyResult structure. - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - int32_t restricNum = verifyResult.profile.permission.restricNum; - for (int32_t i = 0; i < restricNum; i++) { - signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); - } - // Release memory in VerifyResult. - APPVERI_FreeVerifyRst(&verifyResult); - return ERR_OK; -} -``` - -## Development Procedure \(Scenario 2\) - -### Signature Verification - -To verify applications signed with certificates that are based on debugging root keys, perform the following steps: - -1. Call the APPVERI\_SetDebugMode\(true\) function to enable the debugging mode. - - ``` - ManagerService::SetDebugMode(true); - ... - uint8_t ManagerService::SetDebugMode(bool enable) - { - int32_t ret = APPVERI_SetDebugMode(enable); - if (ret < 0) { - HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); - return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; - } - isDebugMode_ = enable; - HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); - return ERR_OK; - } - ``` - -2. Construct the **VerifyResult** structure, verify the application signature, and release memory in **VerifyResult**. -3. Call the APPVERI\_SetDebugMode\(false\) function to disable the debugging mode. - - ``` - ManagerService::SetDebugMode(false); - ``` - - -### Development Examples - -The following is the example code \(supplemented based on the example code for scenario 1\): - -``` -uint8_t ManagerService::SetDebugMode(bool enable) -{ - int32_t ret = APPVERI_SetDebugMode(enable); - if (ret < 0) { - HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); - return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; - } - isDebugMode_ = enable; - HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); - return ERR_OK; -} -uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) -{ - // Enable debugging mode. - ManagerService::SetDebugMode(true); - bool mode = ManagerService::GetInstance().IsDebugMode(); - HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); - // Construct the VerifyResult structure. - VerifyResult verifyResult = {0}; - // Verify the signature by specifying the file path. - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - uint8_t errorCode = SwitchErrorCode(ret); - if (errorCode != ERR_OK) { - return errorCode; - } - // Obtain appid from the VerifyResult structure. - signatureInfo.appId = verifyResult.profile.appid; - // Obtain the application name written in the profile from the VerifyResult structure. - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - int32_t restricNum = verifyResult.profile.permission.restricNum; - for (int32_t i = 0; i < restricNum; i++) { - signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); - } - // Release memory in VerifyResult. - APPVERI_FreeVerifyRst(&verifyResult); - // Disable debugging mode. - ManagerService::SetDebugMode(false); - return ERR_OK; -} -``` - -## Debugging and Verification - -1. Choose an application that can be properly installed on OpenHarmony. -2. Develop the application based on the development guidelines. -3. Use a self-developed program to verify the signature of the developed application. If the verification is successful and **appid** can be obtained, the development is successful. - diff --git a/en/device-dev/subsystems/development-guidelines-on-common-components.md b/en/device-dev/subsystems/development-guidelines-on-common-components.md deleted file mode 100644 index 556f8ee94d54b0a738d66544522f3ee30424075e..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-common-components.md +++ /dev/null @@ -1,555 +0,0 @@ -# Development Guidelines on Common Components - -- [UIButton](#section145353310214) -- [When to Use](#section1169616141577) -- [Available APIs](#section341211538315) -- [How to Develop](#section22501726193214) -- [UIImageView](#section19523161611259) -- [When to Use](#section1274484210400) -- [Available APIs](#section74981992411) -- [How to Develop \(Adaptive Mode\)](#section144341333134114) -- [How to Develop \(Tile Mode\)](#section97178160421) -- [UILabel](#section16588132012911) -- [When to Use](#section6870195634218) -- [Available APIs](#section2012714510433) -- [How to Develop \(Default Mode\)](#section83221538114410) -- [How to Develop \(Background Color and Opacity\)](#section933360204510) -- [How to Develop \(Letter Spacing\)](#section19447826124518) -- [How to Develop \(Size-Adaptive Mode\)](#section101711842154617) -- [How to Develop \(Ellipsis Mode\)](#section1249519410471) -- [How to Develop \(Scrolling Mode\)](#section15643122618478) - -Common components inherit from the base class **UIView**. Child components cannot be added to common components, such as buttons, images, and labels. - -**Figure 1** Tree structure of common components -![](figures/tree-structure-of-common-components.png "tree-structure-of-common-components") - -**UIView** is a base class of the following components: **UIAbstractProgress**, **UIArcLabel**, **UIButton**, **UICanvas**, **UILabel**, and **UIImageView**. **UIBoxProgress** and **UICircleProgress** inherit from **UIAbstractProgress**. **UILabelButton** and **UIRepeatButton** inherit from **UIButton**. **UIImageAnimatorView** and **UITextureMapper** inherit from **UIImageView**. - -## UIButton - -## When to Use - -**UIButton** supports the click event and allows you to set styles in different states. - -## Available APIs - -**Table 1** Available functions in UIButton - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

void SetImageSrc (const char *defaultImgSrc, const char *triggeredImgSrc)

-

Sets the button image.

-

void SetImagePosition (const int16_t x, const int16_t y)

-

Sets the position of the button image.

-

int16_t GetImageX () const

-

Obtains the x-coordinate of the button image.

-

int16_t GetImageY () const

-

Obtains the y-coordinate of the button image.

-

const ImageInfo* GetCurImageSrc() const

-

Obtains the image of the button in the current state.

-

Style& GetStyleForState (ButtonState state)

-

Sets the style for the button in the current state.

-

voidSetStyleForState (const Style &style, ButtonState state)

-

Sets the style for the button in a specified state.

-

void Disable ()

-

Disables the button.

-

void Enable ()

-

Enables the button.

-
- -## How to Develop - -1. Implement the click event. - - ``` - class TestBtnOnClickListener : public OHOS::UIView::OnClickListener { - bool OnClick(UIView& view, const ClickEvent& event) override - { - int16_t width = view.GetWidth() + 10; - int16_t height = view.GetHeight() + 10; - view.Resize(width, height); - view.Invalidate(); - return true; - } - }; - ``` - -2. Create a **UIButton** instance. - - ``` - UIButton* button = new UIButton(); - button->SetPosition(50, 50); - button->SetWidth(100); - button->SetHeight(50); - ``` - -3. Register the click event callback for **UIButton**. - - ``` - button->SetOnClickListener(new TestBtnOnClickListener()); - ``` - -4. Verify that the button is clicked and its size increases gradually, as shown in the following figure. - - **Figure 2** Effect of clicking a **UIButton** - ![](figures/effect-of-clicking-a-uibutton.gif "effect-of-clicking-a-uibutton") - - -## UIImageView - -## When to Use - -**UIImageView** supports the functions to display images, set opacity, rotate images, and zoom in or out images. The following image formats are supported: RGB565, RGB888, RGBA8888, PNG, and JPG. - -## Available APIs - -**Table 2** Available functions in UIImageView - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

void SetSrc (const char *src)

-

Sets the image path with binary data.

-

void SetSrc (const ImageInfo *src)

-

Sets the pointer to image information.

-

void SetAutoEnable (bool enable)

-

Sets whether the component size adapts to the image size.

-

const void* GetSrcType () const

-

Obtains the image type.

-

bool GetAutoEnable () const

-

Checks whether the component size adapts to the image size.

-

void SetBlurLevel(BlurLevel level)

-

Sets the blur level for the image background.

-

BlurLevel GetBlurLevel() const

-

Obtains the blur level of the image background.

-

void SetTransformAlgorithm(TransformAlgorithm algorithm)

-

Sets the transformation algorithm.

-

TransformAlgorithm GetTransformAlgorithm() const

-

Obtains the transformation algorithm.

-
- -## How to Develop \(Adaptive Mode\) - -1. Create a **UIImageView** instance. - - ``` - UIImageView* imageView = new UIImageView(); - imageView->SetPosition(0, 30); - ``` - -2. Set the image path with binary data. - - ``` - imageView->SetSrc("..\\config\\images\\A021_001.bin"); - ``` - -3. Verify that the **UIImageView** component is adaptive to the image. - - **Figure 3** Image auto-adaption effect - ![](figures/image-auto-adaption-effect.png "image-auto-adaption-effect") - - -## How to Develop \(Tile Mode\) - -1. Create a **UIImageView** instance. - - ``` - UIImageView* imageView = new UIImageView(); - imageView->SetPosition(0, 30); - ``` - -2. Set the image path. - - ``` - imageView->SetSrc("..\\config\\images\\A021_001.bin"); - ``` - -3. Disable the image auto-adaptation effect and resize the image to display the image in tile mode. - - ``` - imageView->SetAutoEnable(false); - imageView->Resize(454, 150); - ``` - -4. Verify that the tile mode has been enabled for the **UIImageView**. - - **Figure 4** Image tile effect - ![](figures/image-tile-effect.png "image-tile-effect") - - -## UILabel - -## When to Use - -**UILabel** displays text in an area. You can set the background color, text display style, and long text display effect for a label. - -## Available APIs - -**Table 3** Available functions in UILabel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

void SetText(const char* text);

-

Sets text for the label.

-

const char* GetText() const;

-

Obtains text of the label.

-

void SetLineBreakMode(const uint8_t lineBreakMode);

-

Sets the label mode, such as truncation and automatic extension.

-

uint8_t GetLineBreakMode() const

-

Obtains the label mode.

-

void SetTextColor(ColorType color)

-

Set the text color.

-

ColorType GetTextColor() const

-

Obtains the text color.

-

void SetAlign(UITextLanguageAlignment horizontalAlign,

-

UITextLanguageAlignment verticalAlign = TEXT_ALIGNMENT_TOP);

-

Sets the text alignment mode.

-

UITextLanguageAlignment GetHorAlign() const

-

Obtains the horizontal alignment mode of text.

-

UITextLanguageAlignment GetVerAlign() const

-

Obtains the vertical alignment mode of text.

-

void SetDirect(UITextLanguageDirect direct)

-

Sets the text display direction.

-

UITextLanguageDirect GetDirect() const

-

Obtains the text display direction.

-

void SetFontId(uint8_t fontId);

-

Sets the dynamic font ID.

-

uint8_t GetFontId() const

-

Obtains the dynamic font ID.

-

void SetFont(const char *name, uint8_t size);

-

Sets the font name and size.

-

void SetAnimatorSpeed(uint16_t animSpeed);

-

Sets the font rotation speed.

-

uint16_t GetTextWidth();

-

Obtains the font width.

-

uint16_t GetTextHeight();

-

Obtains the font height.

-

void SetRollStartPos(int16_t pos)

-

Sets the rotation position.

-

int16_t GetRollStartPos() const

-

Obtains the rotation position.

-

void SetTextRotation(LabelRotateDegree angle)

-

Sets the enumerated value of the text rotation angle.

-

LabelRotateDegree GetTextRotation() const

-

Obtains the enumerated value of the text rotation angle.

-

uint16_t GetTextRotateDegree() const

-

Obtains the number of text rotation degrees.

-
- -## How to Develop \(Default Mode\) - -1. Create a **lUILabel** instance and set its size and position. - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. Set the font. - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. Set the text. - - ``` - label->SetText("label"); - ``` - -4. Verify the label size and display effect, as shown in the following figure. - - ![](figures/en-us_image_0000001051782526.png) - - -## How to Develop \(Background Color and Opacity\) - -1. Create a **lUILabel** instance and set its size and position. - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. Set the font. - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. Set the background color and opacity. - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetStyle(STYLE_BACKGROUND_OPA, 127); - label->SetText("Label"); - ``` - -4. Verify that the background color of the label is **Gray**, as shown in the following figure. - - ![](figures/en-us_image_0000001052582522.png) - - -## How to Develop \(Letter Spacing\) - -1. Create a **lUILabel** instance and set its size and position. - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. Set the font. - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. Set the font color and letter spacing. - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetStyle(STYLE_LETTER_SPACE, 5); - label->SetText("Label"); - ``` - -4. Verify that the letter spacing is **5** pixels on the label, as shown in the following figure. - - ![](figures/en-us_image_0000001052942531.png) - - -## How to Develop \(Size-Adaptive Mode\) - -Regarding too long text, the size of a label can be automatically adjusted based on the text, or the text can be truncated or displayed with the scrolling effect. - -1. Create a **lUILabel** instance and set its size and position. - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. Set the font. - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. Set the font color to **Gray** and enable the label size to adapt to the text. - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); - label->SetText("123\n567890"); - ``` - -4. Verify that the label size adapts to the text, as shown in the following figure. - - ![](figures/en-us_image_0000001052782555.png) - - -## How to Develop \(Ellipsis Mode\) - -In ellipsis mode, an ellipsis \(...\) is displayed at the end of the label if the text cannot be completely displayed. - -1. Create a **lUILabel** instance and set its size and position. - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. Set the font. - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. Set the text display mode to **LINE\_BREAK\_ELLIPSIS**. - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); - label->SetText("123567890"); - ``` - -4. Verify that the ellipsis mode has taken effect on the label, as shown in the following figure. - - ![](figures/en-us_image_0000001052662559.png) - - -## How to Develop \(Scrolling Mode\) - -In scrolling mode, long text is kept scrolling on a screen to bring the entire text into view. - -1. Create a **lUILabel** instance and set its size and position. - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. Set the font. - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. Set the text display mode to **UI\_LABEL\_LONG\_ROLL**. - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetStyle(STYLE_BACKGROUND_OPA, 127); - label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); - label->SetText("123567890"); - ``` - -4. Verify that the text is scrolling on the label, as shown in the following figure. - - ![](figures/20200721-223604(espace).gif) - - diff --git a/en/device-dev/subsystems/development-guidelines-on-container-components.md b/en/device-dev/subsystems/development-guidelines-on-container-components.md deleted file mode 100644 index 7f4c52c933edc39a8fe283ded70d22d63c514d42..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-container-components.md +++ /dev/null @@ -1,244 +0,0 @@ -# Development Guidelines on Container Components - -- [UIViewGroup](#section145471898812) -- [When to Use](#section0916112362216) -- [Available APIs](#section12641756192212) -- [How to Develop](#section5412161692311) -- [UIScrollView](#section174961523161315) -- [When to Use](#section8937101902413) -- [Available APIs](#section14789133142420) -- [How to Develop](#section1769754422417) - -Container components are capable of containing UI components and inherit from **UIViewGroup**. Components that are commonly used and need to contain child components are placed in the container class inheritance structure. For example, you need to call the **Add** function to add information such as time statistics and icons to **UIAnalogClock**. - -**Figure 1** Structure of common container components -![](figures/structure-of-common-container-components.png "structure-of-common-container-components") - -The **RootView**, **UIAbstractScroll**, and **UIPicker** components inherit from **UIViewGroup**, and the **UIList**, **UIScrollView**, and **UISwipeView** components inherit from **UIAbstractScroll**. - -## UIViewGroup - -## When to Use - -**UIViewGroup** is a base class for container components. For example, you can call the functions in this class to add, remove, and insert container components. Also, you can call the **Add** function to add child components for a container component. You need to set the position information for child components in a common container component. The position information is the coordinates relative to those of their parent component. The following figure shows the tree structure of components. - -**Figure 2** Component tree structure -![](figures/component-tree-structure.png "component-tree-structure") - -As shown in the figure, the container component **ViewGroup1** and the component **View1** are added to **RootView**, the component **View2** and the container component **ViewGroup2** are added to **ViewGroup1**, and then the component **View3** \(as a sibling of **View1**\) is also added to **ViewGroup1**. - -- Rendering: During rendering of a container component, you need to call the **OnDraw** function on all its child components to update them. -- Coordinates: As the position information of child components is the coordinates relative to those of their parent components, the system calculates and displays the absolute coordinates of child components during rendering. -- Tree structure traversing: The **UIViewGroup** class provides the functions below to traverse, search for, and manage the component tree. - -## Available APIs - -**Table 1** Available functions in ViewGroup - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

virtual void Add(UIView* view)

-

Adds a child component.

-

virtual void Insert(UIView* prevView, UIView* insertView)

-

Inserts a child component.

-

virtual void Remove(UIView* view)

-

Removes a child component.

-

virtual void RemoveAll()

-

Removes all child components.

-

virtual void GetTargetView(const Point& point, UIView** last)

-

Obtains the target view.

-

virtual void MoveChildByOffset(int16_t x, int16_t y)

-

Moves a child component by a specified offset.

-

UIView* GetChildrenHead() const

-

Obtains the first child view in a view group.

-

UIView* GetChildrenTail() const

-

Obtains the last child view in a view group.

-

virtual UIView* GetChildById(const char* id) const override

-

Obtains a child view based on its ID.

-
- -## How to Develop - -1. Create **ULLabelButton** instances and set their coordinates. - - ``` - UILabelButton* btn1 = new UILabelButton(); - btn1->SetPosition(0, 0, 100, 50); - btn1->SetText("btn1"); - - UILabelButton* btn2 = new UILabelButton(); - btn2->SetPosition(50, 50, 100, 50); - btn2->SetText("btn2"); - - UILabelButton* btn3 = new UILabelButton(); - btn3->SetPosition(100, 100, 100, 50); - btn3->SetText("btn3"); - ``` - -2. Create a **UIViewGroup** instance and set its coordinates. - - ``` - UIViewGroup* group = new UIViewGroup(); - group->SetPosition(0, 0, 300, 300); - ``` - -3. Add the **ULLabelButton** instances to **UIViewGroup**. - - ``` - group->Add(btn1); - group->Add(btn2); - group->Add(btn3); - ``` - -4. The following figure shows the effect of adding view instances to a **ViewGroup**. - - **Figure 3** Effect of adding view instances to a ViewGroup - ![](figures/effect-of-adding-view-instances-to-a-viewgroup.png "effect-of-adding-view-instances-to-a-viewgroup") - - -## UIScrollView - -## When to Use - -**UIScrollView** provides scrolling container components, which enable child components to scroll upwards, downwards, leftwards, and rightwards upon a touch event. This class also supports horizontal and vertical cursor display. - -## Available APIs - -**Table 2** Available functions in ScrollView - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

void ScrollBy(int16_t xDistance, int16_t yDistance)

-

Scrolls a view.

-

void SetScrollbarWidth(uint8_t width)

-

Sets the scrollbar width.

-

void SetHorizontalScrollState(bool state)

-

Sets the horizontal scrolling state.

-

bool GetHorizontalScrollState() const

-

Checks whether horizontal scrolling is allowed.

-

void SetVerticalScrollState(bool state)

-

Sets the vertical scrolling state.

-

bool GetVerticalScrollState() const

-

Checks whether vertical scrolling is allowed.

-

void SetXScrollBarVisible(bool state)

-

Sets whether the x-axis scrollbar is visible.

-

void SetYScrollBarVisible(bool state)

-

Sets whether the y-axis scrollbar is visible.

-

void RegisterScrollListener(OnScrollListener* scrollListener)

-

Registers the scrolling callback class.

-

void RefreshScrollBar()

-

Refreshes the scrollbar.

-

virtual void OnScrollStart() {}

-

Called when scrolling starts.

-

virtual void OnScrollEnd() {}

-

Called when scrolling ends.

-

uint8_t GetScrollState() const

-

Obtains the scrolling state.

-

void SetScrollState(uint8_t state)

-

Sets the scrolling state.

-
- -## How to Develop - -Add two buttons as child components and display horizontal and vertical cursors. - -``` -scrollView* scroll = new UIScrollView(); -scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); -scroll->SetPosition(0,0, 200, 200); -scroll->SetXScrollBarVisible(true); -scroll->SetYScrollBarVisible(true); -UILabelButton* button1 = new UILabelButton(); -button1->SetText("button1"); -button1->SetPosition(0, 0, 300, 300); -UILabelButton* button2 = new UILabelButton(); -button2->SetText("button2"); -button2->SetPosition(0, 300, 300, 300); -scroll->Add(button1); -scroll->Add(button2); -``` - -**Figure 4** Scrolling effect in both horizontal and vertical directions -![](figures/scrolling-effect-in-both-horizontal-and-vertical-directions.gif "scrolling-effect-in-both-horizontal-and-vertical-directions") - diff --git a/en/device-dev/subsystems/development-guidelines-on-layout-container-components.md b/en/device-dev/subsystems/development-guidelines-on-layout-container-components.md deleted file mode 100644 index b90467d679cb0819acba97d6454315bfdffeeacf..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-layout-container-components.md +++ /dev/null @@ -1,216 +0,0 @@ -# Development Guidelines on Layout Container Components - -- [UISwipeView](#section13631719181717) -- [When to Use](#section11299120102617) -- [Available APIs](#section767434119261) -- [Development Procedure \(Non-Cyclic Horizontal Swiping\)](#section111911175287) -- [Development Procedure \(Cyclic Horizontal Swiping\)](#section1976914915282) -- [GridLayout](#section46819199173) -- [When to Use](#section831618247294) -- [Available APIs](#section597214622912) -- [How to Develop](#section1418253410306) - -Layout container components consist of basic view classes. You can set the view positions to achieve nested and overlapped layouts, set the layout type and margin to standardize the child components in the layout, and call certain functions to implement layout views based on parent and sibling components. - -## UISwipeView - -## When to Use - -**UISwipeView** inherits from **UIViewGroup**. In addition to the **Add**, **Remove**, and **Insert** functions, **UISwipeView** provides the functions to swipe contents by page and center the current page after swiping. This component can be horizontally or vertically centered. Child components added via the **Add** function are automatically horizontally or vertically centered, adaptive to the **UISwipeView** direction, in the sequence they were added. - -## Available APIs - -**Table 1** Available functions in SwipeView - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

void SetCurrentPage(uint16_t index);

-

Sets the current page.

-

uint16_t GetCurrentPage()

-

Obtains the current page.

-

UIView* GetCurrentView() const

-

Obtains the current view.

-

void SetOnSwipeListener(OnSwipeListener& onSwipeListener)

-

Sets the swiping callback class.

-

void SetAnimatorTime(uint16_t time);

-

Sets the animator event.

-

void SetLoopState(bool loop)

-

Sets whether to enable the cyclic state.

-

UIView* GetViewByIndex(uint16_t index);

-

Obtains a view based on its index.

-
- -## Development Procedure \(Non-Cyclic Horizontal Swiping\) - -1. Create a horizontal swiping **UISwipeView**. - - ``` - UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); - ``` - -2. Add child components to **UISwipeView**. - - ``` - UILabelButton* button1 = new UILabelButton(); - button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button1->SetText("button1"); - swipe->Add(button1); - UILabelButton* button2 = new UILabelButton(); - button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button2->SetText("button2"); - swipe->Add(button2); - UILabelButton* button3 = new UILabelButton(); - button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button3->SetText("button3"); - swipe->Add(button3); - ``` - -3. Verify that the components are swiping horizontally but not cyclically. - - **Figure 1** Horizontal swiping effect of **UISwipeView** - - - ![](figures/en-us_image_0000001053247975.gif) - - -## Development Procedure \(Cyclic Horizontal Swiping\) - -1. Create a horizontal swiping **UISwipeView** and add its child components. - - ``` - UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); - UILabelButton* button1 = new UILabelButton(); - button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button1->SetText("button1"); - swipe->Add(button1); - UILabelButton* button2 = new UILabelButton(); - button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button2->SetText("button2"); - swipe->Add(button2); - UILabelButton* button3 = new UILabelButton(); - button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button3->SetText("button3"); - swipe->Add(button3); - ``` - -2. Enable cyclic swiping for the **UISwipeView**. - - ``` - swipe->SetLoopState(true); - ``` - -3. Verify that the components are swiping horizontally and cyclically. - - **Figure 2** Cyclic horizontal swiping effect of **UISwipeView** - - - ![](figures/en-us_image_0000001053207924.gif) - - -## GridLayout - -## When to Use - -**GridLayout** provides the basic layout capability to set the number of grid rows and columns. Child components added via the **Add** function are automatically arranged after the **LayoutChildren\(\)** function is called. - -## Available APIs - -**Table 2** Available functions in GridLayout - - - - - - - - - - - - - - - - -

Function

-

Description

-

void SetRows(const uint16_t& rows)

-

Sets the number of grid rows.

-

void SetCols(const uint16_t& cols)

-

Sets the number of grid columns.

-

void LayoutChildren(bool needInvalidate = false)

-

Lays out child components.

-
- -## How to Develop - -1. Create a **GridLayout** instance and set its position and size. - - ``` - GridLayout* layout_ = new GridLayout(); - layout_->SetPosition(0, g_y, HROIZONTAL_RESOLUTION, 200); - layout_->SetLayoutDirection(LAYOUT_HOR); - layout_->SetRows(2); - layout_->SetCols(2); - ``` - -2. Create **UILabelButton** instances. - - ``` - UILabelButton* bt1 = new UILabelButton(); - bt1->SetPosition(0,0,100,50); - bt1->SetText("bt1"); - UILabelButton* bt2 = new UILabelButton(); - bt2->SetPosition(0, 0, 100, 50); - bt2->SetText("bt2"); - UILabelButton* bt3 = new UILabelButton(); - bt3->SetPosition(0, 0, 100, 50); - bt3->SetText("bt3"); - UILabelButton* bt4 = new UILabelButton(); - bt4->SetPosition(0, 0, 100, 50); - bt4->SetText("bt4"); - ``` - -3. Add child components and call the **LayoutChildren\(\)** function. - - ``` - layout_->Add(bt1); - layout_->Add(bt2); - layout_->Add(bt3); - layout_->Add(bt4); - layout_->LayoutChildren(); - ``` - -4. Verify the layout of buttons, as shown in the following figure. - - **Figure 3** Setting a 2x2 grid and adding four buttons in a layout - ![](figures/setting-a-2x2-grid-and-adding-four-buttons-in-a-layout.png "setting-a-2x2-grid-and-adding-four-buttons-in-a-layout") - - diff --git a/en/device-dev/subsystems/development-guidelines-on-media-recording.md b/en/device-dev/subsystems/development-guidelines-on-media-recording.md deleted file mode 100644 index 407bfa9e5ad89a15c251d5ad5c1907812989992a..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-media-recording.md +++ /dev/null @@ -1,287 +0,0 @@ -# Development Guidelines on Media Recording - -- [When to Use](#section186634310418) -- [Available APIs](#section125479541744) -- [Limitations and Constraints](#section1165911177314) -- [How to Develop](#section34171333656) - -## When to Use - -To record audios and videos, use APIs described in this section to set the encoding format, sampling rate, and bit rate, and encapsulate output files based on the parameters. - -## Available APIs - -The following table describes APIs available for audio and video recording. - -**Table 1** APIs available for media recording - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

API

-

Function

-

Description

-

Recorder

-

int32_t SetVideoSource(VideoSourceType source, int32_t &sourceId)

-

Sets a video source for recording.

-

Recorder

-

int32_t SetVideoEncoder(int32_t sourceId, VideoCodecFormat encoder)

-

Sets a video encoder for recording.

-

Recorder

-

int32_t SetVideoSize(int32_t sourceId, int32_t width, int32_t height)

-

Sets the width and height of the video to record.

-

Recorder

-

int32_t SetVideoFrameRate(int32_t sourceId, int32_t frameRate)

-

Sets the frame rate of the video to record.

-

Recorder

-

int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate)

-

Sets the encoding bit rate of the video to record.

-

Recorder

-

int32_t SetCaptureRate(int32_t sourceId, double fps)

-

Sets the video capture rate.

-

Recorder

-

std::shared_ptr<OHOS::Surface> GetSurface(int32_t sourceId);

-

Obtains the surface of the video source.

-

Recorder

-

int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId)

-

Sets an audio source for recording.

-

Recorder

-

int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder)

-

Sets an audio encoder for recording.

-

Recorder

-

int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate)

-

Sets the audio sampling rate for recording.

-

Recorder

-

int32_t SetAudioChannels(int32_t sourceId, int32_t num)

-

Sets the number of audio channels for recording.

-

Recorder

-

int32_t SetAudioEncodingBitRate(int32_t sourceId, int32_t bitRate)

-

Sets the encoding bit rate of the audio to record.

-

Recorder

-

int32_t SetMaxDuration(int32_t duration)

-

Sets the maximum duration of an output file, in seconds.

-

Recorder

-

int32_t SetOutputFormat(OutputFormatType format)

-

Sets the output file format.

-

Recorder

-

int32_t SetOutputPath(const string &path);

-

Sets the output file path.

-

Recorder

-

int32_t SetOutputFile(int32_t fd)

-

Sets the file descriptor of the output file.

-

Recorder

-

int32_t SetNextOutputFile(int32_t fd);

-

Sets the file descriptor of the next output file.

-

Recorder

-

int32_t SetMaxFileSize(int64_t size)

-

Sets the maximum size of an output file, in bytes.

-

Recorder

-

int32_t SetRecorderCallback(const std::shared_ptr<RecorderCallback> &callback)

-

Registers a recording listener.

-

Recorder

-

int32_t Prepare()

-

Prepares for recording.

-

Recorder

-

int32_t Start()

-

Starts recording.

-

Recorder

-

int32_t Pause()

-

Pauses recording.

-

Recorder

-

int32_t Resume()

-

Resumes recording.

-

Recorder

-

int32_t Stop(bool block)

-

Stops recording.

-

Recorder

-

int32_t Reset();

-

Resets recording.

-

Recorder

-

int32_t Release()

-

Releases recording resources.

-

Recorder

-

int32_t SetFileSplitDuration(FileSplitType type, int64_t timestamp, uint32_t duration)

-

Sets the duration to split an output file.

-

Recorder

-

int32_t SetParameter(int32_t sourceId, const Format &format)

-

Sets an extended parameter for recording.

-
- -## Limitations and Constraints - -None - -## How to Develop - -1. Create a **Recorder** instance. - - ``` - Recorder *recorder = new Recorder(); - ``` - -2. Sets parameters for the **Recorder** instance, including the media source information, encoding format, sampling rate, bit rate, and video width and height. - - ``` - int32_t sampleRate = 48000; - int32_t channelCount = 1; - AudioCodecFormat audioFormat = AAC_LC; - AudioSourceType inputSource = AUDIO_MIC; - int32_t audioEncodingBitRate = sampleRate; - VideoSourceType source = VIDEO_SOURCE_SURFACE_ES; - int32_t frameRate = 30; - double fps = 30; - int32_t rate = 4096; - int32_t sourceId = 0; - int32_t audioSourceId = 0; - int32_t width = 1920; - int32_t height = 1080; - VideoCodecFormat encoder = H264; - recorder->SetVideoSource(source, sourceId); // Set the video source and obtain the source ID. - recorder->SetVideoEncoder(sourceId, encoder); // Set the video encoding format. - recorder->SetVideoSize(sourceId, width, height); // Set the video width and height. - recorder->SetVideoFrameRate(sourceId, frameRate); // Set the video frame rate. - recorder->SetVideoEncodingBitRate(sourceId, rate); // Set the video encoding bit rate. - recorder->SetCaptureRate(sourceId, fps); // Set the capture rate for video frames. - recorder->SetAudioSource(inputSource, audioSourceId); // Set the audio source and obtain the source ID. - recorder->SetAudioEncoder(audioSourceId, audioFormat); // Set the audio encoding format. - recorder->SetAudioSampleRate(audioSourceId, sampleRate); // Set the audio sampling rate. - recorder->SetAudioChannels(audioSourceId, channelCount); // Set the number of audio channels. - recorder->SetAudioEncodingBitRate(audioSourceId, audioEncodingBitRate); // Set the audio encoding bit rate. - ``` - -3. Prepare the **Recorder** instance for recording. - - ``` - recorder->Prepare(); // Prepare for recording. - ``` - -4. Start recording. The **Recorder** instance starts recording based on the audio and video sources. - - ``` - recorder->Start(); // Start recording. - ``` - -5. Stop recording and release resources. - - ``` - recorder->Stop(); // Stop recording. - recorder->Release(); // Release recording resources. - ``` - - diff --git a/en/device-dev/subsystems/development-guidelines-on-photographing.md b/en/device-dev/subsystems/development-guidelines-on-photographing.md deleted file mode 100644 index 23f92734097a2c318c8701f8c30983b88100b7bc..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-photographing.md +++ /dev/null @@ -1,395 +0,0 @@ -# Development Guidelines on Photographing - -- [When to Use](#section1963312376119) -- [Available APIs](#section56549532016) -- [Limitations and Constraints](#section1165911177314) -- [How to Develop](#section138543918214) - -## When to Use - -Use the camera module APIs to capture frames \(photographing\). - -## Available APIs - -**Table 1** APIs for photographing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Class

-

Function

-

Description

-

CameraKit

-

int32_t GetCameraIds(std::list<string> cameraList)

-

Obtains IDs of cameras that are currently available.

-

CameraKit

-

CameraAbility& GetCameraAbility(string cameraId)

-

Obtains the camera capability

-

CameraKit

-

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

-

Registers a camera callback for camera status changes.

-

CameraKit

-

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

-

Unregisters a camera callback.

-

CameraKit

-

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

-

Creates a Camera instance.

-

Camera

-

string GetCameraId()

-

Obtains the camera ID.

-

Camera

-

CameraConfig& GetCameraConfig()

-

Obtains the camera configuration.

-

Camera

-

FrameConfig& GetFrameConfig(int32_t type)

-

Obtains the frame configuration.

-

Camera

-

void Configure(CameraConfig& config)

-

Configures the camera using the CameraConfig object.

-

Camera

-

void Release()

-

Releases the Camera object and associated resources.

-

Camera

-

int TriggerLoopingCapture(FrameConfig& frameConfig)

-

Starts looping-frame capture.

-

Camera

-

void StopLoopingCapture()

-

Stops looping-frame capture.

-

Camera

-

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

-

Starts single-frame capture.

-

CameraConfig

-

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

-

Sets a frame state callback to respond to state changes.

-

CameraConfig

-

static CameraConfig* CreateCameraConfig()

-

Creates a CameraConfig instance.

-

CameraAbility

-

std::list<Size> GetSupportedSizes(int format)

-

Obtains the supported image sizes for a specified image format.

-

CameraAbility

-

std::list<T> GetParameterRange(uint32_t key)

-

Obtains the parameter value range based on a specified parameter key.

-

CameraDevice

-

CameraDeviceCallback()

-

A constructor used to create a CameraDeviceCallback instance.

-

CameraDevice

-

void OnCameraStatus​(std::string cameraId, int32_t status)

-

Called when the camera device status changes.

-

CameraStateCallback

-

CameraStateCallback​()

-

A constructor used to create a CameraStateCallback instance.

-

CameraStateCallback

-

void OnConfigured​(Camera& camera)

-

Called when the camera is configured.

-

CameraStateCallback

-

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

-

Called when the camera fails to be configured.

-

CameraStateCallback

-

void OnCreated​(Camera& camera)

-

Called when the camera is successfully created.

-

CameraStateCallback

-

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

-

Called when the camera fails to be created.

-

CameraStateCallback

-

void OnReleased​(Camera& camera)

-

Called when the camera is released.

-

FrameStateCallback

-

FrameStateCallback​()

-

A constructor used to create a FrameStateCallback instance.

-

FrameStateCallback

-

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

-

Called when the frame capture is completed.

-

FrameStateCallback

-

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

-

Called when the frame capture fails.

-

FrameConfig

-

int32_t GetFrameConfigType()

-

Obtains the frame configuration type.

-

FrameConfig

-

std::list<OHOS::Surface> GetSurfaces()

-

Obtains a list of surface objects (shared memories).

-

FrameConfig

-

void AddSurface(OHOS::AGP::UISurface& surface);

-

Adds a surface.

-

FrameConfig

-

void RemoveSurface(OHOS::AGP::UISurface& surface);

-

Removes a surface.

-
- -## Limitations and Constraints - -None - -## How to Develop - -1. Extend the **CameraDeviceCallback** class and call **OnCameraStatus** to customize operations when the camera device changes, for example, when a camera becomes available or unavailable. - - ``` - class SampleCameraDeviceCallback : public CameraDeviceCallback { - void OnCameraStatus(std::string cameraId, int32_t status) override - { - // Do something when camera is available or unavailable. - } - }; - ``` - -2. Extend the **FrameStateCallback** class. After obtaining the frame data, save the data as a file. - - ``` - static void SampleSaveCapture(const char *p, uint32_t size) - { - cout << "Start saving picture" << endl; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm *ltm = localtime(&tv.tv_sec); - if (ltm != nullptr) { - ostringstream ss("Capture_"); - ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; - - ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); - cout << "write " << size << " bytes" << endl; - pic.write(p, size); - cout << "Saving picture end" << endl; - } - } - - class TestFrameStateCallback : public FrameStateCallback { - void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override - { - cout << "Receive frame complete inform." << endl; - if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { - cout << "Capture frame received." << endl; - list surfaceList = fc.GetSurfaces(); - for (Surface *surface : surfaceList) { - SurfaceBuffer *buffer = surface->AcquireBuffer(); - if (buffer != nullptr) { - char *virtAddr = static_cast(buffer->GetVirAddr()); - if (virtAddr != nullptr) { - SampleSaveCapture(virtAddr, buffer->GetSize()); - } - surface->ReleaseBuffer(buffer); - } - delete surface; - } - delete &fc; - } - } - }; - ``` - -3. Extend the **CameraStateCallback** class and customize operations when the camera state changes \(configuration successful or failed, and creation successful or failed\). - - ``` - class SampleCameraStateMng : public CameraStateCallback { - public: - SampleCameraStateMng() = delete; - SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} - ~SampleCameraStateMng() - { - if (recordFd_ != -1) { - close(recordFd_); - } - } - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} - void OnReleased(Camera &c) override {} - }; - ``` - -4. Create a **CameraKit** instance to set and obtain camera information. - - ``` - CameraKit *camKit = CameraKit::GetInstance(); - list camList = camKit->GetCameraIds(); - string camId; - for (auto &cam : camList) { - cout << "camera name:" << cam << endl; - const CameraAbility *ability = camKit->GetCameraAbility(cam); - /* Find the camera that fits your ability. */ - list sizeList = ability->GetSupportedSizes(0); - if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { - camId = cam; - break; - } - } - ``` - -5. Create a **Camera** instance. - - ``` - EventHandler eventHdlr; // Create a thread to handle callback events. - SampleCameraStateMng CamStateMng(eventHdlr); - - camKit->CreateCamera(camId, CamStateMng, eventHdlr); - ``` - -6. In the main process, synchronize configurations set by callback functions implemented in [step 1](#li378084192111), [step 2](#li8716104682913), and [step 3](#li6671035102514). - - ``` - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - - void Capture() - { - if (cam_ == nullptr) { - cout << "Camera is not ready." << endl; - return; - } - FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); - Surface *surface = Surface::CreateSurface(); - if (surface == nullptr) { - delete fc; - } - surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ - fc->AddSurface(*surface); - cam_->TriggerSingleCapture(*fc); - } - ``` - - diff --git a/en/device-dev/subsystems/development-guidelines-on-trusted-device-group-management.md b/en/device-dev/subsystems/development-guidelines-on-trusted-device-group-management.md deleted file mode 100644 index 91c4013935b5b3b8ce3cea7997dbeae25f7ac67d..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-trusted-device-group-management.md +++ /dev/null @@ -1,264 +0,0 @@ -# Development Guidelines on Trusted Device Group Management - -- [When to Use](#section18502174174019) -- [Available APIs](#section1633115419401) -- [How to Develop](#section17516229192313) -- [Debugging and Verification](#section427316292411) - -## When to Use - -When a distributed service needs to exploit the secure communication channel provided by the distributed virtual bus for different devices, it can use the trusted device group management component to create groups of trusted devices. Distributed applications can establish and use secure, trusted relationships between devices based on the authentication capabilities for devices using different HUAWEI IDs, such as PIN code, QR code, and OneHop, and the capabilities for grouped devices using the same HUAWEI ID. For a device on which you have not logged in using your HUAWEI ID, you can enter the PIN code or scan the QR code to obtain the connection and PIN code information of the device. Then you can create a group of trusted devices and add this device to the group. If other applications have created and shared their groups of trusted devices, or have logged in using the same HUAWEI ID as yours, you can call APIs to query and use the groups. - -## Available APIs - -The following tables list the innerkits APIs provided by trusted device group management. These APIs are intended for system applications only. - -**Table 1** Java APIs provided by trusted device group management - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

public static DeviceGroupManager getInstance(Abilityability, StringappID, IHichainGroupCallbackcallbackHandler)

-

Obtains a DeviceGroupManager instance and registers a listener.

-

int createGroup(String appId, String groupName, int groupType, String groupInfo)

-

Creates a group of trusted devices.

-

public int deleteGroup(String gourpId)

-

Deletes a group of trusted devices.

-

public String getLocalConnectInfo()

-

Obtains the network connection information of the local device.

-

int addMemberToGroup(String appId, long requestId, String addParams, String connectParams, int groupType)

-

Adds a member to a specified group.

-

int deleteMemberFromGroup(String appId, long requestId, String deleteParams, String connectParams)

-

Deletes a member from a specified group.

-

int cancelRequest(long requestId)

-

Cancels an ongoing request, for example, adding or deleting a member.

-

List<String> listJoinedGroups(int groupType)

-

Obtains a list of groups of a specified type to which the current device has been added.

-

List<String> listTrustedDevices(String groupId)

-

Obtains a list of devices in a specified group.

-

boolean isDeviceInGroup(String groupId, String deviceId)

-

Checks whether a specified device has been added to the given group.

-

List<String> getGroupInfo(String queryParams)

-

Obtains a list of information about the groups that match the input parameters.

-

int setFriendsList(String groupId, List<String> friendsList)

-

Adds a friend list to a specified group.

-

List<String> getFriendsList(String groupId)

-

Obtains the friend list of a specified group.

-

int registerGroupNotice(String groupId, IHichainGroupChangeListener groupChangeListener)

-

Registers a listener for changes to a specified group.

-

int revokeGroupNotice(String groupId)

-

Revokes the listener for changes to a specified group.

-
- -**Table 2** C++ APIs provided by trusted device group management for internal applications to query group information using SA - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

DeviceAuthProxy()

-

Obtains a DeviceAuthProxy instance.

-

~DeviceAuthProxy()

-

A destructor used to delete the DeviceAuthProxy instance.

-

static int CheckAccessToGroup(const std::string &groupId, const std::string &pkgName);

-

Checks whether an application with a specified bundle name can access a specified group.

-

static int CheckAccessToDevice(const std::string &connDeviceId, const std::string &pkgName);

-

Checks whether an application with a specified bundle name can access the group that contains a specified device.

-

static std::vector<std::string> GetRelatedGroupInfo(const std::string &connDeviceId);

-

Obtains information about all the groups that contain both the local device and the device with a specified ID.

-
- -## How to Develop - -To develop trusted device group management, first obtain a management instance \(a callback to obtain group operation results is registered during the process\). Then you can use the instance to add or delete members, set a friend list for a group, and perform related query operations. - -**Scenario 1**: Create a group. - -``` -private HwDeviceGroupManager hwDeviceGroupManager; -... -private HichainGroupCallback groupCallbackByA = new HichainGroupCallback() { - @Override public void onFinish(long requestId, GroupOperation operationCode, String returnData) { - - } - @Override public void onError(long requestId, GroupOperation operationCode, int errorCode, String errorReturn) { - - } - @Override public String onRequest(long requestId, GroupOperation operationCode, String reqParams) { - JSONObject onRequestJson = generateConfirmation(REQUEST_ACCEPTED); - return onRequestJson.toString(); - } -}; -... -Optional context = convertAbilityToContext(mAbility); -Context ctxt = context.get(); -hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA); -int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO); -``` - -1. Declare the private member variable of the **HwDeviceGroupManager** instance. - - ``` - private HwDeviceGroupManager hwDeviceGroupManager; - ``` - -2. Create a callback for group management operations. - - ``` - private HichainGroupCallback groupCallbackByA = new HichainGroupCallback(); - ``` - -3. Obtain a **HwDeviceGroupManager** instance. \(In distributed scenarios, the same application on different devices must use the same **APP\_ID**.\) - - ``` - hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA); - ``` - -4. Call the **createGroup** function to create a group. If **0** is returned, the creation request is submitted successfully. - - ``` - int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO); - ``` - -5. After the group is created, **onFinish** is called. In this callback, the value of **operationCode** is **OperationCode.CREATE**, indicating a group creation operation. **returnData** is in JSON format and contains the **groupId** field, indicating the ID of the created group. - -**Scenario 2**: Add an authenticated device \(member\) to a group so that you can initiate trusted, encrypted connections to the device through the distributed virtual bus. - -``` -deviceGroupManager = DeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback); -private static final String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}"; -private static final String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}"; -private static final int GROUP_TYPE = 256; -int result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE); -``` - -1. Obtain an **HwDeviceGroupManager** instance. - - ``` - deviceGroupManager = HwDeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback); - ``` - -2. Set network connection parameters for the member to add \(in JSON format\), which are network parameters supported by the distributed virtual bus, such as **WIFI\_IP**, **WIFI\_PORT**, **BLR\_MAC**, and **DEVICE\_ID**. For details about the parameters, see the distributed virtual bus development guidelines. - - ``` - String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}"; - ``` - -3. Set parameters for the member to add \(in JSON format\), including the group ID, name, and whether the member is an administrator. If the member is invited to add a group, the value of **isAdmin** is **true**; otherwise, the value of **isAdmin** is **false**. - - ``` - String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}"; - ``` - -4. Set the type of the target group to **256**, indicating a P2P group. - - ``` - private static final int GROUP_TYPE = 256; - ``` - -5. Set **generateConfirmation** of the **onRequest** function in **HichainGroupCallback**. **PIN\_CODE** indicates the PIN code, which is input by users on the UI of the service. \(In a distributed communication, two devices must use the same PIN code.\) - - ``` - private JSONObject generateConfirmation(int confirmation) { - JSONObject jsonObject = new JSONObject(); - try { jsonObject.put("pinCode", PIN_CODE); - jsonObject.put("confirmation", confirmation); - } catch (JSONException e) { - LogUtil.error(TAG, "" + e.getMessage()); - } - return jsonObject; - } - ``` - -6. Call the **addMemberToGroup** function to add the member to the group. - - ``` - result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE); - ``` - -7. Check whether **HichainGroupCallback.onFinish** is called \(**operationCode** is **OperationCode.JOIN**\). If it is called, the member is added successfully. -8. Call APIs of the distributed virtual bus to create secure sessions between devices. - -## Debugging and Verification - -1. Develop an application with OpenHarmony. - -2. Develop an application by following the development guidelines. - -3. Create a group. If the **onFinish** callback is invoked, the group is created successfully. - -4. Deploy the same application on two devices, A and B. - -5. Transmit the connection parameters of device B to device A through a QR code. - -6. In the application on device A, create group1 and call the API to add device B to group1. If **HichainGroupCallback.onFinish** is called, device B is successfully added to group1. - diff --git a/en/device-dev/subsystems/development-guidelines.md b/en/device-dev/subsystems/development-guidelines.md deleted file mode 100644 index 6f14243a239391be4a4bce69425c6cca27844187..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines.md +++ /dev/null @@ -1,11 +0,0 @@ -# Development Guidelines - -To access the AI engine framework, you need to develop the SDKs and plug-ins shown in [Figure 1](ai-engine-framework.md#fig143186187187). In this way, you can call the APIs provided by the SDKs to call the algorithm capabilities of plug-ins to implement lifecycle management and on-demand deployment of AI capabilities. - -- **[SDK](sdk.md)** - -- **[Plug-in](plug-in.md)** - -- **[Configuration File](configuration-file.md)** - - diff --git a/en/device-dev/subsystems/dfx-11.md b/en/device-dev/subsystems/dfx-11.md deleted file mode 100644 index faf8b0d8fa8e4c39a1548d7a7e77b6eb6906bd95..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/dfx-11.md +++ /dev/null @@ -1,34 +0,0 @@ -# DFX - -- [Basic Concepts](#section5635178134811) - -[Design for X](https://en.wikipedia.org/wiki/Design_for_X) \(DFX\) refers to the software design that aims to improve the quality attributes in OpenHarmony. It mainly consists of two parts: design for reliability \(DFR\) and design for testability \(DFT\). - -The DFX subsystem provides the following functions: - -- HiLog: Implements the logging function. It is applicable to Mini-System Devices \(reference memory ≥ 128 KB\), Small-System Devices \(reference memory ≥ 1 MB\), and Standard-System Devices \(reference memory ≥ 128 MB\). - -- HiSysEvent: Implements system event logging. It is applicable to Standard-System Devices \(reference memory ≥ 128 MB\). - -## Basic Concepts - -**Logging** - -Logging means to record the log information generated during system running so you can understand the running process and status of the system or applications. - -**Distributed call chain tracing** - -In a distributed system, the initiation of a service may involve multiple software modules, with control commands and data transmitted over intra-process, inter-process, and inter-device communication interfaces. To help you understand such complex communication processes and locate service faults efficiently, the DFX subsystem provides a distributed call chain tracing framework. - -**Thread suspension detection** - -If a thread is trapped in an infinite loop or the kernel state \(for example, Uninterruptable Sleep, Traced, Zombie, or synchronous wait\) when it is running, the thread cannot respond to normal service requests and cannot detect and recover from faults by itself. To detect and locate this type of faults, the DFX subsystem provides a simple watchdog mechanism by inserting detection probes to the process nodes that are prone to suspension. This ensures that suspension faults can be detected and logs can be collected. - -**Event logging** - -Event logging means to collect and log events reported during system running. The log information will help you better analyze the product usage. - -**System event** - -A system event is an indication of the system status at a given time point during system running. You can use these events to analyze the status change of the system. - diff --git a/en/device-dev/subsystems/dfx.md b/en/device-dev/subsystems/dfx.md deleted file mode 100644 index 241303cae97af3db18251e836e22ca628efba17c..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/dfx.md +++ /dev/null @@ -1,11 +0,0 @@ -# DFX - -- **[DFX](dfx-11.md)** - -- **[Development Guidelines on HiLog](development-guidelines-on-hilog.md)** - -- **[Development Guidelines on HiLog\_Lite](development-guidelines-on-hilog_lite.md)** - -- **[Development Guidelines on HiSysEvent](development-guidelines-on-hisysevent.md)** - - diff --git a/en/device-dev/subsystems/faqs.md b/en/device-dev/subsystems/faqs.md deleted file mode 100644 index f7acfe005f855c58ba12fd8bcb8cc8ae4a21e6de..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/faqs.md +++ /dev/null @@ -1,56 +0,0 @@ -# FAQs - -- [System startup interrupted due to "parse failed!" error](#section2041345718513) -- [System automatically restarted again and again](#section57381816168) -- [Failed to call the SetParameter or GetParameter API with correct parameter values](#section129991227141512) - -## System startup interrupted due to "parse failed!" error - -**Problem** - -During system startup, the error message "\[Init\] InitReadCfg, parse failed! please check file /etc/init.cfg format." is displayed, and the startup is interrupted, as shown in the following figure. - -![](figures/en-us_image_0000001063839940.png) - -**Cause** - -During the modification of the **init.cfg** file, required commas \(,\) or parentheses are missing or unnecessary ones are added. As a result, the file's JSON format becomes invalid. - -**Solution** - -Check the **init.cfg** file and ensure that its format meets the JSON specifications. - -## System automatically restarted again and again - -**Problem** - -After the image burning is complete, the system keeps restarting. - -**Cause** - -Each service started by the init process has the **importance** attribute, as described in Table 3 in [init Module](init-module.md). - -- If the attribute value is **0**, the init process does not need to restart the development board when the current service process exits. -- If the attribute value is **1**, the init process needs to restart the development board when the current service process exits. - -During the startup of a service whose **importance** is **1**, if the service exits due to a process crash or an error, the init process automatically restarts the development board. - -**Solution** - -1. View logs to identify the service that encounters a process crash or exits due to an error, rectify the issue, and then burn the image again. -2. Alternatively, change the value of **importance** to **0** for the service that exits due to a process crash or an error, and then burn the image again. In this way, the development board will not be restarted even if the service exits. - -## Failed to call the **SetParameter** or **GetParameter** API with correct parameter values - -**Problem** - -Calling the **SetParameter** or **GetParameter** API fails even if correct values are passed to all input parameters. - -**Cause** - -Permission verification has been enabled for the **SetParameter** and **GetParameter** APIs. If the UID of the caller is greater than 1000, that is, the caller does not have the permission to call these APIs, API calls will fail even if the parameters are correct. - -**Solution** - -No action is required. - diff --git a/en/device-dev/subsystems/figures/20200721-223604(espace).gif b/en/device-dev/subsystems/figure/20200721-223604(espace).gif similarity index 100% rename from en/device-dev/subsystems/figures/20200721-223604(espace).gif rename to en/device-dev/subsystems/figure/20200721-223604(espace).gif diff --git a/en/device-dev/subsystems/figures/animator-effect.gif b/en/device-dev/subsystems/figure/animator-effect.gif similarity index 100% rename from en/device-dev/subsystems/figures/animator-effect.gif rename to en/device-dev/subsystems/figure/animator-effect.gif diff --git a/en/device-dev/subsystems/figures/application-startup-process.png b/en/device-dev/subsystems/figure/application-startup-process.png similarity index 100% rename from en/device-dev/subsystems/figures/application-startup-process.png rename to en/device-dev/subsystems/figure/application-startup-process.png diff --git a/en/device-dev/subsystems/figures/architecture-of-the-ability-management-framework.png b/en/device-dev/subsystems/figure/architecture-of-the-ability-management-framework.png similarity index 100% rename from en/device-dev/subsystems/figures/architecture-of-the-ability-management-framework.png rename to en/device-dev/subsystems/figure/architecture-of-the-ability-management-framework.png diff --git a/en/device-dev/subsystems/figures/architecture-of-the-bundle-management-framework.png b/en/device-dev/subsystems/figure/architecture-of-the-bundle-management-framework.png similarity index 100% rename from en/device-dev/subsystems/figures/architecture-of-the-bundle-management-framework.png rename to en/device-dev/subsystems/figure/architecture-of-the-bundle-management-framework.png diff --git a/en/device-dev/subsystems/figure/build-process.jpg b/en/device-dev/subsystems/figure/build-process.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a48ea734509526b3ed0fe85b7c4a98b0a2a9c4f0 Binary files /dev/null and b/en/device-dev/subsystems/figure/build-process.jpg differ diff --git a/en/device-dev/subsystems/figures/component-tree-structure.png b/en/device-dev/subsystems/figure/component-tree-structure.png similarity index 100% rename from en/device-dev/subsystems/figures/component-tree-structure.png rename to en/device-dev/subsystems/figure/component-tree-structure.png diff --git a/en/device-dev/subsystems/figures/effect-of-adding-view-instances-to-a-viewgroup.png b/en/device-dev/subsystems/figure/effect-of-adding-view-instances-to-a-viewgroup.png similarity index 100% rename from en/device-dev/subsystems/figures/effect-of-adding-view-instances-to-a-viewgroup.png rename to en/device-dev/subsystems/figure/effect-of-adding-view-instances-to-a-viewgroup.png diff --git a/en/device-dev/subsystems/figures/effect-of-clicking-a-uibutton.gif b/en/device-dev/subsystems/figure/effect-of-clicking-a-uibutton.gif similarity index 100% rename from en/device-dev/subsystems/figures/effect-of-clicking-a-uibutton.gif rename to en/device-dev/subsystems/figure/effect-of-clicking-a-uibutton.gif diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001051782526.png b/en/device-dev/subsystems/figure/en-us_image_0000001051782526.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001051782526.png rename to en/device-dev/subsystems/figure/en-us_image_0000001051782526.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001052582522.png b/en/device-dev/subsystems/figure/en-us_image_0000001052582522.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001052582522.png rename to en/device-dev/subsystems/figure/en-us_image_0000001052582522.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001052662559.png b/en/device-dev/subsystems/figure/en-us_image_0000001052662559.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001052662559.png rename to en/device-dev/subsystems/figure/en-us_image_0000001052662559.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001052782555.png b/en/device-dev/subsystems/figure/en-us_image_0000001052782555.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001052782555.png rename to en/device-dev/subsystems/figure/en-us_image_0000001052782555.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001052942531.png b/en/device-dev/subsystems/figure/en-us_image_0000001052942531.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001052942531.png rename to en/device-dev/subsystems/figure/en-us_image_0000001052942531.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001053207924.gif b/en/device-dev/subsystems/figure/en-us_image_0000001053207924.gif similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001053207924.gif rename to en/device-dev/subsystems/figure/en-us_image_0000001053207924.gif diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001053247975.gif b/en/device-dev/subsystems/figure/en-us_image_0000001053247975.gif similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001053247975.gif rename to en/device-dev/subsystems/figure/en-us_image_0000001053247975.gif diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001054101094.png b/en/device-dev/subsystems/figure/en-us_image_0000001054101094.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001054101094.png rename to en/device-dev/subsystems/figure/en-us_image_0000001054101094.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001054421113.png b/en/device-dev/subsystems/figure/en-us_image_0000001054421113.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001054421113.png rename to en/device-dev/subsystems/figure/en-us_image_0000001054421113.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001059334449.png b/en/device-dev/subsystems/figure/en-us_image_0000001059334449.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001059334449.png rename to en/device-dev/subsystems/figure/en-us_image_0000001059334449.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001060200050.png b/en/device-dev/subsystems/figure/en-us_image_0000001060200050.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001060200050.png rename to en/device-dev/subsystems/figure/en-us_image_0000001060200050.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001061889268.png b/en/device-dev/subsystems/figure/en-us_image_0000001061889268.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001061889268.png rename to en/device-dev/subsystems/figure/en-us_image_0000001061889268.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001062334618.png b/en/device-dev/subsystems/figure/en-us_image_0000001062334618.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001062334618.png rename to en/device-dev/subsystems/figure/en-us_image_0000001062334618.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001062476933.png b/en/device-dev/subsystems/figure/en-us_image_0000001062476933.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001062476933.png rename to en/device-dev/subsystems/figure/en-us_image_0000001062476933.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001062942690.png b/en/device-dev/subsystems/figure/en-us_image_0000001062942690.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001062942690.png rename to en/device-dev/subsystems/figure/en-us_image_0000001062942690.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001063839940.png b/en/device-dev/subsystems/figure/en-us_image_0000001063839940.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001063839940.png rename to en/device-dev/subsystems/figure/en-us_image_0000001063839940.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001077724150.png b/en/device-dev/subsystems/figure/en-us_image_0000001077724150.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001077724150.png rename to en/device-dev/subsystems/figure/en-us_image_0000001077724150.png diff --git a/en/device-dev/subsystems/figures/en-us_image_0000001077727032.png b/en/device-dev/subsystems/figure/en-us_image_0000001077727032.png similarity index 100% rename from en/device-dev/subsystems/figures/en-us_image_0000001077727032.png rename to en/device-dev/subsystems/figure/en-us_image_0000001077727032.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001119924146.gif b/en/device-dev/subsystems/figure/en-us_image_0000001119924146.gif similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001119924146.gif rename to en/device-dev/subsystems/figure/en-us_image_0000001119924146.gif diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001166643927.jpg b/en/device-dev/subsystems/figure/en-us_image_0000001166643927.jpg similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001166643927.jpg rename to en/device-dev/subsystems/figure/en-us_image_0000001166643927.jpg diff --git a/en/device-dev/subsystems/figures/image-auto-adaption-effect.png b/en/device-dev/subsystems/figure/image-auto-adaption-effect.png similarity index 100% rename from en/device-dev/subsystems/figures/image-auto-adaption-effect.png rename to en/device-dev/subsystems/figure/image-auto-adaption-effect.png diff --git a/en/device-dev/subsystems/figures/image-tile-effect.png b/en/device-dev/subsystems/figure/image-tile-effect.png similarity index 100% rename from en/device-dev/subsystems/figures/image-tile-effect.png rename to en/device-dev/subsystems/figure/image-tile-effect.png diff --git a/en/device-dev/subsystems/figures/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel.png b/en/device-dev/subsystems/figure/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel.png similarity index 100% rename from en/device-dev/subsystems/figures/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel.png rename to en/device-dev/subsystems/figure/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel.png diff --git a/en/device-dev/subsystems/figures/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel.png b/en/device-dev/subsystems/figure/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel.png similarity index 100% rename from en/device-dev/subsystems/figures/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel.png rename to en/device-dev/subsystems/figure/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel.png diff --git a/en/device-dev/subsystems/figures/platform-architecture.png b/en/device-dev/subsystems/figure/platform-architecture.png similarity index 100% rename from en/device-dev/subsystems/figures/platform-architecture.png rename to en/device-dev/subsystems/figure/platform-architecture.png diff --git a/en/device-dev/subsystems/figures/relationship-between-a-page-ability-and-its-ability-slices.png b/en/device-dev/subsystems/figure/relationship-between-a-page-ability-and-its-ability-slices.png similarity index 100% rename from en/device-dev/subsystems/figures/relationship-between-a-page-ability-and-its-ability-slices.png rename to en/device-dev/subsystems/figure/relationship-between-a-page-ability-and-its-ability-slices.png diff --git a/en/device-dev/subsystems/figures/running-sequence-of-the-test-platform.png b/en/device-dev/subsystems/figure/running-sequence-of-the-test-platform.png similarity index 100% rename from en/device-dev/subsystems/figures/running-sequence-of-the-test-platform.png rename to en/device-dev/subsystems/figure/running-sequence-of-the-test-platform.png diff --git a/en/device-dev/subsystems/figures/scrolling-effect-in-both-horizontal-and-vertical-directions.gif b/en/device-dev/subsystems/figure/scrolling-effect-in-both-horizontal-and-vertical-directions.gif similarity index 100% rename from en/device-dev/subsystems/figures/scrolling-effect-in-both-horizontal-and-vertical-directions.gif rename to en/device-dev/subsystems/figure/scrolling-effect-in-both-horizontal-and-vertical-directions.gif diff --git a/en/device-dev/subsystems/figures/setting-a-2x2-grid-and-adding-four-buttons-in-a-layout.png b/en/device-dev/subsystems/figure/setting-a-2x2-grid-and-adding-four-buttons-in-a-layout.png similarity index 100% rename from en/device-dev/subsystems/figures/setting-a-2x2-grid-and-adding-four-buttons-in-a-layout.png rename to en/device-dev/subsystems/figure/setting-a-2x2-grid-and-adding-four-buttons-in-a-layout.png diff --git a/en/device-dev/subsystems/figures/startup-of-the-ability-manager-service-and-bundle-manager-service.png b/en/device-dev/subsystems/figure/startup-of-the-ability-manager-service-and-bundle-manager-service.png similarity index 100% rename from en/device-dev/subsystems/figures/startup-of-the-ability-manager-service-and-bundle-manager-service.png rename to en/device-dev/subsystems/figure/startup-of-the-ability-manager-service-and-bundle-manager-service.png diff --git a/en/device-dev/subsystems/figures/structure-of-common-container-components.png b/en/device-dev/subsystems/figure/structure-of-common-container-components.png similarity index 100% rename from en/device-dev/subsystems/figures/structure-of-common-container-components.png rename to en/device-dev/subsystems/figure/structure-of-common-container-components.png diff --git a/en/device-dev/subsystems/figures/tree-structure-of-common-components.png b/en/device-dev/subsystems/figure/tree-structure-of-common-components.png similarity index 100% rename from en/device-dev/subsystems/figures/tree-structure-of-common-components.png rename to en/device-dev/subsystems/figure/tree-structure-of-common-components.png diff --git a/en/device-dev/subsystems/figures/unnaming.png b/en/device-dev/subsystems/figure/unnaming.png similarity index 100% rename from en/device-dev/subsystems/figures/unnaming.png rename to en/device-dev/subsystems/figure/unnaming.png diff --git "a/en/device-dev/subsystems/figures/\345\233\276\347\211\2071.png" "b/en/device-dev/subsystems/figure/\345\233\276\347\211\2071.png" similarity index 100% rename from "en/device-dev/subsystems/figures/\345\233\276\347\211\2071.png" rename to "en/device-dev/subsystems/figure/\345\233\276\347\211\2071.png" diff --git "a/en/device-dev/subsystems/figures/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" "b/en/device-dev/subsystems/figure/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" similarity index 100% rename from "en/device-dev/subsystems/figures/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" rename to "en/device-dev/subsystems/figure/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" diff --git "a/en/device-dev/subsystems/figures/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" "b/en/device-dev/subsystems/figure/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" similarity index 100% rename from "en/device-dev/subsystems/figures/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" rename to "en/device-dev/subsystems/figure/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" diff --git a/en/device-dev/subsystems/figures/build-process.jpg b/en/device-dev/subsystems/figures/build-process.jpg deleted file mode 100644 index c8d58bc3d172524c78e3c45455622d081429529c..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/figures/build-process.jpg and /dev/null differ diff --git a/en/device-dev/subsystems/figures/building-process.jpg b/en/device-dev/subsystems/figures/building-process.jpg deleted file mode 100644 index c8d58bc3d172524c78e3c45455622d081429529c..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/figures/building-process.jpg and /dev/null differ diff --git a/en/device-dev/subsystems/figures/ril-adapter.png b/en/device-dev/subsystems/figures/ril-adapter.png deleted file mode 100644 index 51d8a0668a19b26071873247a5cf1f483d9044e5..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/figures/ril-adapter.png and /dev/null differ diff --git "a/en/device-dev/subsystems/figures/\345\216\273\347\224\265.png" "b/en/device-dev/subsystems/figures/\345\216\273\347\224\265.png" deleted file mode 100644 index fd53e705cde494b3b5a7a5e2c923a9b5ac07aa4f..0000000000000000000000000000000000000000 Binary files "a/en/device-dev/subsystems/figures/\345\216\273\347\224\265.png" and /dev/null differ diff --git "a/en/device-dev/subsystems/figures/\346\235\245\347\224\265.png" "b/en/device-dev/subsystems/figures/\346\235\245\347\224\265.png" deleted file mode 100644 index 9b27f13794e395cb6b05ec588f96bc938288ec01..0000000000000000000000000000000000000000 Binary files "a/en/device-dev/subsystems/figures/\346\235\245\347\224\265.png" and /dev/null differ diff --git a/en/device-dev/subsystems/graphics.md b/en/device-dev/subsystems/graphics.md deleted file mode 100644 index 254f1e0fa0022f821ba9ecb5f8f88846a868bfe7..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/graphics.md +++ /dev/null @@ -1,13 +0,0 @@ -# Graphics - -- **[Graphics](graphics-2.md)** - -- **[Development Guidelines on Container Components](development-guidelines-on-container-components.md)** - -- **[Development Guidelines on Layout Container Components](development-guidelines-on-layout-container-components.md)** - -- **[Development Guidelines on Common Components](development-guidelines-on-common-components.md)** - -- **[Development Guidelines on Animators](development-guidelines-on-animators.md)** - - diff --git a/en/device-dev/subsystems/hdc_std-faqs.md b/en/device-dev/subsystems/hdc_std-faqs.md deleted file mode 100644 index a767f3e60aad365ce1f66252889c5ccd3eb99773..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/hdc_std-faqs.md +++ /dev/null @@ -1,39 +0,0 @@ -# hdc\_std FAQs - -- [hdc\_std Fails to Connect to a Device](#section1221016541119) -- [hdc\_std Fails to Run](#section219185710311) - -## hdc\_std Fails to Connect to a Device - -- **Symptom** - - **\[Empty\]** is displayed in the output after the **hdc\_std list targets** command is run. - -- **Possible Causes and Solutions** - 1. The device cannot be identified. - - Check whether **HDC Device** exists in the universal serial bus device of the device manager. If **HDC Device** does not exist, the device cannot be connected. In this case, remove and then insert the device or burn the latest image for the device. - - 2. hdc\_std works improperly. - - Run the **hdc kill** or **hdc start -r** command to kill or restart the hdc service, and then run the **hdc list targets** command to check whether device information is obtained. - - If no device information is obtained, check whether the adb process exists in the task manager. If the adb process exists, kill this process because it may affect the hdc service. After that, run **hdc kill** or **hdc start -r** and then **hdc list targets** again. - - 3. hdc\_std does not match the device. - - If the latest image is burnt for the device, hdc\_std must also be of the latest version. As hdc\_std is updated continuously, obtain hdc\_std of the latest version from the **developtools\_hdc\_standard** repository in the **prebuilt** directory. - - - -## hdc\_std Fails to Run - -- **Symptom** - - The **hdc\_std.exe** file does not run after being clicked. - -- **Possible Causes and Solutions** - - **hdc\_std.exe** requires no installation and can be directly used on a disk. It can also be added to environment variables. Open the cmd window and run the **hdc\_std** command to use **hdc\_std.exe**. - - diff --git a/en/device-dev/subsystems/hdc_std-usage-guidelines.md b/en/device-dev/subsystems/hdc_std-usage-guidelines.md deleted file mode 100644 index 76a821114ce609f1355d03c91c7cc7df7b43433b..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/hdc_std-usage-guidelines.md +++ /dev/null @@ -1,656 +0,0 @@ -# hdc\_std Usage Guidelines - -- [Preparations](#section05992022154916) -- [Important Notes](#section19543134915210) -- [Global Options](#section618522925119) -- [Querying the Device List](#section174891132104218) -- [Service Process Commands](#section680531510497) -- [Network Commands](#section71176123212) -- [File Commands](#section173133523013) -- [App Commands](#section2072647133819) -- [Debugging Commands](#section112861250195015) - -hdc\_std \(OpenHarmony Device Connector\) is a command line tool provided by OpenHarmony for debugging. With hdc, you can interact with real devices or simulators from a Windows or Linux OS. - -This section describes how to build the hdc\_std environment, its common commands, and how to use the commands. - -## Preparations - -**hdc\_std obtaining method:** - -Obtain hdc\_std from the **developtools\_hdc\_standard** repository in the **prebuilt** directory. - -**Example:** - -To obtain hdc\_std on Windows, obtain the executable file **hdc\_std.exe** from **prebuilt/windows** and place it in a specified directory on the disk. - -## Important Notes - -1. If an exception occurs when you are using hdc\_std, you can run the **hdc\_std kill** command to kill the hdc\_std service or run the **hdc\_std start -r** command to restart the service process. - -2. If no device information is obtained after **hdc\_std list targets** is executed, use the task manager to check whether the **hdc.exe** process exists. If it exists, kill the process. - -## Global Options - -The following options are globally available: - -- **-h/help -v/version** - -Obtains the hdc help and version information. - -**Table 1** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

-h/help -v/version

-

None

-

Return Value

-

Description

-

Required information

-

hdc help or version information

-
- -Examples: - -hdc\_std -h / hdc\_std help - -hdc\_std -v / hdc\_std version - -- **-t key** - -Connects to a device with a specified key. - -**Table 2** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

key

-

Key that identifies the device. The value is in the IP address:Port number format or is a USB serial number.

-

Return Value

-

Description

-

1. error: device '***' not found

-

②Nothing to do...

-

1. The device does not exist.

-

2. The command does not exist.

-
- -Examples: - -This option must be used together with a specific operation command. The following uses the shell command as an example: - -hdc\_std list targets \(for obtaining device information\) - -hdc\_std -t _key_ shell \(replace _key_ with the obtained device information\) - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->You can connect to multiple devices from the device you use for development. Each device has a unique key, which is _IP address:Port number_ for a device that can be connected through a network and the serial number for a device that can be connected through USB. - -## Querying the Device List - -The following command is available: - -**list targets\[-v\]** - -Queries all the connected devices. - -**Table 3** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

-v

-

Prints detailed device information.

-

Return Value

-

Description

-

1. Device information

-

②[Empty]

-

1. A list of connected devices

-

1. No device information is found.

-
- -Examples: - -hdc\_std list targets - -hdc\_std list targets -v - -## Service Process Commands - -The following commands are available: - -- **target mount** - -Mounts a partition such as **/system** with the read and write permissions. - -**Table 4** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

None

-

None

-

Return Value

-

Description

-

①Mount finish

-

2. Returned information

-

1. Information returned when the operation is successful.

-

2. Information returned when the operation fails.

-
- -Example: - -hdc\_std target mount - -- **smode \[off\]** - -Grants the root permission to a background service process. The **off** option is used to revoke the granted permission. - -Examples: - -hdc\_std smode - -hdc\_std smode off - -- **kill \[-r\]** - -Stops a service process. - -**Table 5** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

-r

-

Triggers the service restart.

-

Return Value

-

Description

-

①Kill server finish

-

1. Error information

-

1. Information returned when the operation is successful.

-

1. The operation fails.

-
- -Example: - -hdc\_std kill - -- **start \[-r\]** - -Starts the service process. - -**Table 6** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

-r

-

Restarts the service process if it has started.

-

Return Value

-

Description

-

None

-

None

-
- -Examples: - -hdc\_std start - -## Network Commands - -The following commands are available: - -- **tconn _host_\[:_port_\]\[-remove\]** - -Connects to a device with a specified IP address and port number. - -**Table 7** Command description - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

host[:port]

-

IP address and port number of the device to be connected

-

-remove

-

Disconnects from the specified device.

-

Return Value

-

Description

-

1. Error information

-

2. None

-

1. The operation fails.

-

2. The operation is successful.

-
- -Example: - -hdc\_std tconn 192.168.0.100:8710 - -- **tmode usb** - -Restarts the daemon process and connects to the device using USB. - -**Table 8** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

None

-

None

-

Return Value

-

Description

-

1. Error information

-

2. None

-

1. The operation fails.

-

2. The operation is successful.

-
- -Example: - -hdc\_std tmode usb - -- **tmode port _port-number_** - -Restarts the daemon process and connects to the device over TCP. - -**Table 9** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

port-number

-

Port number used to connect to the device

-

Return Value

-

Description

-

1. Error information

-

2. None

-

1. The operation fails.

-

2. The operation is successful.

-
- -Example: - -hdc\_std tmode port 8710 - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->After this command is executed, the remote daemon process exits and restarts, and the TCP connection is enabled by default. If you do not include **port-number** in this command, a random port will be used to connect to the device. - -## File Commands - -The following commands are available: - -- **file send _local remote_** - -Sends a file to a remote device. - -**Table 10** Command description - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

local

-

Path of the file to send

-

remote

-

Destination path on the remote device

-

Return Value

-

Description

-

1. Error information

-

2. File transfer result

-

1. The operation fails.

-

2. The operation is successful.

-
- -Example: - -hdc\_std file send E:\\a.txt /data/local/tmp/a.txt - -- **file recv \[-a\] _remote local_** - -Receives a file from a remote device. - -**Table 11** Command description - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

-a

-

File retention timestamp mode

-

local

-

Path on the local device to receive the file

-

remote

-

File path on the remote device

-

Return Value

-

Description

-

1. Error information

-

2. None

-

1. The operation fails.

-

2. The operation is successful.

-
- -Example: - -hdc\_std file recv /data/local/tmp/a.txt ./a.txt - -## App Commands - -The following commands are available: - -- **install \[-r/-d/-g\] _package_** - -Installs the OpenHarmony application. - -**Table 12** Command description - - - - - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

package

-

OpenHarmony application installation package

-

-r

-

Replaces an existing application.

-

-d

-

Allows downgraded installation.

-

-g

-

Dynamic permission granting

-

Return Value

-

Description

-

1. Error information

-

2. None

-

1. The operation fails.

-

2. The operation is successful.

-
- -Examples: - -hdc\_std install _hwadmin.hap_ - -- **uninstall \[-k\] _package_** - -Uninstalls the OpenHarmony application. - -**Table 13** Command description - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

package

-

OpenHarmony application installation package

-

-k

-

Retains /data/cache.

-

Return Value

-

Description

-

1. Error information

-

2. None

-

1. The operation fails.

-

2. The operation is successful.

-
- -Example: - -hdc\_std uninstall _package_ - -## Debugging Commands - -The following commands are available: - -- **hilog** - -Obtains logs for debugging. - -**Table 14** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

None

-

None

-

Return Value

-

Description

-

Returned information

-

Obtained logs

-
- -Example: - -hdc\_std hilog - -- **shell \[_command_\]** - -Executes a command remotely or enters an interactive command environment. - -**Table 15** Command description - - - - - - - - - - - - - - - -

Parameter

-

Description

-

command

-

Command to be executed

-

Return Value

-

Description

-

Returned information

-

Execution result of the command

-
- -Examples: - -hdc\_std shell - diff --git a/en/device-dev/subsystems/kws-sdk.md b/en/device-dev/subsystems/kws-sdk.md deleted file mode 100644 index 50cbbfb0fbf499e95455d7bda54292094b864a4b..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/kws-sdk.md +++ /dev/null @@ -1,81 +0,0 @@ -# KWS SDK - -1. Add the API of the KWS SDK to the **//foundation/ai/engine /interfaces/kits** directory. This API can be called by third-party applications. The following code snippet is an example API for the KWS SDK. The reference code is available at the **//foundation/ai/engine /interfaces/kits/asr/keyword\_spotting** directory. - - ``` - class KWSSdk { - public: - KWSSdk(); - virtual ~KWSSdk(); - - // Create a KWS SDK instance. - int32_t Create(); - - // Synchronously execute the KWS task. - int32_t SyncExecute(const Array &audioInput); - - // Set the KWS callback. - int32_t SetCallback(const std::shared_ptr &callback); - - // Destroy the KWS SDK instance to release the session engaged with the plug-in. - int32_t Destroy(); - }; - ``` - -2. Add the API implementation of the SDK to the **//foundation/ai/engine/services/client/algorithm\_sdk** directory and call the APIs provided by the client to use the algorithm plug-in capabilities. The following code snippet is an example implementation of the **create** method in the API of the KWS SDK. For more details, see the reference code at **//foundation/ai/engine/services/client/algorithm\_sdk/asr/keyword\_spotting**. - - ``` - int32_t KWSSdk::KWSSdkImpl::Create() - { - if (kwsHandle_ != INVALID_KWS_HANDLE) { - HILOGE("[KWSSdkImpl]The SDK has been created"); - return KWS_RETCODE_FAILURE; - } - if (InitComponents() != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]Fail to init sdk components"); - return KWS_RETCODE_FAILURE; - } - // Call the AieClientInit API provided by the client to initialize the engine service and activate IPC call. - int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr); - if (retCode != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode); - return KWS_RETCODE_FAILURE; - } - if (clientInfo_.clientId == INVALID_CLIENT_ID) { - HILOGE("[KWSSdkImpl]Fail to allocate client id"); - return KWS_RETCODE_FAILURE; - } - DataInfo inputInfo = { - .data = nullptr, - .length = 0, - }; - DataInfo outputInfo = { - .data = nullptr, - .length = 0, - }; - // Call the AieClientPrepare API provided by the client to load the algorithm plug-in. - retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr); - if (retCode != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode); - return KWS_RETCODE_FAILURE; - } - if (outputInfo.data == nullptr || outputInfo.length <= 0) { - HILOGE("[KWSSdkImpl]The data or length of output info is invalid"); - return KWS_RETCODE_FAILURE; - } - MallocPointerGuard pointerGuard(outputInfo.data); - retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_); - if (retCode != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]Get handle from inputInfo failed"); - return KWS_RETCODE_FAILURE; - } - return KWS_RETCODE_SUCCESS; - } - ``` - - The preceding code is the specific API implementation. The **create** function in the API of the KWS SDK calls the open **AieClientInit** and **AieClientPrepare** APIs provided by the client to connect to the server and load the algorithm model. For details, see the implementation of the **create** method in following sections. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >The sequence for the SDK to call client APIs: **AieClientInit** -\> **AieClientPrepare** -\> **AieClientSyncProcess** or **AieClientAsyncProcess** -\> **AieClientRelease** -\> **AieClientDestroy**. An exception will be thrown if the call sequence is violated. - - diff --git a/en/device-dev/subsystems/multimedia.md b/en/device-dev/subsystems/multimedia.md deleted file mode 100644 index 47ec966c82b0b54452feb625537d36538ca9c14e..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/multimedia.md +++ /dev/null @@ -1,7 +0,0 @@ -# Multimedia - -- **[Camera](camera.md)** - -- **[Audio/Video](audio-video.md)** - - diff --git a/en/device-dev/subsystems/oem_subsys_toolchain_hdc_guide.md b/en/device-dev/subsystems/oem_subsys_toolchain_hdc_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..8116d317a2f56abdd4fcd5304d2c5076fd5fdf6b --- /dev/null +++ b/en/device-dev/subsystems/oem_subsys_toolchain_hdc_guide.md @@ -0,0 +1,706 @@ +# hdc\_std Usage Guidelines + +- [Preparations](#section05992022154916) +- [Important Notes](#section19543134915210) +- [Option-related Commands](#section618522925119) + - [-h/help -v/version](#section51533527212) + - [-t key](#section1180555115159) + +- [Querying the Device List](#section174891132104218) + - [list targets\[-v\]](#section12911142313168) + +- [Service Process Commands](#section680531510497) + - [target mount](#section396717571168) + - [smode \[off\]](#section179951621713) + - [kill \[-r\]](#section419144621712) + - [start \[-r\]](#section184811812183) + +- [Network Commands](#section71176123212) + - [tconn host\[:port\]\[-remove\]](#section191911334206) + - [tmode usb](#section17840182562015) + - [tmode port port-number](#section101113462113) + +- [File Commands](#section173133523013) + - [file send local remote](#section126223231307) + - [file recv \[-a\] remote local](#section26966541304) + +- [App Commands](#section2072647133819) + - [install \[-r/-d/-g\] package](#section49615195111) + - [uninstall \[-k\] package](#section167618461814) + +- [Debugging Commands](#section112861250195015) + - [hilog](#section32171612221) + - [shell \[command\]](#section524235625) + +- [Troubleshooting](#section592920255582) + - [hdc\_std Fails to Connect to a Device](#section74019384588) + +- [hdc\_std Fails to Run](#section6825095917) + +hdc\_std \(OpenHarmony Device Connector\) is a command line tool provided by OpenHarmony for debugging. With this tool, you can interact with real devices or simulators from a Windows or Linux OS. + +This section describes how to set up the hdc\_std environment and use its common commands. + +## Preparations + +**Obtaining hdc\_std:** + +Obtain hdc\_std from the **developtools\_hdc\_standard** repository in the **prebuilt** directory. + +**Example:** + +To obtain hdc\_std on Windows, obtain the executable file **hdc\_std.exe** from **prebuilt/windows** and place it in a directory on the disk. + +## Important Notes + +- If an exception occurs when you are using hdc\_std, run the **hdc\_std kill** command to kill the hdc\_std service or run the **hdc\_std start -r** command to restart the service process. +- If no device information is obtained after **hdc\_std list targets** is executed, use the task manager to check whether the **hdc.exe** process exists. If it exists, kill the process. + +## Option-related Commands + +The following commands are available: + +### -h/help -v/version + +Obtains hdc help and version information. + +**Table 1** Command description + + + + + + + + + +

Return Value

+

Description

+

Required information

+

hdc help or version information

+
+ +Examples: + +hdc\_std -h / hdc\_std help + +hdc\_std -v / hdc\_std version + +### -t key + +Connects to a device with a specified key. + +**Table 2** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

key

+

Key that identifies the device. The value is in the IP address:Port number format or is a USB serial number.

+

Return Value

+

Description

+

1. error: device '***' not found

+

②Nothing to do...

+

1. The device does not exist.

+

2. The command appended to -t key does not exist.

+
+ +Examples: + +This option must be used together with a specific operation command. The following uses the shell command as an example: + +**hdc\_std list targets** \(obtain device information\) + +**hdc\_std -t _key_ shell** \(replace _key_ with the device information obtained\) + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>You can connect to multiple devices from the device you use for development. Each device has a unique key. The key can be _IP address:Port number_ for a device connected through a network or the serial number for a device connected through USB. + +## Querying the Device List + +The following command is used to query the device list: + +### list targets\[-v\] + +Displays all the connected devices. + +**Table 3** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

-v

+

Prints detailed device information.

+

Return Value

+

Description

+

1. Device information

+

②[Empty]

+

1. A list of connected devices

+

2. No device information is found.

+
+ +Examples: + +hdc\_std list targets + +hdc\_std list targets -v + +## Service Process Commands + +The following commands are available: + +### target mount + +Mounts a partition, such as **/system**, with the read and write permissions. + +**Table 4** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

None

+

None

+

Return Value

+

Description

+

①Mount finish

+

2. Returned information

+

1. Information returned when the operation is successful.

+

2. Information returned when the operation fails.

+
+ +Example: + +hdc\_std target mount + +### smode \[off\] + +Grants the root permission to a background service process. The **off** option is used to revoke the granted permission. + +Examples: + +hdc\_std smode + +hdc\_std smode off + +### kill \[-r\] + +Stops a service process. + +**Table 5** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

-r

+

Triggers the service restart.

+

Return Value

+

Description

+

①Kill server finish

+

2. Error information

+

1. Information returned when the operation is successful.

+

2. The operation fails.

+
+ +Example: + +hdc\_std kill + +### start \[-r\] + +Starts a service process. + +**Table 6** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

-r

+

Restarts the service process if it has started.

+

Return Value

+

Description

+

None

+

None

+
+ +Examples: + +hdc\_std start + +## Network Commands + +The following commands are available: + +### tconn _host_\[:_port_\]\[-remove\] + +Connects to a device with a specified IP address and port number. + +**Table 7** Command description + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

host[:port]

+

IP address and port number of the device to be connected

+

-remove

+

Disconnects from the specified device.

+

Return Value

+

Description

+

1. Error information

+

2. None

+

1. The operation fails.

+

2. The operation is successful.

+
+ +Example: + +hdc\_std tconn 192.168.0.100:8710 + +### tmode usb + +Restarts the daemon process and connects to the device using USB. + +**Table 8** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

None

+

None

+

Return Value

+

Description

+

1. Error information

+

2. None

+

1. The operation fails.

+

2. The operation is successful.

+
+ +Example: + +hdc\_std tmode usb + +### tmode port _port-number_ + +Restarts the daemon process and connects to the device over TCP. + +**Table 9** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

port-number

+

Port number used to connect to the device

+

Return Value

+

Description

+

1. Error information

+

2. None

+

1. The operation fails.

+

2. The operation is successful.

+
+ +Example: + +hdc\_std tmode port 8710 + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>After this command is executed, the remote daemon process exits and restarts, and the TCP connection is enabled by default. If you do not include **port-number** in this command, a random port will be used to connect to the device. + +## File Commands + +The following commands are available: + +### file send _local remote_ + +Sends a file to a remote device. + +**Table 10** Command description + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

local

+

Path of the file to send

+

remote

+

Destination path on the remote device

+

Return Value

+

Description

+

1. Error information

+

2. File transfer result

+

1. The operation fails.

+

2. The operation is successful.

+
+ +Example: + +hdc\_std file send E:\\a.txt /data/local/tmp/a.txt + +### file recv \[-a\] _remote local_ + +Receives a file from a remote device. + +**Table 11** Command description + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

-a

+

File retention timestamp mode

+

local

+

Path on the local device to receive the file

+

remote

+

File path on the remote device

+

Return Value

+

Description

+

1. Error information

+

2. None

+

1. The operation fails.

+

2. The operation is successful.

+
+ +Example: + +hdc\_std file recv /data/local/tmp/a.txt ./a.txt + +## App Commands + +The following commands are available: + +### install \[-r/-d/-g\] _package_ + +Installs the OpenHarmony application. + +**Table 12** Command description + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

package

+

OpenHarmony application installation package

+

-r

+

Replaces an existing application.

+

-d

+

Allows downgraded installation.

+

-g

+

Grants permission dynamically

+

Return Value

+

Description

+

1. Error information

+

2. None

+

1. The operation fails.

+

2. The operation is successful.

+
+ +Example: + +hdc\_std install _hwadmin.hap_ + +### uninstall \[-k\] _package_ + +Uninstalls the OpenHarmony application. + +**Table 13** Command description + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

package

+

OpenHarmony application installation package

+

-k

+

Retains /data/cache.

+

Return Value

+

Description

+

1. Error information

+

2. None

+

1. The operation fails.

+

2. The operation is successful.

+
+ +Example: + +hdc\_std uninstall _package_ + +## Debugging Commands + +The following commands are available: + +### hilog + +Obtains logs for debugging. + +**Table 14** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

None

+

None

+

Return Value

+

Description

+

Returned information

+

Obtained logs

+
+ +Example: + +hdc\_std hilog + +### shell \[_command_\] + +Executes a command remotely or enters an interactive command environment. + +**Table 15** Command description + + + + + + + + + + + + + + + +

Parameter

+

Description

+

command

+

Command to be executed

+

Return Value

+

Description

+

Returned information

+

Execution result of the command

+
+ +Examples: + +hdc\_std shell + +## Troubleshooting + +### hdc\_std Fails to Connect to a Device + +- **Symptom** + + **\[Empty\]** is displayed in the output after the **hdc\_std list targets** command is executed. + +- **Solutions** + 1. The device cannot be identified. + + Check whether **HDC Device** exists in the universal serial bus device of the device manager. If **HDC Device** does not exist, the device cannot be connected. In this case, remove and then insert the device or burn the latest image for the device. + + 2. hdc\_std works improperly. + + Run the **hdc kill** or **hdc start -r** command to kill or restart the hdc service. Then, run the **hdc list targets** command to check whether device information can be obtained. + + 3. hdc\_std does not match the device. + + If the latest image is burnt on the device, the latest hdc\_std version must be used. As hdc\_std is updated continuously, obtain hdc\_std of the latest version from the **developtools\_hdc\_standard** repository in the **prebuilt** directory. + + + +## hdc\_std Fails to Run + +- **Symptom** + + The **hdc\_std.exe** file does not run after being clicked. + +- **Solutions** + + **hdc\_std.exe** requires no installation. It can be directly used on a disk or added to environment variables. Open the cmd window and run the **hdc\_std** command to use **hdc\_std.exe**. + + diff --git a/en/device-dev/subsystems/utils-overview.md b/en/device-dev/subsystems/oem_subsys_utils_des.md similarity index 100% rename from en/device-dev/subsystems/utils-overview.md rename to en/device-dev/subsystems/oem_subsys_utils_des.md diff --git a/en/device-dev/subsystems/utils-faq.md b/en/device-dev/subsystems/oem_subsys_utils_faq.md similarity index 100% rename from en/device-dev/subsystems/utils-faq.md rename to en/device-dev/subsystems/oem_subsys_utils_faq.md diff --git a/en/device-dev/subsystems/oem_subsys_utils_guide.md b/en/device-dev/subsystems/oem_subsys_utils_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..48a566a1a921eb5f3a6fcaadbc2b47a852b0b2aa --- /dev/null +++ b/en/device-dev/subsystems/oem_subsys_utils_guide.md @@ -0,0 +1,293 @@ +# Utils Development Guidelines + +- [Available APIs](#section1633115419401) +- [How to Develop](#section17450172710292) + - [Developing a Native Application for the KV Store That Uses the LiteOS Cortex-A Kernel \(Hi3516 or Hi3518\)](#section258354119295) + - [Dumping System Attributes on the Platform That Uses the LiteOS Cortex-M Kernel](#section9179161863014) + - [Dumping System Attributes on the Platform That Uses the LiteOS Cortex-A Kernel](#section3179121853017) + + +## Available APIs + +**Table 1** APIs for file operations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

int UtilsFileOpen(const char* path, int oflag, int mode)

+

Opens or creates a file.

+

int UtilsFileClose(int fd)

+

Closes a file with a specified file descriptor.

+

int UtilsFileRead(int fd, char *buf, unsigned int len)

+

Reads a specified length of data from a file with the specified file descriptor and writes the data into the buffer.

+

int UtilsFileWrite(int fd, const char *buf, unsigned int len)

+

Writes a specified length of data into a file with the specified file descriptor.

+

int UtilsFileDelete(const char *path)

+

Deletes a specified file.

+

int UtilsFileStat(const char *path, unsigned int *fileSize)

+

Obtains the file size.

+

int UtilsFileSeek(int fd, int offset, unsigned int whence)

+

Adjusts the read and write position offset in a file.

+

int UtilsFileCopy(const char* src, const char* dest)

+

Copies the source file to a target file.

+

int UtilsFileMove(const char* src, const char* dest)

+

Moves the source file into a target file.

+
+ +Sample code for file operations: + +``` +// Open a file and write data. +char fileName[] = "testfile"; +static const char def[] = "utils_file_operation implement."; +int fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0); +printf("file handle = %d\n", fd); +int ret = UtilsFileWrite(fd, def, strlen(def)); +printf("write ret = %d\n", ret); + +// Adjust the position offset in the file. +ret = UtilsFileSeek(fd, 5, SEEK_SET_FS); +printf("lseek ret = %d\n", ret); + +// Read data and close the file. +char buf[64] = {0}; +int readLen = UtilsFileRead(fd, buf, 64); +ret = UtilsFileClose(fd); +printf("read len = %d : buf = %s\n", readLen, buf); + +// Obtain the file size. +int fileLen = 0; +ret = UtilsFileStat(fileName, &fileLen); +printf("file size = %d\n", fileLen); + +// Delete the file. +ret = UtilsFileDelete(fileName); +printf("delete ret = %d\n", ret); +``` + +**Table 2** APIs for KV store operations + + + + + + + + + + + + + + + + +

Function

+

Description

+

int UtilsGetValue(const char* key, char* value, unsigned int len)

+

Obtains the value matching a specified key from the file system or cache.

+

int UtilsSetValue(const char* key, const char* value)

+

Adds or updates the value matching a specified key in the file system or cache.

+

int UtilsDeleteValue(const char* key)

+

Deletes the value matching a specified key from the file system or cache.

+
+ +Sample code for the KV store: + +``` +// Set the value matching the specified key. +char key[] = "rw.sys.version_100"; +char value[] = "Hello kv operation implement!"; +int ret = UtilsSetValue(key, value); +printf("UtilsSetValue set ret = %d\n", ret); + +// Obtain the value matching the specified key. +char temp[128] = {0}; +ret = UtilsGetValue(key, temp, 128); +printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); + +// Delete the value matching the specified key. +ret = UtilsDeleteValue(key); +printf("UtilsDeleteValue delete ret = %d\n", ret); +``` + +## How to Develop + +### Developing a Native Application for the KV Store That Uses the LiteOS Cortex-A Kernel \(Hi3516 or Hi3518\) + +1. Develop the native application for the KV store using **AbilityKit** APIs. + - Write the user program by calling the APIs provided by the KV store and compile the **libLauncher.so** file. + + ``` + // Set the value matching the specified key. + char key[] = "rw.sys.version_100"; + char value[] = "Hello kv operation implement!"; + int ret = UtilsSetValue(key, value); + printf("UtilsSetValue set ret = %d\n", ret); + + // Obtain the value matching the specified key. + char temp[128] = {0}; + ret = UtilsGetValue(key, temp, 128); + printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); + + // Delete the value matching the specified key. + ret = UtilsDeleteValue(key); + printf("UtilsDeleteValue delete ret = %d\n", ret); + ``` + + - Edit the **config.json** file as follows: + + ``` + { + "app": { + "bundleName": "com.huawei.launcher", + "vendor": "huawei", + "version": { + "code": 1, + "name": "1.0" + } + }, + "deviceConfig": { + "default": { + "reqSdk": { + "compatible": "zsdk 1.0.0", + "target": "zsdk 1.0.1" + }, + "keepAlive": false + }, + "smartCamera": { + "reqSdk": { + "compatible": "zsdk 1.0.0", + "target": "zsdk 1.0.1" + }, + "keepAlive": false + } + }, + "module": { + "package": "com.huawei.launcher", + "name": ".MyHarmonyAbilityPackage", + "deviceType": [ + "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "Launcher", + "moduleType": "entry" + }, + "abilities": [{ + "name": "MainAbility", + "icon": "res/drawable/phone.png", + "label": "test app 1", + "launchType": "standard", + "type": "page" + }, + { + "name": "SecondAbility", + "icon": "res/drawable/phone.png", + "label": "test app 2", + "launchType": "standard", + "type": "page" + }, + { + "name": "ServiceAbility", + "icon": "res/drawable/phone.png", + "label": "test app 2", + "launchType": "standard", + "type": "service" + } + ] + } + } + ``` + + + - Generate a HAP file. + + - Add resource files in the **res/drawable** directory based on the following directory structure. + + ![](figure/unnaming.png) + + - Compress the **libLauncher.so**, **config.json**, and resource files into a ZIP package and change the file name extension to **.hap**, for example, **Launcher.hap**. + + +2. Connect the development board and send the command for installing the native KV store application to the board through the serial port. + + ``` + ./nfs/dev_tools/bin/bm install -p /nfs/Launcher.hap + ``` + +3. Send the command for running the native KV store application to the board through the serial port. + + ``` + ./nfs/dev_tools/bin/aa start -p com.huawei.launcher -n ServiceAbility + ``` + + +### Dumping System Attributes on the Platform That Uses the LiteOS Cortex-M Kernel + +1. Connect the development board and send the **AT+SYSPARA** command to the board through the serial port. + + ``` + AT+SYSPARA + ``` + + **Figure 1** Output of the system attribute dumping command for the LiteOS Cortex-M kernel + ![](figure/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel.png "output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel") + + +### Dumping System Attributes on the Platform That Uses the LiteOS Cortex-A Kernel + +1. Connect the development board and run the **os\_dump --help** command in the **bin** directory to view the **os\_dump** help information. + + ``` + ./bin/os_dump --help + ``` + +2. Run the **os\_dump -l** command in the **bin** directory to view system modules that support attribute dumping. + + ``` + ./bin/os_dump -l + ``` + +3. Run the **os\_dump syspara** command in the **bin** directory to dump the current system attributes. + + ``` + ./bin/os_dump syspara + ``` + + **Figure 2** Output of the system attribute dumping command for the LiteOS Cortex-A kernel + ![](figure/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel.png "output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel") + + diff --git a/en/device-dev/subsystems/ota-upgrade.md b/en/device-dev/subsystems/ota-upgrade.md deleted file mode 100644 index 6e6a648ba8aa60a29d3263ceb53401e4cfc5802f..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/ota-upgrade.md +++ /dev/null @@ -1,358 +0,0 @@ -# OTA Upgrade - -- [Limitations and Constraints](#section691733275418) -- [Generating a Public/Private Key Pair](#section94411533155010) -- [Generating an Upgrade Package](#section632383718539) -- [Uploading the Upgrade Package](#section5772112473213) -- [Downloading the Upgrade Package](#section251732474917) -- [Integrating OTA Update Capabilities](#section298217330534) -- [API Application Scenario \(Default\)](#section7685171192916) - - [How to Develop](#section0745926153017) - - [Sample Code](#section1337111363306) - -- [API Application Scenario \(Custom\)](#section1686395317306) - - [How to Develop](#section524515314317) - - [Sample Code](#section525974743120) - -- [Upgrading the System](#section151997114334) - -Over the Air \(OTA\) is a technology that makes it easier for you to remotely update devices, such as IP cameras. A device can be upgraded with a full or differential package. A full package contains all content of a new system, and a differential package contains the differences between the old and new systems. Currently, only the full-package upgrade is supported. - -## Limitations and Constraints - -- The open-source suites for devices developed based on Hi3861, Hi3518E V300 and Hi3516D V300 are supported. -- Devices developed based on Hi3518E V300 and Hi3516D V300 must support the SD card in the Virtual Festival of Aerobatic Teams \(VFAT\) format. - -## Generating a Public/Private Key Pair - -1. Download the OpenSSL tool from the following website and install it on a Windows PC, and configure environment variables. - - [http://slproweb.com/products/Win32OpenSSL.html](http://slproweb.com/products/Win32OpenSSL.html) - -2. Access the **tools\\update\_tools\\update\_pkg\_tools** directory, download the upgrade package making tool, and save it to a local directory, for example, **D:\\ota\_tools**. -3. Run **Generate\_public\_private\_key.bat** in the **ota\_tools\\key** directory to generate **Metis\_PUBLIC.key**, **private.key**, and **public\_arr.txt** that contains public values, as shown in the following figure. Keep the private key properly. - - **Figure 1** Generating a Public/Private Key Pair - - - ![](figures/en-us_image_0000001060200050.png) - -4. Use the array written in **public\_arr.txt** as a substitute for **g\_pubKeyBuf** in **base\\update\\ota\_lite\\frameworks\\source\\verify\\hota\_verify.c** of the OTA module. - - Example array in **public\_arr.txt**: - - ``` - 0x30,0x82,0x1,0xa,0x2,0x82,0x1,0x1,0x0,0xc7,0x8c,0xf3,0x91,0xa1,0x98,0xbf,0xb1,0x8c, - 0xbe,0x22,0xde,0x32,0xb2,0xfa,0xec,0x2c,0x69,0xf6,0x8f,0x43,0xa7,0xb7,0x6f,0x1e,0x4a,0x97, - 0x4b,0x27,0x5d,0x56,0x33,0x9a,0x73,0x4e,0x7c,0xf8,0xfd,0x1a,0xf0,0xe4,0x50,0xda,0x2b,0x8, - 0x74,0xe6,0x28,0xcc,0xc8,0x22,0x1,0xa8,0x14,0x9,0x46,0x46,0x6a,0x10,0xcd,0x39,0xd,0xf3, - 0x4a,0x7f,0x1,0x63,0x21,0x33,0x74,0xc6,0x4a,0xeb,0x68,0x40,0x55,0x3,0x80,0x1d,0xd9,0xbc, - 0xd4,0xb0,0x4a,0x84,0xb7,0xac,0x43,0x1d,0x76,0x3a,0x61,0x40,0x23,0x3,0x88,0xcc,0x80,0xe, - 0x75,0x10,0xe4,0xad,0xac,0xb6,0x4c,0x90,0x8,0x17,0x26,0x21,0xff,0xbe,0x1,0x82,0x16,0x76, - 0x9a,0x1c,0xee,0x8e,0xd9,0xb0,0xea,0xd5,0x50,0x61,0xcc,0x9c,0x2e,0x78,0x15,0x2d,0x1f,0x8b, - 0x94,0x77,0x30,0x39,0x70,0xcf,0x16,0x22,0x82,0x99,0x7c,0xe2,0x55,0x37,0xd4,0x76,0x9e,0x4b, - 0xfe,0x48,0x26,0xc,0xff,0xd9,0x59,0x6f,0x77,0xc6,0x92,0xdd,0xce,0x23,0x68,0x83,0xbd,0xd4, - 0xeb,0x5,0x1b,0x2a,0x7e,0xda,0x9a,0x59,0x93,0x41,0x7b,0x4d,0xef,0x19,0x89,0x4,0x8d,0x5, - 0x7d,0xbc,0x3,0x1f,0x77,0xe6,0x3d,0xa5,0x32,0xf5,0x4,0xb7,0x9c,0xe9,0xfa,0x6e,0xc,0x9f, - 0x4,0x62,0xfe,0x2a,0x5f,0xbf,0xeb,0x9a,0x73,0xa8,0x2a,0x72,0xe3,0xf0,0x57,0x56,0x5c,0x59, - 0x14,0xdd,0x79,0x11,0x42,0x3a,0x48,0xf7,0xe8,0x80,0xb1,0xaf,0x1c,0x40,0xa2,0xc6,0xec,0xf5, - 0x67,0xc1,0x88,0xf6,0x26,0x5c,0xd3,0x11,0x5,0x11,0xed,0xb1,0x45,0x2,0x3,0x1,0x0,0x1, - ``` - - Example configuration for the public key of the OTA module: - - ``` - #define PUBKEY_LENGTH 270 - - static uint8 g_pubKeyBuf[PUBKEY_LENGTH] = { - 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, - 0x63, 0x07, 0x84, 0xCF, 0x37, 0xF0, 0x45, 0xE8, 0xB9, 0x6E, 0xEF, 0x04, 0x88, 0xD3, 0x43, 0x06, - ``` - -5. \(Optional\) For Hi3518E V300 and Hi3516D V300 suites, further replace the array written in **g\_pub\_key** with that in **public\_arr.txt**. The **g\_pub\_key** file is provided in **device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\verify\\update\_public\_key.c** of the U-Boot module. - - Example configuration for the public key of the U-Boot module: - - ``` - static unsigned char g_pub_key[PUBKEY_LEN] = { - 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, - 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, - ``` - - -## Generating an Upgrade Package - -1. Save the files to be upgraded in the **ota\_tools\\Components** directory. - - **Figure 2** Location of original image files - - - ![](figures/en-us_image_0000001061889268.png) - - **Table 1** Files to be upgraded - - - - - - - - - - - - - - - - - - - - - - -

File

-

Description

-

u-boot.bin

-

Renamed from the u-boot-hi351XevX00.bin file generated after compilation.

-

kernel.bin

-

Renamed from the liteos.bin or kernel file generated after compilation.

-

rootfs.img

-

Renamed from the rootfs_xxxxx.img file generated after compilation.

-

config

-

Provides development board and kernel information. For details, see the SD card burning description of the corresponding open-source suite.

-

OTA.tag

-

Contains 32 bytes in the package_type:otaA1S2D3F4G5H6J7K8 format. The last 16 bytes are random, varying with the version.

-
- -2. Open the **packet\_harmony.xml** file in **ota\_tools\\xml** to modify **compAddr** as follows. Other items are reserved. - - Example configuration for the component information: - - ``` - - - .\Components\rootfs_jffs2.img - .\Components\liteos.bin - .\Components\userfs_jffs2.img - - ``` - -3. Configure the paths of private and public keys in **packet\_harmony.xml**. - - Example configuration for paths of private and public keys: - - ``` - - .\key\private.key - .\key\Metis_PUBLIC.key - - ``` - -4. Configure the product name and software version in **ota\_tools\\VersionDefine.bat** for anti-rollback. - - Example configuration for the product name and software version: - - ``` - set FILE_PRODUCT_NAME=Hisi - - @rem Set the software version number to a string of no more than 16 characters. - set SOFTWARE_VER=OHOS_1.1 - ``` - -5. Run **Make\_Harmony\_PKG.bat** in the **ota\_tools** directory to generate the **Hisi\_OpenHarmony 1.1.bin** upgrade package. The upgrade package is signed using **SHA-256** and **RSA 2048** to ensure its integrity and validity. - - **Figure 3** Upgrade package making tool - - - ![](figures/en-us_image_0000001059334449.png) - - -## Uploading the Upgrade Package - -Upload the **Hisi\_OpenHarmony 1.1.bin** upgrade package to the vendor's OTA server. - -## Downloading the Upgrade Package - -1. Download the **Hisi\_OpenHarmony 1.1.bin** upgrade package from the OTA server. -2. \(Optional\) Insert an SD card \(capacity greater than 100 MB\) if the device is developed based on Hi3518E V300 or Hi3516D V300. - -## Integrating OTA Update Capabilities - -- If vendors request OTA capabilities, use the dynamic library **libhota.so** and include the header files **hota\_partition.h** and **hota\_updater.h** in **base\\update\\ota\_lite\\interfaces\\kits**. -- The **libhota.so** source code is stored in **base\\update\\ota\_lite\\frameworks\\source**. -- For details about how to use APIs, see [API Application Scenario \(Default\)](#section7685171192916) and OTA APIs in _API Reference_. -- If the development board needs to be adapted, see the **base\\update\\ota\_lite\\hals\\hal\_hota\_board.h** header file. - -## API Application Scenario \(Default\) - -The upgrade package is generated by following the instructions provided in [Generating a Public/Private Key Pair](#section94411533155010) and [Generating an Upgrade Package](#section632383718539). - -### **How to Develop** - -1. Download the upgrade package for the current device, and then call the **HotaInit** function to initialize the OTA module. -2. Call the **HotaWrite** function to verify, parse, and write data streams into the device. -3. Call the **HotaRestart** function to restart the system. - - If you want to cancel the upgrade, call the **HotaCancel** function. - - -### **Sample Code** - -Perform an OTA update using the upgrade package format and verification method provided by OpenHarmony. - -``` -int main(int argc, char **argv) -{ - printf("this is update print!\r\n"); - if (HotaInit(NULL, NULL) < 0) { - printf("ota update init fail!\r\n"); - return -1; - } - int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) { - printf("file open failed, fd = %d\r\n", fd); - (void)HotaCancel(); - return -1; - } - int offset = 0; - int fileLen = lseek(fd, 0, SEEK_END); - int leftLen = fileLen; - while (leftLen > 0) { - if (lseek(fd, offset, SEEK_SET) < 0) { - close(fd); - printf("lseek fail!\r\n"); - (void)HotaCancel(); - return -1; - } - int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; - (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); - if (read(fd, g_readBuf, tmpLen) < 0) { - close(fd); - printf("read fail!\r\n"); - (void)HotaCancel(); - return -1; - } - if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { - printf("ota write fail!\r\n"); - close(fd); - (void)HotaCancel(); - return -1; - } - offset += READ_BUF_LEN; - leftLen -= tmpLen; - } - close(fd); - printf("ota write finish!\r\n"); - printf("device will reboot in 10s...\r\n"); - sleep(10); - (void)HotaRestart(); - return 0; -} -``` - -## API Application Scenario \(Custom\) - -The upgrade package is generated in other ways instead of by referring to the preceding two sections. - -### **How to Develop** - -1. Download the upgrade package for the current device, and then call the **HotaInit** function to initialize the OTA module. -2. Call the **HotaSetPackageType** function to set the package type to **NOT\_USE\_DEFAULT\_PKG**. -3. Call the **HotaWrite** function to write data streams into the device. -4. Call the **HotaRead** function to read data. Vendors can choose to verify the data. -5. \(Optional\) Call the **HotaSetBootSettings** function to set the startup tag used for entering the U-Boot mode after restarting the system. -6. Call the **HotaRestart** function to restart the system. - - If you want to cancel the upgrade, call the **HotaCancel** function. - - -### **Sample Code** - -Perform an OTA update using the upgrade package format and verification method not provided by OpenHarmony. - -``` -int main(int argc, char **argv) -{ - printf("this is update print!\r\n"); - if (HotaInit(NULL, NULL) < 0) { - printf("ota update init fail!\r\n"); - (void)HotaCancel(); - return -1; - } - (void)HotaSetPackageType(NOT_USE_DEFAULT_PKG); - int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) { - printf("file open failed, fd = %d\r\n", fd); - (void)HotaCancel(); - return -1; - } - int offset = 0; - int fileLen = lseek(fd, 0, SEEK_END); - int leftLen = fileLen; - while (leftLen > 0) { - if (lseek(fd, offset, SEEK_SET) < 0) { - close(fd); - printf("lseek fail!\r\n"); - (void)HotaCancel(); - return -1; - } - int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; - (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); - if (read(fd, g_readBuf, tmpLen) < 0) { - close(fd); - printf("read fail!\r\n"); - (void)HotaCancel(); - return -1; - } - if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { - printf("ota write fail!\r\n"); - close(fd); - (void)HotaCancel(); - return -1; - } - offset += READ_BUF_LEN; - leftLen -= tmpLen; - } - close(fd); - printf("ota write finish!\r\n"); - leftLen = fileLen; - while (leftLen > 0) { - int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; - (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); - if (HotaRead(offset, READ_BUF_LEN, (unsigned char *)g_readBuf) != 0) {} - printf("ota write fail!\r\n"); - (void)HotaCancel(); - return -1; - } - /* do your verify and parse */ - offset += READ_BUF_LEN; - leftLen -= tmpLen; - } - /* set your boot settings */ - (void)HotaSetBootSettings(); - printf("device will reboot in 10s...\r\n"); - sleep(10); - (void)HotaRestart(); - return 0; -} -``` - -## Upgrading the System - -Vendor applications call APIs of the OTA module to perform functions such as signature verification of the upgrade package, anti-rollback, burning and data flushing-to-disk. After the upgrade is complete, the system automatically restarts. - -For Hi3518E V300 and Hi3516D V300 open-source suites, the value of **LOCAL\_VERSION** needs to be modified for anti-rollback, for example, modifying **ohos default 1.0** to **ohos default 1.1**. The macro **LOCAL\_VERSION** is provided in **device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\ota\_update\\ota\_local\_info.c**. - -Example for modification of the local version: - -``` -const char *get_local_version(void) -{ -#if defined(CONFIG_TARGET_HI3516EV200) || \ - defined(CONFIG_TARGET_HI3516DV300) || \ - defined(CONFIG_TARGET_HI3518EV300) -#define LOCAL_VERSION "ohos default 1.0" /* increase: default release version */ -``` - diff --git a/en/device-dev/subsystems/overview-4.md b/en/device-dev/subsystems/overview-4.md deleted file mode 100644 index be32c8ebf46f3db9ab43c7a48fc0556250a04b7b..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/overview-4.md +++ /dev/null @@ -1,148 +0,0 @@ -# Overview - -- [Basic Concepts](#section72601941194812) -- [Ability Management Framework](#section14633111813374) -- [Bundle Management Framework](#section1341146154412) -- [Working Principles](#section94302021112717) -- [Limitations and Constraints](#section89534912527) - -The application framework is provided by OpenHarmony for you to develop OpenHarmony applications. It consists of two modules: ability management framework \(also called the ability framework\) and bundle management framework. - -## Basic Concepts - -This section describes some basic concepts for you to better understand the OpenHarmony application framework before you start development. - -## Ability Management Framework - -The ability management framework manages running status of OpenHarmony applications. - -**Figure 1** Architecture of the ability management framework -![](figures/architecture-of-the-ability-management-framework.png "architecture-of-the-ability-management-framework") - -- **Ability** is the minimum unit for the system to schedule applications. It is a component that can implement an independent functionality. An application can contain one or more **Ability** instances. There are two types of templates that you can use to create an **Ability** instance: Page and Service. - - An **Ability using the Page template** \(Page ability for short\) provides a UI for interacting with users. - - - An **Ability using the Service template** does not have a UI and is used for running background tasks. - - - -- An **AbilitySlice** represents a single screen and its control logic. It is specific to Page abilities. A Page ability may contain one ability slice or multiple ability slices that provide highly relevant capabilities. - - **Figure 2** Relationship between a Page ability and its ability slices - ![](figures/relationship-between-a-page-ability-and-its-ability-slices.png "relationship-between-a-page-ability-and-its-ability-slices") - -- **Lifecycle** is a general term for all states of an ability, including **INITIAL**, **INACTIVE**, **ACTIVE**, and **BACKGROUND**. - - **Figure 3** Lifecycle state transition of a Page ability - - - ![](figures/图片1.png) - - - **OnStart\(\)** - - This callback is invoked when the system first creates the Page ability. After this callback is executed, the Page ability enters the **INACTIVE** state. This callback is triggered only once in the entire lifecycle of each Page ability. You must override this callback and set the default ability slice to be displayed. - - - **OnActive\(\)** - - This callback is invoked when the Page ability in the **INACTIVE** state enters the foreground. After this callback is executed, the Page ability enters the **ACTIVE** state, in which it becomes interactive. The Page ability will stay in this state unless it loses focus upon a certain event, for example, when the user touches the Back button or navigates to another Page ability. - - When such an event occurs, the Page ability returns to the **INACTIVE** state, and the system invokes the **OnInactive\(\)** callback. The Page ability may move to the **ACTIVE** state again, and the system will then invoke the **OnActive\(\)** callback again. You should implement both **OnActive\(\)** and **OnInactive\(\)** for a Page ability and use **OnActive\(\)** to obtain the resources released in **OnInactive\(\)**. - - - **OnInactive\(\)** - - This callback is invoked when the Page ability loses focus, and the Page ability then becomes **INACTIVE**. You can implement the behavior to perform after the Page ability loses focus. - - - **OnBackground\(\)** - - This callback is invoked based on the system resource status when the Page ability becomes invisible to the user. After this callback is executed, the Page ability enters the **BACKGROUND** state. You should release the resources that are no longer needed after the Page ability becomes invisible or perform time-consuming save operations in this callback. - - - **OnForeground\(\)** - - A Page ability in the **BACKGROUND** state still resides in memory. When the Page ability returns to the foreground \(for example, when the user navigates to this Page ability again\), the system first calls **OnForeground\(\)** to switch the Page ability to the **INACTIVE** state, and then calls **OnActive\(\)** to make it **ACTIVE**. You should use the **OnForeground\(\)** callback to reclaim the resources released in **OnBackground\(\)**. Currently, the **OnForeground\(\)** callback is unavailable to lite devices. - - - **OnStop\(\)** - - This callback is invoked when the system is destroying a Page ability due to one of the following possible causes: - - - The user explicitly closes the Page ability using a system management feature, for example, the task manager. - - The user behavior, for example, exiting an application, triggers the **TerminateAbility\(\)** function on the Page ability. - - The system needs to temporarily destroy the Page ability and re-create it due to configuration changes. - - The system automatically destroys a Page ability in the **BACKGROUND** state due to resource management purposes. - - -- **AbilityKit** is a development kit provided by the ability management framework. You can use this kit to develop applications based on the **Ability** component. There are two types of applications developed based on the **Ability** component: JS Ability developed using the JavaScript language and Native Ability developed using the C/C++ language. The JS application development framework encapsulates JavaScript UI components on the basis of the AbilityKit and is used to help you quickly develop JS Ability-based applications. -- **AbilityLoader** is used to register and load **Ability** classes. After creating an **Ability** class, you should first call the registration API defined in **AbilityLoader** to register the **Ability** class name with the ability management framework so that this **Ability** can be instantiated when being started. - -- **AbilityManager** enables inter-process communication \(IPC\) between the AbilityKit and the Ability Manager Service. - -- **EventHandler** is provided by the AbilityKit to enable inter-thread communication between abilities. - -- The **Ability Manager Service** is a system service used to coordinate the running relationships and lifecycle states of **Ability** instances. It consists of the following modules: - - - The service startup module starts and registers the Ability Manager Service. - - The service interface management module manages external capabilities provided by the Ability Manager Service. - - The process management module starts and destroys processes where **Ability** instances are running, and maintains the process information. - - The ability stack management module maintains the presentation sequence of abilities in the stack. - - The lifecycle scheduling module changes an ability to a particular state based on the current operation of the system. - - The connection management module manages connections to Service abilities. - -- **AppSpawn** is a system service used to create the process for running an ability. This service has high permissions. It sets permissions for **Ability** instances and pre-loads some common modules to accelerate application startup. - - -## Bundle Management Framework - -The bundle management framework is provided by OpenHarmony for you to manage application bundles. - -**Figure 4** Architecture of the bundle management framework -![](figures/architecture-of-the-bundle-management-framework.png "architecture-of-the-bundle-management-framework") - -- **BundleKit** includes external APIs provided by the Bundle Manager Service, including the APIs for application installation and uninstallation, bundle information query, and bundle state change listeners. -- The **bundle scanning sub-module** parses pre-installed or installed bundles on the local device and extracts information from them for the bundle management module to manage and make the information persistent for storage. -- The **bundle installation sub-module** installs, uninstalls, and updates a bundle. The **bundle installation service** is an independent process that communicates with the Bundle Manager Service through IPC. It is used to create or delete installation directories and has high permissions. - -- The **bundle management sub-module** manages information related to application bundles and stores persistent bundle information. - -- The **bundle security management sub-module** verifies signatures, and grants and manages permissions. - - -## Working Principles - -The Ability Manager Service and Bundle Manager Service are the core modules of the ability management framework and bundle management framework, respectively. The two system-level services are registered and discovered by using the system service framework SAMgr, and they are used by manage abilities and bundles for other processes. The Ability Manager Service and Bundle Manager Service are provided as open APIs in the AbilityKit and BundleKit. - -**Figure 5** Startup of the Ability Manager Service and Bundle Manager Service -![](figures/startup-of-the-ability-manager-service-and-bundle-manager-service.png "startup-of-the-ability-manager-service-and-bundle-manager-service") - -OpenHarmony applications can be installed and started after the two services are started. - -**Figure 6** Application startup process -![](figures/application-startup-process.png "application-startup-process") - -The home screen is the first OpenHarmony application started by the Ability Manager Service. After the home screen is started, the user can touch any installed OpenHarmony application on the home screen to start the particular application. The figure above shows the interaction process of starting an installed application from the home screen. - -As shown in the figure, the Ability Manager Service is responsible for displaying or hiding an ability, and the Bundle Manager Service is responsible for storing and querying ability information. - -## Limitations and Constraints - -- Language version - - - C++ 11 or later - - -- The specifications of the application framework vary depending on the System-on-a-Chip \(SoC\) and underlying OS capabilities. - - - Cortex-M RAM and ROM - - - RAM: greater than 20 KB \(recommended\) - - - ROM: greater than 300 KB \(for the JS application development framework and related subsystems, such as UIKit and engine\) - - - - Cortex-A RAM and ROM - - - RAM: greater than 2 MB \(recommended\) - - - ROM: greater than 2 MB \(for the JS application development framework and related subsystems, such as UIKit and engine\) - - - - diff --git a/en/device-dev/subsystems/overview.md b/en/device-dev/subsystems/overview.md deleted file mode 100644 index af871180f3042797494129e8a9a80e36e62a1ca7..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/overview.md +++ /dev/null @@ -1,116 +0,0 @@ -# Overview - -- [Basic Concepts](#section175012297491) -- [Working Principles](#section193961322175011) - -## Basic Concepts - -Camera is one of the services provided by the OpenHarmony multimedia subsystem. The camera module provides recording, preview, and photographing features and supports concurrent stream reading by multiple users. - -It is considered good practice that you understand the following concepts before starting development: - -- Video frame - - A video frame is formed by the stream data of a video image. Video data streams are formed by a series of image data arranged at a fixed time interval. - -- Frame per second \(FPS\) - - FPS is used to represent the frame rate at which images are refreshed during video playback, or the number of frames per second during video playback. A higher frame rate means smoother video playback. - -- Resolution - - Information about each image frame consists of pixels. The number of pixels in an image is presented by the resolution. For example, 1080p \(1920 x 1080\) indicates that the image width is 1920 pixels and the image height is 1080 pixels. - - -## Working Principles - -- Multimedia services - - Multimedia services are started by the **Init** process upon system startup, and media hardware resources \(such as memory, display hardware, image sensors, and codecs\) are initialized and allocated. During the initialization, the configuration file is parsed, which determines the upper limit of capabilities and resources of each service. Generally, the upper limit is configured by original equipment manufacturers \(OEMs\) in the configuration file. The following configuration items are available for the camera service during multimedia service initialization: - - - Memory pool: Memory blocks in the memory pool are accessed and released continuously by all multimedia services. - - Image sensor: sensor type, resolution, ISP, and more - - Image processor: resolution, bit rate, image inversion, and more - - Image encoder: encoding format, bit rate, resolution, and more - - -- Major classes - - You can use the **Camera** class and its asynchronous callback classes to configure and access the camera functionalities. The three callback classes correspond to different asynchronous processing scenarios, as described in [Table 1](#table486418149411). - - **Table 1** Class description - - - - - - - - - - - - - - - - - - - - - - - - -

Class

-

Description

-

Examples

-

Camera

-

Configures the static camera capability through the configuration class to use basic camera functionalities.

-

Photographing, video recording, and previewing

-

CameraDeviceCallback

-

Handles camera hardware state changes.

-

Available or unavailable

-

CameraStateCallback

-

Handles camera instance state changes.

-

Created or released

-

FrameStateCallback

-

Handles frame status changes.

-

Start and end of photographing, and frame rate changes

-
- -- Stream transfer - - A surface is the basic data structure for transferring audio and video data. A camera is generally used as the data producer of a surface and has specific consumers in different scenarios. - - Camera preview and recording outputs are video streams, and photographing outputs are image frames. The outputs are transferred through the **Surface** class. A surface can transmit media information streams within and cross processes. - - Take video recording as an example. You create a **Recorder** instance, obtain the surface of the **Recorder** instance, and then transfer the surface to the **Camera** instance. In this case, the **Camera** instance works as a producer to inject video streams to the surface, and the **Recorder** instance act as the consumer to obtain video streams from the surface for storage. In this case, you connect the recorder and camera through the surface. - - Similarly, you can create a surface, implement consumer logic for it, and transfer it to the **Camera** instance. For example, transmit video streams over the network or save captured frame data as an image file. - - The graphics module also obtains stream resources from the camera module through surfaces. For details, see development guidelines on [Graphic](graphics-2.md). - -- Camera running process - 1. Creating a camera - - This process creates a **Camera** instance by **CameraManager**, binds the camera device to the server, and asynchronously notifies you of the successful creation. The following figure shows the time sequence between classes. - - **Figure 1** Sequence diagram for creating a camera - - - ![](figures/en-us_image_0000001054101094.png) - - - 1. Taking a video/Previewing - - This process creates a **Camera** instance via **CameraKit**, and configures frame attributes via **FrameConfig** for recording or previewing. The following figure shows the time sequence. - - **Figure 2** Sequence diagram for recording/previewing - - - ![](figures/en-us_image_0000001054421113.png) - - - diff --git a/en/device-dev/subsystems/public_sys-resources/icon-caution.gif b/en/device-dev/subsystems/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/device-dev/subsystems/public_sys-resources/icon-danger.gif b/en/device-dev/subsystems/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/device-dev/subsystems/public_sys-resources/icon-note.gif b/en/device-dev/subsystems/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/device-dev/subsystems/public_sys-resources/icon-notice.gif b/en/device-dev/subsystems/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/device-dev/subsystems/public_sys-resources/icon-tip.gif b/en/device-dev/subsystems/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/device-dev/subsystems/public_sys-resources/icon-warning.gif b/en/device-dev/subsystems/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/device-dev/subsystems/r-d-tools.md b/en/device-dev/subsystems/r-d-tools.md deleted file mode 100644 index 03f6b950d21aabb40bae141a58f40f1c42793407..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/r-d-tools.md +++ /dev/null @@ -1,9 +0,0 @@ -# R&D Tools - -- **[bytrace Usage Guidelines](bytrace-usage-guidelines.md)** - -- **[hdc\_std Usage Guidelines](hdc_std-usage-guidelines.md)** - -- **[hdc\_std FAQs](hdc_std-faqs.md)** - - diff --git a/en/device-dev/subsystems/sdk.md b/en/device-dev/subsystems/sdk.md deleted file mode 100644 index 5cc0b855635d383e046ae6c117a8d28428406da3..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/sdk.md +++ /dev/null @@ -1,162 +0,0 @@ -# SDK - -The function of the SDK header file is implemented by mapping SDK API calls to client API calls. [Table 1](#table203963834718) lists the APIs provided by the client. - -**Table 1** APIs provided by the client - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

API

-

Description

-

Parameters

-

int AieClientInit(const ConfigInfo &configInfo, ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, IServiceDeadCb *cb)

-

Function: Links and initializes the engine service and activates IPC call.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

configInfo: Indicates engine-related initial configuration data. This parameter must not be null.

-

clientInfo: Indicates engine client information. This parameter must not be null.

-

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

-

cb: Indicates the death callback object. This parameter can be null.

-

int AieClientPrepare(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo, IClientCb *cb)

-

Function: Loads an algorithm plug-in.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

clientInfo: Indicates engine client information. This parameter must not be null.

-

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

-

inputInfo: Indicates input information specified for algorithm plug-in loading. This parameter can be null.

-

outputInfo: Indicates information returned after algorithm plug-in loading, if any. This parameter can be null.

-

cb: Indicates the return result of the asynchronous algorithm. This parameter must not be null for the asynchronous algorithm. For the synchronous algorithm, this parameter must be null.

-

int AieClientAsyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

-

Function: Executes an asynchronous algorithm.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

clientInfo: Indicates engine client information. This parameter must not be null.

-

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

-

inputInfo: Indicates input information specified for algorithm operations. This parameter can be null.

-

int AieClientSyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo)

-

Function: Executes a synchronous algorithm.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

clientInfo: Indicates engine client information. This parameter must not be null.

-

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

-

inputInfo: Indicates input information specified for algorithm operations. This parameter can be null.

-

outputInfo: Indicates output information in the return result of the synchronous algorithm. This parameter can be null.

-

int AieClientRelease(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

-

Function: Uninstalls an algorithm plug-in.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

clientInfo: Indicates engine client information. This parameter must not be null.

-

algorithmInfo: Indicates information about the algorithm plug-in to be uninstalled. This parameter must not be null.

-

inputInfo: Indicates input information specified for algorithm plug-in uninstallation. This parameter can be null.

-

int AieClientDestroy(ClientInfo &clientInfo)

-

Function: Disconnects from the server and releases the cache.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

clientInfo: Indicates information about the engine client to be destroyed. This parameter must not be null.

-

int AieClientSetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo)

-

Function: Sets configuration items. You can use this API to pass algorithm's extended information to plug-ins.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

clientInfo: Indicates engine client information. This parameter must not be null.

-

optionType: Indicates the algorithm for obtaining the configuration item information. An algorithm plug-in can use this parameter as needed. This parameter must not be null.

-

inputInfo: Indicates algorithm parameter information. An algorithm plug-in can use this parameter as needed. This parameter can be null.

-

int AieClientGetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo, DataInfo &outputInfo)

-

Function: Obtains configuration item information based on the specified optionType and inputInfo.

-

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

-

clientInfo: Indicates engine client information. This parameter must not be null.

-

optionType: Indicates the algorithm for obtaining the configuration item information. This parameter must not be null.

-

inputInfo: Indicates input information specified for obtaining configuration item information of the algorithm. This parameter can be null.

-

outputInfo: Indicates the configuration item information in the return result. This parameter can be null.

-
- -[Table 2](#table22154317482) describes the data structure of **ConfigInfo**, **ClientInfo**, **AlgorithmInfo**, and **DataInfo**. - -**Table 2** Data structure of ConfigInfo, ClientInfo, AlgorithmInfo, and DataInfo - - - - - - - - - - - - - - - - - - - - - - - - -

Structure

-

Description

-

Attributes

-

ConfigInfo

-

Algorithm configuration item information

-

const char *description: Indicates the body of configuration item information.

-

ClientInfo

-

Client information

-

long long clientVersion: Indicates client version number. This parameter is not used currently.

-

int clientId: Indicates the client ID.

-

int sessionId: Indicates the session ID.

-

uid_t serverUid: Indicates the server UID.

-

uid_t clientUid: Indicates the client UID.

-

int extendLen: Indicates the length of the extended information (extendMsg).

-

unsigned char *extendMsg: Indicates the body of the extended information.

-

AlgorithmInfo

-

Algorithm information

-

long long clientVersion: Indicates client version number. This parameter is not used currently.

-

bool isAsync: Indicates whether asynchronous execution is used.

-

int algorithmType: Indicates the algorithm type ID allocated by the AI engine framework based on the plug-in loading sequence.

-

long long algorithmVersion: Indicates the algorithm version number.

-

bool isCloud: Indicates whether to migrate data to the cloud. This parameter is not used currently.

-

int operateId: Indicates the execution ID. This parameter is not used currently.

-

int requestId: Indicates the request ID, which identifies each request and corresponds to the execution result.

-

int extendLen: Indicates the length of the extended information (extendMsg).

-

unsigned char *extendMsg: Indicates the body of the extended information.

-

DataInfo

-

Algorithm input parameter configuration information (inputInfo) and output parameter configuration information (outputInfo)

-

unsigned char *data: Indicates the data body.

-

int length: Indicates the data length.

-
- -For details about the development process, see the development example for the KWS SDK. - diff --git a/en/device-dev/subsystems/security.md b/en/device-dev/subsystems/security.md deleted file mode 100644 index e69ec0072cf44c6314e688ce37d3a25bbe8df412..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/security.md +++ /dev/null @@ -1,13 +0,0 @@ -# Security - -- **[Overview](overview-9.md)** - -- **[Development Guidelines on Application Signature Verification](development-guidelines-on-application-signature-verification.md)** - -- **[Development Guidelines on Application Permission Management](development-guidelines-on-application-permission-management.md)** - -- **[Development Guidelines on IPC Authentication](development-guidelines-on-ipc-authentication.md)** - -- **[Development Guidelines on Trusted Device Group Management](development-guidelines-on-trusted-device-group-management.md)** - - diff --git a/en/device-dev/subsystems/sensors-overview.md b/en/device-dev/subsystems/sensors-overview.md deleted file mode 100644 index df576eafc34eefed1cb2740def706a469e72273f..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/sensors-overview.md +++ /dev/null @@ -1,99 +0,0 @@ -# Sensors Overview - -- [Introduction](#section667413271505) -- [Available APIs](#section7255104114110) - -## Introduction - -The pan-sensor service subsystem provides a lightweight sensor service framework. You can call APIs offered by this framework to query the sensor list, enable or disable a sensor, and subscribe to or unsubscribe from sensor data. The following figure shows the architecture of the lightweight sensor framework. - -**Figure 1** Sensor service framework - -![](figures/en-us_image_0000001077724150.png) - -- Sensor API: provides APIs for performing basic operations on sensors, including querying the sensor list, subscribing to or unsubscribing from sensor data, and executing control commands. This module makes application development simpler. -- Sensor Framework: manages sensor data subscription, creates and destroys data channels, and implements communication with the Sensor Service module. -- Sensor Service: interacts with the HDF module to receive, parse, and distribute data, manages sensors on hardware and sensor data reporting, and controls sensor permissions. - -## Available APIs - -**Table 1** APIs of the sensor framework - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

Parameter

-

int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count)

-

Obtains information about all sensors in the system.

-

Return value: Returns 0 if the information is obtained; returns a non-zero value otherwise.

-

sensorInfo (not NULL): information about all sensors in the system

-

count (not NULL): total number of sensors in the system

-

int32_t SubscribeSensor(int32_t sensorTypeId, SensorUser *user)

-

Subscribes to sensor data. The system will report the obtained sensor data to the subscriber.

-

Return value: Returns 0 if the subscription is successful; returns a non-zero value otherwise.

-

sensorTypeId: ID of a sensor type

-

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

-

int32_t UnsubscribeSensor(int32_t sensorTypeId, SensorUser *user)

-

Unsubscribes from sensor data. The system will no longer report sensor data to the subscriber.

-

Return value: Returns 0 if the unsubscription is successful; returns a non-zero value otherwise.

-

sensorTypeId: ID of a sensor type

-

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

-

int32_t SetBatch(int32_t sensorTypeId, SensorUser *user, int64_t samplingInterval, int64_t reportInterval)

-

Sets the data sampling interval and data reporting interval for the specified sensor.

-

Return value: Returns 0 if the setting is successful; returns a non-zero value otherwise.

-

sensorTypeId: ID of a sensor type

-

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

-

samplingInterval: sensor data sampling interval, in nanoseconds

-

reportInterval: sensor data reporting interval, in nanoseconds

-

int32_t ActivateSensor(int32_t sensorTypeId, SensorUser *user)

-

Enables the specified sensor that has been subscribed to.

-

Return value: Returns 0 if the sensor is successfully enabled; returns a non-zero value otherwise.

-

sensorTypeId: ID of a sensor type

-

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

-

int32_t DeactivateSensor(int32_t sensorTypeId, SensorUser *user)

-

Disables an enabled sensor.

-

Return value: Returns 0 if the sensor is successfully disabled; returns a non-zero value otherwise.

-

sensorTypeId: ID of a sensor type

-

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

-

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

-

Sets the data reporting mode for the specified sensor.

-

Return value: Returns 0 if the sensor data reporting mode is successfully set; returns a non-zero value otherwise.

-

sensorTypeId: ID of a sensor type

-

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

-

mode: data reporting mode of the sensor

-
- diff --git a/en/device-dev/subsystems/sensors-usage-guidelines.md b/en/device-dev/subsystems/sensors-usage-guidelines.md deleted file mode 100644 index f3e692948c004bc721cf862b2ac4a47a01f574f6..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/sensors-usage-guidelines.md +++ /dev/null @@ -1,72 +0,0 @@ -# Sensors Usage Guidelines - -- [How to Use](#section18816105182315) - -The following steps use the sensor whose **sensorTypeId** is **0** as an example. The guidelines for other sensor types are similar. - -## How to Use - -1. Import the required header files. - -``` -#include "sensor_agent.h" -#include "sensor_agent_type.h" -``` - -1. Create a sensor callback. - -``` -void SensorDataCallbackImpl(SensorEvent *event) -{ - if(event == NULL){ - return; - } - float *sensorData=(float *)event->data; -} -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The callback must be of the RecordSensorCallback type. - -1. Obtain the list of sensors supported by the device. - -``` -SensorInfo *sensorInfo = (SensorInfo *)NULL; -int32_t count = 0; -int32_t ret = GetAllSensors(&sensorInfo, &count); -``` - -1. Create a sensor user. - -``` -SensorUser sensorUser; -sensorUser.callback = SensorDataCallbackImpl; // Assign the created callback SensorDataCallbackImpl to the member variable callback. -``` - -1. Enable the sensor. - -``` -int32_t ret = ActivateSensor(0, &sensorUser); -``` - -1. Subscribe to sensor data. - -``` -int32_t ret = SubscribeSensor(0, &sensorUser); -``` - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Till now, you can obtain the sensor data via the callback. - -1. Unsubscribe from the sensor data. - -``` -int32_t ret = UnsubscribeSensor(0, &sensorUser); -``` - -1. Disable the sensor. - -``` -int32_t ret = DeactivateSensor(0, &sensorUser); -``` - diff --git a/en/device-dev/subsystems/sensors.md b/en/device-dev/subsystems/sensors.md deleted file mode 100644 index 1cb5c1ea4ccc7754bf186c31d6d7e1e1fae063ad..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/sensors.md +++ /dev/null @@ -1,9 +0,0 @@ -# Sensors - -- **[Sensors Overview](sensors-overview.md)** - -- **[Sensors Usage Guidelines](sensors-usage-guidelines.md)** - -- **[Sensors Usage Example](sensors-usage-example.md)** - - diff --git a/en/device-dev/subsystems/setting-up-a-development-environment.md b/en/device-dev/subsystems/setting-up-a-development-environment.md deleted file mode 100644 index 1fc80b0e712510b8126974d0beffabd558cc66b0..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/setting-up-a-development-environment.md +++ /dev/null @@ -1,7 +0,0 @@ -# Setting Up a Development Environment - -- Development board: Hi3516D V300 - -- [Download the source code](../get-code/source-code-acquisition.md). -- [Build the application framework](https://gitee.com/openharmony/docs/blob/master/en/readme/application-framework.md). - diff --git a/en/device-dev/subsystems/startup-10.md b/en/device-dev/subsystems/startup-10.md deleted file mode 100644 index b6ef1916de1c9e9e7cdf903841ded765d0ce841a..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/startup-10.md +++ /dev/null @@ -1,86 +0,0 @@ -# Startup - -- [Limitations and Constraints](#section2029921310472) - -The startup subsystem provides the functions of starting key system processes after the kernel is started and before applications are started, and restoring the system to factory settings. The subsystem consists of the following modules: - -- init module - - This module corresponds to the init process, which is the first user-space process started after the kernel is initialized. Upon startup, the init process reads and parses the configuration file **init.cfg**. Based on the parsing result, the init module executes the commands listed in Table 2 in [init Module](init-module.md) and starts the key system service processes in sequence with corresponding permissions granted. - -- appspawn module - - This module spawns application processes upon receiving commands from the application framework, configures permissions for new processes, and calls the entry function of the application framework. - -- bootstrap module - - This module provides entry identifiers for starting services and features. When the Samgr is started, the entry function identified by boostrap is called and system services are started. - -- syspara module - - This module provides APIs for obtaining device information, such as the product name, brand name, and manufacturer name, based on the OpenHarmony Product Compatibility Specifications \(PCS\). It also provides APIs for setting and obtaining system parameters. - - -## Limitations and Constraints - -The directories of startup subsystem are applicable to different platforms. - -**Table 1** Directories and applicable platforms of the startup subsystem - - - - - - - - - - - - - - - - - - - -

Directory

-

Applicable Platform

-

base/startup/appspawn_lite

-

Small-system devices (reference memory ≥ 1 MB), for example, Hi3516D V300 and Hi3518E V300

-

base/startup/bootstrap_lite

-

Mini-system devices (reference memory ≥ 128 KB), for example, Hi3861 V100

-

base/startup/init_lite

-

Small-system devices (reference memory ≥ 1 MB), for example, Hi3516D V300 and Hi3518E V300

-

base/startup/syspara_lite

-
  • Mini-system devices (reference memory ≥ 128 KB), for example, Hi3861 V100
  • Small-system devices (reference memory ≥ 1 MB), for example, Hi3516D V300 and Hi3518E V300
-
- - - - - - - - - - - - - -

Directory

-

Applicable Platform

-

base/startup/startup

-

Large-system devices (reference memory ≥ 1 GB)

-

base/startup/systemrestore

-

Large-system devices (reference memory ≥ 1 GB)

-
- -- init module - - After being burnt to the development board, the configuration file **init.cfg** changes to read-only. If you want to modify the file, you must repack and burn the rootfs image again. - - The configuration file **init.cfg** must be in JSON format. - -- bootstrap module: The zInit code needs to be configured in the link script. -- syspara module: The **SetParameter** and **GetParameter** APIs can only be called by applications whose UID is greater than 1000. - diff --git a/en/device-dev/subsystems/startup.md b/en/device-dev/subsystems/startup.md deleted file mode 100644 index 5a2025350a8b09b4a2afd74af17e2dc4894efa53..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/startup.md +++ /dev/null @@ -1,17 +0,0 @@ -# Startup - -- **[Startup](startup-10.md)** - -- **[init Module](init-module.md)** - -- **[appspawn Module](appspawn-module.md)** - -- **[bootstrap Module](bootstrap-module.md)** - -- **[syspara Module](syspara-module.md)** - -- **[FAQs](faqs.md)** - -- **[Reference](reference.md)** - - diff --git a/en/device-dev/subsystems/kws-configuration-file.md b/en/device-dev/subsystems/subsys-aiframework-demo-conf.md similarity index 100% rename from en/device-dev/subsystems/kws-configuration-file.md rename to en/device-dev/subsystems/subsys-aiframework-demo-conf.md diff --git a/en/device-dev/subsystems/kws-plug-in.md b/en/device-dev/subsystems/subsys-aiframework-demo-plugin.md similarity index 100% rename from en/device-dev/subsystems/kws-plug-in.md rename to en/device-dev/subsystems/subsys-aiframework-demo-plugin.md diff --git a/en/device-dev/subsystems/subsys-aiframework-demo-sdk.md b/en/device-dev/subsystems/subsys-aiframework-demo-sdk.md new file mode 100644 index 0000000000000000000000000000000000000000..969d35269f74b0a7efe86fd387d4fe066409d2b2 --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-demo-sdk.md @@ -0,0 +1,81 @@ +# KWS SDK + +1. Add the API of the KWS SDK to the **//foundation/ai/engine /interfaces/kits** directory. This API can be called by third-party applications. The following code snippet is an example API for the KWS SDK. The reference code is available at the **//foundation/ai/engine /interfaces/kits/asr/keyword\_spotting** directory. + + ``` + class KWSSdk { + public: + KWSSdk(); + virtual ~KWSSdk(); + + // Create a KWS SDK instance. + int32_t Create(); + + // Synchronously execute the KWS task. + int32_t SyncExecute(const Array &audioInput); + + // Set the KWS callback. + int32_t SetCallback(const std::shared_ptr &callback); + + // Destroy the KWS SDK instance to release the session engaged with the plug-in. + int32_t Destroy(); + }; + ``` + +2. Add the API implementation of the SDK to the **//foundation/ai/engine/services/client/algorithm\_sdk** directory and call the APIs provided by the client to use the algorithm plug-in capabilities. The following code snippet is an example implementation of the **create** method in the API of the KWS SDK. For more details, see the reference code at **//foundation/ai/engine/services/client/algorithm\_sdk/asr/keyword\_spotting**. + + ``` + int32_t KWSSdk::KWSSdkImpl::Create() + { + if (kwsHandle_ != INVALID_KWS_HANDLE) { + HILOGE("[KWSSdkImpl]The SDK has been created"); + return KWS_RETCODE_FAILURE; + } + if (InitComponents() != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]Fail to init sdk components"); + return KWS_RETCODE_FAILURE; + } + // Call the AieClientInit API provided by the client to initialize the engine service and activate IPC call. + int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr); + if (retCode != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode); + return KWS_RETCODE_FAILURE; + } + if (clientInfo_.clientId == INVALID_CLIENT_ID) { + HILOGE("[KWSSdkImpl]Fail to allocate client id"); + return KWS_RETCODE_FAILURE; + } + DataInfo inputInfo = { + .data = nullptr, + .length = 0, + }; + DataInfo outputInfo = { + .data = nullptr, + .length = 0, + }; + // Call the AieClientPrepare API provided by the client to load the algorithm plug-in. + retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr); + if (retCode != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode); + return KWS_RETCODE_FAILURE; + } + if (outputInfo.data == nullptr || outputInfo.length <= 0) { + HILOGE("[KWSSdkImpl]The data or length of output info is invalid"); + return KWS_RETCODE_FAILURE; + } + MallocPointerGuard pointerGuard(outputInfo.data); + retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_); + if (retCode != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]Get handle from inputInfo failed"); + return KWS_RETCODE_FAILURE; + } + return KWS_RETCODE_SUCCESS; + } + ``` + + The preceding code is the specific API implementation. The **create** function in the API of the KWS SDK calls the open **AieClientInit** and **AieClientPrepare** APIs provided by the client to connect to the server and load the algorithm model. For details, see the implementation of the **create** method in following sections. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >The sequence for the SDK to call client APIs: **AieClientInit** -\> **AieClientPrepare** -\> **AieClientSyncProcess** or **AieClientAsyncProcess** -\> **AieClientRelease** -\> **AieClientDestroy**. An exception will be thrown if the call sequence is violated. + + diff --git a/en/device-dev/subsystems/subsys-aiframework-demo.md b/en/device-dev/subsystems/subsys-aiframework-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..0dd54a375edf3ec101a6999dfd25d3f424c5cca4 --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-demo.md @@ -0,0 +1,13 @@ +# Development Examples + +For your better understanding, a KWS application is used as an example to walk you through the development process. You can develop the KWS SDK and plug-in based on the AI engine framework on the Hi3516D V300 development board, compile an image for the new version, and burn the image into the version. Then, develop an application with the KWS function. The application can receive external audio and pass the audio to the SDK API. If the audio contains specified keywords, the application will be able to recognize these keywords and print them in the command line. + +This example uses a fixed keyword **Hi, xiaowen** for illustration. If the input audio contains **Hi, xiaowen**, the application prints **\[Hi, xiaowen\]**; otherwise, the application prints **\[UNKNOWN\]**. + +- **[KWS SDK](subsys-aiframework-demo-sdk.md)** + +- **[KWS Plug-in](subsys-aiframework-demo-plugin.md)** + +- **[KWS Configuration File](subsys-aiframework-demo-conf.md)** + + diff --git a/en/device-dev/subsystems/configuration-file.md b/en/device-dev/subsystems/subsys-aiframework-devguide-conf.md similarity index 100% rename from en/device-dev/subsystems/configuration-file.md rename to en/device-dev/subsystems/subsys-aiframework-devguide-conf.md diff --git a/en/device-dev/subsystems/plug-in.md b/en/device-dev/subsystems/subsys-aiframework-devguide-plugin.md similarity index 100% rename from en/device-dev/subsystems/plug-in.md rename to en/device-dev/subsystems/subsys-aiframework-devguide-plugin.md diff --git a/en/device-dev/subsystems/subsys-aiframework-devguide-sdk.md b/en/device-dev/subsystems/subsys-aiframework-devguide-sdk.md new file mode 100644 index 0000000000000000000000000000000000000000..f185750d0f6ffa1d1027b717e6b67acc9e1fd666 --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-devguide-sdk.md @@ -0,0 +1,162 @@ +# SDK + +The function of the SDK header file is implemented by mapping SDK API calls to client API calls. [Table 1](#table203963834718) lists the APIs provided by the client. + +**Table 1** APIs provided by the client + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

API

+

Description

+

Parameters

+

int AieClientInit(const ConfigInfo &configInfo, ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, IServiceDeadCb *cb)

+

Function: Links and initializes the engine service and activates IPC call.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

configInfo: Indicates engine-related initial configuration data. This parameter must not be null.

+

clientInfo: Indicates engine client information. This parameter must not be null.

+

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

+

cb: Indicates the death callback object. This parameter can be null.

+

int AieClientPrepare(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo, IClientCb *cb)

+

Function: Loads an algorithm plug-in.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

clientInfo: Indicates engine client information. This parameter must not be null.

+

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

+

inputInfo: Indicates input information specified for algorithm plug-in loading. This parameter can be null.

+

outputInfo: Indicates information returned after algorithm plug-in loading, if any. This parameter can be null.

+

cb: Indicates the return result of the asynchronous algorithm. This parameter must not be null for the asynchronous algorithm. For the synchronous algorithm, this parameter must be null.

+

int AieClientAsyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

+

Function: Executes an asynchronous algorithm.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

clientInfo: Indicates engine client information. This parameter must not be null.

+

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

+

inputInfo: Indicates input information specified for algorithm operations. This parameter can be null.

+

int AieClientSyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo)

+

Function: Executes a synchronous algorithm.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

clientInfo: Indicates engine client information. This parameter must not be null.

+

algorithmInfo: Indicates information about the called algorithm. This parameter must not be null.

+

inputInfo: Indicates input information specified for algorithm operations. This parameter can be null.

+

outputInfo: Indicates output information in the return result of the synchronous algorithm. This parameter can be null.

+

int AieClientRelease(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

+

Function: Uninstalls an algorithm plug-in.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

clientInfo: Indicates engine client information. This parameter must not be null.

+

algorithmInfo: Indicates information about the algorithm plug-in to be uninstalled. This parameter must not be null.

+

inputInfo: Indicates input information specified for algorithm plug-in uninstallation. This parameter can be null.

+

int AieClientDestroy(ClientInfo &clientInfo)

+

Function: Disconnects from the server and releases the cache.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

clientInfo: Indicates information about the engine client to be destroyed. This parameter must not be null.

+

int AieClientSetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo)

+

Function: Sets configuration items. You can use this API to pass algorithm's extended information to plug-ins.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

clientInfo: Indicates engine client information. This parameter must not be null.

+

optionType: Indicates the algorithm for obtaining the configuration item information. An algorithm plug-in can use this parameter as needed. This parameter must not be null.

+

inputInfo: Indicates algorithm parameter information. An algorithm plug-in can use this parameter as needed. This parameter can be null.

+

int AieClientGetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo, DataInfo &outputInfo)

+

Function: Obtains configuration item information based on the specified optionType and inputInfo.

+

Return value: Returns 0 if the operation is successful; returns a non-zero value otherwise.

+

clientInfo: Indicates engine client information. This parameter must not be null.

+

optionType: Indicates the algorithm for obtaining the configuration item information. This parameter must not be null.

+

inputInfo: Indicates input information specified for obtaining configuration item information of the algorithm. This parameter can be null.

+

outputInfo: Indicates the configuration item information in the return result. This parameter can be null.

+
+ +[Table 2](#table22154317482) describes the data structure of **ConfigInfo**, **ClientInfo**, **AlgorithmInfo**, and **DataInfo**. + +**Table 2** Data structure of ConfigInfo, ClientInfo, AlgorithmInfo, and DataInfo + + + + + + + + + + + + + + + + + + + + + + + + +

Structure

+

Description

+

Attributes

+

ConfigInfo

+

Algorithm configuration item information

+

const char *description: Indicates the body of configuration item information.

+

ClientInfo

+

Client information

+

long long clientVersion: Indicates client version number. This parameter is not used currently.

+

int clientId: Indicates the client ID.

+

int sessionId: Indicates the session ID.

+

uid_t serverUid: Indicates the UID of the server.

+

uid_t clientUid: Indicates the UID of the client.

+

int extendLen: Indicates the length of the extended information (extendMsg).

+

unsigned char *extendMsg: Indicates the body of the extended information.

+

AlgorithmInfo

+

Algorithm information

+

long long clientVersion: Indicates client version number. This parameter is not used currently.

+

bool isAsync: Indicates whether asynchronous execution is used.

+

int algorithmType: Indicates the algorithm type ID allocated by the AI engine framework based on the plug-in loading sequence.

+

long long algorithmVersion: Indicates the algorithm version number.

+

bool isCloud: Indicates whether to migrate data to the cloud. This parameter is not used currently.

+

int operateId: Indicates the execution ID. This parameter is not used currently.

+

int requestId: Indicates the request ID, which identifies each request and corresponds to the execution result.

+

int extendLen: Indicates the length of the extended information (extendMsg).

+

unsigned char *extendMsg: Indicates the body of the extended information.

+

DataInfo

+

Algorithm input parameter configuration information (inputInfo) and output parameter configuration information (outputInfo)

+

unsigned char *data: Indicates the data body.

+

int length: Indicates the data length.

+
+ +For details about the development process, see the development example for the KWS SDK. + diff --git a/en/device-dev/subsystems/subsys-aiframework-devguide.md b/en/device-dev/subsystems/subsys-aiframework-devguide.md new file mode 100644 index 0000000000000000000000000000000000000000..b3bd0bb4e3ccfccd3d91a6b8c35fec13dd570683 --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-devguide.md @@ -0,0 +1,11 @@ +# Development Guidelines + +To access the AI engine framework, you need to develop the SDKs and plug-ins shown in [Figure 1](subsys-aiframework-guide.md#fig143186187187). In this way, you can call the APIs provided by the SDKs to call the algorithm capabilities of plug-ins to implement lifecycle management and on-demand deployment of AI capabilities. + +- **[SDK](subsys-aiframework-devguide-sdk.md)** + +- **[Plug-in](subsys-aiframework-devguide-plugin.md)** + +- **[Configuration File](subsys-aiframework-devguide-conf.md)** + + diff --git a/en/device-dev/subsystems/subsys-aiframework-envbuild.md b/en/device-dev/subsystems/subsys-aiframework-envbuild.md new file mode 100644 index 0000000000000000000000000000000000000000..ebfa0e83dcaf00e8123da6264df60db3ddbfa20e --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-envbuild.md @@ -0,0 +1,5 @@ +# Development Environment + +1. Prepare development boards Hi3516D V300 and Hi3518E V300. +2. [Download the source code](../get-code/sourcecode-acquire.md). + diff --git a/en/device-dev/subsystems/subsys-aiframework-guide.md b/en/device-dev/subsystems/subsys-aiframework-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..3e13aeb62273b5b51cd951aa803db6f0d02426ae --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-guide.md @@ -0,0 +1,9 @@ +# AI Engine Framework + +The AI subsystem of OpenHarmony provides native distributed AI capabilities. At the heart of the subsystem is a unified AI engine framework, which implements quick integration of AI algorithm plug-ins. The framework consists of the plug-in management, module management, and communication management modules, fulfilling lifecycle management and on-demand deployment of AI algorithms. Plug-in management implements lifecycle management, on-demand deployment, and quick integration of AI algorithm plug-ins. Module management implements task scheduling and client instance management. Communication management implements inter-process communication \(IPC\) between the client and server and data transmission between the AI engine and plug-ins. Under this framework, AI algorithm APIs will be standardized to facilitate distributed calling of AI capabilities. In addition, unified inference APIs will be provided to adapt to different inference framework hierarchies. [Figure 1](#fig143186187187) shows the AI engine framework. + +**Figure 1** AI engine framework + + +![](figure/en-us_image_0000001077727032.png) + diff --git a/en/device-dev/subsystems/subsys-aiframework-tech-codemanage.md b/en/device-dev/subsystems/subsys-aiframework-tech-codemanage.md new file mode 100644 index 0000000000000000000000000000000000000000..71784ff093472cfa6658ba319b3b6d701e955d68 --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-tech-codemanage.md @@ -0,0 +1,40 @@ +# Code Management + +- [Recommendation: Develop plug-ins and northbound SDKs in the directories specified by the AI engine.](#section17176374131) +- [Rule: Store all external APIs provided by plug-ins in the interfaces/kits directory of the AI subsystem.](#section2551029111312) +- [Rule: Make sure that plug-in compilation results are stored in the /usr/lib directory.](#section97021558121310) + +Code of the AI engine framework consists of three parts: **client**, **server**, and **common**. The client module provides the server connection management function. The northbound SDK needs to encapsulate and call the public APIs provided by the client in the algorithm's external APIs. The server module provides functions such as plug-in loading and task management. Plug-ins are integrated using the plug-in APIs provided by the server. The common module provides platform-related operation methods, engine protocols, and tool classes for other modules. + +[Figure 1](#fig171811112818) shows the code dependency between modules of the AI engine framework. + +**Figure 1** Code dependency + + +![](figure/插件依赖-(2).jpg) + +## Recommendation: Develop plug-ins and northbound SDKs in the directories specified by the AI engine. + +In the overall planning of the AI engine framework, northbound SDKs are a part of the client, and plug-ins are called by the server and are considered a part of the server. Therefore, the following directories have been planned for plug-in and northbound SDK development in the AI engine framework: + +- SDK code directory: //foundation/ai/engine/services/client/algorithm\_sdk + + e.g. //foundation/ai/engine/services/client/algorithm\_sdk/cv + + e.g. //foundation/ai/engine/services/client/algorithm\_sdk/nlu + +- Plug-in code directory: //foundation/ai/engine/services/server/plugin + + e.g. //foundation/ai/engine/services/server/plugin/cv + + e.g. //foundation/ai/engine/services/server/plugin/nlu + + +## Rule: Store all external APIs provided by plug-ins in the **interfaces/kits** directory of the AI subsystem. + +The AI subsystem exposes its capabilities through external APIs of northbound SDKs. According to API management requirements of OpenHarmony, store all external APIs of northbound SDKs in the **interfaces/kits** directory of the subsystem. Currently, the external APIs of plug-ins of the AI subsystem are stored in the following directory: **//foundation/ai/engine/interface/kits**. You can add a sub-directory for each newly added plug-in in this directory. For example, if you add a CV plug-in, then store its external APIs in the **//foundation/ai/engine/interfaces/kits/cv** directory. + +## Rule: Make sure that plug-in compilation results are stored in the **/usr/lib** directory. + +Plug-in loading on the server uses the dlopen mode and can only be performed in the **/usr/lib** directory. Therefore, when compiling the **.so** file of a plug-in, set the output directory as **/usr/lib** in the compilation configuration file. + diff --git a/en/device-dev/subsystems/api-development.md b/en/device-dev/subsystems/subsys-aiframework-tech-interface.md similarity index 100% rename from en/device-dev/subsystems/api-development.md rename to en/device-dev/subsystems/subsys-aiframework-tech-interface.md diff --git a/en/device-dev/subsystems/naming.md b/en/device-dev/subsystems/subsys-aiframework-tech-name.md similarity index 100% rename from en/device-dev/subsystems/naming.md rename to en/device-dev/subsystems/subsys-aiframework-tech-name.md diff --git a/en/device-dev/subsystems/subsys-aiframework-tech.md b/en/device-dev/subsystems/subsys-aiframework-tech.md new file mode 100644 index 0000000000000000000000000000000000000000..ed9edda03a6fabc4651e76a13271f159b4510e51 --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework-tech.md @@ -0,0 +1,15 @@ +# Technical Specifications + +**Conventions** + +**Rule**: a convention that must be observed + +**Recommendation**: a convention that should be considered + +- **[Code Management](subsys-aiframework-tech-codemanage.md)** + +- **[Naming](subsys-aiframework-tech-name.md)** + +- **[API Development](subsys-aiframework-tech-interface.md)** + + diff --git a/en/device-dev/subsystems/subsys-aiframework.md b/en/device-dev/subsystems/subsys-aiframework.md new file mode 100644 index 0000000000000000000000000000000000000000..bdd0b162508a053ffe7b7b9f62fffa6401d644d1 --- /dev/null +++ b/en/device-dev/subsystems/subsys-aiframework.md @@ -0,0 +1,13 @@ +# AI Framework + +- **[AI Engine Framework](subsys-aiframework-guide.md)** + +- **[Development Environment](subsys-aiframework-envbuild.md)** + +- **[Technical Specifications](subsys-aiframework-tech.md)** + +- **[Development Guidelines](subsys-aiframework-devguide.md)** + +- **[Development Examples](subsys-aiframework-demo.md)** + + diff --git a/en/device-dev/subsystems/subsys-application-framework-builden.md b/en/device-dev/subsystems/subsys-application-framework-builden.md new file mode 100644 index 0000000000000000000000000000000000000000..c7497eb01035c6d5c8569cfef1ca944cbf444136 --- /dev/null +++ b/en/device-dev/subsystems/subsys-application-framework-builden.md @@ -0,0 +1,7 @@ +# Setting Up a Development Environment + +- Development board: Hi3516D V300 + +- [Download the source code](../get-code/sourcecode-acquire.md). +- [Build the application framework](https://gitee.com/openharmony/docs/blob/master/en/readme/application-framework.md). + diff --git a/en/device-dev/subsystems/development-example.md b/en/device-dev/subsystems/subsys-application-framework-demo.md similarity index 100% rename from en/device-dev/subsystems/development-example.md rename to en/device-dev/subsystems/subsys-application-framework-demo.md diff --git a/en/device-dev/subsystems/subsys-application-framework-guide.md b/en/device-dev/subsystems/subsys-application-framework-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..a4f37e5be36824b3f229c5f1b178e5a3e8d1197c --- /dev/null +++ b/en/device-dev/subsystems/subsys-application-framework-guide.md @@ -0,0 +1,711 @@ +# Development Guidelines + +- [When to Use](#section93012287133) +- [Available APIs](#section11821047161319) +- [How to Develop](#section10514141679) + - [Creating a Service Ability](#section19921154214315) + - [Development Guidelines on Bundle Management](#section1724016743217) + - [Packing a HAP File](#section171771212328) + + +## When to Use + +- Develop Page abilities for applications that have a UI for human-machine interaction, such as news applications, video players, navigation applications, and payment applications. Most applications we use in our daily lives are such type of applications. + +- Develop Service abilities for applications so that they can run particular services in the background, such as music playing, computing, and navigation services. + +- Pack both Page and Service abilities into HarmonyOS Ability Packages \(HAPs\). All applications must be packed into HAP files before being published to the application market. Once published, users can then download the applications from the application market. + +## Available APIs + +**Table 1** APIs of the ability management framework + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

Want *WantParseUri(const char *uri)

+

Converts a specified character string into a Want object.

+

const char *WantToUri(Want want)

+

Converts a specified Want object into a character string.

+

void SetWantElement(Want *want, ElementName element);

+

Sets the element variable for a specified Want object.

+

void SetWantData(Want *want, const void *data, uint16_t dataLength)

+

Sets data to carry in a specified Want object for starting a particular ability.

+

bool SetWantSvcIdentity(Want *want, SvcIdentity sid)

+

Sets the sid member variable for a specified Want object.

+

void ClearWant(Want *want)

+

Clears the memory of a specified Want object.

+

void SetMainRoute(const std::string &entry)

+

Sets the main route for the ability.

+

void SetUIContent(RootView *rootView)

+

Sets the UI layout for the ability.

+

void OnStart(const Want& intent)

+

Called when the ability is started. This callback is invoked to handle transitions between ability lifecycle states.

+

void OnStop()

+

Called when the ability is being destroyed. This callback is invoked to handle transitions between ability lifecycle states.

+

void OnActive(const Want& intent)

+

Called when the ability is visible to users. This callback is invoked to handle transitions between ability lifecycle states.

+

void OnInactive()

+

Called when the ability is invisible to users. This callback is invoked to handle transitions between ability lifecycle states.

+

void OnBackground()

+

Called when the ability is moved to the background. This callback is invoked to handle transitions between ability lifecycle states.

+

const SvcIdentity *OnConnect(const Want &want)

+

Called when the Service ability is connected for the first time.

+

void OnDisconnect(const Want &want);

+

Called when all abilities connected to the Service ability are disconnected.

+

void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply);

+

Handles a message sent by the client to the Service ability.

+

void Dump(const std::string &extra)

+

Prints ability information to the console.

+

void Present(AbilitySlice *abilitySlice, const Want &want)

+

Presents another ability slice.

+

void Terminate()

+

Destroys the ability slice.

+

void SetUIContent(RootView *rootView)

+

Sets the UI layout for the host ability of the ability slice.

+

void OnStart(const Want& want)

+

Called when the ability slice is started. This callback is invoked to handle transitions between ability slice lifecycle states.

+

void OnStop()

+

Called when the ability slice is being destroyed. This callback is invoked to handle transitions between ability slice lifecycle states.

+

void OnActive(const Want& want)

+

Called when the ability slice is visible to users. This callback is invoked to handle transitions between ability slice lifecycle states.

+

void OnInactive()

+

Called when the ability slice is invisible to users. This callback is invoked to handle transitions between ability slice lifecycle states.

+

void OnBackground()

+

Called when the ability slice is moved to the background. This callback is invoked to handle transitions between ability slice lifecycle states.

+

int StartAbility(const Want &want)

+

Starts an ability based on the specified Want information.

+

int StopAbility(const Want &want)

+

Stops a Service ability based on the specified Want information.

+

int TerminateAbility()

+

Destroys the ability.

+

int ConnectAbility(const Want &want, const IAbilityConnection &conn, void *data);

+

Connects to a Service ability based on the specified Want information.

+

int DisconnectAbility(const IAbilityConnection &conn)

+

Disconnects from a Service ability.

+

const char *GetBundleName()

+

Obtains the bundle name of the application to which the ability belongs.

+

const char *GetSrcPath()

+

Obtains the source code path of the ability.

+

const char *GetDataPath()

+

Obtains the data path of the ability.

+

int StartAbility(const Want *want)

+

Starts an Ability. This function does not need to be used in applications developed based on Ability.

+

int ConnectAbility(const Want *want, const IAbilityConnection *conn, void *data);

+

Connects to a Service ability based on the specified Want information. This function does not need to be used in applications developed based on Ability.

+

int DisconnectAbility(const IAbilityConnection *conn);

+

Disconnects from a Service ability. This function does not need to be used in applications developed based on Ability.

+

int StopAbility(const Want *want)

+

Stops a Service ability based on the specified Want information. This function does not need to be used in applications developed based on Ability.

+

void (*OnAbilityConnectDone)(ElementName *elementName, SvcIdentity *serviceSid, int resultCode, void *data)

+

Called when a client is connected to a Service ability.

+

void (*OnAbilityDisconnectDone)(ElementName *elementName, int resultCode, void *data)

+

Called after all connections to a Service ability are disconnected.

+

void PostTask(const Task& task)

+

Posts a task to an asynchronous thread.

+

void PostQuit()

+

Quits the event loop of the current thread.

+

static AbilityEventHandler* GetCurrentHandler()

+

Obtains the event handler of the current thread.

+

void Run()

+

Starts running the event loop of the current thread.

+

#define REGISTER_AA(className)

+

Registers the class name of an Ability child class.

+

#define REGISTER_AS(className)

+

Registers the class name of an AbilitySlice child class.

+
+ +## How to Develop + +### Creating a Service Ability + +1. Create the **MyServiceAbility** child class from **Ability** in **my\_service\_ability.h**. + + ``` + class MyServiceAbility: public Ability { + protected: + void OnStart(const Want& want); + const SvcIdentity *OnConnect(const Want &want) override; + void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) override; + }; + ``` + +2. Call the **REGISTER\_AA** macro to register the **ServiceAbility** class with the application framework so that the framework can instantiate the **MyServiceAbility** class you have created. + + ``` + #include "my_service_ability.h" + + REGISTER_AA(ServiceAbility) + + void MyServiceAbility::OnStart(const Want& want) + { + printf("ServiceAbility::OnStart\n"); + Ability::OnStart(want); + } + + const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) + { + printf("ServiceAbility::OnConnect\n"); + return Ability::OnConnect(want); + } + + void MyServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) + { + printf("ServiceAbility::MsgHandle, funcId is %u\n", funcId); + int result = 0; + if (funcId == 0) { + result = IpcIoPopInt32(request) + IpcIoPopInt32(request); + } + // push data + IpcIoPushInt32(reply, result); + } + ``` + +3. Override the following lifecycle callbacks for Service abilities to implement your own logic for your Service ability. When overriding a lifecycle callback, you must call the corresponding function from the parent class. + - OnStart\(\) + + This callback is invoked when a Service ability is being created to perform Service ability initialization operations that take a short time. This callback is invoked only once in the entire lifecycle of a Service ability. + + ``` + void MyServiceAbility::OnStart(const Want& want) + { + printf("ServiceAbility::OnStart\n"); + Ability::OnStart(want); + } + ``` + + - OnConnect\(\) + + This callback is invoked when another ability is connected to the Service ability. This callback returns an **SvcIdentity** object for the other ability to interact with the Service ability. + + ``` + const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) + { + printf("ServiceAbility::OnConnect\n"); + return Ability::OnConnect(want); + } + ``` + + - OnDisconnect​\(\) + + This callback is invoked when another ability is disconnected from the Service ability. + + - OnStop\(\) + + This callback is invoked when a Service ability is destroyed. You should override this callback for your Service ability to clear its resources, such as threads and registered listeners. + + +4. Override the message handling function. + + The **MsgHandle** function is used by Service abilities to handle messages sent from clients. **funcId** indicates the type of the message sent from the client, and **request** indicates the pointer to the serialized request parameters sent from the client. If you want to send the result back after the message is handled, serialize the result and write it into **reply**. + + ``` + void ServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) + { + printf("ServiceAbility::MsgHandle, funcId is %d\n", funcId); + int result = 0; + if (funcId == PLUS) { + result = IpcIoPopInt32(request) + IpcIoPopInt32(request); + } + // push data + IpcIoPushInt32(reply, result); + } + ``` + +5. Register a Service ability. + + Declare your Service ability in the **config.json** file by setting its **type** attribute to **service**. + + ``` + "abilities": [{ + "name": "ServiceAbility", + "icon": "res/drawable/phone.png", + "label": "test app 2", + "launchType": "standard", + "type": "service", + "visible": true + } + ] + ``` + +6. Start a Service ability. + - The **Ability** class provides the **StartAbility\(\)** function to start another ability. You can pass a **Want** object to this function to start a Service ability. + + You can use the **SetWantElement\(\)** function provided in the **AbilityKit** to set information about the target Service ability to start. The **element** parameter of the **SetWantElement\(\)** function indicates the **ElementName** structure that contains the bundle name and target ability name required for starting an ability. + + ``` + { + Want want = { nullptr }; + ElementName element = { nullptr }; + SetElementBundleName(&element, "com.company.appname"); + SetElementAbilityName(&element, "ServiceAbility"); + SetWantElement(&want, element); + StartAbility(want); + ClearElement(&element); + ClearWant(&want); + } + ``` + + The **StartAbility\(\)** function is executed immediately. If the Service ability is not running while the function is called, the system invokes **OnStart\(\)** first. + + - Stops a Service ability. + + Once created, the Service ability keeps running in the background. You can call **StopAbility\(\)** to stop the Service ability. + + +7. Connect to a Service ability. + - If you need to connect a Service ability to a Page ability or to a Service ability in another application, you should first create a Service ability for connection. A Service ability allows other abilities to connect to it through **ConnectAbility\(\)** by passing a **Want** object that contains information about the target Service ability to the function. You can implement callbacks in **IAbilityConnection** to be invoked when a Service ability is connected or disconnected. The **OnAbilityConnectDone\(\)** callback is invoked when an ability is connected, and **OnAbilityDisconnectDone\(\)** is invoked when an ability is disconnected. + + ``` + { + // Create an IAbilityConnection object and implement the two callbacks. + IAbilityConnection abilityConnection = new IAbilityConnection(); + abilityConnection->OnAbilityConnectDone = OnAbilityConnectDone; + abilityConnection->OnAbilityDisconnectDone = OnAbilityDisconnectDone; + + void OnAbilityConnectDone(ElementName *elementName, SvcIdentity *serviceSid, + int resultCode, void *data) + { + if (resultCode != 0) { + return; + } + // Push data. + IpcIo request; + char dataBuffer[IPC_IO_DATA_MAX]; + IpcIoInit(&request, dataBuffer, IPC_IO_DATA_MAX, 0); + IpcIoPushInt32(&request, 10); + IpcIoPushInt32(&request, 6); + + // Send and receive the reply. + IpcIo reply; + uintptr_t ptr = 0; + if (Transact(nullptr, *serviceSid, 0, &request, &reply, + LITEIPC_FLAG_DEFAULT, &ptr) != LITEIPC_OK) { + printf("transact error\n"); + return; + } + int result = IpcIoPopInt32(&reply); + printf("execute add method, result is %d\n", result); + if (ptr != 0) { + FreeBuffer(nullptr, reinterpret_cast(ptr)); + } + } + + void OnAbilityDisconnectDone(ElementName *elementName, + int resultCode, void *data) + { + printf("elementName is %s, %s\n", + elementName->bundleName, elementName->abilityName); + } + } + ``` + + - The following sample code snippet shows how to initiate ability connection and disconnection: + + ``` + { + // Connect an ability to a specified Service ability. + Want want = { nullptr }; + ElementName element = { nullptr }; + SetElementBundleName(&element, "com.company.appname"); + SetElementAbilityName(&element, "ServiceAbility"); + SetWantElement(&want, element); + ConnectAbility(want, *abilityConnection, this); + + // Disconnect from a Service ability. + DisconnectAbility(*abilityConnection); + } + ``` + + + +### Development Guidelines on Bundle Management + +**Installing an Application** + +The installation API can only be used by built-in system applications. Applications can be installed in either of the following paths: + +- Default installation directory **/storage/app/** in the system +- Particular directory on the external storage, for example, a microSD card + +You can specify the installation path when creating an **InstallParam** instance. To install the application in the **/storage/app/** directory, set the **installLocation** member variable in the **InstallParam** instance to **INSTALL\_LOCATION\_INTERNAL\_ONLY**. To install the application in the **/sdcard/app/** directory of the external storage, set **installLocation** to **INSTALL\_LOCATION\_PREFER\_EXTERNAL**. The application installation process is asynchronous, and a semaphore-like mechanism is required to ensure that the installation callback can be executed. + +The procedure for installing an application is as follows \(the system directory is used as an example\): + +1. Place the signed HAP file in a specified directory. +2. Create an **InstallParam** instance and define the semaphore. + + ``` + InstallParam installParam = { + .installLocation = INSTALL_LOCATION_INTERNAL_ONLY, // Install the application in the system directory. + .keepData = false + }; + static sem_t g_sem; + ``` + +3. Define the callback function. + + ``` + static void InstallCallback(const uint8_t resultCode, const void *resultMessage) + { + std::string strMessage = reinterpret_cast(resultMessage); + if (!strMessage.empty()) { + printf("install resultMessage is %s, %d\n", strMessage.c_str(),resultCode); + } + sem_post(&g_sem); + } + ``` + +4. Call the **Install** function. + + ``` + const uint32_t WAIT_TIMEOUT = 30; + sem_init(&g_sem, 0, 0); + std::string installPath = "/storage/bundle/demo.hap"; // Specify the path where the HAP file is stored. + bool result = Install(installPath.c_str(), &installParam, InstallCallback); + struct timespec ts = {}; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += WAIT_TIMEOUT; // Release the semaphore upon timeout. + sem_timedwait(&g_sem, &ts); + ``` + + +**Uninstalling an Application** + +When uninstalling an application, you can specify whether to retain application data using the **keepData** member variable in the created **InstallParam** instance. If **keepData** is set to **true**, the application data will be retained after the application is uninstalled. If the variable is set to **false**, the application data will be removed during application installation. + +1. Create an **InstallParam** instance and define the semaphore. + + ``` + static sem_t g_sem; + InstallParam installParam = { + .installLocation = 1, + .keepData = false // Remove application data. + }; + ``` + +2. Define the callback function. + + ``` + static void UninstallCallback(const uint8_t resultCode, const void *resultMessage) + { + std::string strMessage = reinterpret_cast(resultMessage); + if (!strMessage.empty()) { + printf("uninstall resultMessage is %s\n", strMessage.c_str()); + g_resultMessage = strMessage; + } + g_resultCode = resultCode; + sem_post(&g_sem); + } + ``` + +3. Call the **Uninstall** function. + + ``` + sem_init(&g_sem, 0, 0); + const uint32_t WAIT_TIMEOUT = 30; + std::string BUNDLE_NAME = "com.huawei.demo"; // Bundle name of the application to be uninstalled + Uninstall(BUNDLE_NAME.c_str(), &installParam, UninstallCallback); + struct timespec ts = {}; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += WAIT_TIMEOUT; + sem_timedwait(&g_sem, &ts); + ``` + + +**Querying Bundle Information About an Installed Application** + +You can use the **GetBundleInfo** function provided by **BundleManager** to query the bundle information about installed applications in the system. + +1. Create and initialize a **BundleInfo** object. + + ``` + BundleInfo bundleInfo; + (void) memset_s(&bundleInfo, sizeof(BundleInfo), 0, sizeof(BundleInfo)); + ``` + +2. Call **GetBundleInfo** to obtain bundle information about a specified application. The **bundleName** parameter indicates the pointer to the application bundle name, and the **flags** parameter specifies whether the obtained **BundleInfo** object can contain **AbilityInfo**. + + ``` + std::string BUNDLE_NAME = "com.huawei.demo"; + uint8_t ret = GetBundleInfo(BUNDLE_NAME.c_str(), 1, &bundleInfo); // When flags is set to 1, the obtained BundleInfo object contains AbilityInfo. + ``` + +3. After you finish using the obtained **BundleInfo** object, clear the memory space occupied by the object in a timely manner to prevent memory leakage. + + ``` + ClearBundleInfo(&bundleInfo); + ``` + + +### Packing a HAP File + +The packing tool is generally integrated into the development tool or IDE, and you rarely have the occasion to use it directly. This section is provided for you to have a general knowledge of the packing tool. The JAR file of the packing tool is stored in the **developtools/packing\_tool/jar** directory of the open-source code. + +- CLI command parameters for packing a HAP file + + **Table 2** Description of resource files required for packing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Command Parameter

+

Resource File

+

Description

+

Initial Value Allowed

+

--mode

+

-

+

This parameter is set to hap for packing the resource files into a HAP file.

+

No

+

--json-path

+

Configuration file config.json

+

-

+

No

+

--resources-path

+

Resource file resources

+

-

+

Yes

+

--assets-path

+

Resource file assets

+

-

+

Yes

+

--lib-path

+

Dependent library file

+

-

+

Yes

+

--shared-libs-path

+

Shared library file

+

The shared library is used by system applications in special cases.

+

Yes

+

--ability-so-path

+

SO file providing main functionality

+

-

+

Yes

+

--index-path

+

Resource index

+

The resource index file is generated by the resource generation tool and integrated by the resource pipeline.

+

Yes

+

--out-path

+

-

+

This parameter indicates the output path of the generated HAP file. The default value is the current directory.

+

Yes

+

--force

+

-

+

This parameter specifies whether to overwrite an existing file with the same name. The default value is false.

+

Yes

+
+ +- Example HAP File Structure + - Development view + + ![](figure/en-us_image_0000001062942690.png) + + - Compilation view + + ![](figure/en-us_image_0000001062334618.png) + + - Run the following commands to pack a HAP file using the packing tool. + + ![](figure/en-us_image_0000001062476933.png) + + ``` + $ java -jar hmos_app_packing_tool.jar --mode hap --json-path ./config.json --assets-path ./assets/ --ability-so-path ./libentry.so --index-path ./resources.index --out-path out/entry.hap --force true + ``` + + + diff --git a/en/device-dev/subsystems/subsys-application-framework-overview.md b/en/device-dev/subsystems/subsys-application-framework-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..a199610651dc5f2867adf61d356371d07e70b91a --- /dev/null +++ b/en/device-dev/subsystems/subsys-application-framework-overview.md @@ -0,0 +1,148 @@ +# Overview + +- [Basic Concepts](#section72601941194812) +- [Ability Management Framework](#section14633111813374) +- [Bundle Management Framework](#section1341146154412) +- [Working Principles](#section94302021112717) +- [Limitations and Constraints](#section89534912527) + +The application framework is provided by OpenHarmony for you to develop OpenHarmony applications. It consists of two modules: ability management framework \(also called the ability framework\) and bundle management framework. + +## Basic Concepts + +This section describes some basic concepts for you to better understand the OpenHarmony application framework before you start development. + +## Ability Management Framework + +The ability management framework manages running status of OpenHarmony applications. + +**Figure 1** Architecture of the ability management framework +![](figure/architecture-of-the-ability-management-framework.png "architecture-of-the-ability-management-framework") + +- **Ability** is the minimum unit for the system to schedule applications. It is a component that can implement an independent functionality. An application can contain one or more **Ability** instances. There are two types of templates that you can use to create an **Ability** instance: Page and Service. + - An **Ability using the Page template** \(Page ability for short\) provides a UI for interacting with users. + + - An **Ability using the Service template** does not have a UI and is used for running background tasks. + + + +- An **AbilitySlice** represents a single screen and its control logic. It is specific to Page abilities. A Page ability may contain one ability slice or multiple ability slices that provide highly relevant capabilities. + + **Figure 2** Relationship between a Page ability and its ability slices + ![](figure/relationship-between-a-page-ability-and-its-ability-slices.png "relationship-between-a-page-ability-and-its-ability-slices") + +- **Lifecycle** is a general term for all states of an ability, including **INITIAL**, **INACTIVE**, **ACTIVE**, and **BACKGROUND**. + + **Figure 3** Lifecycle state transition of a Page ability + + + ![](figure/图片1.png) + + - **OnStart\(\)** + + This callback is invoked when the system first creates the Page ability. After this callback is executed, the Page ability enters the **INACTIVE** state. This callback is triggered only once in the entire lifecycle of each Page ability. You must override this callback and set the default ability slice to be displayed. + + - **OnActive\(\)** + + This callback is invoked when the Page ability in the **INACTIVE** state enters the foreground. After this callback is executed, the Page ability enters the **ACTIVE** state, in which it becomes interactive. The Page ability will stay in this state unless it loses focus upon a certain event, for example, when the user touches the Back button or navigates to another Page ability. + + When such an event occurs, the Page ability returns to the **INACTIVE** state, and the system invokes the **OnInactive\(\)** callback. The Page ability may move to the **ACTIVE** state again, and the system will then invoke the **OnActive\(\)** callback again. You should implement both **OnActive\(\)** and **OnInactive\(\)** for a Page ability and use **OnActive\(\)** to obtain the resources released in **OnInactive\(\)**. + + - **OnInactive\(\)** + + This callback is invoked when the Page ability loses focus, and the Page ability then becomes **INACTIVE**. You can implement the behavior to perform after the Page ability loses focus. + + - **OnBackground\(\)** + + This callback is invoked based on the system resource status when the Page ability becomes invisible to the user. After this callback is executed, the Page ability enters the **BACKGROUND** state. You should release the resources that are no longer needed after the Page ability becomes invisible or perform time-consuming save operations in this callback. + + - **OnForeground\(\)** + + A Page ability in the **BACKGROUND** state still resides in memory. When the Page ability returns to the foreground \(for example, when the user navigates to this Page ability again\), the system first calls **OnForeground\(\)** to switch the Page ability to the **INACTIVE** state, and then calls **OnActive\(\)** to make it **ACTIVE**. You should use the **OnForeground\(\)** callback to reclaim the resources released in **OnBackground\(\)**. Currently, the **OnForeground\(\)** callback is unavailable to lite devices. + + - **OnStop\(\)** + + This callback is invoked when the system is destroying a Page ability due to one of the following possible causes: + + - The user explicitly closes the Page ability using a system management feature, for example, the task manager. + - The user behavior, for example, exiting an application, triggers the **TerminateAbility\(\)** function on the Page ability. + - The system needs to temporarily destroy the Page ability and re-create it due to configuration changes. + - The system automatically destroys a Page ability in the **BACKGROUND** state due to resource management purposes. + + +- **AbilityKit** is a development kit provided by the ability management framework. You can use this kit to develop applications based on the **Ability** component. There are two types of applications developed based on the **Ability** component: JS Ability developed using the JavaScript language and Native Ability developed using the C/C++ language. The JS application development framework encapsulates JavaScript UI components on the basis of the AbilityKit and is used to help you quickly develop JS Ability-based applications. +- **AbilityLoader** is used to register and load **Ability** classes. After creating an **Ability** class, you should first call the registration API defined in **AbilityLoader** to register the **Ability** class name with the ability management framework so that this **Ability** can be instantiated when being started. + +- **AbilityManager** enables inter-process communication \(IPC\) between the AbilityKit and the Ability Manager Service. + +- **EventHandler** is provided by the AbilityKit to enable inter-thread communication between abilities. + +- The **Ability Manager Service** is a system service used to coordinate the running relationships and lifecycle states of **Ability** instances. It consists of the following modules: + + - The service startup module starts and registers the Ability Manager Service. + - The service interface management module manages external capabilities provided by the Ability Manager Service. + - The process management module starts and destroys processes where **Ability** instances are running, and maintains the process information. + - The ability stack management module maintains the presentation sequence of abilities in the stack. + - The lifecycle scheduling module changes an ability to a particular state based on the current operation of the system. + - The connection management module manages connections to Service abilities. + +- **AppSpawn** is a system service used to create the process for running an ability. This service has high permissions. It sets permissions for **Ability** instances and pre-loads some common modules to accelerate application startup. + + +## Bundle Management Framework + +The bundle management framework is provided by OpenHarmony for you to manage application bundles. + +**Figure 4** Architecture of the bundle management framework +![](figure/architecture-of-the-bundle-management-framework.png "architecture-of-the-bundle-management-framework") + +- **BundleKit** includes external APIs provided by the Bundle Manager Service, including the APIs for application installation and uninstallation, bundle information query, and bundle state change listeners. +- The **bundle scanning sub-module** parses pre-installed or installed bundles on the local device and extracts information from them for the bundle management module to manage and make the information persistent for storage. +- The **bundle installation sub-module** installs, uninstalls, and updates a bundle. The **bundle installation service** is an independent process that communicates with the Bundle Manager Service through IPC. It is used to create or delete installation directories and has high permissions. + +- The **bundle management sub-module** manages information related to application bundles and stores persistent bundle information. + +- The **bundle security management sub-module** verifies signatures, and grants and manages permissions. + + +## Working Principles + +The Ability Manager Service and Bundle Manager Service are the core modules of the ability management framework and bundle management framework, respectively. The two system-level services are registered and discovered by using the system service framework SAMgr, and they are used by manage abilities and bundles for other processes. The Ability Manager Service and Bundle Manager Service are provided as open APIs in the AbilityKit and BundleKit. + +**Figure 5** Startup of the Ability Manager Service and Bundle Manager Service +![](figure/startup-of-the-ability-manager-service-and-bundle-manager-service.png "startup-of-the-ability-manager-service-and-bundle-manager-service") + +OpenHarmony applications can be installed and started after the two services are started. + +**Figure 6** Application startup process +![](figure/application-startup-process.png "application-startup-process") + +The home screen is the first OpenHarmony application started by the Ability Manager Service. After the home screen is started, the user can touch any installed OpenHarmony application on the home screen to start the particular application. The figure above shows the interaction process of starting an installed application from the home screen. + +As shown in the figure, the Ability Manager Service is responsible for displaying or hiding an ability, and the Bundle Manager Service is responsible for storing and querying ability information. + +## Limitations and Constraints + +- Language version + + - C++ 11 or later + + +- The specifications of the application framework vary depending on the System-on-a-Chip \(SoC\) and underlying OS capabilities. + + - Cortex-M RAM and ROM + + - RAM: greater than 20 KB \(recommended\) + + - ROM: greater than 300 KB \(for the JS application development framework and related subsystems, such as UIKit and engine\) + + + - Cortex-A RAM and ROM + + - RAM: greater than 2 MB \(recommended\) + + - ROM: greater than 2 MB \(for the JS application development framework and related subsystems, such as UIKit and engine\) + + + + diff --git a/en/device-dev/subsystems/subsys-application-framework.md b/en/device-dev/subsystems/subsys-application-framework.md new file mode 100644 index 0000000000000000000000000000000000000000..aeca8dc7dd6695791adc4204f1c76c88acd96568 --- /dev/null +++ b/en/device-dev/subsystems/subsys-application-framework.md @@ -0,0 +1,11 @@ +# Application Framework + +- **[Overview](subsys-application-framework-overview.md)** + +- **[Setting Up a Development Environment](subsys-application-framework-builden.md)** + +- **[Development Guidelines](subsys-application-framework-guide.md)** + +- **[Development Example](subsys-application-framework-demo.md)** + + diff --git a/en/device-dev/subsystems/appspawn-module.md b/en/device-dev/subsystems/subsys-boot-appspawn.md similarity index 100% rename from en/device-dev/subsystems/appspawn-module.md rename to en/device-dev/subsystems/subsys-boot-appspawn.md diff --git a/en/device-dev/subsystems/bootstrap-module.md b/en/device-dev/subsystems/subsys-boot-bootstrap.md similarity index 100% rename from en/device-dev/subsystems/bootstrap-module.md rename to en/device-dev/subsystems/subsys-boot-bootstrap.md diff --git a/en/device-dev/subsystems/subsys-boot-faqs.md b/en/device-dev/subsystems/subsys-boot-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..25aa1270b4fb1352445d1e41a4569eb255c95cf1 --- /dev/null +++ b/en/device-dev/subsystems/subsys-boot-faqs.md @@ -0,0 +1,56 @@ +# FAQs + +- [System startup interrupted due to "parse failed!" error](#section2041345718513) +- [System automatically restarted again and again](#section57381816168) +- [Failed to call the SetParameter or GetParameter API with correct parameter values](#section129991227141512) + +## System startup interrupted due to "parse failed!" error + +**Problem** + +During system startup, the error message "\[Init\] InitReadCfg, parse failed! please check file /etc/init.cfg format." is displayed, and the startup is interrupted, as shown in the following figure. + +![](figure/en-us_image_0000001063839940.png) + +**Cause** + +During the modification of the **init.cfg** file, required commas \(,\) or parentheses are missing or unnecessary ones are added. As a result, the file's JSON format becomes invalid. + +**Solution** + +Check the **init.cfg** file and ensure that its format meets the JSON specifications. + +## System automatically restarted again and again + +**Problem** + +After the image burning is complete, the system keeps restarting. + +**Cause** + +Each service started by the init process has the **importance** attribute, as described in Table 3 in [init Module](subsys-boot-init.md). + +- If the attribute value is **0**, the init process does not need to restart the development board when the current service process exits. +- If the attribute value is **1**, the init process needs to restart the development board when the current service process exits. + +During the startup of a service whose **importance** is **1**, if the service exits due to a process crash or an error, the init process automatically restarts the development board. + +**Solution** + +1. View logs to identify the service that encounters a process crash or exits due to an error, rectify the issue, and then burn the image again. +2. Alternatively, change the value of **importance** to **0** for the service that exits due to a process crash or an error, and then burn the image again. In this way, the development board will not be restarted even if the service exits. + +## Failed to call the **SetParameter** or **GetParameter** API with correct parameter values + +**Problem** + +Calling the **SetParameter** or **GetParameter** API fails even if correct values are passed to all input parameters. + +**Cause** + +Permission verification has been enabled for the **SetParameter** and **GetParameter** APIs. If the UID of the caller is greater than 1000, that is, the caller does not have the permission to call these APIs, API calls will fail even if the parameters are correct. + +**Solution** + +No action is required. + diff --git a/en/device-dev/subsystems/init-module.md b/en/device-dev/subsystems/subsys-boot-init.md similarity index 100% rename from en/device-dev/subsystems/init-module.md rename to en/device-dev/subsystems/subsys-boot-init.md diff --git a/en/device-dev/subsystems/subsys-boot-overview.md b/en/device-dev/subsystems/subsys-boot-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..77400377f93c5cbb3df8b79958bb6db53446ae72 --- /dev/null +++ b/en/device-dev/subsystems/subsys-boot-overview.md @@ -0,0 +1,66 @@ +# Startup + +- [Limitations and Constraints](#section2029921310472) + +The startup subsystem provides the functions of starting key system processes after the kernel is started and before applications are started, and restoring the system to factory settings. The subsystem consists of the following modules: + +- init module + + This module corresponds to the init process, which is the first user-space process started after the kernel is initialized. Upon startup, the init process reads and parses the configuration file **init.cfg**. Based on the parsing result, the init module executes the commands listed in Table 2 in [init Module](subsys-boot-init.md) and starts the key system service processes in sequence with corresponding permissions granted. + +- appspawn module + + This module spawns application processes upon receiving commands from the application framework, configures permissions for new processes, and calls the entry function of the application framework. + +- bootstrap module + + This module provides entry identifiers for starting services and features. When the Samgr is started, the entry function identified by boostrap is called and system services are started. + +- syspara module + + This module provides APIs for obtaining device information, such as the product name, brand name, and manufacturer name, based on the OpenHarmony Product Compatibility Specifications \(PCS\). It also provides APIs for setting and obtaining system parameters. + + +## Limitations and Constraints + +The directories of startup subsystem are applicable to different platforms. + +**Table 1** Directories and applicable platforms of the startup subsystem + + + + + + + + + + + + + + + + + + + +

Directory

+

Applicable Platform

+

base/startup/appspawn_lite

+

Small-system devices (reference memory ≥ 1 MB), for example, Hi3516D V300 and Hi3518E V300

+

base/startup/bootstrap_lite

+

Mini-system devices (reference memory ≥ 128 KB), for example, Hi3861 V100

+

base/startup/init_lite

+

Small-system devices (reference memory ≥ 1 MB), for example, Hi3516D V300 and Hi3518E V300

+

base/startup/syspara_lite

+
  • Mini-system devices (reference memory ≥ 128 KB), for example, Hi3861 V100
  • Small-system devices (reference memory ≥ 1 MB), for example, Hi3516D V300 and Hi3518E V300
+
+ +- init module + - After being burnt to the development board, the configuration file **init.cfg** changes to read-only. If you want to modify the file, you must repack and burn the rootfs image again. + - The configuration file **init.cfg** must be in JSON format. + +- bootstrap module: The zInit code needs to be configured in the link script. +- syspara module: The **SetParameter** and **GetParameter** APIs can only be called by applications whose UID is greater than 1000. + diff --git a/en/device-dev/subsystems/reference.md b/en/device-dev/subsystems/subsys-boot-ref.md similarity index 100% rename from en/device-dev/subsystems/reference.md rename to en/device-dev/subsystems/subsys-boot-ref.md diff --git a/en/device-dev/subsystems/syspara-module.md b/en/device-dev/subsystems/subsys-boot-syspara.md similarity index 100% rename from en/device-dev/subsystems/syspara-module.md rename to en/device-dev/subsystems/subsys-boot-syspara.md diff --git a/en/device-dev/subsystems/subsys-boot.md b/en/device-dev/subsystems/subsys-boot.md new file mode 100644 index 0000000000000000000000000000000000000000..b8f465d360614689758d2a538638e51da9f70007 --- /dev/null +++ b/en/device-dev/subsystems/subsys-boot.md @@ -0,0 +1,17 @@ +# Startup + +- **[Startup](subsys-boot-overview.md)** + +- **[init Module](subsys-boot-init.md)** + +- **[appspawn Module](subsys-boot-appspawn.md)** + +- **[bootstrap Module](subsys-boot-bootstrap.md)** + +- **[syspara Module](subsys-boot-syspara.md)** + +- **[FAQs](subsys-boot-faqs.md)** + +- **[Reference](subsys-boot-ref.md)** + + diff --git a/en/device-dev/subsystems/subsys-build-mini-lite.md b/en/device-dev/subsystems/subsys-build-mini-lite.md new file mode 100644 index 0000000000000000000000000000000000000000..5d95a69ed431174a90a4c3c5451b845e349809f2 --- /dev/null +++ b/en/device-dev/subsystems/subsys-build-mini-lite.md @@ -0,0 +1,998 @@ +# Building Guidelines for Mini and Small Systems + +- [Overview](#section10958256161119) + - [Basic Concepts](#section1732301411128) + - [Directory Structure](#section1588744014121) + - [Build Process](#section15761735134) + +- [Configuration Rules](#section2345183962710) + - [Module](#section142532518308) + - [Chipset](#section121501451143710) + - [Product](#section134549283435) + +- [Usage Guidelines](#section13754457192211) + - [Prerequisites](#section31651120233) + - [Using hb](#section1133304172313) + - [Adding a Module](#section167110415315) + - [Adding a Chipset Solution](#section1474718565412) + - [Adding a Product Solution](#section1097623294220) + +- [Troubleshooting](#section19909721104319) + - [Invalid -- w Option](#section138233464318) + - [Library ncurses Not Found](#section151033911442) + - [mcopy not Found](#section19811838104418) + - [No riscv File or Directory](#section03111118451) + - [No Crypto](#section69981127125013) + - [Unexpected Operator](#section967617530505) + + +## Overview + +The Compilation and Building subsystem is a build framework that supports module-based OpenHarmony development using Generate Ninja \(GN\) and Ninja. You can use this subsystem to: + +- Assemble modules for a product and build the product. + +- Build chipset source code independently. +- Build a single module independently. + +### Basic Concepts + +Learn the following concepts before you start compilation and building: + +- Subsystem + + A subsystem is a logical concept. It consists of one or more modules. OpenHarmony is designed with a layered architecture, which consists of the kernel layer, system service layer, framework layer, and application layer from bottom to top. System functions are developed by the level of system, subsystem, and module. In a multi-device deployment scenario, you can customize subsystems and modules as required. + + +- Module + + A module is a reusable, configurable, and tailorable function unit. Each module has an independent directory, and multiple modules can be developed concurrently and built and tested independently. + +- **GN** + + Generate Ninja \(GN\) is used to generate Ninja files. + +- **Ninja** + + Ninja is a small high-speed build system. + +- **hb** + + hb is a command line tool for OpenHarmony to execute build commands. + + +### Directory Structure + +``` +build/lite +├── components # Module description file +├── figures # Figures in the readme file +├── hb # hb pip installation package +├── make_rootfs # Script used to create the file system image +├── config # Build configuration +│ ├── component # Module-related template definition +│ ├── kernel # Kernel-related build configuration +│ └── subsystem # Subsystem build configuration +├── platform # ld script +├── testfwk # Test build framework +└── toolchain # Build toolchain configuration, which contains the compiler directories, build options, and linking options +``` + +### **Build Process** + +[Figure 1](#fig9744112715161) shows the build process. + +**Figure 1** Build process +![](figure/build-process.jpg "build-process") + +1. Use **hb set **to set the OpenHarmony source code directory and the product to build. +2. Use **hb build** to build the product, development board, or module. The procedure is as follows: + - Read the **config.gni** file of the development board selected. The file contains the build toolchain, linking commands, and build options. + - Run the **gn gen** command to read the product configuration and generate the **out** directory and **ninja** files for the solution. + - Run **ninja -C out/board/product** to start the build. + - Package the build result, set the file attributes and permissions, and create a file system image. + + +## Configuration Rules + +To ensure that the chipset and product solutions are pluggable and decoupled from OpenHarmony, the paths, directory trees, and configuration of modules, chipset solutions, and product solutions must comply with the following rules: + +### **Module** + +The source code directory for a module is named in the _\{Domain\}/\{Subsystem\}/\{Module\}_ format. The module directory tree is as follows: + +>![](../public_sys-resources/icon-caution.gif) **CAUTION:** +>Define module attributes, such as the name, source code directory, function description, mandatory or not, build targets, RAM, ROM, build outputs, adapted kernels, configurable features, and dependencies, in the JSON file of the subsystem in the **build/lite/components** directory. When adding a module, add its definition to the JSON file of the corresponding subsystem. The module configured for a product must have been defined in a subsystem. Otherwise, the verification will fail. + +``` +component +├── interfaces +│ ├── innerkits # APIs exposed internally among modules +│ └── kits # App APIs provided for app developers +├── frameworks # Framework implementation +├── services # Service implementation +└── BUILD.gn # Build script +``` + +The following example shows how to define attributes of the sensor module of the pan-sensor subsystem: + +``` +{ + "components": [ + { + "component": "sensor_lite", # Module name + "description": "Sensor services", # Brief description of the module + "optional": "true", # Whether the module is mandatory for the system + "dirs": [ # Source code directory of the module + "base/sensors/sensor_lite" + ], + "targets": [ # Build entry of the module + "//base/sensors/sensor_lite/services:sensor_service" + ], + "rom": "92KB", # Module ROM + "ram": "~200KB", # Module RAM (estimated) + "output": [ "libsensor_frameworks.so" ], # Module build outputs + "adapted_kernel": [ "liteos_a" ], # Adapted kernel for the module + "features": [], # Configurable features of the module + "deps": { + "components": [ # Other modules on which the module depends + "samgr_lite", + "ipc_lite" + + ], + "third_party": [ # Open-source third-party software on which the module depends + "bounds_checking_function" + ] + } + } + ] +} +``` + +Observe the following rules when building the **BUILD.gn** module: + +- The build target name must be the same as the module name. +- Define the configurable features in the **BUILD.gn** file of the module. Name the configurable features in the **ohos\_**\{_subsystem_\}**\_**\{_module_\}**\_**\{_feature_\} format. Define the features in module description and configure them in the **config.json** file. +- Define macros in the **OHOS\_**\{_SUBSYSTEM_\}**\_**\{_MODULE_\}**\_**\{_FEATURE_\} format. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >GN is used as the build script language for modules. For details about how to use GN, see the [GN Quick Start Guide](https://gn.googlesource.com/gn/+/master/docs/quick_start.md). In GN, a module is a build target, which can be a static library, a dynamic library, an executable file, or a group. + + +The following example shows how to build the **foundation/graphic/ui/BUILD.gn** file for a graphics UI module: + +``` + # Declare the configurable features of the module + declare_args() { + enable_ohos_graphic_ui_animator = false # Animation switch + ohos_ohos_graphic_ui_font = "vector" # Configurable font type, which can be vector or bitmap + } + + # Basic module functions + shared_library("base") { + sources = [ + ...... + ] + include_dirs = [ + ...... + ] + } + + # Build only when the animator is enabled + if(enable_ohos_graphic_ui_animator ) { + shared_library("animator") { + sources = [ + ...... + ] + include_dirs = [ + ...... + ] + deps = [ :base ] + } + } + ...... + # It is recommended that the target name be the same as the module name, which can be an executable .bin file, shared_library (.so file), static_library (.a file), or a group. + executable("ui") { + deps = [ + ":base" + ] + + # The animator feature is configured by the product. + if(enable_ohos_graphic_ui_animator ) { + deps += [ + "animator" + ] + } + } +``` + +### **Chipset** + +- The chipset solution is a complete solution based on a development board. The solution includes the drivers, API adaptation, and SDK. +- The chipset solution is a special module, whose source code directory is named in the _**device**/\{Chipset solution vendor\}/\{Development board\}_ format. +- The chipset solution module is built by default based on the development board selected by the product. + +The chipset solution directory tree is as follows: + +``` +device +└── company # Chipset solution vendor + └── board # Name of the development board + ├── BUILD.gn # Build script + ├── hals # Southbound APIs for OS adaptation + ├── linux # Linux kernel version (optional) + │ └── config.gni # Build options for the Linux version + └── liteos_a # LiteOS kernel version (optional) + └── config.gni # Build options for the LiteOS Cortex-A version +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The **config.gni** file contains build-related configurations of the development board. The parameters in the file are globally visible to the system and can be used to build all OS modules during the build process. + +The **config.gni** file contains the following key parameters: + +``` +kernel_type: kernel used by the development board, for example, liteos_a, liteos_m, or linux. +kernel_version: kernel version used by the development board, for example, 4.19. +board_cpu: CPU of the development board, for example, cortex-a7 or riscv32. +board_arch: chipset architecture of the development board, for example, armv7-a or rv32imac. +board_toolchain: name of the customized build toolchain used by the development board, for example, gcc-arm-none-eabi. If this field is not specified, ohos-clang will be used by default. +board_toolchain_prefix: prefix of the build toolchain, for example, gcc-arm-none-eabi. +board_toolchain_type: build toolchain type, for example, gcc or clang. Currently, only GCC and clang are supported. +board_cflags: build options of the .c file configured for the development board. +board_cxx_flags: build options of the .cpp file configured for the development board. +board_ld_flags: link options configured for the development board. +``` + +### **Product** + +The product solution is a complete product based on a development board. It includes the OS adaptation, module assembly configuration, startup configuration, and file system configuration. The source code directory of a product solution is named in the **vendor**/\{_Product solution vendor_\}/\{_Product name_\} format. A product solution is also a special module. + +The product solution directory tree is as follows: + +``` +vendor +└── company # Product solution vendor + ├── product # Product name + │ ├── init_configs + │ │ ├── etc # Startup configuration of the init process (only required for the Linux kernel) + │ │ └── init.cfg # System service startup configuration + │ ├── hals # OS adaptation + │ ├── BUILD.gn # Product build script + │ └── config.json # Product configuration file + │ └── fs.yml # File system packaging configuration + └── ...... +``` + +>![](../public_sys-resources/icon-caution.gif) **CAUTION:** +>Create directories and files based on the preceding rules for new products. The Compilation and Building subsystem scans the configured products based on the rules. + +The key directories and files are described as follows: + +1. **vendor/company/product/init\_configs/etc** + + This folder contains the **rcS**, **S**_xxx_, and **fstab** scripts. The **init** process runs the **rcS**, **fstab**, and **S**_00_-_xxx_ scripts in sequence before starting system services. The **S**_xxx_ script contains content related to the development board and product. It is used to create device nodes and directories, scan device nodes, and change file permissions. These scripts are copied from the **BUILD.gn** file to the **out** directory of the product as required and packaged into the **rootfs** image. + +2. **vendor/company/product/init\_configs/init.cfg** + + This file is the configuration file for the **init** process to start services. Currently, the following commands are supported: + + - **start**: starts a service. + - **mkdir**: creates a folder. + - **chmod**: changes the permission on a specified directory or file. + - **chown**: changes the owner group of a specified directory or file. + - **mount**: mounts a device. + + The fields in the file are described as follows: + + ``` + { + "jobs" : [{ # Job array. A job corresponds to a command set. Jobs are executed in the following sequence: pre-init > init > post-init. + "name" : "pre-init", + "cmds" : [ + "mkdir /storage/data", # Create a directory. + "chmod 0755 /storage/data", # Change the permission, which is in 0xxx format, for example, 0755. + "mkdir /storage/data/log", + "chmod 0755 /storage/data/log", + "chown 4 4 /storage/data/log", # Change the owner group. The first number indicates the UID, and the second indicates the GID. + ...... + "mount vfat /dev/mmcblock0 /sdcard rw, umask=000" # The command is in the mount [File system type][source] [target] [flags] [data] format. + # Currently, flags can only be nodev, noexec, nosuid, or rdonly. + ] + }, { + "name" : "init", + "cmds" : [ # Start services based on the sequence of the cmds array. + "start shell", # Note that there is only one space between start and the service name. + ...... + "start service1" + ] + }, { + "name" : "post-init", # Job that is finally executed. Operations performed after the init process is started, for example, mounting a device after the driver initialization. + "cmds" : [] + } + ], + "services" : [{ # Service array. A service corresponds to a process. + "name" : "shell", # Service name + "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"], # Full path of the executable file. It must start with "path". + "uid" : 0, # Process UID, which must be the same as that in the binary file. + "gid" : 0, # Process GID, which must be the same as that in the binary file. + "once" : 0, # Whether the process is a one-off process. 1: The proces is a one-off process. The init process does not restart it after the process exits. 0: The process is not a one-off process. The init process restarts it if the process exits. + "importance" : 0, # Whether the process is a key process. 1: The process is a key process. If it exits, the init process restarts the board. 0: The process is not a key process. If it exits, the init process does not restart the board. + "caps" : [4294967295] + }, + ...... + ] + } + ``` + +3. **vendor/company/product/init\_configs/hals** + + This file stores the content related to OS adaptation of the product. For details about APIs for implementing OS adaptation, see the readme file of each module. + +4. **vendor/company/product/config.json** + + The **config.json** file is the main entry for the build and contains configurations of the development board, OS modules, and kernel. + + The following example shows the **config.json** file of the IP camera developed based on the hispark\_taurus development board: + + ``` + { + "product_name": "ipcamera", # Product name + "ohos_version": "OpenHarmony 1.0", # OS version + "device_company": "hisilicon", # Chipset vendor + "board": "hispark_taurus", # Name of the development board + "kernel_type": "liteos_a", # Kernel type + "kernel_version": "3.0.0", # Kernel version + "subsystems": [ + { + "subsystem": "aafwk", # Subsystem + "components": [ + { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] } # Module and its features + ] + }, + { + ...... + } + ...... + More subsystems and modules + } + } + ``` + +5. **vendor/company/product/fs.yml** + + This file packages the build result to create a configuration file system image, for example, **rootfs.img** \(user-space root file system\) and **userfs.img** \(readable and writable file\). It consists of multiple lists, and each list corresponds to a file system. The fields are described as follows: + + ``` + fs_dir_name: (Mandatory) declares the name of the file system, for example, rootfs or userfs. + fs_dirs: (Optional) configures the mapping between the file directory in the out directory and the system file directory. Each file directory corresponds to a list. + source_dir: (Optional) specifies the target file directory in the out directory. If this field is missing, an empty directory will be created in the file system based on target_dir. + target_dir: (Mandatory) specifies the corresponding file directory in the file system. + ignore_files: (Optional) declares ignored files during the copy operation. + dir_mode: (Optional) specifies the file directory permission, which is set to 755 by default. + file_mode: (Optional) declares permissions of all files in the directory, which is set to 555 by default. + fs_filemode: (Optional) configures files that require special permissions. Each file corresponds to a list. + file_dir: (Mandatory) specifies the detailed file path in the file system. + file_mode: (Mandatory) declares file permissions. + fs_symlink: (Optional) configures the soft link of the file system. + fs_make_cmd: (Mandatory) creates the file system script. The script provided by the OS is stored in the build/lite/make_rootfs directory. Linux, LiteOS, ext4, jffs2, and vfat are supported. Chipset vendors can also customize the script as required. + fs_attr: (Optional) dynamically adjusts the file system based on configuration items. + ``` + + The **fs\_symlink** and **fs\_make\_cmd** fields support the following variables: + + - $\{root\_path\} + + Code root directory, which corresponds to **$\{ohos\_root\_path\}** of GN + + - $\{out\_path\} + + **out** directory of the product, which corresponds to **$\{root\_out\_dir\}** of GN + + - $\{fs\_dir\} + + File system directory, which consists of the following variables + + - $\{root\_path\} + - $\{fs\_dir\_name\} + + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >**fs.yml** is optional and does not need to be configured for devices without a file system. + +6. **vendor/company/product/BUILD.gn** + + This file is the entry for building the source code of the solution vendor and copying the startup configuration file. The **BUILD.gn** file in the corresponding product directory will be built by default if a product is selected. The following example shows how to build the **BUILD.gn** file of a product: + + ``` + group("product") { # The target name must be the same as the product name (level-3 directory name under the product directory). + deps = [] + # Copy the init configuration. + deps += [ "init_configs" ] + # Others + ...... + } + ``` + + +## Usage Guidelines + +### Prerequisites + +The development environment has GN, Ninja, Python 3.7.4 or later, and hb available. For details about installation methods, see [Environment Setup](../quick-start/quickstart-lite-env-setup.md). + +### Using hb + +**hb** is a command line tool for OpenHarmony to execute build commands. Common hb commands are described as follows: + +**hb set** + +``` +hb set -h +usage: hb set [-h] [-root [ROOT_PATH]] [-p] + +optional arguments: + -h, --help show this help message and exit + -root [ROOT_PATH], --root_path [ROOT_PATH] + Set OHOS root path + -p, --product Set OHOS board and kernel +``` + +- **hb set** \(without argument\): starts the default setting process. +- **hb set -root** _dir_: sets the root directory of the code. +- **hb set -p**: sets the product to build. + +**hb env** + +Displays the current configuration. + +``` +hb env +[OHOS INFO] root path: xxx +[OHOS INFO] board: hispark_taurus +[OHOS INFO] kernel: liteos +[OHOS INFO] product: ipcamera +[OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera +[OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 +``` + +**hb build** + +``` +hb build -h +usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] + [--dmverity] [--tee] [-p PRODUCT] [-f] [-n] + [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch] + [component [component ...]] + +positional arguments: + component name of the component + +optional arguments: + -h, --help show this help message and exit + -b BUILD_TYPE, --build_type BUILD_TYPE + release or debug version + -c COMPILER, --compiler COMPILER + specify compiler + -t [TEST [TEST ...]], --test [TEST [TEST ...]] + compile test suit + --dmverity Enable dmverity + --tee Enable tee + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: camera@huawei + -f, --full full code compilation + -n, --ndk compile ndk + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target + -v, --verbose show all command lines while building + -shs, --sign_haps_by_server + sign haps by server + --patch apply product patch before compiling + + --dmverity Enable dmverity + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: ipcamera@hisilcon + -f, --full full code compilation + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target +``` + +- **hb build** \(without argument\): builds the code based on the configured code directory, product, and options. The **-f** option deletes all products to be built, which is equivalent to running **hb clean** and **hb build**. +- **hb build** _\{module\_name\}_: builds a product module separately based on the development board and kernel set for the product, for example, **hb build kv\_store**. +- **hb build -p ipcamera@hisilicon**: skips the **set** step and builds the product directly. +- You can run **hb build** in **device/device\_company/board** to select the kernel and start the build based on the current development board and the selected kernel to generate an image that contains the kernel and driver only. + +**hb clean** + +You can run **hb clean** to clear the build result of the product in the **out** directory and retain the **args.gn** and **build.log** files only. To clear files in a specified directory, add the directory parameter to the command, for example, **hb clean out/xxx/xxx**. + +``` +hb clean +usage: hb clean [-h] [out_path] + +positional arguments: + out_path clean a specified path. + +optional arguments: + -h, --help show this help message and exit +``` + +### Adding a Module + +To add a module, determine the subsystem to which the module belongs and the module name, and then perform the following steps: + +1. Add the module build script after the source code development is complete. + + The following example adds the **BUILD.gn** script \(stored in the **applications/sample/hello\_world** directory\) to build the **hello\_world** module \(as an executable file\). + + ``` + executable("hello_world") { + include_dirs = [ + "include", + ] + sources = [ + "src/hello_world.c" + ] + } + ``` + + The above script is used to build **hello\_world** that can run on OpenHarmony. + + To build the preceding module separately, select a product via the **hb set** command and run the **-T** command. + + ``` + hb build -f -T //applications/sample/hello_world + ``` + + After the module functions are verified on the development board, perform steps [2 to 4](#li11471037297) to configure the module to the product. + +2. Add module description. + + The module description is stored in the **build/lite/components** directory. New modules must be added to the JSON file of the corresponding subsystem. The module description must contain the following fields: + + - **module**: name of the module + - **description**: brief description of the module + - **optional**: whether the module is optional + - **dirs**: source code directory of the module + - **targets**: module build entry + + For example, to add the **hello\_world** module to the application subsystem, add the **hello\_world** object to the **applications.json** file. + + ``` + { + "components": [ + { + "component": "hello_world", + "description": "Hello world.", + "optional": "true", + "dirs": [ + "applications/sample/hello_world" + ], + "targets": [ + "//applications/sample/hello_world" + ] + }, + ... + ] + } + ``` + +3. Configure the module for the product. + + The **config.json** file is stored in the **vendor/company/product/** directory. The file must contain the product name, OpenHarmony version, device vendor, development board, kernel type, kernel version, and the subsystem and module to configure. The following example adds the **hello\_world** module to the **my\_product.json** configuration file: + + ``` + { + "product_name": "hello_world_test", + "ohos_version": "OpenHarmony 1.0", + "device_company": "hisilicon", + "board": "hispark_taurus", + "kernel_type": "liteos_a", + "kernel_version": "1.0.0", + "subsystems": [ + { + "subsystem": "applications", + "components": [ + { "component": "hello_world", "features":[] } + ] + }, + ... + ] + } + ``` + +4. Build the product. + + 1. Run the **hb set** command in the root code directory and select the product. + + 2. Run the **hb build** command. + + +### Adding a Chipset Solution + +The following uses the RTL8720 development board provided by Realtek as an example. To a chipset solution, perform the following steps: + +1. Create a directory for the chipset solution. + + To create a directory based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](#section1625463413327), run the following command in the root code directory: + + ``` + mkdir -p device/realtek/rtl8720 + ``` + +2. Create a directory for kernel adaptation and build the **config.gni** file of the development board. + + For example, to adapt the LiteOS Cortex-M kernel to the RTL8720 development board, configure the **device/realtek/rtl8720/liteos\_a/config.gni** file as follows: + + ``` + # Kernel type, e.g. "linux", "liteos_a", "liteos_m". + kernel_type = "liteos_a" + + # Kernel version. + kernel_version = "3.0.0" + + # Board CPU type, e.g. "cortex-a7", "riscv32". + board_cpu = "real-m300" + + # Board arch, e.g. "armv7-a", "rv32imac". + board_arch = "" + + # Toolchain name used for system compiling. + # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. + # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. + board_toolchain = "gcc-arm-none-eabi" + + # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. + board_toolchain_path = + rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", + root_build_dir) + + # Compiler prefix. + board_toolchain_prefix = "gcc-arm-none-eabi-" + + # Compiler type, "gcc" or "clang". + board_toolchain_type = "gcc" + + # Board related common compile flags. + board_cflags = [] + board_cxx_flags = [] + board_ld_flags = [] + ``` + +3. Build the script. + + Create the **BUILD.gn** file in the development board directory. The target name must be the same as that of the development board. The content in the **device/realtek/rtl8720/BUILD.gn** file is configured as follows: + + ``` + group("rtl8720") { # The target can be shared_library, static_library, or an executable file. + # Content + ...... + } + ``` + +4. Build the chipset solution. + + Run the **hb build** command in the development board directory to start the build. + + +### Adding a Product Solution + +You can use the Compilation and Building subsystem to customize product solutions by assembling chipset solutions and modules. The procedure is as follows: + +1. Create a product directory. + + The following uses the Wi-Fi IoT module on the RTL8720 development board as an example. Run the following command in the root code directory to create a product directory based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](#section1625463413327): + + ``` + mkdir -p vendor/my_company/wifiiot + ``` + +2. Assemble the product. + + Create the **config.json** file in the product directory. The **vendor/my\_company/wifiiot/config.json** file is as follows: + + ``` + { + "product_name": "wifiiot", # Product name + "ohos_version": "OpenHarmony 1.0", # OS version + "device_company": "realtek", # Name of the chipset solution vendor + "board": "rtl8720", # Name of the development board + "kernel_type": "liteos_m", # Kernel type + "kernel_version": "3.0.0", # Kernel version + "subsystems": [ + { + "subsystem": "kernel", # Subsystem + "components": [ + { "component": "liteos_m", "features":[] } # Module and its features + ] + }, + ... + { + More subsystems and modules + } + ] + } + ``` + + Before the build, the Compilation and Building subsystem checks the validity of fields, including **device\_company**, **board**, **kernel\_type**, **kernel\_version**, **subsystem**, and **component**. The **device\_company**, **board**, **kernel\_type**, and **kernel\_version** fields must match the current chipset solution, and **subsystem** and **component** must match the module description in the **build/lite/components** file. + +3. Implement adaptation to OS APIs. + + Create the **hals** directory in the product directory and store the source code as well as the build script for OS adaptation in this directory. + +4. Configure the system service. + + Create the **init\_configs** directory in the product directory and then the **init.cfg** file in the newly created directory. Configure the system service to be started. + +5. \(Optional\) Configure the init process only for the Linux kernel. + + Create the **etc** directory in the **init\_configs** directory, and then the **init.d** folder and the **fstab** file in the newly created directory. Then, create the **rcS** and **S**_xxx_ files in the **init.d** file and edit them based on product requirements. + +6. \(Optional\) Configure the file system image only for the development board that supports the file system. + + Create the **fs.yml** file in the product directory and configure it as required. A typical **fs.yml** file is as follows: + + ``` + - + fs_dir_name: rootfs # Image name + fs_dirs: + - + # Copy the files in the out/my_board/my_product/bin directory to the rootfs/bin directory and ignore the .bin files related to testing. + source_dir: bin + target_dir: bin + ignore_files: + - Test.bin + - TestSuite.bin + - + # Copy the files in the out/my_board/my_product/libs directory to the rootfs/lib directory, ignore all .a files, and set the file permissions to 644 and folder permissions 755. + source_dir: libs + target_dir: lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: usr/lib + target_dir: usr/lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: config + target_dir: etc + - + source_dir: system + target_dir: system + - + source_dir: sbin + target_dir: sbin + - + source_dir: usr/bin + target_dir: usr/bin + - + source_dir: usr/sbin + target_dir: usr/sbin + - + # Create an empty proc directory. + target_dir: proc + - + target_dir: mnt + - + target_dir: opt + - + target_dir: tmp + - + target_dir: var + - + target_dir: sys + - + source_dir: etc + target_dir: etc + - + source_dir: vendor + target_dir: vendor + - + target_dir: storage + + fs_filemode: + - + file_dir: lib/ld-uClibc-0.9.33.2.so + file_mode: 555 + - + file_dir: lib/ld-2.24.so + file_mode: 555 + - + file_dir: etc/init.cfg + file_mode: 400 + fs_symlink: + - + # Create the soft link ld-musl-arm.so.1 -> libc.so in the rootfs/lib directory. + source: libc.so + link_name: ${fs_dir}/lib/ld-musl-arm.so.1 + - + source: mksh + link_name: ${fs_dir}/bin/sh + - + source: mksh + link_name: ${fs_dir}/bin/shell + fs_make_cmd: + # Create an ext4 image for the rootfs directory using the script. + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + - + fs_dir_name: userfs + fs_dirs: + - + source_dir: storage/etc + target_dir: etc + - + source_dir: data + target_dir: data + fs_make_cmd: + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + + ``` + +7. \(Optional\) Configure patches if the product and modules need to be patched. + + Create the **patch.yml** file in the product directory and configure it as required. A typical **patch.yml** file is as follows: + + ``` + # Directory in which the patch is to be installed + foundation/communication/dsoftbus: + # Directory in which the patch is stored + - foundation/communication/dsoftbus/1.patch + - foundation/communication/dsoftbus/2.patch + third_party/wpa_supplicant: + - third_party/wpa_supplicant/1.patch + - third_party/wpa_supplicant/2.patch + - third_party/wpa_supplicant/3.patch + ... + ``` + + If you add **--patch** when running the **hb build** command, the patch file can be added to the specified directory before the build. + + ``` + hb build -f --patch + ``` + +8. Build the script. + + Create the **BUILD.gn** file in the product directory and write the script. The following **BUILD.gn** file uses the Wi-Fi IoT module in [1](#li1970321162111) as an example: + + ``` + group("wifiiot") { # The target name must be the same as the product name. + deps = [] + # Copy the init configuration. + deps += [ "init_configs" ] + # Build the hals directory. + deps += [ "hals" ] + # Others + ...... + } + ``` + +9. Build the product. + + Run the **hb set** command in the code root directory, select the new product as prompted, and run the **hb build** command. + + +## Troubleshooting + +### Invalid -- w Option + +- **Symptom** + + The build fails, and "usr/sbin/ninja: invalid option -- w" is displayed. + +- **Cause** + + The Ninja version in the build environment is outdated and does not support the **--w** option. + +- **Solution** + + Uninstall Ninja and GN and follow the instructions provided in [IDE](../get-code/gettools-ide.md) to install Ninja and GN of the required version. + + +### Library ncurses Not Found + +- **Symptom** + + The build fails, and "/usr/bin/ld: cannot find -lncurses" is displayed. + +- **Cause** + + The ncurses library is not installed. + +- **Solution** + + ``` + sudo apt-get install lib32ncurses5-dev + ``` + + +### mcopy not Found + +- **Symptom** + + The build fails, and "line 77: mcopy: command not found" is displayed. + +- **Cause** + + mcopy is not installed. + +- **Solution** + + ``` + ​sudo apt-get install dosfstools mtools + ``` + + +### No riscv File or Directory + +- **Symptom** + + The build fails, and the following information is displayed: + + riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory. + +- **Cause** + + Permission is required to access files in the **riscv** compiler directory. + +- **Solution** + + Run the following command to query the directory where **gcc\_riscv32** is located: + + ``` + which riscv32-unknown-elf-gcc + ``` + + Run the **chmod** command to change the directory permission to **755**. + + +### No Crypto + +- **Symptom** + + The build fails, and "No module named 'Crypto'" is displayed. + +- **Cause** + + Crypto is not installed in Python 3. + +- **Solution** + 1. Run the following command to query the Python version: + + ``` + python3 --version + ``` + + 2. Ensure that Python 3.7 or later is installed, and then run the following command to install pycryptodome: + + ``` + sudo pip3 install pycryptodome + ``` + + + +### Unexpected Operator + +- **Symptom** + + The build fails, and "xx.sh \[: xx unexpected operator" is displayed. + +- **Cause** + + The build environment is shell, not bash. + +- **Solution** + + ``` + sudo rm -rf /bin/sh + sudo ln -s /bin/bash /bin/sh + ``` + + diff --git a/en/device-dev/subsystems/subsys-build-standard-large.md b/en/device-dev/subsystems/subsys-build-standard-large.md new file mode 100644 index 0000000000000000000000000000000000000000..e1a47c1b1329e7efcf2947b9018ae202e3dd50f1 --- /dev/null +++ b/en/device-dev/subsystems/subsys-build-standard-large.md @@ -0,0 +1,237 @@ +# Building Guidelines for Standard Systems + +- [Overview](#section17466112012244) + - [Basic Concepts](#section445513507246) + - [Working Principles](#section12541217142510) + - [Limitations and Constraints](#section886933762513) + +- [Compilation and Building Guidelines](#section16901215262) + - [Directory Structure](#section109065332264) + - [Build Command](#section123265539266) + - [How to Develop](#section591084422719) + + +## Overview + +The compilation and building subsystem provides a framework based on Generate Ninja \(GN\) and Ninja. This subsystem allows you to: + +- Build products based on different chipset platforms, for example, Hi3516D V300. + +- Package capabilities required by a product by assembling modules based on the product configuration. + +### Basic Concepts + +It is considered best practice to learn the following basic concepts before you start building: + +- **Platform** + + A platform is a combination of development boards and kernels. + + Supported subsystems and modules vary according to the platform. + +- **Subsystems** + + OpenHarmony is designed with a layered architecture, which from bottom to top consists of the kernel layer, system service layer, framework layer, and application layer. System functions are expanded by levels, from system to subsystem, and further to module. In a multi-device deployment scenario, unnecessary subsystems and modules can be excluded from the system as required. A subsystem is a logical concept and is a flexible combination of functions. + +- **Module** + + A module is a reusable software binary unit that contains source code, configuration files, resource files, and build scripts. A module can be built independently, integrated in binary mode, and then tested independently. + +- **GN** + + GN is short for Generate Ninja, which is used to generate Ninja files. + +- **Ninja** + + Ninja is a small high-speed build system. + + +### Working Principles + +The process to build OpenHarmony is as follows: + +- Parsing commands: Parse the name of the product to build and load related configurations. +- Running GN: Configure toolchains and global options based on the parsed product name and compilation type. +- Running Ninja: Start building and generate a product distribution. + +### Limitations and Constraints + +- You must download the source code using method 3 described in [Source Code Acquisition](../get-code/sourcecode-acquire.md). +- The build environment must be Ubuntu 18.04 or later. +- You must install the software package required for build. + + The installation command is as follows: + + ``` + sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 + ``` + + +## Compilation and Building Guidelines + +### Directory Structure + +``` +/build # Primary directory +├── config # Build configuration items +├── core +│ └── gn # Build entry BUILD.gn configuration +├── loader # Loader of module configuration, which also generates a template for the module +├── ohos # Configuration of the process for building and packaging OpenHarmony +│ ├── kits # Build and packaging templates and processing flow for kits +│ ├── ndk # NDK template and processing flow +│ ├── notice # Notice template and processing flow +│ ├── packages # Distribution packaging template and processing flow +│ ├── sa_profile # SA template and processing flow +│ ├── sdk # SDK template and processing flow, which contains the module configuration in the SDK +│ └── testfwk # Processing flow related to the test +├── scripts # Build-related Python script +├── templates # C/C++ build templates +└── toolchain # Toolchain configuration +``` + +### Build Command + +- Run the following command in the root directory of the source code to build the full distribution: + + ``` + ./build.sh --product-name {product_name} + ``` + + **product\_name** indicates the product supported by the current distribution, for example, Hi3516D V300. + + The image generated after build is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + +- The build command supports the following options: + + ``` + --product-name # (Mandatory) Name of the product to build, for example, Hi3516D V300 + --build-target # (Optional) One or more build targets + --gn-args # (Optional) One or more gn parameters + --ccache # (Optional) Use of Ccache for build. This option takes effect only when Ccache is installed on the local PC. + ``` + + +### How to Develop + +1. Add a module. + + The following steps use a custom module as an example to describe how to build the module, including build a library, an executable file, and a configuration file. + + The example module **partA** consists of **feature1**, **feature2**, and **feature3**. The target is a dynamic library for **feature1**, an executable file for **feature2**, and an etc configuration file for **feature3**. + + Add **partA** to a subsystem, for example, **subsystem\_examples** \(defined in the **test/examples/** directory\). + + The complete directory structure of **partA** is as follows: + + ``` + test/examples/partA + ├── feature1 + │ ├── BUILD.gn + │ ├── include + │ │ └── helloworld1.h + │ └── src + │ └── helloworld1.cpp + ├── feature2 + │ ├── BUILD.gn + │ ├── include + │ │ └── helloworld2.h + │ └── src + │ └── helloworld2.cpp + └── feature3 + ├── BUILD.gn + └── src + └── config.conf + ``` + + Example 1: GN script \(**test/examples/partA/feature1/BUILD.gn**\) for building a dynamic library + + ``` + config("helloworld_lib_config") { + include_dirs = [ "include" ] + } + + ohos_shared_library("helloworld_lib") { + sources = [ + "include/helloworld1.h", + "src/helloworld1.cpp", + ] + public_configs = [ ":helloworld_lib_config" ] + part_name = "partA" + } + ``` + + Example 2: GN script \(**test/examples/partA/feature2/BUILD.gn**\) for building an executable file + + ``` + ohos_executable("helloworld_bin") { + sources = [ + "src/helloworld2.cpp" + ] + include_dirs = [ "include" ] + deps = [ # Dependent submodule + "../feature1:helloworld_lib" + ] + external_deps = [ "partB:module1" ] # (Optional) If there is a cross-module dependency, the format is "module name: submodule name" + install_enable = true # By default, the executable file is not installed. You need to set this parameter to true for installation. + part_name = "partA" + } + ``` + + Example 3: GN script \(**test/examples/partA/feature3/BUILD.gn**\) for building the etc configuration file \(submodule\). + + ``` + ohos_prebuilt_etc("feature3_etc") { + source = "src/config.conf" + relative_install_dir = "init" # (Optional) Directory for installing the submodule, which is relative to the default installation directory (/system/etc) + part_name = "partA" + } + ``` + + Example 4: Adding the module configuration file **test/examples/ohos.build** to the **ohos.build** file of this subsystem. Each subsystem has an **ohos.build** file in its root directory. Example: + + ``` + "partA": { + "module_list": [ + "//test/examples/partA/feature1:helloworld_lib", + "//test/examples/partA/feature2:helloworld_bin", + "//test/examples/partA/feature3:feature3_etc", + ], + "inner_kits": [ + + ], + "system_kits": [ + + ], + "test_list": [ + + ] + } + ``` + + The declaration of a module contains the following parts: + + - **module\_list**: submodule list of the module + - **inner\_kits**: APIs for other modules that depend on this module through **external\_deps** + - **system\_kits**: APIs for developers + - **test\_list**: test cases for the submodules of the module + +2. Add the module to the product configuration file. + + Add the module to the product configuration file **productdefine/common/products/\{product-name\}.json**. + + Add "subsystem\_examples:partA" to the product configuration file. **partA** will be built and packaged into the distribution. + +3. Build the module. + + For example, run the following command to build Hi3516D V300: + + ``` + ./build.sh --product-name Hi3516DV300 --ccache + ``` + +4. Obtain the build result. + + Files generated during the build process are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + + diff --git a/en/device-dev/subsystems/subsys-build.md b/en/device-dev/subsystems/subsys-build.md new file mode 100644 index 0000000000000000000000000000000000000000..8af635290fe343c07c8da6e6d902a1218ed5207f --- /dev/null +++ b/en/device-dev/subsystems/subsys-build.md @@ -0,0 +1,7 @@ +# Compilation and Building + +- **[Building Guidelines for Mini and Small Systems](subsys-build-mini-lite.md)** + +- **[Building Guidelines for Standard Systems](subsys-build-standard-large.md)** + + diff --git a/en/device-dev/subsystems/development-guidelines-on-hilog_lite.md b/en/device-dev/subsystems/subsys-dfx-hilog-lite.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-on-hilog_lite.md rename to en/device-dev/subsystems/subsys-dfx-hilog-lite.md diff --git a/en/device-dev/subsystems/development-guidelines-on-hilog.md b/en/device-dev/subsystems/subsys-dfx-hilog-rich.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-on-hilog.md rename to en/device-dev/subsystems/subsys-dfx-hilog-rich.md diff --git a/en/device-dev/subsystems/development-guidelines-on-hisysevent.md b/en/device-dev/subsystems/subsys-dfx-hisysevent.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-on-hisysevent.md rename to en/device-dev/subsystems/subsys-dfx-hisysevent.md diff --git a/en/device-dev/subsystems/subsys-dfx-hisyseventread.md b/en/device-dev/subsystems/subsys-dfx-hisyseventread.md new file mode 100644 index 0000000000000000000000000000000000000000..bd59a05b8727eb3b84857d700c04bdf98cb46bbe --- /dev/null +++ b/en/device-dev/subsystems/subsys-dfx-hisyseventread.md @@ -0,0 +1,103 @@ +# HiSysEvent订阅指导 + +- [概述](#section315316685112) +- [接口说明](#section0342191810519) +- [开发实例](#section123181432175110) + +## 概述 + +The HiSysEvent provides the cross-process subscription mechanism. You can register the subscription interface. + +## 接口说明 + +**Table 1** HiSysEvent订阅接口 + + + + + + + + + + + + + +

接口名

+

描述

+

int ISysEventService::AddListener(in SysEventRule[] rules, in ISysEventCallback callback)

+

接口功能:订阅HiSysEvent事件。

+

输入参数:

+
  • rules:事件订阅规则
  • callback:订阅回调对象
+

返回值:

+
  • 0:订阅成功,重复订阅
  • 1:订阅成功,初次订阅
  • 其他返回值:订阅失败
+

void ISysEventCallback::Handle(in String domain, in String eventName, in int eventType, in String eventDetail)

+

接口功能:订阅事件的回调接口。

+

输入参数:

+
  • domain:事件所属领域
  • eventName:事件的名称
  • eventType:事件类型
  • eventDetail:包含事件相关信息的字符串,以json的形式体现
+

返回值:无。

+
+ +**Table 2** SysEventRule订阅规则对象 + + + + + + + + + + + + + + + + +

属性名称

+

描述

+

uint32_t ruleType

+

规则类型(匹配范围包括domain以及eventName):

+
  • 1:全字符匹配
  • 2:前缀匹配
  • 3:正则表达式匹配
  • 其他值:无效的匹配方式
+

std::string domain;

+
  • domain:事件所属领域,如果传入的是空字符串,则默认事件领域字段匹配成功
+

std::string eventName

+
  • eventName:事件的名称,如果传入的是空字符串,则默认事件名称字段匹配成功
+
+ +## 开发实例 + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventRule.aidl、ISysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象: + + ISysEventCallback::Handle\(in String domain, in String eventName, in int eventType, in String eventDetail\) + + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventRule.aidl、ISysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象: + + ISysEventCallback::Handle\(in String domain, in String eventName, in int eventType, in String eventDetail\) + +2. 编译设置: + +在编译子系统里面,需要依赖libbinder模块 + +aosp\_deps = \[ "shared\_library:libbinder", \] + +- **[bytrace Usage Guidelines](subsys-toolchain-bytrace-guide.md)** + +- **[hdc\_std Usage Guidelines](oem_subsys_toolchain_hdc_guide.md)** + + diff --git a/en/device-dev/subsystems/subsys-dfx-overview.md b/en/device-dev/subsystems/subsys-dfx-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..b7bfac023a5bf84628ceb40723a9ed2e62dbb892 --- /dev/null +++ b/en/device-dev/subsystems/subsys-dfx-overview.md @@ -0,0 +1,34 @@ +# DFX + +- [Basic Concepts](#section5635178134811) + +[Design for X](https://en.wikipedia.org/wiki/Design_for_X) \(DFX\) refers to the software design that aims to improve the quality attributes in OpenHarmony. It mainly consists of two parts: design for reliability \(DFR\) and design for testability \(DFT\). + +The DFX subsystem provides the following functions: + +- HiLog: Implements the logging function. It is applicable to Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) as well as Standard-System Devices \(reference memory ≥ 128 MB\). + +- HiSysEvent: Implements system event logging. It is applicable to Standard-System Devices \(reference memory ≥ 128 MB\). + +## Basic Concepts + +**Logging** + +Logging means to record the log information generated during system running so you can understand the running process and status of the system or applications. + +**Distributed call chain tracing** + +In a distributed system, the initiation of a service may involve multiple software modules, with control commands and data transmitted over intra-process, inter-process, and inter-device communication interfaces. To help you understand such complex communication processes and locate service faults efficiently, the DFX subsystem provides a distributed call chain tracing framework. + +**Thread suspension detection** + +If a thread is trapped in an infinite loop or the kernel state \(for example, Uninterruptable Sleep, Traced, Zombie, or synchronous wait\) when it is running, the thread cannot respond to normal service requests and cannot detect and recover from faults by itself. To detect and locate this type of faults, the DFX subsystem provides a simple watchdog mechanism by inserting detection probes to the process nodes that are prone to suspension. This ensures that suspension faults can be detected and logs can be collected. + +**Event logging** + +Event logging means to collect and log events reported during system running. The log information will help you better analyze the product usage. + +**System event** + +A system event is an indication of the system status at a given time point during system running. You can use these events to analyze the status change of the system. + diff --git a/en/device-dev/subsystems/subsys-dfx.md b/en/device-dev/subsystems/subsys-dfx.md new file mode 100644 index 0000000000000000000000000000000000000000..88a1a79938cf22e2d9c343ebedb42897934a1b64 --- /dev/null +++ b/en/device-dev/subsystems/subsys-dfx.md @@ -0,0 +1,11 @@ +# DFX + +- **[DFX](subsys-dfx-overview.md)** + +- **[Development Guidelines on HiLog](subsys-dfx-hilog-rich.md)** + +- **[Development Guidelines on HiLog\_Lite](subsys-dfx-hilog-lite.md)** + +- **[Development Guidelines on HiSysEvent](subsys-dfx-hisysevent.md)** + + diff --git a/en/device-dev/subsystems/subsys-graphics-animation-guide.md b/en/device-dev/subsystems/subsys-graphics-animation-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..4bb1a33190f3c76e78c9d4b4d83c25690b943937 --- /dev/null +++ b/en/device-dev/subsystems/subsys-graphics-animation-guide.md @@ -0,0 +1,190 @@ +# Development Guidelines on Animators + +- [When to Use](#section726685714018) +- [Available APIs](#section85794718418) +- [How to Develop](#section14101161317435) + +## When to Use + +A UI animator is implemented by calling the callback function you set for each tick using the task processing mechanism. The following classes are provided for you to implement an animator: + +- **AnimatorManager**: Manages Animator instances. This is a singleton class, which is registered with the system task callback when the **Init** function is executed. The system task mechanism ensures that each tick invokes the callback function of **AnimatorManager**. +- **Animator**: Represents animator-related attributes, including the start and end time of an animator. It also provides animator-specific functions, for example, to start and stop an animator, to set the animator state, and to obtain the animator. +- **AnimatorCallback**: Implements the content of each tick. You need to implement your own logic in this callback class so that the desired operation is executed upon the corresponding callback is invoked. + +## Available APIs + +**Table 1** Available functions for an animator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Module

+

Function

+

Description

+

Animator

+

void Start ()

+

Starts an animator.

+

Animator

+

void Stop ()

+

Stops the animator.

+

Animator

+

void Pause ()

+

Pauses the animator.

+

Animator

+

void Resume ()

+

Resumes the animator.

+

Animator

+

uint8_t GetState () const

+

Obtains the current state of the animator.

+

Animator

+

void SetState (uint8_t state)

+

Sets the current state for the animator.

+

Animator

+

uint32_t GetTime () const

+

Obtains the total duration of the animator.

+

Animator

+

void SetTime (uint32_t time)

+

Sets the total duration for the animator.

+

Animator

+

uint32_t GetRunTime () const

+

Obtains the running time of the animator.

+

Animator

+

void SetRunTime (uint32_t runTime)

+

Sets the running time for the animator.

+

Animator

+

bool IsRepeat () const

+

Checks whether the animator is repeated.

+

AnimatorCallback

+

virtual void Callback (UIView *view)=0

+

Represents the animator callback. You can implement your own logic in this callback.

+

AnimatorCallback

+

virtual void OnStop(UIView& view) {}

+

Called after the animator stops. You can implement your own logic in this callback.

+

AnimatorManager

+

static AnimatorManager* GetInstance()

+

Obtains an AnimatorManager instance.

+

AnimatorManager

+

void Add (Animator *animator)

+

Adds an animator.

+

AnimatorManager

+

void Remove(const Animator* animator);

+

Removes the animator.

+
+ +## How to Develop + +1. Implement the callback in **AnimatorCallback**. + + ``` + class AnimatorCallbackDemo : public OHOS::AnimatorCallback { + public: + AnimatorCallbackDemo(int16_t startPos, int16_t endPos, uint16_t time) + : start_(startPos), end_(endPos), time_(time), curTime_(0) {} + + virtual void Callback(OHOS::UIView* view) + { + curTime_++; + int16_t pos = EasingEquation::CubicEaseIn(start_, end_, curTime_, time_); + view->Invalidate(); + view->SetPosition(pos, view->GetY()); + view->Invalidate(); + } + protected: + int16_t start_; + int16_t end_; + uint16_t time_; + uint16_t curTime_; + }; + ``` + +2. Register **AnimatorCallback** to the animator. + + ``` + UIImageView* image = new UIImageView(); + image->SetSrc("..\\config\\images\\A021_001.bin"); + image->SetPosition(0, 50); + AnimatorCallbackDemo* callback = new AnimatorCallbackDemo(0, 338, 60); + Animator* animator = new Animator(callback, image, 0, true); + ``` + +3. Add the animator to **AnimatorManager**. + + ``` + AnimatorManager::GetInstance()->Add(animator); + ``` + +4. Click the buttons in the lower part of the following figure to verify that the animation effects are as expected. + + **Figure 1** Animator effect + ![](figure/animator-effect.gif "animator-effect") + + diff --git a/en/device-dev/subsystems/subsys-graphics-bundle-guide1.md b/en/device-dev/subsystems/subsys-graphics-bundle-guide1.md new file mode 100644 index 0000000000000000000000000000000000000000..cc2f751868597158a0473bf52324e0ed708bef89 --- /dev/null +++ b/en/device-dev/subsystems/subsys-graphics-bundle-guide1.md @@ -0,0 +1,244 @@ +# Development Guidelines on Container Components + +- [UIViewGroup](#section145471898812) +- [When to Use](#section0916112362216) +- [Available APIs](#section12641756192212) +- [How to Develop](#section5412161692311) +- [UIScrollView](#section174961523161315) +- [When to Use](#section8937101902413) +- [Available APIs](#section14789133142420) +- [How to Develop](#section1769754422417) + +Container components are capable of containing UI components and inherit from **UIViewGroup**. Components that are commonly used and need to contain child components are placed in the container class inheritance structure. For example, you need to call the **Add** function to add information such as time statistics and icons to **UIAnalogClock**. + +**Figure 1** Structure of common container components +![](figure/structure-of-common-container-components.png "structure-of-common-container-components") + +The **RootView**, **UIAbstractScroll**, and **UIPicker** components inherit from **UIViewGroup**, and the **UIList**, **UIScrollView**, and **UISwipeView** components inherit from **UIAbstractScroll**. + +## UIViewGroup + +## When to Use + +**UIViewGroup** is a base class for container components. For example, you can call the functions in this class to add, remove, and insert container components. Also, you can call the **Add** function to add child components for a container component. You need to set the position information for child components in a common container component. The position information is the coordinates relative to those of their parent component. The following figure shows the tree structure of components. + +**Figure 2** Component tree structure +![](figure/component-tree-structure.png "component-tree-structure") + +As shown in the figure, the container component **ViewGroup1** and the component **View1** are added to **RootView**, the component **View2** and the container component **ViewGroup2** are added to **ViewGroup1**, and then the component **View3** \(as a sibling of **View1**\) is also added to **ViewGroup1**. + +- Rendering: During rendering of a container component, you need to call the **OnDraw** function on all its child components to update them. +- Coordinates: As the position information of child components is the coordinates relative to those of their parent components, the system calculates and displays the absolute coordinates of child components during rendering. +- Tree structure traversing: The **UIViewGroup** class provides the functions below to traverse, search for, and manage the component tree. + +## Available APIs + +**Table 1** Available functions in ViewGroup + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

virtual void Add(UIView* view)

+

Adds a child component.

+

virtual void Insert(UIView* prevView, UIView* insertView)

+

Inserts a child component.

+

virtual void Remove(UIView* view)

+

Removes a child component.

+

virtual void RemoveAll()

+

Removes all child components.

+

virtual void GetTargetView(const Point& point, UIView** last)

+

Obtains the target view.

+

virtual void MoveChildByOffset(int16_t x, int16_t y)

+

Moves a child component by a specified offset.

+

UIView* GetChildrenHead() const

+

Obtains the first child view in a view group.

+

UIView* GetChildrenTail() const

+

Obtains the last child view in a view group.

+

virtual UIView* GetChildById(const char* id) const override

+

Obtains a child view based on its ID.

+
+ +## How to Develop + +1. Create **ULLabelButton** instances and set their coordinates. + + ``` + UILabelButton* btn1 = new UILabelButton(); + btn1->SetPosition(0, 0, 100, 50); + btn1->SetText("btn1"); + + UILabelButton* btn2 = new UILabelButton(); + btn2->SetPosition(50, 50, 100, 50); + btn2->SetText("btn2"); + + UILabelButton* btn3 = new UILabelButton(); + btn3->SetPosition(100, 100, 100, 50); + btn3->SetText("btn3"); + ``` + +2. Create a **UIViewGroup** instance and set its coordinates. + + ``` + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, 300, 300); + ``` + +3. Add the **ULLabelButton** instances to **UIViewGroup**. + + ``` + group->Add(btn1); + group->Add(btn2); + group->Add(btn3); + ``` + +4. The following figure shows the effect of adding view instances to a **ViewGroup**. + + **Figure 3** Effect of adding view instances to a ViewGroup + ![](figure/effect-of-adding-view-instances-to-a-viewgroup.png "effect-of-adding-view-instances-to-a-viewgroup") + + +## UIScrollView + +## When to Use + +**UIScrollView** provides scrolling container components, which enable child components to scroll upwards, downwards, leftwards, and rightwards upon a touch event. This class also supports horizontal and vertical cursor display. + +## Available APIs + +**Table 2** Available functions in ScrollView + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

void ScrollBy(int16_t xDistance, int16_t yDistance)

+

Scrolls a view.

+

void SetScrollbarWidth(uint8_t width)

+

Sets the scrollbar width.

+

void SetHorizontalScrollState(bool state)

+

Sets the horizontal scrolling state.

+

bool GetHorizontalScrollState() const

+

Checks whether horizontal scrolling is allowed.

+

void SetVerticalScrollState(bool state)

+

Sets the vertical scrolling state.

+

bool GetVerticalScrollState() const

+

Checks whether vertical scrolling is allowed.

+

void SetXScrollBarVisible(bool state)

+

Sets whether the x-axis scrollbar is visible.

+

void SetYScrollBarVisible(bool state)

+

Sets whether the y-axis scrollbar is visible.

+

void RegisterScrollListener(OnScrollListener* scrollListener)

+

Registers the scrolling callback class.

+

void RefreshScrollBar()

+

Refreshes the scrollbar.

+

virtual void OnScrollStart() {}

+

Called when scrolling starts.

+

virtual void OnScrollEnd() {}

+

Called when scrolling ends.

+

uint8_t GetScrollState() const

+

Obtains the scrolling state.

+

void SetScrollState(uint8_t state)

+

Sets the scrolling state.

+
+ +## How to Develop + +Add two buttons as child components and display horizontal and vertical cursors. + +``` +scrollView* scroll = new UIScrollView(); +scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); +scroll->SetPosition(0,0, 200, 200); +scroll->SetXScrollBarVisible(true); +scroll->SetYScrollBarVisible(true); +UILabelButton* button1 = new UILabelButton(); +button1->SetText("button1"); +button1->SetPosition(0, 0, 300, 300); +UILabelButton* button2 = new UILabelButton(); +button2->SetText("button2"); +button2->SetPosition(0, 300, 300, 300); +scroll->Add(button1); +scroll->Add(button2); +``` + +**Figure 4** Scrolling effect in both horizontal and vertical directions +![](figure/scrolling-effect-in-both-horizontal-and-vertical-directions.gif "scrolling-effect-in-both-horizontal-and-vertical-directions") + diff --git a/en/device-dev/subsystems/subsys-graphics-bundle-guide2.md b/en/device-dev/subsystems/subsys-graphics-bundle-guide2.md new file mode 100644 index 0000000000000000000000000000000000000000..95e8e154a98157305fcded6bec0d44526399740d --- /dev/null +++ b/en/device-dev/subsystems/subsys-graphics-bundle-guide2.md @@ -0,0 +1,216 @@ +# Development Guidelines on Layout Container Components + +- [UISwipeView](#section13631719181717) +- [When to Use](#section11299120102617) +- [Available APIs](#section767434119261) +- [Development Procedure \(Non-Cyclic Horizontal Swiping\)](#section111911175287) +- [Development Procedure \(Cyclic Horizontal Swiping\)](#section1976914915282) +- [GridLayout](#section46819199173) +- [When to Use](#section831618247294) +- [Available APIs](#section597214622912) +- [How to Develop](#section1418253410306) + +Layout container components consist of basic view classes. You can set the view positions to achieve nested and overlapped layouts, set the layout type and margin to standardize the child components in the layout, and call certain functions to implement layout views based on parent and sibling components. + +## UISwipeView + +## When to Use + +**UISwipeView** inherits from **UIViewGroup**. In addition to the **Add**, **Remove**, and **Insert** functions, **UISwipeView** provides the functions to swipe contents by page and center the current page after swiping. This component can be horizontally or vertically centered. Child components added via the **Add** function are automatically horizontally or vertically centered, adaptive to the **UISwipeView** direction, in the sequence they were added. + +## Available APIs + +**Table 1** Available functions in SwipeView + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

void SetCurrentPage(uint16_t index);

+

Sets the current page.

+

uint16_t GetCurrentPage()

+

Obtains the current page.

+

UIView* GetCurrentView() const

+

Obtains the current view.

+

void SetOnSwipeListener(OnSwipeListener& onSwipeListener)

+

Sets the swiping callback class.

+

void SetAnimatorTime(uint16_t time);

+

Sets the animator event.

+

void SetLoopState(bool loop)

+

Sets whether to enable the cyclic state.

+

UIView* GetViewByIndex(uint16_t index);

+

Obtains a view based on its index.

+
+ +## Development Procedure \(Non-Cyclic Horizontal Swiping\) + +1. Create a horizontal swiping **UISwipeView**. + + ``` + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + ``` + +2. Add child components to **UISwipeView**. + + ``` + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button2->SetText("button2"); + swipe->Add(button2); + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button3->SetText("button3"); + swipe->Add(button3); + ``` + +3. Verify that the components are swiping horizontally but not cyclically. + + **Figure 1** Horizontal swiping effect of **UISwipeView** + + + ![](figure/en-us_image_0000001053247975.gif) + + +## Development Procedure \(Cyclic Horizontal Swiping\) + +1. Create a horizontal swiping **UISwipeView** and add its child components. + + ``` + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button2->SetText("button2"); + swipe->Add(button2); + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button3->SetText("button3"); + swipe->Add(button3); + ``` + +2. Enable cyclic swiping for the **UISwipeView**. + + ``` + swipe->SetLoopState(true); + ``` + +3. Verify that the components are swiping horizontally and cyclically. + + **Figure 2** Cyclic horizontal swiping effect of **UISwipeView** + + + ![](figure/en-us_image_0000001053207924.gif) + + +## GridLayout + +## When to Use + +**GridLayout** provides the basic layout capability to set the number of grid rows and columns. Child components added via the **Add** function are automatically arranged after the **LayoutChildren\(\)** function is called. + +## Available APIs + +**Table 2** Available functions in GridLayout + + + + + + + + + + + + + + + + +

Function

+

Description

+

void SetRows(const uint16_t& rows)

+

Sets the number of grid rows.

+

void SetCols(const uint16_t& cols)

+

Sets the number of grid columns.

+

void LayoutChildren(bool needInvalidate = false)

+

Lays out child components.

+
+ +## How to Develop + +1. Create a **GridLayout** instance and set its position and size. + + ``` + GridLayout* layout_ = new GridLayout(); + layout_->SetPosition(0, g_y, HROIZONTAL_RESOLUTION, 200); + layout_->SetLayoutDirection(LAYOUT_HOR); + layout_->SetRows(2); + layout_->SetCols(2); + ``` + +2. Create **UILabelButton** instances. + + ``` + UILabelButton* bt1 = new UILabelButton(); + bt1->SetPosition(0,0,100,50); + bt1->SetText("bt1"); + UILabelButton* bt2 = new UILabelButton(); + bt2->SetPosition(0, 0, 100, 50); + bt2->SetText("bt2"); + UILabelButton* bt3 = new UILabelButton(); + bt3->SetPosition(0, 0, 100, 50); + bt3->SetText("bt3"); + UILabelButton* bt4 = new UILabelButton(); + bt4->SetPosition(0, 0, 100, 50); + bt4->SetText("bt4"); + ``` + +3. Add child components and call the **LayoutChildren\(\)** function. + + ``` + layout_->Add(bt1); + layout_->Add(bt2); + layout_->Add(bt3); + layout_->Add(bt4); + layout_->LayoutChildren(); + ``` + +4. Verify the layout of buttons, as shown in the following figure. + + **Figure 3** Setting a 2x2 grid and adding four buttons in a layout + ![](figure/setting-a-2x2-grid-and-adding-four-buttons-in-a-layout.png "setting-a-2x2-grid-and-adding-four-buttons-in-a-layout") + + diff --git a/en/device-dev/subsystems/subsys-graphics-bundle-guide3.md b/en/device-dev/subsystems/subsys-graphics-bundle-guide3.md new file mode 100644 index 0000000000000000000000000000000000000000..fc7c79ec29f35df2218ea4d5d74ef3da7c5a6783 --- /dev/null +++ b/en/device-dev/subsystems/subsys-graphics-bundle-guide3.md @@ -0,0 +1,555 @@ +# Development Guidelines on Common Components + +- [UIButton](#section145353310214) +- [When to Use](#section1169616141577) +- [Available APIs](#section341211538315) +- [How to Develop](#section22501726193214) +- [UIImageView](#section19523161611259) +- [When to Use](#section1274484210400) +- [Available APIs](#section74981992411) +- [How to Develop \(Adaptive Mode\)](#section144341333134114) +- [How to Develop \(Tile Mode\)](#section97178160421) +- [UILabel](#section16588132012911) +- [When to Use](#section6870195634218) +- [Available APIs](#section2012714510433) +- [How to Develop \(Default Mode\)](#section83221538114410) +- [How to Develop \(Background Color and Opacity\)](#section933360204510) +- [How to Develop \(Letter Spacing\)](#section19447826124518) +- [How to Develop \(Size-Adaptive Mode\)](#section101711842154617) +- [How to Develop \(Ellipsis Mode\)](#section1249519410471) +- [How to Develop \(Scrolling Mode\)](#section15643122618478) + +Common components inherit from the base class **UIView**. Child components cannot be added to common components, such as buttons, images, and labels. + +**Figure 1** Tree structure of common components +![](figure/tree-structure-of-common-components.png "tree-structure-of-common-components") + +**UIView** is a base class of the following components: **UIAbstractProgress**, **UIArcLabel**, **UIButton**, **UICanvas**, **UILabel**, and **UIImageView**. **UIBoxProgress** and **UICircleProgress** inherit from **UIAbstractProgress**. **UILabelButton** and **UIRepeatButton** inherit from **UIButton**. **UIImageAnimatorView** and **UITextureMapper** inherit from **UIImageView**. + +## UIButton + +## When to Use + +**UIButton** supports the click event and allows you to set styles in different states. + +## Available APIs + +**Table 1** Available functions in UIButton + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

void SetImageSrc (const char *defaultImgSrc, const char *triggeredImgSrc)

+

Sets the button image.

+

void SetImagePosition (const int16_t x, const int16_t y)

+

Sets the position of the button image.

+

int16_t GetImageX () const

+

Obtains the x-coordinate of the button image.

+

int16_t GetImageY () const

+

Obtains the y-coordinate of the button image.

+

const ImageInfo* GetCurImageSrc() const

+

Obtains the image of the button in the current state.

+

Style& GetStyleForState (ButtonState state)

+

Sets the style for the button in the current state.

+

voidSetStyleForState (const Style &style, ButtonState state)

+

Sets the style for the button in a specified state.

+

void Disable ()

+

Disables the button.

+

void Enable ()

+

Enables the button.

+
+ +## How to Develop + +1. Implement the click event. + + ``` + class TestBtnOnClickListener : public OHOS::UIView::OnClickListener { + bool OnClick(UIView& view, const ClickEvent& event) override + { + int16_t width = view.GetWidth() + 10; + int16_t height = view.GetHeight() + 10; + view.Resize(width, height); + view.Invalidate(); + return true; + } + }; + ``` + +2. Create a **UIButton** instance. + + ``` + UIButton* button = new UIButton(); + button->SetPosition(50, 50); + button->SetWidth(100); + button->SetHeight(50); + ``` + +3. Register the click event callback for **UIButton**. + + ``` + button->SetOnClickListener(new TestBtnOnClickListener()); + ``` + +4. Verify that the button is clicked and its size increases gradually, as shown in the following figure. + + **Figure 2** Effect of clicking a **UIButton** + ![](figure/effect-of-clicking-a-uibutton.gif "effect-of-clicking-a-uibutton") + + +## UIImageView + +## When to Use + +**UIImageView** supports the functions to display images, set opacity, rotate images, and zoom in or out images. The following image formats are supported: RGB565, RGB888, RGBA8888, PNG, and JPG. + +## Available APIs + +**Table 2** Available functions in UIImageView + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

void SetSrc (const char *src)

+

Sets the image path with binary data.

+

void SetSrc (const ImageInfo *src)

+

Sets the pointer to image information.

+

void SetAutoEnable (bool enable)

+

Sets whether the component size adapts to the image size.

+

const void* GetSrcType () const

+

Obtains the image type.

+

bool GetAutoEnable () const

+

Checks whether the component size adapts to the image size.

+

void SetBlurLevel(BlurLevel level)

+

Sets the blur level for the image background.

+

BlurLevel GetBlurLevel() const

+

Obtains the blur level of the image background.

+

void SetTransformAlgorithm(TransformAlgorithm algorithm)

+

Sets the transformation algorithm.

+

TransformAlgorithm GetTransformAlgorithm() const

+

Obtains the transformation algorithm.

+
+ +## How to Develop \(Adaptive Mode\) + +1. Create a **UIImageView** instance. + + ``` + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(0, 30); + ``` + +2. Set the image path with binary data. + + ``` + imageView->SetSrc("..\\config\\images\\A021_001.bin"); + ``` + +3. Verify that the **UIImageView** component is adaptive to the image. + + **Figure 3** Image auto-adaption effect + ![](figure/image-auto-adaption-effect.png "image-auto-adaption-effect") + + +## How to Develop \(Tile Mode\) + +1. Create a **UIImageView** instance. + + ``` + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(0, 30); + ``` + +2. Set the image path. + + ``` + imageView->SetSrc("..\\config\\images\\A021_001.bin"); + ``` + +3. Disable the image auto-adaptation effect and resize the image to display the image in tile mode. + + ``` + imageView->SetAutoEnable(false); + imageView->Resize(454, 150); + ``` + +4. Verify that the tile mode has been enabled for the **UIImageView**. + + **Figure 4** Image tile effect + ![](figure/image-tile-effect.png "image-tile-effect") + + +## UILabel + +## When to Use + +**UILabel** displays text in an area. You can set the background color, text display style, and long text display effect for a label. + +## Available APIs + +**Table 3** Available functions in UILabel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

void SetText(const char* text);

+

Sets text for the label.

+

const char* GetText() const;

+

Obtains text of the label.

+

void SetLineBreakMode(const uint8_t lineBreakMode);

+

Sets the label mode, such as truncation and automatic extension.

+

uint8_t GetLineBreakMode() const

+

Obtains the label mode.

+

void SetTextColor(ColorType color)

+

Set the text color.

+

ColorType GetTextColor() const

+

Obtains the text color.

+

void SetAlign(UITextLanguageAlignment horizontalAlign,

+

UITextLanguageAlignment verticalAlign = TEXT_ALIGNMENT_TOP);

+

Sets the text alignment mode.

+

UITextLanguageAlignment GetHorAlign() const

+

Obtains the horizontal alignment mode of text.

+

UITextLanguageAlignment GetVerAlign() const

+

Obtains the vertical alignment mode of text.

+

void SetDirect(UITextLanguageDirect direct)

+

Sets the text display direction.

+

UITextLanguageDirect GetDirect() const

+

Obtains the text display direction.

+

void SetFontId(uint8_t fontId);

+

Sets the dynamic font ID.

+

uint8_t GetFontId() const

+

Obtains the dynamic font ID.

+

void SetFont(const char *name, uint8_t size);

+

Sets the font name and size.

+

void SetAnimatorSpeed(uint16_t animSpeed);

+

Sets the font rotation speed.

+

uint16_t GetTextWidth();

+

Obtains the font width.

+

uint16_t GetTextHeight();

+

Obtains the font height.

+

void SetRollStartPos(int16_t pos)

+

Sets the rotation position.

+

int16_t GetRollStartPos() const

+

Obtains the rotation position.

+

void SetTextRotation(LabelRotateDegree angle)

+

Sets the enumerated value of the text rotation angle.

+

LabelRotateDegree GetTextRotation() const

+

Obtains the enumerated value of the text rotation angle.

+

uint16_t GetTextRotateDegree() const

+

Obtains the number of text rotation degrees.

+
+ +## How to Develop \(Default Mode\) + +1. Create a **lUILabel** instance and set its size and position. + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. Set the font. + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. Set the text. + + ``` + label->SetText("label"); + ``` + +4. Verify the label size and display effect, as shown in the following figure. + + ![](figure/en-us_image_0000001051782526.png) + + +## How to Develop \(Background Color and Opacity\) + +1. Create a **lUILabel** instance and set its size and position. + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. Set the font. + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. Set the background color and opacity. + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetStyle(STYLE_BACKGROUND_OPA, 127); + label->SetText("Label"); + ``` + +4. Verify that the background color of the label is **Gray**, as shown in the following figure. + + ![](figure/en-us_image_0000001052582522.png) + + +## How to Develop \(Letter Spacing\) + +1. Create a **lUILabel** instance and set its size and position. + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. Set the font. + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. Set the font color and letter spacing. + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetStyle(STYLE_LETTER_SPACE, 5); + label->SetText("Label"); + ``` + +4. Verify that the letter spacing is **5** pixels on the label, as shown in the following figure. + + ![](figure/en-us_image_0000001052942531.png) + + +## How to Develop \(Size-Adaptive Mode\) + +Regarding too long text, the size of a label can be automatically adjusted based on the text, or the text can be truncated or displayed with the scrolling effect. + +1. Create a **lUILabel** instance and set its size and position. + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. Set the font. + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. Set the font color to **Gray** and enable the label size to adapt to the text. + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + label->SetText("123\n567890"); + ``` + +4. Verify that the label size adapts to the text, as shown in the following figure. + + ![](figure/en-us_image_0000001052782555.png) + + +## How to Develop \(Ellipsis Mode\) + +In ellipsis mode, an ellipsis \(...\) is displayed at the end of the label if the text cannot be completely displayed. + +1. Create a **lUILabel** instance and set its size and position. + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. Set the font. + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. Set the text display mode to **LINE\_BREAK\_ELLIPSIS**. + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + label->SetText("123567890"); + ``` + +4. Verify that the ellipsis mode has taken effect on the label, as shown in the following figure. + + ![](figure/en-us_image_0000001052662559.png) + + +## How to Develop \(Scrolling Mode\) + +In scrolling mode, long text is kept scrolling on a screen to bring the entire text into view. + +1. Create a **lUILabel** instance and set its size and position. + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. Set the font. + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. Set the text display mode to **UI\_LABEL\_LONG\_ROLL**. + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetStyle(STYLE_BACKGROUND_OPA, 127); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetText("123567890"); + ``` + +4. Verify that the text is scrolling on the label, as shown in the following figure. + + ![](figure/20200721-223604(espace).gif) + + diff --git a/en/device-dev/subsystems/graphics-2.md b/en/device-dev/subsystems/subsys-graphics-overview.md similarity index 100% rename from en/device-dev/subsystems/graphics-2.md rename to en/device-dev/subsystems/subsys-graphics-overview.md diff --git a/en/device-dev/subsystems/subsys-graphics.md b/en/device-dev/subsystems/subsys-graphics.md new file mode 100644 index 0000000000000000000000000000000000000000..bf96041837411ebf1c96ea894d70fdae2846b2ca --- /dev/null +++ b/en/device-dev/subsystems/subsys-graphics.md @@ -0,0 +1,13 @@ +# Graphics + +- **[Graphics](subsys-graphics-overview.md)** + +- **[Development Guidelines on Container Components](subsys-graphics-bundle-guide1.md)** + +- **[Development Guidelines on Layout Container Components](subsys-graphics-bundle-guide2.md)** + +- **[Development Guidelines on Common Components](subsys-graphics-bundle-guide3.md)** + +- **[Development Guidelines on Animators](subsys-graphics-animation-guide.md)** + + diff --git a/en/device-dev/subsystems/subsys-multimedia-camera-overview.md b/en/device-dev/subsystems/subsys-multimedia-camera-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..363f36457acbce8ac0ea1a8046c08920bde4807c --- /dev/null +++ b/en/device-dev/subsystems/subsys-multimedia-camera-overview.md @@ -0,0 +1,116 @@ +# Overview + +- [Basic Concepts](#section175012297491) +- [Working Principles](#section193961322175011) + +## Basic Concepts + +Camera is one of the services provided by the OpenHarmony multimedia subsystem. The camera module provides recording, preview, and photographing features and supports concurrent stream reading by multiple users. + +It is considered good practice that you understand the following concepts before starting development: + +- Video frame + + A video frame is formed by the stream data of a video image. Video data streams are formed by a series of image data arranged at a fixed time interval. + +- Frame per second \(FPS\) + + FPS is used to represent the frame rate at which images are refreshed during video playback, or the number of frames per second during video playback. A higher frame rate means smoother video playback. + +- Resolution + + Information about each image frame consists of pixels. The number of pixels in an image is presented by the resolution. For example, 1080p \(1920 x 1080\) indicates that the image width is 1920 pixels and the image height is 1080 pixels. + + +## Working Principles + +- Multimedia services + + Multimedia services are started by the **Init** process upon system startup, and media hardware resources \(such as memory, display hardware, image sensors, and codecs\) are initialized and allocated. During the initialization, the configuration file is parsed, which determines the upper limit of capabilities and resources of each service. Generally, the upper limit is configured by original equipment manufacturers \(OEMs\) in the configuration file. The following configuration items are available for the camera service during multimedia service initialization: + + - Memory pool: Memory blocks in the memory pool are accessed and released continuously by all multimedia services. + - Image sensor: sensor type, resolution, ISP, and more + - Image processor: resolution, bit rate, image inversion, and more + - Image encoder: encoding format, bit rate, resolution, and more + + +- Major classes + + You can use the **Camera** class and its asynchronous callback classes to configure and access the camera functionalities. The three callback classes correspond to different asynchronous processing scenarios, as described in [Table 1](#table486418149411). + + **Table 1** Class description + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

Description

+

Examples

+

Camera

+

Configures the static camera capability through the configuration class to use basic camera functionalities.

+

Photographing, video recording, and previewing

+

CameraDeviceCallback

+

Handles camera hardware state changes.

+

Available or unavailable

+

CameraStateCallback

+

Handles camera instance state changes.

+

Created or released

+

FrameStateCallback

+

Handles frame status changes.

+

Start and end of photographing, and frame rate changes

+
+ +- Stream transfer + + A surface is the basic data structure for transferring audio and video data. A camera is generally used as the data producer of a surface and has specific consumers in different scenarios. + + Camera preview and recording outputs are video streams, and photographing outputs are image frames. The outputs are transferred through the **Surface** class. A surface can transmit media information streams within and cross processes. + + Take video recording as an example. You create a **Recorder** instance, obtain the surface of the **Recorder** instance, and then transfer the surface to the **Camera** instance. In this case, the **Camera** instance works as a producer to inject video streams to the surface, and the **Recorder** instance act as the consumer to obtain video streams from the surface for storage. In this case, you connect the recorder and camera through the surface. + + Similarly, you can create a surface, implement consumer logic for it, and transfer it to the **Camera** instance. For example, transmit video streams over the network or save captured frame data as an image file. + + The graphics module also obtains stream resources from the camera module through surfaces. For details, see development guidelines on [Graphic](subsys-graphics-overview.md). + +- Camera running process + 1. Creating a camera + + This process creates a **Camera** instance by **CameraManager**, binds the camera device to the server, and asynchronously notifies you of the successful creation. The following figure shows the time sequence between classes. + + **Figure 1** Sequence diagram for creating a camera + + + ![](figure/en-us_image_0000001054101094.png) + + + 1. Taking a video/Previewing + + This process creates a **Camera** instance via **CameraKit**, and configures frame attributes via **FrameConfig** for recording or previewing. The following figure shows the time sequence. + + **Figure 2** Sequence diagram for recording/previewing + + + ![](figure/en-us_image_0000001054421113.png) + + + diff --git a/en/device-dev/subsystems/subsys-multimedia-camera-photo-guide.md b/en/device-dev/subsystems/subsys-multimedia-camera-photo-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..d35bed7457c70bc19d6c66cdbca1267b7da37aec --- /dev/null +++ b/en/device-dev/subsystems/subsys-multimedia-camera-photo-guide.md @@ -0,0 +1,396 @@ +# Development Guidelines on Photographing + +- [When to Use](#section1963312376119) +- [Available APIs](#section56549532016) +- [Limitations and Constraints](#section1165911177314) +- [How to Develop](#section138543918214) + +## When to Use + +Use the camera module APIs to capture frames \(photographing\). + +## Available APIs + +**Table 1** APIs for photographing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

Function

+

Description

+

CameraKit

+

int32_t GetCameraIds(std::list<string> cameraList)

+

Obtains IDs of cameras that are currently available.

+

CameraKit

+

CameraAbility& GetCameraAbility(string cameraId)

+

Obtains the camera capability

+

CameraKit

+

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

+

Registers a camera callback for camera status changes.

+

CameraKit

+

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

+

Unregisters a camera callback.

+

CameraKit

+

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

+

Creates a Camera instance.

+

Camera

+

string GetCameraId()

+

Obtains the camera ID.

+

Camera

+

CameraConfig& GetCameraConfig()

+

Obtains the camera configuration.

+

Camera

+

FrameConfig& GetFrameConfig(int32_t type)

+

Obtains the frame configuration.

+

Camera

+

void Configure(CameraConfig& config)

+

Configures the camera using the CameraConfig object.

+

Camera

+

void Release()

+

Releases the Camera object and associated resources.

+

Camera

+

int TriggerLoopingCapture(FrameConfig& frameConfig)

+

Starts looping-frame capture.

+

Camera

+

void StopLoopingCapture()

+

Stops looping-frame capture.

+

Camera

+

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

+

Starts single-frame capture.

+

CameraConfig

+

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

+

Sets a frame state callback to respond to state changes.

+

CameraConfig

+

static CameraConfig* CreateCameraConfig()

+

Creates a CameraConfig instance.

+

CameraAbility

+

std::list<Size> GetSupportedSizes(int format)

+

Obtains the supported image sizes for a specified image format.

+

CameraAbility

+

std::list<T> GetParameterRange(uint32_t key)

+

Obtains the parameter value range based on a specified parameter key.

+

CameraDevice

+

CameraDeviceCallback()

+

A constructor used to create a CameraDeviceCallback instance.

+

CameraDevice

+

void OnCameraStatus​(std::string cameraId, int32_t status)

+

Called when the camera device status changes.

+

CameraStateCallback

+

CameraStateCallback​()

+

A constructor used to create a CameraStateCallback instance.

+

CameraStateCallback

+

void OnConfigured​(Camera& camera)

+

Called when the camera is configured.

+

CameraStateCallback

+

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

+

Called when the camera fails to be configured.

+

CameraStateCallback

+

void OnCreated​(Camera& camera)

+

Called when the camera is successfully created.

+

CameraStateCallback

+

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

+

Called when the camera fails to be created.

+

CameraStateCallback

+

void OnReleased​(Camera& camera)

+

Called when the camera is released.

+

FrameStateCallback

+

FrameStateCallback​()

+

A constructor used to create a FrameStateCallback instance.

+

FrameStateCallback

+

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

+

Called when the frame capture is completed.

+

FrameStateCallback

+

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

+

Called when the frame capture fails.

+

FrameConfig

+

int32_t GetFrameConfigType()

+

Obtains the frame configuration type.

+

FrameConfig

+

std::list<OHOS::Surface> GetSurfaces()

+

Obtains a list of surface objects (shared memories).

+

FrameConfig

+

void AddSurface(OHOS::AGP::UISurface& surface);

+

Adds a surface.

+

FrameConfig

+

void RemoveSurface(OHOS::AGP::UISurface& surface);

+

Removes a surface.

+
+ +## Limitations and Constraints + +None + +## How to Develop + +1. Extend the **CameraDeviceCallback** class and call **OnCameraStatus** to customize operations when the camera device changes, for example, when a camera becomes available or unavailable. + + ``` + class SampleCameraDeviceCallback : public CameraDeviceCallback { + void OnCameraStatus(std::string cameraId, int32_t status) override + { + // Do something when camera is available or unavailable. + } + }; + ``` + +2. Extend the **FrameStateCallback** class. After obtaining the frame data, save the data as a file. + + ``` + static void SampleSaveCapture(const char *p, uint32_t size) + { + cout << "Start saving picture" << endl; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm *ltm = localtime(&tv.tv_sec); + if (ltm != nullptr) { + ostringstream ss("Capture_"); + ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; + + ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); + cout << "write " << size << " bytes" << endl; + pic.write(p, size); + cout << "Saving picture end" << endl; + } + } + + class TestFrameStateCallback : public FrameStateCallback { + void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override + { + cout << "Receive frame complete inform." << endl; + if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { + cout << "Capture frame received." << endl; + list surfaceList = fc.GetSurfaces(); + for (Surface *surface : surfaceList) { + SurfaceBuffer *buffer = surface->AcquireBuffer(); + if (buffer != nullptr) { + char *virtAddr = static_cast(buffer->GetVirAddr()); + if (virtAddr != nullptr) { + SampleSaveCapture(virtAddr, buffer->GetSize()); + } + surface->ReleaseBuffer(buffer); + } + delete surface; + } + delete &fc; + } + } + }; + ``` + +3. Extend the **CameraStateCallback** class and customize operations when the camera state changes \(configuration successful or failed, and creation successful or failed\). + + ``` + class SampleCameraStateMng : public CameraStateCallback { + public: + SampleCameraStateMng() = delete; + SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} + ~SampleCameraStateMng() + { + if (recordFd_ != -1) { + close(recordFd_); + } + } + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} + void OnReleased(Camera &c) override {} + }; + ``` + +4. Create a **CameraKit** instance to set and obtain camera information. + + ``` + CameraKit *camKit = CameraKit::GetInstance(); + list camList = camKit->GetCameraIds(); + string camId; + for (auto &cam : camList) { + cout << "camera name:" << cam << endl; + const CameraAbility *ability = camKit->GetCameraAbility(cam); + /* Find the camera that fits your ability. */ + list sizeList = ability->GetSupportedSizes(0); + if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { + camId = cam; + break; + } + } + ``` + +5. Create a **Camera** instance. + + ``` + EventHandler eventHdlr; // Create a thread to handle callback events. + SampleCameraStateMng CamStateMng(eventHdlr); + + camKit->CreateCamera(camId, CamStateMng, eventHdlr); + ``` + +6. In the main process, synchronize configurations set by callback functions implemented in [step 1](#li378084192111), [step 2](#li8716104682913), and [step 3](#li6671035102514). + + ``` + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + + void Capture() + { + if (cam_ == nullptr) { + cout << "Camera is not ready." << endl; + return; + } + FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); + Surface *surface = Surface::CreateSurface(); + if (surface == nullptr) { + delete fc; + return; + } + surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ + fc->AddSurface(*surface); + cam_->TriggerSingleCapture(*fc); + } + ``` + + diff --git a/en/device-dev/subsystems/development-guidelines-on-previewing.md b/en/device-dev/subsystems/subsys-multimedia-camera-preview-guide.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-on-previewing.md rename to en/device-dev/subsystems/subsys-multimedia-camera-preview-guide.md diff --git a/en/device-dev/subsystems/development-guidelines-on-video-recording.md b/en/device-dev/subsystems/subsys-multimedia-camera-record-guide.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-on-video-recording.md rename to en/device-dev/subsystems/subsys-multimedia-camera-record-guide.md diff --git a/en/device-dev/subsystems/subsys-multimedia-camera.md b/en/device-dev/subsystems/subsys-multimedia-camera.md new file mode 100644 index 0000000000000000000000000000000000000000..a4fac683ab17078ed5dd196da525256463c77df1 --- /dev/null +++ b/en/device-dev/subsystems/subsys-multimedia-camera.md @@ -0,0 +1,11 @@ +# Camera + +- **[Overview](subsys-multimedia-camera-overview.md)** + +- **[Development Guidelines on Photographing](subsys-multimedia-camera-photo-guide.md)** + +- **[Development Guidelines on Video Recording](subsys-multimedia-camera-record-guide.md)** + +- **[Development Guidelines on Previewing](subsys-multimedia-camera-preview-guide.md)** + + diff --git a/en/device-dev/subsystems/overview-3.md b/en/device-dev/subsystems/subsys-multimedia-video-overview.md similarity index 100% rename from en/device-dev/subsystems/overview-3.md rename to en/device-dev/subsystems/subsys-multimedia-video-overview.md diff --git a/en/device-dev/subsystems/development-guidelines-on-media-playback.md b/en/device-dev/subsystems/subsys-multimedia-video-play-guide.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-on-media-playback.md rename to en/device-dev/subsystems/subsys-multimedia-video-play-guide.md diff --git a/en/device-dev/subsystems/subsys-multimedia-video-record-guide.md b/en/device-dev/subsystems/subsys-multimedia-video-record-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..e4258a87ca4b14f39f43046146ef066eab6c557b --- /dev/null +++ b/en/device-dev/subsystems/subsys-multimedia-video-record-guide.md @@ -0,0 +1,287 @@ +# Development Guidelines on Media Recording + +- [When to Use](#section186634310418) +- [Available APIs](#section125479541744) +- [Limitations and Constraints](#section1165911177314) +- [How to Develop](#section34171333656) + +## When to Use + +To record audios and videos, use APIs described in this section to set the encoding format, sampling rate, and bit rate, and encapsulate output files based on the parameters. + +## Available APIs + +The following table describes APIs available for audio and video recording. + +**Table 1** APIs available for media recording + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

API

+

Function

+

Description

+

Recorder

+

int32_t SetVideoSource(VideoSourceType source, int32_t &sourceId)

+

Sets a video source for recording.

+

Recorder

+

int32_t SetVideoEncoder(int32_t sourceId, VideoCodecFormat encoder)

+

Sets a video encoder for recording.

+

Recorder

+

int32_t SetVideoSize(int32_t sourceId, int32_t width, int32_t height)

+

Sets the width and height of the video to record.

+

Recorder

+

int32_t SetVideoFrameRate(int32_t sourceId, int32_t frameRate)

+

Sets the frame rate of the video to record.

+

Recorder

+

int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate)

+

Sets the encoding bit rate of the video to record.

+

Recorder

+

int32_t SetCaptureRate(int32_t sourceId, double fps)

+

Sets the video capture rate.

+

Recorder

+

std::shared_ptr<OHOS::Surface> GetSurface(int32_t sourceId);

+

Obtains the surface of the video source.

+

Recorder

+

int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId)

+

Sets an audio source for recording.

+

Recorder

+

int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder)

+

Sets an audio encoder for recording.

+

Recorder

+

int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate)

+

Sets the audio sampling rate for recording.

+

Recorder

+

int32_t SetAudioChannels(int32_t sourceId, int32_t num)

+

Sets the number of audio channels for recording.

+

Recorder

+

int32_t SetAudioEncodingBitRate(int32_t sourceId, int32_t bitRate)

+

Sets the encoding bit rate of the audio to record.

+

Recorder

+

int32_t SetMaxDuration(int32_t duration)

+

Sets the maximum duration of an output file, in seconds.

+

Recorder

+

int32_t SetOutputFormat(OutputFormatType format)

+

Sets the output file format.

+

Recorder

+

int32_t SetOutputPath(const string &path);

+

Sets the output file path.

+

Recorder

+

int32_t SetOutputFile(int32_t fd)

+

Sets the file descriptor of the output file.

+

Recorder

+

int32_t SetNextOutputFile(int32_t fd);

+

Sets the file descriptor of the next output file.

+

Recorder

+

int32_t SetMaxFileSize(int64_t size)

+

Sets the maximum size of an output file, in bytes.

+

Recorder

+

int32_t SetRecorderCallback(const std::shared_ptr<RecorderCallback> &callback)

+

Registers a recording listener.

+

Recorder

+

int32_t Prepare()

+

Prepares for recording.

+

Recorder

+

int32_t Start()

+

Starts recording.

+

Recorder

+

int32_t Pause()

+

Pauses recording.

+

Recorder

+

int32_t Resume()

+

Resumes recording.

+

Recorder

+

int32_t Stop(bool block)

+

Stops recording.

+

Recorder

+

int32_t Reset();

+

Resets recording.

+

Recorder

+

int32_t Release()

+

Releases recording resources.

+

Recorder

+

int32_t SetFileSplitDuration(FileSplitType type, int64_t timestamp, uint32_t duration)

+

Sets the duration to split an output file.

+

Recorder

+

int32_t SetParameter(int32_t sourceId, const Format &format)

+

Sets an extended parameter for recording.

+
+ +## Limitations and Constraints + +None + +## How to Develop + +1. Create a **Recorder** instance. + + ``` + Recorder *recorder = new Recorder(); + ``` + +2. Sets parameters for the **Recorder** instance, including the media source information, encoding format, sampling rate, bit rate, and video width and height. + + ``` + int32_t sampleRate = 48000; + int32_t channelCount = 1; + AudioCodecFormat audioFormat = AAC_LC; + AudioSourceType inputSource = AUDIO_MIC; + int32_t audioEncodingBitRate = sampleRate; + VideoSourceType source = VIDEO_SOURCE_SURFACE_ES; + int32_t frameRate = 30; + double fps = 30; + int32_t rate = 4096; + int32_t sourceId = 0; + int32_t audioSourceId = 0; + int32_t width = 1920; + int32_t height = 1080; + VideoCodecFormat encoder = H264; + recorder->SetVideoSource(source, sourceId); // Set the video source and obtain the source ID. + recorder->SetVideoEncoder(sourceId, encoder); // Set the video encoding format. + recorder->SetVideoSize(sourceId, width, height); // Set the video width and height. + recorder->SetVideoFrameRate(sourceId, frameRate); // Set the video frame rate. + recorder->SetVideoEncodingBitRate(sourceId, rate); // Set the video encoding bit rate. + recorder->SetCaptureRate(sourceId, fps); // Set the capture rate for video frames. + recorder->SetAudioSource(inputSource, audioSourceId); // Set the audio source and obtain the source ID. + recorder->SetAudioEncoder(audioSourceId, audioFormat); // Set the audio encoding format. + recorder->SetAudioSampleRate(audioSourceId, sampleRate); // Set the audio sampling rate. + recorder->SetAudioChannels(audioSourceId, channelCount); // Set the number of audio channels. + recorder->SetAudioEncodingBitRate(audioSourceId, audioEncodingBitRate); // Set the audio encoding bit rate. + ``` + +3. Prepare the **Recorder** instance for recording. + + ``` + recorder->Prepare(); // Prepare for recording. + ``` + +4. Start recording. The **Recorder** instance starts recording based on the audio and video sources. + + ``` + recorder->Start(); // Start recording. + ``` + +5. Stop recording and release resources. + + ``` + recorder->Stop(); // Stop recording. + recorder->Release(); // Release recording resources. + ``` + + diff --git a/en/device-dev/subsystems/subsys-multimedia-video.md b/en/device-dev/subsystems/subsys-multimedia-video.md new file mode 100644 index 0000000000000000000000000000000000000000..9d075f20b5a9a5ec0570bc6610b7bab093f230fe --- /dev/null +++ b/en/device-dev/subsystems/subsys-multimedia-video.md @@ -0,0 +1,9 @@ +# Audio/Video + +- **[Overview](subsys-multimedia-video-overview.md)** + +- **[Development Guidelines on Media Playback](subsys-multimedia-video-play-guide.md)** + +- **[Development Guidelines on Media Recording](subsys-multimedia-video-record-guide.md)** + + diff --git a/en/device-dev/subsystems/subsys-multimedia.md b/en/device-dev/subsystems/subsys-multimedia.md new file mode 100644 index 0000000000000000000000000000000000000000..c4b8f72b08f658c27e999c81452c400e0403018b --- /dev/null +++ b/en/device-dev/subsystems/subsys-multimedia.md @@ -0,0 +1,7 @@ +# Multimedia + +- **[Camera](subsys-multimedia-camera.md)** + +- **[Audio/Video](subsys-multimedia-video.md)** + + diff --git a/en/device-dev/subsystems/subsys-ota-guide.md b/en/device-dev/subsystems/subsys-ota-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..a249a319bae47c068ae9051865429d0e7f74bc27 --- /dev/null +++ b/en/device-dev/subsystems/subsys-ota-guide.md @@ -0,0 +1,358 @@ +# OTA Upgrade + +- [Limitations and Constraints](#section691733275418) +- [Generating a Public/Private Key Pair](#section94411533155010) +- [Generating an Upgrade Package](#section632383718539) +- [Uploading the Upgrade Package](#section5772112473213) +- [Downloading the Upgrade Package](#section251732474917) +- [Integrating OTA Update Capabilities](#section298217330534) +- [API Application Scenario \(Default\)](#section7685171192916) + - [How to Develop](#section0745926153017) + - [Sample Code](#section1337111363306) + +- [API Application Scenario \(Custom\)](#section1686395317306) + - [How to Develop](#section524515314317) + - [Sample Code](#section525974743120) + +- [Upgrading the System](#section151997114334) + +Over the Air \(OTA\) is a technology that makes it easier for you to remotely update devices, such as IP cameras. A device can be upgraded with a full or differential package. A full package contains all content of a new system, and a differential package contains the differences between the old and new systems. Currently, only the full-package upgrade is supported. + +## Limitations and Constraints + +- The open-source suites for devices developed based on Hi3861, Hi3518E V300 and Hi3516D V300 are supported. +- Devices developed based on Hi3518E V300 and Hi3516D V300 must support the SD card in the Virtual Festival of Aerobatic Teams \(VFAT\) format. + +## Generating a Public/Private Key Pair + +1. Download the OpenSSL tool from the following website and install it on a Windows PC, and configure environment variables. + + [http://slproweb.com/products/Win32OpenSSL.html](http://slproweb.com/products/Win32OpenSSL.html) + +2. Access the **tools\\update\_tools\\update\_pkg\_tools** directory, download the upgrade package making tool, and save it to a local directory, for example, **D:\\ota\_tools**. +3. Run **Generate\_public\_private\_key.bat** in the **ota\_tools\\key** directory to generate **Metis\_PUBLIC.key**, **private.key**, and **public\_arr.txt** that contains public values, as shown in the following figure. Keep the private key properly. + + **Figure 1** Generating a Public/Private Key Pair + + + ![](figure/en-us_image_0000001060200050.png) + +4. Use the array written in **public\_arr.txt** as a substitute for **g\_pubKeyBuf** in **base\\update\\ota\_lite\\frameworks\\source\\verify\\hota\_verify.c** of the OTA module. + + Example array in **public\_arr.txt**: + + ``` + 0x30,0x82,0x1,0xa,0x2,0x82,0x1,0x1,0x0,0xc7,0x8c,0xf3,0x91,0xa1,0x98,0xbf,0xb1,0x8c, + 0xbe,0x22,0xde,0x32,0xb2,0xfa,0xec,0x2c,0x69,0xf6,0x8f,0x43,0xa7,0xb7,0x6f,0x1e,0x4a,0x97, + 0x4b,0x27,0x5d,0x56,0x33,0x9a,0x73,0x4e,0x7c,0xf8,0xfd,0x1a,0xf0,0xe4,0x50,0xda,0x2b,0x8, + 0x74,0xe6,0x28,0xcc,0xc8,0x22,0x1,0xa8,0x14,0x9,0x46,0x46,0x6a,0x10,0xcd,0x39,0xd,0xf3, + 0x4a,0x7f,0x1,0x63,0x21,0x33,0x74,0xc6,0x4a,0xeb,0x68,0x40,0x55,0x3,0x80,0x1d,0xd9,0xbc, + 0xd4,0xb0,0x4a,0x84,0xb7,0xac,0x43,0x1d,0x76,0x3a,0x61,0x40,0x23,0x3,0x88,0xcc,0x80,0xe, + 0x75,0x10,0xe4,0xad,0xac,0xb6,0x4c,0x90,0x8,0x17,0x26,0x21,0xff,0xbe,0x1,0x82,0x16,0x76, + 0x9a,0x1c,0xee,0x8e,0xd9,0xb0,0xea,0xd5,0x50,0x61,0xcc,0x9c,0x2e,0x78,0x15,0x2d,0x1f,0x8b, + 0x94,0x77,0x30,0x39,0x70,0xcf,0x16,0x22,0x82,0x99,0x7c,0xe2,0x55,0x37,0xd4,0x76,0x9e,0x4b, + 0xfe,0x48,0x26,0xc,0xff,0xd9,0x59,0x6f,0x77,0xc6,0x92,0xdd,0xce,0x23,0x68,0x83,0xbd,0xd4, + 0xeb,0x5,0x1b,0x2a,0x7e,0xda,0x9a,0x59,0x93,0x41,0x7b,0x4d,0xef,0x19,0x89,0x4,0x8d,0x5, + 0x7d,0xbc,0x3,0x1f,0x77,0xe6,0x3d,0xa5,0x32,0xf5,0x4,0xb7,0x9c,0xe9,0xfa,0x6e,0xc,0x9f, + 0x4,0x62,0xfe,0x2a,0x5f,0xbf,0xeb,0x9a,0x73,0xa8,0x2a,0x72,0xe3,0xf0,0x57,0x56,0x5c,0x59, + 0x14,0xdd,0x79,0x11,0x42,0x3a,0x48,0xf7,0xe8,0x80,0xb1,0xaf,0x1c,0x40,0xa2,0xc6,0xec,0xf5, + 0x67,0xc1,0x88,0xf6,0x26,0x5c,0xd3,0x11,0x5,0x11,0xed,0xb1,0x45,0x2,0x3,0x1,0x0,0x1, + ``` + + Example configuration for the public key of the OTA module: + + ``` + #define PUBKEY_LENGTH 270 + + static uint8 g_pubKeyBuf[PUBKEY_LENGTH] = { + 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, + 0x63, 0x07, 0x84, 0xCF, 0x37, 0xF0, 0x45, 0xE8, 0xB9, 0x6E, 0xEF, 0x04, 0x88, 0xD3, 0x43, 0x06, + ``` + +5. \(Optional\) For Hi3518E V300 and Hi3516D V300 suites, further replace the array written in **g\_pub\_key** with that in **public\_arr.txt**. The **g\_pub\_key** file is provided in **device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\verify\\update\_public\_key.c** of the U-Boot module. + + Example configuration for the public key of the U-Boot module: + + ``` + static unsigned char g_pub_key[PUBKEY_LEN] = { + 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, + ``` + + +## Generating an Upgrade Package + +1. Save the files to be upgraded in the **ota\_tools\\Components** directory. + + **Figure 2** Location of original image files + + + ![](figure/en-us_image_0000001061889268.png) + + **Table 1** Files to be upgraded + + + + + + + + + + + + + + + + + + + + + + +

File

+

Description

+

u-boot.bin

+

Renamed from the u-boot-hi351XevX00.bin file generated after compilation.

+

kernel.bin

+

Renamed from the liteos.bin or kernel file generated after compilation.

+

rootfs.img

+

Renamed from the rootfs_xxxxx.img file generated after compilation.

+

config

+

Provides development board and kernel information. For details, see the SD card burning description of the corresponding open-source suite.

+

OTA.tag

+

Contains 32 bytes in the package_type:otaA1S2D3F4G5H6J7K8 format. The last 16 bytes are random, varying with the version.

+
+ +2. Open the **packet\_harmony.xml** file in **ota\_tools\\xml** to modify **compAddr** as follows. Other items are reserved. + + Example configuration for the component information: + + ``` + + + .\Components\rootfs_jffs2.img + .\Components\liteos.bin + .\Components\userfs_jffs2.img + + ``` + +3. Configure the paths of private and public keys in **packet\_harmony.xml**. + + Example configuration for paths of private and public keys: + + ``` + + .\key\private.key + .\key\Metis_PUBLIC.key + + ``` + +4. Configure the product name and software version in **ota\_tools\\VersionDefine.bat** for anti-rollback. + + Example configuration for the product name and software version: + + ``` + set FILE_PRODUCT_NAME=Hisi + + @rem Set the software version number to a string of no more than 16 characters. + set SOFTWARE_VER=OpenHarmony 1.1 + ``` + +5. Run **Make\_Harmony\_PKG.bat** in the **ota\_tools** directory to generate the **Hisi\_OpenHarmony 1.1.bin** upgrade package. The upgrade package is signed using **SHA-256** and **RSA 2048** to ensure its integrity and validity. + + **Figure 3** Upgrade package making tool + + + ![](figure/en-us_image_0000001059334449.png) + + +## Uploading the Upgrade Package + +Upload the **Hisi\_OpenHarmony 1.1.bin** upgrade package to the vendor's OTA server. + +## Downloading the Upgrade Package + +1. Download the **Hisi\_OpenHarmony 1.1.bin** upgrade package from the OTA server. +2. \(Optional\) Insert an SD card \(capacity greater than 100 MB\) if the device is developed based on Hi3518E V300 or Hi3516D V300. + +## Integrating OTA Update Capabilities + +- If vendors request OTA capabilities, use the dynamic library **libhota.so** and include the header files **hota\_partition.h** and **hota\_updater.h** in **base\\update\\ota\_lite\\interfaces\\kits**. +- The **libhota.so** source code is stored in **base\\update\\ota\_lite\\frameworks\\source**. +- For details about how to use APIs, see [API Application Scenario \(Default\)](#section7685171192916) and OTA APIs in _API Reference_. +- If the development board needs to be adapted, see the **base\\update\\ota\_lite\\hals\\hal\_hota\_board.h** header file. + +## API Application Scenario \(Default\) + +The upgrade package is generated by following the instructions provided in [Generating a Public/Private Key Pair](#section94411533155010) and [Generating an Upgrade Package](#section632383718539). + +### **How to Develop** + +1. Download the upgrade package for the current device, and then call the **HotaInit** function to initialize the OTA module. +2. Call the **HotaWrite** function to verify, parse, and write data streams into the device. +3. Call the **HotaRestart** function to restart the system. + + If you want to cancel the upgrade, call the **HotaCancel** function. + + +### **Sample Code** + +Perform an OTA update using the upgrade package format and verification method provided by OpenHarmony. + +``` +int main(int argc, char **argv) +{ + printf("this is update print!\r\n"); + if (HotaInit(NULL, NULL) < 0) { + printf("ota update init fail!\r\n"); + return -1; + } + int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + printf("file open failed, fd = %d\r\n", fd); + (void)HotaCancel(); + return -1; + } + int offset = 0; + int fileLen = lseek(fd, 0, SEEK_END); + int leftLen = fileLen; + while (leftLen > 0) { + if (lseek(fd, offset, SEEK_SET) < 0) { + close(fd); + printf("lseek fail!\r\n"); + (void)HotaCancel(); + return -1; + } + int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; + (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); + if (read(fd, g_readBuf, tmpLen) < 0) { + close(fd); + printf("read fail!\r\n"); + (void)HotaCancel(); + return -1; + } + if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { + printf("ota write fail!\r\n"); + close(fd); + (void)HotaCancel(); + return -1; + } + offset += READ_BUF_LEN; + leftLen -= tmpLen; + } + close(fd); + printf("ota write finish!\r\n"); + printf("device will reboot in 10s...\r\n"); + sleep(10); + (void)HotaRestart(); + return 0; +} +``` + +## API Application Scenario \(Custom\) + +The upgrade package is generated in other ways instead of by referring to the preceding two sections. + +### **How to Develop** + +1. Download the upgrade package for the current device, and then call the **HotaInit** function to initialize the OTA module. +2. Call the **HotaSetPackageType** function to set the package type to **NOT\_USE\_DEFAULT\_PKG**. +3. Call the **HotaWrite** function to write data streams into the device. +4. Call the **HotaRead** function to read data. Vendors can choose to verify the data. +5. \(Optional\) Call the **HotaSetBootSettings** function to set the startup tag used for entering the U-Boot mode after restarting the system. +6. Call the **HotaRestart** function to restart the system. + + If you want to cancel the upgrade, call the **HotaCancel** function. + + +### **Sample Code** + +Perform an OTA update using the upgrade package format and verification method not provided by OpenHarmony. + +``` +int main(int argc, char **argv) +{ + printf("this is update print!\r\n"); + if (HotaInit(NULL, NULL) < 0) { + printf("ota update init fail!\r\n"); + (void)HotaCancel(); + return -1; + } + (void)HotaSetPackageType(NOT_USE_DEFAULT_PKG); + int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + printf("file open failed, fd = %d\r\n", fd); + (void)HotaCancel(); + return -1; + } + int offset = 0; + int fileLen = lseek(fd, 0, SEEK_END); + int leftLen = fileLen; + while (leftLen > 0) { + if (lseek(fd, offset, SEEK_SET) < 0) { + close(fd); + printf("lseek fail!\r\n"); + (void)HotaCancel(); + return -1; + } + int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; + (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); + if (read(fd, g_readBuf, tmpLen) < 0) { + close(fd); + printf("read fail!\r\n"); + (void)HotaCancel(); + return -1; + } + if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { + printf("ota write fail!\r\n"); + close(fd); + (void)HotaCancel(); + return -1; + } + offset += READ_BUF_LEN; + leftLen -= tmpLen; + } + close(fd); + printf("ota write finish!\r\n"); + leftLen = fileLen; + while (leftLen > 0) { + int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; + (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); + if (HotaRead(offset, READ_BUF_LEN, (unsigned char *)g_readBuf) != 0) {} + printf("ota write fail!\r\n"); + (void)HotaCancel(); + return -1; + } + /* do your verify and parse */ + offset += READ_BUF_LEN; + leftLen -= tmpLen; + } + /* set your boot settings */ + (void)HotaSetBootSettings(); + printf("device will reboot in 10s...\r\n"); + sleep(10); + (void)HotaRestart(); + return 0; +} +``` + +## Upgrading the System + +Vendor applications call APIs of the OTA module to perform functions such as signature verification of the upgrade package, anti-rollback, burning and data flushing-to-disk. After the upgrade is complete, the system automatically restarts. + +For Hi3518E V300 and Hi3516D V300 open-source suites, the value of **LOCAL\_VERSION** needs to be modified for anti-rollback, for example, modifying **ohos default 1.0** to **ohos default 1.1**. The macro **LOCAL\_VERSION** is provided in **device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\ota\_update\\ota\_local\_info.c**. + +Example for modification of the local version: + +``` +const char *get_local_version(void) +{ +#if defined(CONFIG_TARGET_HI3516EV200) || \ + defined(CONFIG_TARGET_HI3516DV300) || \ + defined(CONFIG_TARGET_HI3518EV300) +#define LOCAL_VERSION "ohos default 1.0" /* increase: default release version */ +``` + diff --git a/en/device-dev/subsystems/distributed-remote-startup.md b/en/device-dev/subsystems/subsys-remote-start.md similarity index 100% rename from en/device-dev/subsystems/distributed-remote-startup.md rename to en/device-dev/subsystems/subsys-remote-start.md diff --git a/en/device-dev/subsystems/development-guidelines-on-ipc-authentication.md b/en/device-dev/subsystems/subsys-security-communicationverify.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-on-ipc-authentication.md rename to en/device-dev/subsystems/subsys-security-communicationverify.md diff --git a/en/device-dev/subsystems/overview-9.md b/en/device-dev/subsystems/subsys-security-overview.md similarity index 100% rename from en/device-dev/subsystems/overview-9.md rename to en/device-dev/subsystems/subsys-security-overview.md diff --git a/en/device-dev/subsystems/subsys-security-rightmanagement.md b/en/device-dev/subsystems/subsys-security-rightmanagement.md new file mode 100644 index 0000000000000000000000000000000000000000..747ecce03eb0dfdeeda525206f398330dbd6f6c4 --- /dev/null +++ b/en/device-dev/subsystems/subsys-security-rightmanagement.md @@ -0,0 +1,228 @@ +# Development Guidelines on Application Permission Management + +- [How Application Permission Management Works](#section193961322175011) +- [When to Use](#section18502174174019) +- [Available APIs](#section1633115419401) +- [How to Develop](#section022611498210) + +## How Application Permission Management Works + +OpenHarmony allows users to install third-party applications and controls calls made by third-party applications to sensitive permissions. When developing an application, you need to declare the sensitive permissions that the application may require in the **profile.json** file. The permissions include static and dynamic ones. Static permissions need to be registered during application installation, and dynamic permissions can be obtained only upon user authorization. Authorization modes include system settings, manual authorization by applications, and others. In addition, application signature control is used to ensure that the application installation package has been confirmed by the device vendor. + +**Table 1** OpenHarmony permissions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

OpenHarmony Permission

+

Grant Mode

+

Description

+

ohos.permission.LISTEN_BUNDLE_CHANGE

+

system_grant (static permission)

+

Allows an application to listen for application changes.

+

ohos.permission.GET_BUNDLE_INFO

+

system_grant (static permission)

+

Allows an application to obtain information about other applications.

+

ohos.permission.INSTALL_BUNDLE

+

system_grant (static permission)

+

Allows an application to install other applications.

+

ohos.permission.CAMERA

+

user_grant (dynamic permission)

+

Allows an application to use the camera to take photos and record videos at any time.

+

ohos.permission.MODIFY_AUDIO_SETTINGS

+

system_grant (static permission)

+

Allows an application to modify global audio settings, such as the volume and speaker for output.

+

ohos.permission.READ_MEDIA

+

user_grant (dynamic permission)

+

Allows an application to read users' favorite videos.

+

ohos.permission.MICROPHONE

+

user_grant (dynamic permission)

+

Allows an application to use the microphone for audio recording at any time.

+

ohos.permission.WRITE_MEDIA

+

user_grant (dynamic permission)

+

Allows an application to write users' favorite music.

+

ohos.permission.DISTRIBUTED_DATASYNC

+

user_grant (dynamic permission)

+

Allows an application to manage distributed data transmission.

+

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

+

user_grant (dynamic permission)

+

Allows an application to use distributed virtualization features.

+
+ +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Static permission: a permission granted by the system during application installation. The sensitivity level of this type of permission is **system\_grant**. +>Dynamic permission: a permission granted by users during application running. The sensitivity level of this type of permission is **user\_grant**. + +## When to Use + +Application permissions are used to control access to system resources and features. In scenarios where an application wants to access features or data related to users' privacy, such as accessing hardware features of personal devices like cameras and microphones, and reading and writing media files, OpenHarmony uses the application permission management component to protect such features and data. + +When developing a system application that requires a sensitive permission, you can call the corresponding API of the application permission management component to check whether the required permission is granted. If the permission is not granted, the application cannot use it. + +## Available APIs + +The following table lists the APIs available for application permission management. These APIs are only intended for system applications and services. + +**Table 2** APIs available for application permission management + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

int CheckPermission(int uid, const char *permissionName)

+

Checks whether the application with a specified UID has the permission to access system service APIs.

+

int CheckSelfPermission(const char *permissionName)

+

Checks whether the caller has the permission to access system service APIs.

+

int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)

+

Queries all permissions requested by the application and checks whether the requested permissions have been granted.

+

int GrantPermission(const char *identifier, const char *permName)

+

Grants a specified permission to the application.

+

int RevokePermission(const char *identifier, const char *permName)

+

Revokes a specified permission from the application.

+

int GrantRuntimePermission(int uid, const char *permissionName)

+

Grants a specified runtime permission to the application.

+

int RevokeRuntimePermission(int uid, const char *permissionName)

+

Revokes a specified runtime permission from the application.

+
+ +## How to Develop + +This section uses the BMS as an example to describe the application permission development. Before starting development, you need to declare the required sensitive permissions in the **config.json** file. During application installation, the BMS calls APIs of the application permission management component to check whether the required permissions have been granted. If yes, the installation proceeds; if not, the installation fails. + +1. Declare the required permission \(**ohos.permission.INSTALL\_BUNDLE**\) in the **config.json** file. + + ``` + { + ... + "module": { + "package": "com.huawei.kitframework", + "deviceType": [ + "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera", "smartVision" + ], + "reqPermissions": [{ + // Declare the ohos.permission.INSTALL_BUNDLE permission required for installing the application. + "name": "ohos.permission.INSTALL_BUNDLE", + "reason": "install bundle", + "usedScene": { + "ability": [ + "KitFramework" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.LISTEN_BUNDLE_CHANGE", + "reason": "install bundle", + "usedScene": { + "ability": [ + "KitFramework" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.GET_BUNDLE_INFO", + "reason": "install bundle", + "usedScene": { + "ability": [ + "KitFramework" + ], + "when": "always" + } + } + ], + ... + } + ``` + +2. The BMS calls the corresponding API of the application permission management component \(for example, the **CheckPermission** function with **ohos.permission.INSTALL\_BUNDLE** as an input parameter\) to check whether the BMS has the permission to install the application. If yes, the installation proceeds; if not, the installation fails. + + ``` + constexpr static char PERMISSION_INSTALL_BUNDLE[] = "ohos.permission.INSTALL_BUNDLE"; + + bool Install(const char *hapPath, const InstallParam *installParam, InstallerCallback installerCallback) + { + if ((hapPath == nullptr) || (installerCallback == nullptr) || (installParam == nullptr)) { + HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to nullptr parameters"); + return false; + } + // Check whether the ohos.permission.INSTALL_BUNDLE permission has been granted. + if (CheckPermission(0, static_cast(PERMISSION_INSTALL_BUNDLE)) != GRANTED) { + HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to permission denied"); + return false; // Application installation fails. + } + // Application installation process + ... + } + ``` + + diff --git a/en/device-dev/subsystems/subsys-security-sigverify.md b/en/device-dev/subsystems/subsys-security-sigverify.md new file mode 100644 index 0000000000000000000000000000000000000000..8436c859d8d7708e4fd34d08f786dc53a359db4f --- /dev/null +++ b/en/device-dev/subsystems/subsys-security-sigverify.md @@ -0,0 +1,272 @@ +# Development Guidelines on Application Signature Verification + +- [When to Use](#section18502174174019) +- [Signature Verification Process](#section554632717226) +- [Available APIs](#section1633115419401) +- [Development Procedure \(Scenario 1\)](#section4207112818418) + - [Signature Verification](#section11470123816297) + - [OpenHarmony Self-signed Application Generation](#section167151429133312) + - [Development Examples](#section174318361353) + +- [Development Procedure \(Scenario 2\)](#section81272563427) + - [Signature Verification](#section07028210442) + - [Development Examples](#section1930711345445) + +- [Debugging and Verification](#section427316292411) + +## When to Use + +You can call the APIs provided by the signature verification component to check integrity of a debugging, released, or OpenHarmony self-signed application. You can also call APIs of the signature verification component to obtain some information in the profile, for example, **appid**. In addition, you can call APIs to check whether the UDID of a debugging application matches that of the device to ensure that the application is installed on the right device. + +## Signature Verification Process + +An unsigned HAP is in **.zip** format and consists of a file block, central directory, and end of central directory \(EOCD\). + +After the HAP is signed, a signature block is added between the file block and the central directory. The signature block consists of a file signature block, profile signature block, and signature header. The following figure shows the structure of a signed HAP. + +**Figure 1** Structure of a signed HAP + + +![](figure/安全子系统.png) + +The signature verification process consists of three steps: HAP signature verification, signature verification for the profile signature block, and profile content verification. + +**HAP signature verification** + +Use the preset root certificate of the device and the certificate chain to prove that the leaf certificate is trusted. Then use the digest obtained by decrypting the public key of the leaf certificate to prove that the HAP is not tampered with. + +The process is as follows: + +1. Use the preset root certificate of the device to verify the certificate chain in the file signature block and prove that the leaf certificate is trusted. +2. Use the public key in the leaf certificate to verify the file signature block and prove that this block is not tampered with. +3. Calculate and merge the digests of the file block, central directory, and EOCD. Merge the calculation result with the digest of the profile signature block in the signature block. Then compare the merge result with the digest of the file signature block. If they are the same, the HAP signature verification is successful. + +**Signature verification for the profile signature block** + +First of all, check who issued the signature of the profile signature block. If the signature was issued by the application market, the signature is trusted and does not need to be verified. Otherwise, the signature needs to be verified. Next, verify the certificate chain and then use the leaf certificate to verify the signature of the profile signature block to prove that it is not tampered with. + +**Profile content verification** + +Obtain the profile and check the validity of its content. If the HAP is a debugging application, check whether the UDID of the current device is contained in the UDID list in the profile. If yes, the verification is successful. Then compare the certificate in the profile with the leaf certificate used for HAP verification \(this is not required for a released or OpenHarmony self-signed application\). If they are the same, the entire signature verification process is complete. + +## Available APIs + +The following table lists the innerkits APIs provided by the signature verification component. These APIs are available only for system applications. + +**Table 1** APIs provided by the signature verification component + + + + + + + + + + + + + + + + +

Function

+

Description

+

int APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)

+

Verifies a signature by specifying the file path and returns the data obtained from the profile to the caller through verifyRst. This is the main entry function.

+

int APPVERI_SetDebugMode(bool mode)

+

Sets the debugging mode. If mode is set to true, certificate chain verification based on the debugging root key is enabled; if mode is set to false, it is disabled.

+

Note: Currently, no certificate based on the existing debugging root key is available. You can replace the debugging root key and perform related verification as required.

+

void APPVERI_FreeVerifyRst(VerifyResult *verifyRst)

+

Releases memory in verifyRst.

+
+ +## Development Procedure \(Scenario 1\) + +### Signature Verification + +To verify applications released in the application market, debugging applications signed with debugging certificates of the application market, and OpenHarmony self-signed applications, perform the following steps: + +1. Construct the VerifyResult structure. + + ``` + VerifyResult verifyResult = {0}; + ``` + +2. Call the APPVERI\_AppVerify function by specifying the file path and VerifyResult to verify the application signature. + + ``` + int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); + ``` + +3. Check the returned result. If the verification is successful, obtain and process the data in VerifyResult. + + ``` + signatureInfo.appId = verifyResult.profile.appid; + signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; + ``` + +4. Call the APPVERI\_FreeVerifyRst function to release memory in VerifyResult. + + ``` + APPVERI_FreeVerifyRst(&verifyResult); + ``` + + +### OpenHarmony Self-signed Application Generation + +The procedure is as follows: + +1. Prepare required materials. + + Prepare the signature tool, system application HAP, system application profile \(\*.p7b\), signing certificate \(\*.cer\), and signing public/private key pair \(\*.jks\). + +2. Place all the materials in the same directory and start the shell. +3. Run the following command in the shell to sign the application: + + ``` + java -jar hapsigntoolv2.jar sign -mode localjks -privatekey "OpenHarmony Software Signature" -inputFile camera.hap -outputFile signed_camera.hap -signAlg SHA256withECDSA -keystore OpenHarmony.jks -keystorepasswd 123456 -keyaliaspasswd 123456 -profile camera_release.p7b -certpath OpenHarmony.cer -profileSigned 1 + ``` + + Key fields: + + **-jar**: signature tool, which is **[hapsigntool](https://repo.huaweicloud.com/harmonyos/develop_tools/hapsigntoolv2.jar)** + + **-mode**: local signature flag, which is fixed at **localjks** + + **-privatekey**: alias of the public/private key pair, which is **OpenHarmony Software Signature** + + **-inputFile**: application to be signed, which is generated through compilation + + **-outputFile**: signed application + + **-signAlg**: signing algorithm, which is fixed at **SHA256withECDSA** + + **-keystore**: public/private key pair, which is [OpenHarmony.jks](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.jks) in the **OpenHarmonyCer** directory of the **security\_services\_app\_verify** repository. The default password is **123456**. You can use a tool \(such as keytool\) to change the password. + + **-keystorepasswd**: password of the public/private key pair, which is **123456** by default + + **-keyaliaspasswd**: password of the public/private key pair alias, which is **123456** by default + + **-profile**: application profile, which is stored in the code directory + + **-certpath**: signing certificate, which is [OpenHarmony.cer](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.cer) in the **OpenHarmonyCer** directory of the **security\_services\_app\_verify** repository. + + **-profileSigned**: whether the signature block contains the profile. The value is fixed at **1**, indicating that the signature block contains the profile. + + +### Development Examples + +The following example describes how the application management framework component verifies the signature of an application during its installation. + +``` +uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) +{ + bool mode = ManagerService::GetInstance().IsDebugMode(); + HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); + // Construct the VerifyResult structure. + VerifyResult verifyResult = {0}; + // Verify the signature by specifying the file path. + int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); + uint8_t errorCode = SwitchErrorCode(ret); + if (errorCode != ERR_OK) { + return errorCode; + } + // Obtain appid from the VerifyResult structure. + signatureInfo.appId = verifyResult.profile.appid; + // Obtain the application name written in the profile from the VerifyResult structure. + signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; + int32_t restricNum = verifyResult.profile.permission.restricNum; + for (int32_t i = 0; i < restricNum; i++) { + signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); + } + // Release memory in VerifyResult. + APPVERI_FreeVerifyRst(&verifyResult); + return ERR_OK; +} +``` + +## Development Procedure \(Scenario 2\) + +### Signature Verification + +To verify applications signed with certificates that are based on debugging root keys, perform the following steps: + +1. Call the APPVERI\_SetDebugMode\(true\) function to enable the debugging mode. + + ``` + ManagerService::SetDebugMode(true); + ... + uint8_t ManagerService::SetDebugMode(bool enable) + { + int32_t ret = APPVERI_SetDebugMode(enable); + if (ret < 0) { + HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); + return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; + } + isDebugMode_ = enable; + HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); + return ERR_OK; + } + ``` + +2. Construct the **VerifyResult** structure, verify the application signature, and release memory in **VerifyResult**. +3. Call the APPVERI\_SetDebugMode\(false\) function to disable the debugging mode. + + ``` + ManagerService::SetDebugMode(false); + ``` + + +### Development Examples + +The following is the example code \(supplemented based on the example code for scenario 1\): + +``` +uint8_t ManagerService::SetDebugMode(bool enable) +{ + int32_t ret = APPVERI_SetDebugMode(enable); + if (ret < 0) { + HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); + return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; + } + isDebugMode_ = enable; + HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); + return ERR_OK; +} +uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) +{ + // Enable debugging mode. + ManagerService::SetDebugMode(true); + bool mode = ManagerService::GetInstance().IsDebugMode(); + HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); + // Construct the VerifyResult structure. + VerifyResult verifyResult = {0}; + // Verify the signature by specifying the file path. + int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); + uint8_t errorCode = SwitchErrorCode(ret); + if (errorCode != ERR_OK) { + return errorCode; + } + // Obtain appid from the VerifyResult structure. + signatureInfo.appId = verifyResult.profile.appid; + // Obtain the application name written in the profile from the VerifyResult structure. + signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; + int32_t restricNum = verifyResult.profile.permission.restricNum; + for (int32_t i = 0; i < restricNum; i++) { + signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); + } + // Release memory in VerifyResult. + APPVERI_FreeVerifyRst(&verifyResult); + // Disable debugging mode. + ManagerService::SetDebugMode(false); + return ERR_OK; +} +``` + +## Debugging and Verification + +1. Choose an application that can be properly installed on OpenHarmony. +2. Develop the application based on the development guidelines. +3. Use a self-developed program to verify the signature of the developed application. If the verification is successful and **appid** can be obtained, the development is successful. + diff --git a/en/device-dev/subsystems/subsys-security.md b/en/device-dev/subsystems/subsys-security.md new file mode 100644 index 0000000000000000000000000000000000000000..b4ac9422314e3dcc450be62ed8ad0a2b1328bff5 --- /dev/null +++ b/en/device-dev/subsystems/subsys-security.md @@ -0,0 +1,11 @@ +# Security + +- **[Overview](subsys-security-overview.md)** + +- **[Development Guidelines on Application Signature Verification](subsys-security-sigverify.md)** + +- **[Development Guidelines on Application Permission Management](subsys-security-rightmanagement.md)** + +- **[Development Guidelines on IPC Authentication](subsys-security-communicationverify.md)** + + diff --git a/en/device-dev/subsystems/sensors-usage-example.md b/en/device-dev/subsystems/subsys-sensor-demo.md similarity index 100% rename from en/device-dev/subsystems/sensors-usage-example.md rename to en/device-dev/subsystems/subsys-sensor-demo.md diff --git a/en/device-dev/subsystems/subsys-sensor-guide.md b/en/device-dev/subsystems/subsys-sensor-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..74a27dfd84c880908bb950bb9ddacef86230ddb2 --- /dev/null +++ b/en/device-dev/subsystems/subsys-sensor-guide.md @@ -0,0 +1,72 @@ +# Sensors Usage Guidelines + +- [How to Use](#section18816105182315) + +The following steps use the sensor whose **sensorTypeId** is **0** as an example. The guidelines for other sensor types are similar. + +## How to Use + +1. Import the required header files. + +``` +#include "sensor_agent.h" +#include "sensor_agent_type.h" +``` + +1. Create a sensor callback. + +``` +void SensorDataCallbackImpl(SensorEvent *event) +{ + if(event == NULL){ + return; + } + float *sensorData=(float *)event->data; +} +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>The callback must be of the RecordSensorCallback type. + +1. Obtain the list of sensors supported by the device. + +``` +SensorInfo *sensorInfo = (SensorInfo *)NULL; +int32_t count = 0; +int32_t ret = GetAllSensors(&sensorInfo, &count); +``` + +1. Create a sensor user. + +``` +SensorUser sensorUser; +sensorUser.callback = SensorDataCallbackImpl; // Assign the created callback SensorDataCallbackImpl to the member variable callback. +``` + +1. Enable the sensor. + +``` +int32_t ret = ActivateSensor(0, &sensorUser); +``` + +1. Subscribe to sensor data. + +``` +int32_t ret = SubscribeSensor(0, &sensorUser); +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>Till now, you can obtain the sensor data via the callback. + +1. Unsubscribe from the sensor data. + +``` +int32_t ret = UnsubscribeSensor(0, &sensorUser); +``` + +1. Disable the sensor. + +``` +int32_t ret = DeactivateSensor(0, &sensorUser); +``` + diff --git a/en/device-dev/subsystems/subsys-sensor-overview.md b/en/device-dev/subsystems/subsys-sensor-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..89b943330352cb8c3e65927a25fb847f5a69e2fd --- /dev/null +++ b/en/device-dev/subsystems/subsys-sensor-overview.md @@ -0,0 +1,99 @@ +# Sensors Overview + +- [Introduction](#section667413271505) +- [Available APIs](#section7255104114110) + +## Introduction + +The pan-sensor service subsystem provides a lightweight sensor service framework. You can call APIs offered by this framework to query the sensor list, enable or disable a sensor, and subscribe to or unsubscribe from sensor data. The following figure shows the architecture of the lightweight sensor framework. + +**Figure 1** Sensor service framework + +![](figure/en-us_image_0000001077724150.png) + +- Sensor API: provides APIs for performing basic operations on sensors, including querying the sensor list, subscribing to or unsubscribing from sensor data, and executing control commands. This module makes application development simpler. +- Sensor Framework: manages sensor data subscription, creates and destroys data channels, and implements communication with the Sensor Service module. +- Sensor Service: interacts with the HDF module to receive, parse, and distribute data, manages sensors on hardware and sensor data reporting, and controls sensor permissions. + +## Available APIs + +**Table 1** APIs of the sensor framework + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

Description

+

Parameter

+

int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count)

+

Obtains information about all sensors in the system.

+

Return value: Returns 0 if the information is obtained; returns a non-zero value otherwise.

+

sensorInfo (not NULL): information about all sensors in the system

+

count (not NULL): total number of sensors in the system

+

int32_t SubscribeSensor(int32_t sensorTypeId, SensorUser *user)

+

Subscribes to sensor data. The system will report the obtained sensor data to the subscriber.

+

Return value: Returns 0 if the subscription is successful; returns a non-zero value otherwise.

+

sensorTypeId: ID of a sensor type

+

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

+

int32_t UnsubscribeSensor(int32_t sensorTypeId, SensorUser *user)

+

Unsubscribes from sensor data. The system will no longer report sensor data to the subscriber.

+

Return value: Returns 0 if the unsubscription is successful; returns a non-zero value otherwise.

+

sensorTypeId: ID of a sensor type

+

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

+

int32_t SetBatch(int32_t sensorTypeId, SensorUser *user, int64_t samplingInterval, int64_t reportInterval)

+

Sets the data sampling interval and data reporting interval for the specified sensor.

+

Return value: Returns 0 if the setting is successful; returns a non-zero value otherwise.

+

sensorTypeId: ID of a sensor type

+

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

+

samplingInterval: sensor data sampling interval, in nanoseconds

+

reportInterval: sensor data reporting interval, in nanoseconds

+

int32_t ActivateSensor(int32_t sensorTypeId, SensorUser *user)

+

Enables the specified sensor that has been subscribed to.

+

Return value: Returns 0 if the sensor is successfully enabled; returns a non-zero value otherwise.

+

sensorTypeId: ID of a sensor type

+

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

+

int32_t DeactivateSensor(int32_t sensorTypeId, SensorUser *user)

+

Disables an enabled sensor.

+

Return value: Returns 0 if the sensor is successfully disabled; returns a non-zero value otherwise.

+

sensorTypeId: ID of a sensor type

+

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

+

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

+

Sets the data reporting mode for the specified sensor.

+

Return value: Returns 0 if the sensor data reporting mode is successfully set; returns a non-zero value otherwise.

+

sensorTypeId: ID of a sensor type

+

user (not NULL): sensor subscriber that requests sensor data. A subscriber can obtain data from only one sensor.

+

mode: data reporting mode of the sensor

+
+ diff --git a/en/device-dev/subsystems/subsys-sensor.md b/en/device-dev/subsystems/subsys-sensor.md new file mode 100644 index 0000000000000000000000000000000000000000..937d03221f56bff810edbf42b2697710d1df131f --- /dev/null +++ b/en/device-dev/subsystems/subsys-sensor.md @@ -0,0 +1,9 @@ +# Sensors + +- **[Sensors Overview](subsys-sensor-overview.md)** + +- **[Sensors Usage Guidelines](subsys-sensor-guide.md)** + +- **[Sensors Usage Example](subsys-sensor-demo.md)** + + diff --git a/en/device-dev/subsystems/subsys-testguide-test.md b/en/device-dev/subsystems/subsys-testguide-test.md new file mode 100644 index 0000000000000000000000000000000000000000..215b683bd1ccb771b45c32a5256989b67af595ae --- /dev/null +++ b/en/device-dev/subsystems/subsys-testguide-test.md @@ -0,0 +1,987 @@ +# Testing + +- [Overview](#section12403172115920) + - [Basic Concepts](#section53632272090) + - [Working Principles](#section2394431106) + +- [Limitations and Constraints](#section2029921310472) +- [Setting Up a Test Environment](#section175012297491) + - [Environment Requirements](#section935055691014) + - [Installing the Environment](#section6511193210111) + - [Verifying the Test Environment](#section1899144517117) + +- [Development Guidelines](#section16741101301210) + - [When to Use](#section93782214124) + - [Available APIs](#section54131732101218) + - [How to Develop](#section53541946111218) + +- [Development Example](#section7477121918136) +- [How to Use the Test Platform](#section76401945124810) +- [Directory Structure](#section1875515364133) + +## Overview + +### Basic Concepts + +The testing subsystem provides a one-click Python-based self-test platform for developers. It supports cross-platform tests and extension to third-party testing frameworks. The subsystem consists of modules for compiling, managing, scheduling and distributing, and executing test cases, collecting test results, generating test reports, creating test case templates, managing test environments, and many others. + +Before development using the testing subsystem, you need to understand the following concepts: + +- Test case compilation + + This operation compiles the source code of test cases into binary files that can be executed on the tested device. + +- Test case scheduling & distributing + + This operation distributes test cases to different tested devices through the network port or serial port, and allocates a specific executor for each test case. + +- Test case executor + + A test case executor defines the execution logic of each test case, such as its pre-processing, execution, and result recording. + +- Test case template + + A test case template defines respective unified formats for test cases and for GN files. + +- Test platform kits + + The test platform provides common methods to be used during the running of the test tool, for example, providing the test case directory to mount the file system to a tested device, distributing test cases to the tested device, or obtaining test results from the tested device. + +- Test report generation + + This operation defines a template for generating self-test reports and web test reports. + +- Test environment management + + The tested devices can be managed through the USB port or serial port, including discovering a device and querying the device status. + + +### Working Principles + +- The following figure shows the architecture of the test platform. + +**Figure 1** Platform architecture +![](figure/platform-architecture.png "platform-architecture") + +- The following figure shows the running sequence diagram of the test platform. + +**Figure 2** Running sequence of the test platform +![](figure/running-sequence-of-the-test-platform.png "running-sequence-of-the-test-platform") + +- Working principle of the test platform + +The test platform is started using a shell script. It executes a series of testing commands entered on the command line interface \(CLI\) and prints the command output. + +## Limitations and Constraints + +- The self-test platform supports only code-level test case development and verification, such as unit testing and module testing. +- Currently, the testing framework supports only white-box testing. +- Only one test platform can be started on a testing device. + +## Setting Up a Test Environment + +### Environment Requirements + +**Table 1** Environment requirements + + + + + + + + + + + + + + + + +

Item

+

Testing Device

+

Tested Device

+

Hardware

+
  • Memory: 8 GB or above
  • Hard disk space: 100 GB or above
  • Hardware architecture: x86 or ARM64
+
  • Hi3516D V300 development board
  • Hi3518E V300 development board
+

Software

+
  • OS: Windows 10 (64-bit) or Ubuntu 18.04

    System component (Linux): libreadline-dev

    +
  • Python: 3.7.5 or later
  • Python plug-ins: pySerial 3.3 or later, Paramiko 2.7.1 or later, Setuptools 40.8.0 or later, and RSA 4.0 or later
  • NFS server: haneWIN NFS Server 1.2.50 or later, or NFSv4 or later
+
  • OS: OpenHarmony 1.0 or later
  • Kernel: LiteOS Cortex-A or Linux kernel
+
+ +### Installing the Environment + +1. \(Optional\) If the test environment runs Linux, run the following command to install system component Readline: + + ``` + sudo apt-get install libreadline-dev + ``` + + If the installation is successful, the following prompts are displayed: + + ``` + Reading package lists... Done + Building dependency tree + Reading state information... Done + libreadline-dev is already the newest version (7.0-3). + 0 upgraded, 0 newly installed, 0 to remove and 11 not upgraded. + ``` + +2. Install Python extension plug-ins Setuptools. Install RSA, Paramiko, and pySerial if the device supports the serial port only. + + 1. Run the following command to install Setuptools: + + ``` + pip install setuptools + ``` + + If the installation is successful, the following prompts are displayed: + + ``` + Requirement already satisfied: setuptools in d:\programs\python37\lib\site-packages (41.2.0) + ``` + + 2. Run the following command to install RSA: + + ``` + pip install rsa + ``` + + If the installation is successful, the following prompts are displayed: + + ``` + Installing collected packages: pyasn1, rsa + Successfully installed pyasn1-0.4.8 rsa-4.7 + ``` + + 3. Run the following command to install Paramiko: + + ``` + pip install paramiko + ``` + + If the installation is successful, the following prompts are displayed: + + ``` + Installing collected packages: pycparser, cffi, pynacl, bcrypt, cryptography, paramiko + Successfully installed bcrypt-3.2.0 cffi-1.14.4 cryptography-3.3.1 paramiko-2.7.2 pycparser-2.20 pynacl-1.4.0 + ``` + + 4. \(Optional\) Run the following command to install pySerial. This step is mandatory for tested devices that support serial ports only. + + ``` + pip install pyserial + ``` + + If the installation is successful, the following prompts are displayed: + + ``` + Requirement already satisfied: pyserial in d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg (3.4) + ``` + +3. \(Optional\) Install the NFS server. This step is mandatory for tested devices that support serial ports only. + + **Windows OS** + + Download and install **haneWIN NFS Server 1.2.50** at https://www.hanewin.net/nfs-e.htm. + + **Linux OS** + + ``` + sudo apt install nfs-kernel-server + ``` + + After the environment is installed, you can conduct coding and debugging for a test platform in an integrated development environment \(IDE\) \(DevEco Studio is recommended\). + + +### Verifying the Test Environment + +**Table 2** Environment verification + + + + + + + + + + + + + + + + + + + + +

Item

+

Operation

+

Requirement

+

Check that a compliant Python version has been installed.

+

Run the python --version command.

+

The Python version must be 3.7.5 or later.

+

Check that Python extension plug-ins have been installed.

+

Access the test/xdevice directory and run run.bat or run.sh.

+

The >>> prompt is displayed.

+

Check that the NFS server has been started (for tested devices that support serial ports only).

+

Log in to the development board through the serial port and run the mount command to mount the NFS server.

+

The file directory can be mounted properly.

+
+ +## Development Guidelines + +### When to Use + +You can call the APIs to conduct white box tests of service code. + +### Available APIs + +The testing framework integrates the open-source unit testing framework and expands the macros of the test cases. For details about the framework, see the official open-source documentation. + +**Table 3** Expanded macros of the framework + + + + + + + + + + + + + + + + +

Macro

+

Description

+

HWTEST

+

The execution of test cases does not rely on setup and teardown execution. Based on the TEST macro, this macro has added the TestSize.Level1 parameter to specify the test case level, for example, HWTEST(CalculatorAddTest, TestPoint_001, TestSize.Level1).

+

HWTEST_F

+

The execution of test cases (without parameters) depends on setup and teardown execution. Based on the TEST_F macro, this macro has added the TestSize.Level1 parameter to specify the test case level, for example, HWTEST_F(CalculatorAddTest, TestPoint_001, TestSize.Level1).

+

HWTEST_P

+

The execution of test cases (with parameters) depends on setup and teardown execution. Based on the TEST_P macro, this macro has added the TestSize.Level1 parameter to specify the test case level, for example, HWTEST_P(CalculatorAddTest, TestPoint_001, TestSize.Level1).

+
+ +### How to Develop + +1. Define a test suite file based on the test case directory, for example, **test/developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp**. The class in this test suite should be inherited from the **testing::Test** class and named in the format of "_Tested feature_\_**Test**". + + ``` + /* + * Copyright (c) 2020 OpenHarmony. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include + + using namespace std; + using namespace testing::ext; + + class CalcSubtractionTest : public testing::Test { + public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + }; + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >You must write test cases by observing the following specifications: + >- Naming + > The source file name of a test case must be consistent with the test suite content. Each test suite has multiple test cases and a test source file that is globally unique and named in \[Feature\]\_\[Function\]\_\[Subfunction 1\]\_\[Subfunction 1.1\] format \(subfunctions can be further divided\). + > The file name can contain only lower-case letters and underscores \(\_\) and must end with **test**, for example, **developertest/examples/lite/cxx\_demo**. + >- Coding + > The test cases must comply with the coding specifications for feature code. In addition, case descriptions are required for further clarification. For details, see [Test case template](#li2069415903917). + >- Compilation and configuration + > The test cases must be compiled using GN, and the configurations must comply with the compilation guide of this open-source project. For details, see [Compilation and Building Subsystem - Lightweight and Small-Scale Systems](subsys-build-mini-lite.md). + >- Test case template + > For details, see the example test case **developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp**. + +2. Implement the preprocessing \(via the **SetUp** function\) and postprocessing \(via the **TearDown** function\) operations required by the execution of the test suite. + + ``` + void CalcSubtractionTest::SetUpTestCase(void) + { + // step 1: input testsuite setup step + } + + void CalcSubtractionTest::TearDownTestCase(void) + { + // step 2: input testsuite teardown step + } + + void CalcSubtractionTest::SetUp(void) + { + // step 3: input testcase setup step + } + + void CalcSubtractionTest::TearDown(void) + { + // step 4: input testcase teardown step + } + ``` + +3. Compile a test case based on the feature to be tested. The following code uses **HWTEST\_F** as an example: + + ``` + /** + * @tc.name: integer_sub_001 + * @tc.desc: Test Calculator + * @tc.type: FUNC + * @tc.require: AR00000000 SR00000000 + */ + HWTEST_F(CalcSubtractionTest, integer_sub_001, TestSize.Level1) + { + EXPECT_EQ(0, Subtraction(1, 0)); + } + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >- **@tc.name**: test case name, which briefly describes the test purpose + >- **@tc.desc**: detailed description of the test case, including the test purpose, test procedure, and expected result + >- **@tc.type**: test type, which can be **FUNC**, **PERF**, **SECU**, or **RELI**. + >- **@tc.require**: requirement ID or issue ID, which is used to associate the modification with the test case + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

SN

+

Test Type

+

Code

+

Description

+

1

+

Functionality test

+

FUNC

+

Verifies that each functionality of the software complies with the function design and specifications.

+

2

+

Performance test

+

PERF

+

Verifies that the software meets the performance requirements. Performance tests include load tests, capacitance tests, and pressure tests.

+

3

+

Security test

+

SECU

+

Verifies that the software complies with security requirements and related laws and regulations within the software lifecycle.

+

4

+

Reliability test

+

RELI

+

Verifies the probability that the software does not cause system failures within a specified period of time and under given conditions. Software stability is also involved in the test.

+
+ +4. Compile the GN file of the test case, including defining the compilation target, adding compilation dependencies, and setting the source file. + + Example file path: **test/developertest/examples/lite/cxx\_demo/test/unittest/common/BUILD.gn** + + ``` + import("//build/lite/config/test.gni") + + unittest("CalcSubTest") { + output_extension = "bin" + sources = [ + "calc_subtraction_test.cpp" + ] + include_dirs = [] + deps = [] + } + ``` + +5. Add the compilation target to the subsystem compilation configuration to ensure that the test case is compiled with the version distribution. The following is an example: + 1. For devices that support connection to the Harmony device connector \(hdc\), the example compilation configuration directory is **test/developertest/examples/ohos.build**. + + ``` + { + "subsystem": "subsystem_examples", + "parts": { + "subsystem_examples": { + "module_list": [ + "//test/developertest/examples/detector:detector", + ... + ], + "test_list": [ + "//test/developertest/examples/detector/test:unittest", + ... + ] + }, + ... + } + ``` + + 2. For devices that support serial ports only, the example compilation configuration directory is **test/developertest/examples/lite/BUILD.gn**. + + ``` + import("//build/lite/config/test.gni") + + subsystem_test("test") { + test_components = [] + if(ohos_kernel_type == "liteos_riscv") { + features += [ + ] + }else if(ohos_kernel_type == "liteos_a") { + test_components += [ + "//test/developertest/examples/lite/cxx_demo/test/unittest/common:CalcSubTest" + ] + } + } + ``` + + +6. Create a resource configuration file for the test case to use static resources. + 1. Create the **resource** directory in the **test** directory of a component or module. + 2. Create a directory for a device type, for example, **phone**, in the **resource** directory. + 3. Create a folder named after the module in the device type directory, for example, **testmodule**. + 4. Create the **ohos\_test.xml** file in the folder named after the module. The file content is in the following format: + + ``` + + + + + + + + ``` + + 5. Define **resource\_config\_file** in the compilation configuration file of the test case to specify the resource file **ohos\_test.xml**. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >The resource file is used to push the **test.txt** file in the **resource** directory to the **/data/test/resource** directory of the device to test. To do so, run the **hdc push** command. + + +7. Execute the test case after it is compiled \(the preceding steps are complete\). + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >- For devices that support connection to the hdc, test cases can be compiled separately. + >- For devices that support serial ports only, to compile the test case, run the commands in the root directory for compiling the debug code. + > For details about how to execute a test case, see [How to Use the Test Platform](#section76401945124810). + + +## Development Example + +The code repository of the testing subsystem provides complete demo cases, which are available in the **test/developertest/examples/** directory. The following is an example of compiling a test case for a subtraction function: + +- The tested code is as follows: + + ``` + static int Subtraction(int a, int b) + { + return a - b; + } + ``` + +- The test case code is as follows: + + ``` + /** + * @tc.name: integer_sub_002 + * @tc.desc: Verify the Subtraction function. + * @tc.type: FUNC + * @tc.require: AR00000000 SR00000000 + */ + HWTEST_F(CalcSubtractionTest, integer_sub_002, TestSize.Level1) + { + EXPECT_EQ(1, Subtraction(2, 1)); + } + ``` + + +## How to Use the Test Platform + +1. \(Optional\) Install the XDevice component. XDevice can be used as a Python extension package. + + Go to the installation directory **test/xdevice** and run the following command: + + ``` + python setup.py install + ``` + + If the installation is successful, the following prompts are displayed: + + ``` + ... + Installed d:\programs\python37\lib\site-packages\xdevice-0.0.0-py3.7.egg + Processing dependencies for xdevice==0.0.0 + Searching for pyserial==3.4 + Best match: pyserial 3.4 + Processing pyserial-3.4-py3.7.egg + pyserial 3.4 is already the active version in easy-install.pth + Installing miniterm.py script to D:\Programs\Python37\Scripts + + Using d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg + Finished processing dependencies for xdevice==0.0.0 + ``` + +2. Modify the **developertest/config/user\_config.xml** file to configure the Developertest component. + 1. Modify basic configuration parameters. + + \[build\] \# Set build parameters of the test case. + + ``` + + false + false + true + ... ... + + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >**example**: whether to build the test case example. The default value is **false**. + >**version**: whether to build the test version. The default value is **false**. + >**testcase**: whether to build the test case. The default value is **true**. + + 2. For devices that support connection to the hdc, modify the configuration file as follows: + + Between the **device** tags with the **"usb-hdc"** attribute, modify the IP address of the device and the port number matching the HDC connection. For example: + + ``` + + 192.168.1.1 + 9111 + + + ``` + + 3. For devices that support serial ports only, modify the configuration file as follows: + + \[board\_info\] \# Configure development board information. + + ``` + + hispark + taurus + ipcamera + hb build + + ``` + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >**board\_series**: development board series. The default value is **hispark**. + >**board\_type**: development board type. The default value is **taurus**. + >**board\_product**: target product. The default value is **ipcamera**. + >**build\_command**: command used for building the test version and test case. The default value is **hb build**. + + Between the **device** tags with the **"ipcamera"** attribute, modify the serial port information, including the COM port and baud rate. For example: + + ``` + + + COM1 + cmd + 115200 + 8 + 1 + 1 + + + ``` + + +3. \(Optional\) Modify the Developertest configuration. If a test case has been compiled, specify the compilation output path of the test case. In this case the test platform will not recompile the test case. + + Modify the **config/user\_config.xml** file. + + 1. Specify the output path of the test case, that is, the compilation output directory between the **test\_cases** tags. Example: + + ``` + + /home/opencode/out/release/tests + + ``` + + 2. For devices that support serial ports only, specify the NFS directory on the PC \(**host\_dir**\) and the corresponding directory on the board \(**board\_dir**\) between the **NFS** tags. For example: + + ``` + + D:\nfs + user + + ``` + + +4. \(Optional\) Prepare the test environment. If devices to be tested support only serial ports, check whether the environment is ready: + - The system image and file system have been burnt into the development board and are running properly on it. For example, in system mode, if the device prompt **OHOS\#** when you log in with the shell, the system is running properly. + - The development host has been connected to the serial port of the development board and the network port. + - IP addresses of the development host and development board are in the same network segment and can ping each other. + - An empty directory has been created on the development host for mounting test cases through NFS, and the NFS service has been started properly. + +5. Start the test platform and execute the test case. + - Start the test framework, go to the **test/developertest** directory, and execute the startup script. + 1. Run the following command to start the test framework in Windows: + + ``` + start.bat + ``` + + 2. Run the following command to start the test framework in Linux: + + ``` + ./start.sh + ``` + + + - Select a device type. + + Configure the device type based on the development board in the configuration file, for example, **developertest/config/framework\_config.xml**. + + - Run test commands. + 1. To query the subsystems, modules, product form, and test types supported by test cases, run the **show** commands. + + ``` + Usage: + show productlist Query supported product forms + show typelist Query the supported test type + show subsystemlist Query supported subsystems + show modulelist Query supported modules + ``` + + 2. Run test commands. **-t** is mandatory, and **-ss** and **-tm** are optional. The following is an example: + + ``` + run -t ut -ss subsystem_examples -tm calculator + ``` + + 3. Specify the arguments to execute the test suite for a specific feature or module. + + ``` + usage: run [-h] [-p PRODUCTFORM] [-t [TESTTYPE [TESTTYPE ...]]] + [-ss SUBSYSTEM] [-tm TESTMODULE] [-ts TESTSUIT] + [-tc TESTCASE] [-tl TESTLEVEL] + + Optional arguments: + -h, --help Show this help message and exit. + -p PRODUCTFORM, --productform PRODUCTFORM Specified product form + -t [TESTTYPE [TESTTYPE ...]], --testtype [TESTTYPE [TESTTYPE ...]] + Specify test type(UT,MST,ST,PERF,ALL) + -ss SUBSYSTEM, --subsystem SUBSYSTEM Specify test subsystem + -tm TESTMODULE, --testmodule TESTMODULE Specified test module + -ts TESTSUIT, --testsuite TESTSUIT Specify test suite + -tc TESTCASE, --testcase TESTCASE Specify test case + -tl TESTLEVEL, --testlevel TESTLEVEL Specify test level + ``` + + + - View the test framework help if needed. + + Run the following command query test commands that are supported by the test platform: + + ``` + help + ``` + + - Exit the test platform. + + Run the following command to exit the test platform: + + ``` + quit + ``` + + +6. View the test result and logs. The test logs and reports are generated in the **developertest/reports** directory after you run the test commands. + - The test result is displayed on the console. The root path of the test result is as follows: + + ``` + reports/xxxx-xx-xx-xx-xx-xx + ``` + + - The test case formatting result is stored in the following directory: + + ``` + result/ + ``` + + - The test logs are stored in the following directory: + + ``` + log/plan_log_xxxx-xx-xx-xx-xx-xx.log + ``` + + - The report summary file is as follows: + + ``` + summary_report.html + ``` + + - The report details file is as follows: + + ``` + details_report.html + ``` + + + - The log directory of the test platform is as follows: + + ``` + reports/platform_log_xxxx-xx-xx-xx-xx-xx.log + ``` + + + +## Directory Structure + +The source code of XDevice is stored in the **test/xdevice** directory. The following table describes the **xdevice** directory structure. + +**Table 4** XDevice structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

xdevice

+

Basic components of the test platform

+

xdevice/src/xdevice

+

Source code for the basic test framework

+

xdevice/config

+

Configuration file of the basic test framework

+

xdevice/src/xdevice/__main__.py

+

Internal entrance to the basic test framework

+

xdevice/src/xdevice/__init__.py

+

Package and plug-in dependencies

+

xdevice/src/xdevice/variables.py

+

Global variables

+

xdevice/src/xdevice/_core/command

+

Commands input by test cases

+

xdevice/src/xdevice/_core/config

+

Configuration management of the basic test framework

+

xdevice/src/xdevice/_core/environment

+

Environment management of the basic test framework, including device management

+

xdevice/src/xdevice/_core/executor

+

Scheduling and distribution of test cases

+

xdevice/src/xdevice/_core/driver

+

Test executor for the basic test framework

+

xdevice/src/xdevice/_core/resource

+

Resource files and test report templates for the basic test framework

+

xdevice/src/xdevice/_core/testkit

+

Common operations for the basic test framework, including NFS mounting

+

xdevice/src/xdevice/_core/logger.py

+

Log management of the basic test framework

+

xdevice/src/xdevice/_core/plugin.py

+

Plug-in management of the basic test framework

+

xdevice/src/xdevice/_core/interface.py

+

Interfaces for plug-ins of the basic test framework

+

xdevice/setup.py

+

Installation script of the basic test framework

+

xdevice/run.bat

+

Startup script of the basic test framework (Windows)

+

xdevice/run.sh

+

Startup script of the basic test framework (Linux)

+
+ +The source code of Developertest is stored in the **test/developertest** directory. The following table describes the **developertest** directory structure. + +**Table 5** Developertest structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory

+

Description

+

developertest

+

Development test framework

+

developertest/src

+

Test framework source code

+

developertest/src/core

+

Test executor

+

developertest/src/core/build

+

Test case compilation

+

developertest/src/core/command

+

Processing of command lines entered by users

+

developertest/src/core/config

+

Test framework configuration management

+

developertest/src/core/driver

+

Test framework driver executor

+

developertest/src/core/resource

+

Test framework configuration file

+

developertest/src/core/testcase

+

Test case management

+

developertest/src/core/common.py

+

Common operations on the test framework

+

developertest/src/core/constants.py

+

Global constants of the test framework

+

developertest/src/core/exception.py

+

Test framework exceptions

+

developertest/src/core/utils.py

+

Test framework tools and methods

+

developertest/src/main

+

Test framework platform

+

developertest/src/main/__main__.py

+

Internal entrance of the test framework

+

developertest/examples

+

Test framework demo cases

+

developertest/third_party

+

Third-party components

+

developertest/BUILD.gn

+

Compilation configuration of the subsystem

+

developertest/start.bat

+

Developer test entry (Windows)

+

developertest/start.sh

+

Developer test entry (Linux)

+
+ diff --git a/en/device-dev/subsystems/subsys-toolchain-bytrace-guide.md b/en/device-dev/subsystems/subsys-toolchain-bytrace-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..e6ddd00929d2f6b6bd378701f31ea1b756de3a9e --- /dev/null +++ b/en/device-dev/subsystems/subsys-toolchain-bytrace-guide.md @@ -0,0 +1,115 @@ +# bytrace Usage Guidelines + +- [Overview](#section11388623181619) +- [How to Develop](#section1595564317164) +- [Usage Example](#section667273201818) + +## Overview + +bytrace is a tool for you to trace processes and analyze performance. It encapsulates and extends the kernel ftrace and supports event tracking in the user space. With bytrace, you can open a user-space or kernel-space label you want to view \(run the **bytrace -l** command to query all the supported labels\) and run the **--trace\_begin** and **-o filename** \(or **--output filename**\) commands to capture traces and dump them to a specified file. + +## How to Develop + +bytrace supports the following commands: + +**Table 1** Commands + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Option

+

Description

+

-h, --help

+

Views the help text for bytrace.

+

-b n, --buffer_size n

+

Sets the size of the buffer (KB) for storing and reading traces. The default buffer size is 2048 KB.

+

-t n, --time n

+

Sets the bytrace uptime in seconds, which depends on the time required for analysis.

+

--trace_clock clock

+

Sets the type of the clock for adding a timestamp to a trace, which can be boot (default), global, mono, uptime, or perf.

+

--trace_begin

+

Starts capturing traces.

+

--trace_dump

+

Dumps traces to a specified position (console where you run this command by default).

+

--trace_finish

+

Stops capturing traces and dumps traces to a specified position (console where you run this command by default).

+

-l, --list_categories

+

Lists the bytrace categories supported by the device.

+

--overwrite

+

Sets the action to take when the buffer is full. If this option is used, the latest traces are discarded; if this option is not used, the earliest traces are discarded (default).

+

-o filename, --output filename

+

Outputs traces to a specified file.

+

-z

+

Compresses a captured trace.

+
+ +## Usage Example + +The following are some examples of bytrace commands: + +- Run the following command to query supported labels: + +``` +bytrace -l +``` + +Alternatively, you can run the following command: + +``` +bytrace --list_categories +``` + +- Run the following command to capture traces whose label is ability, with the buffer size set to 4096 KB and bytrace uptime set to 10s: + +``` +bytrace -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace +``` + +- Run the following command to set the clock type for traces to **mono**: + +``` +bytrace --trace_clock mono -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace +``` + +- Run the following command to compress the captured trace: + +``` +bytrace -z -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace +``` + diff --git a/en/device-dev/subsystems/subsys-toolchain.md b/en/device-dev/subsystems/subsys-toolchain.md new file mode 100644 index 0000000000000000000000000000000000000000..29f4d588550d44b6260b133f5df92fb29be79db2 --- /dev/null +++ b/en/device-dev/subsystems/subsys-toolchain.md @@ -0,0 +1,6 @@ +# R&D Tools + +- [bytrace Usage Guidelines](subsys-toolchain-bytrace-guide.md) +- [hdc\_std Usage Guidelines](oem_subsys_toolchain_hdc_guide.md) + + diff --git a/en/device-dev/subsystems/subsys-utils.md b/en/device-dev/subsystems/subsys-utils.md new file mode 100644 index 0000000000000000000000000000000000000000..53ee39995f7021e3f563ee7cc6ceb08a2353f247 --- /dev/null +++ b/en/device-dev/subsystems/subsys-utils.md @@ -0,0 +1,9 @@ +# Utils + +- **[Utils Overview](oem_subsys_utils_des.md)** + +- **[Utils Development Guidelines](oem_subsys_utils_guide.md)** + +- **[Utils FAQ](oem_subsys_utils_faq.md)** + + diff --git a/en/device-dev/subsystems/subsys-xts-guide.md b/en/device-dev/subsystems/subsys-xts-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..8c39f59591f073526f2b2f269e93e5a724fa48cc --- /dev/null +++ b/en/device-dev/subsystems/subsys-xts-guide.md @@ -0,0 +1,716 @@ +# XTS + +- [Introduction](#section465982318513) +- [System Types](#section125090457443) +- [Directory Structure](#section161941989596) +- [Constraints](#section119744591305) +- [Usage Guidelines](#section137768191623) +- [Test Case Development Guidelines](#section3695134065513) + - [C-based Test Case Development and Compilation \(for the Mini System\)](#section198193336544) + - [C-based Test Case Execution \(for the Mini System\)](#section13820233175418) + - [C++-based Test Case Development and Compilation \(for Standard and Small Systems\)](#section3822123311540) + - [C++-based Test Case Execution \(for Standard and Small Systems\)](#section128222336544) + - [JavaScript-based Test Case Development \(for the Standard System\)](#section159801435165220) + - [JavaScript-based Test Case Packaging \(for the Standard System\)](#section445519106559) + - [\#EN-US\_TOPIC\_0000001126156429/section191521423950](#section191521423950) + +- [Full Compilation Guide \(for the Standard System\)](#section1519992743415) +- [Full Test Case Execution Guide \(for Small and Standard Systems\)](#section118149111426) + +## Introduction + +The X test suite \(XTS\) subsystem contains a set of OpenHarmony certification test suites, including the currently supported application compatibility test suite \(ACTS\) and the device compatibility test suite \(DCTS\) that will be supported in the future. + +This subsystem contains the ACTS and **tools** software package. + +- The **acts** directory stores the source code and configuration files of ACTS test cases. The ACTS helps device vendors detect the software incompatibility as early as possible and ensures that the software is compatible to OpenHarmony during the entire development process. +- The **tools** software package stores the test case development framework related to **acts**. + +## System Types + +OpenHarmony supports the following system types: + +- Mini system + + A mini system runs on the devices whose memory is greater than or equal to 128 KiB and that are equipped with MCU processors such as ARM Cortex-M and 32-bit RISC-V. This system provides multiple lightweight network protocols and graphics frameworks, and a wide range of read/write components for the IoT bus. Typical products include connection modules, sensors, and wearables for smart home. + +- Small system + + A small system runs on the devices whose memory is greater than or equal to 1 MiB and that are equipped with application processors such as ARM Cortex-A. This system provides higher security capabilities, standard graphics frameworks, and video encoding and decoding capabilities. Typical products include smart home IP cameras, electronic cat eyes, and routers, and event data recorders \(EDRs\) for smart travel. + +- Standard system + + A standard system runs on the devices whose memory is greater than or equal to 128 MiB and that are equipped with application processors such as ARM Cortex-A. This system provides a complete application framework supporting the enhanced interaction, 3D GPU, hardware composer, diverse components, and rich animations. This system applies to high-end refrigerator displays. + + +## Directory Structure + +``` +/test/xts +├── acts # Test code +│ └── subsystem # Source code of subsystem test cases for the standard system +│ └── subsystem_lite # Source code of subsystems test cases for mini and small systems +│ └── BUILD.gn # Build configuration of test cases for the standard system +│ └── build_lite +│ └── BUILD.gn # Build configuration of test cases for mini and small systems +└── tools # Test tool code +``` + +## Constraints + +Test cases for the mini system must be developed based on C, and those for the small system must be developed based on C++. + +## Usage Guidelines + +**Table 1** Test case levels + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Level

+

Definition

+

Scope

+

Level0

+

Smoke

+

Verifies basic functionalities of key features and basic DFX attributes with the most common input. The pass result indicates that the features are runnable.

+

Level1

+

Basic

+

Verifies basic functionalities of key features and basic DFX attributes with common input. The pass result indicates that the features are testable.

+

Level2

+

Major

+

Verifies basic functionalities of key features and basic DFX attributes with common input and errors. The pass result indicates that the features are functional and ready for beta testing.

+

Level3

+

Regular

+

Verifies functionalities of all key features, and all DFX attributes with common and uncommon input combinations or normal and abnormal preset conditions.

+

Level4

+

Rare

+

Verifies functionalities of key features under extremely abnormal presets and uncommon input combinations.

+
+ +**Table 2** Test case granularities + + + + + + + + + + + + + + + + + + + + +

Test Scale

+

Test Objects

+

Test Environment

+

LargeTest

+

Service functionalities, all-scenario features, and mechanical power environment (MPE) and scenario-level DFX

+

Devices close to real devices

+

MediumTest

+

Modules, subsystem functionalities after module integration, and DFX

+

Single device that is actually used. You can perform message simulation, but do not mock functions.

+

SmallTest

+

Modules, classes, and functions

+

Local PC. Use a large number of mocks to replace dependencies with other modules.

+
+ +**Table 3** Test types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Type

+

Definition

+

Function

+

Tests the correctness of both service and platform functionalities provided by the tested object for end users or developers.

+

Performance

+

Tests the processing capability of the tested object under specific preset conditions and load models. The processing capability is measured by the service volume that can be processed in a unit time, for example, call per second, frame per second, or event processing volume per second.

+

Power

+

Tests the power consumption of the tested object in a certain period of time under specific preset conditions and load models.

+

Reliability

+

Tests the service performance of the tested object under common and uncommon input conditions, or specified service volume pressure and long-term continuous running pressure. The test covers stability, pressure handling, fault injection, and Monkey test times.

+

Security

+
  • Tests the capability of defending against security threats, including but not limited to unauthorized access, use, disclosure, damage, modification, and destruction, to ensure information confidentiality, integrity, and availability.
  • Tests the privacy protection capability to ensure that the collection, use, retention, disclosure, and disposal of users' private data comply with laws and regulations.
  • Tests the compliance with various security specifications, such as security design, security requirements, and security certification of the Ministry of Industry and Information Technology (MIIT).
+

Global

+

Tests the internationalized data and localization capabilities of the tested object, including multi-language display, various input/output habits, time formats, and regional features, such as currency, time, and culture taboos.

+

Compatibility

+
  • Tests backward compatibility of an application with its own data, the forward and backward compatibility with the system, and the compatibility with different user data, such as audio file content of the player and smart SMS messages.
  • Tests system backward compatibility with its own data and the compatibility of common applications in the ecosystem.
  • Tests software compatibility with related hardware.
+

User

+

Tests user experience of the object in real user scenarios. All conclusions and comments should come from the users, which are all subjective evaluation in this case.

+

Standard

+

Tests the compliance with industry and company-specific standards, protocols, and specifications. The standards here do not include any security standards that should be classified into the security test.

+

Safety

+

Tests the safety property of the tested object to avoid possible hazards to personal safety, health, and the object itself.

+

Resilience

+

Tests the resilience property of the tested object to ensure that it can withstand and maintain the defined running status (including downgrading) when being attacked, and recover from and adapt defense to the attacks to approach mission assurance.

+
+ +## Test Case Development Guidelines + +You should select the appropriate programming language and your target test framework to develop test cases. + +**Table 4** Test frameworks and test case languages for different systems + + + + + + + + + + + + + + + + + + + + +

System

+

Test Framework

+

Language

+

Mini

+

HCTest

+

C

+

Small

+

HCPPTest

+

C++

+

Standard

+

HJSUnit and HCPPTest

+

JavaScript and C++

+
+ +### C-based Test Case Development and Compilation \(for the Mini System\) + +**Developing test cases for the mini system** + +The HCTest framework is used to support test cases developed with the C language. HCTest is enhanced and adapted based on the open-source test framework Unity. + +1. Access the **test/xts/acts** repository where the test cases will be stored. + + ``` + ├── acts + │ └──subsystem_lite + │ │ └── module_hal + │ │ │ └── BUILD.gn + │ │ │ └── src + │ └──build_lite + │ │ └── BUILD.gn + ``` + +2. Write the test case in the **src** directory. + + 1. Import the test framework header file. + + ``` + #include "hctest.h" + ``` + + 2. Use the **LITE\_TEST\_SUIT** macro to define names of the subsystem, module, and test suite. + + ``` + /** + * @brief Registers a test suite named IntTestSuite. + * @param test Subsystem name + * @param example Module name + * @param IntTestSuite Test suite name + */ + LITE_TEST_SUIT(test, example, IntTestSuite); + ``` + + 3. Define Setup and TearDown. + + Format: Test suite name+Setup, Test suite name+TearDown. + + The Setup and TearDown functions must exist, but function bodies can be empty. + + 4. Use the **LITE\_TEST\_CASE** macro to write the test case. + + Three parameters are involved: test suite name, test case name, and test case properties \(including type, granularity, and level\). + + ``` + LITE_TEST_CASE(IntTestSuite, TestCase001, Function | MediumTest | Level1) + { + // Do something + }; + ``` + + 5. Use the **RUN\_TEST\_SUITE** macro to register the test suite. + + ``` + RUN_TEST_SUITE(IntTestSuite); + ``` + +3. Create the configuration file \(**BUILD.gn**\) of the test module. + + Create a **BUILD.gn** \(example\) build file in each test module directory. Specify the name of the built static library and its dependent header file and library in the build file. The format is as follows: + + ``` + import("//test/xts/tools/lite/build/suite_lite.gni") + hctest_suite("ActsDemoTest") { + suite_name = "acts" + sources = [ + "src/test_demo.c", + ] + include_dirs = [ ] + cflags = [ "-Wno-error" ] + } + ``` + +4. Add build options to the **BUILD.gn** file in the **acts** directory. + + You need to add the test module to the **test/xts/acts/build\_lite/BUILD.gn** script in the **acts** directory. + + ``` + lite_component("acts") { + ... + if(board_name == "liteos_m") { + features += [ + ... + "//xts/acts/subsystem_lite/module_hal:ActsDemoTest" + ] + } + } + ``` + +5. Run build commands. + + Test suites are built along with version build. The ACTS is built together with the debug version. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >The ACTS build middleware is a static library, which will be linked to the image. + + +### C-based Test Case Execution \(for the Mini System\) + +**Executing test cases for the mini system** + +Burn the image into the development board. + +**Executing the test** + +1. Use a serial port tool to log in to the development board and save information about the serial port. +2. Restart the device and view serial port logs. + +**Analyzing the test result** + +View the serial port logs, whose format is as follows: + +The log for each test suite starts with **Start to run test suite:** and ends with **xx Tests xx Failures xx Ignored**. + +### C++-based Test Case Development and Compilation \(for Standard and Small Systems\) + +**Developing test cases for small-system devices** \(For examples of the standard system, go to the **global/i18n\_standard directory**.\) + +The HCPPTest framework is enhanced and adapted based on the open-source framework Googletest. + +1. Access the **test/xts/acts** repository where the test cases will be stored. + + ``` + ├── acts + │ └──subsystem_lite + │ │ └── module_posix + │ │ │ └── BUILD.gn + │ │ │ └── src + │ └──build_lite + │ │ └── BUILD.gn + ``` + +2. Write the test case in the **src** directory. + + 1. Import the test framework header file. + + The following statement includes **gtest.h**. + + ``` + #include "gtest/gtest.h" + ``` + + 2. Define Setup and TearDown. + + ``` + using namespace std; + using namespace testing::ext; + class TestSuite: public testing::Test { + protected: + // Preset action of the test suite, which is executed before the first test case + static void SetUpTestCase(void){ + } + // Test suite cleanup action, which is executed after the last test case + static void TearDownTestCase(void){ + } + // Preset action of the test case + virtual void SetUp() + { + } + // Cleanup action of the test case + virtual void TearDown() + { + } + }; + ``` + + 3. Use the **HWTEST** or **HWTEST\_F** macro to write the test case. + + **HWTEST**: definition of common test cases, including the test suite name, test case name, and case annotation. + + **HWTEST\_F**: definition of SetUp and TearDown test cases, including the test suite name, test case name, and case annotation. + + Three parameters are involved: test suite name, test case name, and test case properties \(including type, granularity, and level\). + + ``` + HWTEST_F(TestSuite, TestCase_0001, Function | MediumTest | Level1) { + // Do something + } + ``` + +3. Create a configuration file \(**BUILD.gn**\) of the test module. + + Create a **BUILD.gn** build file in each test module directory. Specify the name of the built static library and its dependent header file and library in the build file. Each test module is independently built into a **.bin** executable file, which can be directly pushed to the development board for testing. + + Example: + + ``` + import("//test/xts/tools/lite/build/suite_lite.gni") + hcpptest_suite("ActsDemoTest") { + suite_name = "acts" + sources = [ + "src/TestDemo.cpp" + ] + + include_dirs = [ + "src", + ... + ] + deps = [ + ... + ] + cflags = [ "-Wno-error" ] + } + + ``` + +4. Add build options to the **BUILD.gn** file in the **acts** directory. + + Add the test module to the **test/xts/acts/build\_lite/BUILD.gn** script in the **acts** directory. + + ``` + lite_component("acts") { + ... + else if(board_name == "liteos_a") { + features += [ + ... + "//xts/acts/subsystem_lite/module_posix:ActsDemoTest" + ] + } + } + ``` + +5. Run build commands. + + Test suites are built along with the version build. The ACTS is built together with the debug version. + + >![](../public_sys-resources/icon-note.gif) **NOTE:** + >The ACTS for the small system is independently built to an executable file \(.bin\) and archived in the **suites\\acts** directory of the build result. + + +### C++-based Test Case Execution \(for Standard and Small Systems\) + +**Executing test cases for the small system** + +Currently, test cases are shared by the NFS and mounted to the development board for execution. + +**Setting up the environment** + +1. Use a network cable or wireless network to connect the development board to your PC. +2. Configure the IP address, subnet mask, and gateway for the development board. Ensure that the development board and the PC are in the same network segment. +3. Install and register the NFS server on the PC and start the NFS service. +4. Run the **mount** command for the development board to ensure that the development board can access NFS shared files on the PC. + + Format: **mount** _NFS server IP address_**:/**_NFS shared directory_ **/**_development board directory_ **nfs** + + Example: + + ``` + mount 192.168.1.10:/nfs /nfs nfs + ``` + + +**Executing test cases** + +Execute **ActsDemoTest.bin** to trigger test case execution, and analyze serial port logs generated after the execution is complete. + +### JavaScript-based Test Case Development \(for the Standard System\) + +The HJSUnit framework is used to support automated test of OpenHarmony apps that are developed using the JavaScript language based on the JS application framework. + +**Basic syntax of test cases** + +The test cases are developed with the JavaScript language and must meet the programming specifications of the language. + +**Table 5** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Syntax

+

Description

+

Mandatory

+

beforeAll

+

Presets a test-suite-level action executed only once before all test cases are executed. You can pass the action function as the only parameter.

+

No

+

afterAll

+

Presets a test-suite-level clear action executed only once after all test cases are executed. You can pass the clear function as the only parameter.

+

No

+

beforeEach

+

Presets a test-case-level action executed before each test case is executed. The number of execution times is the same as the number of test cases defined by it. You can pass the action function as the only parameter.

+

No

+

afterEach

+

Presets a test-case-level clear action executed after each test case is executed. The number of execution times is the same as the number of test cases defined by it. You can pass the clear function as the only parameter.

+

No

+

describe

+

Defines a test suite. You can pass two parameters: test suite name and test suite function. The describe statement supports nesting. You can use beforeall, beforeEach, afterEach, and afterAll in each describe statement.

+

Yes

+

it

+

Defines a test case. You can pass three parameters: test case name, filter parameter, and test case function.

+

Usage of the filter parameter:

+

The value of the filter parameter is a 32-bit integer. Setting different bits to 1 means different configurations:

+
  • bit 0: whether the filter parameter takes effect. 1 means that the test case is used for the function test and other settings of the parameter do not take effect.
  • Bits 0-10: test case categories
  • Bits 16-18: test case scales
  • Bits 24-28: test levels
+

Test case categories: Bits 0-10 indicate FUNCTION (function test), PERFORMANCE (performance test), POWER (power consumption test), RELIABILITY (reliability test), SECURITY (security compliance test), GLOBAL (integrity test), COMPATIBILITY (compatibility test), USER (user test), STANDARD (standard test), SAFETY (security feature test), and RESILIENCE (resilience test), respectively.

+

Test case scales: Bits 16-18 indicate SMALL (small-scale test), MEDIUM (medium-scale test), and LARGE (large-scale test), respectively.

+

Test levels: Bits 24-28 indicate LEVEL0 (level-0 test), LEVEL1 (level-1 test), LEVEL2 (level-2 test), LEVEL3 (level-3 test), and LEVEL4 (level-4 test), respectively.

+

Yes

+
+ +Use the standard syntax of Jasmine to write test cases. The ES6 specification is supported. + +1. Store the test cases in the **entry/src/main/js/test** directory, whose structure is as follows: + + ``` + ├── BUILD.gn + │ └──entry + │ │ └──src + │ │ │ └──main + │ │ │ │ └──js + │ │ │ │ │ └──default + │ │ │ │ │ │ └──pages + │ │ │ │ │ │ │ └──index + │ │ │ │ │ │ │ │ └──index.js # Entry file + │ │ │ │ │ └──test # Test code + │ │ │ └── resources # HAP resources + │ │ │ └── config.json # HAP configuration file + ``` + +2. Start the JS test framework and load test cases. The following is an example for **index.js**. + + ``` + // Start the JS test framework and load test cases. + import {Core, ExpectExtend} from 'deccjsunit/index' + + export default { + data: { + title: "" + }, + onInit() { + this.title = this.$t('strings.world'); + }, + onShow() { + console.info('onShow finish') + const core = Core.getInstance() + const expectExtend = new ExpectExtend({ + 'id': 'extend' + }) + core.addService('expect', expectExtend) + core.init() + const configService = core.getDefaultService('config') + configService.setConfig(this) + require('../../../test/List.test') + core.execute() + }, + onReady() { + }, + } + ``` + +3. Write a unit test case by referring to the following example: + + ``` + // Use HJSUnit to perform the unit test. + describe('appInfoTest', function () { + it('app_info_test_001', 0, function () { + var info = app.getInfo() + expect(info.versionName).assertEqual('1.0') + expect(info.versionCode).assertEqual('3') + }) + }) + ``` + + +### JavaScript-based Test Case Packaging \(for the Standard System\) + +For details about how to build a HAP, see the JS application development guide of the standard system [Building and Creating HAPs](https://developer.harmonyos.com/en/docs/documentation/doc-guides/build_overview-0000001055075201). + +## Full Compilation Guide \(for the Standard System\) + +1. Perform full building. + + Command: + + ``` + ./build.sh suite=acts system_size=standard + ``` + + Test case output directory: **out/release/suites/acts/testcases** + + Test framework and case output directory: **out/release/suites/acts** \(The test suite execution framework is compiled during case compilation.\) + + +## Full Test Case Execution Guide \(for Small and Standard Systems\) + +**Setting up a test environment** + +Install Python 3.7 or a later version on a Windows environment and ensure that the Windows environment is properly connected to the test device. + +**Test execution directory** \(corresponding to the **out/release/suites/acts** directory generated during compilation\) + +``` +├── testcase # Directory for storing test suite files +│ └──xxx.hap # HAP file executed by the test suite +│ └──xxx.json # Execution configuration file of the test suite +├── tools # Test framework tool directory +├── run.bat # File for starting the test suite on the Windows platform +├── report # Directory for storing the test reports +``` + +**Executing test cases** + +1. On the Windows environment, locate the directory in which the test cases are stored \(**out/release/suites/acts**, copied from the Linux server\), go to the directory in the Windows command window, and run **acts\\run.bat**. + +1. Enter the command for executing the test case. + + - Execute all test cases. + + ``` + run acts + ``` + + ![](figure/en-us_image_0000001119924146.gif) + + + - Execute the test cases of a module \(view specific module information in **\\acts\\testcases\\**\). + + ``` + run –l ActsSamgrTest + ``` + + ![](figure/en-us_image_0000001166643927.jpg) + + + Wait until the test case is complete. + + +1. View test reports. + + Go to **acts\\reports\\**, obtain the current execution record, and open **summary\_report.html** to view the test report. + + diff --git a/en/device-dev/subsystems/subsys.md b/en/device-dev/subsystems/subsys.md new file mode 100644 index 0000000000000000000000000000000000000000..9d1d0bdfb4c6b26ee49e9c93cec6e649f02940f7 --- /dev/null +++ b/en/device-dev/subsystems/subsys.md @@ -0,0 +1,33 @@ +# Subsystem Development Guidelines + +- **[Compilation and Building](subsys-build.md)** + +- **[Distributed Remote Startup](subsys-remote-start.md)** + +- **[Graphics](subsys-graphics.md)** + +- **[Multimedia](subsys-multimedia.md)** + +- **[Utils](subsys-utils.md)** + +- **[AI Framework](subsys-aiframework.md)** + +- **[Sensors](subsys-sensor.md)** + +- **[Application Framework](subsys-application-framework.md)** + +- **[OTA Upgrade](subsys-ota-guide.md)** + +- **[Security](subsys-security.md)** + +- **[Startup](subsys-boot.md)** + +- **[Testing](subsys-testguide-test.md)** + +- **[DFX](subsys-dfx.md)** + +- **[HiSysEvent订阅指导](subsys-dfx-hisyseventread.md)** + +- **[XTS](subsys-xts-guide.md)** + + diff --git a/en/device-dev/subsystems/technical-specifications.md b/en/device-dev/subsystems/technical-specifications.md deleted file mode 100644 index 6a53ac57a84e50addac49a9b002d3a3db7678e20..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/technical-specifications.md +++ /dev/null @@ -1,15 +0,0 @@ -# Technical Specifications - -**Conventions** - -**Rule**: a convention that must be observed - -**Recommendation**: a convention that should be considered - -- **[Code Management](code-management.md)** - -- **[Naming](naming.md)** - -- **[API Development](api-development.md)** - - diff --git a/en/device-dev/subsystems/testing.md b/en/device-dev/subsystems/testing.md deleted file mode 100644 index 6b84a0b1cd8b9ca8a1f149396299679e24d07edc..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/testing.md +++ /dev/null @@ -1,987 +0,0 @@ -# Testing - -- [Overview](#section12403172115920) - - [Basic Concepts](#section53632272090) - - [Working Principles](#section2394431106) - -- [Limitations and Constraints](#section2029921310472) -- [Setting Up a Test Environment](#section175012297491) - - [Environment Requirements](#section935055691014) - - [Installing the Environment](#section6511193210111) - - [Verifying the Test Environment](#section1899144517117) - -- [Development Guidelines](#section16741101301210) - - [When to Use](#section93782214124) - - [Available APIs](#section54131732101218) - - [How to Develop](#section53541946111218) - -- [Development Example](#section7477121918136) -- [How to Use the Test Platform](#section76401945124810) -- [Directory Structure](#section1875515364133) - -## Overview - -### Basic Concepts - -The testing subsystem provides a one-click Python-based self-test platform for developers. It supports cross-platform tests and extension to third-party testing frameworks. The subsystem consists of modules for compiling, managing, scheduling and distributing, and executing test cases, collecting test results, generating test reports, creating test case templates, managing test environments, and many others. - -Before development using the testing subsystem, you need to understand the following concepts: - -- Test case compilation - - This operation compiles the source code of test cases into binary files that can be executed on the tested device. - -- Test case scheduling & distributing - - This operation distributes test cases to different tested devices through the network port or serial port, and allocates a specific executor for each test case. - -- Test case executor - - A test case executor defines the execution logic of each test case, such as its pre-processing, execution, and result recording. - -- Test case template - - A test case template defines respective unified formats for test cases and for GN files. - -- Test platform kits - - The test platform provides common methods to be used during the running of the test tool, for example, providing the test case directory to mount the file system to a tested device, distributing test cases to the tested device, or obtaining test results from the tested device. - -- Test report generation - - This operation defines a template for generating self-test reports and web test reports. - -- Test environment management - - The tested devices can be managed through the USB port or serial port, including discovering a device and querying the device status. - - -### Working Principles - -- The following figure shows the architecture of the test platform. - -**Figure 1** Platform architecture -![](figures/platform-architecture.png "platform-architecture") - -- The following figure shows the running sequence diagram of the test platform. - -**Figure 2** Running sequence of the test platform -![](figures/running-sequence-of-the-test-platform.png "running-sequence-of-the-test-platform") - -- Working principle of the test platform - -The test platform is started using a shell script. It executes a series of testing commands entered on the command line interface \(CLI\) and prints the command output. - -## Limitations and Constraints - -- The self-test platform supports only code-level test case development and verification, such as unit testing and module testing. -- Currently, the testing framework supports only white-box testing. -- Only one test platform can be started on a testing device. - -## Setting Up a Test Environment - -### Environment Requirements - -**Table 1** Environment requirements - - - - - - - - - - - - - - - - -

Item

-

Testing Device

-

Tested Device

-

Hardware

-
  • Memory: 8 GB or above
  • Hard disk space: 100 GB or above
  • Hardware architecture: x86 or ARM64
-
  • Hi3516D V300 development board
  • Hi3518E V300 development board
-

Software

-
  • OS: Windows 10 (64-bit) or Ubuntu 18.04

    System component (Linux): libreadline-dev

    -
  • Python: 3.7.5 or later
  • Python plug-ins: pySerial 3.3 or later, Paramiko 2.7.1 or later, Setuptools 40.8.0 or later, and RSA 4.0 or later
  • NFS server: haneWIN NFS Server 1.2.50 or later, or NFSv4 or later
-
  • OS: OpenHarmony 1.0 or later
  • Kernel: LiteOS Cortex-A or Linux kernel
-
- -### Installing the Environment - -1. \(Optional\) If the test environment runs Linux, run the following command to install system component Readline: - - ``` - sudo apt-get install libreadline-dev - ``` - - If the installation is successful, the following prompts are displayed: - - ``` - Reading package lists... Done - Building dependency tree - Reading state information... Done - libreadline-dev is already the newest version (7.0-3). - 0 upgraded, 0 newly installed, 0 to remove and 11 not upgraded. - ``` - -2. Install Python extension plug-ins Setuptools. Install RSA, Paramiko, and pySerial if the device supports the serial port only. - - 1. Run the following command to install Setuptools: - - ``` - pip install setuptools - ``` - - If the installation is successful, the following prompts are displayed: - - ``` - Requirement already satisfied: setuptools in d:\programs\python37\lib\site-packages (41.2.0) - ``` - - 2. Run the following command to install RSA: - - ``` - pip install rsa - ``` - - If the installation is successful, the following prompts are displayed: - - ``` - Installing collected packages: pyasn1, rsa - Successfully installed pyasn1-0.4.8 rsa-4.7 - ``` - - 3. Run the following command to install Paramiko: - - ``` - pip install paramiko - ``` - - If the installation is successful, the following prompts are displayed: - - ``` - Installing collected packages: pycparser, cffi, pynacl, bcrypt, cryptography, paramiko - Successfully installed bcrypt-3.2.0 cffi-1.14.4 cryptography-3.3.1 paramiko-2.7.2 pycparser-2.20 pynacl-1.4.0 - ``` - - 4. \(Optional\) Run the following command to install pySerial. This step is mandatory for tested devices that support serial ports only. - - ``` - pip install pyserial - ``` - - If the installation is successful, the following prompts are displayed: - - ``` - Requirement already satisfied: pyserial in d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg (3.4) - ``` - -3. \(Optional\) Install the NFS server. This step is mandatory for tested devices that support serial ports only. - - **Windows OS** - - Download and install **haneWIN NFS Server 1.2.50** at https://www.hanewin.net/nfs-e.htm. - - **Linux OS** - - ``` - sudo apt install nfs-kernel-server - ``` - - After the environment is installed, you can conduct coding and debugging for a test platform in an integrated development environment \(IDE\) \(DevEco Studio is recommended\). - - -### Verifying the Test Environment - -**Table 2** Environment verification - - - - - - - - - - - - - - - - - - - - -

Item

-

Operation

-

Requirement

-

Check that a compliant Python version has been installed.

-

Run the python --version command.

-

The Python version must be 3.7.5 or later.

-

Check that Python extension plug-ins have been installed.

-

Access the test/xdevice directory and run run.bat or run.sh.

-

The >>> prompt is displayed.

-

Check that the NFS server has been started (for tested devices that support serial ports only).

-

Log in to the development board through the serial port and run the mount command to mount the NFS server.

-

The file directory can be mounted properly.

-
- -## Development Guidelines - -### When to Use - -You can call the APIs to conduct white box tests of service code. - -### Available APIs - -The testing framework integrates the open-source unit testing framework and expands the macros of the test cases. For details about the framework, see the official open-source documentation. - -**Table 3** Expanded macros of the framework - - - - - - - - - - - - - - - - -

Macro

-

Description

-

HWTEST

-

The execution of test cases does not rely on setup and teardown execution. Based on the TEST macro, this macro has added the TestSize.Level1 parameter to specify the test case level, for example, HWTEST(CalculatorAddTest, TestPoint_001, TestSize.Level1).

-

HWTEST_F

-

The execution of test cases (without parameters) depends on setup and teardown execution. Based on the TEST_F macro, this macro has added the TestSize.Level1 parameter to specify the test case level, for example, HWTEST_F(CalculatorAddTest, TestPoint_001, TestSize.Level1).

-

HWTEST_P

-

The execution of test cases (with parameters) depends on setup and teardown execution. Based on the TEST_P macro, this macro has added the TestSize.Level1 parameter to specify the test case level, for example, HWTEST_P(CalculatorAddTest, TestPoint_001, TestSize.Level1).

-
- -### How to Develop - -1. Define a test suite file based on the test case directory, for example, **test/developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp**. The class in this test suite should be inherited from the **testing::Test** class and named in the format of "_Tested feature_\_**Test**". - - ``` - /* - * Copyright (c) 2020 OpenHarmony. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include - - using namespace std; - using namespace testing::ext; - - class CalcSubtractionTest : public testing::Test { - public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); - }; - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >You must write test cases by observing the following specifications: - >- Naming - > The source file name of a test case must be consistent with the test suite content. Each test suite has multiple test cases and a test source file that is globally unique and named in \[Feature\]\_\[Function\]\_\[Subfunction 1\]\_\[Subfunction 1.1\] format \(subfunctions can be further divided\). - > The file name can contain only lower-case letters and underscores \(\_\) and must end with **test**, for example, **developertest/examples/lite/cxx\_demo**. - >- Coding - > The test cases must comply with the coding specifications for feature code. In addition, case descriptions are required for further clarification. For details, see [Test case template](#li2069415903917). - >- Compilation and configuration - > The test cases must be compiled using GN, and the configurations must comply with the compilation guide of this open-source project. For details, see [Compilation and Building Guidelines](https://device.harmonyos.com/en/docs/develop/subsystems/oem_subsys_build_des-0000001060646620). - >- Test case template - > For details, see the example test case **developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp**. - -2. Implement the preprocessing \(via the **SetUp** function\) and postprocessing \(via the **TearDown** function\) operations required by the execution of the test suite. - - ``` - void CalcSubtractionTest::SetUpTestCase(void) - { - // step 1: input testsuite setup step - } - - void CalcSubtractionTest::TearDownTestCase(void) - { - // step 2: input testsuite teardown step - } - - void CalcSubtractionTest::SetUp(void) - { - // step 3: input testcase setup step - } - - void CalcSubtractionTest::TearDown(void) - { - // step 4: input testcase teardown step - } - ``` - -3. Compile a test case based on the feature to be tested. The following code uses **HWTEST\_F** as an example: - - ``` - /** - * @tc.name: integer_sub_001 - * @tc.desc: Test Calculator - * @tc.type: FUNC - * @tc.require: AR00000000 SR00000000 - */ - HWTEST_F(CalcSubtractionTest, integer_sub_001, TestSize.Level1) - { - EXPECT_EQ(0, Subtraction(1, 0)); - } - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >- **@tc.name**: test case name, which briefly describes the test purpose - >- **@tc.desc**: detailed description of the test case, including the test purpose, test procedure, and expected result - >- **@tc.type**: test type, which can be **FUNC**, **PERF**, **SECU**, or **RELI**. - >- **@tc.require**: requirement ID or issue ID, which is used to associate the modification with the test case - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

SN

-

Test Type

-

Code

-

Description

-

1

-

Functionality test

-

FUNC

-

Verifies that each functionality of the software complies with the function design and specifications.

-

2

-

Performance test

-

PERF

-

Verifies that the software meets the performance requirements. Performance tests include load tests, capacitance tests, and pressure tests.

-

3

-

Security test

-

SECU

-

Verifies that the software complies with security requirements and related laws and regulations within the software lifecycle.

-

4

-

Reliability test

-

RELI

-

Verifies the probability that the software does not cause system failures within a specified period of time and under given conditions. Software stability is also involved in the test.

-
- -4. Compile the GN file of the test case, including defining the compilation target, adding compilation dependencies, and setting the source file. - - Example file path: **test/developertest/examples/lite/cxx\_demo/test/unittest/common/BUILD.gn** - - ``` - import("//build/lite/config/test.gni") - - unittest("CalcSubTest") { - output_extension = "bin" - sources = [ - "calc_subtraction_test.cpp" - ] - include_dirs = [] - deps = [] - } - ``` - -5. Add the compilation target to the subsystem compilation configuration to ensure that the test case is compiled with the version distribution. The following is an example: - 1. For devices that support connection to the Harmony device connector \(hdc\), the example compilation configuration directory is **test/developertest/examples/ohos.build**. - - ``` - { - "subsystem": "subsystem_examples", - "parts": { - "subsystem_examples": { - "module_list": [ - "//test/developertest/examples/detector:detector", - ... - ], - "test_list": [ - "//test/developertest/examples/detector/test:unittest", - ... - ] - }, - ... - } - ``` - - 2. For devices that support serial ports only, the example compilation configuration directory is **test/developertest/examples/lite/BUILD.gn**. - - ``` - import("//build/lite/config/test.gni") - - subsystem_test("test") { - test_components = [] - if(ohos_kernel_type == "liteos_riscv") { - features += [ - ] - }else if(ohos_kernel_type == "liteos_a") { - test_components += [ - "//test/developertest/examples/lite/cxx_demo/test/unittest/common:CalcSubTest" - ] - } - } - ``` - - -6. Create a resource configuration file for the test case to use static resources. - 1. Create the **resource** directory in the **test** directory of a component or module. - 2. Create a directory for a device type, for example, **phone**, in the **resource** directory. - 3. Create a folder named after the module in the device type directory, for example, **testmodule**. - 4. Create the **ohos\_test.xml** file in the folder named after the module. The file content is in the following format: - - ``` - - - - - - - - ``` - - 5. Define **resource\_config\_file** in the compilation configuration file of the test case to specify the resource file **ohos\_test.xml**. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >The resource file is used to push the **test.txt** file in the **resource** directory to the **/data/test/resource** directory of the device to test. To do so, run the **hdc push** command. - - -7. Execute the test case after it is compiled \(the preceding steps are complete\). - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >- For devices that support connection to the hdc, test cases can be compiled separately. - >- For devices that support serial ports only, to compile the test case, run the commands in the root directory for compiling the debug code. - > For details about how to execute a test case, see [How to Use the Test Platform](#section76401945124810). - - -## Development Example - -The code repository of the testing subsystem provides complete demo cases, which are available in the **test/developertest/examples/** directory. The following is an example of compiling a test case for a subtraction function: - -- The tested code is as follows: - - ``` - static int Subtraction(int a, int b) - { - return a - b; - } - ``` - -- The test case code is as follows: - - ``` - /** - * @tc.name: integer_sub_002 - * @tc.desc: Verify the Subtraction function. - * @tc.type: FUNC - * @tc.require: AR00000000 SR00000000 - */ - HWTEST_F(CalcSubtractionTest, integer_sub_002, TestSize.Level1) - { - EXPECT_EQ(1, Subtraction(2, 1)); - } - ``` - - -## How to Use the Test Platform - -1. \(Optional\) Install the XDevice component. XDevice can be used as a Python extension package. - - Go to the installation directory **test/xdevice** and run the following command: - - ``` - python setup.py install - ``` - - If the installation is successful, the following prompts are displayed: - - ``` - ... - Installed d:\programs\python37\lib\site-packages\xdevice-0.0.0-py3.7.egg - Processing dependencies for xdevice==0.0.0 - Searching for pyserial==3.4 - Best match: pyserial 3.4 - Processing pyserial-3.4-py3.7.egg - pyserial 3.4 is already the active version in easy-install.pth - Installing miniterm.py script to D:\Programs\Python37\Scripts - - Using d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg - Finished processing dependencies for xdevice==0.0.0 - ``` - -2. Modify the **developertest/config/user\_config.xml** file to configure the Developertest component. - 1. Modify basic configuration parameters. - - \[build\] \# Set build parameters of the test case. - - ``` - - false - false - true - ... ... - - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >**example**: whether to build the test case example. The default value is **false**. - >**version**: whether to build the test version. The default value is **false**. - >**testcase**: whether to build the test case. The default value is **true**. - - 2. For devices that support connection to the hdc, modify the configuration file as follows: - - Between the **device** tags with the **"usb-hdc"** attribute, modify the IP address of the device and the port number matching the HDC connection. For example: - - ``` - - 192.168.1.1 - 9111 - - - ``` - - 3. For devices that support serial ports only, modify the configuration file as follows: - - \[board\_info\] \# Configure development board information. - - ``` - - hispark - taurus - ipcamera - hb build - - ``` - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >**board\_series**: development board series. The default value is **hispark**. - >**board\_type**: development board type. The default value is **taurus**. - >**board\_product**: target product. The default value is **ipcamera**. - >**build\_command**: command used for building the test version and test case. The default value is **hb build**. - - Between the **device** tags with the **"ipcamera"** attribute, modify the serial port information, including the COM port and baud rate. For example: - - ``` - - - COM1 - cmd - 115200 - 8 - 1 - 1 - - - ``` - - -3. \(Optional\) Modify the Developertest configuration. If a test case has been compiled, specify the compilation output path of the test case. In this case the test platform will not recompile the test case. - - Modify the **config/user\_config.xml** file. - - 1. Specify the output path of the test case, that is, the compilation output directory between the **test\_cases** tags. Example: - - ``` - - /home/opencode/out/release/tests - - ``` - - 2. For devices that support serial ports only, specify the NFS directory on the PC \(**host\_dir**\) and the corresponding directory on the board \(**board\_dir**\) between the **NFS** tags. For example: - - ``` - - D:\nfs - user - - ``` - - -4. \(Optional\) Prepare the test environment. If devices to be tested support only serial ports, check whether the environment is ready: - - The system image and file system have been burnt into the development board and are running properly on it. For example, in system mode, if the device prompt **OHOS\#** when you log in with the shell, the system is running properly. - - The development host has been connected to the serial port of the development board and the network port. - - IP addresses of the development host and development board are in the same network segment and can ping each other. - - An empty directory has been created on the development host for mounting test cases through NFS, and the NFS service has been started properly. - -5. Start the test platform and execute the test case. - - Start the test framework, go to the **test/developertest** directory, and execute the startup script. - 1. Run the following command to start the test framework in Windows: - - ``` - start.bat - ``` - - 2. Run the following command to start the test framework in Linux: - - ``` - ./start.sh - ``` - - - - Select a device type. - - Configure the device type based on the development board in the configuration file, for example, **developertest/config/framework\_config.xml**. - - - Run test commands. - 1. To query the subsystems, modules, product form, and test types supported by test cases, run the **show** commands. - - ``` - Usage: - show productlist Query supported product forms - show typelist Query the supported test type - show subsystemlist Query supported subsystems - show modulelist Query supported modules - ``` - - 2. Run test commands. **-t** is mandatory, and **-ss** and **-tm** are optional. The following is an example: - - ``` - run -t ut -ss subsystem_examples -tm calculator - ``` - - 3. Specify the arguments to execute the test suite for a specific feature or module. - - ``` - usage: run [-h] [-p PRODUCTFORM] [-t [TESTTYPE [TESTTYPE ...]]] - [-ss SUBSYSTEM] [-tm TESTMODULE] [-ts TESTSUIT] - [-tc TESTCASE] [-tl TESTLEVEL] - - Optional arguments: - -h, --help Show this help message and exit. - -p PRODUCTFORM, --productform PRODUCTFORM Specified product form - -t [TESTTYPE [TESTTYPE ...]], --testtype [TESTTYPE [TESTTYPE ...]] - Specify test type(UT,MST,ST,PERF,ALL) - -ss SUBSYSTEM, --subsystem SUBSYSTEM Specify test subsystem - -tm TESTMODULE, --testmodule TESTMODULE Specified test module - -ts TESTSUIT, --testsuite TESTSUIT Specify test suite - -tc TESTCASE, --testcase TESTCASE Specify test case - -tl TESTLEVEL, --testlevel TESTLEVEL Specify test level - ``` - - - - View the test framework help if needed. - - Run the following command query test commands that are supported by the test platform: - - ``` - help - ``` - - - Exit the test platform. - - Run the following command to exit the test platform: - - ``` - quit - ``` - - -6. View the test result and logs. The test logs and reports are generated in the **developertest/reports** directory after you run the test commands. - - The test result is displayed on the console. The root path of the test result is as follows: - - ``` - reports/xxxx-xx-xx-xx-xx-xx - ``` - - - The test case formatting result is stored in the following directory: - - ``` - result/ - ``` - - - The test logs are stored in the following directory: - - ``` - log/plan_log_xxxx-xx-xx-xx-xx-xx.log - ``` - - - The report summary file is as follows: - - ``` - summary_report.html - ``` - - - The report details file is as follows: - - ``` - details_report.html - ``` - - - - The log directory of the test platform is as follows: - - ``` - reports/platform_log_xxxx-xx-xx-xx-xx-xx.log - ``` - - - -## Directory Structure - -The source code of XDevice is stored in the **test/xdevice** directory. The following table describes the **xdevice** directory structure. - -**Table 4** XDevice structure - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

xdevice

-

Basic components of the test platform

-

xdevice/src/xdevice

-

Source code for the basic test framework

-

xdevice/config

-

Configuration file of the basic test framework

-

xdevice/src/xdevice/__main__.py

-

Internal entrance to the basic test framework

-

xdevice/src/xdevice/__init__.py

-

Package and plug-in dependencies

-

xdevice/src/xdevice/variables.py

-

Global variables

-

xdevice/src/xdevice/_core/command

-

Commands input by test cases

-

xdevice/src/xdevice/_core/config

-

Configuration management of the basic test framework

-

xdevice/src/xdevice/_core/environment

-

Environment management of the basic test framework, including device management

-

xdevice/src/xdevice/_core/executor

-

Scheduling and distribution of test cases

-

xdevice/src/xdevice/_core/driver

-

Test executor for the basic test framework

-

xdevice/src/xdevice/_core/resource

-

Resource files and test report templates for the basic test framework

-

xdevice/src/xdevice/_core/testkit

-

Common operations for the basic test framework, including NFS mounting

-

xdevice/src/xdevice/_core/logger.py

-

Log management of the basic test framework

-

xdevice/src/xdevice/_core/plugin.py

-

Plug-in management of the basic test framework

-

xdevice/src/xdevice/_core/interface.py

-

Interfaces for plug-ins of the basic test framework

-

xdevice/setup.py

-

Installation script of the basic test framework

-

xdevice/run.bat

-

Startup script of the basic test framework (Windows)

-

xdevice/run.sh

-

Startup script of the basic test framework (Linux)

-
- -The source code of Developertest is stored in the **test/developertest** directory. The following table describes the **developertest** directory structure. - -**Table 5** Developertest structure - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Directory

-

Description

-

developertest

-

Development test framework

-

developertest/src

-

Test framework source code

-

developertest/src/core

-

Test executor

-

developertest/src/core/build

-

Test case compilation

-

developertest/src/core/command

-

Processing of command lines entered by users

-

developertest/src/core/config

-

Test framework configuration management

-

developertest/src/core/driver

-

Test framework driver executor

-

developertest/src/core/resource

-

Test framework configuration file

-

developertest/src/core/testcase

-

Test case management

-

developertest/src/core/common.py

-

Common operations on the test framework

-

developertest/src/core/constants.py

-

Global constants of the test framework

-

developertest/src/core/exception.py

-

Test framework exceptions

-

developertest/src/core/utils.py

-

Test framework tools and methods

-

developertest/src/main

-

Test framework platform

-

developertest/src/main/__main__.py

-

Internal entrance of the test framework

-

developertest/examples

-

Test framework demo cases

-

developertest/third_party

-

Third-party components

-

developertest/BUILD.gn

-

Compilation configuration of the subsystem

-

developertest/start.bat

-

Developer test entry (Windows)

-

developertest/start.sh

-

Developer test entry (Linux)

-
- diff --git a/en/device-dev/subsystems/utils-development-guidelines.md b/en/device-dev/subsystems/utils-development-guidelines.md deleted file mode 100644 index 3c93cc03c0e754686770e4862286f66fed3dbf31..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/utils-development-guidelines.md +++ /dev/null @@ -1,293 +0,0 @@ -# Utils Development Guidelines - -- [Available APIs](#section1633115419401) -- [How to Develop](#section17450172710292) - - [Developing a Native Application for the KV Store That Uses the LiteOS Cortex-A Kernel \(Hi3516 or Hi3518\)](#section258354119295) - - [Dumping System Attributes on the Platform That Uses the LiteOS Cortex-M Kernel](#section9179161863014) - - [Dumping System Attributes on the Platform That Uses the LiteOS Cortex-A Kernel](#section3179121853017) - - -## Available APIs - -**Table 1** APIs for file operations - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

int UtilsFileOpen(const char* path, int oflag, int mode)

-

Opens or creates a file.

-

int UtilsFileClose(int fd)

-

Closes a file with a specified file descriptor.

-

int UtilsFileRead(int fd, char *buf, unsigned int len)

-

Reads a specified length of data from a file with the specified file descriptor and writes the data into the buffer.

-

int UtilsFileWrite(int fd, const char *buf, unsigned int len)

-

Writes a specified length of data into a file with the specified file descriptor.

-

int UtilsFileDelete(const char *path)

-

Deletes a specified file.

-

int UtilsFileStat(const char *path, unsigned int *fileSize)

-

Obtains the file size.

-

int UtilsFileSeek(int fd, int offset, unsigned int whence)

-

Adjusts the read and write position offset in a file.

-

int UtilsFileCopy(const char* src, const char* dest)

-

Copies the source file to a target file.

-

int UtilsFileMove(const char* src, const char* dest)

-

Moves the source file into a target file.

-
- -Sample code for file operations: - -``` -// Open a file and write data. -char fileName[] = "testfile"; -static const char def[] = "utils_file_operation implement."; -int fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0); -printf("file handle = %d\n", fd); -int ret = UtilsFileWrite(fd, def, strlen(def)); -printf("write ret = %d\n", ret); - -// Adjust the position offset in the file. -ret = UtilsFileSeek(fd, 5, SEEK_SET_FS); -printf("lseek ret = %d\n", ret); - -// Read data and close the file. -char buf[64] = {0}; -int readLen = UtilsFileRead(fd, buf, 64); -ret = UtilsFileClose(fd); -printf("read len = %d : buf = %s\n", readLen, buf); - -// Obtain the file size. -int fileLen = 0; -ret = UtilsFileStat(fileName, &fileLen); -printf("file size = %d\n", fileLen); - -// Delete the file. -ret = UtilsFileDelete(fileName); -printf("delete ret = %d\n", ret); -``` - -**Table 2** APIs for KV store operations - - - - - - - - - - - - - - - - -

Function

-

Description

-

int UtilsGetValue(const char* key, char* value, unsigned int len)

-

Obtains the value matching a specified key from the file system or cache.

-

int UtilsSetValue(const char* key, const char* value)

-

Adds or updates the value matching a specified key in the file system or cache.

-

int UtilsDeleteValue(const char* key)

-

Deletes the value matching a specified key from the file system or cache.

-
- -Sample code for the KV store: - -``` -// Set the value matching the specified key. -char key[] = "rw.sys.version_100"; -char value[] = "Hello kv operation implement!"; -int ret = UtilsSetValue(key, value); -printf("UtilsSetValue set ret = %d\n", ret); - -// Obtain the value matching the specified key. -char temp[128] = {0}; -ret = UtilsGetValue(key, temp, 128); -printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); - -// Delete the value matching the specified key. -ret = UtilsDeleteValue(key); -printf("UtilsDeleteValue delete ret = %d\n", ret); -``` - -## How to Develop - -### Developing a Native Application for the KV Store That Uses the LiteOS Cortex-A Kernel \(Hi3516 or Hi3518\) - -1. Develop the native application for the KV store using **AbilityKit** APIs. - - Write the user program by calling the APIs provided by the KV store and compile the **libLauncher.so** file. - - ``` - // Set the value matching the specified key. - char key[] = "rw.sys.version_100"; - char value[] = "Hello kv operation implement!"; - int ret = UtilsSetValue(key, value); - printf("UtilsSetValue set ret = %d\n", ret); - - // Obtain the value matching the specified key. - char temp[128] = {0}; - ret = UtilsGetValue(key, temp, 128); - printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); - - // Delete the value matching the specified key. - ret = UtilsDeleteValue(key); - printf("UtilsDeleteValue delete ret = %d\n", ret); - ``` - - - Edit the **config.json** file as follows: - - ``` - { - "app": { - "bundleName": "com.huawei.launcher", - "vendor": "huawei", - "version": { - "code": 1, - "name": "1.0" - } - }, - "deviceConfig": { - "default": { - "reqSdk": { - "compatible": "zsdk 1.0.0", - "target": "zsdk 1.0.1" - }, - "keepAlive": false - }, - "smartCamera": { - "reqSdk": { - "compatible": "zsdk 1.0.0", - "target": "zsdk 1.0.1" - }, - "keepAlive": false - } - }, - "module": { - "package": "com.huawei.launcher", - "name": ".MyHarmonyAbilityPackage", - "deviceType": [ - "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera" - ], - "distro": { - "deliveryWithInstall": true, - "moduleName": "Launcher", - "moduleType": "entry" - }, - "abilities": [{ - "name": "MainAbility", - "icon": "res/drawable/phone.png", - "label": "test app 1", - "launchType": "standard", - "type": "page" - }, - { - "name": "SecondAbility", - "icon": "res/drawable/phone.png", - "label": "test app 2", - "launchType": "standard", - "type": "page" - }, - { - "name": "ServiceAbility", - "icon": "res/drawable/phone.png", - "label": "test app 2", - "launchType": "standard", - "type": "service" - } - ] - } - } - ``` - - - - Generate a HAP file. - - - Add resource files in the **res/drawable** directory based on the following directory structure. - - ![](figures/unnaming.png) - - - Compress the **libLauncher.so**, **config.json**, and resource files into a ZIP package and change the file name extension to **.hap**, for example, **Launcher.hap**. - - -2. Connect the development board and send the command for installing the native KV store application to the board through the serial port. - - ``` - ./nfs/dev_tools/bin/bm install -p /nfs/Launcher.hap - ``` - -3. Send the command for running the native KV store application to the board through the serial port. - - ``` - ./nfs/dev_tools/bin/aa start -p com.huawei.launcher -n ServiceAbility - ``` - - -### Dumping System Attributes on the Platform That Uses the LiteOS Cortex-M Kernel - -1. Connect the development board and send the **AT+SYSPARA** command to the board through the serial port. - - ``` - AT+SYSPARA - ``` - - **Figure 1** Output of the system attribute dumping command for the LiteOS Cortex-M kernel - ![](figures/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel.png "output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-m-kernel") - - -### Dumping System Attributes on the Platform That Uses the LiteOS Cortex-A Kernel - -1. Connect the development board and run the **os\_dump --help** command in the **bin** directory to view the **os\_dump** help information. - - ``` - ./bin/os_dump --help - ``` - -2. Run the **os\_dump -l** command in the **bin** directory to view system modules that support attribute dumping. - - ``` - ./bin/os_dump -l - ``` - -3. Run the **os\_dump syspara** command in the **bin** directory to dump the current system attributes. - - ``` - ./bin/os_dump syspara - ``` - - **Figure 2** Output of the system attribute dumping command for the LiteOS Cortex-A kernel - ![](figures/output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel.png "output-of-the-system-attribute-dumping-command-for-the-liteos-cortex-a-kernel") - - diff --git a/en/device-dev/subsystems/utils.md b/en/device-dev/subsystems/utils.md deleted file mode 100644 index 3b50567c41f81e03d3d937266cd6cb635f15ca4e..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/utils.md +++ /dev/null @@ -1,9 +0,0 @@ -# Utils - -- **[Utils Overview](utils-overview.md)** - -- **[Utils Development Guidelines](utils-development-guidelines.md)** - -- **[Utils FAQ](utils-faq.md)** - - diff --git a/en/device-dev/subsystems/xts.md b/en/device-dev/subsystems/xts.md deleted file mode 100644 index 24396f880e05a6ed78dfcb41c8a78660ad469317..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/xts.md +++ /dev/null @@ -1,648 +0,0 @@ -# XTS - -- [Introduction](#section465982318513) -- [System Types](#section125090457443) -- [Directory Structure](#section161941989596) -- [Constraints](#section119744591305) -- [Usage Guidelines](#section137768191623) -- [Test Case Development Guidelines](#section3695134065513) - - [C-based Test Case Development and Compilation \(for the Mini System\)](#section198193336544) - - [C-based Test Case Execution \(for the Mini System\)](#section13820233175418) - - [C++-based Test Case Development and Compilation \(for Standard and Small Systems\)](#section3822123311540) - - [C++-based Test Case Execution \(for Standard and Small Systems\)](#section128222336544) - - [JavaScript-based Test Case Development \(for the Standard System\)](#section159801435165220) - - [JavaScript-based Test Case Packaging \(for the Standard System\)](#section445519106559) - - -## Introduction - -The X test suite \(XTS\) subsystem contains a set of OpenHarmony certification test suites, including the currently supported application compatibility test suite \(ACTS\) and the device compatibility test suite \(DCTS\) that will be supported in the future. - -This subsystem contains the ACTS and **tools** software package. - -- The **acts** directory stores the source code and configuration files of ACTS test cases. The ACTS helps device vendors detect the software incompatibility as early as possible and ensures that the software is compatible to OpenHarmony during the entire development process. -- The **tools** software package stores the test case development framework related to **acts**. - -## System Types - -OpenHarmony supports the following system types: - -- Mini system - - A mini system runs on the devices whose memory is greater than or equal to 128 KiB and that are equipped with MCU processors such as ARM Cortex-M and 32-bit RISC-V. This system provides multiple lightweight network protocols and graphics frameworks, and a wide range of read/write components for the IoT bus. Typical products include connection modules, sensors, and wearables for smart home. - -- Small system - - A small system runs on the devices whose memory is greater than or equal to 1 MiB and that are equipped with application processors such as ARM Cortex-A. This system provides higher security capabilities, standard graphics frameworks, and video encoding and decoding capabilities. Typical products include smart home IP cameras, electronic cat eyes, and routers, and event data recorders \(EDRs\) for smart travel. - -- Standard system - - A standard system runs on the devices whose memory is greater than or equal to 128 MiB and that are equipped with application processors such as ARM Cortex-A. This system provides a complete application framework supporting the enhanced interaction, 3D GPU, hardware composer, diverse components, and rich animations. This system applies to high-end refrigerator displays. - - -## Directory Structure - -``` -/test/xts -├── acts # Test code -│ └── subsystem # Source code of subsystem test cases for the standard system -│ └── subsystem_lite # Source code of subsystems test cases for mini and small systems -│ └── BUILD.gn # Build configuration of test cases for the standard system -│ └── build_lite -│ └── BUILD.gn # Build configuration of test cases for mini and small systems -└── tools # Test tool code -``` - -## Constraints - -Test cases for the mini system must be developed based on C, and those for the small system must be developed based on C++. - -## Usage Guidelines - -**Table 1** Test case levels - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Level

-

Definition

-

Scope

-

Level0

-

Smoke

-

Verifies basic functionalities of key features and basic DFX attributes with the most common input. The pass result indicates that the features are runnable.

-

Level1

-

Basic

-

Verifies basic functionalities of key features and basic DFX attributes with common input. The pass result indicates that the features are testable.

-

Level2

-

Major

-

Verifies basic functionalities of key features and basic DFX attributes with common input and errors. The pass result indicates that the features are functional and ready for beta testing.

-

Level3

-

Regular

-

Verifies functionalities of all key features, and all DFX attributes with common and uncommon input combinations or normal and abnormal preset conditions.

-

Level4

-

Rare

-

Verifies functionalities of key features under extremely abnormal presets and uncommon input combinations.

-
- -**Table 2** Test case granularities - - - - - - - - - - - - - - - - - - - - -

Test Scale

-

Test Objects

-

Test Environment

-

LargeTest

-

Service functionalities, all-scenario features, and mechanical power environment (MPE) and scenario-level DFX

-

Devices close to real devices

-

MediumTest

-

Modules, subsystem functionalities after module integration, and DFX

-

Single device that is actually used. You can perform message simulation, but do not mock functions.

-

SmallTest

-

Modules, classes, and functions

-

Local PC. Use a large number of mocks to replace dependencies with other modules.

-
- -**Table 3** Test types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Type

-

Definition

-

Function

-

Tests the correctness of both service and platform functionalities provided by the tested object for end users or developers.

-

Performance

-

Tests the processing capability of the tested object under specific preset conditions and load models. The processing capability is measured by the service volume that can be processed in a unit time, for example, call per second, frame per second, or event processing volume per second.

-

Power

-

Tests the power consumption of the tested object in a certain period of time under specific preset conditions and load models.

-

Reliability

-

Tests the service performance of the tested object under common and uncommon input conditions, or specified service volume pressure and long-term continuous running pressure. The test covers stability, pressure handling, fault injection, and Monkey test times.

-

Security

-
  • Tests the capability of defending against security threats, including but not limited to unauthorized access, use, disclosure, damage, modification, and destruction, to ensure information confidentiality, integrity, and availability.
  • Tests the privacy protection capability to ensure that the collection, use, retention, disclosure, and disposal of users' private data comply with laws and regulations.
  • Tests the compliance with various security specifications, such as security design, security requirements, and security certification of the Ministry of Industry and Information Technology (MIIT).
-

Global

-

Tests the internationalized data and localization capabilities of the tested object, including multi-language display, various input/output habits, time formats, and regional features, such as currency, time, and culture taboos.

-

Compatibility

-
  • Tests backward compatibility of an application with its own data, the forward and backward compatibility with the system, and the compatibility with different user data, such as audio file content of the player and smart SMS messages.
  • Tests system backward compatibility with its own data and the compatibility of common applications in the ecosystem.
  • Tests software compatibility with related hardware.
-

User

-

Tests user experience of the object in real user scenarios. All conclusions and comments should come from the users, which are all subjective evaluation in this case.

-

Standard

-

Tests the compliance with industry and company-specific standards, protocols, and specifications. The standards here do not include any security standards that should be classified into the security test.

-

Safety

-

Tests the safety property of the tested object to avoid possible hazards to personal safety, health, and the object itself.

-

Resilience

-

Tests the resilience property of the tested object to ensure that it can withstand and maintain the defined running status (including downgrading) when being attacked, and recover from and adapt defense to the attacks to approach mission assurance.

-
- -## Test Case Development Guidelines - -You should select the appropriate programming language and your target test framework to develop test cases. - -**Table 4** Test frameworks and test case languages for different systems - - - - - - - - - - - - - - - - - - - - -

System

-

Test Framework

-

Language

-

Mini

-

HCTest

-

C

-

Small

-

HCPPTest

-

C++

-

Standard

-

HJSUnit and HCPPTest

-

JavaScript and C++

-
- -### C-based Test Case Development and Compilation \(for the Mini System\) - -**Developing test cases for the mini system** - -The HCTest framework is used to support test cases developed with the C language. HCTest is enhanced and adapted based on the open-source test framework Unity. - -1. Access the **test/xts/acts** repository where the test cases will be stored. - - ``` - ├── acts - │ └──subsystem_lite - │ │ └── module_hal - │ │ │ └── BUILD.gn - │ │ │ └── src - │ └──build_lite - │ │ └── BUILD.gn - ``` - -2. Write the test case in the **src** directory. - - 1 Import the test framework header file. - - ``` - #include "hctest.h" - ``` - - 2. Use the **LITE\_TEST\_SUIT** macro to define names of the subsystem, module, and test suite. - - ``` - /** - * @brief Registers a test suite named IntTestSuite. - * @param test Subsystem name - * @param example Module name - * @param IntTestSuite Test suite name - */ - LITE_TEST_SUIT(test, example, IntTestSuite); - ``` - - 3. Define Setup and TearDown. - - Format: Test suite name+Setup, Test suite name+TearDown. - - The Setup and TearDown functions must exist, but function bodies can be empty. - - 4. Use the **LITE\_TEST\_CASE** macro to write the test case. - - Three parameters are involved: test suite name, test case name, and test case properties \(including type, granularity, and level\). - - ``` - LITE_TEST_CASE(IntTestSuite, TestCase001, Function | MediumTest | Level1) - { - // Do something - }; - ``` - - 5. Use the **RUN\_TEST\_SUITE** macro to register the test suite. - - ``` - RUN_TEST_SUITE(IntTestSuite); - ``` - -3. Create the configuration file \(**BUILD.gn**\) of the test module. - - Create a **BUILD.gn** \(example\) build file in each test module directory. Specify the name of the built static library and its dependent header file and library in the build file. The format is as follows: - - ``` - import("//test/xts/tools/lite/build/suite_lite.gni") - hctest_suite("ActsDemoTest") { - suite_name = "acts" - sources = [ - "src/test_demo.c", - ] - include_dirs = [ ] - cflags = [ "-Wno-error" ] - } - ``` - -4. Add build options to the **BUILD.gn** file in the **acts** directory. - - You need to add the test module to the **test/xts/acts/build\_lite/BUILD.gn** script in the **acts** directory. - - ``` - lite_component("acts") { - ... - if(board_name == "liteos_m") { - features += [ - ... - "//xts/acts/subsystem_lite/module_hal:ActsDemoTest" - ] - } - } - ``` - -5. Run build commands. - - Test suites are built along with version build. The ACTS is built together with the debug version. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >The ACTS build middleware is a static library, which will be linked to the image. - - -### C-based Test Case Execution \(for the Mini System\) - -**Executing test cases for the mini system** - -Burn the image into the development board. - -**Executing the test** - -1. Use a serial port tool to log in to the development board and save information about the serial port. -2. Restart the device and view serial port logs. - -**Analyzing the test result** - -View the serial port logs, whose format is as follows: - -The log for each test suite starts with **Start to run test suite:** and ends with **xx Tests xx Failures xx Ignored**. - -### C++-based Test Case Development and Compilation \(for Standard and Small Systems\) - -**Developing test cases for small-system devices** \(For examples of the standard system, go to the **global/i18n\_standard directory**.\) - -The HCPPTest framework is enhanced and adapted based on the open-source framework Googletest. - -1. Access the **test/xts/acts** repository where the test cases will be stored. - - ``` - ├── acts - │ └──subsystem_lite - │ │ └── module_posix - │ │ │ └── BUILD.gn - │ │ │ └── src - │ └──build_lite - │ │ └── BUILD.gn - ``` - -2. Write the test case in the **src** directory. - - 1. Import the test framework header file. - - The following statement includes **gtest.h**. - - ``` - #include "gtest/gtest.h" - ``` - - 2. Define Setup and TearDown. - - ``` - using namespace std; - using namespace testing::ext; - class TestSuite: public testing::Test { - protected: - // Preset action of the test suite, which is executed before the first test case - static void SetUpTestCase(void){ - } - // Test suite cleanup action, which is executed after the last test case - static void TearDownTestCase(void){ - } - // Preset action of the test case - virtual void SetUp() - { - } - // Cleanup action of the test case - virtual void TearDown() - { - } - }; - ``` - - 3. Use the **HWTEST** or **HWTEST\_F** macro to write the test case. - - **HWTEST**: definition of common test cases, including the test suite name, test case name, and case annotation. - - **HWTEST\_F**: definition of SetUp and TearDown test cases, including the test suite name, test case name, and case annotation. - - Three parameters are involved: test suite name, test case name, and test case properties \(including type, granularity, and level\). - - ``` - HWTEST_F(TestSuite, TestCase_0001, Function | MediumTest | Level1) { - // Do something - } - ``` - -3. Create a configuration file \(**BUILD.gn**\) of the test module. - - Create a **BUILD.gn** build file in each test module directory. Specify the name of the built static library and its dependent header file and library in the build file. Each test module is independently built into a **.bin** executable file, which can be directly pushed to the development board for testing. - - Example: - - ``` - import("//test/xts/tools/lite/build/suite_lite.gni") - hcpptest_suite("ActsDemoTest") { - suite_name = "acts" - sources = [ - "src/TestDemo.cpp" - ] - - include_dirs = [ - "src", - ... - ] - deps = [ - ... - ] - cflags = [ "-Wno-error" ] - } - ``` - -4. Add build options to the **BUILD.gn** file in the **acts** directory. - - Add the test module to the **test/xts/acts/build\_lite/BUILD.gn** script in the **acts** directory. - - ``` - lite_component("acts") { - ... - else if(board_name == "liteos_a") { - features += [ - ... - "//xts/acts/subsystem_lite/module_posix:ActsDemoTest" - ] - } - } - ``` - -5. Run build commands. - - Test suites are built along with the version build. The ACTS is built together with the debug version. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >The ACTS for the small system is independently built to an executable file \(.bin\) and archived in the **suites\\acts** directory of the build result. - - -### C++-based Test Case Execution \(for Standard and Small Systems\) - -**Executing test cases for the small system** - -Currently, test cases are shared by the NFS and mounted to the development board for execution. - -**Setting up the environment** - -1. Use a network cable or wireless network to connect the development board to your PC. -2. Configure the IP address, subnet mask, and gateway for the development board. Ensure that the development board and the PC are in the same network segment. -3. Install and register the NFS server on the PC and start the NFS service. -4. Run the **mount** command for the development board to ensure that the development board can access NFS shared files on the PC. - - Format: **mount** _NFS server IP address_**:/**_NFS shared directory_ **/**_development board directory_ **nfs** - - Example: - - ``` - mount 192.168.1.10:/nfs /nfs nfs - ``` - - -**Executing test cases** - -Execute **ActsDemoTest.bin** to trigger test case execution, and analyze serial port logs generated after the execution is complete. - -### JavaScript-based Test Case Development \(for the Standard System\) - -The HJSUnit framework is used to support automated test of OpenHarmony apps that are developed using the JavaScript language based on the JS application framework. - -**Basic syntax of test cases** - -The test cases are developed with the JavaScript language and must meet the programming specifications of the language. - -**Table 5** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Syntax

-

Description

-

Mandatory

-

beforeAll

-

Presets a test-suite-level action executed only once before all test cases are executed. You can pass the action function as the only parameter.

-

No

-

afterAll

-

Presets a test-suite-level clear action executed only once after all test cases are executed. You can pass the clear function as the only parameter.

-

No

-

beforeEach

-

Presets a test-case-level action executed before each test case is executed. The number of execution times is the same as the number of test cases defined by it. You can pass the action function as the only parameter.

-

No

-

afterEach

-

Presets a test-case-level clear action executed after each test case is executed. The number of execution times is the same as the number of test cases defined by it. You can pass the clear function as the only parameter.

-

No

-

describe

-

Defines a test suite. You can pass two parameters: test suite name and test suite function. The describe statement supports nesting. You can use beforeall, beforeEach, afterEach, and afterAll in each describe statement.

-

Yes

-

it

-

Defines a test case. You can pass three parameters: test case name, filter parameter, and test case function.

-

Usage of the filter parameter:

-

The value of the filter parameter is a 32-bit integer. Setting different bits to 1 means different configurations:

-
  • bit 0: whether the filter parameter takes effect. 1 means that the test case is used for the function test and other settings of the parameter do not take effect.
  • Bits 0-10: test case categories
  • Bits 16-18: test case scales
  • Bits 24-28: test levels
-

Test case categories: Bits 0-10 indicate FUNCTION (function test), PERFORMANCE (performance test), POWER (power consumption test), RELIABILITY (reliability test), SECURITY (security compliance test), GLOBAL (integrity test), COMPATIBILITY (compatibility test), USER (user test), STANDARD (standard test), SAFETY (security feature test), and RESILIENCE (resilience test), respectively.

-

Test case scales: Bits 16-18 indicate SMALL (small-scale test), MEDIUM (medium-scale test), and LARGE (large-scale test), respectively.

-

Test levels: Bits 24-28 indicate LEVEL0 (level-0 test), LEVEL1 (level-1 test), LEVEL2 (level-2 test), LEVEL3 (level-3 test), and LEVEL4 (level-4 test), respectively.

-

Yes

-
- -Use the standard syntax of Jasmine to write test cases. The ES6 specification is supported. - -1. Store the test cases in the **entry/src/main/js/test** directory, whose structure is as follows: - - ``` - ├── BUILD.gn - │ └──entry - │ │ └──src - │ │ │ └──main - │ │ │ │ └──js - │ │ │ │ │ └──default - │ │ │ │ │ │ └──pages - │ │ │ │ │ │ │ └──index - │ │ │ │ │ │ │ │ └──index.js # Entry file - │ │ │ │ │ └──test # Test code - │ │ │ └── resources # HAP resources - │ │ │ └── config.json # HAP configuration file - ``` - -2. Start the JS test framework and load test cases. The following is an example for **index.js**. - - ``` - // Start the JS test framework and load test cases. - import {Core, ExpectExtend} from 'deccjsunit/index' - - export default { - data: { - title: "" - }, - onInit() { - this.title = this.$t('strings.world'); - }, - onShow() { - console.info('onShow finish') - const core = Core.getInstance() - const expectExtend = new ExpectExtend({ - 'id': 'extend' - }) - core.addService('expect', expectExtend) - core.init() - const configService = core.getDefaultService('config') - configService.setConfig(this) - require('../../../test/List.test') - core.execute() - }, - onReady() { - }, - } - ``` - -3. Write a unit test case by referring to the following example: - - ``` - // Use HJSUnit to perform the unit test. - describe('appInfoTest', function () { - it('app_info_test_001', 0, function () { - var info = app.getInfo() - expect(info.versionName).assertEqual('1.0') - expect(info.versionCode).assertEqual('3') - }) - }) - ``` - - -### JavaScript-based Test Case Packaging \(for the Standard System\) - -For details about how to build a HAP, see the JS application development guide of the standard system [Building and Creating HAPs](https://developer.harmonyos.com/en/docs/documentation/doc-guides/build_overview-0000001055075201). - diff --git a/en/readme.md b/en/readme.md index 6f5507767fb638dc4a82b16d8c40da15bc4bf0af..4931059a15b9ae98cadd621128623ef81acd0fed 100644 --- a/en/readme.md +++ b/en/readme.md @@ -1,77 +1,82 @@ # WELCOME TO OPENHARMONY + This project stores OpenHarmony documentation, including the quick start guide, development guides, and API reference. We appreciate your contribution to the OpenHarmony documentation. -## Motivation -Traditional OSs are limited to a specific type of device, while OpenHarmony provides distributed features that are compatible with a wide range of different devices. The first version supports devices with 128 KB to 128 MB of memory. Join us as we keep updating OpenHarmony versions. -For device developers, OpenHarmony utilizes a component-based design to tailor its features to better suit specific devices, based on each device's capabilities and service characteristics. OpenHarmony can run on devices with limited resources and wearables with hundreds of KB of memory, as well as more powerful devices, such as smart home cameras and dashcams with hundreds of MB of memory. - -[中文版本](../zh-cn/readme.md) - -## Device Development - Documentation Directory Structure -- [Overview](device-dev/quick-start/overview.md) -- [Getting Started](device-dev/quick-start/Readme-EN.md) -- [Source Code Acquisition/Tool Acquisition](device-dev/get-code/Readme-EN.md) -- [Kernel Usage Guidelines](device-dev/kernel/Readme-EN.md) -- [Driver Usage Guidelines](device-dev/driver/Readme-EN.md) -- [Subsystem Development Guidelines](device-dev/subsystems/Readme-EN.md) - - [Compilation and Building](device-dev/subsystems/compilation-and-building.md) - - [Distributed Remote Startup](device-dev/subsystems/distributed-remote-startup.md) - - [Graphics](device-dev/subsystems/graphics.md) - - [Multimedia](device-dev/subsystems/multimedia.md) - - [Utils](device-dev/subsystems/utils.md) - - [AI Framework](device-dev/subsystems/ai-framework.md) - - [Sensors](device-dev/subsystems/sensors.md) - - [Application Framework](device-dev/subsystems/application-framework.md) - - [OTA Upgrade](device-dev/subsystems/ota-upgrade.md) - - [Security](device-dev/subsystems/security.md) - - [Startup](device-dev/subsystems/startup.md) - - [Testing](device-dev/subsystems/testing.md) - - [DFX](device-dev/subsystems/dfx.md) - - [R&D Tools](device-dev/subsystems/r-d-tools.md) - - [X Test Suite](device-dev/subsystems/xts.md) -- [Bundle Development Guidelines](device-dev/bundles/Readme-EN.md) -- [Third-Party Library Porting Guide](device-dev/porting/Readme-EN.md) -- [Device Development Guidelines](device-dev/guide/Readme-EN.md) - - [WLAN-connected Products](device-dev/guide/wlan-connected-products.md) - - [Cameras Without a Screen](device-dev/guide/cameras-without-a-screen.md) - - [Cameras with a Screen](device-dev/guide/cameras-with-a-screen.md) - - [Visual Application Development](device-dev/guide/visual-application-development.md) - - [Development Example for Clock Apps](device-dev/guide/development-example-for-clock-apps.md) - - [Development Example for Platform Drivers](device-dev/guide/development-example-for-platform-drivers.md) - - [Development Example for Peripheral Drivers](device-dev/guide/development-example-for-peripheral-drivers.md) -- [Privacy and Security](device-dev/security/Readme-EN.md) -- [Glossary](device-dev/glossary/glossary.md) - -# Application Development - Documentation Directory Structure - -- [Getting Started](application-dev/quick-start/getting-started.md) -- [UI](application-dev/ui/Readme-EN.md) -- [Media](application-dev/media/Readme-EN.md) -- [Connectivity](application-dev/connectivity/Readme-EN.md) -- [JS Reference](application-dev/js-reference/Readme-EN.md) - -## Start Contributing - -OpenHarmony is an open-source community and encourages everyone in the community to submit patches directly to the project. You can contribute either to the code or documentation. -- [Contributing to the Code](contribute/contributing-code.md) -- [Contributing to the Documentation](contribute/documentation-contribution.md) - -For more details on how to contribute, see [Contributing Documents](contribute). -## Get Source Code and Tools -To download the source code and tools required for the project, click the following links: -- [Source Code Acquisition](device-dev/get-code/source-code-acquisition.md) -- [Tool Acquisition](device-dev/get-code/tool-acquisition.md) - -## Where to Turn for Help -You can subscribe to the mailing list to get constant updates on new features, released road maps, and community activities. For how to subscribe to the mailing list or get any other support, see [Communication in Community](https://gitee.com/openharmony/docs/tree/master/contribute/communication-in-community.md). - -## Code of Conduct -OpenHarmony is committed to providing a welcoming and inspiring community for all. In order to maintain a collaborative environment, we recommend you read and follow the community [Code of Conduct](https://gitee.com/openharmony/docs/blob/master/contribute/code-of-conduct.md). - -## Contributors & Acknowledgements -A great open-source project wouldn't be possible without the hard work of many contributors. We'd like to invite anyone from around the world to participate in this exciting journey, and we're grateful for your time, passion, and efforts! - -## Release -In order to provide new features and bug fixes, the community constantly updates code and provides new releases. - -See [OpenHarmony Release Notes](release-notes/OpenHarmony-Release-Notes.md). \ No newline at end of file +## Contents + +- [OpenHarmony Overview](OpenHarmony-Overview.md) +- Mini and Small System Development Guidelines \(Reference Memory < 128 MB\) + - Device development + - **overview**: [device development overview](device-dev/overview.md) + - **quick-start**: [quick start guide](device-dev/quick-start/Readme-EN.md) \(covering environment setup, source code acquisition, build, and burning\) + - Basic development capabilities + - **Kernel**: [lite kernel](device-dev/kernel/kernel-lite.md) + - **Drivers**: [drivers](device-dev/driver/Readme-EN.md) + - **Subsystems**: [subsystems](device-dev/subsystems/Readme-EN.md) \(such as compilation and building, graphics, DFX, and XTS\) + - **Security**: [privacy and security](device-dev/security/Readme-EN.md) + + - **guide**: + - [WLAN-connected products](device-dev/guide/device-wifi.md) \(LED peripheral control and third-party SDK integration\) + - [Screenless cameras](device-dev/guide/device-iotcamera.md) \(camera control\) + - [Cameras with a screen](device-dev/guide/device-camera.md) \(screen and camera control, visual application development\) + + - **porting**: + - [Mini System SoC Porting Guide](device-dev/porting/transplant-minichip.md) + - [Small System SoC Porting Guide](device-dev/porting/transplant-smallchip.md) + - [Third-Party Library Porting Guide](device-dev/porting/transplant-thirdparty.md) + + - **bundles**: + - [Development Specifications](device-dev/bundles/bundles-standard-rules.md) + - [Development Guidelines](device-dev/bundles/bundles-guide.md) + - [HPM User Guide](device-dev/bundles/bundles-demo.md) + +- Standard System Development Guidelines \(Reference Memory ≥ 128 MB\) + - Device development + - **overview**: [device development overview](device-dev/overview.md) + - **quick-start**: [quick start guide](device-dev/quick-start/quickstart-standard.md) \(covering environment setup, source code acquisition, build, and burning\) + - Basic development capabilities + - **Kernel**: [Linux kernel](device-dev/kernel/kernel-standard.md) + - **Drivers**: [drivers](device-dev/driver/Readme-EN.md) + - **Subsystems**: [subsystems](device-dev/subsystems/Readme-EN.md) \(such as compilation and building, graphics, DFX, and XTS\) + - **Security**: [privacy and security](device-dev/security/Readme-EN.md) + + - **guide**: + - [Clock apps](device-dev/guide/oem_device_clockapp_des.md) + - [Platform drivers](device-dev/guide/device-driver-demo.md) + - [Peripheral drivers](device-dev/guide/device-outerdriver-demo.md) + + - **porting**: + + [Third-Party Library Porting Guide](device-dev/porting/transplant-thirdparty.md) + + - **bundles**: + - [Development Specifications](device-dev/bundles/bundles-standard-rules.md) + - [Development Guidelines](device-dev/bundles/bundles-guide.md) + - [HPM User Guide](device-dev/bundles/bundles-demo.md) + + +- App development + - **Overview**: [app development overview](application-dev/application-dev-guide.md) + - **quick-start**: [quick start guide](application-dev/quick-start/Readme-EN.md) + - **ui**: [UI](application-dev/ui/Readme-EN.md) + - **media**: [media](application-dev/media/Readme-EN.md) + - **connectivity**: [networks and connectivity](application-dev/connectivity/Readme-EN.md) + - **js-reference**: [JS reference](application-dev/js-reference/Readme-EN.md) +- **glossary**: [glossary](device-dev/glossary/glossary.md) + +## Version Change History + +For details, see [Release Notes](release-notes/OpenHarmony-Release-Notes.md). + +## Third-Party Open-Source Software and License Notice + +None. + +## How to Contribute + +A great open-source project wouldn't be possible without the hard work of many contributors. We'd like to invite anyone from around the world to [participate](contribute/contribution.md) in this exciting journey, and we're grateful for your time, passion, and efforts! + +You can evaluate available documents, make simple modifications, provide feedback on document quality, and contribute your original content. For details, see [Documentation Contribution](contribute/documentation-contribution.md). + +Excellent contributors will be awarded and the contributions will be publicized in the developer community. + diff --git a/zh-cn/OpenHarmony-Overview_zh.md b/zh-cn/OpenHarmony-Overview_zh.md index a83cac5948fd0da61c55a96d68aa7c3543a078f9..da8a20cd67d23b98b1eb02e1104017c0831520b9 100644 --- a/zh-cn/OpenHarmony-Overview_zh.md +++ b/zh-cn/OpenHarmony-Overview_zh.md @@ -366,7 +366,7 @@ OpenHarmony归档组织地址:[https://gitee.com/openharmony-retired](https:// ## 源码下载 -获取OpenHarmony源码:[下载说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/%E6%BA%90%E7%A0%81%E8%8E%B7%E5%8F%96.md) +获取OpenHarmony源码:[下载说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md) ## 如何参与 diff --git a/zh-cn/device-dev/bundles/Readme-CN.md b/zh-cn/device-dev/bundles/Readme-CN.md index 6b1ae76002fff938ab4b3098621a85736b7756c9..7233ea64d4297bef0816b08f413009882a6e3a64 100755 --- a/zh-cn/device-dev/bundles/Readme-CN.md +++ b/zh-cn/device-dev/bundles/Readme-CN.md @@ -1,20 +1,12 @@ -# 组件开发 - -- [组件开发规范](组件开发规范.md) - - [概述](概述.md) - - [组件构成](组件构成.md) - - [组件管理](组件管理.md) - - [组件版本](组件版本.md) - - [发行版](发行版.md) - - [环境变量说明](环境变量说明.md) - -- [组件开发指南](组件开发指南.md) - - [概述](概述-0.md) - - [准备工作](准备工作.md) - - [组件开发](组件开发.md) - -- [组件开发示例](组件开发示例.md) - - [HPM介绍](HPM介绍.md) - - [环境准备](环境准备.md) - - [操作实例](操作实例.md) +# 组件开发指南 + +- [组件开发规范](bundles-standard-rules.md) +- [组件开发指南](bundles-guide.md) + - [组件开发指南](bundles-guide-overview.md) + - [准备工作](bundles-guide-prepare.md) + - [组件开发](bundles-guide-develop.md) +- [组件开发示例](bundles-demo.md) + - [HPM介绍](bundles-demo-hpmdescription.md) + - [环境准备](bundles-demo-environment.md) + - [操作实例](bundles-demo-devsample.md) diff --git a/zh-cn/device-dev/bundles/bundles-demo-devsample.md b/zh-cn/device-dev/bundles/bundles-demo-devsample.md new file mode 100644 index 0000000000000000000000000000000000000000..1de6091e00561003efb769708a6dd5af62bd3f24 --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-demo-devsample.md @@ -0,0 +1,54 @@ +# 操作实例 + +环境准备好后,接下来本文以Hi3861平台为例,演示如何利用HPM进行组件的安装、编译和打包。 + +1. 执行以下命令,初始化安装目录(目录名可自行设置): + + ``` + mkdir test3861 + cd test3861 + hpm init -t dist + ``` + + 初始化成功则显示: + + ``` + Initialization finished. + ``` + +2. 安装wifi\_iot发行版。 + + ``` + hpm install @ohos/wifi_iot + ``` + + 安装成功则显示: + + ``` + Installed. + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >Hi3516平台采用下述命令: + >``` + >hpm install @ohos/ip_camera_hi3516dv300 + >``` + >Hi3518平台采用下述命令: + >``` + >hpm install @ohos/ip_camera_hi3518ev300 + >``` + +3. 编译打包 + + ``` + hpm dist + ``` + + 编译成功会显示: + + ``` + {{name}}: distribution building completed. + ``` + +4. 上述所有命令执行成功后,在 ./out 目录下会生成编译结果,开发者可以将编译结果烧录到对应的开发板上进行测试。 + diff --git a/zh-cn/device-dev/bundles/bundles-demo-environment.md b/zh-cn/device-dev/bundles/bundles-demo-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..1a05b2a302aa04390d4b294e784f30f07ebc0e72 --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-demo-environment.md @@ -0,0 +1,139 @@ +# 环境准备 + +- [linux服务器](#section20979554791) +- [安装Node.js](#section9954105413153) +- [安装HPM](#section15937194904819) +- [安装python环境](#section1621819180417) +- [安装文件打包工具](#section77617165913) +- [安装SCons](#section20558439191516) + +## linux服务器 + +准备一台装有Ubuntu 16.04 及以上 64 位系统的linux服务器(hpm是支持windows的,但是目前OpenHarmony开源的Hi3861、Hi3516、Hi3518三个解决方案都只支持Ubuntu)。 + +将linux shell改为bash: + +``` +ls -l $(which sh) +# 如果指向的不是bash,则按以下方式修改: +# 方法一:执行以下命令,然后选择no +dpkg-reconfigure dash +# 方法二:先删除sh,再重新创建软连接 +rm -f /bin/sh +ln -s bash /bin/sh +``` + +## 安装Node.js + +>![](../public_sys-resources/icon-note.gif) **说明:** +>如果配置的源的nodejs版本太低,可以执行以下语句后再执行apt-get install: +>``` +>curl -L https://deb.nodesource.com/setup_12.x | bash +>``` + +推荐安装 Node.js 12.x (包含 npm 6.14.4)或更高版本(推荐 12.13.0+): + +``` +sudo apt-get install nodejs +sudo apt-get install npm +``` + +查看版本: + +``` +node --version # 查看nodejs版本 +npm --version # 查看npm版本 +``` + +## 安装HPM + +通过 Node.js 自带的 npm(使用默认的源 https://registry.npmjs.org/ )安装 hpm-cli 命令行工具: + +``` +npm install -g @ohos/hpm-cli +``` + +安装完hpm-cli命令行工具后,执行以下命令可以查看hpm配置: + +``` +hpm config +``` + +上述命令执行后将会显示hpm的默认配置,您可以根据自己的喜好对默认配置进行修改,以下是hpm的常用配置: + +``` +registry = https://hpm.harmonyos.com # hpm注册中心地址,下载组件必须 +strictSsl = true # 通过https连接时,是否需要校验证书 +http_proxy = http://your-proxy-server:port # 配置HTTP代理 +https_proxy = http://your-proxy-server:port # 配置HTTPS代理 +``` + +hpm-cli的命令介绍可以参考:[hpm操作命令](bundles-standard-rules.md) + +## 安装python环境 + +需使用python3.7以上版本,采用以下命令进行安装: + +``` +sudo apt-get install python3.8 +sudo apt-get install python3-pip +sudo pip3 install setuptools +sudo pip3 install kconfiglib # 建议安装kconfiglib 13.2.0+版本 +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>上述方式适用Hi3518和Hi3516两种平台,针对Hi3861平台采用以下方式安装python环境: +>``` +>sudo apt-get install python3.8 +>sudo apt-get install python3-pip +>sudo pip3 install setuptools +>sudo pip3 install kconfiglib # 建议安装kconfiglib 13.2.0+版本 +>sudo pip3 install pycryptodome +>sudo pip3 install six --upgrade --ignore-installed six +>sudo pip3 install ecdsa +>``` + +如果当前系统中既存在python2又存在python3,参考以下方法将默认python修改为python3: + +``` +ll `which python` +rm /usr/bin/python +ln -s python3.8 /usr/bin/python +``` + +## 安装文件打包工具 + +采用以下命令进行安装: + +``` +which mkfs.vfat # 如果没找到,执行以下命令安装 +sudo apt-get install dosfstools +which mcopy # 如果没找到,执行以下命令安装 +sudo apt-get install mtools +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>Hi3518和Hi3516两种平台需要安装打包工具,Hi3861平台不需要。 + +## 安装SCons + +1. 打开Linux编译服务器终端。 +2. 运行如下命令,安装SCons安装包。 + + ``` + python3 -m pip install scons + ``` + +3. 运行如下命令,查看是否安装成功。如果安装成功,查询结果下图所示。 + + ``` + scons -v + ``` + + **图 1** SCons安装成功界面,版本要求3.0.4以上 + ![](figure/SCons安装成功界面-版本要求3-0-4以上-21.png "SCons安装成功界面-版本要求3-0-4以上-21") + + +>![](../public_sys-resources/icon-note.gif) **说明:** +>Hi3861平台需要安装SCons,Hi3518和Hi3516两种平台不需要。 + diff --git "a/zh-cn/device-dev/bundles/HPM\344\273\213\347\273\215.md" b/zh-cn/device-dev/bundles/bundles-demo-hpmdescription.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/bundles/HPM\344\273\213\347\273\215.md" rename to zh-cn/device-dev/bundles/bundles-demo-hpmdescription.md diff --git a/zh-cn/device-dev/bundles/bundles-demo.md b/zh-cn/device-dev/bundles/bundles-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..bcdc877e6dd00f49a3195ff4443a08de52917a1c --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-demo.md @@ -0,0 +1,9 @@ +# 组件开发示例 + +- **[HPM介绍](bundles-demo-hpmdescription.md)** + +- **[环境准备](bundles-demo-environment.md)** + +- **[操作实例](bundles-demo-devsample.md)** + + diff --git a/zh-cn/device-dev/bundles/bundles-guide-develop.md b/zh-cn/device-dev/bundles/bundles-guide-develop.md new file mode 100644 index 0000000000000000000000000000000000000000..bc462fd12dceefd0cb04dcfbdccf97a8412c6027 --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-guide-develop.md @@ -0,0 +1,240 @@ +# 组件开发 + +- [创建OpenHarmony组件](#section1976410130540) +- [新建组件](#section717481119145) +- [改造组件](#section102861955201410) +- [从模板创建组件](#section15882846181510) +- [编译组件](#section136732148541) +- [定义编译脚本](#section10274147111610) +- [执行编译](#section879301916172) +- [定义发行版](#section413216495619) +- [定义脚本](#section11503171219190) +- [发行](#section4694125521912) +- [烧录](#section1746331545413) +- [运行调试](#section6742131615549) + +## 创建OpenHarmony组件 + +创建OpenHarmony组件有如下几种方式: + +- 从头开发一个全新的组件。 +- 将一个现有的非组件的代码改造成组件。 +- hpm提供了一些组件模板方便快速创建组件。 + +## 新建组件 + +通常情况下,[HPM网站](https://hpm.harmonyOS.com)上能找到您开发常用的组件,如果现有的组件不能完全满足开发,这时可以自己动手开发一个组件。 + +如果您愿意,可以将组件发布到HPM的仓库中供其他用户使用。假设要在D:/source目录下新建一个全新的组件my-bundle: + +可以使用hpm init 创建该组件的脚手架代码,例如,进入D:/source目录,执行如下命令: + +``` +hpm init -t default -d demo my-bundle +``` + +会在 source 目录下生成如下文件: + +``` +mybundle +├── bundle.json # 组件元数据描述文件 +├── example # 测试组件功能的示例 +│ └── main.c +├── include # 组件的内部头文件 +│ └── mybundle.h +├── README.md # 组件的简要说明 +└── src # 组件的源代码 + └─ mybundle.c +``` + +接下来根据您的业务需要,实现组件内部的功能代码,完成代码开发后,通过git将代码(包括bundle.json文件)提交到组件代码托管仓库中(如gitee)。 + +## 改造组件 + +如果您已经有了代码,只是还不满足OpenHarmony的组件结构,需要改造成为hpm的组件包,只需要在当前要改造的代码目录下(例如mybundle2),执行如下命令,会提示您输入组件名称和版本。 + +``` +hpm init +``` + +1. 输入名称后回车(如mybundle2)。 +2. 输入版本后(如1.0.0)回车,在当前组件目录下会生成一个bundle.json文件。 +3. 打开bundle.json文件再添加其他的描述,这时候他已经是一个具备可发布的组件了。 + + ``` + $ hpm init + Your bundle will be created in dirname E:\demo\mybundle2 + ? bundle name mybundel2 + ? version 1.0.0 + Init finished! + ``` + + +1. 打开bundle.json文件修改其他信息(如作者,代码仓库,代码目录,命令脚本,依赖组件等),如下: + + ``` + { + "name": "mybundle2", + "version": "1.0.0", + "publishAs": "source", + "dirs":{ + ".":[ + "README.md" + ], + "src":[ + "test.c" + ], + "header":[ + "header/test.h" + ], + "src/common":[ + "src/common/foobar.txt" + ] + }, + "scripts": { + "build": "make -${args}" + }, + "dependencies": { + "@ohos/cjson": "^1.0.0", + "@ohos/": "^1.2.0" + } + } + ``` + + +## 从模板创建组件 + +hpm 除了提供了默认模板 default和simple两个简单的模板之外,其他模板均存储在服务器端。 + +可以使用命令hpm search -t template 从服务器端搜索模板。 + +![](figure/zh-cn_image_0000001051452177.png) + +根据description简要中的描述,找到适合的模板,基于模板可以快速创建一个组件的脚手架,执行如下初始化命令(指定-t -d 参数)。 + +``` +hpm init -t {templatename} -d dir name +``` + +- \{templatename\} :指的是模板名称。 +- -d 后面的参数dir:是要创建的组件所存放的路径。 +- name:为要创建的组件名称。 + +## 编译组件 + +完成代码开发后,需要对组件进行编译。hpm提供了命令集成的能力,您可以选择任意的适合项目的编译工具(如make,gcc,gn等等)。只需在当前项目的bundle.json文件中定义scripts脚本中的build命令,就可以通过执行hpm build执行编译。 + +## 定义编译脚本 + +以编译一个app目录下helloworld可执行文件为例: + +``` +app +├── BUILD.gn +├── include +│ └── helloworld.h +└── src + └── helloworld.c +``` + +在helloworld.c同级目录下新建一个BUILD.gn + +``` +touch BUILD.gn +vim BUILD.gn +``` + +以下是BUILD.gn的样例,仅供参考 + +``` +executable("hello_world") { + sources = [ + "src/helloworld.c" + ] + + include_dirs = [ + "include" + ] +} +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- “executable”是gn内置模板,可以用“gn help executable ”查看使用方法。 +>- “sources ”是源码路径,“include\_dirs ”是头文件路径。 + +## 执行编译 + +在当前文件夹下,执行编译命令: + +``` +hpm build +``` + +在完成一系列的编译动作后,显示build succeed。检查编译的输出结果: + +![](figure/zh-cn_image_0000001051770876.png) + +## 定义发行版 + +发行版是将一组组件组合起来的,编译生成可以运行的OpenHarmony解决方案,里面包含了较多依赖的组件,以及以脚本形式描述如何完整编译、链接这些组件。 + +## 定义脚本 + +bundle.json中定义 + +``` +{ +"name": "my_dist", +"version": "1.0.0", +"publishAs": "distribution", +"scripts": { +"dist": "make -${args}" + }, +"base": { +"name": "dist-bundle", +"version": "1.0.0" + }, +"envs": { +"args": "x86" + }, +"dependencies": { +} +} +``` + +## 发行 + +在当前发行版根目录下,执行如下命令。 + +``` +hpm dist +``` + +hpm-cli工具会自动执行编译,打包操作,将根据scripts定义的dist脚本生成镜像文件,如: + +``` +out +|-xxdist.img +|-xx.file +``` + +## 烧录 + +发行版的编译结果可以烧录到设备中运行,例如使用hiburn工具进行烧录。在发行版的bundle.json文件配置烧录参数。 + +``` +"scripts": { +"flash": "{$DEP_HIBURN}/hiburn" +}, +``` + +配置烧录相关的参数(参考烧录工具的说明进行配置)。 + +``` +hpm run flash +``` + +## 运行调试 + +将发行版的镜像烧录到设备中后,就可以启动运行调试了,由于运行调试和具体的开发板和IDE调试工具相关,此处不再详细描述。 + diff --git a/zh-cn/device-dev/bundles/bundles-guide-overview.md b/zh-cn/device-dev/bundles/bundles-guide-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..332a8fc00782f0ca9db5bbe4668e3ad6d68f38ef --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-guide-overview.md @@ -0,0 +1,54 @@ +# 概述 + +本章节将简要介绍如何开发OpenHarmony组件和发行版,并通过命令行工具方式完成组件创建、开发、编译、烧录、调试等开发过程。 + +- 一个组件(bundle)通常和一个代码仓库对应,在代码的基础上增加bundle.json、README文件、LICENSE描述文件。 +- 一个发行版(distribution)是由多个组件构成的。发行版中集合了一个完整系统的各种组件(如驱动、内核、框架、应用),可以用于设备的烧录。 + +**表 1** 组件和发行版的差异对比 + + + + + + + + + + + + + + + + + + + + + + + + +

异同点

+

组件

+

发行版

+

应用场景

+

面向功能特性开发

+

面向系统开发

+

内容

+

功能或特性的实现代码或二进制库

+

依赖的组件清单及编译构建脚本

+

完整程度

+

操作系统的一部分

+

一个完整操作系统版本

+

编译后结果

+

组件包

+

系统镜像

+
+ +**图 1** 组件和发行版的构成 + + +![](figure/组件0924.png) + diff --git a/zh-cn/device-dev/bundles/bundles-guide-prepare.md b/zh-cn/device-dev/bundles/bundles-guide-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..4068e7d7bee57afd03cd3098b97e923dc16edb66 --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-guide-prepare.md @@ -0,0 +1,84 @@ +# 准备工作 + +- [硬件要求](#section98535485518) +- [安装Node.js和hpm命令行工具](#section106591616205311) +- [更改hpm的配置(可选)](#section71821165412) +- [下载OpenHarmony代码](#section102338221707) +- [安装开发依赖的组件](#section19233183315020) + +## 硬件要求 + +- 准备设备开发的开发板(如Hi3861、Hi3516DV300、Hi3518EV300) +- 主机电脑(Windows工作台) +- Linux服务器 + +**图 1** 硬件环境连接关系 +![](figure/硬件环境连接关系.png "硬件环境连接关系") + +## 安装Node.js和hpm命令行工具 + +1. 安装Node.js。 + + 从官网下载并在本地安装Node.js. + + 推荐安装 [Node.js](https://nodejs.org/) 12.x \(包含 npm 6.14.4\)或更高版本 \(推荐 12.13.0+\)。 + +2. 通过Node.js自带的npm安装hpm-cli命令行工具。执行以下命令: + + ``` + npm install -g @ohos/hpm-cli + ``` + +3. 安装完成后执行如下命令,显示hpm版本,即安装成功。 + + ``` + hpm -V 或 hpm --version + ``` + +4. (可选)如果需要升级hpm版本,请执行如下命令: + + ``` + npm update -g @ohos/hpm-cli + ``` + + +## 更改hpm的配置(可选) + +安装完hpm-cli命令行工具后,执行以下命令可以查看hpm配置: + +``` +hpm config +``` + +上述命令执行后将会显示hpm的默认配置,您可以根据自己的喜好对默认配置进行修改,以下是hpm的常用配置: + +``` +registry = https://hpm.harmonyos.com/hpm/registry/api # hpm注册中心地址,下载组件必须 +login = https://hpm.harmonyos.com/hpm/auth/pk # hpm处理登录地址,发布组件必须 +loginUser = {your-account} # 配置hpm登录账号,发布组件必须 +shellPath = C:\WINDOWS\System32\cmd.exe # hpm命令执行使用的shell +globalRepo = C:\Users\yourname\.global # 配置全局安装的组件存放路径 +http_proxy = http://your-proxy-server:port # 配置HTTP代理 +https_proxy = http://your-proxy-server:port # 配置HTTPS代理 +``` + +hpm-cli的命令介绍可以参考:[hpm操作命令](bundles-guide-overview.md) + +## 下载OpenHarmony代码 + +参考[《源码获取》](../get-code/sourcecode-acquire.md)。 + +## 安装开发依赖的组件 + +hpm包管理器将常用开发开发工具(如烧录,编译,压缩等)也发布成了组件。可以通过如下命令方式进行安装,执行完该命令后,系统会自动将开发依赖的工具下载安装,且这些组件只需全局安装一次。 + +``` +hpm i -g @ohos/llvm +hpm i -g @ohos/ninja +hpm i -g @ohos/gn +hpm i -g @ohos/hc_gen +hpm i -g @ohos/sysroot +``` + +这是一组开发工具的组件包(如包含gn,ninja等工具),有了这些开发态的组件,就可以进行常规的源码组件的开发了。 + diff --git a/zh-cn/device-dev/bundles/bundles-guide.md b/zh-cn/device-dev/bundles/bundles-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..ca5ee5824bee855bc41e9c5d0bf758fee2e29041 --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-guide.md @@ -0,0 +1,9 @@ +# 组件开发指南 + +- **[概述](bundles-guide-overview.md)** + +- **[准备工作](bundles-guide-prepare.md)** + +- **[组件开发](bundles-guide-develop.md)** + + diff --git a/zh-cn/device-dev/bundles/bundles-standard-rules.md b/zh-cn/device-dev/bundles/bundles-standard-rules.md new file mode 100644 index 0000000000000000000000000000000000000000..350c2f80db60eba6fe7f2a4b1adf5b304ff5e8b8 --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles-standard-rules.md @@ -0,0 +1,549 @@ +# 组件开发规范 + +- [概述](#section1725818533344) + - [定义](#section4821219183514) + - [组件划分原则](#section1089794263513) + - [组件依赖](#section25701647163710) + +- [组件构成](#section185538333914) + - [代码文件](#section8431268393) + - [说明文件](#section168121548173914) + - [元数据描述文件](#section7107181819406) + +- [组件管理](#section32061634104110) + - [依赖关系](#section791115242423) + - [hpm操作命令参考](#section1183205411429) + +- [组件版本](#section12612142864316) + - [版本号命名规范](#section1487612416432) + - [版本发布](#section1548171014440) + +- [发行版](#section1264139114413) +- [环境变量说明](#section15352105174512) + +## 概述 + +本文档将介绍组件的基本概念以及如何按照规范定义组件。 + +### 定义 + +OpenHarmony软件以组件\(bundle\)作为基本单元,从系统角度看,凡是运行在OpenHarmony上的软件都可以定义为组件;一般来讲,根据组件的应用范围,可以分为: + +- 板级组件:如board、arch、mcu这些与设备硬件相关的组件。 +- 系统组件:一组独立功能的集合,如内核、文件系统、框架等。 +- 应用组件:直接面向用户提供服务的应用\(如wifi\_iot,ip\_camera\)。 + +从形式上看,组件是为复用而生,一切可以复用的模块都可以定义为组件,可以分为: + +- 源代码 +- 二进制 +- 代码片段 +- 发行版 + +### 组件划分原则 + +原则上应尽可能划分为细颗粒度的组件,以满足最大限度的复用。主要考虑以下几点: + +- 独立性:组件的功能应该相对独立,支持独立编译,可以单独对外提供接口和服务; +- 耦合性:如果组件必须依赖其他的组件,才能对外提供服务,应考虑和被依赖的组件合并为一个组件。 +- 相关性:如果一组组件共同完成一项功能,且没有被其他组件依赖,未来也没有被依赖的可能,则可以考虑合并为一个组件。 + +### 组件依赖 + +组件的依赖关系分为两种:必选依赖和可选依赖。 + +- 必选依赖:是指组件A在完成某个功能时,必须引入组件B,调用B的接口或服务配合才能完成。称B为A的必选依赖。 +- 可选依赖:是在组件A在完成某个功能时,可以引入组件C,也可以引入组件D。C和D可以相互替换,称C和D为A的可选依赖。 + +## 组件构成 + +一个组件包一般包含如下内容: + +- 组件包的代码或库(src目录下的代码文件) +- ohos\_bundles文件夹(存放依赖的组件,安装组件时自动生成,无需提交到代码库) +- 组件包的说明文件\(README.md\) +- 组件包元数据声明文件\(bundle.json\) +- 开源许可文件\(LICENSE\) + + ``` + my-bundle + |_ohos_bundles + |_src + |_bundle.json + |_README.md + |_LICENSE + ``` + + +### 代码文件 + +组件的代码文件和普通的代码目录没有差异。但要注意的是,组件中对外暴露的接口(头文件),会被其他组件所引用,需要单独在bundle.json的dirs中声明。 + +### 说明文件 + +README.md,为markdown格式的描述关于组件自述说明文件。([语法参考](https://www.markdownguide.org/getting-started/)\) + +为了帮助他人在hpm上找到该组件,并更方便的使用它,在组件的根目录中包含一个README文件。 + +README文件可能包括如何安装,配置和使用组件包中的实例代码说明,以及可能会对用户有所帮助的任何其他信息。 + +每个组件的自述文件将显示在hpm系统的组件详情页面的描述中。 + +### 元数据描述文件 + +bundle.json文件是对当前组件的元数据描述,每个组件中必须包含一个bundle.json文件。 + +``` +{ + "name": "@myorg/demo-bundle", + "version": "1.0.0", + "license": "MIT", + "description": "bundle description", + "keywords": ["hos"], + "tags": ["applications", "drivers"], + "author": {"name":"","email":"","url":""}, + "contributors":[{"name":"","email":"","url":""},{"name":"","email":"","url":""}], + "homepage": "http://www.foo.bar.com", + "repository": "https://git@gitee.com:foo/bar.git", + "publishAs": "code-segment", + "segment":{ + "destPath":"/the/dest/path" + }, + "dirs": { + "src": ["src/**/*.c"], + "headers": ["headers/**/*.h"], + "bin": ["bin/**/*.o"] + }, + "scripts": { + "build": "make" + }, + "envs": {}, + "ohos": { + "os": "2.0.0", + "board": "hi3516", + "kernel": "liteos-a" + }, + "rom": "10240", + "ram": "1024", + "dependencies": { + "@myorg/net":"1.0.0" + } +} +``` + +bundle.json文件具有如下功能: + +- name:定义组件的名称,放到组织下, 以@开头,/分割,如:@myorg/mybundle + +- version:定义组件版本号,如1.0.0,需满足semver的标准。 + +- description:一句话对组件进行简要的描述。 +- dependencies:定义组件的依赖组件。 + +- envs: 定义组件编译时所需要的参数,包括全局参数以及依赖所需的参数。 + +- scripts:定义在当前组件下能够执行的命令(如编译,构建,测试,烧录等)。 + +- publishAs:定义组件的发布类型(source:源码,binary:二进制,distribution:发行版,code-segment:代码片段)。 + +- segment: 仅针对code-segment类型的组件,定义组件的目标路径(即安装后,组件包中包含的文件复制到的目标路径) +- dirs:定义发布时打包的目录结构(如头文件)。 + +- ram&rom:统计相关信息:预计占用ROM和RAM信息。 +- ohos:描述OpenHarmony系统版本、开发板及内核的匹配关系(多个请用英文逗号的“,”分割)。 +- 定义其他扩展信息:作者,主页,代码仓库,许可协议,标签,关键字。 +- 对于发行版类型,还有个base,可以定义继承自的发行版。 + +## 组件管理 + +### 依赖关系 + +生成基础bundle.json以后,需要继续添加组件依赖来实现更复杂的功能。此时需要知道所依赖组件的名称和版本号,并且把它们定义在bundle.json里面的dependencies字段中。 + +``` +{ + "name": "my-bundle", + "version": "1.0.0", + "dependencies": { + "net": "1.0.0" + } +} +``` + +上述示例中,my-bundle组件依赖于net 1.0.0组件。在全局安装了 hpm CLI 工具之后,执行如下命令可以从远端仓库获取到依赖: + +``` +hpm install +``` + +依赖获取以后,会保存到当前组件根目录下到ohos\_bundles文件夹中。组件以及依赖之间会形成一个依赖关系的树状结构。全局安装了 hpm CLI 工具之后,在组件根目录下执行如下命令: + +``` +username@server MINGW64 /f/showcase/demo/demo +$ hpm list ++--demo@1.0.0 +| +--@huawei/media@1.0.2 +| +--@demo/sport_hi3518ev300_liteos_a@1.0.0 +| | +--@demo/app@4.0.1 +| | | +--@demo/build@4.0.1 +| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 +| | +--@demo/liteos_a@4.0.0 +| | | +--@demo/third_party_fatfs@4.0.0 +| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 +| | +--@demo/init@4.0.0 +| | +--@demo/dist_tools@4.0.0 +``` + +还可以使用可视化的形式,来查看当前组件的依赖关系,执行如下命令: + +``` +hpm ui +``` + +会在本地启动一个web服务(默认会打开浏览器并进入项目页),点击侧边栏的项目依赖图标,打开页面,可以看到项目的依赖组件列表,点击右侧按钮切换到树状视图,就可以看到依赖关系的图形化展示\(如下图\)。 + +**图 1** 组件包依赖关系图 + + +![](figure/zh-cn_image_0000001173313501.png) + +### hpm操作命令参考 + +组件的全生命周期管理,可以通过hpm命令工具进行操作,hpm的操作命令如下(详细帮助可以执行 hpm -h学习): + +**表 1** hpm操作命令 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令类别

+

命令行

+

含义说明

+

版本查询

+

hpm -V 或 hpm --version

+

查看hpm-cli 版本号。

+

帮助查询

+

hpm -h 或 hpm --version

+

查看命令列表及帮助。

+

hpm -h

+

查看命令帮助。

+

创建

+

+

hpm init bundle

+

创建组件工程。

+

hpm init -t template

+

根据模板创建脚手架工程。

+

安装

+

+

hpm install 或hpm i

+

安装bundle.json中依赖的组件。

+

hpm install bundle@version

+

安装指定组件版本。

+

卸载

+

+

hpm uninstall bundle

+

删除depedencies依赖的组件。

+

hpm remove 或hpm rm bundlename

+

删除depedencies依赖的组件。

+

查看

+

+

hpm list 或者 hpm ls

+

显示当前组件/发行版所有的组件树。

+

hpm dependencies

+

生成当前组件/发行版依赖关系数据(在hpm ui也集成了该命令的调用,可以图形化的展示)

+

搜索

+

hpm search name

+

搜索组件,--json,可以以json格式输出 -type 可以设置搜索组件的类型,包括bundle,distribution,code-segment三种。

+

设置hpm配置项

+

hpm config set key value

+

设置配置值,如服务器地址,网络代理。

+

hpm config delete key

+

删除配置。

+

更新

+

+

hpm update

+

更新当前组件依赖的组件的版本。

+

hpm check-update

+

检查依赖的组件版本是否有更新。

+

编译

+

+

hpm build

+

编译组件/发行版。

+

hpm dist

+

针对发行版(distribution),发行版编译构建(依赖bundle.json的scripts中的dist脚本)。

+

打包

+

hpm pack

+

本地组件打包依赖。

+

烧录

+

hpm run flash

+

烧录固件(依赖bundle.json的scripts中的flash脚本)。

+

发布

+

hpm publish

+

发布组件,发布的组件在仓库中必须唯一,且版本唯一(需要账号登录)。

+

执行扩展命令

+

hpm run

+

执行bundle.json文件中定义的scripts脚本命令,支持多个命令可用 && 连接。

+

解压包

+

hpm extract

+

解压文件. 支持格式'zip','tar','tgz' 和'.tar.gz'

+

启动图形化界面

+

hpm ui

+

本地启动HPM UI,可通过-p参数指定端口,Windows平台下会启动默认的浏览器打开

+

多语言切换

+

hpm lang

+

切换中英文操作界面(同时支持命令行和UI)

+

转换为hpm包格式

+

hpm x2h

+

将一个maven格式或npm格式包转换成hpm的包格式,并发布到HPM

+

代码段还原或清理

+

hpm code clean|restore

+

针对依赖的代码段(code-segment)组件,执行清理或还原操作(即根据segment.destPath执行拷贝/删除操作)

+

生成秘钥

+

hpm gen-keys

+

生成公钥/私钥对,将公钥配置到HPM服务端,可以实现hpm-cli 免密登录,发布组件。

+

生成第三方开源说明

+

hpm gen-notice

+

根据每个组件的说明,生成一份合并后的第三方开源说明的合并文件。

+
+ +## 组件版本 + +### 版本号命名规范 + +名称需要为全小写字母,中间可以使用中划线或者下划线分隔。比如 "bundle", "my\_bundle"。 + +版本号的格式为 "主版本号.次版本号.修订号" 或 "主版本号.次版本号.修订号-先行版本号",比如 "1.0.0", "1.0.0-beta",详细规格可以参考 [https://semver.org](https://semver.org/)。 + +### 版本发布 + +为了使组件能被其他开发者使用,组件需要上传到远端仓库。组件上传使用如下命令: + +``` +hpm publish +``` + +命令执行以后,系统会对的整个依赖关系进行检查,下载缺失依赖组件。依赖检查完成后,如果发布类型为binary,系统会对整个组件进行编译,生成二进制文件,然后打包上传。如果使其他上传类型,则直接根据定义的打包规则进行打包,然后上传。 + +注意:发布组件需要用户账号登录,需要先拥有hpm的系统账号后,并注册组织,申请组织认证通过后,才拥有发布的权限。 + +## 发行版 + +发行版通常是将一系列组件组合起来,成为编译可以运行的OpenHarmony解决方案镜像,里面包含了多个依赖的组件,以及脚本,用于描述如何完整编译、链接这些组件。 + +发行版本身通常不需要包含功能实现代码,仅包含bundle.json描述(设置publishAs为distribution)和一些编译脚本组成。 + +因为发行版编译的过程需要系统提供环境变量,所以发行版使用scripts脚本中内置的dist命令: + +``` +{ + "publishAs":"distribution", + "scripts": { + "dist": "script compile command" + } +} +``` + +编译执行使用如下命令: + +``` +hpm dist +``` + +重新定义一个发行版所具有的功能是一个复杂的过程,所以系统允许对发行版进行继承,从而在现有功能的基础上进行定制。继承发行版需要在bundle.json中定义base字段。 + +``` +{ + "base": { + "name": "dist_wifi_iot", + "version": "1.0.0" + } +} +``` + +上述定义表明当前组件继承自发行版组件dist-wifi-iot 1.0.0。 + +发行版由很多的依赖组件组成,通过bundle.json中的dependencies段来描述,有些依赖是必须的,有些依赖则是根据可以需求增加或删除的。bundle.json中名称前带有?的依赖表示可选依赖,继承它的发行版,可以移除掉该可选组件,再增加别的组件进行替换。 + +``` +{ + "dependencies": { + "?my_bundle": "1.0.0" + } +} +``` + +上述声明表示my\_bundle依赖可以被移除。如果想要移除my\_bundle,在上层依赖方需要使用excludes关键字来进行定义 + +``` +{ + "excludes": [ "my_bundle" ] +} +``` + +依赖被移除后,就不会参入组件的构建过程。只有标记为可选的依赖才能够被移除,强行移除未被标记的依赖会出现错误提示。 + +## 环境变量说明 + +组件在编译的过程中需要依赖系统提供的环境变量来自定义输出,链接所需二进制文件等等。这里提出的环境变量均指根据需求把所需变量注入脚本执行的上下文中。所以在脚本中可以直接获取到变量的值。下面介绍当前系统存在的几种环境变量。 + +全局变量由bundle.json中的envs属性来定义。整个组件中的依赖都可以获取到全局变量定义的值。 + +``` +{ + "envs": { + "compileEnv": "arm" + } +} +``` + +不同组件在引入依赖的过程中可以传入不同的参数,从而使依赖的编译可以满足当前组件的需求。依赖中定义的参数可以在对应依赖脚本执行的上下文中获取到。 + +``` +{ + "dependencies": { + "my-bundle": { + "version": "1.0.0", + "mode": "debug" + } + } +} +``` + +组件在链接二进制文件的时候,需要知道二进制文件在依赖中的路径,所以依赖的路径会作为环境变量传入编译组件中。 + +传入的环境变量的格式为DEP\_BundleName,BundleName为依赖的名称,例如 DEP\_first\_bundle。 + +依赖中可以定义标签,对引入的依赖进行分组。在脚本中可以根据标签,获得这一组依赖的路径。定义的标签以\#开头,具体定义的方式为: + +``` +{ + "dependencies": { + "#tool": { + "first-bundle": "1.0.0", + "second-bundle": "1.0.0" + }, + "#drivers": { + "xx-bundle": "1.0.0", + "yy-bundle": "1.0.0" + } + } +} +``` + +系统中存在两个固定环境变量: + +- DEP\_OHOS\_BUNDLES:表示ohos\_bundles文件夹所在的路径。 +- DEP\_BUNDLE\_BASE:表示最外层组件的路径。 + diff --git a/zh-cn/device-dev/bundles/bundles.md b/zh-cn/device-dev/bundles/bundles.md new file mode 100644 index 0000000000000000000000000000000000000000..9c560fca9d5b6ac9381ebc8dbc3a11de2eaba84b --- /dev/null +++ b/zh-cn/device-dev/bundles/bundles.md @@ -0,0 +1,9 @@ +# 组件开发指南 + +- **[组件开发规范](bundles-standard-rules.md)** + +- **[组件开发指南](bundles-guide.md)** + +- **[组件开发示例](bundles-demo.md)** + + diff --git "a/zh-cn/device-dev/bundles/figures/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212.png" "b/zh-cn/device-dev/bundles/figure/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212-21.png" similarity index 100% rename from "zh-cn/device-dev/bundles/figures/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212.png" rename to "zh-cn/device-dev/bundles/figure/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212-21.png" diff --git a/zh-cn/device-dev/bundles/figures/zh-cn_image_0000001051452177.png b/zh-cn/device-dev/bundles/figure/zh-cn_image_0000001051452177.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/bundles/figures/zh-cn_image_0000001051452177.png rename to zh-cn/device-dev/bundles/figure/zh-cn_image_0000001051452177.png diff --git a/zh-cn/device-dev/bundles/figures/zh-cn_image_0000001051770876.png b/zh-cn/device-dev/bundles/figure/zh-cn_image_0000001051770876.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/bundles/figures/zh-cn_image_0000001051770876.png rename to zh-cn/device-dev/bundles/figure/zh-cn_image_0000001051770876.png diff --git a/zh-cn/device-dev/bundles/figure/zh-cn_image_0000001173313501.png b/zh-cn/device-dev/bundles/figure/zh-cn_image_0000001173313501.png new file mode 100644 index 0000000000000000000000000000000000000000..bc682a3dbd7e3de6a83a7292d9c6942c43909c98 Binary files /dev/null and b/zh-cn/device-dev/bundles/figure/zh-cn_image_0000001173313501.png differ diff --git "a/zh-cn/device-dev/bundles/figure/\347\241\254\344\273\266\347\216\257\345\242\203\350\277\236\346\216\245\345\205\263\347\263\273.png" "b/zh-cn/device-dev/bundles/figure/\347\241\254\344\273\266\347\216\257\345\242\203\350\277\236\346\216\245\345\205\263\347\263\273.png" new file mode 100644 index 0000000000000000000000000000000000000000..c4636401a20e37794d8ec28dc173e9308b2b72db Binary files /dev/null and "b/zh-cn/device-dev/bundles/figure/\347\241\254\344\273\266\347\216\257\345\242\203\350\277\236\346\216\245\345\205\263\347\263\273.png" differ diff --git "a/zh-cn/device-dev/bundles/figures/\347\273\204\344\273\2660924.png" "b/zh-cn/device-dev/bundles/figure/\347\273\204\344\273\2660924.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/bundles/figures/\347\273\204\344\273\2660924.png" rename to "zh-cn/device-dev/bundles/figure/\347\273\204\344\273\2660924.png" diff --git "a/zh-cn/device-dev/bundles/figures/\347\273\204\344\273\266\345\214\205\344\276\235\350\265\226\345\205\263\347\263\273\345\233\276.png" "b/zh-cn/device-dev/bundles/figures/\347\273\204\344\273\266\345\214\205\344\276\235\350\265\226\345\205\263\347\263\273\345\233\276.png" deleted file mode 100755 index 1b936a2cbc95d3f9d7ddab0187305c3d0c486b0a..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/bundles/figures/\347\273\204\344\273\266\345\214\205\344\276\235\350\265\226\345\205\263\347\263\273\345\233\276.png" and /dev/null differ diff --git a/zh-cn/device-dev/bundles/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/bundles/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/bundles/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/bundles/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/bundles/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/bundles/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/bundles/public_sys-resources/icon-note.gif b/zh-cn/device-dev/bundles/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/bundles/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/bundles/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/bundles/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/bundles/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/bundles/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/bundles/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/bundles/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/bundles/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/bundles/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/bundles/public_sys-resources/icon-warning.gif and /dev/null differ diff --git "a/zh-cn/device-dev/bundles/\345\207\206\345\244\207\345\267\245\344\275\234.md" "b/zh-cn/device-dev/bundles/\345\207\206\345\244\207\345\267\245\344\275\234.md" deleted file mode 100755 index 981e7e299a86af578bde9dfdb0e7807acfad0aa8..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\345\207\206\345\244\207\345\267\245\344\275\234.md" +++ /dev/null @@ -1,84 +0,0 @@ -# 准备工作 - -- [硬件要求](#section98535485518) -- [安装Node.js和hpm命令行工具](#section106591616205311) -- [更改hpm的配置(可选)](#section71821165412) -- [下载OpenHarmony代码](#section102338221707) -- [安装开发依赖的组件](#section19233183315020) - -## 硬件要求 - -- 准备设备开发的开发板(如Hi3861、Hi3516DV300、Hi3518EV300) -- 主机电脑(Windows工作台) -- Linux服务器 - -**图 1** 硬件环境连接关系 -![](figures/硬件环境连接关系.png "硬件环境连接关系") - -## 安装Node.js和hpm命令行工具 - -1. 安装Node.js。 - - 从官网下载并在本地安装Node.js. - - 推荐安装 [Node.js](https://nodejs.org/) 12.x \(包含 npm 6.14.4\)或更高版本 \(推荐 12.13.0+\)。 - -2. 通过Node.js自带的npm安装hpm-cli命令行工具。执行以下命令: - - ``` - npm install -g @ohos/hpm-cli - ``` - -3. 安装完成后执行如下命令,显示hpm版本,即安装成功。 - - ``` - hpm -V 或 hpm --version - ``` - -4. (可选)如果需要升级hpm版本,请执行如下命令: - - ``` - npm update -g @ohos/hpm-cli - ``` - - -## 更改hpm的配置(可选) - -安装完hpm-cli命令行工具后,执行以下命令可以查看hpm配置: - -``` -hpm config -``` - -上述命令执行后将会显示hpm的默认配置,您可以根据自己的喜好对默认配置进行修改,以下是hpm的常用配置: - -``` -registry = https://hpm.harmonyos.com/hpm/registry/api # hpm注册中心地址,下载组件必须 -login = https://hpm.harmonyos.com/hpm/auth/pk # hpm处理登录地址,发布组件必须 -loginUser = {your-account} # 配置hpm登录账号,发布组件必须 -shellPath = C:\WINDOWS\System32\cmd.exe # hpm命令执行使用的shell -globalRepo = C:\Users\yourname\.global # 配置全局安装的组件存放路径 -http_proxy = http://your-proxy-server:port # 配置HTTP代理 -https_proxy = http://your-proxy-server:port # 配置HTTPS代理 -``` - -hpm-cli的命令介绍可以参考:[hpm操作命令](组件管理.md) - -## 下载OpenHarmony代码 - -参考[《源码获取》](../get-code/源码获取.md) - -## 安装开发依赖的组件 - -hpm包管理器将常用开发开发工具(如烧录,编译,压缩等)也发布成了组件。可以通过如下命令方式进行安装,执行完该命令后,系统会自动将开发依赖的工具下载安装,且这些组件只需全局安装一次。 - -``` -hpm i -g @ohos/llvm -hpm i -g @ohos/ninja -hpm i -g @ohos/gn -hpm i -g @ohos/hc_gen -hpm i -g @ohos/sysroot -``` - -这是一组开发工具的组件包(如包含gn,ninja等工具),有了这些开发态的组件,就可以进行常规的源码组件的开发了。 - diff --git "a/zh-cn/device-dev/bundles/\345\217\221\350\241\214\347\211\210.md" "b/zh-cn/device-dev/bundles/\345\217\221\350\241\214\347\211\210.md" deleted file mode 100755 index 00640e559945546ce8b17badb65e388934290751..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\345\217\221\350\241\214\347\211\210.md" +++ /dev/null @@ -1,56 +0,0 @@ -# 发行版 - -发行版通常是将一系列组件组合起来,成为编译可以运行的OpenHarmony解决方案镜像,里面包含了多个依赖的组件,以及脚本,用于描述如何完整编译、链接这些组件。 - -发行版本身通常不需要包含功能实现代码,仅包含bundle.json描述(设置publishAs为distribution)和一些编译脚本组成。 - -因为发行版编译的过程需要系统提供环境变量,所以发行版使用scripts脚本中内置的dist命令: - -``` -{ - "publishAs":"distribution", - "scripts": { - "dist": "script compile command" - } -} -``` - -编译执行使用如下命令: - -``` -hpm dist -``` - -重新定义一个发行版所具有的功能是一个复杂的过程,所以系统允许对发行版进行继承,从而在现有功能的基础上进行定制。继承发行版需要在bundle.json中定义base字段。 - -``` -{ - "base": { - "name": "dist_wifi_iot", - "version": "1.0.0" - } -} -``` - -上述定义表明当前组件继承自发行版组件dist-wifi-iot 1.0.0。 - -发行版由很多的依赖组件组成,通过bundle.json中的dependencies段来描述,有些依赖是必须的,有些依赖则是根据可以需求增加或删除的。bundle.json中名称前带有?的依赖表示可选依赖,继承它的发行版,可以移除掉该可选组件,再增加别的组件进行替换。 - -``` -{ - "dependencies": { - "?my_bundle": "1.0.0" - } -} -``` - -上述声明表示my\_bundle依赖可以被移除。如果想要移除my\_bundle,在上层依赖方需要使用excludes关键字来进行定义 - -``` -{ - "excludes": [ "my_bundle" ] -} -``` - -依赖被移除后,就不会参入组件的构建过程。只有标记为可选的依赖才能够被移除,强行移除未被标记的依赖会出现错误提示。 - diff --git "a/zh-cn/device-dev/bundles/\346\223\215\344\275\234\345\256\236\344\276\213.md" "b/zh-cn/device-dev/bundles/\346\223\215\344\275\234\345\256\236\344\276\213.md" deleted file mode 100755 index d49c4267cc6a997708e0018a61fded11f6bdb2bd..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\346\223\215\344\275\234\345\256\236\344\276\213.md" +++ /dev/null @@ -1,54 +0,0 @@ -# 操作实例 - -环境准备好后,接下来本文以Hi3861平台为例,演示如何利用HPM进行组件的安装、编译和打包。 - -1. 执行以下命令,初始化安装目录(目录名可自行设置): - - ``` - mkdir test3861 - cd test3861 - hpm init -t dist - ``` - - 初始化成功则显示: - - ``` - Initialization finished. - ``` - -2. 安装wifi\_iot发行版。 - - ``` - hpm install @ohos/wifi_iot - ``` - - 安装成功则显示: - - ``` - Installed. - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >Hi3516平台采用下述命令: - >``` - >hpm install @ohos/ip_camera_hi3516dv300 - >``` - >Hi3518平台采用下述命令: - >``` - >hpm install @ohos/ip_camera_hi3518ev300 - >``` - -3. 编译打包 - - ``` - hpm dist - ``` - - 编译成功会显示: - - ``` - {{name}}: distribution building completed. - ``` - -4. 上述所有命令执行成功后,在 ./out 目录下会生成编译结果,开发者可以将编译结果烧录到对应的开发板上进行测试。 - diff --git "a/zh-cn/device-dev/bundles/\346\246\202\350\277\260-0.md" "b/zh-cn/device-dev/bundles/\346\246\202\350\277\260-0.md" deleted file mode 100755 index 758ec2fb9fd0d18aa4df95bfc0355d7c307429ef..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\346\246\202\350\277\260-0.md" +++ /dev/null @@ -1,54 +0,0 @@ -# 概述 - -本章节将简要介绍如何开发OpenHarmony组件和发行版,并通过命令行工具方式完成组件创建、开发、编译、烧录、调试等开发过程。 - -- 一个组件(bundle)通常和一个代码仓库对应,在代码的基础上增加bundle.json、README文件、LICENSE描述文件。 -- 一个发行版(distribution)是由多个组件构成的。发行版中集合了一个完整系统的各种组件(如驱动、内核、框架、应用),可以用于设备的烧录。 - -**表 1** 组件和发行版的差异对比 - - - - - - - - - - - - - - - - - - - - - - - - -

异同点

-

组件

-

发行版

-

应用场景

-

面向功能特性开发

-

面向系统开发

-

内容

-

功能或特性的实现代码或二进制库

-

依赖的组件清单及编译构建脚本

-

完整程度

-

操作系统的一部分

-

一个完整操作系统版本

-

编译后结果

-

组件包

-

系统镜像

-
- -**图 1** 组件和发行版的构成 - - -![](figures/组件0924.png) - diff --git "a/zh-cn/device-dev/bundles/\346\246\202\350\277\260.md" "b/zh-cn/device-dev/bundles/\346\246\202\350\277\260.md" deleted file mode 100755 index 2eea128f92a994c5b63625ee824d4bf4abc14fc1..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\346\246\202\350\277\260.md" +++ /dev/null @@ -1,38 +0,0 @@ -# 概述 - -- [定义](#section177563344911) -- [组件划分原则](#section2487162541016) -- [组件依赖](#section185955409107) - -本文档将介绍组件的基本概念以及如何按照规范定义组件。 - -## 定义 - -OpenHarmony软件以组件\(bundle\)作为基本单元,从系统角度看,凡是运行在OpenHarmony上的软件都可以定义为组件;一般来讲,根据组件的应用范围,可以分为: - -- 板级组件:如board、arch、mcu这些与设备硬件相关的组件。 -- 系统组件:一组独立功能的集合,如内核、文件系统、框架等。 -- 应用组件:直接面向用户提供服务的应用\(如wifi\_iot,ip\_camera\)。 - -从形式上看,组件是为复用而生,一切可以复用的模块都可以定义为组件,可以分为: - -- 源代码 -- 二进制 -- 代码片段 -- 发行版 - -## 组件划分原则 - -原则上应尽可能划分为细颗粒度的组件,以满足最大限度的复用。主要考虑以下几点: - -- 独立性:组件的功能应该相对独立,支持独立编译,可以单独对外提供接口和服务; -- 耦合性:如果组件必须依赖其他的组件,才能对外提供服务,应考虑和被依赖的组件合并为一个组件。 -- 相关性:如果一组组件共同完成一项功能,且没有被其他组件依赖,未来也没有被依赖的可能,则可以考虑合并为一个组件。 - -## 组件依赖 - -组件的依赖关系分为两种:必选依赖和可选依赖。 - -- 必选依赖:是指组件A在完成某个功能时,必须引入组件B,调用B的接口或服务配合才能完成。称B为A的必选依赖。 -- 可选依赖:是在组件A在完成某个功能时,可以引入组件C,也可以引入组件D。C和D可以相互替换,称C和D为A的可选依赖。 - diff --git "a/zh-cn/device-dev/bundles/\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/zh-cn/device-dev/bundles/\347\216\257\345\242\203\345\207\206\345\244\207.md" deleted file mode 100755 index d4d5662f297230dcd45cd8706b239be7fada4e65..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\216\257\345\242\203\345\207\206\345\244\207.md" +++ /dev/null @@ -1,139 +0,0 @@ -# 环境准备 - -- [linux服务器](#section20979554791) -- [安装Node.js](#section9954105413153) -- [安装HPM](#section15937194904819) -- [安装python环境](#section1621819180417) -- [安装文件打包工具](#section77617165913) -- [安装SCons](#section20558439191516) - -## linux服务器 - -准备一台装有Ubuntu 16.04 及以上 64 位系统的linux服务器(hpm是支持windows的,但是目前OpenHarmony开源的Hi3861、Hi3516、Hi3518三个解决方案都只支持Ubuntu)。 - -将linux shell改为bash: - -``` -ls -l $(which sh) -# 如果指向的不是bash,则按以下方式修改: -# 方法一:执行以下命令,然后选择no -dpkg-reconfigure dash -# 方法二:先删除sh,再重新创建软连接 -rm -f /bin/sh -ln -s bash /bin/sh -``` - -## 安装Node.js - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果配置的源的nodejs版本太低,可以执行以下语句后再执行apt-get install: ->``` ->curl -L https://deb.nodesource.com/setup_12.x | bash ->``` - -推荐安装 Node.js 12.x (包含 npm 6.14.4)或更高版本(推荐 12.13.0+): - -``` -sudo apt-get install nodejs -sudo apt-get install npm -``` - -查看版本: - -``` -node --version # 查看nodejs版本 -npm --version # 查看npm版本 -``` - -## 安装HPM - -通过 Node.js 自带的 npm(使用默认的源 https://registry.npmjs.org/ )安装 hpm-cli 命令行工具: - -``` -npm install -g @ohos/hpm-cli -``` - -安装完hpm-cli命令行工具后,执行以下命令可以查看hpm配置: - -``` -hpm config -``` - -上述命令执行后将会显示hpm的默认配置,您可以根据自己的喜好对默认配置进行修改,以下是hpm的常用配置: - -``` -registry = https://hpm.harmonyos.com # hpm注册中心地址,下载组件必须 -strictSsl = true # 通过https连接时,是否需要校验证书 -http_proxy = http://your-proxy-server:port # 配置HTTP代理 -https_proxy = http://your-proxy-server:port # 配置HTTPS代理 -``` - -hpm-cli的命令介绍可以参考:[hpm操作命令](组件管理.md) - -## 安装python环境 - -需使用python3.7以上版本,采用以下命令进行安装: - -``` -sudo apt-get install python3.8 -sudo apt-get install python3-pip -sudo pip3 install setuptools -sudo pip3 install kconfiglib # 建议安装kconfiglib 13.2.0+版本 -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->上述方式适用Hi3518和Hi3516两种平台,针对Hi3861平台采用以下方式安装python环境: ->``` ->sudo apt-get install python3.8 ->sudo apt-get install python3-pip ->sudo pip3 install setuptools ->sudo pip3 install kconfiglib # 建议安装kconfiglib 13.2.0+版本 ->sudo pip3 install pycryptodome ->sudo pip3 install six --upgrade --ignore-installed six ->sudo pip3 install ecdsa ->``` - -如果当前系统中既存在python2又存在python3,参考以下方法将默认python修改为python3: - -``` -ll `which python` -rm /usr/bin/python -ln -s python3.8 /usr/bin/python -``` - -## 安装文件打包工具 - -采用以下命令进行安装: - -``` -which mkfs.vfat # 如果没找到,执行以下命令安装 -sudo apt-get install dosfstools -which mcopy # 如果没找到,执行以下命令安装 -sudo apt-get install mtools -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->Hi3518和Hi3516两种平台需要安装打包工具,Hi3861平台不需要。 - -## 安装SCons - -1. 打开Linux编译服务器终端。 -2. 运行如下命令,安装SCons安装包。 - - ``` - python3 -m pip install scons - ``` - -3. 运行如下命令,查看是否安装成功。如果安装成功,查询结果下图所示。 - - ``` - scons -v - ``` - - **图 1** SCons安装成功界面,版本要求3.0.4以上 - ![](figures/SCons安装成功界面-版本要求3-0-4以上.png "SCons安装成功界面-版本要求3-0-4以上") - - ->![](public_sys-resources/icon-note.gif) **说明:** ->Hi3861平台需要安装SCons,Hi3518和Hi3516两种平台不需要。 - diff --git "a/zh-cn/device-dev/bundles/\347\216\257\345\242\203\345\217\230\351\207\217\350\257\264\346\230\216.md" "b/zh-cn/device-dev/bundles/\347\216\257\345\242\203\345\217\230\351\207\217\350\257\264\346\230\216.md" deleted file mode 100755 index 1ebf8fb99e32dc1c0394271881de47afba0d47a4..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\216\257\345\242\203\345\217\230\351\207\217\350\257\264\346\230\216.md" +++ /dev/null @@ -1,53 +0,0 @@ -# 环境变量说明 - -组件在编译的过程中需要依赖系统提供的环境变量来自定义输出,链接所需二进制文件等等。这里提出的环境变量均指根据需求把所需变量注入脚本执行的上下文中。所以在脚本中可以直接获取到变量的值。下面介绍当前系统存在的几种环境变量。全局变量 - -全局变量由bundle.json中的envs属性来定义。整个组件中的依赖都可以获取到全局变量定义的值。 - -``` -{ - "envs": { - "compileEnv": "arm" - } -} -``` - -不同组件在引入依赖的过程中可以传入不同的参数,从而使依赖的编译可以满足当前组件的需求。依赖中定义的参数可以在对应依赖脚本执行的上下文中获取到。 - -``` -{ - "dependencies": { - "my-bundle": { - "version": "1.0.0", - "mode": "debug" - } - } -} -``` - -组件在链接二进制文件的时候,需要知道二进制文件在依赖中的路径,所以依赖的路径会作为环境变量传入编译组件中。 - -传入的环境变量的格式为DEP\_BundleName,BundleName为依赖的名称,例如 DEP\_first\_bundle。 - -依赖中可以定义标签,对引入的依赖进行分组。在脚本中可以根据标签,获得这一组依赖的路径。定义的标签以\#开头,具体定义的方式为: - -``` -{ - "dependencies": { - "#tool": { - "first-bundle": "1.0.0", - "second-bundle": "1.0.0" - }, - "#drivers": { - "xx-bundle": "1.0.0", - "yy-bundle": "1.0.0" - } - } -} -``` - -系统中存在两个固定环境变量: - -- DEP\_OHOS\_BUNDLES:表示ohos\_bundles文件夹所在的路径。 -- DEP\_BUNDLE\_BASE:表示最外层组件的路径。 - diff --git "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221.md" "b/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221.md" deleted file mode 100755 index 292c88d6d2cc329d255c12fe1d118009d84ee82d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221.md" +++ /dev/null @@ -1,241 +0,0 @@ -# 组件开发 - -- [创建OpenHarmony组件](#section1976410130540) -- [新建组件](#section717481119145) -- [改造组件](#section102861955201410) -- [从模板创建组件](#section15882846181510) -- [编译组件](#section136732148541) -- [定义编译脚本](#section10274147111610) -- [执行编译](#section879301916172) -- [定义发行版](#section413216495619) -- [定义脚本](#section11503171219190) -- [发行](#section4694125521912) -- [烧录](#section1746331545413) -- [运行调试](#section6742131615549) - -## 创建OpenHarmony组件 - -创建OpenHarmony组件有如下几种方式: - -- 从头开发一个全新的组件。 -- 将一个现有的非组件的代码改造成组件。 - -- hpm提供了一些组件模板方便快速创建组件。 - -## 新建组件 - -通常情况下,[HPM网站](https://hpm.harmonyOS.com)上能找到您开发常用的组件,如果现有的组件不能完全满足开发,这时可以自己动手开发一个组件。 - -如果您愿意,可以将组件发布到HPM的仓库中供其他用户使用。假设要在D:/source目录下新建一个全新的组件my-bundle: - -可以使用hpm init 创建该组件的脚手架代码,例如,进入D:/source目录,执行如下命令: - -``` -hpm init -t default -d demo my-bundle -``` - -会在 source 目录下生成如下文件: - -``` -mybundle -├── bundle.json # 组件元数据描述文件 -├── example # 测试组件功能的示例 -│ └── main.c -├── include # 组件的内部头文件 -│ └── mybundle.h -├── README.md # 组件的简要说明 -└── src # 组件的源代码 - └─ mybundle.c -``` - -接下来根据您的业务需要,实现组件内部的功能代码,完成代码开发后,通过git将代码(包括bundle.json文件)提交到组件代码托管仓库中(如gitee)。 - -## 改造组件 - -如果您已经有了代码,只是还不满足OpenHarmony的组件结构,需要改造成为hpm的组件包,只需要在当前要改造的代码目录下(例如mybundle2),执行如下命令,会提示您输入组件名称和版本。 - -``` -hpm init -``` - -1. 输入名称后回车(如mybundle2)。 -2. 输入版本后(如1.0.0)回车,在当前组件目录下会生成一个bundle.json文件。 -3. 打开bundle.json文件再添加其他的描述,这时候他已经是一个具备可发布的组件了。 - - ``` - $ hpm init - Your bundle will be created in dirname E:\demo\mybundle2 - ? bundle name mybundel2 - ? version 1.0.0 - Init finished! - ``` - - -1. 打开bundle.json文件修改其他信息(如作者,代码仓库,代码目录,命令脚本,依赖组件等),如下: - - ``` - { - "name": "mybundle2", - "version": "1.0.0", - "publishAs": "source", - "dirs":{ - ".":[ - "README.md" - ], - "src":[ - "test.c" - ], - "header":[ - "header/test.h" - ], - "src/common":[ - "src/common/foobar.txt" - ] - }, - "scripts": { - "build": "make -${args}" - }, - "dependencies": { - "@ohos/cjson": "^1.0.0", - "@ohos/": "^1.2.0" - } - } - ``` - - -## 从模板创建组件 - -hpm 除了提供了默认模板 default和simple两个简单的模板之外,其他模板均存储在服务器端。 - -可以使用命令hpm search -t template 从服务器端搜索模板。 - -![](figures/zh-cn_image_0000001051452177.png) - -根据description简要中的描述,找到适合的模板,基于模板可以快速创建一个组件的脚手架,执行如下初始化命令(指定-t -d 参数)。 - -``` -hpm init -t {templatename} -d dir name -``` - -- \{templatename\} :指的是模板名称。 -- -d 后面的参数dir:是要创建的组件所存放的路径。 -- name:为要创建的组件名称。 - -## 编译组件 - -完成代码开发后,需要对组件进行编译。hpm提供了命令集成的能力,您可以选择任意的适合项目的编译工具(如make,gcc,gn等等)。只需在当前项目的bundle.json文件中定义scripts脚本中的build命令,就可以通过执行hpm build执行编译。 - -## 定义编译脚本 - -以编译一个app目录下helloworld可执行文件为例: - -``` -app -├── BUILD.gn -├── include -│ └── helloworld.h -└── src - └── helloworld.c -``` - -在helloworld.c同级目录下新建一个BUILD.gn - -``` -touch BUILD.gn -vim BUILD.gn -``` - -以下是BUILD.gn的样例,仅供参考 - -``` -executable("hello_world") { - sources = [ - "src/helloworld.c" - ] - - include_dirs = [ - "include" - ] -} -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->- “executable”是gn内置模板,可以用“gn help executable ”查看使用方法。 ->- “sources ”是源码路径,“include\_dirs ”是头文件路径。 - -## 执行编译 - -在当前文件夹下,执行编译命令: - -``` -hpm build -``` - -在完成一系列的编译动作后,显示build succeed。检查编译的输出结果: - -![](figures/zh-cn_image_0000001051770876.png) - -## 定义发行版 - -发行版是将一组组件组合起来的,编译生成可以运行的OpenHarmony解决方案,里面包含了较多依赖的组件,以及以脚本形式描述如何完整编译、链接这些组件。 - -## 定义脚本 - -bundle.json中定义 - -``` -{ -"name": "my_dist", -"version": "1.0.0", -"publishAs": "distribution", -"scripts": { -"dist": "make -${args}" - }, -"base": { -"name": "dist-bundle", -"version": "1.0.0" - }, -"envs": { -"args": "x86" - }, -"dependencies": { -} -} -``` - -## 发行 - -在当前发行版根目录下,执行如下命令。 - -``` -hpm dist -``` - -hpm-cli工具会自动执行编译,打包操作,将根据scripts定义的dist脚本生成镜像文件,如: - -``` -out -|-xxdist.img -|-xx.file -``` - -## 烧录 - -发行版的编译结果可以烧录到设备中运行,例如使用hiburn工具进行烧录。在发行版的bundle.json文件配置烧录参数。 - -``` -"scripts": { -"flash": "{$DEP_HIBURN}/hiburn" -}, -``` - -配置烧录相关的参数(参考烧录工具的说明进行配置)。 - -``` -hpm run flash -``` - -## 运行调试 - -将发行版的镜像烧录到设备中后,就可以启动运行调试了,由于运行调试和具体的开发板和IDE调试工具相关,此处不再详细描述。 - diff --git "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.md" deleted file mode 100755 index cb1868b0b4463c569d8e022005d52487f9e05f29..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 组件开发指南 - -- **[概述](概述-0.md)** - -- **[准备工作](准备工作.md)** - -- **[组件开发](组件开发.md)** - - diff --git "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100755 index d3e13752118de3f3e106ab01950b786e0ed3e757..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 组件开发示例 - -- **[HPM介绍](HPM介绍.md)** - -- **[环境准备](环境准备.md)** - -- **[操作实例](操作实例.md)** - - diff --git "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\350\247\204\350\214\203.md" "b/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\350\247\204\350\214\203.md" deleted file mode 100755 index 4205b8d5383cd8baea3a4ce99710e0715682190d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\345\274\200\345\217\221\350\247\204\350\214\203.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 组件开发规范 - -- **[概述](概述.md)** - -- **[组件构成](组件构成.md)** - -- **[组件管理](组件管理.md)** - -- **[组件版本](组件版本.md)** - -- **[发行版](发行版.md)** - -- **[环境变量说明](环境变量说明.md)** - - diff --git "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\346\236\204\346\210\220.md" "b/zh-cn/device-dev/bundles/\347\273\204\344\273\266\346\236\204\346\210\220.md" deleted file mode 100755 index 98e4e2dd608c2fb78374ae2c9b8ce57748499723..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\346\236\204\346\210\220.md" +++ /dev/null @@ -1,99 +0,0 @@ -# 组件构成 - -- [代码文件](#section101483489110) -- [说明文件](#section10519101221211) -- [元数据描述文件](#section45511827111211) - -一个组件包一般包含如下内容: - -- 组件包的代码或库(src目录下的代码文件) -- ohos\_bundles文件夹(存放依赖的组件,安装组件时自动生成,无需提交到代码库) -- 组件包的说明文件\(README.md\) -- 组件包元数据声明文件\(bundle.json\) -- 开源许可文件\(LICENSE\) - - ``` - my-bundle - |_ohos_bundles - |_src - |_bundle.json - |_README.md - |_LICENSE - ``` - - -## 代码文件 - -组件的代码文件和普通的代码目录没有差异。但要注意的是,组件中对外暴露的接口(头文件),会被其他组件所引用,需要单独在bundle.json的dirs中声明。 - -## 说明文件 - -README.md,为markdown格式的描述关于组件自述说明文件。([语法参考](https://www.markdownguide.org/getting-started/)\) - -为了帮助他人在hpm上找到该组件,并更方便的使用它,在组件的根目录中包含一个README文件。 - -README文件可能包括如何安装,配置和使用组件包中的实例代码说明,以及可能会对用户有所帮助的任何其他信息。 - -每个组件的自述文件将显示在hpm系统的组件详情页面的描述中。 - -## 元数据描述文件 - -bundle.json文件是对当前组件的元数据描述,每个组件中必须包含一个bundle.json文件。 - -``` -{ - "name": "@myorg/demo-bundle", - "version": "1.0.0", - "license": "MIT", - "description": "bundle description", - "keywords": ["hos"], - "tags": ["applications", "drivers"], - "author": {"name":"","email":"","url":""}, - "contributors":[{"name":"","email":"","url":""},{"name":"","email":"","url":""}], - "homepage": "http://www.foo.bar.com", - "repository": "https://git@gitee.com:foo/bar.git", - "publishAs": "source", - "dirs": { - "src": ["src/**/*.c"], - "headers": ["headers/**/*.h"], - "bin": ["bin/**/*.o"] - }, - "scripts": { - "build": "make" - }, - "envs": {}, - "ohos": { - "os": "2.0.0", - "board": "hi3516", - "kernel": "liteos-a" - }, - "rom": "10240", - "ram": "1024", - "dependencies": { - "@myorg/net":"1.0.0" - } -} -``` - -bundle.json文件具有如下功能: - -- name:定义组件的名称,放到组织下, 以@开头,/分割,如:@myorg/mybundle - -- version:定义组件版本号,如1.0.0,需满足semver的标准。 - -- description:一句话对组件进行简要的描述。 -- dependencies:定义组件的依赖组件。 - -- envs: 定义组件编译时所需要的参数,包括全局参数以及依赖所需的参数。 - -- scripts:定义在当前组件下能够执行的命令(如编译,构建,测试,烧录等)。 - -- publishAs:定义组件的发布类型(source:源码,binary:二进制,distribution:发行版,code-segment:代码片段)。 - -- dirs:定义发布时打包的目录结构(如头文件)。 - -- ram&rom:统计相关信息:预计占用ROM和RAM信息。 -- ohos:描述OpenHarmony系统版本、开发板及内核的匹配关系(多个请用英文逗号的“,”分割)。 -- 定义其他扩展信息:作者,主页,代码仓库,许可协议,标签,关键字。 -- 对于发行版类型,还有个base,可以定义继承自的发行版。 - diff --git "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\347\211\210\346\234\254.md" "b/zh-cn/device-dev/bundles/\347\273\204\344\273\266\347\211\210\346\234\254.md" deleted file mode 100755 index 55647fdcb7093589938272e874379867ef00ffea..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\347\211\210\346\234\254.md" +++ /dev/null @@ -1,23 +0,0 @@ -# 组件版本 - -- [版本号命名规范](#section16893854141310) -- [版本发布](#section43401320171420) - -## 版本号命名规范 - -名称需要为全小写字母,中间可以使用中划线或者下划线分隔。比如 "bundle", "my\_bundle"。 - -版本号的格式为 "主版本号.次版本号.修订号" 或 "主版本号.次版本号.修订号-先行版本号",比如 "1.0.0", "1.0.0-beta",详细规格可以参考 [https://semver.org](https://semver.org/)。 - -## 版本发布 - -为了使组件能被其他开发者使用,组件需要上传到远端仓库。组件上传使用如下命令: - -``` -hpm publish -``` - -命令执行以后,系统会对的整个依赖关系进行检查,下载缺失依赖组件。依赖检查完成后,如果发布类型为binary,系统会对整个组件进行编译,生成二进制文件,然后打包上传。如果使其他上传类型,则直接根据定义的打包规则进行打包,然后上传。 - -注意:发布组件需要用户账号登录,需要先拥有hpm的系统账号后,并注册组织,申请组织认证通过后,才拥有发布的权限。 - diff --git "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\347\256\241\347\220\206.md" "b/zh-cn/device-dev/bundles/\347\273\204\344\273\266\347\256\241\347\220\206.md" deleted file mode 100755 index 852d9929b0961be9d557c496806167e5301f0ec2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/bundles/\347\273\204\344\273\266\347\256\241\347\220\206.md" +++ /dev/null @@ -1,237 +0,0 @@ -# 组件管理 - -- [依赖关系](#section12657593129) -- [hpm操作命令参考](#section1258849181312) - -## 依赖关系 - -生成基础bundle.json以后,需要继续添加组件依赖来实现更复杂的功能。此时需要知道所依赖组件的名称和版本号,并且把它们定义在bundle.json里面的dependencies字段中。 - -``` -{ - "name": "my-bundle", - "version": "1.0.0", - "dependencies": { - "net": "1.0.0" - } -} -``` - -上述示例中,my-bundle组件依赖于net 1.0.0组件。在全局安装了 hpm CLI 工具之后,执行如下命令可以从远端仓库获取到依赖: - -``` -hpm install -``` - -依赖获取以后,会保存到当前组件根目录下到ohos\_bundles文件夹中。组件以及依赖之间会形成一个依赖关系的树状结构。全局安装了 hpm CLI 工具之后,在组件根目录下执行如下命令: - -``` -username@server MINGW64 /f/showcase/demo/demo -$ hpm list -+--demo@1.0.0 -| +--@huawei/media@1.0.2 -| +--@demo/sport_hi3518ev300_liteos_a@1.0.0 -| | +--@demo/app@4.0.1 -| | | +--@demo/build@4.0.1 -| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 -| | +--@demo/liteos_a@4.0.0 -| | | +--@demo/third_party_fatfs@4.0.0 -| | | +--@demo/arm_harmonyeabi_gcc@4.0.0 -| | +--@demo/init@4.0.0 -| | +--@demo/dist_tools@4.0.0 -``` - -还可以使用图的形式,来查看当前组件的依赖关系,执行如下命令: - -``` -hpm dependencies -``` - -在当前目录下会生成deps\_visual文件夹,里面包含两个文件,deps.html 和 deps-data.js。在浏览器中打开 deps.html 文件,就可以看到依赖关系的图形化展示\(如下图\)。 - -根据不同的依赖类型,图形结点呈现出不同的颜色。鼠标悬浮在结点上,可以查看当前结点的状态。 - -**图 1** 组件包依赖关系图 -![](figures/组件包依赖关系图.png "组件包依赖关系图") - -## hpm操作命令参考 - -组件的全生命周期管理,可以通过hpm命令工具进行操作,hpm的操作命令如下(详细帮助可以执行 hpm -h学习): - -**表 1** hpm操作命令 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

命令类别

-

命令行

-

含义说明

-

版本查询

-

hpm -V 或 hpm --version

-

查看hpm-cli 版本号。

-

帮助查询

-

hpm -h 或 hpm --version

-

查看命令列表及帮助。

-

hpm -h

-

查看命令帮助。

-

创建

-

-

hpm init bundle

-

创建组件工程。

-

hpm init -t template

-

根据模板创建脚手架工程。

-

安装

-

-

hpm install 或hpm i

-

安装bundle.json中依赖的组件。

-

hpm install bundle@version

-

安装指定组件版本。

-

卸载

-

-

hpm uninstall bundle

-

删除depedencies依赖的组件。

-

hpm remove 或hpm rm bundlename

-

删除depedencies依赖的组件。

-

查看

-

-

hpm list 或者 hpm ls

-

显示当前组件/发行版所有的组件树。

-

hpm dependencies

-

生成当前组件/发行版依赖关系图(html格式)。

-

搜索

-

hpm search name

-

搜索组件,--json,可以以json格式输出 -type 可以设置搜索组件的类型,包括bundle,distribution,code-segment三种。

-

设置hpm配置项

-

hpm config set key value

-

设置配置值,如服务器地址,网络代理。

-

hpm config delete key

-

删除配置。

-

更新

-

-

hpm update

-

更新当前组件依赖的组件的版本。

-

hpm check-update

-

检查依赖的组件版本是否有更新。

-

编译

-

-

hpm build

-

编译组件/发行版。

-

hpm dist

-

发行版打包(依赖bundle.json的scripts中的dist脚本)。

-

打包

-

hpm pack

-

本地组件打包依赖。

-

烧录

-

hpm run flash

-

烧录固件(依赖bundle.json的scripts中的flash脚本)。

-

发布

-

hpm publish

-

发布组件,发布的组件在仓库中必须唯一,且版本唯一(需要账号登录)。

-

执行扩展命令

-

hpm run

-

执行bundle.json文件中定义的scripts脚本命令,支持多个命令可用 && 连接。

-

生成秘钥

-

hpm gen-keys

-

生成公钥/私钥对,将公钥配置到HPM服务端,可以实现hpm-cli 免密登录,发布组件。

-

生成第三方开源说明

-

hpm gen-notice

-

根据每个组件的说明,生成一份合并后的第三方开源说明的合并文件。

-
- - - - -
- diff --git a/zh-cn/device-dev/driver/GPIO.md b/zh-cn/device-dev/driver/GPIO.md deleted file mode 100755 index afffef57ab689bd2220b0cc24b3323089b0e2d52..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/GPIO.md +++ /dev/null @@ -1,9 +0,0 @@ -# GPIO - -- **[GPIO概述](GPIO概述.md)** - -- **[GPIO使用指导](GPIO使用指导.md)** - -- **[GPIO使用实例](GPIO使用实例.md)** - - diff --git "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 86231b7af28d913333f5ee3c7440ce6c7551d4a7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,79 +0,0 @@ -# GPIO使用实例 - -本实例程序中,我们将测试一个GPIO管脚的中断触发:为管脚设置中断服务函数,触发方式为边沿触发,然后通过交替写高低电平到管脚,产生电平波动,制造触发条件,观察中断服务函数的执行。 - -首先需要选取一个空闲的GPIO管脚,本例程基于Hi3516DV300某开发板,GPIO管脚选择GPIO10\_3,换算成GPIO号为83。 - -读者可以根据自己使用的开发板,参考其原理图,选择一个空闲的GPIO管脚即可。 - -``` -#include "gpio_if.h" -#include "hdf_log.h" -#include "osal_irq.h" -#include "osal_time.h" - -static uint32_t g_irqCnt; - -/* 中断服务函数*/ -static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) -{ - HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); - g_irqCnt++; /* 如果中断服务函数触发执行,则将全局中断计数加1 */ - return GpioDisableIrq(gpio); -} - -/* 测试用例函数 */ -static int32_t TestCaseGpioIrqEdge(void) -{ - int32_t ret; - uint16_t valRead; - uint16_t mode; - uint16_t gpio = 83; /* 待测试的GPIO管脚号 */ - uint32_t timeout; - - /* 将管脚方向设置为输出 */ - ret = GpioSetDir(gpio, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret); - return ret; - } - - /* 先禁止该管脚中断 */ - ret = GpioDisableIrq(gpio); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret); - return ret; - } - - /* 为管脚设置中断服务函数,触发模式为上升沿和下降沿共同触发 */ - mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING; - HDF_LOGE("%s: mode:%0x\n", __func__, mode); - ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret); - return ret; - } - - /* 使能此管脚中断 */ - ret = GpioEnableIrq(gpio); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret); - (void)GpioUnSetIrq(gpio); - return ret; - } - - g_irqCnt = 0; /* 清除全局计数器 */ - timeout = 0; /* 等待时间清零 */ - /* 等待此管脚中断服务函数触发,等待超时时间为1000毫秒 */ - while (g_irqCnt <= 0 && timeout < 1000) { - (void)GpioRead(gpio, &valRead); - (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); - HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout); - OsalMDelay(200); /* wait for irq trigger */ - timeout += 200; - } - (void)GpioUnSetIrq(gpio); - return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; -} -``` - diff --git "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 1bc136ee21147a7eca55b507cd96dfa8ab5fe583..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,395 +0,0 @@ -# GPIO使用指导 - -- [使用流程](#section1583613406410) -- [确定GPIO管脚号](#section135943361443) -- [使用API操作GPIO管脚](#section69151114115315) - -## 使用流程 - -GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如[图1](#fig1399416053717)所示。 - -**图 1** GPIO使用流程图 - - -![](figures/zh-cn_image_0000001057342245.png) - -## 确定GPIO管脚号 - -不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。 - -- Hi3516DV300 - - 控制器管理12组GPIO管脚,每组8个。 - - GPIO号 = GPIO组索引 \(0\~11\) \* 每组GPIO管脚数\(8\) + 组内偏移 - - 举例:GPIO10\_3的GPIO号 = 10 \* 8 + 3 = 83 - -- Hi3518EV300 - - 控制器管理10组GPIO管脚,每组10个。 - - GPIO号 = GPIO组索引 \(0\~9\) \* 每组GPIO管脚数\(10\) + 组内偏移 - - 举例:GPIO7\_3的GPIO管脚号 = 7 \* 10 + 3 = 73 - - -## 使用API操作GPIO管脚 - -- 设置GPIO管脚方向 - - 在进行GPIO管脚读写前,需要先通过如下函数设置GPIO管脚方向: - - int32\_t GpioSetDir\(uint16\_t gpio, uint16\_t dir\); - - **表 1** GpioSetDir参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

待设置的GPIO管脚号

-

dir

-

待设置的方向值

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- -- 读写GPIO管脚 - - 如果要读取一个GPIO管脚电平,通过以下函数完成: - - int32\_t GpioRead\(uint16\_t gpio, uint16\_t \*val\); - - **表 2** GpioRead参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

待读取的GPIO管脚号

-

val

-

接收读取电平值的指针

-

返回值

-

返回值描述

-

0

-

读取成功

-

负数

-

读取失败

-
- - 如果要向GPIO管脚写入电平值,通过以下函数完成: - - int32\_t GpioWrite\(uint16\_t gpio, uint16\_t val\); - - **表 3** GpioWrite参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

待写入的GPIO管脚号

-

val

-

待写入的电平值

-

返回值

-

返回值描述

-

0

-

写入成功

-

负数

-

写入失败

-
- - 示例代码: - - ``` - int32_t ret; - uint16_t val; - /* 将3号GPIO管脚配置为输出 */ - ret = GpioSetDir(3, GPIO_DIR_OUT); - if (ret != 0) { - HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); - return; - } - /* 向3号GPIO管脚写入低电平GPIO_VAL_LOW */ - ret = GpioWrite(3, GPIO_VAL_LOW); - if (ret != 0) { - HDF_LOGE("GpioWrite: failed, ret %d\n", ret); - return; - } - /* 将6号GPIO管脚配置为输入 */ - ret = GpioSetDir(6, GPIO_DIR_IN); - if (ret != 0) { - HDF_LOGE("GpioSetDir: failed, ret %d\n", ret); - return; - } - /* 读取6号GPIO管脚的电平值 */ - ret = GpioRead(6, &val); - ``` - - -- 设置GPIO中断 - - 如果要为一个GPIO管脚设置中断响应程序,使用如下函数: - - int32\_t GpioSetIrq\(uint16\_t gpio, uint16\_t mode, GpioIrqFunc func, void \*arg\); - - **表 4** GpioSetIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

mode

-

中断触发模式

-

func

-

中断服务程序

-

arg

-

传递给中断服务程序的入参

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- - >![](public_sys-resources/icon-caution.gif) **注意:** - >同一时间,只能为某个GPIO管脚设置一个中断服务函数,如果重复调用GpioSetIrq函数,则之前设置的中断服务函数会被取代。 - - 当不再需要响应中断服务函数时,使用如下函数取消中断设置: - - int32\_t GpioUnSetIrq\(uint16\_t gpio\); - - **表 5** GpioUnSetIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

返回值

-

返回值描述

-

0

-

取消成功

-

负数

-

取消失败

-
- - 在中断服务程序设置完成后,还需要先通过如下函数使能GPIO管脚的中断: - - int32\_t GpioEnableIrq\(uint16\_t gpio\); - - **表 6** GpioEnableIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

返回值

-

返回值描述

-

0

-

使能成功

-

负数

-

使能失败

-
- - >![](public_sys-resources/icon-caution.gif) **注意:** - >必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。 - - 如果要临时屏蔽此中断,可以通过如下函数禁止GPIO管脚中断: - - int32\_t GpioDisableIrq\(uint16\_t gpio\); - - **表 7** GpioDisableIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

返回值

-

返回值描述

-

0

-

禁止成功

-

负数

-

禁止失败

-
- - 示例代码: - - ``` - /* 中断服务函数 - */ - int32_t MyCallBackFunc(uint16_t gpio, void *data) - { - HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); - return 0; - } - - int32_t ret; - /* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */ - ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); - if (ret != 0) { - HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); - return; - } - - /* 使能3号GPIO管脚中断 */ - ret = GpioEnableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); - return; - } - - /* 禁止3号GPIO管脚中断 */ - ret = GpioDisableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); - return; - } - - /* 取消3号GPIO管脚中断服务程序 */ - ret = GpioUnSetIrq(3); - if (ret != 0) { - HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); - return; - } - ``` - - diff --git "a/zh-cn/device-dev/driver/GPIO\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/GPIO\346\246\202\350\277\260.md" deleted file mode 100755 index 1c4bcfc9c060718e31a5dd7bf267513fdb3afb0d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/GPIO\346\246\202\350\277\260.md" +++ /dev/null @@ -1,82 +0,0 @@ -# GPIO概述 - -- [简介](#section15318165672215) -- [接口说明](#section18977142162418) - -## 简介 - -GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。 - -GPIO接口定义了操作GPIO管脚的标准方法集合,包括: - -- 设置管脚方向: 方向可以是输入或者输出\(暂不支持高阻态\) - -- 读写管脚电平值: 电平值可以是低电平或高电平 -- 设置管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式 -- 使能和禁止管脚中断:禁止或使能管脚中断 - -## 接口说明 - -**表 1** GPIO驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

GPIO读写

-

GpioRead

-

读管脚电平值

-

GpioWrite

-

写管脚电平值

-

GPIO配置

-

GpioSetDir

-

设置管脚方向

-

GpioGetDir

-

获取管脚方向

-

GPIO中断设置

-

GpioSetIrq

-

设置管脚对应的中断服务函数

-

GpioUnSetIrq

-

取消管脚对应的中断服务函数

-

GpioEnableIrq

-

使能管脚中断

-

GpioDisableIrq

-

禁止管脚中断

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git "a/zh-cn/device-dev/driver/HDF\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/HDF\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index f9b3ca1aca4612cba98dd4d788645e0704f59850..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/HDF\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,238 +0,0 @@ -# HDF开发实例 - -- [添加配置](#section27261067111) -- [编写驱动代码](#section177988005) -- [编写用户程序和驱动交互代码](#section6205173816412) - -下面基于HDF框架,提供一个完整的样例,包含配置文件的添加,驱动代码的实现以及用户态程序和驱动交互的流程。 - -## 添加配置 - -在HDF框架的配置文件(例如vendor/hisilicon/xxx/config/device\_info)中添加该驱动的配置信息,如下所示: - -``` -root { - device_info { - match_attr = "hdf_manager"; - template host { - hostName = ""; - priority = 100; - template device { - template deviceNode { - policy = 0; - priority = 100; - preload = 0; - permission = 0664; - moduleName = ""; - serviceName = ""; - deviceMatchAttr = ""; - } - } - } - sample_host :: host { - hostName = "sample_host"; - sample_device :: device { - device0 :: deviceNode { - policy = 2; - priority = 100; - preload = 1; - permission = 0664; - moduleName = "sample_driver"; - serviceName = "sample_service"; - } - } - } - } -} -``` - -## 编写驱动代码 - -基于HDF框架编写的sample驱动代码如下: - -``` -#include -#include -#include -#include "hdf_log.h" -#include "hdf_base.h" -#include "hdf_device_desc.h" - -#define HDF_LOG_TAG "sample_driver" - -#define SAMPLE_WRITE_READ 123 - -int32_t HdfSampleDriverDispatch( - struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply) -{ - HDF_LOGE("%s: received cmd %d", __func__, id); - if (id == SAMPLE_WRITE_READ) { - const char *readData = HdfSbufReadString(data); - if (readData != NULL) { - HDF_LOGE("%s: read data is: %s", __func__, readData); - } - if (!HdfSbufWriteInt32(reply, INT32_MAX)) { - HDF_LOGE("%s: reply int32 fail", __func__); - } - return HdfDeviceSendEvent(deviceObject, id, data); - } - return HDF_FAILURE; -} - -void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) -{ - // release resources here - return; -} - -int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) -{ - if (deviceObject == NULL) { - return HDF_FAILURE; - } - static struct IDeviceIoService testService = { - .Dispatch = HdfSampleDriverDispatch, - }; - deviceObject->service = &testService; - return HDF_SUCCESS; -} - -int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) -{ - if (deviceObject == NULL) { - HDF_LOGE("%s::ptr is null!", __func__); - return HDF_FAILURE; - } - HDF_LOGE("Sample driver Init success"); - return HDF_SUCCESS; -} - -struct HdfDriverEntry g_sampleDriverEntry = { - .moduleVersion = 1, - .moduleName = "sample_driver", - .Bind = HdfSampleDriverBind, - .Init = HdfSampleDriverInit, - .Release = HdfSampleDriverRelease, -}; - -HDF_INIT(g_sampleDriverEntry); -``` - -## 编写用户程序和驱动交互代码 - -基于HDF框架编写的用户态程序和驱动交互的代码如下: - -``` -#include -#include -#include -#include -#include "hdf_log.h" -#include "hdf_sbuf.h" -#include "hdf_io_service_if.h" - -#define HDF_LOG_TAG "sample_test" -#define SAMPLE_SERVICE_NAME "sample_service" - -#define SAMPLE_WRITE_READ 123 - -int g_replyFlag = 0; - -static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) -{ - const char *string = HdfSbufReadString(data); - if (string == NULL) { - HDF_LOGE("fail to read string in event data"); - g_replyFlag = 1; - return HDF_FAILURE; - } - HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string); - g_replyFlag = 1; - return HDF_SUCCESS; -} - -static int SendEvent(struct HdfIoService *serv, char *eventData) -{ - int ret = 0; - struct HdfSBuf *data = HdfSBufObtainDefaultSize(); - if (data == NULL) { - HDF_LOGE("fail to obtain sbuf data"); - return 1; - } - - struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); - if (reply == NULL) { - HDF_LOGE("fail to obtain sbuf reply"); - ret = HDF_DEV_ERR_NO_MEMORY; - goto out; - } - - if (!HdfSbufWriteString(data, eventData)) { - HDF_LOGE("fail to write sbuf"); - ret = HDF_FAILURE; - goto out; - } - - ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); - if (ret != HDF_SUCCESS) { - HDF_LOGE("fail to send service call"); - goto out; - } - - int replyData = 0; - if (!HdfSbufReadInt32(reply, &replyData)) { - HDF_LOGE("fail to get service call reply"); - ret = HDF_ERR_INVALID_OBJECT; - goto out; - } - HDF_LOGE("Get reply is: %d", replyData); -out: - HdfSBufRecycle(data); - HdfSBufRecycle(reply); - return ret; -} - -int main() -{ - char *sendData = "default event info"; - struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME); - if (serv == NULL) { - HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME); - return HDF_FAILURE; - } - - static struct HdfDevEventlistener listener = { - .callBack = OnDevEventReceived, - .priv ="Service0" - }; - - if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) { - HDF_LOGE("fail to register event listener"); - return HDF_FAILURE; - } - if (SendEvent(serv, sendData)) { - HDF_LOGE("fail to send event"); - return HDF_FAILURE; - } - - while (g_replyFlag == 0) { - sleep(1); - } - - if (HdfDeviceUnregisterEventListener(serv, &listener)) { - HDF_LOGE("fail to unregister listener"); - return HDF_FAILURE; - } - - HdfIoServiceRecycle(serv); - return HDF_SUCCESS; -} -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->用户态应用程序使用了HDF框架中的消息发送接口,因此在编译用户态程序的过程中需要依赖HDF框架对外提供的hdf\_core和osal的动态库,在gn编译文件中添加如下依赖项: ->deps = \[ ->"//drivers/adapter/lite/uhdf/manager:hdf\_core", ->"//drivers/adapter/lite/uhdf/posix:hdf\_posix\_osal", ->\] - diff --git "a/zh-cn/device-dev/driver/HDF\351\251\261\345\212\250\346\241\206\346\236\266.md" "b/zh-cn/device-dev/driver/HDF\351\251\261\345\212\250\346\241\206\346\236\266.md" deleted file mode 100755 index fb6f985a6e5516f1520061a7923ee782a26fc9a0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/HDF\351\251\261\345\212\250\346\241\206\346\236\266.md" +++ /dev/null @@ -1,15 +0,0 @@ -# HDF驱动框架 - -- **[HDF开发概述](HDF开发概述.md)** - -- **[驱动开发](驱动开发.md)** - -- **[驱动服务管理](驱动服务管理.md)** - -- **[驱动消息机制管理](驱动消息机制管理.md)** - -- **[配置管理](配置管理.md)** - -- **[HDF开发实例](HDF开发实例.md)** - - diff --git a/zh-cn/device-dev/driver/I2C.md b/zh-cn/device-dev/driver/I2C.md deleted file mode 100755 index 5bc8c5bf3ce065ab72f19260fe0ab8ca622c0cd8..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/I2C.md +++ /dev/null @@ -1,9 +0,0 @@ -# I2C - -- **[I2C概述](I2C概述.md)** - -- **[I2C使用指导](I2C使用指导.md)** - -- **[I2C使用实例](I2C使用实例.md)** - - diff --git "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index a75da59b1b8b225230df1091d4335afbd8240b1d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,192 +0,0 @@ -# I2C使用实例 - -本例程以操作开发板上的I2C设备为例,详细展示I2C接口的完整使用流程。 - -本例拟对Hi3516DV300某开发板上TouchPad设备进行简单的寄存器读写访问,基本硬件信息如下: - -- SOC:hi3516dv300。 - -- Touch IC:I2C地址为0x38, IC内部寄存器位宽为1字节。 - -- 原理图信息:TouchPad设备挂接在3号I2C控制器下;IC的复位管脚为3号GPIO。 - -本例程首先对Touch IC进行复位操作(开发板上电默认会给TouchIC供电,本例程不考虑供电),然后对其内部寄存器进行随机读写,测试I2C通路是否正常。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->本例程重点在于展示I2C设备访问流程,并验证I2C通路,所以对于设备寄存器读写值不做关注,读写寄存器导致的行为由设备自身决定。 - -示例如下: - -``` -#include "i2c_if.h" /* I2C标准接口头文件 */ -#include "gpio_if.h" /* GPIO标准接口头文件 */ -#include "hdf_log.h" /* 标准日志打印头文件 */ -#include "osal_io.h" /* 标准IO读写接口头文件 */ -#include "osal_time.h" /* 标准延迟&睡眠接口头文件 */ - -/* 定义一个表示TP设备的结构体,存储i2c及gpio相关硬件信息 */ -struct TpI2cDevice { - uint16_t rstGpio; /* 复位管脚 */ - uint16_t busId; /* I2C总线号 */ - uint16_t addr; /* I2C设备地址 */ - uint16_t regLen; /* 寄存器字节宽度 */ - DevHandle i2cHandle; /* I2C控制器句柄 */ -}; - -/* I2C管脚io配置,需要查阅SOC寄存器手册 */ -#define I2C3_DATA_REG_ADDR 0x112f008c /* 3号I2C控制器SDA管脚配置寄存器地址 */ -#define I2C3_CLK_REG_ADDR 0x112f0090 /* 3号I2C控制器SCL管脚配置寄存器地址 */ -#define I2C_REG_CFG 0x5f1 /* 3号I2C控制器SDA及SCL管脚配置值 */ - -static void TpSocIoCfg(void) -{ - /* 将3号I2C控制器对应两个管脚的IO功能设置为I2C */ - OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR)); - OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR)); -} - -/* 对TP的复位管脚进行初始化, 拉高维持20ms, 再拉底维持50ms,最后再拉高维持20ms, 完成复位动作 */ -static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice) -{ - int32_t ret; - - /* 设置复位管脚方向为输出 */ - ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret); - return ret; - } - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(20); - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst low fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(50); - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst high fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(20); - - return HDF_SUCCESS; -} - -/* 基于I2cTransfer方法封装一个寄存器读写的辅助函数, 通过flag表示读或写 */ -static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen, uint8_t flag) -{ - int index = 0; - unsigned char regBuf[4] = {0}; - struct I2cMsg msgs[2] = {0}; - - /* 单双字节寄存器长度适配 */ - if (tpDevice->regLen == 1) { - regBuf[index++] = regAddr & 0xFF; - } else { - regBuf[index++] = (regAddr >> 8) & 0xFF; - regBuf[index++] = regAddr & 0xFF; - } - - /* 填充I2cMsg消息结构 */ - msgs[0].addr = tpDevice->addr; - msgs[0].flags = 0; /* 标记为0,表示写入 */ - msgs[0].len = tpDevice->regLen; - msgs[0].buf = regBuf; - - msgs[1].addr = tpDevice->addr; - msgs[1].flags = (flag == 1) ? I2C_FLAG_READ : 0; /* 添加读标记位,表示读取 */ - msgs[1].len = dataLen; - msgs[1].buf = regData; - - if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) { - HDF_LOGE("%s: i2c read err", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -/* TP寄存器读函数 */ -static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen) -{ - return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1); -} - -/* TP寄存器写函数 */ -static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen) -{ - return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0); -} - -/* I2C例程总入口 */ -static int32_t TestCaseI2c(void) -{ - int32_t i; - int32_t ret; - unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC }; - unsigned char bufRead[7] = {0}; - static struct TpI2cDevice tpDevice; - - /* IO管脚功能配置 */ - TpSocIoCfg(); - - /* TP设备信息初始化 */ - tpDevice.rstGpio = 3; - tpDevice.busId = 3; - tpDevice.addr = 0x38; - tpDevice.regLen = 1; - tpDevice.i2cHandle = NULL; - - /* GPIO管脚初始化 */ - ret = TestCaseGpioInit(&tpDevice); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: gpio init fail!:%d", __func__, ret); - return ret; - } - - /* 打开I2C控制器 */ - tpDevice.i2cHandle = I2cOpen(tpDevice.busId); - if (tpDevice.i2cHandle == NULL) { - HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId); - return -1; - } - - /* 向TP-IC的0xD5寄存器连续写7字节数据 */ - ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret); - I2cClose(tpDevice.i2cHandle); - return -1; - } - OsalMSleep(10); - - /* 从TP-IC的0xDO寄存器连续读7字节数据 */ - ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); - I2cClose(tpDevice.i2cHandle); - return -1; - } - - HDF_LOGE("%s: tp i2c write&read reg success!", __func__); - for (i = 0; i < 7; i++) { - HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]); - } - - /* 访问完毕关闭I2C控制器 */ - I2cClose(tpDevice.i2cHandle); - return ret; -} -``` - diff --git "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 38341ca1d40f1c2572078f2f449e8a37065a9281..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,171 +0,0 @@ -# I2C使用指导 - -- [使用流程](#section333203315215) -- [打开I2C控制器](#section123631358135713) -- [进行I2C通信](#section11091522125812) -- [关闭I2C控制器](#section13519505589) - -## 使用流程 - -使用I2C设备的一般流程如[图1](#fig166181128151112)所示。 - -**图 1** I2C设备使用流程图 - - -![](figures/zh-cn_image_0000001057902344.png) - -## 打开I2C控制器 - -在进行I2C通信前,首先要调用I2cOpen打开I2C控制器。 - -DevHandle I2cOpen\(int16\_t number\); - -**表 1** I2cOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

number

-

I2C控制器号

-

返回值

-

返回值描述

-

NULL

-

打开I2C控制器失败

-

设备句柄

-

打开的I2C控制器设备句柄

-
- -假设系统中存在8个I2C控制器,编号从0到7,那么我们现在获取3号控制器 - -``` -DevHandle i2cHandle = NULL; /* I2C控制器句柄 / - -/* 打开I2C控制器 */ -i2cHandle = I2cOpen(3); -if (i2cHandle == NULL) { - HDF_LOGE("I2cOpen: failed\n"); - return; -} -``` - -## 进行I2C通信 - -消息传输 - -int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\); - -**表 2** I2cTransfer参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

I2C控制器设备句柄

-

msgs

-

待传输数据的消息结构体数组

-

count

-

消息数组长度

-

返回值

-

返回值描述

-

正整数

-

成功传输的消息结构体数目

-

负数

-

执行失败

-
- -I2C传输消息类型为I2cMsg,每个传输消息结构体表示一次读或写,通过一个消息数组,可以执行若干次的读写组合操作。 - -``` -int32_t ret; -uint8_t wbuff[2] = { 0x12, 0x13 }; -uint8_t rbuff[2] = { 0 }; -struct I2cMsg msgs[2]; /* 自定义传输的消息结构体数组 */ -msgs[0].buf = wbuff; /* 写入的数据 */ -msgs[0].len = 2; /* 写入数据长度为2 */ -msgs[0].addr = 0x5A; /* 写入设备地址为0x5A */ -msgs[0].flags = 0; /* 传输标记为0,默认为写 */ -msgs[1].buf = rbuff; /* 要读取的数据 */ -msgs[1].len = 2; /* 读取数据长度为2 */ -msgs[1].addr = 0x5A; /* 读取设备地址为0x5A */ -msgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ置位 */ -/* 进行一次自定义传输,传输的消息个数为2 */ -ret = I2cTransfer(i2cHandle, msgs, 2); -if (ret != 2) { - HDF_LOGE("I2cTransfer: failed, ret %d\n", ret); - return; -} -``` - ->![](public_sys-resources/icon-caution.gif) **注意:** ->- I2cMsg结构体中的设备地址不包含读写标志位,读写信息由flags成员变量的读写控制位传递。 ->- 本函数不对消息结构体个数count做限制,其最大个数度由具体I2C控制器决定。 ->- 本函数也不对每个消息结构体中的数据长度做限制,同样由具体I2C控制器决定。 ->- 本函数可能会引起系统休眠,不允许在中断上下文调用 - -## 关闭I2C控制器 - -I2C通信完成之后,需要关闭2C控制器,关闭函数如下所示: - -void I2cClose\(DevHandle handle\); - -**表 3** I2cClose参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

I2C控制器设备句柄

-
- -``` -I2cClose(i2cHandle); /* 关闭I2C控制器 */ -``` - diff --git "a/zh-cn/device-dev/driver/I2C\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/I2C\346\246\202\350\277\260.md" deleted file mode 100755 index 7961b58a8284049766dc470b862e377d79f1c696..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/I2C\346\246\202\350\277\260.md" +++ /dev/null @@ -1,60 +0,0 @@ -# I2C概述 - -- [简介](#section5361140416) -- [接口说明](#section7606310210) - -## 简介 - -- I2C\(Inter Integrated Circuit\)总线是由Philips公司开发的一种简单、双向二线制同步串行总线。 -- I2C以主从方式工作,通常有一个主设备和一个或者多个从设备,主从设备通过SDA\(SerialData\)串行数据线以及SCL\(SerialClock\)串行时钟线两根线相连,如[图1 ](#fig1135561232714)所示。 - -- I2C数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。数据传输以字节为单位,高位在前,逐个bit进行传输。 -- I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址,当主设备需要和某一个从设备通信时,通过广播的方式,将从设备地址写到总线上,如果某个从设备符合此地址,将会发出应答信号,建立传输。 - -- I2C接口定义了完成I2C传输的通用方法集合,包括: - - - I2C控制器管理: 打开或关闭I2C控制器 - - I2C消息传输:通过消息传输结构体数组进行自定义传输 - - **图 1** I2C物理连线示意图 - ![](figures/I2C物理连线示意图.png "I2C物理连线示意图") - - -## 接口说明 - -**表 1** I2C驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

I2C控制器管理接口

-

I2cOpen

-

打开I2C控制器

-

I2cClose

-

关闭I2C控制器

-

I2c消息传输接口

-

I2cTransfer

-

自定义传输

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/LCD.md b/zh-cn/device-dev/driver/LCD.md deleted file mode 100755 index b6352ca83310a7c0f1d6af1d09f47a8450e626db..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/LCD.md +++ /dev/null @@ -1,9 +0,0 @@ -# LCD - -- **[LCD开发概述](LCD开发概述.md)** - -- **[LCD开发指导](LCD开发指导.md)** - -- **[LCD开发实例](LCD开发实例.md)** - - diff --git "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index 6de19704008c9850cec3a9f79baeddeef0c24401..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,291 +0,0 @@ -# LCD开发实例 - -添加设备描述配置: - -``` -/* Display驱动相关的设备描述配置 */ -display :: host { - hostName = "display_host"; - /* Display平台驱动设备描述 */ - device_hdf_disp :: device { - device0 :: deviceNode { - policy = 2; - priority = 200; - permission = 0660; - moduleName = "HDF_DISP"; - serviceName = "hdf_disp"; - } - } - /* SOC适配层驱动设备描述 */ - device_hi35xx_disp :: device { - device0 :: deviceNode { - policy = 0; - priority = 199; - moduleName = "HI351XX_DISP"; - } - } - /* LCD器件驱动设备描述 */ - device_lcd :: device { - device0 :: deviceNode { - policy = 0; - priority = 100; - preload = 0; - moduleName = "LCD_Sample"; - } - device1 :: deviceNode { - policy = 0; - priority = 100; - preload = 2; - moduleName = "LCD_SampleXX"; - } - } -} -``` - -SOC适配层驱动,以Hi35xx系列芯片为例,需要在本层驱动中适配MIPI等和芯片平台相关的配置,示例如下: - -``` -static int32_t MipiDsiInit(struct PanelInfo *info) -{ - int32_t ret; - struct DevHandle *mipiHandle = NULL; - struct MipiCfg cfg; - - mipiHandle = MipiDsiOpen(0); - if (mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - cfg.lane = info->mipi.lane; - cfg.mode = info->mipi.mode; - cfg.format = info->mipi.format; - cfg.burstMode = info->mipi.burstMode; - cfg.timing.xPixels = info->width; - cfg.timing.hsaPixels = info->hsw; - cfg.timing.hbpPixels = info->hbp; - cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; - cfg.timing.vsaLines = info->vsw; - cfg.timing.vbpLines = info->vbp; - cfg.timing.vfpLines = info->vfp; - cfg.timing.ylines = info->height; - /* 0 : no care */ - cfg.timing.edpiCmdSize = 0; - cfg.pixelClk = CalcPixelClk(info); - cfg.phyDataRate = CalcDataRate(info); - /* config mipi device */ - ret = MipiDsiSetCfg(mipiHandle, &cfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); - } - MipiDsiClose(mipiHandle); - HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, - cfg.pixelClk, cfg.phyDataRate); - return ret; -} -``` - -LCD器件驱动示例如下: - -``` -#define RESET_GPIO 5 -#define MIPI_DSI0 0 -#define BLK_PWM1 1 -#define PWM_MAX_PERIOD 100000 -/* backlight setting */ -#define MIN_LEVEL 0 -#define MAX_LEVEL 255 -#define DEFAULT_LEVEL 100 - -#define WIDTH 480 -#define HEIGHT 960 -#define HORIZONTAL_BACK_PORCH 20 -#define HORIZONTAL_FRONT_PORCH 20 -#define HORIZONTAL_SYNC_WIDTH 10 -#define VERTIACL_BACK_PORCH 14 -#define VERTIACL_FRONT_PORCH 16 -#define VERTIACL_SYNC_WIDTH 2 -#define FRAME_RATE 60 - -/* Panel Info结构体结构体 */ -struct PanelInfo { - uint32_t width; - uint32_t height; - uint32_t hbp; - uint32_t hfp; - uint32_t hsw; - uint32_t vbp; - uint32_t vfp; - uint32_t vsw; - uint32_t frameRate; - enum LcdIntfType intfType; - enum IntfSync intfSync; - struct MipiDsiDesc mipi; - struct BlkDesc blk; - struct PwmCfg pwm; -}; - -/* LCD屏的初始化序列 */ -static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; -static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; -static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; -static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; -static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; -static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; -static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; -static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; -static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; -static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; -static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; -static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; -static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; -static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; -static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; -static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; -static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; -static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; -static uint8_t g_payLoad18[] = { - 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, - 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, - 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 -}; -static uint8_t g_payLoad19[] = { 0x11 }; -static uint8_t g_payLoad20[] = { 0x29 }; - -struct DsiCmdDesc g_OnCmd[] = { - { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, - { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, - { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, - { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, - { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, - { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, - { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, - { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, - { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, - { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, - { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, - { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, - { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, - { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, - { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, - { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, - { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, - { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, - { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, - { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, - { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, -}; -static DevHandle g_mipiHandle = NULL; -static DevHandle g_pwmHandle = NULL; - -/* 设置Reset Pin脚状态 */ -static int32_t LcdResetOn(void) -{ - int32_t ret; - ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioSetDir failure, ret:%d", ret); - return HDF_FAILURE; - } - ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioWrite failure, ret:%d", ret); - return HDF_FAILURE; - } - /* delay 20ms */ - OsalMSleep(20); - return HDF_SUCCESS; -} - -static int32_t SampleInit(void) -{ - /* 获取MIPI DSI设备操作句柄 */ - g_mipiHandle = MipiDsiOpen(MIPI_DSI0); - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -static int32_t SampleOn(void) -{ - int32_t ret; - /* LCD上电序列 */ - ret = LcdResetOn(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: LcdResetOn failure", __func__); - return HDF_FAILURE; - } - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: g_mipiHandle is null", __func__); - return HDF_FAILURE; - } - /* 使用mipi下发初始化序列 */ - int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); - int32_t i; - for (i = 0; i < count; i++) { - ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); - if (ret != HDF_SUCCESS) { - HDF_LOGE("MipiDsiTx failure"); - return HDF_FAILURE; - } - } - /* 将mipi切换到HS模式 */ - MipiDsiSetHsMode(g_mipiHandle); - return HDF_SUCCESS; -} - -/* PanelInfo结构体变量 */ -static struct PanelInfo g_panelInfo = { - .width = WIDTH, /* width */ - .height = HEIGHT, /* height */ - .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ - .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ - .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ - .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ - .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ - .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ - .frameRate = FRAME_RATE, /* frame rate */ - .intfType = MIPI_DSI, /* panel interface type */ - .intfSync = OUTPUT_USER, /* output timming type */ - /* mipi config info */ - .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, - /* backlight config info */ - .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, - .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, -}; - -/* 器件驱动需要适配的基础接口 */ -static struct PanelData g_panelData = { - .info = &g_panelInfo, - .init = SampleInit, - .on = SampleOn, - .off = SampleOff, - .setBacklight = SampleSetBacklight, -}; - -/* 器件驱动入口函数 */ -int32_t SampleEntryInit(struct HdfDeviceObject *object) -{ - HDF_LOGI("%s: enter", __func__); - if (object == NULL) { - HDF_LOGE("%s: param is null!", __func__); - return HDF_FAILURE; - } - /* 器件驱动接口注册,ops提供给平台驱动调用 */ - if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { - HDF_LOGE("%s: PanelDataRegister error!", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -struct HdfDriverEntry g_sampleDevEntry = { - .moduleVersion = 1, - .moduleName = "LCD_SAMPLE", - .Init = SampleEntryInit, -}; - -HDF_INIT(g_sampleDevEntry); -``` - diff --git "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 12161e4cef9752fb16db59f597560828f5af8085..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,23 +0,0 @@ -# LCD开发指导 - -- [开发步骤](#section3904154911218) - -Display驱动模型基于HDF驱动框架、Platform接口及OSAL接口开发,可以做到不区分OS(LiteOS、Linux)和芯片平台(Hi35xx、Hi38xx、V3S等),为LCD器件提供统一的驱动模型。 - -## 开发步骤 - -1. 添加LCD驱动相关的设备描述配置。 -2. 在SOC平台驱动适配层中适配对应的芯片平台驱动。 -3. 添加器件驱动,并在驱动入口函数Init中注册Panel驱动数据,驱动数据接口主要包括如下接口: - - LCD上下电 - - 根据LCD硬件连接,使用Platform接口层提供的GPIO操作接口操作对应LCD管脚,例如复位管脚、IOVCC管脚,上电时序参考LCD供应商提供的SPEC。 - - - 发送初始化序列 - - 根据LCD硬件接口,使用Platform接口层提供的I2C、SPI、MIPI等接口,下载LCD初始化序列,初始化参数序列可以参考LCD供应商提供的SPEC。 - - -4. 根据需求实现HDF框架其他接口,比如Release接口。 -5. 根据需求使用HDF框架可创建其他设备节点,用于业务逻辑或者调试功能。 - diff --git "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index ab5e824934e96eedd766288dbeb33f93d7b38ab2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,46 +0,0 @@ -# LCD开发概述 - -- [简介](#section3781515122118) -- [接口说明](#section20280192712120) - -## 简介 - -LCD(Liquid Crystal Display)液晶显示驱动,对LCD进行上电,并通过接口初始化LCD内部寄存器,使LCD正常工作。Display驱动模型基于HDF( Hardware Driver Foundation)[驱动框架](HDF开发概述.md)开发,实现跨OS、跨平台,为LCD硬件提供上下电功能、发送初始化序列功能,使LCD进入正常的工作模式,显示芯片平台侧的图像数据,基于HDF驱动框架的Display驱动模型如[图1](#fig69138814229)。 - -**图 1** 基于HDF驱动框架的Display驱动模型 -![](figures/基于HDF驱动框架的Display驱动模型.png "基于HDF驱动框架的Display驱动模型") - -- **Display驱动模型介绍** - - Display驱动模型主要由平台驱动层、芯片平台适配层、LCD器件驱动层三部分组成。驱动模型基于HDF驱动框架开发,通过Platform层和OSAL层提供的接口,屏蔽内核形态的差异,使得器件驱动可以便利的迁移到不同OS及芯片平台。模型向上对接Display公共hal层,支撑HDI接口的实现,通过Display-HDI(Hardware Display Interface)对图形服务提供各类驱动能力接口。 - - (1)Display平台驱动层:通过HDF提供的IOService数据通道,与公共Hal层对接,集中接收并处理各类上层调用指令; - - (2)SOC平台驱动适配层:借助此SOC适配层,实现Display驱动和SOC侧驱动解耦,主要完成芯片平台相关的参数配置,并传递平台驱动层的调用到器件驱动层; - - (3)LCD器件驱动层:在器件驱动层中,主要实现和器件自身强相关的驱动适配接口,例如发送初始化序列、上下电、背光设置等。 - - 基于Display驱动模型开发LCD驱动,可以借助平台提供的各种能力及接口,较大程度的降低器件驱动的开发周期和难度,提升开发效率。 - - -## 接口说明 - -LCD接口通常可分为MIPI DSI接口、TTL接口和LVDS接口,常用的是MIPI DSI接口和TTL接口,下面对常用的MIPI DSI接口和TTL接口作简要介绍。 - -- MIPI DSI接口 - - **图 2** MIPI DSI接口 - ![](figures/MIPI-DSI接口.png "MIPI-DSI接口") - - MIPI DSI接口是MIPI(移动行业处理器接口)联盟定义的显示接口,主要用于移动终端显示屏接口,接口数据传输遵循MIPI协议,MIPI DSI接口为数据接口,传输图像数据,通常情况下MIPI DSI接口的控制信息以MIPI包形式通过MIPI DSI接口发送到对端IC,不需要额外的外设接口。 - -- TTL接口 - - **图 3** TTL接口 - ![](figures/TTL接口.png "TTL接口") - - TTL(Transistor Transistor Logic)即晶体管-晶体管逻辑,TTL电平信号由TTL器件产生,TTL器件是数字集成电路的一大门类,它采用双极型工艺制造,具有高速度、低功耗和品种多等特点。 - - TTL接口是并行方式传输数据的接口,有数据信号、时钟信号和控制信号(行同步、帧同步、数据有效信号等),在控制信号控制下完成数据传输。通常TTL接口的LCD,内部寄存器读写需要额外的外设接口,比如SPI接口、I2C接口等。 - - diff --git a/zh-cn/device-dev/driver/MIPI-DSI.md b/zh-cn/device-dev/driver/MIPI-DSI.md deleted file mode 100755 index 2dcbddcdd053fdc85e2b8478b690d79dfe41909d..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/MIPI-DSI.md +++ /dev/null @@ -1,9 +0,0 @@ -# MIPI DSI - -- **[MIPI DSI概述](MIPI-DSI概述.md)** - -- **[MIPI DSI使用指导](MIPI-DSI使用指导.md)** - -- **[MIPI DSI使用实例](MIPI-DSI使用实例.md)** - - diff --git "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 77e9242f30b175fee1f855d9516d3e407aa2a8fa..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,98 +0,0 @@ -# MIPI DSI使用实例 - -MIPI-DSI完整的使用示例如下所示: - -``` -#include "hdf.h" -#include "mipi_dsi_if.h" - -void PalMipiDsiTestSample(void) -{ - uint8_t chnId; - int32_t ret; - DevHandle handle = NULL; - - /* 设备通道编号 */ - chnId = 0; - /* 获取操作句柄 */ - handle = MipiDsiOpen(chnId); - if (handle == NULL) { - HDF_LOGE("MipiDsiOpen: failed!\n"); - return; - } - /* 配置相应参数 */ - struct MipiCfg cfg = {0}; - cfg.lane = DSI_4_LANES; - cfg.mode = DSI_CMD_MODE; - cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; - cfg.format = FORMAT_RGB_24_BIT; - cfg.pixelClk = 174; - cfg.phyDataRate = 384; - cfg.timingInfo.hsaPixels = 50; - cfg.timingInfo.hbpPixels = 55; - cfg.timingInfo.hlinePixels = 1200; - cfg.timingInfo.yResLines = 1800; - cfg.timingInfo.vbpLines = 33; - cfg.timingInfo.vsaLines = 76; - cfg.timingInfo.vfpLines = 120; - cfg.timingInfo.xResPixels = 1342; - /* 写入配置数据 */ - ret = MipiDsiSetCfg(g_handle, &cfg); - if (ret != 0) { - HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); - return; - } - /* 发送PANEL初始化指令 */ - struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); - if (cmd == NULL) { - return; - } - cmd->dtype = DTYPE_DCS_WRITE; - cmd->dlen = 1; - cmd->payload = OsalMemCalloc(sizeof(uint8_t)); - if (cmd->payload == NULL) { - HdfFree(cmd); - return; - } - *(cmd->payload) = DTYPE_GEN_LWRITE; - MipiDsiSetLpMode(mipiHandle); - ret = MipiDsiTx(mipiHandle, cmd); - MipiDsiSetHsMode(mipiHandle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret); - HdfFree(cmd->payload); - HdfFree(cmd); - return; - } - HdfFree(cmd->payload); - HdfFree(cmd); - /* 回读panel状态寄存器 */ - uint8_t readVal = 0; - struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); - if (cmdRead == NULL) { - return; - } - cmdRead->dtype = DTYPE_DCS_READ; - cmdRead->dlen = 1; - cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); - if (cmdRead->payload == NULL) { - HdfFree(cmdRead); - return; - } - *(cmdRead->payload) = DDIC_REG_STATUS; - MipiDsiSetLpMode(g_handle); - ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); - MipiDsiSetHsMode(g_handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - return; - } - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - /* 释放MIPI DSI设备句柄 */ - MipiDsiClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 58603da99a1536aebce4f61f049e5bc960d0114f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,365 +0,0 @@ -# MIPI DSI使用指导 - -- [使用流程](#section8982671284) -- [获取MIPI-DSI操作句柄](#section57982569176) -- [MIPI-DSI相应配置](#section5935410201815) -- [发送/回读控制指令](#section611661316194) -- [释放MIPI-DSI操作句柄](#section217313211199) - -## 使用流程 - -使用MIPI-DSI的一般流程如[图1](#fig99821771782)所示。 - -**图 1** MIPI-DSI使用流程图 - - -![](figures/zh-cn_image_0000001072553354.png) - -## 获取MIPI-DSI操作句柄 - -在进行MIPI-DSI进行通信前,首先要调用MipiDsiOpen获取操作句柄,该函数会返回指定通道ID的操作句柄。 - -DevHandle MipiDsiOpen\(uint8\_t id\); - -**表 1** MipiDsiOpen的参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

id

-

MIPI DSI通道ID

-

返回值

-

返回值描述

-

NULL

-

获取失败

-

设备句柄

-

获取到指令通道的操作句柄, 类型为DevHandle

-
- -假设系统中的MIPI-DSI通道为0,获取该通道操作句柄的示例如下: - -``` -DevHandle mipiDsiHandle = NULL; /* 设备句柄 */ -chnId = 0; /* MIPI-DSI通道ID */ - -/* 获取操作句柄 */ -mipiDsiHandle = MipiDsiOpen(chnId); -if (mipiDsiHandle == NULL) { - HDF_LOGE("MipiDsiOpen: failed\n"); - return; -} -``` - -## MIPI-DSI相应配置 - -- 写入MIPI-DSI配置 - -int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\); - -**表 2** MipiDsiSetCfg的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cfg

-

MIPI-DSI相应配置buf 指针

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- -``` -int32_t ret; -struct MipiCfg cfg = {0}; - -/* 当前对接的屏幕配置如下 */ -cfg.lane = DSI_4_LANES; -cfg.mode = DSI_CMD_MODE; -cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; -cfg.format = FORMAT_RGB_24_BIT; -cfg.pixelClk = 174; -cfg.phyDataRate = 384; -cfg.timingInfo.hsaPixels = 50; -cfg.timingInfo.hbpPixels = 55; -cfg.timingInfo.hlinePixels = 1200; -cfg.timingInfo.yResLines = 1800; -cfg.timingInfo.vbpLines = 33; -cfg.timingInfo.vsaLines = 76; -cfg.timingInfo.vfpLines = 120; -cfg.timingInfo.xResPixels = 1342; -/* 写入配置数据 */ -ret = MipiDsiSetCfg(g_handle, &cfg); -if (ret != 0) { - HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); - return -1; -} -``` - -- 获取当前MIPI-DSI的配置 - -int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); - -**表 3** MipiDsiGetCfg的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cfg

-

MIPI-DSI相应配置buf 指针

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -struct MipiCfg cfg; -memset(&cfg, 0, sizeof(struct MipiCfg)); -ret = MipiDsiGetCfg(g_handle, &cfg); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); - return HDF_FAILURE; -} -``` - -## 发送/回读控制指令 - -- 发送指令 - -int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); - -**表 4** MipiDsiTx的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cmd

-

需要发送的指令数据指针

-

返回值

-

返回值描述

-

0

-

发送成功

-

负数

-

发送失败

-
- -``` -int32_t ret; -struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); -if (cmd == NULL) { - return HDF_FAILURE; -} -cmd->dtype = DTYPE_DCS_WRITE; -cmd->dlen = 1; -cmd->payload = OsalMemCalloc(sizeof(uint8_t)); -if (cmd->payload == NULL) { - HdfFree(cmd); - return HDF_FAILURE; -} -*(cmd->payload) = DTYPE_GEN_LWRITE; -MipiDsiSetLpMode(mipiHandle); -ret = MipiDsiTx(mipiHandle, cmd); -MipiDsiSetHsMode(mipiHandle); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret); - HdfFree(cmd->payload); - HdfFree(cmd); - return HDF_FAILURE; -} -HdfFree(cmd->payload); -HdfFree(cmd); -``` - -- 回读指令 - -int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); - -**表 5** MipiDsiRx的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cmd

-

需要回读的指令数据指针

-

readLen

-

期望回读的数据长度

-

out

-

回读的数据buf指针

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -uint8_t readVal = 0; - -struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); -if (cmdRead == NULL) { - return HDF_FAILURE; -} -cmdRead->dtype = DTYPE_DCS_READ; -cmdRead->dlen = 1; -cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); -if (cmdRead->payload == NULL) { - HdfFree(cmdRead); - return HDF_FAILURE; -} -*(cmdRead->payload) = DDIC_REG_STATUS; -MipiDsiSetLpMode(g_handle); -ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); -MipiDsiSetHsMode(g_handle); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - return HDF_FAILURE; -} -HdfFree(cmdRead->payload); -HdfFree(cmdRead); -``` - -## 释放MIPI-DSI操作句柄 - -MIPI-DSI使用完成之后,需要释放操作句柄,释放句柄的函数如下所示: - -void MipiDsiClose\(DevHandle handle\); - -该函数会释放掉由MipiDsiOpen申请的资源。 - -**表 6** MipiDsiClose的参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

MIPI-DSI操作句柄

-
- -``` -MipiDsiClose(mipiHandle); /* 释放掉MIPI-DSI操作句柄 */ -``` - diff --git "a/zh-cn/device-dev/driver/MIPI-DSI\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/MIPI-DSI\346\246\202\350\277\260.md" deleted file mode 100755 index 5af73287eb9f6d46a3ec9f7fb5ca2e3d0668ce1b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/MIPI-DSI\346\246\202\350\277\260.md" +++ /dev/null @@ -1,84 +0,0 @@ -# MIPI DSI概述 - -- [简介](#section1369320102013) -- [接口说明](#section6577545192317) - -## 简介 - -- DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface \(MIPI\) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设\(通常是LCD或者类似的显示设备\),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。 - -- MIPI-DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。 - - 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。 - - **图 1** DSI发送、接收接口 - ![](figures/DSI发送-接收接口.png "DSI发送-接收接口") - - - -## 接口说明 - -**表 1** MIPI-DSI API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

设置/获取当前MIPI-DSI相关配置

-

MipiDsiSetCfg

-

设置MIPI-DSI相关配置

-

MipiDsiGetCfg

-

获取当前MIPI-DSI相关配置

-

获取/释放MIPI-DSI操作句柄

-

MipiDsiOpen

-

获取MIPI-DSI操作句柄

-

MipiDsiClose

-

释放MIPI-DSI操作句柄

-

设置MIPI-DSI进入Low power模式/High speed模式

-

MipiDsiSetLpMode

-

设置MIPI-DSI进入Low power模式

-

MipiDsiSetHsMode

-

设置MIPI-DSI进入High speed模式

-

MIPI-DSI发送/回读指令

-

MipiDsiTx

-

MIPI-DSI发送相应指令的接口

-

MipiDsiRx

-

MIPI-DSI按期望长度回读的接口

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用 - diff --git a/zh-cn/device-dev/driver/RTC.md b/zh-cn/device-dev/driver/RTC.md deleted file mode 100755 index de745a39f9bbe657f60ac09e4dcfac7bd225b829..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/RTC.md +++ /dev/null @@ -1,9 +0,0 @@ -# RTC - -- **[RTC概述](RTC概述.md)** - -- **[RTC使用指导](RTC使用指导.md)** - -- **[RTC使用实例](RTC使用实例.md)** - - diff --git "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index d413efda41b8fbc48a7f5c6b8837dbc8aef2c480..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,97 +0,0 @@ -# RTC使用实例 - -本实例提供RTC接口的完整使用流程: - -1. 系统启动,驱动管理模块会识别系统当前的RTC器件; -2. 驱动管理模块完成RTC设备的初始化和设备创建; -3. 用户通过不同API,对该RTC设备进行对应的操作; -4. 关闭RTC设备,释放设备资源。 - -示例如下: - -``` -#include "rtc_if.h" -int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) -{ - if (alarmIndex == RTC_ALARM_INDEX_A) { - /* 报警A的处理 */ - printf("RTC Alarm A callback function\n\r"); - } else if (alarmIndex == RTC_ALARM_INDEX_B) { - /* 报警B的处理 */ - printf("RTC Alarm B callback function\n\r"); - } else { - /* 错误处理 */ - } - return 0; -} - -void RtcTestSample(void) -{ - int32_t ret; - struct RtcTime tm; - struct RtcTime alarmTime; - uint32_t freq; - DevHandle handle = NULL; - - /* 获取RTC设备句柄 */ - handle = RtcOpen(); - if (handle == NULL) { - /* 错误处理 */ - } - /* 注册报警A的定时回调函数 */ - ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ - freq = 32768; /* 32768 Hz */ - ret = RtcSetFreq(handle, freq); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC报警中断使能 */ - ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC时间为2020/01/01 00:00:10 .990 */ - tm.year = 2020; - tm.month = 01; - tm.day = 01; - tm.hour= 0; - tm.minute = 0; - tm.second = 10; - tm.millisecond = 990; - /* 写RTC时间信息 */ - ret = RtcWriteTime(handle, &tm); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC报警时间为2020/01/01 00:00:30 .100 */ - alarmTime.year = 2020; - alarmTime.month = 01; - alarmTime.day = 01; - alarmTime.hour = 0; - alarmTime.minute = 0; - alarmTime.second = 30; - alarmTime.millisecond = 100; - /* 设置RTC_ALARM_INDEX_A索引定时报警时间信息, 定时时间到后会打印"RTC Alarm A callback function" */ - ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); - if (ret != 0) { - /* 错误处理 */ - } - - /* 读取RTC实时时间 */ - ret = RtcReadTime(handle, &tm); - if (ret != 0) { - /* 错误处理 */ - } - sleep(5) - printf("RTC read time:\n\r"); - printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", - tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); - /* 销毁RTC设备句柄 */ - RtcClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 45065165bd233fa2a09b4f8843b40c2325786823..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,741 +0,0 @@ -# RTC使用指导 - -- [使用流程](#section620515765714) -- [创建RTC设备句柄](#section0702183665711) -- [销毁RTC设备句柄](#section639962619542) -- [注册RTC定时报警回调函数](#section123631358135713) -- [操作RTC](#section11091522125812) - -## 使用流程 - -在操作系统启动过程中,驱动管理模块根据配置文件加载RTC驱动,RTC驱动会检测RTC器件并初始化驱动。 - -使用RTC设备的一般流程如[图1](#fig166181128151112)所示。 - -**图 1** RTC设备使用流程图 - - -![](figures/zh-cn_image_0000001054728498.png) - -## 创建RTC设备句柄 - -RTC驱动加载成功后,驱动开发者使用驱动框架提供的查询接口并调用RTC设备驱动接口。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前操作系统支持一个RTC设备。 - -DevHandle RtcOpen\(void\); - -**表 1** RtcOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

void

-

NA

-

返回值

-

返回值描述

-

handle

-

操作成功返回 指针类型

-

NULL

-

操作失败

-
- -``` -DevHandle handle = NULL; - -/* 获取RTC句柄 */ -handle = RtcOpen(); -if (handle == NULL) { - /* 错误处理 */ -} -``` - -## 销毁RTC设备句柄 - -销毁RTC设备句柄,系统释放对应的资源。 - -void RtcClose\(DevHandle handle\); - -**表 2** RtcClose参数描述 - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-
- -``` -/* 销毁RTC句柄 */ -RtcClose(handle); -``` - -## 注册RTC定时报警回调函数 - -系统启动后需要注册RTC定时报警回调函数,报警超时后触发回调函数。 - -int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\); - -**表 3** RtcRegisterAlarmCallback参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

cb

-

定时报警回调函数

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -注册RTC\_ALARM\_INDEX\_A的定时报警处理函数, 示例如下: - -``` -/* 用户注册RTC定时报警回调函数的方法 */ -int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) -{ - if (alarmIndex == RTC_ALARM_INDEX_A) { - /* 报警A的处理 */ - } else if (alarmIndex == RTC_ALARM_INDEX_B) { - /* 报警B的处理 */ - } else { - /* 错误处理 */ - } - return 0; -} -int32_t ret; -/* 注册报警A的定时回调函数 */ -ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); -if (ret != 0) { - /* 错误处理 */ -} -``` - -## 操作RTC - -- 读取RTC时间。 - -系统从RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒,则可以通过以下函数完成: - -int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\); - -**表 4** RtcReadTime参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

time

-

RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -struct RtcTime tm; - -/* 系统从RTC读取时间信息 */ -ret = RtcReadTime(handle, &tm); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置RTC时间 - -设置RTC时间,则可以通过以下函数完成: - -int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\); - -**表 5** RtcWriteTime参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

time

-

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 - -``` -int32_t ret; -struct RtcTime tm; - -/* 设置RTC时间为 UTC 2020/01/01 00:59:00 .000 */ -tm.year = 2020; -tm.month = 01; -tm.day = 01; -tm.hour= 00; -tm.minute = 59; -tm.second = 00; -tm.millisecond = 0; -/* 写RTC时间信息 */ -ret = RtcWriteTime(handle, &tm); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 读取RTC报警时间 - -如果需要读取定时报警时间,则可以通过以下函数完成: - -int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); - -**表 6** RtcReadAlarm参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

time

-

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -struct RtcTime alarmTime; - -/* 读RTC_ALARM_INDEX_A索引的RTC定时报警时间信息 */ -ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置RTC报警时间 - -根据报警索引设置RTC报警时间,通过以下函数完成: - -int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); - -**表 7** RtcWriteAlarm参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

time

-

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 - -``` -int32_t ret; -struct RtcTime alarmTime; - -/* 设置RTC报警时间为2020/01/01 00:59:59 .000 */ -alarmTime.year = 2020; -alarmTime.month = 01; -alarmTime.day = 01; -alarmTime.hour = 00; -alarmTime.minute = 59; -alarmTime.second = 59; -alarmTime.millisecond = 0; -/* 设置RTC_ALARM_INDEX_A索引的定时报警时间 */ -ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置定时报警中断使能或去使能 - -在启动报警操作前,需要先设置报警中断使能,报警超时后会触发告警回调函数,可以通过以下函数完成: - -int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\); - -**表 8** RtcAlarmInterruptEnable参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

enable

-

RTC报警中断配置,1:使能,0:去使能

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; - -/* 设置RTC报警中断使能 */ -ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 读取RTC外频 - -读取RTC外接晶体振荡频率,可以通过以下函数完成: - -int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\); - -**表 9** RtcGetFreq参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

freq

-

RTC的外接晶体振荡频率,单位(HZ)

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint32_t freq = 0; - -/* 读取RTC外接晶体振荡频率 */ -ret = RtcGetFreq(handle, &freq); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 配置RTC外频 - -配置RTC外接晶体振荡频率,可以通过以下函数完成: - -int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\); - -**表 10** RtcSetFreq参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

freq

-

RTC的外接晶体振荡频率,单位(HZ)

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint32_t freq = 32768; /* 32768 Hz */ - -/* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ -ret = RtcSetFreq(handle, freq); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 复位RTC - -复位RTC,复位RTC后各配置寄存器恢复默认值,可以通过以下函数完成: - -int32\_t RtcReset\(DevHandle handle\); - -**表 11** RtcReset参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; - -/* 复位RTC,复位RTC后各配置寄存器恢复默认值 */ -ret = RtcReset(handle); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 读取RTC自定义寄存器配置 - -按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: - -int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\); - -**表 12** RtcReadReg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

usrDefIndex

-

用户定义的寄存器对应索引

-

value

-

寄存器值

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义的第一个寄存器*/ -uint8_t value = 0; - -/* 按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值 */ -ret = RtcReadReg(handle, usrDefIndex, &value); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置RTC自定义寄存器配置 - -按照用户定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: - -int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\); - -**表 13** RtcWriteReg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

usrDefIndex

-

用户定义的寄存器对应索引

-

value

-

寄存器值

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义第一个寄存器*/ -uint8_t value = 0x10; - -/* 按照用户的定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值 */ -ret = RtcWriteReg(handle, usrDefIndex, value); -if (ret != 0) { - /* 错误处理 */ -} -``` - diff --git "a/zh-cn/device-dev/driver/RTC\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/RTC\346\246\202\350\277\260.md" deleted file mode 100755 index 19b903394cd28f79241b90a90db46a81f1d82529..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/RTC\346\246\202\350\277\260.md" +++ /dev/null @@ -1,103 +0,0 @@ -# RTC概述 - -- [简介](#section104842041574) -- [接口说明](#section16892932155715) - -## 简介 - -RTC\(real-time clock\)为操作系统中的实时时钟设备,为操作系统提供精准的实时时间和定时报警功能。当设备下电后,通过外置电池供电,RTC继续记录操作系统时间;设备上电后,RTC提供实时时钟给操作系统,确保断电后系统时间的连续性。 - -## 接口说明 - -**表 1** RTC设备API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

RTC句柄操作

-

RtcOpen

-

获取RTC设备驱动句柄

-

RtcClose

-

释放RTC设备驱动句柄

-

RTC时间操作接口

-

RtcReadTime

-

读RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

RtcWriteTime

-

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

RTC报警操作接口

-

RtcReadAlarm

-

读RTC报警时间信息

-

RtcWriteAlarm

-

写RTC报警时间信息

-

RtcRegisterAlarmCallback

-

注册报警超时回调函数

-

RtcAlarmInterruptEnable

-

使能/去使能RTC报警中断

-

RTC配置操作

-

RtcGetFreq

-

读RTC外接晶振频率

-

RtcSetFreq

-

配置RTC外接晶振频率

-

RtcReset

-

RTC复位

-

读写用户定义寄存器

-

RtcReadReg

-

读用户自定义寄存器

-

RtcWriteReg

-

写用户自定义寄存器

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/Readme-CN.md b/zh-cn/device-dev/driver/Readme-CN.md index f86ff0362ebca8304d36ae274a125ce7bd8e22bc..6651085f3517295a31202d656c994a57540fa765 100755 --- a/zh-cn/device-dev/driver/Readme-CN.md +++ b/zh-cn/device-dev/driver/Readme-CN.md @@ -1,73 +1,24 @@ -# 驱动 - -- [HDF驱动框架](HDF驱动框架.md) - - [HDF开发概述](HDF开发概述.md) - - [驱动开发](驱动开发.md) - - [驱动服务管理](驱动服务管理.md) - - [驱动消息机制管理](驱动消息机制管理.md) - - [配置管理](配置管理.md) - - [HDF开发实例](HDF开发实例.md) - -- [驱动平台](驱动平台.md) - - [GPIO](GPIO.md) - - [GPIO概述](GPIO概述.md) - - [GPIO使用指导](GPIO使用指导.md) - - [GPIO使用实例](GPIO使用实例.md) - - - [I2C](I2C.md) - - [I2C概述](I2C概述.md) - - [I2C使用指导](I2C使用指导.md) - - [I2C使用实例](I2C使用实例.md) - - - [RTC](RTC.md) - - [RTC概述](RTC概述.md) - - [RTC使用指导](RTC使用指导.md) - - [RTC使用实例](RTC使用实例.md) - - - [SDIO](SDIO.md) - - [SDIO概述](SDIO概述.md) - - [SDIO使用指导](SDIO使用指导.md) - - [SDIO使用实例](SDIO使用实例.md) - - - [SPI](SPI.md) - - [SPI概述](SPI概述.md) - - [SPI使用指导](SPI使用指导.md) - - [SPI使用实例](SPI使用实例.md) - - - [UART](UART.md) - - [UART概述](UART概述.md) - - [UART使用指导](UART使用指导.md) - - [UART使用实例](UART使用实例.md) - - - [WATCHDOG](WATCHDOG.md) - - [看门狗概述](看门狗概述.md) - - [看门狗使用指导](看门狗使用指导.md) - - [看门狗使用实例](看门狗使用实例.md) - - - [MIPI DSI](MIPI-DSI.md) - - [MIPI DSI概述](MIPI-DSI概述.md) - - [MIPI DSI使用指导](MIPI-DSI使用指导.md) - - [MIPI DSI使用实例](MIPI-DSI使用实例.md) - -- [外设](外设.md) - - [LCD](LCD.md) - - [LCD开发概述](LCD开发概述.md) - - [LCD开发指导](LCD开发指导.md) - - [LCD开发实例](LCD开发实例.md) - - - [TOUCHSCREEN](TOUCHSCREEN.md) - - [Touchscreen开发概述](Touchscreen开发概述.md) - - [Touchscreen开发指导](Touchscreen开发指导.md) - - [Touchscreen开发实例](Touchscreen开发实例.md) - - - [SENSOR](SENSOR.md) - - [传感器驱动开发概述](传感器驱动开发概述.md) - - [传感器驱动开发指导](传感器驱动开发指导.md) - - [传感器驱动开发实例](传感器驱动开发实例.md) - - [传感器驱动测试指导](传感器驱动测试指导.md) - - - [WLAN](WLAN.md) - - [WLAN开发概述](WLAN开发概述.md) - - [WLAN开发指导](WLAN开发指导.md) - - [WLAN开发实例](WLAN开发实例.md) +# 驱动使用指南 + +- [HDF驱动框架](driver.md) + - [HDF开发概述](driver-hdf-overview.md) + - [驱动开发](driver-hdf-development.md) + - [驱动服务管理](driver-hdf-servicemanage.md) + - [驱动消息机制管理](driver-hdf-news.md) + - [配置管理](driver-hdf-manage.md) + - [HDF开发实例](driver-hdf-sample.md) +- [平台驱动](driver-platform.md) + - [GPIO](driver-platform-gpio-des.md) + - [I2C](driver-platform-i2c-des.md) + - [RTC](driver-platform-rtc-des.md) + - [SDIO](driver-platform-sdio-des.md) + - [SPI](driver-platform-spi-des.md) + - [UART](driver-platform-uart-des.md) + - [WATCHDOG](driver-platform-watchdog-des.md) + - [MIPI DSI](driver-platform-mipidsi-des.md) +- [外设](driver-peripherals.md) + - [LCD](driver-peripherals-lcd-des.md) + - [TOUCHSCREEN](driver-peripherals-touch-des.md) + - [SENSOR](driver-peripherals-sensor-des.md) + - [WLAN](driver-peripherals-external-des.md) diff --git a/zh-cn/device-dev/driver/SDIO.md b/zh-cn/device-dev/driver/SDIO.md deleted file mode 100755 index 192dd216b5df44ef51ede3e7ac9dab09eaca828a..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/SDIO.md +++ /dev/null @@ -1,9 +0,0 @@ -# SDIO - -- **[SDIO概述](SDIO概述.md)** - -- **[SDIO使用指导](SDIO使用指导.md)** - -- **[SDIO使用实例](SDIO使用实例.md)** - - diff --git "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 18ddb74593b5ea69a427ecd03e8a41394daae174..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,129 +0,0 @@ -# SDIO使用实例 - -SDIO设备完整的使用示例如下所示,首先打开总线号为1的SDIO控制器,然后独占HOST、使能设备、注册中断,接着进行SDIO通信(读写等),通信完成之后,释放中断、去使能设备、释放HOST,最后关闭SDIO控制器。 - -``` -#include "hdf_log.h" -#include "sdio_if.h" - -#define TEST_FUNC_NUM 1 /* 本测试用例中,使用编号为1的I/O function */ -#define TEST_FBR_BASE_ADDR 0x100 /* 编号为1的I/O function的FBR基地址 */ -#define TEST_ADDR_OFFSET 9 /* 本测试用例中,需要读写的寄存器的地址偏移 */ -#define TEST_DATA_LEN 3 /* 本测试用例中,读写数据的长度 */ -#define TEST_BLOCKSIZE 2 /* 本测试用例中,数据块的大小,单位字节 */ - -/* 中断服务函数,需要根据各自平台的情况去实现 */ -static void SdioIrqFunc(void *data) -{ - if (data == NULL) { - HDF_LOGE("SdioIrqFunc: data is NULL.\n"); - return; - } - /* 需要开发者自行添加具体的实现 */ -} - -void SdioTestSample(void) -{ - int32_t ret; - DevHandle handle = NULL; - uint8_t data[TEST_DATA_LEN] = {0}; - struct SdioFunctionConfig config = {1, 0x123, 0x456}; - uint8_t val; - uint32_t addr; - - /* 打开总线号为1的SDIO设备 */ - handle = SdioOpen(1, &config); - if (handle == NULL) { - HDF_LOGE("SdioOpen: failed!\n"); - return; - } - /* 独占HOST */ - SdioClaimHost(handle); - /* 使能SDIO设备 */ - ret = SdioEnableFunc(handle); - if (ret != 0) { - HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); - goto ENABLE_ERR; - } - /* 注册中断 */ - ret = SdioClaimIrq(handle, SdioIrqFunc); - if (ret != 0) { - HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); - goto CLAIM_IRQ_ERR; - } - /* 设置块大小为2字节 */ - ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE); - if (ret != 0) { - HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO设备增量地址读取3字节的数据 */ - addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET; - ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN); - if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO设备增量地址写入3字节的数据 */ - ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN); - if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO设备读取1字节的数据 */ - ret = SdioReadBytes(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO设备写入1字节的数据 */ - ret = SdioWriteBytes(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO设备固定地址读取3字节的数据 */ - ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO设备固定地址写入1字节的数据 */ - ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO function 0读取1字节的数据 */ - addr = 0x02; - ret = SdioReadBytesFromFunc0(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO function 0写入1字节的数据 */ - ret = SdioWriteBytesToFunc0(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); - goto COMM_ERR; - } -COMM_ERR: - /* 释放中断 */ - ret = SdioReleaseIrq(handle); - if (ret != 0) { - HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); - } -CLAIM_IRQ_ERR: - /* 去使能SDIO设备 */ - ret = SdioDisableFunc(handle); - if (ret != 0) { - HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); - } -ENABLE_ERR: - /* 释放HOST */ - SdioReleaseHost(handle); - /* 关闭SDIO设备 */ - SdioClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index fd65e6de6adcef6ef307018c850ca1cb513d3b1f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,787 +0,0 @@ -# SDIO使用指导 - -- [使用流程](#section1962415610383) -- [打开SDIO控制器](#section814751015461) -- [独占HOST](#section49274582455) -- [使能SDIO设备](#section1431520410489) -- [注册SDIO中断](#section3662781537) -- [进行SDIO通信](#section391941913484) -- [释放SDIO中断](#section56205204481) -- [去使能SDIO设备](#section181181621124815) -- [释放HOST](#section657117215486) -- [关闭SDIO控制器](#section1898172114818) - -## 使用流程 - -使用SDIO的一般流程如[图1](SPI使用指导.md#fig23885455594)所示。 - -**图 1** SDIO使用流程图 - - -![](figures/zh-cn_image_0000001054440624.png) - -## 打开SDIO控制器 - -在使用SDIO进行通信前,首先要调用SdioOpen获取SDIO控制器的设备句柄,该函数会返回指定总线号的SDIO控制器的设备句柄。 - -DevHandle SdioOpen\(int16\_t mmcBusNum, struct SdioFunctionConfig \*config\); - -**表 1** SdioOpen函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

mmcBusNum

-

总线号

-

config

-

SDIO功能配置信息

-

返回值

-

返回值描述

-

NULL

-

获取SDIO控制器的设备句柄失败

-

设备句柄

-

SDIO控制器的设备句柄

-
- -打开SDIO控制器的示例如下: - -``` -DevHandle handle = NULL; -struct SdioFunctionConfig config; -config.funcNr = 1; -config.vendorId = 0x123; -config.deviceId = 0x456; -/* 打开总线号为1的SDIO控制器 */ -handle = SdioOpen(1, &config); -if (handle == NULL) { - HDF_LOGE("SdioOpen: failed!\n"); -} -``` - -## 独占HOST - -获取到SDIO控制器的设备句柄之后,需要先独占HOST才能进行SDIO后续的一系列操作,独占HOST函数如下所示: - -void SdioClaimHost\(DevHandle handle\); - -**表 2** SdioClaimHost函数的参数描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-
- -独占HOST示例如下: - -``` -SdioClaimHost(handle); /* 独占HOST */ -``` - -## 使能SDIO设备 - -在访问寄存器之前,需要先使能SDIO设备,使能SDIO设备的函数如下所示: - -int32\_t SdioEnableFunc\(DevHandle handle\); - -**表 3** SdioEnableFunc函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

返回值

-

返回值描述

-

0

-

SDIO使能成功

-

负数

-

SDIO使能失败

-
- -使能SDIO设备的示例如下: - -``` -int32_t ret; -/* 使能SDIO设备 */ -ret = SdioEnableFunc(handle); -if (ret != 0) { - HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); -} -``` - -## 注册SDIO中断 - -在通信之前,还需要注册SDIO中断,注册SDIO中断函数如下图所示: - -int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\); - -**表 4** SdioClaimIrq函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

handler

-

中断服务函数指针

-

返回值

-

返回值描述

-

0

-

注册中断成功

-

负数

-

注册中断失败

-
- -注册SDIO中的示例如下: - -``` -/* 中断服务函数需要根据各自平台的情况去实现 */ -static void SdioIrqFunc(void *data) -{ - if (data == NULL) { - HDF_LOGE("SdioIrqFunc: data is NULL.\n"); - return; - } - /* 需要开发者自行添加具体实现 */ -} - -int32_t ret; -/* 注册SDIO中断 */ -ret = SdioClaimIrq(handle, SdioIrqFunc); -if (ret != 0) { - HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); -} -``` - -## 进行SDIO通信 - -- 向SDIO设备增量写入指定长度的数据 - -对应的接口函数如下所示: - -int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 5** SdioWriteBytes函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

待写入数据的指针

-

addr

-

待写入数据的起始地址

-

size

-

待写入数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO写数据成功

-

负数

-

SDIO写数据失败

-
- -向SDIO设备增量写入指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t wbuff[] = {1,2,3,4,5}; -uint32_t addr = 0x100 + 0x09; -/* 向SDIO设备起始地址0x109,增量写入5个字节的数据 */ -ret = SdioWriteBytes(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0])); -if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); -} -``` - -- 从SDIO设备增量读取指定长度的数据 - -对应的接口函数如下所示: - -int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 6** SdioReadBytes函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

接收读取数据的指针

-

addr

-

待读取数据的起始地址

-

size

-

待读取数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO读数据成功

-

负数

-

SDIO读数据失败

-
- -从SDIO设备增量读取指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t rbuff[5] = {0}; -uint32_t addr = 0x100 + 0x09; -/* 从SDIO设备起始地址0x109,增量读取5个字节的数据 */ -ret = SdioReadBytes(handle, rbuff, addr, 5); -if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); -} -``` - -- 向SDIO设备的固定地址写入指定长度的数据 - - 对应的接口函数如下所示: - - int32\_t SdioWriteBytesToFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); - - **表 7** SdioWriteBytesToFixedAddr函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

待写入数据的指针

-

addr

-

待写入数据的固定地址

-

size

-

待写入数据的长度

-

scatterLen

-

集散表的长度。如果该字段不为0,则data为集散表类型。

-

返回值

-

返回值描述

-

0

-

SDIO写数据成功

-

负数

-

SDIO写数据失败

-
- - 向SDIO设备的固定地址写入指定长度的数据的示例如下: - - ``` - int32_t ret; - uint8_t wbuff[] = {1,2,3,4,5}; - uint32_t addr = 0x100 + 0x09; - /* 向SDIO设备固定地址0x109写入5个字节的数据 */ - ret = SdioWriteBytesToFixedAddr(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0]), 0); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); - } - ``` - -- 从SDIO设备的固定地址读取指定长度的数据 - - 对应的接口函数如下所示: - - int32\_t SdioReadBytesFromFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); - - **表 8** SdioReadBytesFromFixedAddr函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

接收读取数据的指针

-

addr

-

待读取数据的起始地址

-

size

-

待读取数据的长度

-

scatterLen

-

集散表的长度。如果该字段不为0,则data为集散表类型。

-

返回值

-

返回值描述

-

0

-

SDIO读数据成功

-

负数

-

SDIO读数据失败

-
- - 从SDIO设备的固定地址读取指定长度的数据的示例如下: - - ``` - int32_t ret; - uint8_t rbuff[5] = {0}; - uint32_t addr = 0x100 + 0x09; - /* 从SDIO设备固定地址0x109中读取5个字节的数据 */ - ret = SdioReadBytesFromFixedAddr(handle, rbuff, addr, 5, 0); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); - } - ``` - - -- 向SDIO function 0的指定地址空间写入指定长度的数据 - -当前只支持写入一个字节的数据,对应的接口函数如下所示: - -int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 9** SdioWriteBytesToFunc0函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

待写入数据的指针

-

addr

-

待写入数据的起始地址

-

size

-

待写入数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO写数据成功

-

负数

-

SDIO写数据失败

-
- -向SDIO function 0的指定地址空间写入指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t wbuff = 1; -/* 向SDIO function 0地址0x2中写入1字节的数据 */ -ret = SdioWriteBytesToFunc0(handle, &wbuff, 0x2, 1); -if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); -} -``` - -- 从SDIO function 0的指定地址空间读取指定长度的数据 - -当前只支持读取一个字节的数据,对应的接口函数如下所示: - -int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 10** SdioReadBytesFromFunc0函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

接收读取数据的指针

-

addr

-

待读取数据的起始地址

-

size

-

待读取数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO读数据成功

-

负数

-

SDIO读数据失败

-
- -从SDIO function 0的指定地址空间读取指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t rbuff; -/* 从SDIO function 0设备地址0x2中读取1字节的数据 */ -ret = SdioReadBytesFromFunc0(handle, &rbuff, 0x2, 1); -if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); -} -``` - -## 释放SDIO中断 - -通信完成之后,需要释放SDIO中断,函数如下所示: - -int32\_t SdioReleaseIrq\(DevHandle handle\); - -**表 11** SdioReleaseIrq函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

返回值

-

返回值描述

-

0

-

释放SDIO中断成功

-

负数

-

释放SDIO中断失败

-
- -释放SDIO中断的示例如下: - -``` -int32_t ret; -/* 释放SDIO中断 */ -ret = SdioReleaseIrq(handle); -if (ret != 0) { - HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); -} -``` - -## 去使能SDIO设备 - -通信完成之后,还需要去使能SDIO设备,函数如下所示: - -int32\_t SdioDisableFunc\(DevHandle handle\); - -**表 12** SdioDisableFunc函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

返回值

-

返回值描述

-

0

-

去使能SDIO设备成功

-

负数

-

去使能SDIO设备失败

-
- -去使能SDIO设备的示例如下: - -``` -int32_t ret; -/* 去使能SDIO设备 */ -ret = SdioDisableFunc(handle); -if (ret != 0) { - HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); -} -``` - -## 释放HOST - -通信完成之后,还需要释放去HOST,函数如下所示: - -void SdioReleaseHost\(DevHandle handle\); - -**表 13** SdioReleaseHost函数的参数描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-
- -释放HOST的示例如下: - -``` -SdioReleaseHost(handle); /* 释放HOST */ -``` - -## 关闭SDIO控制器 - -SDIO通信完成之后,最后需要关闭SDIO控制器,函数如下所示: - -void SdioClose\(DevHandle handle\); - -该函数会释放掉申请的资源。 - -**表 14** SdioClose函数的参数描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-
- -关闭SDIO控制器的示例如下: - -``` -SdioClose(handle); /* 关闭SDIO控制器 */ -``` - diff --git "a/zh-cn/device-dev/driver/SDIO\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/SDIO\346\246\202\350\277\260.md" deleted file mode 100755 index 69b74874472f27c6f3d737e8383f80708ae654a7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SDIO\346\246\202\350\277\260.md" +++ /dev/null @@ -1,149 +0,0 @@ -# SDIO概述 - -- [简介](#section1155271783811) -- [接口说明](#section10204143763819) - -## 简介 - -- SDIO是安全数字输入输出接口(Secure Digital Input and Output)的缩写,是从SD内存卡接口的基础上演化出来的一种外设接口。SDIO接口兼容以前的SD内存卡,并且可以连接支持SDIO接口的设备。 -- SDIO的应用比较广泛,目前,有许多手机都支持SDIO功能,并且很多SDIO外设也被开发出来,使得手机外接外设更加容易。常见的SDIO外设有WLAN、GPS、CAMERA、蓝牙等。 -- SDIO总线有两端,其中一端是主机端(HOST),另一端是设备端(DEVICE)。所有的通信都是由HOST端发出命令开始的,在DEVICE端只要能解析HOST的命令,就可以同HOST进行通信了。SDIO的HOST可以连接多个DEVICE,如下图所示: - - - CLK信号:HOST给DEVICE的时钟信号。 - - VDD信号:电源信号。 - - VSS信号:Ground信号。 - - D0-3信号:4条数据线,其中,DAT1信号线复用为中断线,在1BIT模式下DAT0用来传输数据,在4BIT模式下DAT0-DAT3用来传输数据。 - - CMD信号:用于HOST发送命令和DEVICE回复响应。 - - **图 1** SDIO的HOST-DEVICE连接示意图 - - - ![](figures/zh-cn_image_0000001054280608.png) - -- SDIO接口定义了操作SDIO的通用方法集合,包括打开/关闭SDIO控制器、独占/释放HOST、使能/去使能设备、申请/释放中断、读写、获取/设置公共信息等。 - -## 接口说明 - -**表 1** SDIO驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

SDIO设备打开/关闭接口

-

SdioOpen

-

打开指定总线号的SDIO控制器

-

SdioClose

-

关闭SDIO控制器

-

SDIO读写接口

-

SdioReadBytes

-

从指定地址开始,增量读取指定长度的数据

-

SdioWriteBytes

-

从指定地址开始,增量写入指定长度的数据

-

SdioReadBytesFromFixedAddr

-

从固定地址读取指定长度的数据

-

SdioWriteBytesToFixedAddr

-

向固定地址写入指定长度的数据

-

SdioReadBytesFromFunc0

-

从SDIO function 0的指定地址空间读取指定长度的数据

-

SdioWriteBytesToFunc0

-

向SDIO function 0的指定地址空间写入指定长度的数据

-

SDIO设置块大小接口

-

SdioSetBlockSize

-

设置块的大小

-

SDIO获取/设置公共信息接口

-

SdioGetCommonInfo

-

获取公共信息

-

SdioSetCommonInfo

-

设置公共信息

-

SDIO刷新数据接口

-

SdioFlushData

-

刷新数据

-

SDIO独占/释放HOST接口

-

SdioClaimHost

-

独占Host

-

SdioReleaseHost

-

释放Host

-

SDIO使能/去使能功能设备接口

-

SdioEnableFunc

-

使能SDIO功能设备

-

SdioDisableFunc

-

去使能SDIO功能设备

-

SDIO申请/释放中断接口

-

SdioClaimIrq

-

申请中断

-

SdioReleaseIrq

-

释放中断

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,目前只支持在内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/SENSOR.md b/zh-cn/device-dev/driver/SENSOR.md deleted file mode 100755 index 5907809028cf4b2f14cf484c96adbd8c25a57db2..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/SENSOR.md +++ /dev/null @@ -1,11 +0,0 @@ -# SENSOR - -- **[传感器驱动开发概述](传感器驱动开发概述.md)** - -- **[传感器驱动开发指导](传感器驱动开发指导.md)** - -- **[传感器驱动开发实例](传感器驱动开发实例.md)** - -- **[传感器驱动测试指导](传感器驱动测试指导.md)** - - diff --git a/zh-cn/device-dev/driver/SPI.md b/zh-cn/device-dev/driver/SPI.md deleted file mode 100755 index 394692a78397c81a270b1cc0e5e944c4837336ab..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/SPI.md +++ /dev/null @@ -1,9 +0,0 @@ -# SPI - -- **[SPI概述](SPI概述.md)** - -- **[SPI使用指导](SPI使用指导.md)** - -- **[SPI使用实例](SPI使用实例.md)** - - diff --git "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 4c3a6280301b448fad37b861d0028fd737ef2f82..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,70 +0,0 @@ -# SPI使用实例 - -SPI设备完整的使用示例如下所示,首先获取SPI设备句柄,然后配置SPI设备属性,接着调用读写接口进行数据传输,最后销毁SPI设备句柄。 - -``` -#include "hdf_log.h" -#include "spi_if.h" - -void SpiTestSample(void) -{ - int32_t ret; - struct SpiCfg cfg; /* SPI配置信息 */ - struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ - DevHandle spiHandle = NULL; /* SPI设备句柄 */ - struct SpiMsg msg; /* 自定义传输的消息 */ - uint8_t rbuff[4] = { 0 }; - uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; - uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; - - spiDevinfo.busNum = 0; /* SPI设备总线号 */ - spiDevinfo.csNum = 0; /* SPI设备片选号 */ - spiHandle = SpiOpen(&spiDevinfo); /* 根据spiDevinfo获取SPI设备句柄 */ - if (spiHandle == NULL) { - HDF_LOGE("SpiOpen: failed\n"); - return; - } - /* 获取SPI设备属性 */ - ret = SpiGetCfg(spiHandle, &cfg); - if (ret != 0) { - HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); - goto err; - } - cfg.maxSpeedHz = 115200; /* 将最大时钟频率改为115200 */ - cfg.bitsPerWord = 8; /* 传输位宽改为8比特 */ - /* 配置SPI设备属性 */ - ret = SpiSetCfg(spiHandle, &cfg); - if (ret != 0) { - HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); - goto err; - } - /* 向SPI设备写入指定长度的数据 */ - ret = SpiWrite(spiHandle, wbuff, 4); - if (ret != 0) { - HDF_LOGE("SpiWrite: failed, ret %d\n", ret); - goto err; - } - /* 从SPI设备读取指定长度的数据 */ - ret = SpiRead(spiHandle, rbuff, 4); - if (ret != 0) { - HDF_LOGE("SpiRead: failed, ret %d\n", ret); - goto err; - } - msg.wbuf = wbuff2; /* 写入的数据 */ - msg.rbuf = rbuff; /* 读取的数据 */ - msg.len = 4; /* 读取写入数据的长度为4 */ - msg.csChange = 1; /* 进行下一次传输前关闭片选 */ - msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ - msg.speed = 115200; /* 本次传输的速度 */ - /* 进行一次自定义传输,传输的msg个数为1 */ - ret = SpiTransfer(spiHandle, &msg, 1); - if (ret != 0) { - HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); - goto err; - } -err: - /* 销毁SPI设备句柄 */ - SpiClose(spiHandle); -} -``` - diff --git "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 58698a9460cefc157fd27f41bfb3978a1547fdfc..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,386 +0,0 @@ -# SPI使用指导 - -- [使用流程](#section691514116412) -- [获取SPI设备句柄](#section12372204616215) -- [获取SPI设备属性](#section17121446171311) -- [配置SPI设备属性](#section97691946634) -- [进行SPI通信](#section197116254416) -- [销毁SPI设备句柄](#section117661819108) - -## 使用流程 - -使用SPI的一般流程如[图1](#fig23885455594)所示。 - -**图 1** SPI使用流程图 - - -![](figures/zh-cn_image_0000001054726248.png) - -## 获取SPI设备句柄 - -在使用SPI进行通信时,首先要调用SpiOpen获取SPI设备句柄,该函数会返回指定总线号和片选号的SPI设备句柄。 - -DevHandle SpiOpen\(const struct SpiDevInfo \*info\); - -**表 1** SpiOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

info

-

SPI设备描述符

-

返回值

-

返回值描述

-

NULL

-

获取SPI设备句柄失败

-

设备句柄

-

对应的SPI设备句柄

-
- -假设系统中的SPI设备总线号为0,片选号为0,获取该SPI设备句柄的示例如下: - -``` -struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ -DevHandle spiHandle = NULL; /* SPI设备句柄 */ -spiDevinfo.busNum = 0; /* SPI设备总线号 */ -spiDevinfo.csNum = 0; /* SPI设备片选号 */ - -/* 获取SPI设备句柄 */ -spiHandle = SpiOpen(&spiDevinfo); -if (spiHandle == NULL) { - HDF_LOGE("SpiOpen: failed\n"); - return; -} -``` - -## 获取SPI设备属性 - -在获取到SPI设备句柄之后,需要配置SPI设备属性。配置SPI设备属性之前,可以先获取SPI设备属性,获取SPI设备属性的函数如下所示: - -int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\); - -**表 2** SpiGetCfg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

cfg

-

SPI设备配置参数

-

返回值

-

返回值描述

-

0

-

获取配置成功

-

负数

-

获取配置失败

-
- -``` -int32_t ret; -struct SpiCfg cfg = {0}; /* SPI配置信息*/ -ret = SpiGetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ -if (ret != 0) { - HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); -} -``` - -## 配置SPI设备属性 - -在获取到SPI设备句柄之后,需要配置SPI设备属性,配置SPI设备属性的函数如下所示: - -int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\); - -**表 3** SpiSetCfg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

cfg

-

SPI设备配置参数

-

返回值

-

返回值描述

-

0

-

配置成功

-

负数

-

配置失败

-
- -``` -int32_t ret; -struct SpiCfg cfg = {0}; /* SPI配置信息*/ -cfg.mode = SPI_MODE_LOOP; /* 以回环模式进行通信 */ -cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* 以轮询的方式进行通信 */ -cfg.maxSpeedHz = 115200; /* 最大传输频率 */ -cfg.bitsPerWord = 8; /* 读写位宽为8个比特 */ -ret = SpiSetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ -if (ret != 0) { - HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); -} -``` - -## 进行SPI通信 - -- 向SPI设备写入指定长度的数据 - -如果只向SPI设备写一次数据,则可以通过以下函数完成: - -int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); - -**表 4** SpiWrite参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

buf

-

待写入数据的指针

-

len

-

待写入的数据长度

-

返回值

-

返回值描述

-

0

-

写入成功

-

负数

-

写入失败

-
- -``` -int32_t ret; -uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78}; -/* 向SPI设备写入指定长度的数据 */ -ret = SpiWrite(spiHandle, wbuff, 4); -if (ret != 0) { - HDF_LOGE("SpiWrite: failed, ret %d\n", ret); -} -``` - -- 从SPI设备读取指定长度的数据 - -如果只读取一次数据,则可以通过以下函数完成: - -int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); - -**表 5** SpiRead参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

buf

-

待读取数据的指针

-

len

-

待读取的数据长度

-

返回值

-

返回值描述

-

0

-

读取成功

-

负数

-

读取失败

-
- -``` -int32_t ret; -uint8_t rbuff[4] = {0}; -/* 从SPI设备读取指定长度的数据 */ -ret = SpiRead(spiHandle, rbuff, 4); -if (ret != 0) { - HDF_LOGE("SpiRead: failed, ret %d\n", ret); -} -``` - -- 自定义传输 - -如果需要发起一次自定义传输,则可以通过以下函数完成: - -int32\_t SpiTransfer\(DevHandle handle, struct SpiMsg \*msgs, uint32\_t count\); - -**表 6** SpiTransfer参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

msgs

-

待传输数据的数组

-

count

-

msgs数组长度

-

返回值

-

返回值描述

-

0

-

执行成功

-

负数

-

执行失败

-
- -``` -int32_t ret; -uint8_t wbuff[1] = {0x12}; -uint8_t rbuff[1] = {0}; -struct SpiMsg msg; /* 自定义传输的消息*/ -msg.wbuf = wbuff; /* 写入的数据 */ -msg.rbuf = rbuff; /* 读取的数据 */ -msg.len = 1; /* 读取、写入数据的长度都是1 */ -msg.csChange = 1; /* 进行下一次传输前关闭片选 */ -msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ -msg.speed = 115200; /* 本次传输的速度 */ -/* 进行一次自定义传输,传输的msg个数为1 */ -ret = SpiTransfer(spiHandle, &msg, 1); -if (ret != 0) { - HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); -} -``` - -## 销毁SPI设备句柄 - -SPI通信完成之后,需要销毁SPI设备句柄,销毁SPI设备句柄的函数如下所示: - -void SpiClose\(DevHandle handle\); - -该函数会释放掉申请的资源。 - -**表 7** SpiClose参数描述 - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-
- -``` -SpiClose(spiHandle); /* 销毁SPI设备句柄 */ -``` - diff --git "a/zh-cn/device-dev/driver/SPI\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/SPI\346\246\202\350\277\260.md" deleted file mode 100755 index 3d3567489af059b7a5f56b8e072bdab95e190eab..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SPI\346\246\202\350\277\260.md" +++ /dev/null @@ -1,107 +0,0 @@ -# SPI概述 - -- [简介](#section9202632114011) -- [接口说明](#section1859594134119) - -## 简介 - -- SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线。 -- SPI是由Motorola公司开发,用于在主设备和从设备之间进行通信,常用于与闪存、实时时钟、传感器以及模数转换器等进行通信。 -- SPI以主从方式工作,通常有一个主设备和一个或者多个从设备。主设备和从设备之间一般用4根线相连,它们分别是: - - SCLK – 时钟信号,由主设备产生; - - MOSI – 主设备数据输出,从设备数据输入; - - MISO – 主设备数据输入,从设备数据输出; - - CS – 片选,从设备使能信号,由主设备控制。 - - -- 一个主设备和两个从设备的连接示意图如[图1](#fig15227181812587)所示,Device A和Device B共享主设备的SCLK、MISO和MOSI三根引脚,Device A的片选CS0连接主设备的CS0,Device B的片选CS1连接主设备的CS1。 - -**图 1** SPI主从设备连接示意图。 - - -![](figures/zh-cn_image_0000001054142582.png) - -- SPI通信通常由主设备发起,通过以下步骤完成一次通信: - -1. 通过CS选中要通信的从设备,在任意时刻,一个主设备上最多只能有一个从设备被选中。 -2. 通过SCLK给选中的从设备提供时钟信号。 -3. 基于SCLK时钟信号,主设备数据通过MOSI发送给从设备,同时通过MISO接收从设备发送的数据,完成通信。 - -- 根据SCLK时钟信号的CPOL(Clock Polarity,时钟极性)和CPHA(Clock Phase,时钟相位)的不同组合,SPI有以下四种工作模式: - - CPOL=0,CPHA=0 时钟信号idle状态为低电平,第一个时钟边沿采样数据。 - - CPOL=0,CPHA=1 时钟信号idle状态为低电平,第二个时钟边沿采样数据。 - - CPOL=1,CPHA=0 时钟信号idle状态为高电平,第一个时钟边沿采样数据。 - - CPOL=1,CPHA=1 时钟信号idle状态为高电平,第二个时钟边沿采样数据。 - - -- SPI接口定义了操作SPI设备的通用方法集合,包括: - - SPI设备句柄获取和释放。 - - SPI读写: 从SPI设备读取或写入指定长度数据。 - - SPI自定义传输:通过消息传输结构体执行任意读写组合过程。 - - SPI设备配置:获取和设置SPI设备属性。 - - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前只支持主机模式,不支持从机模式。 - -## 接口说明 - -**表 1** SPI驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

SPI设备句柄获取释放接口

-

SpiOpen

-

获取SPI设备句柄

-

SpiClose

-

释放SPI设备句柄

-

SPI读写接口

-

SpiRead

-

读取指定长度的数据

-

SpiWrite

-

写入指定长度的数据

-

SpiTransfer

-

SPI数据传输接口

-

SPI设备配置接口

-

-

SpiSetCfg

-

根据指定参数,配置SPI设备

-

SpiGetCfg

-

获取SPI设备配置参数

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/TOUCHSCREEN.md b/zh-cn/device-dev/driver/TOUCHSCREEN.md deleted file mode 100755 index ce5156c848cb3b1ae5403caeb17ae4d9714baadb..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/TOUCHSCREEN.md +++ /dev/null @@ -1,9 +0,0 @@ -# TOUCHSCREEN - -- **[Touchscreen开发概述](Touchscreen开发概述.md)** - -- **[Touchscreen开发指导](Touchscreen开发指导.md)** - -- **[Touchscreen开发实例](Touchscreen开发实例.md)** - - diff --git "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index a298d618c1547f7c66c6213a42563b3896ac80b2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,300 +0,0 @@ -# Touchscreen开发实例 - -- [设备描述配置](#section85281142102317) -- [板级配置及器件私有配置](#section189081946192410) -- [添加器件驱动](#section19856687253) - -本实例提供touchscreen驱动开发示例,并简要对具体关键点进行开发说明。 - -## 设备描述配置 - -如下配置主要包含input驱动模型各模块层级信息,具体原理可参考[HDF驱动开发指南](驱动开发.md),HDF框架依据该配置信息实现对Input模型各模块的依次加载等。 - -``` -input :: host { - hostName = "input_host"; - priority = 100; - device_input_manager :: device { - device0 :: deviceNode { - policy = 2; // 向外发布服务 - priority = 100; // 加载优先级,在input模块内,manager模块优先级应为最高 - preload = 0; // 加载该驱动 0:加载 1:不加载 - permission = 0660; - moduleName = "HDF_INPUT_MANAGER"; - serviceName = "input_dev_manager"; - deviceMatchAttr = ""; - } - } - device_hdf_touch :: device { - device0 :: deviceNode { - policy = 2; - priority = 120; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH"; - serviceName = "event1"; - deviceMatchAttr = "touch_device1"; - } - } - - device_touch_chip :: device { - device0 :: deviceNode { - policy = 0; - priority = 130; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH_SAMPLE"; - serviceName = "hdf_touch_sample_service"; - deviceMatchAttr = "zsj_sample_5p5"; - } - } -} -``` - -## 板级配置及器件私有配置 - -如下配置包含板级硬件配置及器件私有数据配置,实际业务开发时,可根据具体需求增删及修改如下配置文件信息。 - -``` -root { - input_config { - touchConfig { - touch0 { - boardConfig { - match_attr = "touch_device1"; - inputAttr { - inputType = 0; // 0代表触摸屏 - solutionX = 480; - solutionY = 960; - devName = "main_touch"; // 设备名称 - } - busConfig { - busType = 0; // 0代表I2C - busNum = 6; - clkGpio = 86; - dataGpio = 87; - i2cClkIomux = [0x114f0048, 0x403]; // i2c_clk对应pin的寄存器配置 - i2cDataIomux = [0x114f004c, 0x403]; // i2c_data对应pin的寄存器配置 - } - pinConfig { - rstGpio = 3; - intGpio = 4; - rstRegCfg = [0x112f0094, 0x400]; // reset对应pin的寄存器配置 - intRegCfg = [0x112f0098, 0x400]; // interrupt对应pin的寄存器配置 - } - powerConfig { - vccType = 2; // 1代表LDO、2代表GPIO、3代表PMIC - vccNum = 20; // GPIO号为20 - vccValue = 1800; // 电压幅值为1800mV - vciType = 1; - vciNum = 12; - vciValue = 3300; - } - featureConfig { - capacitanceTest = 0; - gestureMode = 0; - gloverMOde = 0; - coverMode = 0; - chargerMode = 0; - knuckleMode = 0; - } - } - chipConfig { - template touchChip { - match_attr = ""; - chipName = "sample"; - vendorName = "zsj"; - chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 - busType = 0; - deviceAddr = 0x5D; - irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 - maxSpeed = 400; - chipVersion = 0; - powerSequence { - /* 上电时序的配置含义说明: - [类型, 状态, 方向 , 延时] - 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 - 0代表下电或拉低,1代表上电或拉高,2代表无操作 - 0代表输入方向,1代表输出方向,2代表无操作 - 代表延时多少毫秒, 例如20代表延时20ms - */ - powerOnSeq = [4, 0, 1, 0, - 3, 0, 1, 10, - 3, 1, 2, 60, - 4, 2, 0, 0]; - suspendSeq = [3, 0, 2, 10]; - resumeSeq = [3, 1, 2, 10]; - powerOffSeq = [3, 0, 2, 10, - 1, 0, 2, 20]; - } - } - chip0 :: touchChip { - match_attr = "zsj_sample_5p5"; - chipInfo = "ZIDN45100"; - chipVersion = 0; - } - } - } - } - } -} -``` - -## 添加器件驱动 - -在器件驱动中,主要实现了平台预留的差异化接口,以器件数据获取及解析进行示例说明。具体开发过程,需要根据实际使用的单板及器件进行适配。 - -``` -/* 将从器件中读取到的报点数据解析为坐标 */ -static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) -{ - int32_t resX = device->driver->boardCfg->attr.resolutionX; - int32_t resY = device->driver->boardCfg->attr.resolutionY; - - for (int32_t i = 0; i < pointNum; i++) { - frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].valid = true; - } -} -/* 从器件中获取报点数据 */ -static int32_t ChipDataHandle(ChipDevice *device) -{ - int32_t ret; - uint8_t touchStatus = 0; - uint8_t pointNum; - uint8_t buf[GT_POINT_SIZE * MAX_SUPPORT_POINT] = {0}; - InputI2cClient *i2cClient = &device->driver->i2cClient; - uint8_t reg[GT_ADDR_LEN] = {0}; - FrameData *frame = &device->driver->frameData; - reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; - ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); - if (ret < 0 || touchStatus == GT_EVENT_INVALID) { - return HDF_FAILURE; - } - OsalMutexLock(&device->driver->mutex); - (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData)); - if (touchStatus == GT_EVENT_UP) { - frame->realPointNum = 0; - frame->definedEvent = TOUCH_UP; - goto exit; - } - reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; - pointNum = touchStatus & GT_FINGER_NUM_MASK; - if (pointNum <= 0 || pointNum > MAX_SUPPORT_POINT) { - HDF_LOGE("%s: pointNum is invalid, %d", __func__, pointNum); - (void)ChipCleanBuffer(i2cClient); - OsalMutexUnlock(&device->driver->mutex); - return HDF_FAILURE; - } - frame->realPointNum = pointNum; - frame->definedEvent = TOUCH_DOWN; - /* 从寄存器中读取报点值 */ - (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); - /* 解析报点值 */ - ParsePointData(device, frame, buf, pointNum); -exit: - OsalMutexUnlock(&device->driver->mutex); - if (ChipCleanBuffer(i2cClient) != HDF_SUCCESS) { - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -static struct TouchChipOps g_sampleChipOps = { - .Init = ChipInit, - .Detect = ChipDetect, - .Resume = ChipResume, - .Suspend = ChipSuspend, - .DataHandle = ChipDataHandle, -}; - -static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device) -{ - TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg)); - if (chipCfg == NULL) { - HDF_LOGE("%s: instance chip config failed", __func__); - return NULL; - } - (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg)); - /* 解析器件私有配置 */ - if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: parse chip config failed", __func__); - OsalMemFree(chipCfg); - chipCfg = NULL; - } - return chipCfg; -} - -static ChipDevice *ChipDeviceInstance(void) -{ - ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice)); - if (chipDev == NULL) { - HDF_LOGE("%s: instance chip device failed", __func__); - return NULL; - } - (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice)); - return chipDev; -} - -static void FreeChipConfig(TouchChipCfg *config) -{ - if (config->pwrSeq.pwrOn.buf != NULL) { - OsalMemFree(config->pwrSeq.pwrOn.buf); - } - if (config->pwrSeq.pwrOff.buf != NULL) { - OsalMemFree(config->pwrSeq.pwrOff.buf); - } - OsalMemFree(config); -} - -static int32_t HdfSampleChipInit(struct HdfDeviceObject *device) -{ - TouchChipCfg *chipCfg = NULL; - ChipDevice *chipDev = NULL; - HDF_LOGE("%s: enter", __func__); - if (device == NULL) { - return HDF_ERR_INVALID_PARAM; - } - /* 器件私有配置解析 */ - chipCfg = ChipConfigInstance(device); - if (chipCfg == NULL) { - return HDF_ERR_MALLOC_FAIL; - } - /* 器件设备实例化 */ - chipDev = ChipDeviceInstance(); - if (chipDev == NULL) { - goto freeCfg; - } - chipDev->chipCfg = chipCfg; - chipDev->ops = &g_sampleChipOps; - chipDev->chipName = chipCfg->chipName; - chipDev->vendorName = chipCfg->vendorName; - - /* 器件设备注册到平台驱动 */ - if (RegisterChipDevice(chipDev) != HDF_SUCCESS) { - goto freeDev; - } - HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName); - return HDF_SUCCESS; - -freeDev: - OsalMemFree(chipDev); -freeCfg: - FreeChipConfig(chipCfg); - return HDF_FAILURE; -} - -struct HdfDriverEntry g_touchSampleChipEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH_SAMPLE", - .Init = HdfSampleChipInit, -}; - -HDF_INIT(g_touchSampleChipEntry); -``` - diff --git "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 09dc518533e0397fd75711d33a582a7520c5af39..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,36 +0,0 @@ -# Touchscreen开发指导 - -- [开发步骤](#section1255740132616) - -Input驱动模型是基于HDF框架、Platform接口和OSAL接口开发,不区分操作系统和芯片平台,为touchscreen等输入器件提供统一的驱动开发架构。 - -- 如下以touchscreen器件驱动为例,说明input驱动模型的完整加载流程: - - (1)设备描述配置:由开发者参考已有模板进行设备描述配置,包括驱动加载顺序、板级硬件信息、器件私有数据信息等。 - - (2)加载input设备管理驱动:input设备管理驱动由HDF驱动加载,完成设备manager的创建并对其初始化。 - - (3)加载平台驱动:平台驱动由HDF框架加载,主要完成板级配置解析及硬件初始化,并提供器件注册接口。 - - (4)加载器件驱动:器件驱动也由HDF框架加载,完成器件设备的实例化,包括器件私有配置解析和平台预留的差异化接口适配。 - - (5)器件设备向平台驱动注册:将实例化的器件设备向平台驱动注册,实现设备和驱动的绑定,并完成中断注册、上下电等器件初始化工作。 - - (6)input设备注册:在器件初始化完成后,实例化input设备,并将其注册到input manager进行管理。 - - -## 开发步骤 - -1. 设备描述配置 - - 目前Input驱动基于HDF驱动框架编写,驱动的加载启动由HDF驱动管理框架统一处理。首先需要在对应的配置文件中,将驱动信息注册进去,如是否加载、加载优先级,此后HDF驱动框架会逐一启动注册过的驱动模块。驱动的相关配置请参考[HDF驱动框架配置指导](驱动开发.md#section1969312275533)。 - -2. 板级配置及Touchscreen器件私有配置 - - 配置对应的IO管脚功能,例如对单板上为touchscreen设计预留的I2C Pin脚,需设置对应的寄存器,使其选择I2C的通信功能。 - -3. 实现器件差异化适配接口 - - 根据硬件单板设计的通信接口,使用Platform接口层提供的管脚操作接口配置对应的复位管脚、中断管脚以及电源操作,对于GPIO的操作,可参考[GPIO操作接口指导](GPIO使用指导.md) - - diff --git "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index b6456936b0195199ef6f29d12e690492892bbda0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,71 +0,0 @@ -# Touchscreen开发概述 - -- [简介](#section124332411260) -- [接口说明](#section10542625172618) - -## 简介 - -- **Touchscreen驱动主要任务** - - Touchscreen驱动用于驱动触摸屏使其正常工作,该驱动主要完成如下工作:对触摸屏驱动IC进行上电、配置硬件管脚并初始化其状态、注册中断、配置通信接口(I2C或SPI)、设定input相关配置、下载及更新固件等操作。 - - -- **Touchscreen驱动层次说明** - - 本节主要介绍基于input驱动模型开发touchscreen器件驱动,其整体的框架模型如[图1](#fig6251184817261)。 - - Input驱动模型基于HDF驱动框架、PLATFORM接口、OSAL接口进行开发,向上对接规范化的驱动接口HDI(Hardware Driver Interface)层,通过Input-HDI层对外提供硬件能力,即上层input service可以通过HDI接口层获取相应的驱动能力,进而操控touchscreen等输入设备。 - - -**图 1** 基于HDF驱动框架的input驱动模型 -![](figures/基于HDF驱动框架的input驱动模型.png "基于HDF驱动框架的input驱动模型") - -- **Input驱动模型介绍** - - Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。器件产生的数据借助平台数据通道能力从内核传递到用户态,驱动模型通过配置文件适配不同器件及硬件平台,提高开发者的器件驱动开发效率。如下部分为模型各部分的说明: - - (1)input设备管理:为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; - - (2)input平台驱动:指各类input设备的公共抽象驱动(例如触摸屏的公共驱动),负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; - - (3)input器件驱动:指各器件厂家的差异化驱动,通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; - - (4)input数据通道:提供一套通用的数据上报通道,各类别的input设备驱动均可用此通道上报input事件; - - (5)input配置解析:负责对input设备的板级配置及器件私有配置进行解析及管理。 - - -- **基于HDF驱动框架开发器件驱动的优势** - - 在HDF(Hardware Driver Foundation)[驱动管理框架](驱动开发.md)的基础上,input驱动模型调用OSAL接口层和Platfom接口层提供的基础接口进行开发,包括bus通信接口、操作系统原生接口(memory、lock、thread、timer等)。由于OSAL接口和Platform接口屏蔽了芯片平台差异,所以基于input驱动模型实现的touchscreen驱动可以进行跨平台、跨OS迁移,以便逐步实现驱动的一次开发,多端部署。 - - -## 接口说明 - -Touchscreen器件的硬件接口相对简单,根据PIN脚的属性,可以简单分为如下三类: - -- 电源接口 -- IO控制接口 -- 通信接口 - -**图 2** Touchscreen器件常用管脚 -![](figures/Touchscreen器件常用管脚.png "Touchscreen器件常用管脚") - -如上图所示的三类接口,分别做简要说明如下: - -1. **电源接口** - - LDO\_1P8:1.8v数字电路 - - LDO\_3P3:3.3v模拟电路 - - 通常情况下,touchscreen驱动IC和LCD驱动IC是相互分离的,这种情况下,touchscreen驱动IC一般同时需要1.8v和3.3v两路供电。随着芯片演进,业内已有touchscreen驱动IC和LCD驱动IC集成在一颗IC中的芯片案例,对touchscreen而言,只需要关注1.8v供电即可,其内部需要的3.3v电源,会在驱动IC内部从LCD的VSP电源(典型值5.5V)中分出来。 - - -2. **IO控制接口** - - Reset:reset管脚,用于在系统休眠、唤醒时,由主机侧对驱动IC进行复位操作。 - - INT:中断管脚,需要在驱动初始化时,配置为输入上拉状态。在驱动IC检测到外部触摸信号后,通过操作中断管脚来触发中断,器件驱动则会在中断处理函数中进行报点数据读取等操作。 - -3. **通信接口** - - I2C:由于touchscreen的报点数据量相对较少,所以一般选用I2C方式传输数据。I2C的具体协议及对应操作接口,可以参考Platform接口层中的[“I2C”使用指南](I2C使用指导.md)。 - - SPI:部分厂商,由于需要传递的数据不止报点坐标,而是需要获取基础容值,数据量较大,所以会选用SPI通信方式。SPI的具体协议及对应操作接口,可以参考Platform接口层中的[“SPI” 使用指南](SPI使用指导.md)。 - - diff --git a/zh-cn/device-dev/driver/UART.md b/zh-cn/device-dev/driver/UART.md deleted file mode 100755 index 5d81f12e15f43bdf7e3302bc33cf1dddd524b4e9..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/UART.md +++ /dev/null @@ -1,9 +0,0 @@ -# UART - -- **[UART概述](UART概述.md)** - -- **[UART使用指导](UART使用指导.md)** - -- **[UART使用实例](UART使用实例.md)** - - diff --git "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index d049e3d021843a422c3e11b1fde5a10b57393070..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,67 +0,0 @@ -# UART使用实例 - -UART设备完整的使用示例如下所示,首先获取UART设备句柄,接着设置波特率、设备属性和传输模式,之后进行UART通信,最后销毁UART设备句柄。 - -``` -#include "hdf_log.h" -#include "uart_if.h" - -void UartTestSample(void) -{ - int32_t ret; - uint32_t port; - DevHandle handle = NULL; - uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; - uint8_t rbuff[5] = { 0 }; - struct UartAttribute attribute; - attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ - attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ - attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ - attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ - attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ - attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ - attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ - /* UART设备端口号,要填写实际平台上的端口号 */ - port = 1; - /* 获取UART设备句柄 */ - handle = UartOpen(port); - if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); - return; - } - /* 设置UART波特率为9600 */ - ret = UartSetBaud(handle, 9600); - if (ret != 0) { - HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); - goto _ERR; - } - /* 设置UART设备属性 */ - ret = UartSetAttribute(handle, &attribute); - if (ret != 0) { - HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); - goto _ERR; - } - /* 设置UART传输模式为非阻塞模式 */ - ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); - if (ret != 0) { - HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); - goto _ERR; - } - /* 向UART设备写入5字节的数据 */ - ret = UartWrite(handle, wbuff, 5); - if (ret != 0) { - HDF_LOGE("UartWrite: failed, ret %d\n", ret); - goto _ERR; - } - /* 从UART设备读取5字节的数据 */ - ret = UartRead(handle, rbuff, 5); - if (ret < 0) { - HDF_LOGE("UartRead: failed, ret %d\n", ret); - goto _ERR; - } -_ERR: - /* 销毁UART设备句柄 */ - UartClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 1d1ee50a8c13e37c506350820c71a5a7b4893d7f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,506 +0,0 @@ -# UART使用指导 - -- [使用流程](#section47784125013) -- [获取UART设备句柄](#section146445153110) -- [UART设置波特率](#section1862705516339) -- [UART获取波特率](#section1263651563414) -- [UART设置设备属性](#section1770091483814) -- [UART获取设备属性](#section117543316384) -- [设置UART传输模式](#section187233112369) -- [向UART设备写入指定长度的数据](#section82416423368) -- [从UART设备中读取指定长度的数据](#section192177171373) -- [销毁UART设备句柄](#section63131236354) - -## 使用流程 - -使用UART的一般流程如[图1](#p58686354483)所示。 - -**图 1** UART使用流程图 - - -![](figures/zh-cn_image_0000001054006983.png) - -## 获取UART设备句柄 - -在使用UART进行通信时,首先要调用UartOpen获取UART设备句柄,该函数会返回指定端口号的UART设备句柄。 - -DevHandle UartOpen\(uint32\_t port\); - -**表 1** UartOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

port

-

UART设备号

-

返回值

-

返回值描述

-

NULL

-

获取UART设备句柄失败

-

设备句柄

-

UART设备句柄

-
- -假设系统中的UART端口号为3,获取该UART设备句柄的示例如下: - -``` -DevHandle handle = NULL; /* UART设备句柄 */ -uint32_t port = 3; /* UART设备端口号 */ -handle = UartOpen(port); -if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); - return; -} -``` - -## UART设置波特率 - -在通信之前,需要设置UART的波特率,设置波特率的函数如下所示: - -int32\_t UartSetBaud\(DevHandle handle, uint32\_t baudRate\); - -**表 2** UartSetBaud参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

baudRate

-

待设置的波特率值

-

返回值

-

返回值描述

-

0

-

UART设置波特率成功

-

负数

-

UART设置波特率失败

-
- -假设需要设置的UART波特率为9600,设置波特率的实例如下: - -``` -int32_t ret; -/* 设置UART波特率 */ -ret = UartSetBaud(handle, 9600); -if (ret != 0) { - HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); -} -``` - -## UART获取波特率 - -设置UART的波特率后,可以通过获取波特率接口来查看UART当前的波特率,获取波特率的函数如下所示: - -int32\_t UartGetBaud\(DevHandle handle, uint32\_t \*baudRate\); - -**表 3** UartGetBaud参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

baudRate

-

接收波特率值的指针

-

返回值

-

返回值描述

-

0

-

UART获取波特率成功

-

负数

-

UART获取波特率失败

-
- -获取波特率的实例如下: - -``` -int32_t ret; -uint32_t baudRate; -/* 获取UART波特率 */ -ret = UartGetBaud(handle, &baudRate); -if (ret != 0) { - HDF_LOGE("UartGetBaud: failed, ret %d\n", ret); -} -``` - -## UART设置设备属性 - -在通信之前,需要设置UART的设备属性,设置设备属性的函数如下图所示: - -int32\_t UartSetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); - -**表 4** UartSetAttribute参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

attribute

-

待设置的设备属性

-

返回值

-

返回值描述

-

0

-

UART设置设备属性成功

-

负数

-

UART设置设备属性失败

-
- -设置UART的设备属性的实例如下: - -``` -int32_t ret; -struct UartAttribute attribute; -attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ -attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ -attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ -attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ -attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ -attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ -attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ -/* 设置UART设备属性 */ -ret = UartSetAttribute(handle, &attribute); -if (ret != 0) { - HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); -} -``` - -## UART获取设备属性 - -设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性,获取设备属性的函数如下图所示: - -int32\_t UartGetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); - -**表 5** UartGetAttribute参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

attribute

-

接收UART设备属性的指针

-

返回值

-

返回值描述

-

0

-

UART获取设备属性成功

-

负数

-

UART获取设备属性失败

-
- -获取UART的设备属性的实例如下: - -``` -int32_t ret; -struct UartAttribute attribute; -/* 获取UART设备属性 */ -ret = UartGetAttribute(handle, &attribute); -if (ret != 0) { - HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret); -} -``` - -## 设置UART传输模式 - -在通信之前,需要设置UART的传输模式,设置传输模式的函数如下图所示: - -int32\_t UartSetTransMode\(DevHandle handle, enum UartTransMode mode\); - -**表 6** UartSetTransMode参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

mode

-

待设置的传输模式,

-

返回值

-

返回值描述

-

0

-

UART设置传输模式成功

-

负数

-

UART设置传输模式失败

-
- -假设需要设置的UART传输模式为UART\_MODE\_RD\_BLOCK,设置传输模式的实例如下: - -``` -int32_t ret; -/* 设置UART传输模式 */ -ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); -if (ret != 0) { - HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); -} -``` - -## 向UART设备写入指定长度的数据 - -对应的接口函数如下所示: - -int32\_t UartWrite\(DevHandle handle, uint8\_t \*data, uint32\_t size\); - -**表 7** UartWrite参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

data

-

待写入数据的指针

-

size

-

待写入数据的长度

-

返回值

-

返回值描述

-

0

-

UART写数据成功

-

负数

-

UART写数据失败

-
- -写入指定长度数据的实例如下: - -``` -int32_t ret; -uint8_t wbuff[5] = {1, 2, 3, 4, 5}; -/* 向UART设备写入指定长度的数据 */ -ret = UartWrite(handle, wbuff, 5); -if (ret != 0) { - HDF_LOGE("UartWrite: failed, ret %d\n", ret); -} -``` - -## 从UART设备中读取指定长度的数据 - -对应的接口函数如下所示: - -int32\_t UartRead\(DevHandle handle, uint8\_t \*data, uint32\_t size\); - -**表 8** UartRead参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

data

-

接收读取数据的指针

-

size

-

待读取数据的长度

-

返回值

-

返回值描述

-

非负数

-

UART读取到的数据长度

-

负数

-

UART读取数据失败

-
- -读取指定长度数据的实例如下: - -``` -int32_t ret; -uint8_t rbuff[5] = {0}; -/* 从UART设备读取指定长度的数据 */ -ret = UartRead(handle, rbuff, 5); -if (ret < 0) { - HDF_LOGE("UartRead: failed, ret %d\n", ret); -} -``` - ->![](public_sys-resources/icon-caution.gif) **注意:** ->UART返回值为非负值,表示UART读取成功。若返回值等于0,表示UART无有效数据可以读取。若返回值大于0,表示实际读取到的数据长度,该长度小于或等于传入的参数size的大小,并且不超过当前正在使用的UART控制器规定的最大单次读取数据长度的值。 - -## 销毁UART设备句柄 - -UART通信完成之后,需要销毁UART设备句柄,函数如下所示: - -void UartClose\(DevHandle handle\); - -该函数会释放申请的资源。 - -**表 9** UartClose参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-
- -销毁UART设备句柄的实例如下: - -``` -UartClose(handle); /* 销毁UART设备句柄 * -``` - diff --git "a/zh-cn/device-dev/driver/UART\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/UART\346\246\202\350\277\260.md" deleted file mode 100755 index 2f295bddd98e43a9ff8670b0b5b44943243e6574..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/UART\346\246\202\350\277\260.md" +++ /dev/null @@ -1,106 +0,0 @@ -# UART概述 - -- [简介](#section14770623164917) -- [接口说明](#section149505462492) - -## 简介 - -- UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)的缩写,是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 -- UART应用比较广泛,常用于输出打印信息,也可以外接各种模块,如GPS、蓝牙等。 -- 两个UART设备的连接示意图如下,UART与其他模块一般用2线(图1)或4线(图2)相连,它们分别是: - - TX:发送数据端,和对端的RX相连; - - RX:接收数据端,和对端的TX相连; - - RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连; - - CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连; - - **图 1** 2线UART设备连接示意图 - - - ![](figures/zh-cn_image_0000001053926237.png) - - **图 2** 4线UART设备连接示意图 - - - ![](figures/zh-cn_image_0000001054007499.png) - - -- UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。 -- UART接口定义了操作UART端口的通用方法集合,包括获取、释放设备句柄、读写数据、获取和设置波特率、获取和设置设备属性。 - -## 接口说明 - -**表 1** UART驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

UART获取/释放设备句柄

-

-

UartOpen

-

UART获取设备句柄

-

UartClose

-

UART释放设备句柄

-

UART读写接口

-

-

UartRead

-

从UART设备中读取指定长度的数据

-

UartWrite

-

向UART设备中写入指定长度的数据

-

UART获取/设置波特率接口

-

UartGetBaud

-

UART获取波特率

-

UartSetBaud

-

UART设置波特率

-

UART获取/设置设备属性

-

-

UartGetAttribute

-

UART获取设备属性

-

UartSetAttribute

-

UART设置设备属性

-

UART设置传输模式

-

UartSetTransMode

-

UART设置传输模式

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/WATCHDOG.md b/zh-cn/device-dev/driver/WATCHDOG.md deleted file mode 100755 index 0d7afef9e34e797337223f629833ac288a532914..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/WATCHDOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# WATCHDOG - -- **[看门狗概述](看门狗概述.md)** - -- **[看门狗使用指导](看门狗使用指导.md)** - -- **[看门狗使用实例](看门狗使用实例.md)** - - diff --git a/zh-cn/device-dev/driver/WLAN.md b/zh-cn/device-dev/driver/WLAN.md deleted file mode 100755 index af39a0d3a2bed463178b7cc278c21373c91ef9f1..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/driver/WLAN.md +++ /dev/null @@ -1,9 +0,0 @@ -# WLAN - -- **[WLAN开发概述](WLAN开发概述.md)** - -- **[WLAN开发指导](WLAN开发指导.md)** - -- **[WLAN开发实例](WLAN开发实例.md)** - - diff --git "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index bc558cb653344f4a82333d7c4ccdcc73815db838..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,372 +0,0 @@ -# WLAN开发实例 - -本例程提供WLAN模块初始化过程的完整使用流程。示例如下(以hi3881WLAN芯片为例): - -1、根据硬件,修改配置参数 - -``` -/* 根据硬件参数,通过wlan_platform.hcs配置相关参数,以下是WLAN平台配置的示例 */ -hisi :& deviceList { - device0 :: deviceInst { - deviceInstId = 0; - powers { - power0 { - powerSeqDelay = 0; /* 电源序列延时 */ - powerType = 1; /* 电源类型:0--总是打开;1--GPIO */ - gpioId = 1; /* GPIO管脚号 */ - activeLevel=1; /* 有效电平:0--低;1--高 */ - } - power1 { - powerSeqDelay = 0; /* 电源序列延时 */ - powerType = 0; /* 电源类型:0--总是打开;1--GPIO */ - } - } - reset { - resetType = 0; /* 复位类型:0--不管理;1--GPIO */ - gpioId = 2; /* GPIO管脚号 */ - activeLevel=1; /* 有效电平:0--低;1--高 */ - resetHoldTime = 30; /* 复位配置后的等待时间(ms) */ - } - bootUpTimeout = 30; /* 启动超时时间(ms) */ - bus { - busType = 0; /* 总线类型:0-sdio */ - busId = 2; /* 总线号 */ - funcNum = [1]; /* SDIO功能号 */ - timeout = 1000; /* 读/写数据的超时时间 */ - blockSize = 512; /* 读/写数据的块大小 */ - } - } -} -/* 每一块芯片添加配置文件wlan_chip_<芯片名>.hcs(如:wlan_chip_hi3881.hcs),配置相关参数。以下是hi3881的配置示例 */ -root { - wlan_config { - hi3881 :& chipList { - chipHi3881 :: chipInst { - match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */ - chipName = "hi3881"; /* WLAN芯片的名称 */ - sdio { - vendorId = 0x0296; /* 厂商Id */ - deviceId = [0x5347]; /* 设备Id */ - } - } - } - } -} -``` - -2、适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化 - -``` -/* WLAN初始化挂接流程 */ -#include "hdf_device_desc.h" -#include "hdf_wifi_product.h" -#include "hdf_log.h" -#include "osal_mem.h" -#include "hdf_wlan_chipdriver_manager.h" -#include "securec.h" -#include "wifi_module.h" -#include "hi_wifi_api.h" -#include "hi_types_base.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* WLAN芯片的初始化和去初始化函数 */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device); -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); -/* WLAN芯片驱动的初始化和去初始化函数 */ -int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); -int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); - -/* 初始化mac80211与芯片侧的函数挂接 */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); - -static const char* const HI3881_DRIVER_NAME = "hisi"; - -/* WLAN芯片驱动挂接以及mac80211与芯片侧的函数挂接 */ -static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) -{ - struct HdfChipDriver *specificDriver = NULL; - if (device == NULL) { - HDF_LOGE("%s fail : channel is NULL", __func__); - return NULL; - } - (void)device; - (void)ifIndex; - specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); - if (specificDriver == NULL) { - HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); - return NULL; - } - if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { - HDF_LOGE("%s fail: memset_s fail!", __func__); - OsalMemFree(specificDriver); - return NULL; - } - - if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { - HDF_LOGE("%s fail : strcpy_s fail", __func__); - OsalMemFree(specificDriver); - return NULL; - } - specificDriver->init = Hi3881Init; - specificDriver->deinit = Hi3881Deinit; - - HiMac80211Init(specificDriver); - - return specificDriver; -} - -/* 释放WLAN芯片驱动 */ -static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - return; - } - if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { - HDF_LOGE("%s:Not my driver!", __func__); - return; - } - OsalMemFree(chipDriver); -} - -static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { - (void)factory; - return 1; -} - -/* WLAN芯片相关函数的注册 */ -static int32_t HDFWlanRegHisiDriverFactory(void) -{ - static struct HdfChipDriverFactory tmpFactory = { 0 }; - struct HdfChipDriverManager *driverMgr = NULL; - driverMgr = HdfWlanGetChipDriverMgr(); - if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; - } - tmpFactory.driverName = HI3881_DRIVER_NAME; - tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; - tmpFactory.InitChip = InitHi3881Chip; - tmpFactory.DeinitChip = DeinitHi3881Chip; - tmpFactory.Build = BuildHi3881Driver; - tmpFactory.Release = ReleaseHi3881Driver; - tmpFactory.ReleaseFactory = NULL; - if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} - -static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) -{ - (void)device; - return HDFWlanRegHisiDriverFactory(); -} - -struct HdfDriverEntry g_hdfHisiChipEntry = { - .moduleVersion = 1, - .Init = HdfWlanHisiChipDriverInit, - .moduleName = "HDF_WLAN_CHIPS" -}; - -HDF_INIT(g_hdfHisiChipEntry); -``` - -``` -#include "hdf_wifi_product.h" -#include "hi_wifi_api.h" -#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) -#include "oal_thread.h" -#include "osal_time.h" -#endif -#include "wifi_mac80211_ops.h" -#include "wal_cfg80211.h" -#include "net_adpater.h" -#include "hdf_wlan_utils.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* WLAN芯片的初始化函数 */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device) -{ - uint8_t maxPortCount = 1; - int32_t ret = HI_SUCCESS; - uint8_t maxRetryCount = 2; - if (device == NULL) { - HDF_LOGE("%s:NULL ptr!", __func__); - return HI_FAIL; - } - - do { - if (ret != HI_SUCCESS) { - if (device->reset != NULL && device->reset->Reset != NULL) { - device->reset->Reset(device->reset); - } - HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); - } - ret = hi_wifi_init(maxPortCount); - } while (ret != 0 && --maxRetryCount > 0); - - if (ret != 0) { - HDF_LOGE("%s:Init hi3881 driver failed!", __func__); - return ret; - } - return HI_SUCCESS; -} - -/* WLAN芯片的去初始化函数 */ -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) -{ - (void)device; - int32_t ret = hi_wifi_deinit(); - if (ret != 0) { - HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); - } - return ret; -} - -/* WLAN芯片驱动的初始化函数 */ -int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - HDF_LOGI("%s: start...", __func__); - hi_u16 mode = wal_get_vap_mode(); - int32_t ret; - nl80211_iftype_uint8 type; - (void)chipDriver; - - if (mode >= WAL_WIFI_MODE_BUTT) { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; - } - - if (mode == WAL_WIFI_MODE_STA) { - type = NL80211_IFTYPE_STATION; - } else if (mode == WAL_WIFI_MODE_AP) { - type = NL80211_IFTYPE_AP; - } else { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; - } - - ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); - if (ret != HI_SUCCESS) { - oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); - } - return ret; -} - -/* WLAN芯片驱动的去初始化函数 */ -int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - (void)chipDriver; - int32_t ret = wal_deinit_drv_wlan_netdev(netDevice); - if (ret != HDF_SUCCESS) { - return ret; - } - return ReleasePlatformNetDevice(netDevice); -} -``` - -3、在芯片侧初始化过程中调用netdev的init和add接口进行初始化netdev,并挂接netdev的一些函数指针 - -``` -hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len) -{ - oal_net_device_stru *netdev = HI_NULL; - - ...... - /* 初始化网络设备,获取对应的实例。*/ - netdev = NetDeviceInit(ifname, *len, LITE_OS); - oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); - ret = wal_init_netif(type, netdev, wdev); - - ...... - - return HI_SUCCESS; -} -/* 挂接netdev的一些函数指针,详细挂接函数{@link NetDeviceInterFace} */ -oal_net_device_ops_stru g_wal_net_dev_ops = -{ - .getStats = wal_netdev_get_stats, - .open = wal_netdev_open, - .stop = wal_netdev_stop, - .xmit = hmac_bridge_vap_xmit, - .ioctl = wal_net_device_ioctl, - .changeMtu = oal_net_device_change_mtu, - .init = oal_net_device_init, - .deInit = oal_net_free_netdev, -#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) - .selectQueue = wal_netdev_select_queue, -#endif - .setMacAddr = wal_netdev_set_mac_addr, -#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) - .netifNotify = HI_NULL, -#endif - .specialEtherTypeProcess = SpecialEtherTypeProcess, -}; - -hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) -{ - /* 添加网络设备到协议栈 */ - hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); - - ...... - - return HI_SUCCESS; -} -``` - -4、WifiMac80211Ops中的函数挂接实现 - -``` -/* 挂接mac80211的一些函数指针 */ - -/* 驱动需要实现的MAC层基本能力的控制接口 */ -static struct HdfMac80211BaseOps g_baseOps = { - .SetMode = WalSetMode, - .AddKey = WalAddKey, - .DelKey = WalDelKey, - .SetDefaultKey = WalSetDefaultKey, - .GetDeviceMacAddr = WalGetDeviceMacAddr, - .SetMacAddr = WalSetMacAddr, - .SetTxPower = WalSetTxPower, - .GetValidFreqsWithBand = WalGetValidFreqsWithBand, - .GetHwCapability = WalGetHwCapability -}; - -/* 驱动需要实现的MAC层STA能力的控制接口 */ -static struct HdfMac80211STAOps g_staOps = { - .Connect = WalConnect, - .Disconnect = WalDisconnect, - .StartScan = WalStartScan, - .AbortScan = WalAbortScan, - .SetScanningMacAddress = WalSetScanningMacAddress, -}; - -/* 驱动需要实现的MAC层AP能力的控制接口 */ -static struct HdfMac80211APOps g_apOps = { - .ConfigAp = WalConfigAp, - .StartAp = WalStartAp, - .StopAp = WalStopAp, - .ConfigBeacon = WalChangeBeacon, - .DelStation = WalDelStation, - .SetCountryCode = WalSetCountryCode, - .GetAssociatedStasCount = WalGetAssociatedStasCount, - .GetAssociatedStasInfo = WalGetAssociatedStasInfo -}; - -/* 初始化mac80211与芯片侧的函数挂接 */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__); - return; - } - chipDriver->ops = &g_baseOps; - chipDriver->staOps = &g_staOps; - chipDriver->apOps = &g_apOps; -} -``` - diff --git "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 1a5d63663ab7c28d50b8ddd19db7d339b1248472..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,18 +0,0 @@ -# WLAN开发指导 - -- [开发步骤](#section96091936185820) - -WLAN驱动基于HDF框架和PLATFORM框架开发,不区分OS和芯片平台,为不同厂商的WLAN模组提供统一的驱动模型,各WLAN模组厂商根据如下指导适配WLAN驱动框架。 - -## 开发步骤 - -1. 通过wifi\_config.hcs文件,配置硬件参数:module\(不同feature\),芯片等。 -2. 解析配置文件, 生成全量配置的结构体对象。 -3. Module初始化,创建Module。 -4. 挂接chip,初始化chip。 -5. 总线初始化。 -6. 上层wpa业务挂接。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->以上驱动框架适配步骤一部分已经提供(详细见开发实例),待开发人员实现的部分有:1、根据硬件,修改配置参数;2、适配挂接chip;3、测试自验证。 - diff --git "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index 869ee1da51d3e2ac53a46eaebef489ab55428c7e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,229 +0,0 @@ -# WLAN开发概述 - -- [简介](#section23087361515) -- [WLAN驱动接口架构](#section1533192516212) -- [接口说明](#section87491484213) - -## 简介 - -WLAN是基于HDF(Hardware Driver Foundation)驱动框架开发的模块,该模块可实现跨操作系统迁移,自适应器件差异,模块化拼装编译等功能。各WLAN厂商驱动开发人员可根据WLAN模块提供的向下统一接口适配各自的驱动代码,实现如下能力:建立/关闭WLAN热点、扫描、关联WLAN热点等;对HDI层向上提供能力如下:设置MAC地址、设置发射功率、获取设备的MAC地址等。[WLAN模块框架图](#fig967034316227)如下: - -**图 1** WLAN框架 - - -![](figures/zh-cn_image_0000001055299108.png) - -## WLAN驱动接口架构 - -WLAN模块有三部分对外开放的API接口,如[下图2](#fig15016395217)所示: - -1. 对HDI层提供的能力接口。 - -2. 驱动直接调用WLAN模块能力接口。 - -3. 提供给各厂商实现的能力接口。 - -**图 2** WLAN模块开放能力分布图 - - -![](figures/接口分布图4.png) - -## 接口说明 - -WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。提供的部分接口说明如[表1](#table1521573319472)所示: - -**表 1** 可直接调用的接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口名称

-

功能描述

-

wifi_module.h

-

-

struct WifiModule *WifiModuleCreate(const struct HdfConfigWifiModuleConfig *config);

-

基于HDF开发WLAN驱动时,创建一个WifiModule。

-

void WifiModuleDelete(struct WifiModule *module);

-

基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。

-

int32_t DelFeature(struct WifiModule *module, uint16_t featureType);

-

基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。

-

int32_t AddFeature(struct WifiModule *module, uint16_t featureType, struct WifiFeature *featureData);

-

基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。

-

wifi_mac80211_ops.h

-

int32_t (*startAp)(NetDevice *netDev);

-

启动AP。

-

int32_t (*stopAp)(NetDevice *netDev);

-

停止AP。

-

int32_t (*connect)(NetDevice *netDev, WifiConnectParams *param);

-

开始关联。

-

int32_t (*disconnect)(NetDevice *netDev, uint16_t reasonCode);

-

取消关联。

-

hdf_netbuf.h

-

static inline void NetBufQueueInit(struct NetBufQueue *q);

-

初始化NetBuf队列。

-

struct NetBuf *NetBufAlloc(uint32_t size);

-

申请NetBuf。

-

void NetBufFree(struct NetBuf *nb);

-

释放NetBuf。

-

struct NetBuf *Pbuf2NetBuf(const struct NetDevice *netdev, struct pbuf *lwipBuf);

-

lwip的pbuf转换为NetBuf。

-

struct pbuf *NetBuf2Pbuf(const struct NetBuf *nb);

-

NetBuf转换为lwip的pbuf。

-
- -同时WLAN驱动模块也提供了需要驱动开发人员实现的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如[表2](#table74613501475)所示: - -**表 2** 需要开发人员实现的接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口名称

-

功能描述

-

net_device.h

-

int32_t (*init)(struct NetDevice *netDev);

-

初始化NetDevice。

-

struct NetDevStats *(*getStats)(struct NetDevice *netDev);

-

获取NetDevice的状态。

-

int32_t (*setMacAddr)(struct NetDevice *netDev, void *addr);

-

设置Mac地址。

-

void (*deInit)(struct NetDevice *netDev);

-

注销NetDevice。

-

int32_t (*open)(struct NetDevice *netDev);

-

打开NetDevice。

-

int32_t (*stop)(struct NetDevice *netDev);

-

关闭NetDevice。

-
- -WLAN驱动模块对HDI层提供的能力接口,主要功能有:创建/销毁 IWiFi对象、设置MAC地址等。提供的部分接口说明如[表3](#table141076311618)所示: - -**表 3** HAL层对外接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口名称

-

功能描述

-

wifi_hal.h

-

-

int32_t WifiConstruct(struct IWiFi **wifiInstance);

-

创建IWiFi对象,提供IWiFi基本能力。

-

int32_t WifiDestruct(struct IWiFi **wifiInstance);

-

销毁IWiFi对象。

-

int32_t (*start)(struct IWiFi *);

-

创建HAL和驱动之间的通道及获取驱动支持的网卡信息。

-

int32_t (*stop)(struct IWiFi *);

-

销毁通道。

-

wifi_hal_base_feature.h

-

int32_t (*getFeatureType)(const struct IWiFiBaseFeature *);

-

获取特性的类型。

-

int32_t (*setMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

-

设置MAC地址。

-

int32_t (*getDeviceMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

-

获取设备持久化的MAC地址。

-

int32_t (*setTxPower)(const struct IWiFiBaseFeature *, int32_t);

-

设置发射功率。

-
- diff --git a/zh-cn/device-dev/driver/driver-hdf-development.md b/zh-cn/device-dev/driver/driver-hdf-development.md new file mode 100644 index 0000000000000000000000000000000000000000..492abc6c66f47310c998d216acf5409cad6ee775 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-hdf-development.md @@ -0,0 +1,175 @@ +# 驱动开发 + +- [驱动模型介绍](#section157425168112) +- [驱动开发步骤](#section1969312275533) + +## 驱动模型介绍 + +HDF框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个host里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个node,HDF驱动模型如下图所示: + +**图 1** HDF驱动模型 + + +![](figure/zh-cn_image_0000001054564784.png) + +## 驱动开发步骤 + +基于HDF框架进行驱动的开发主要分为两个部分,驱动实现和驱动配置,详细开发流程如下所示: + +1. 驱动实现 + + 驱动实现包含驱动业务代码和驱动入口注册,具体写法如下: + + - 驱动业务代码 + + ``` + #include "hdf_device_desc.h" // HDF框架对驱动开放相关能力接口的头文件 + #include "hdf_log.h" // HDF 框架提供的日志接口头文件 + + #define HDF_LOG_TAG "sample_driver" // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签 + + //驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架 + int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver bind success"); + return 0; + } + + // 驱动自身业务初始的接口 + int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver Init success"); + return 0; + } + + // 驱动资源释放的接口 + void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver release success"); + return; + } + ``` + + - 驱动入口注册到HDF框架 + + ``` + // 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量 + struct HdfDriverEntry g_sampleDriverEntry = { + .moduleVersion = 1, + .moduleName = "sample_driver", + .Bind = HdfSampleDriverBind, + .Init = HdfSampleDriverInit, + .Release = HdfSampleDriverRelease, + }; + + // 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 + HDF_INIT(g_sampleDriverEntry); + ``` + + +2. 驱动编译 + - 驱动代码的编译必须要使用HDF框架提供的Makefile模板进行编译。 + + ``` + include $(LITEOSTOPDIR)/../../drivers/adapter/lite/khdf/lite.mk #导入hdf预定义内容,必需 + MODULE_NAME := #生成的结果文件 + LOCAL_INCLUDE := #本驱动的头文件目录 + LOCAL_SRCS := #本驱动的源代码文件 + LOCAL_CFLAGS := #自定义的编译选项 + include $(HDF_DRIVER) #导入模板makefile完成编译 + ``` + + - 编译结果文件链接到内核镜像,添加到vendor目录下的hdf\_vendor.mk里面,示例如下: + + ``` + LITEOS_BASELIB += -lxxx #链接生成的静态库 + LIB_SUBDIRS += #驱动代码Makefile的目录 + ``` + + +3. 驱动配置 + + HDF使用HCS作为配置描述源码,HCS详细介绍参考[配置管理](driver-hdf-manage.md)介绍。 + + 驱动配置包含两部分,HDF框架定义的驱动设备描述和驱动的私有配置信息,具体写法如下: + + - 驱动设备描述(必选) + + HDF框架加载驱动所需要的信息来源于HDF框架定义的驱动设备描述,因此基于HDF框架开发的驱动必须要在HDF框架定义的device\_info.hcs配置文件中添加对应的设备描述,驱动的设备描述填写如下所示: + + ``` + root { + device_info { + match_attr = "hdf_manager"; + template host { // host模板,继承该模板的节点(如下sample_host)如果使用模板中的默认值,则节点字段可以缺省 + hostName = ""; + priority = 100; + template device { + template deviceNode { + policy = 0; + priority = 100; + preload = 0; + permission = 0664; + moduleName = ""; + serviceName = ""; + deviceMatchAttr = ""; + } + } + } + sample_host :: host{ + hostName = "host0"; // host名称,host节点是用来存放某一类驱动的容器 + priority = 100; // host启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证host的加载顺序 + device_sample :: device { // sample设备节点 + device0 :: deviceNode { // sample驱动的DeviceNode节点 + policy = 1; // policy字段是驱动服务发布的策略,在驱动服务管理章节有详细介绍 + priority = 100; // 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 + preload = 0; // 驱动按需加载字段,在本章节最后的说明有详细介绍 + permission = 0664; // 驱动创建设备节点权限 + moduleName = "sample_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 + serviceName = "sample_service"; // 驱动对外发布服务的名称,必须唯一 + deviceMatchAttr = "sample_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 + } + } + } + } + } + ``` + + - 驱动私有配置信息(可选) + + 如果驱动有私有配置,则可以添加一个驱动的配置文件,用来填写一些驱动的默认配置信息,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init(参考[驱动开发](#li35182436435))传递给驱动,驱动的配置信息示例如下: + + ``` + root { + SampleDriverConfig { + sample_version = 1; + sample_bus = "I2C_0"; + match_attr = "sample_config"; //该字段的值必须和device_info.hcs中的deviceMatchAttr值一致 + } + } + ``` + + 配置信息定义之后,需要将该配置文件添加到板级配置入口文件hdf.hcs(这一块可以通过OpenHarmony驱动子系统在DevEco集成驱动开发套件工具一键式配置,具体使用方法参考驱动开发套件中的介绍),示例如下: + + ``` + #include "device_info/device_info.hcs" + #include "sample/sample_config.hcs" + ``` + + + +>![](../public_sys-resources/icon-note.gif) **说明:** +>驱动加载方式支持按需加载和按序加载两种方式,具体使用方法如下: +>- 按需加载 +> ``` +> typedef enum { +> DEVICE_PRELOAD_ENABLE = 0, +> DEVICE_PRELOAD_ENABLE_STEP2, +> DEVICE_PRELOAD_DISABLE, +> DEVICE_PRELOAD_INVALID +> } DevicePreload; +> ``` +> 配置文件中preload 字段配成 0 (DEVICE\_PRELOAD\_ENABLE ),则系统启动过程中默认加载;配成1(DEVICE\_PRELOAD\_ENABLE\_STEP2),当系统支持快启的时候,则在系统系统完成之后再加载这一类驱动,否则和DEVICE\_PRELOAD\_ENABLE 含义相同;配成2(DEVICE\_PRELOAD\_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务(参考[消息机制](driver-hdf-news.md))时,如果驱动服务不存在时,HDF框架会尝试动态加载该驱动。 +>- 按序加载(需要驱动为默认加载) +> 配置文件中的priority(取值范围为整数0到200)是用来表示host和驱动的优先级,不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高。 + diff --git a/zh-cn/device-dev/driver/driver-hdf-manage.md b/zh-cn/device-dev/driver/driver-hdf-manage.md new file mode 100644 index 0000000000000000000000000000000000000000..86cc85d8c7d56c8d5fbe544187e191cb48243a56 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-hdf-manage.md @@ -0,0 +1,437 @@ +# 配置管理 + +- [配置概述](#section59914284576) +- [配置语法](#section533713333580) +- [关键字](#section1316625413586) +- [基本结构](#section173481622115918) +- [数据类型](#section96521601302) +- [预处理](#section8164295515) +- [注释](#section0338205819610) +- [引用修改](#section179799204716) +- [节点复制](#section382424014712) +- [删除](#section165211112586) +- [属性引用](#section192841514490) +- [模板](#section520134294) +- [配置生成](#section106152531919) +- [hc-gen介绍](#section8260625101012) + +## 配置概述 + +HCS\(**H**DF **C**onfiguration **S**ource\)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。 + +HC-GEN**\(H**DF **C**onfiguration **G**enerator**\)**是HCS配置转换工具,可以将HDF配置文件转换为软件可读取的文件格式: + +- 在弱性能环境中,转换为配置树源码,驱动可直接调用C代码获取配置。 +- 在高性能环境中,转换为HCB\(**H**DF **C**onfiguration **B**inary\)二进制文件,驱动可使用HDF框架提供的配置解析接口获取配置。 + +以下是使用HCB模式的典型应用场景: + +**图 1** 配置使用流程图 + + +![](figure/zh-cn_image_0000001053405727.png) + +HCS经过HC-GEN编译生成HCB文件,HDF驱动框架中的HCS Parser模块会从HCB文件中重建配置树,HDF驱动模块使用HCS Parser提供的配置读取接口获取配置内容。 + +## 配置语法 + +HCS的语法介绍如下: + +## 关键字 + +HCS配置语法保留了以下关键字。 + +**表 1** HCS配置语法保留关键字 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

关键字

+

用途

+

说明

+

root

+

配置根节点

+

-

+

include

+

引用其他HCS配置文件

+

-

+

delete

+

删除节点或属性

+

只能用于操作include导入的配置树

+

template

+

定义模板节点

+

-

+

match_attr

+

用于标记节点的匹配查找属性

+

解析配置时可以使用该属性的值查找到对应节点

+
+ +## 基本结构 + +HCS主要分为属性\(Attribute\)和节点\(Node\)两种结构。 + +**属性** + +属性即最小的配置单元,是一个独立的配置项。语法如下: + +``` + attribute_name = value; +``` + +- attribute\_name 是**字母、数字、下划线**的组合且必须以字母或下划线开头,字母区分大小写。 + +- value的可用格式如下: + + - 数字常量,支持二进制、八进制、十进制、十六进制数,具体参考数据类型节。 + + - 字符串,内容使用双引号\(""\)引用。 + + - 节点引用。 + + +- attribute 必须以分号\(;\)结束且必须属于一个node。 + + +**节点** + +节点是一组属性的集合,语法如下: + +``` + node_name { + module = "sample"; + ... + } +``` + +- node\_name 是**字母、数字、下划线**的组合且必须以字母或下划线开头,字母区分大小写。 + +- 大括号后无需添加结束符“;”。 + +- root为保留关键字,用于声明配置表的根节点。每个配置表必须以root节点开始。 + +- root节点中必须包含module属性,其值应该为一个字符串,用于表征该配置所属模块。 + +- 节点中可以增加match\_attr属性,其值为一个全局唯一的字符串。在解析配置时可以调用查找接口以该属性的值查找到包含该属性的节点。 + +## 数据类型 + +在属性定义中使用自动数据类型,不显式指定类型,属性支持的数据类型如下: + +**整型** + +整型长度自动推断,根据实际数据长度给与最小空间占用的类型。 + +- 二进制,0b前缀,示例:0b1010。 + +- 八进制,0前缀,示例:0664。 +- 十进制 ,无前缀,且支持有符号与无符号,示例:1024,+1024均合法。负值在读取时注意使用有符号数读取接口。 + +- 十六进制,0x前缀,示例:0xff00、0xFF。 + + +**字符串** + +字符串使用双引号\(""\)表示。 + +**数组** + +数组元素支持整型、字符串,不支持混合类型。整型数组中uint32\_t uint64\_t混用会向上转型为uint64\_t 数组。整型数组与字符串数组示例如下: + +``` +attr_foo = [0x01, 0x02, 0x03, 0x04]; +attr_bar = ["hello", "world"]; +``` + +**bool类型** + +bool类型中**true**表示真,**false**表示假。 + +## 预处理 + +**include** + +用于导入其他HCS文件。语法示例如下: + +``` +#include "foo.hcs" +#include "../bar.hcs" +``` + +- 文件名必须使用双引号\(""\),不在同一目录使用相对路径引用。被include文件也必须是合法的HCS文件。 +- 多个include,如果存在相同的节点,后者覆盖前者,其余的节点依次展开。 + +## 注释 + +支持两种注释风格。 + +- 单行注释。 + + ``` + // comment + ``` + +- 多行注释。 + + ``` + /* + comment + */ + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >多行注释不支持嵌套。 + + +## 引用修改 + +引用修改可以实现修改另外任意一个节点的内容,语法为: + +``` + node :& source_node +``` + +上述语句表示node中的内容是对source\_node节点内容的修改。示例如下: + +``` +root { + module = "sample"; + foo { + foo_ :& root.bar{ + attr = "foo"; + } + foo1 :& foo2 { + attr = 0x2; + } + foo2 { + attr = 0x1; + } + } + + bar { + attr = "bar"; + } +} +``` + +最终生成配置树为: + +``` +root { + module = "sample"; + foo { + foo2 { + attr = 0x2; + } + } + bar { + attr = "foo"; + } +} +``` + +在以上示例中,可以看到foo.foo\_节点通过引用将bar.attr属性的值修改为了"foo",foo.foo1节点通过引用将foo.foo2.attr属性的值修改为了0x2。foo.foo\_以及foo.foo1节点表示对目标节点内容的修改,其自身并不会存在最终生成的配置树中。 + +- 引用同级node,可以直接使用node名称,否则被引用的节点必须使用绝对路径,节点间使用“.”分隔,root表示根节点,格式为root开始的节点路径序列,例如root.foo.bar即为一个合法的绝对路径。 +- 如果出现修改冲突(即多处修改同一个属性),编译器将提示warning,因为这种情况下只会生效某一个修改而导致最终结果不确定。 + +## 节点复制 + +节点复制可以实现在节点定义时从另一个节点先复制内容,用于定义内容相似的节点。语法为: + +``` + node : source_node +``` + +上述语句表示在定义"node"节点时将另一个节点"source\_node"的属性复制过来。示例如下: + +``` +root { + module = "sample"; + foo { + attr_0 = 0x0; + } + bar:foo { + attr_1 = 0x1; + } +} +``` + +上述代码的最终生成配置树为: + +``` +root { + module = "sample"; + foo { + attr_0 = 0x0; + } + bar { + attr_1 = 0x1; + attr_0 = 0x0; + } +} +``` + +在上述示例中,编译后bar节点即包含attr\_0属性也包含attr\_1属性,在bar中对attr\_0的修改不会影响到foo。 + +在foo和bar在同级node中可不指定foo的路径,否则需要使用绝对路径引用,参考[引用修改](#section179799204716)。 + +## 删除 + +要对include导入的base配置树中不需要的节点或属性进行删除,可以使用delete关键字。下面的举例中sample1.hcs通过include导入了sample2.hcs中的配置内容,并使用delete删除了sample2.hcs中的attribute2属性和foo\_2节点,示例如下: + +``` +// sample2.hcs +root { + attr_1 = 0x1; + attr_2 = 0x2; + foo_2 { + t = 0x1; + } +} + +// sample1.hcs +#include "sample2.hcs" +root { + attr_2 = delete; + foo_2 : delete { + } +} +``` + +上述代码在生成过程中将会删除root.foo\_2节点与attr\_2,最终生成配置树为: + +``` +root { + attr_1 = 0x1; +} +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>在同一个HCS文件中不允许使用delete,建议直接删除不需要的属性。 + +## 属性引用 + +为了在解析配置时快速定位到关联的节点,可以把节点作为属性的右值,通过读取属性查找到对应节点。语法为: + +``` + attribute = &node; +``` + +上述语句表示attribute的值是一个节点node的引用,在解析时可以用这个attribute快速定位到node,便于关联和查询其他node。示例如下: + +``` +node1 { + attributes; +} + +node2 { + attr_1 = &node1; +} +``` + +## 模板 + +模板的用途在于生成严格一致的node结构,以便对同类型node进行遍历和管理。 + +使用template关键字定义模板node,子node通过双冒号“::”声明继承关系。子节点可以改写但不能新增和删除template中的属性,子节点中没有定义的属性将使用template中的定义作为默认值。示例如下: + +``` +root { + module = "sample"; + template foo { + attr_1 = 0x1; + attr_2 = 0x2; + } + + bar :: foo { + } + + bar_1 :: foo { + attr_1 = 0x2; + } +} +``` + +生成配置树如下: + +``` +root { + module = "sample"; + bar { + attr_1 = 0x1; + attr_2 = 0x2; + } + bar_1 { + attr_1 = 0x2; + attr_2 = 0x2; + } +} +``` + +在上述示例中,bar和bar\_1节点继承了foo节点,生成配置树节点结构与foo保持了完全一致,只是属性的值不同。 + +## 配置生成 + +hc-gen是配置生成的工具,可以对HCS配置语法进行检查并把HCS源文件转化成HCB二进制文件。 + +## hc-gen介绍 + +hc-gen参数说明: + +``` +Usage: hc-gen [Options] [File] +options: + -o output file name, default same as input + -a hcb align with four bytes + -b output binary output, default enable + -t output config in C language source file style + -i output binary hex dump in C language source file style + -p prefix of generated symbol name + -d decompile hcb to hcs + -V show verbose info + -v show version + -h show this help message +``` + +生成.c/.h 配置文件方法: + +``` +hc-gen -o [OutputCFileName] -t [SourceHcsFileName] +``` + +生成HCB 配置文件方法: + +``` +hc-gen -o [OutputHcbFileName] -b [SourceHcsFileName] +``` + +反编译HCB文件为HCS方法: + +``` +hc-gen -o [OutputHcsFileName] -d [SourceHcbFileName] +``` + diff --git a/zh-cn/device-dev/driver/driver-hdf-news.md b/zh-cn/device-dev/driver/driver-hdf-news.md new file mode 100644 index 0000000000000000000000000000000000000000..a956303a57cca0d1528d5664b4c6798800479f9b --- /dev/null +++ b/zh-cn/device-dev/driver/driver-hdf-news.md @@ -0,0 +1,193 @@ +# 驱动消息机制管理 + +- [使用场景](#section33014541954) +- [接口说明](#section538852311616) +- [开发步骤](#section946912121153) + +## 使用场景 + +当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。 + +## 接口说明 + +消息机制的功能主要有以下两种: + +1. 用户态应用发送消息到驱动。 +2. 用户态应用接收驱动主动上报事件。 + +**表 1** 消息机制接口 + + + + + + + + + + + + + + + + + + + +

方法

+

描述

+

struct HdfIoService *HdfIoServiceBind(const char *serviceName)

+

用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息。

+

void HdfIoServiceRecycle(struct HdfIoService *service);

+

释放驱动服务。

+

int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);

+

用户态程序注册接收驱动上报事件的操作方法。

+

int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);

+

驱动主动上报事件接口。

+
+ +## 开发步骤 + +1. 将驱动配置信息中服务策略policy字段设置为2(SERVICE\_POLICY\_CAPACITY,参考[policy定义](driver-hdf-servicemanage.md))。 + + ``` + device_sample :: Device { + policy = 2; + ... + } + ``` + +2. 配置驱动信息中的服务设备节点权限(permission字段)是框架给驱动创建设备节点的权限,默认是0666,驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。 +3. 在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。 + + ``` + // Dispatch是用来处理用户态发下来的消息 + int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) + { + HDF_LOGE("sample driver lite A dispatch"); + return 0; + } + int32_t SampleDriverBind(struct HdfDeviceObject *device) + { + HDF_LOGE("test for lite os sample driver A Open!"); + if (device == NULL) { + HDF_LOGE("test for lite os sample driver A Open failed!"); + return -1; + } + static struct ISampleDriverService sampleDriverA = { + .ioService.Dispatch = SampleDriverDispatch, + .ServiceA = SampleDriverServiceA, + .ServiceB = SampleDriverServiceB, + }; + device->service = (struct IDeviceIoService *)(&sampleDriverA); + return 0; + } + ``` + +4. 驱动定义消息处理函数中的cmd类型。 + + ``` + #define SAMPLE_WRITE_READ 1 // 读写操作码1 + ``` + +5. 用户态获取服务接口并发送消息到驱动。 + + ``` + int SendMsg(const char *testMsg) + { + if (testMsg == NULL) { + HDF_LOGE("test msg is null"); + return -1; + } + struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); + if (serv == NULL) { + HDF_LOGE("fail to get service"); + return -1; + } + struct HdfSBuf *data = HdfSBufObtainDefaultSize(); + if (data == NULL) { + HDF_LOGE("fail to obtain sbuf data"); + return -1; + } + struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); + if (reply == NULL) { + HDF_LOGE("fail to obtain sbuf reply"); + ret = HDF_DEV_ERR_NO_MEMORY; + goto out; + } + if (!HdfSbufWriteString(data, testMsg)) { + HDF_LOGE("fail to write sbuf"); + ret = HDF_FAILURE; + goto out; + } + int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("fail to send service call"); + goto out; + } + out: + HdfSBufRecycle(data); + HdfSBufRecycle(reply); + HdfIoServiceRecycle(serv); + return ret; + } + ``` + +6. 用户态接收该驱动上报的消息。 + 1. 用户态编写驱动上报消息的处理函数。 + + ``` + static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) + { + OsalTimespec time; + OsalGetTime(&time); + HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); + + const char *string = HdfSbufReadString(data); + if (string == NULL) { + HDF_LOGE("fail to read string in event data"); + return -1; + } + HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); + return 0; + } + ``` + + 2. 用户态注册接收驱动上报消息的操作方法。 + + ``` + int RegisterListen() + { + struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); + if (serv == NULL) { + HDF_LOGE("fail to get service"); + return -1; + } + static struct HdfDevEventlistener listener = { + .callBack = OnDevEventReceived, + .priv ="Service0" + }; + if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { + HDF_LOGE("fail to register event listener"); + return -1; + } + ...... + HdfDeviceUnregisterEventListener(serv, &listener); + HdfIoServiceRecycle(serv); + return 0; + } + ``` + + 3. 驱动上报事件。 + + ``` + int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) + { + ... // process api call here + return HdfDeviceSendEvent(deviceObject, cmdCode, data); + } + ``` + + + diff --git "a/zh-cn/device-dev/driver/HDF\345\274\200\345\217\221\346\246\202\350\277\260.md" b/zh-cn/device-dev/driver/driver-hdf-overview.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/HDF\345\274\200\345\217\221\346\246\202\350\277\260.md" rename to zh-cn/device-dev/driver/driver-hdf-overview.md diff --git a/zh-cn/device-dev/driver/driver-hdf-sample.md b/zh-cn/device-dev/driver/driver-hdf-sample.md new file mode 100644 index 0000000000000000000000000000000000000000..0cc2f0686ff32618900012839c2800fdb8724962 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-hdf-sample.md @@ -0,0 +1,238 @@ +# HDF开发实例 + +- [添加配置](#section27261067111) +- [编写驱动代码](#section177988005) +- [编写用户程序和驱动交互代码](#section6205173816412) + +下面基于HDF框架,提供一个完整的样例,包含配置文件的添加,驱动代码的实现以及用户态程序和驱动交互的流程。 + +## 添加配置 + +在HDF框架的配置文件(例如vendor/hisilicon/xxx/config/device\_info)中添加该驱动的配置信息,如下所示: + +``` +root { + device_info { + match_attr = "hdf_manager"; + template host { + hostName = ""; + priority = 100; + template device { + template deviceNode { + policy = 0; + priority = 100; + preload = 0; + permission = 0664; + moduleName = ""; + serviceName = ""; + deviceMatchAttr = ""; + } + } + } + sample_host :: host { + hostName = "sample_host"; + sample_device :: device { + device0 :: deviceNode { + policy = 2; + priority = 100; + preload = 1; + permission = 0664; + moduleName = "sample_driver"; + serviceName = "sample_service"; + } + } + } + } +} +``` + +## 编写驱动代码 + +基于HDF框架编写的sample驱动代码如下: + +``` +#include +#include +#include +#include "hdf_log.h" +#include "hdf_base.h" +#include "hdf_device_desc.h" + +#define HDF_LOG_TAG "sample_driver" + +#define SAMPLE_WRITE_READ 123 + +int32_t HdfSampleDriverDispatch( + struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + HDF_LOGE("%s: received cmd %d", __func__, id); + if (id == SAMPLE_WRITE_READ) { + const char *readData = HdfSbufReadString(data); + if (readData != NULL) { + HDF_LOGE("%s: read data is: %s", __func__, readData); + } + if (!HdfSbufWriteInt32(reply, INT32_MAX)) { + HDF_LOGE("%s: reply int32 fail", __func__); + } + return HdfDeviceSendEvent(deviceObject, id, data); + } + return HDF_FAILURE; +} + +void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) +{ + // release resources here + return; +} + +int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) +{ + if (deviceObject == NULL) { + return HDF_FAILURE; + } + static struct IDeviceIoService testService = { + .Dispatch = HdfSampleDriverDispatch, + }; + deviceObject->service = &testService; + return HDF_SUCCESS; +} + +int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) +{ + if (deviceObject == NULL) { + HDF_LOGE("%s::ptr is null!", __func__); + return HDF_FAILURE; + } + HDF_LOGE("Sample driver Init success"); + return HDF_SUCCESS; +} + +struct HdfDriverEntry g_sampleDriverEntry = { + .moduleVersion = 1, + .moduleName = "sample_driver", + .Bind = HdfSampleDriverBind, + .Init = HdfSampleDriverInit, + .Release = HdfSampleDriverRelease, +}; + +HDF_INIT(g_sampleDriverEntry); +``` + +## 编写用户程序和驱动交互代码 + +基于HDF框架编写的用户态程序和驱动交互的代码如下: + +``` +#include +#include +#include +#include +#include "hdf_log.h" +#include "hdf_sbuf.h" +#include "hdf_io_service_if.h" + +#define HDF_LOG_TAG "sample_test" +#define SAMPLE_SERVICE_NAME "sample_service" + +#define SAMPLE_WRITE_READ 123 + +int g_replyFlag = 0; + +static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) +{ + const char *string = HdfSbufReadString(data); + if (string == NULL) { + HDF_LOGE("fail to read string in event data"); + g_replyFlag = 1; + return HDF_FAILURE; + } + HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string); + g_replyFlag = 1; + return HDF_SUCCESS; +} + +static int SendEvent(struct HdfIoService *serv, char *eventData) +{ + int ret = 0; + struct HdfSBuf *data = HdfSBufObtainDefaultSize(); + if (data == NULL) { + HDF_LOGE("fail to obtain sbuf data"); + return 1; + } + + struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); + if (reply == NULL) { + HDF_LOGE("fail to obtain sbuf reply"); + ret = HDF_DEV_ERR_NO_MEMORY; + goto out; + } + + if (!HdfSbufWriteString(data, eventData)) { + HDF_LOGE("fail to write sbuf"); + ret = HDF_FAILURE; + goto out; + } + + ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("fail to send service call"); + goto out; + } + + int replyData = 0; + if (!HdfSbufReadInt32(reply, &replyData)) { + HDF_LOGE("fail to get service call reply"); + ret = HDF_ERR_INVALID_OBJECT; + goto out; + } + HDF_LOGE("Get reply is: %d", replyData); +out: + HdfSBufRecycle(data); + HdfSBufRecycle(reply); + return ret; +} + +int main() +{ + char *sendData = "default event info"; + struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME); + if (serv == NULL) { + HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME); + return HDF_FAILURE; + } + + static struct HdfDevEventlistener listener = { + .callBack = OnDevEventReceived, + .priv ="Service0" + }; + + if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) { + HDF_LOGE("fail to register event listener"); + return HDF_FAILURE; + } + if (SendEvent(serv, sendData)) { + HDF_LOGE("fail to send event"); + return HDF_FAILURE; + } + + while (g_replyFlag == 0) { + sleep(1); + } + + if (HdfDeviceUnregisterEventListener(serv, &listener)) { + HDF_LOGE("fail to unregister listener"); + return HDF_FAILURE; + } + + HdfIoServiceRecycle(serv); + return HDF_SUCCESS; +} +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>用户态应用程序使用了HDF框架中的消息发送接口,因此在编译用户态程序的过程中需要依赖HDF框架对外提供的hdf\_core和osal的动态库,在gn编译文件中添加如下依赖项: +>deps = \[ +>"//drivers/adapter/lite/uhdf/manager:hdf\_core", +>"//drivers/adapter/lite/uhdf/posix:hdf\_posix\_osal", +>\] + diff --git "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\346\234\215\345\212\241\347\256\241\347\220\206.md" b/zh-cn/device-dev/driver/driver-hdf-servicemanage.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/\351\251\261\345\212\250\346\234\215\345\212\241\347\256\241\347\220\206.md" rename to zh-cn/device-dev/driver/driver-hdf-servicemanage.md diff --git a/zh-cn/device-dev/driver/driver-peripherals-external-des.md b/zh-cn/device-dev/driver/driver-peripherals-external-des.md new file mode 100644 index 0000000000000000000000000000000000000000..282d5ed4542e43a142e8262b5f3bbefb87510d36 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-peripherals-external-des.md @@ -0,0 +1,622 @@ +# WLAN + +- [概述](#section729758162218) + - [WLAN驱动接口架构](#section178022416377) + - [接口说明](#section149681312202415) + +- [开发指导](#section15957746172412) + - [开发步骤](#section11776186132513) + +- [开发实例](#section1395253612512) + +## 概述 + +WLAN是基于HDF(Hardware Driver Foundation)驱动框架开发的模块,该模块可实现跨操作系统迁移,自适应器件差异,模块化拼装编译等功能。各WLAN厂商驱动开发人员可根据WLAN模块提供的向下统一接口适配各自的驱动代码,实现如下能力:建立/关闭WLAN热点、扫描、关联WLAN热点等;对HDI层向上提供能力如下:设置MAC地址、设置发射功率、获取设备的MAC地址等。[WLAN模块框架图](#fig967034316227)如下: + +**图 1** WLAN框架 + + +![](figure/zh-cn_image_0000001170383063.png) + +### WLAN驱动接口架构 + +WLAN模块有三部分对外开放的API接口,如[下图2](#fig15016395217)所示: + +1. 对HDI层提供的能力接口。 + +2. 驱动直接调用WLAN模块能力接口。 + +3. 提供给各厂商实现的能力接口。 + +**图 2** WLAN模块开放能力分布图 + + +![](figure/接口分布图4.png) + +### 接口说明 + +WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。提供的部分接口说明如[表1](#table1521573319472)所示: + +**表 1** 可直接调用的接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口名称

+

功能描述

+

wifi_module.h

+

+

struct WifiModule *WifiModuleCreate(const struct HdfConfigWifiModuleConfig *config);

+

基于HDF开发WLAN驱动时,创建一个WifiModule。

+

void WifiModuleDelete(struct WifiModule *module);

+

基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。

+

int32_t DelFeature(struct WifiModule *module, uint16_t featureType);

+

基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。

+

int32_t AddFeature(struct WifiModule *module, uint16_t featureType, struct WifiFeature *featureData);

+

基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。

+

wifi_mac80211_ops.h

+

int32_t (*startAp)(NetDevice *netDev);

+

启动AP。

+

int32_t (*stopAp)(NetDevice *netDev);

+

停止AP。

+

int32_t (*connect)(NetDevice *netDev, WifiConnectParams *param);

+

开始关联。

+

int32_t (*disconnect)(NetDevice *netDev, uint16_t reasonCode);

+

取消关联。

+

hdf_netbuf.h

+

static inline void NetBufQueueInit(struct NetBufQueue *q);

+

初始化NetBuf队列。

+

struct NetBuf *NetBufAlloc(uint32_t size);

+

申请NetBuf。

+

void NetBufFree(struct NetBuf *nb);

+

释放NetBuf。

+

struct NetBuf *Pbuf2NetBuf(const struct NetDevice *netdev, struct pbuf *lwipBuf);

+

lwip的pbuf转换为NetBuf。

+

struct pbuf *NetBuf2Pbuf(const struct NetBuf *nb);

+

NetBuf转换为lwip的pbuf。

+
+ +同时WLAN驱动模块也提供了需要驱动开发人员实现的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如[表2](#table74613501475)所示: + +**表 2** 需要开发人员实现的接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口名称

+

功能描述

+

net_device.h

+

int32_t (*init)(struct NetDevice *netDev);

+

初始化NetDevice。

+

struct NetDevStats *(*getStats)(struct NetDevice *netDev);

+

获取NetDevice的状态。

+

int32_t (*setMacAddr)(struct NetDevice *netDev, void *addr);

+

设置Mac地址。

+

void (*deInit)(struct NetDevice *netDev);

+

注销NetDevice。

+

int32_t (*open)(struct NetDevice *netDev);

+

打开NetDevice。

+

int32_t (*stop)(struct NetDevice *netDev);

+

关闭NetDevice。

+
+ +WLAN驱动模块对HDI层提供的能力接口,主要功能有:创建/销毁 IWiFi对象、设置MAC地址等。提供的部分接口说明如[表3](#table141076311618)所示: + +**表 3** HAL层对外接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口名称

+

功能描述

+

wifi_hal.h

+

+

int32_t WifiConstruct(struct IWiFi **wifiInstance);

+

创建IWiFi对象,提供IWiFi基本能力。

+

int32_t WifiDestruct(struct IWiFi **wifiInstance);

+

销毁IWiFi对象。

+

int32_t (*start)(struct IWiFi *);

+

创建HAL和驱动之间的通道及获取驱动支持的网卡信息。

+

int32_t (*stop)(struct IWiFi *);

+

销毁通道。

+

wifi_hal_base_feature.h

+

int32_t (*getFeatureType)(const struct IWiFiBaseFeature *);

+

获取特性的类型。

+

int32_t (*setMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

+

设置MAC地址。

+

int32_t (*getDeviceMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t);

+

获取设备持久化的MAC地址。

+

int32_t (*setTxPower)(const struct IWiFiBaseFeature *, int32_t);

+

设置发射功率。

+
+ +## 开发指导 + +WLAN驱动基于HDF框架和PLATFORM框架开发,不区分OS和芯片平台,为不同厂商的WLAN模组提供统一的驱动模型,各WLAN模组厂商根据如下指导适配WLAN驱动框架。 + +### 开发步骤 + +1. 通过wifi\_config.hcs文件,配置硬件参数:module\(不同feature\),芯片等。 +2. 解析配置文件, 生成全量配置的结构体对象。 +3. Module初始化,创建Module。 +4. 挂接chip,初始化chip。 +5. 总线初始化。 +6. 上层wpa业务挂接。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>以上驱动框架适配步骤一部分已经提供(详细见开发实例),待开发人员实现的部分有:1、根据硬件,修改配置参数;2、适配挂接chip;3、测试自验证。 + +## 开发实例 + +本例程提供WLAN模块初始化过程的完整使用流程。示例如下(以hi3881WLAN芯片为例): + +1、根据硬件,修改配置参数。 + +``` +/* 根据硬件参数,通过wlan_platform.hcs配置相关参数,以下是WLAN平台配置的示例 */ +hisi :& deviceList { + device0 :: deviceInst { + deviceInstId = 0; + powers { + power0 { + powerSeqDelay = 0; /* 电源序列延时 */ + powerType = 1; /* 电源类型:0--总是打开;1--GPIO */ + gpioId = 1; /* GPIO管脚号 */ + activeLevel=1; /* 有效电平:0--低;1--高 */ + } + power1 { + powerSeqDelay = 0; /* 电源序列延时 */ + powerType = 0; /* 电源类型:0--总是打开;1--GPIO */ + } + } + reset { + resetType = 0; /* 复位类型:0--不管理;1--GPIO */ + gpioId = 2; /* GPIO管脚号 */ + activeLevel=1; /* 有效电平:0--低;1--高 */ + resetHoldTime = 30; /* 复位配置后的等待时间(ms) */ + } + bootUpTimeout = 30; /* 启动超时时间(ms) */ + bus { + busType = 0; /* 总线类型:0-sdio */ + busId = 2; /* 总线号 */ + funcNum = [1]; /* SDIO功能号 */ + timeout = 1000; /* 读/写数据的超时时间 */ + blockSize = 512; /* 读/写数据的块大小 */ + } + } +} +/* 每一块芯片添加配置文件wlan_chip_<芯片名>.hcs(如:wlan_chip_hi3881.hcs),配置相关参数。以下是hi3881的配置示例 */ +root { + wlan_config { + hi3881 :& chipList { + chipHi3881 :: chipInst { + match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */ + chipName = "hi3881"; /* WLAN芯片的名称 */ + sdio { + vendorId = 0x0296; /* 厂商Id */ + deviceId = [0x5347]; /* 设备Id */ + } + } + } + } +} +``` + +2、适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化 + +``` +/* WLAN初始化挂接流程 */ +#include "hdf_device_desc.h" +#include "hdf_wifi_product.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "hdf_wlan_chipdriver_manager.h" +#include "securec.h" +#include "wifi_module.h" +#include "hi_wifi_api.h" +#include "hi_types_base.h" + +#define HDF_LOG_TAG Hi3881Driver + +/* WLAN芯片的初始化和去初始化函数 */ +int32_t InitHi3881Chip(struct HdfWlanDevice *device); +int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); +/* WLAN芯片驱动的初始化和去初始化函数 */ +int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); +int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); + +/* 初始化mac80211与芯片侧的函数挂接 */ +hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); + +static const char* const HI3881_DRIVER_NAME = "hisi"; + +/* WLAN芯片驱动挂接以及mac80211与芯片侧的函数挂接 */ +static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) +{ + struct HdfChipDriver *specificDriver = NULL; + if (device == NULL) { + HDF_LOGE("%s fail : channel is NULL", __func__); + return NULL; + } + (void)device; + (void)ifIndex; + specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); + if (specificDriver == NULL) { + HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); + return NULL; + } + if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { + HDF_LOGE("%s fail: memset_s fail!", __func__); + OsalMemFree(specificDriver); + return NULL; + } + + if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { + HDF_LOGE("%s fail : strcpy_s fail", __func__); + OsalMemFree(specificDriver); + return NULL; + } + specificDriver->init = Hi3881Init; + specificDriver->deinit = Hi3881Deinit; + + HiMac80211Init(specificDriver); + + return specificDriver; +} + +/* 释放WLAN芯片驱动 */ +static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) +{ + if (chipDriver == NULL) { + return; + } + if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { + HDF_LOGE("%s:Not my driver!", __func__); + return; + } + OsalMemFree(chipDriver); +} + +static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { + (void)factory; + return 1; +} + +/* WLAN芯片相关函数的注册 */ +static int32_t HDFWlanRegHisiDriverFactory(void) +{ + static struct HdfChipDriverFactory tmpFactory = { 0 }; + struct HdfChipDriverManager *driverMgr = NULL; + driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + tmpFactory.driverName = HI3881_DRIVER_NAME; + tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; + tmpFactory.InitChip = InitHi3881Chip; + tmpFactory.DeinitChip = DeinitHi3881Chip; + tmpFactory.Build = BuildHi3881Driver; + tmpFactory.Release = ReleaseHi3881Driver; + tmpFactory.ReleaseFactory = NULL; + if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) +{ + (void)device; + return HDFWlanRegHisiDriverFactory(); +} + +struct HdfDriverEntry g_hdfHisiChipEntry = { + .moduleVersion = 1, + .Init = HdfWlanHisiChipDriverInit, + .moduleName = "HDF_WLAN_CHIPS" +}; + +HDF_INIT(g_hdfHisiChipEntry); +``` + +``` +#include "hdf_wifi_product.h" +#include "hi_wifi_api.h" +#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) +#include "oal_thread.h" +#include "osal_time.h" +#endif +#include "wifi_mac80211_ops.h" +#include "wal_cfg80211.h" +#include "net_adpater.h" +#include "hdf_wlan_utils.h" + +#define HDF_LOG_TAG Hi3881Driver + +/* WLAN芯片的初始化函数 */ +int32_t InitHi3881Chip(struct HdfWlanDevice *device) +{ + uint8_t maxPortCount = 1; + int32_t ret = HI_SUCCESS; + uint8_t maxRetryCount = 2; + if (device == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HI_FAIL; + } + + do { + if (ret != HI_SUCCESS) { + if (device->reset != NULL && device->reset->Reset != NULL) { + device->reset->Reset(device->reset); + } + HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); + } + ret = hi_wifi_init(maxPortCount); + } while (ret != 0 && --maxRetryCount > 0); + + if (ret != 0) { + HDF_LOGE("%s:Init hi3881 driver failed!", __func__); + return ret; + } + return HI_SUCCESS; +} + +/* WLAN芯片的去初始化函数 */ +int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) +{ + (void)device; + int32_t ret = hi_wifi_deinit(); + if (ret != 0) { + HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); + } + return ret; +} + +/* WLAN芯片驱动的初始化函数 */ +int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + HDF_LOGI("%s: start...", __func__); + hi_u16 mode = wal_get_vap_mode(); + int32_t ret; + nl80211_iftype_uint8 type; + (void)chipDriver; + + if (mode >= WAL_WIFI_MODE_BUTT) { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + + if (mode == WAL_WIFI_MODE_STA) { + type = NL80211_IFTYPE_STATION; + } else if (mode == WAL_WIFI_MODE_AP) { + type = NL80211_IFTYPE_AP; + } else { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + + ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); + if (ret != HI_SUCCESS) { + oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); + } + return ret; +} + +/* WLAN芯片驱动的去初始化函数 */ +int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + (void)chipDriver; + int32_t ret = wal_deinit_drv_wlan_netdev(netDevice); + if (ret != HDF_SUCCESS) { + return ret; + } + return ReleasePlatformNetDevice(netDevice); +} +``` + +3、在芯片侧初始化过程中调用netdev的init和add接口进行初始化netdev,并挂接netdev的一些函数指针 + +``` +hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len) +{ + oal_net_device_stru *netdev = HI_NULL; + + ...... + /* 初始化网络设备,获取对应的实例。*/ + netdev = NetDeviceInit(ifname, *len, LITE_OS); + oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); + ret = wal_init_netif(type, netdev, wdev); + + ...... + + return HI_SUCCESS; +} +/* 挂接netdev的一些函数指针,详细挂接函数{@link NetDeviceInterFace} */ +oal_net_device_ops_stru g_wal_net_dev_ops = +{ + .getStats = wal_netdev_get_stats, + .open = wal_netdev_open, + .stop = wal_netdev_stop, + .xmit = hmac_bridge_vap_xmit, + .ioctl = wal_net_device_ioctl, + .changeMtu = oal_net_device_change_mtu, + .init = oal_net_device_init, + .deInit = oal_net_free_netdev, +#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) + .selectQueue = wal_netdev_select_queue, +#endif + .setMacAddr = wal_netdev_set_mac_addr, +#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) + .netifNotify = HI_NULL, +#endif + .specialEtherTypeProcess = SpecialEtherTypeProcess, +}; + +hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) +{ + /* 添加网络设备到协议栈 */ + hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); + + ...... + + return HI_SUCCESS; +} +``` + +4、WifiMac80211Ops中的函数挂接实现。 + +``` +/* 挂接mac80211的一些函数指针 */ + +/* 驱动需要实现的MAC层基本能力的控制接口 */ +static struct HdfMac80211BaseOps g_baseOps = { + .SetMode = WalSetMode, + .AddKey = WalAddKey, + .DelKey = WalDelKey, + .SetDefaultKey = WalSetDefaultKey, + .GetDeviceMacAddr = WalGetDeviceMacAddr, + .SetMacAddr = WalSetMacAddr, + .SetTxPower = WalSetTxPower, + .GetValidFreqsWithBand = WalGetValidFreqsWithBand, + .GetHwCapability = WalGetHwCapability +}; + +/* 驱动需要实现的MAC层STA能力的控制接口 */ +static struct HdfMac80211STAOps g_staOps = { + .Connect = WalConnect, + .Disconnect = WalDisconnect, + .StartScan = WalStartScan, + .AbortScan = WalAbortScan, + .SetScanningMacAddress = WalSetScanningMacAddress, +}; + +/* 驱动需要实现的MAC层AP能力的控制接口 */ +static struct HdfMac80211APOps g_apOps = { + .ConfigAp = WalConfigAp, + .StartAp = WalStartAp, + .StopAp = WalStopAp, + .ConfigBeacon = WalChangeBeacon, + .DelStation = WalDelStation, + .SetCountryCode = WalSetCountryCode, + .GetAssociatedStasCount = WalGetAssociatedStasCount, + .GetAssociatedStasInfo = WalGetAssociatedStasInfo +}; + +/* 初始化mac80211与芯片侧的函数挂接 */ +hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) +{ + if (chipDriver == NULL) { + oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__); + return; + } + chipDriver->ops = &g_baseOps; + chipDriver->staOps = &g_staOps; + chipDriver->apOps = &g_apOps; +} +``` + diff --git a/zh-cn/device-dev/driver/driver-peripherals-lcd-des.md b/zh-cn/device-dev/driver/driver-peripherals-lcd-des.md new file mode 100644 index 0000000000000000000000000000000000000000..90f54e12fbaa67eab88e46ecb651c4f7fb4bb7d1 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-peripherals-lcd-des.md @@ -0,0 +1,363 @@ +# LCD + +- [概述](#section141575391542) + - [接口说明](#section14711163785519) + +- [开发指导](#section12394223125615) + - [开发步骤](#section515923045814) + +- [开发实例](#section7441155155813) + +## 概述 + +LCD(Liquid Crystal Display)液晶显示驱动,对LCD进行上电,并通过接口初始化LCD内部寄存器,使LCD正常工作。Display驱动模型基于HDF( Hardware Driver Foundation)[驱动框架](driver-hdf-overview.md)开发,实现跨OS、跨平台,为LCD硬件提供上下电功能、发送初始化序列功能,使LCD进入正常的工作模式,显示芯片平台侧的图像数据,基于HDF驱动框架的Display驱动模型如[图1](#fig69138814229)。 + +**图 1** 基于HDF驱动框架的Display驱动模型 +![](figure/基于HDF驱动框架的Display驱动模型.png "基于HDF驱动框架的Display驱动模型") + +- **Display驱动模型介绍** + + Display驱动模型主要由平台驱动层、芯片平台适配层、LCD器件驱动层三部分组成。驱动模型基于HDF驱动框架开发,通过Platform层和OSAL层提供的接口,屏蔽内核形态的差异,使得器件驱动可以便利的迁移到不同OS及芯片平台。模型向上对接Display公共hal层,支撑HDI接口的实现,通过Display-HDI(Hardware Display Interface)对图形服务提供各类驱动能力接口。 + + (1)Display平台驱动层:通过HDF提供的IOService数据通道,与公共Hal层对接,集中接收并处理各类上层调用指令; + + (2)SOC平台驱动适配层:借助此SOC适配层,实现Display驱动和SOC侧驱动解耦,主要完成芯片平台相关的参数配置,并传递平台驱动层的调用到器件驱动层; + + (3)LCD器件驱动层:在器件驱动层中,主要实现和器件自身强相关的驱动适配接口,例如发送初始化序列、上下电、背光设置等。 + + 基于Display驱动模型开发LCD驱动,可以借助平台提供的各种能力及接口,较大程度的降低器件驱动的开发周期和难度,提升开发效率。 + + +### 接口说明 + +LCD接口通常可分为MIPI DSI接口、TTL接口和LVDS接口,常用的是MIPI DSI接口和TTL接口,下面对常用的MIPI DSI接口和TTL接口作简要介绍。 + +- MIPI DSI接口 + + **图 2** MIPI DSI接口 + ![](figure/MIPI-DSI接口.png "MIPI-DSI接口") + + MIPI DSI接口是MIPI(移动行业处理器接口)联盟定义的显示接口,主要用于移动终端显示屏接口,接口数据传输遵循MIPI协议,MIPI DSI接口为数据接口,传输图像数据,通常情况下MIPI DSI接口的控制信息以MIPI包形式通过MIPI DSI接口发送到对端IC,不需要额外的外设接口。 + +- TTL接口 + + **图 3** TTL接口 + ![](figure/TTL接口.png "TTL接口") + + TTL(Transistor Transistor Logic)即晶体管-晶体管逻辑,TTL电平信号由TTL器件产生,TTL器件是数字集成电路的一大门类,它采用双极型工艺制造,具有高速度、低功耗和品种多等特点。 + + TTL接口是并行方式传输数据的接口,有数据信号、时钟信号和控制信号(行同步、帧同步、数据有效信号等),在控制信号控制下完成数据传输。通常TTL接口的LCD,内部寄存器读写需要额外的外设接口,比如SPI接口、I2C接口等。 + + +## 开发指导 + +Display驱动模型基于HDF驱动框架、Platform接口及OSAL接口开发,可以做到不区分OS(LiteOS、Linux)和芯片平台(Hi35xx、Hi38xx、V3S等),为LCD器件提供统一的驱动模型。 + +### 开发步骤 + +1. 添加LCD驱动相关的设备描述配置。 +2. 在SOC平台驱动适配层中适配对应的芯片平台驱动。 +3. 添加器件驱动,并在驱动入口函数Init中注册Panel驱动数据,驱动数据接口主要包括如下接口: + - LCD上下电 + + 根据LCD硬件连接,使用Platform接口层提供的GPIO操作接口操作对应LCD管脚,例如复位管脚、IOVCC管脚,上电时序参考LCD供应商提供的SPEC。 + + - 发送初始化序列 + + 根据LCD硬件接口,使用Platform接口层提供的I2C、SPI、MIPI等接口,下载LCD初始化序列,初始化参数序列可以参考LCD供应商提供的SPEC。 + + +4. 根据需求实现HDF框架其他接口,比如Release接口。 +5. 根据需求使用HDF框架可创建其他设备节点,用于业务逻辑或者调试功能。 + +## 开发实例 + +添加设备描述配置: + +``` +/* Display驱动相关的设备描述配置 */ +display :: host { + hostName = "display_host"; + /* Display平台驱动设备描述 */ + device_hdf_disp :: device { + device0 :: deviceNode { + policy = 2; + priority = 200; + permission = 0660; + moduleName = "HDF_DISP"; + serviceName = "hdf_disp"; + } + } + /* SOC适配层驱动设备描述 */ + device_hi35xx_disp :: device { + device0 :: deviceNode { + policy = 0; + priority = 199; + moduleName = "HI351XX_DISP"; + } + } + /* LCD器件驱动设备描述 */ + device_lcd :: device { + device0 :: deviceNode { + policy = 0; + priority = 100; + preload = 0; + moduleName = "LCD_Sample"; + } + device1 :: deviceNode { + policy = 0; + priority = 100; + preload = 2; + moduleName = "LCD_SampleXX"; + } + } +} +``` + +SOC适配层驱动,以Hi35xx系列芯片为例,需要在本层驱动中适配MIPI等和芯片平台相关的配置,示例如下: + +``` +static int32_t MipiDsiInit(struct PanelInfo *info) +{ + int32_t ret; + struct DevHandle *mipiHandle = NULL; + struct MipiCfg cfg; + + mipiHandle = MipiDsiOpen(0); + if (mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + cfg.lane = info->mipi.lane; + cfg.mode = info->mipi.mode; + cfg.format = info->mipi.format; + cfg.burstMode = info->mipi.burstMode; + cfg.timing.xPixels = info->width; + cfg.timing.hsaPixels = info->hsw; + cfg.timing.hbpPixels = info->hbp; + cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; + cfg.timing.vsaLines = info->vsw; + cfg.timing.vbpLines = info->vbp; + cfg.timing.vfpLines = info->vfp; + cfg.timing.ylines = info->height; + /* 0 : no care */ + cfg.timing.edpiCmdSize = 0; + cfg.pixelClk = CalcPixelClk(info); + cfg.phyDataRate = CalcDataRate(info); + /* config mipi device */ + ret = MipiDsiSetCfg(mipiHandle, &cfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); + } + MipiDsiClose(mipiHandle); + HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, + cfg.pixelClk, cfg.phyDataRate); + return ret; +} +``` + +LCD器件驱动示例如下: + +``` +#define RESET_GPIO 5 +#define MIPI_DSI0 0 +#define BLK_PWM1 1 +#define PWM_MAX_PERIOD 100000 +/* backlight setting */ +#define MIN_LEVEL 0 +#define MAX_LEVEL 255 +#define DEFAULT_LEVEL 100 + +#define WIDTH 480 +#define HEIGHT 960 +#define HORIZONTAL_BACK_PORCH 20 +#define HORIZONTAL_FRONT_PORCH 20 +#define HORIZONTAL_SYNC_WIDTH 10 +#define VERTIACL_BACK_PORCH 14 +#define VERTIACL_FRONT_PORCH 16 +#define VERTIACL_SYNC_WIDTH 2 +#define FRAME_RATE 60 + +/* Panel Info结构体结构体 */ +struct PanelInfo { + uint32_t width; + uint32_t height; + uint32_t hbp; + uint32_t hfp; + uint32_t hsw; + uint32_t vbp; + uint32_t vfp; + uint32_t vsw; + uint32_t frameRate; + enum LcdIntfType intfType; + enum IntfSync intfSync; + struct MipiDsiDesc mipi; + struct BlkDesc blk; + struct PwmCfg pwm; +}; + +/* LCD屏的初始化序列 */ +static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; +static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; +static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; +static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; +static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; +static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; +static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; +static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; +static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; +static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; +static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; +static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; +static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; +static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; +static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; +static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; +static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; +static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; +static uint8_t g_payLoad18[] = { + 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, + 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, + 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 +}; +static uint8_t g_payLoad19[] = { 0x11 }; +static uint8_t g_payLoad20[] = { 0x29 }; + +struct DsiCmdDesc g_OnCmd[] = { + { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, + { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, + { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, + { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, + { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, + { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, + { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, + { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, + { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, + { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, + { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, + { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, + { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, + { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, + { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, + { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, + { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, + { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, + { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, + { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, + { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, +}; +static DevHandle g_mipiHandle = NULL; +static DevHandle g_pwmHandle = NULL; + +/* 设置Reset Pin脚状态 */ +static int32_t LcdResetOn(void) +{ + int32_t ret; + ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioSetDir failure, ret:%d", ret); + return HDF_FAILURE; + } + ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioWrite failure, ret:%d", ret); + return HDF_FAILURE; + } + /* delay 20ms */ + OsalMSleep(20); + return HDF_SUCCESS; +} + +static int32_t SampleInit(void) +{ + /* 获取MIPI DSI设备操作句柄 */ + g_mipiHandle = MipiDsiOpen(MIPI_DSI0); + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t SampleOn(void) +{ + int32_t ret; + /* LCD上电序列 */ + ret = LcdResetOn(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: LcdResetOn failure", __func__); + return HDF_FAILURE; + } + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: g_mipiHandle is null", __func__); + return HDF_FAILURE; + } + /* 使用mipi下发初始化序列 */ + int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); + int32_t i; + for (i = 0; i < count; i++) { + ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); + if (ret != HDF_SUCCESS) { + HDF_LOGE("MipiDsiTx failure"); + return HDF_FAILURE; + } + } + /* 将mipi切换到HS模式 */ + MipiDsiSetHsMode(g_mipiHandle); + return HDF_SUCCESS; +} + +/* PanelInfo结构体变量 */ +static struct PanelInfo g_panelInfo = { + .width = WIDTH, /* width */ + .height = HEIGHT, /* height */ + .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ + .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ + .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ + .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ + .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ + .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ + .frameRate = FRAME_RATE, /* frame rate */ + .intfType = MIPI_DSI, /* panel interface type */ + .intfSync = OUTPUT_USER, /* output timming type */ + /* mipi config info */ + .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, + /* backlight config info */ + .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, + .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, +}; + +/* 器件驱动需要适配的基础接口 */ +static struct PanelData g_panelData = { + .info = &g_panelInfo, + .init = SampleInit, + .on = SampleOn, + .off = SampleOff, + .setBacklight = SampleSetBacklight, +}; + +/* 器件驱动入口函数 */ +int32_t SampleEntryInit(struct HdfDeviceObject *object) +{ + HDF_LOGI("%s: enter", __func__); + if (object == NULL) { + HDF_LOGE("%s: param is null!", __func__); + return HDF_FAILURE; + } + /* 器件驱动接口注册,ops提供给平台驱动调用 */ + if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { + HDF_LOGE("%s: PanelDataRegister error!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +struct HdfDriverEntry g_sampleDevEntry = { + .moduleVersion = 1, + .moduleName = "LCD_SAMPLE", + .Init = SampleEntryInit, +}; + +HDF_INIT(g_sampleDevEntry); +``` + diff --git a/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md b/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md new file mode 100644 index 0000000000000000000000000000000000000000..a548abe552a26190c342b9f758a681f83861d271 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md @@ -0,0 +1,929 @@ +# SENSOR + +- [概述](#section3634112111) + - [接口说明](#section188213414114) + +- [开发指导](#section1140943382) + - [开发步骤](#section7893102915819) + +- [开发实例](#section257750691) +- [测试指导](#section106021256121219) + +## 概述 + +Sensor(传感器)驱动模块为上层Sensor服务系统提供稳定的Sensor基础能力API,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置等功能;基于HDF(**H**ardware **D**river **F**oundation)驱动框架开发的Sensor驱动模型,实现跨操作系统迁移,器件差异配置等功能。Sensor驱动模型如下图1所示: + +**图 1** Sensor驱动模型图 +![](figure/Sensor驱动模型图.png "Sensor驱动模型图") + +Sensor驱动模型对外开放的API接口能力如下: + +- 提供Sensor HDI(**H**ardware **D**river **I**nterface)能力接口,简化服务开发。 +- 提供Sensor驱动模型能力接口:依赖HDF驱动框架实现Sensor器件驱动的注册,加载,去注册,器件探测等能力,提供同一类型Sensor器件驱动归一接口, 寄存器配置解析操作接口,总线访问抽象接口,平台抽象接口。 +- 提供开发者实现的能力接口:依赖HDF驱动框架的HCS\(**H**DF **C**onfiguration **S**ource\)配置管理,根据同类型Sensor差异化配置,实现Sensor器件参数序列化配置和器件部分操作接口,简化Sensor器件驱动开发。 + +### 接口说明 + +Sensor驱动模型对HDI开放的API接口功能,参考表1。 + +**表 1** Sensor驱动模型对外API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

功能描述

+

查询操作

+

int32_t GetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)

+

获取系统中注册的所有传感器信息,一种类型传感器信息包括传感器名字、设备厂商、固件版本号、硬件版本号、传感器类型编号、传感器标识、最大量程、精度、功耗。

+

配置操作

+

int32_t Enable(int32_t sensorId)

+

使能一种传感器设备,只有数据订阅者使能传感器后,才能获取订阅的传感器数据。

+

int32_t Disable(int32_t sensorId)

+

去使能一种传感器设备。

+

int32_t SetBatch(iint32_t sensorId, int64_t samplingInterval, int64_t reportInterval)

+

设置一种传感器的数据采样间隔和数据上报间隔。

+

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

+

设置一种传感器的工作模式,不同的工作模式,上报数据方式不同。

+

int32_t SetOption(int32_t sensorId, uint32_t option)

+

设置一种传感器量程,精度等可选配置。

+

数据订阅操作

+

int32_t Register(RecordDataCallback cb)

+

订阅者注册传感器数据回调函数,系统会将获取到的传感器数据上报给订阅者。

+

int32_t Unregister(void)

+

订阅者去注册传感器数据回调函数。

+

接口实例

+

const struct SensorInterface *NewSensorInterfaceInstance(void)

+

创建传感器接口实例。

+

int32_t FreeSensorInterfaceInstance(void)

+

释放传感器接口实例。

+
+ +Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无需实现,直接使用,参考表2: + +**表 2** Sensor驱动模型对驱动开发者开放的功能接口列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

功能描述

+

设备管理操作接口

+

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

+

添加当前类型的传感器设备到传感器设备管理。

+

int32_t DeleteSensorDevice(int32_t sensorId)

+

删除传感器设备管理里指定的传感器设备。

+

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

+

上报指定类型传感器的数据到用户侧。

+

Sensor抽象总线和平台操作接口

+

int32_t ReadSensor(struct SensorBusCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen)

+

按照配置的总线方式,读取传感器寄存器配置数据。

+

int32_t WriteSensor(struct SensorBusCfg *busCfg, uint8_t *writeData, uint16_t len)

+

按照配置的总线方式,传感器配置数据写入寄存器。

+

int32_t CreateSensorThread(struct OsalThread *thread, OsalThreadEntry threadEntry, char *name, void *entryPara)

+

创建指定传感器的定时线程,用于传感器数据上报处理。

+

void DestroySensorThread(struct OsalThread *thread, uint8_t *status);

+

销毁传感器创建的定时线程。

+

通用配置操作接口

+

int32_t SetSensorRegCfgArray(struct SensorBusCfg *busCfg, const struct SensorRegCfgGroupNode *group);

+

根据传感器总线类型信息,下发寄存器分组配置。

+

配置解析操作接口

+

+

int32_t GetSensorBaseConfigData(const struct DeviceResourceNode *node, struct SensorCfgData *config)

+

根据传感器设备HCS资源配置,获取传感器信息,总线配置信息,属性配置等基本配置信息,并初始化对应的基本配置数据结构体。

+

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

+

根据传感器设备HCS资源配置,解析寄存器分组信息,并初始化配置数据结构体。

+

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

+

释放传感器配置数据结构体里分配的资源。

+

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

+

获取传感器总线句柄信息。

+

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

+

释放传感器句柄信息。

+
+ +Sensor驱动模型要求驱动开发者实现的接口功能,参考表3 + +**表 3** Sensor驱动模型要求驱动开发者实现的接口列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

功能描述

+

基本功能操作

+

int32_t init(void)

+

传感器器设备探测成功后,需要对传感器器设备初始化配置。

+

int32_t GetInfo(struct SensorBasicInfo *info)

+

从传感器器设备的HCS配置里,获取当前传感器设备的基本信息。

+

int32_t Enable(void)

+

根据当前传感器器设备的HCS配置,下发传感器设备使能操作组的寄存器配置。

+

int32_t Disable(void)

+

根据当前传感器器设备的HCS配置,下发传感器设备去使能操作组的寄存器配置。

+

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

+

根据数据采样率和数据上报间隔,配置当前传感器设备的数据上报线程处理时间。

+

int32_t SetMode(int32_t mode)

+

配置当前传感器设备数据上报方式。

+

int32_t SetOption(uint32_t option)

+

根据可选配置,下发量程,精度等寄存器配置。

+

void ReadSensorData(void)

+

实现传感器的数据读取函数。

+
+ +接口实现参考[SENSOR](#section257750691)章节。 + +## 开发指导 + +Sensor驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同Sensor器件提供统一的驱动模型。本篇开发指导以加速度计传感器为例,介绍传感器驱动开发。 + +### 开发步骤 + +1. 加速度计传感器驱动注册。HDF驱动框架会提供统一的驱动管理模型,通过加速计传感器模块配置信息,识别并加载对应模块驱动。 +2. 加速度计传感器驱动初始化和去初始化。HDF驱动框架通过init入口函数,依次启动传感器设备驱动加载和分配传感器设备数据配置资源。HDF驱动框架通过release函数,释放驱动加载的资源和配置。 +3. 加速度计传感器寄存器组配置解析。不同类型传感器需要在hcs里配置器件对应的HCS配置文件,然后再设备驱动启动过程中探测器件是否在位,然后加载对应的配置文件,生成配置的结构体对象。 +4. 加速度计传感器驱动操作接口实现。实现各个类型传感器归一化驱动接口,如init,GetInfo,Enable,Disable,SetBatch,SetMode,SetOption,ReadSensorData等函数,完成传感器驱动配置下发和数据上报功能。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>传感器驱动模型已经提供一部分能力集,包括驱动设备管理能力,抽象总线和平台操作接口能力,通用配置操作接口能力,配置解析操作接口能力,接口参考[表2](#table1156812588320)。需要开发人员实现部分有:1、传感器部分操作接口([表3](#table1083014911336));2、传感器HCS差异化数据配置;3、驱动基本功能验证。 + +## 开发实例 + +基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md)。加速度传感器选择通讯接口方式为I2C,厂家选择博世BMI160加速度传感器。 + +1. 加速度计传感器驱动入口注册 + +- 加速度计传感器驱动入口函数实现 + +``` +/* 注册加速度计传感器入口数据结构体对象 */ +struct HdfDriverEntry g_sensorAccelDevEntry = { + .moduleVersion = 1, /* 加速度计传感器模块版本号 */ + .moduleName = "HDF_SENSOR_ACCEL", /* 加速度计传感器模块名,要与device_info.hcs文件里的加速度计moduleName字段值一样*/ + .Bind = BindAccelDriver, /* 加速度计传感器绑定函数 */ + .Init = InitAccelDriver, /* 加速度计传感器初始化函数 */ + .Release = ReleaseAccelDriver, /* 加速度计传感器资源释放函数 */ +}; + +/* 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 */ +HDF_INIT(g_sensorAccelDevEntry); +``` + +- 加速度计传感器设备配置描述 + +加速度传感器模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](driver-hdf-manage.md)介绍。 + +``` +/* 加速度计传感器设备HCS配置 */ +device_sensor_accel :: device { + device0 :: deviceNode { + policy = 1; /* policy字段是驱动服务发布的策略 */ + priority = 105; /* 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */ + preload = 2; /* 驱动按需加载字段,0表示加载,2表示不加载 */ + permission = 0664; /* 驱动创建设备节点权限 */ + moduleName = "HDF_SENSOR_ACCEL"; /* 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */ + serviceName = "sensor_accel"; /* 驱动对外发布服务的名称,必须唯一 */ + deviceMatchAttr = "hdf_sensor_accel_driver"; /* 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 */ + } +} +``` + +1. 加速度计传感器驱动初始化和去初始化 + +- 初始化入口函数init + +``` +/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */ +int32_t BindAccelDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + + static struct IDeviceIoService service = { + .object = {0}, + .Dispatch = DispatchAccel, + }; + device->service = &service; + + return HDF_SUCCESS; +} +/*在探测到器件在位后,需要调用RegisterAccelChipOps注册差异化适配函数*/ +int32_t RegisterAccelChipOps(struct AccelOpsCall *ops) +{ + struct AccelDrvData *drvData = NULL; + + CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); + + drvData = AccelGetDrvData(); + drvData->ops.Init = ops->Init; + drvData->ops.ReadData = ops->ReadData; + return HDF_SUCCESS; +} +/* 挂载加速度计传感器驱动归一化的接口函数 */ +static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo) +{ + struct AccelDrvData *drvData = AccelGetDrvData(); + + (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); + deviceInfo->ops.GetInfo = SetAccelInfo; + deviceInfo->ops.Enable = SetAccelEnable; + deviceInfo->ops.Disable = SetAccelDisable; + deviceInfo->ops.SetBatch = SetAccelBatch; + deviceInfo->ops.SetMode = SetAccelMode; + deviceInfo->ops.SetOption = SetAccelOption; + + if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), + &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) { + HDF_LOGE("%s: copy sensor info failed", __func__); + return HDF_FAILURE; + } + /* 传感器类型标识可以在数据HCS配置文件里面配置,也可以在此处 */ + drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER; + drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER; + + return HDF_SUCCESS; +} +/* 传感器寄存器初始化操作 */ +static int32_t InitAccelAfterConfig(void) +{ + struct SensorDeviceInfo deviceInfo; + + if (InitAccelConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel config failed", __func__); + return HDF_FAILURE; + } + + if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: init accel ops failed", __func__); + return HDF_FAILURE; + } + + if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: add accel device failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} +/*通过器件探测函数,挂载器件差异化函数接口*/ +static int32_t DetectAccelChip(void) +{ + int32_t num; + int32_t ret; + int32_t loop; + struct AccelDrvData *drvData = AccelGetDrvData(); + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]); + for (loop = 0; loop < num; ++loop) { + if (g_accelDetectIfList[loop].DetectChip != NULL) { + ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg); + if (ret == HDF_SUCCESS) { + drvData->detectFlag = true; + break; + } + } + } + + if (loop == num) { + HDF_LOGE("%s: detect accel device failed", __func__); + drvData->detectFlag = false; + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +/* 加速度计传感器驱动初始化入口函数,主要功能为对传感器私有数据的结构体对象进行初始化,传感器HCS数据配置对象空间分配,传感器HCS数据配置初始化入口函数调用,传感器设备探测是否在位功能,传感器数据上报定时器创建,传感器归一化接口挂载,传感器设备注册功能 */ +int32_t InitAccelDriver(struct HdfDeviceObject *device) +{ + /* 获取传感器私有数据结构体对象 */ + struct AccelDrvData *drvData = AccelGetDrvData(); + + /* 同类型传感器不同厂家设备探测时,判断此类型传感器是否已经在位,若已经在位,无需再继续探测,直接返回 */ + if (drvData->detectFlag) { + HDF_LOGE("%s: accel sensor have detected", __func__); + return HDF_SUCCESS; + } + + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + /* 分配存放传感器数据配置的私有结构体数据对象,需要在驱动释放时释放分配的资源空间 */ + drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg)); + if (drvData->accelCfg == NULL) { + HDF_LOGE("%s: malloc sensor config data failed", __func__); + return HDF_FAILURE; + } + + drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; + /* 初始化传感器配置数据主要是解析传感器通讯总线配置类型信息,传感器基本信息,传感器属性信息,传感器是否在位信息,寄存器分组信息 */ + if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: get sensor base config failed", __func__); + goto Base_CONFIG_EXIT; + } + + if (DetectAccelChip() != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor detect device no exist", __func__); + goto DETECT_CHIP_EXIT; + } + drvData->detectFlag = true; + if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: detect sensor device failed", __func__); + goto REG_CONFIG_EXIT; + } + + if (InitAccelAfterConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel after config failed", __func__); + goto INIT_EXIT; + } + + HDF_LOGI("%s: init accel driver success", __func__); + return HDF_SUCCESS; + +INIT_EXIT: + DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); +REG_CONFIG_EXIT: + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); +DETECT_CHIP_EXIT: + drvData->detectFlag = false; +BASE_CONFIG_EXIT: + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + return HDF_FAILURE; +} + +/* 释放驱动初始化时分配的资源 */ +void ReleaseAccelDriver(struct HdfDeviceObject *device) +{ + (void)device; + struct AccelDrvData *drvData = NULL; + + drvData = AccelGetDrvData(); + (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); + drvData->detectFlag = false; + + if (drvData->accelCfg != NULL) { + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + } + + drvData->initStatus = false; +} +``` + +1. 加速度计传感器寄存器组配置信息 + +加速度计传感器数据配置只需要按照模板配置即可,基于模板配置的解析功能已经在**InitSensorConfigData**函数完成,只需初始化时调用即可。如果有新增配置项,需要同步修改此函数。 + +``` +加速度传感器数据配置模板(accel_config.hcs) +root { + sensorAccelConfig { + accelChipConfig { + /* 传感器设备信息模板 */ + template sensorInfo { + sensorName = "accelerometer"; /* 加速度计名字,字符最大长度16字节 */ + vendorName = "borsh_bmi160"; /* 传感器设备厂商,字符最大长度16字节 */ + firmwareVersion = "1.0"; /* 传感器固件版本号,默认1.0,字符最大长度16字节 */ + hardwareVersion = "1.0"; /* 传感器硬件版本号,默认1.0,字符最大长度16字节 */ + sensorTypeId = 1; /* 传感器类型编号,详见{@link SensorTypeTag} */ + sensorId = 1; /* 传感器的标识号,有传感器驱动开发者定义,推荐用{@link SensorTypeTag}枚举 */ + maxRange = 8; /* 传感器的最大量程,根据开发者需要配置 */ + precision = 0; /* 传感器的精度,与上报数据配合使用,上报数据结构体{@link SensorEvents } */ + power = 230; /* 传感器的功耗 */ + } + /* 传感器使用的总线类型和配置信息模板 */ + template sensorBusConfig { + busType = 0; /* 0:i2c 1:spi */ + busNum = 6; /* 芯片上分配给传感器的器件号 */ + busAddr = 0; /* 芯片上分配给传感器的地址 */ + regWidth = 1; /* 传感器寄存器地址宽度 */ + regBigEndian = 0; /* 传感器寄存器大小端 */ + } + /* 传感器设备属性模板 */ + template sensorAttr { + chipName = ""; /* 传感器芯片名字 */ + chipIdRegister = 0xf; /* 传感器在位检测寄存器地址 */ + chipIdValue = 0xd1; /* 校验传感器在位检测寄存器值 */ + } + } + } +} + +/* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */ +root { + sensorAccelConfig { + accel_bmi160_chip_config : accelChipConfig { + match_attr = "hdf_sensor_accel_driver"; /* 需要和加速度传感器设备配置match_attr字段保持一致 */ + accelInfo :: sensorInfo { + vendorName = "borsh_bmi160"; + sensorTypeId = 1; + sensorId = 1; + } + accelBusConfig :: sensorBusConfig { + busType = 0; /* i2c通讯方式 */ + busNum = 6; + busAddr = 0x68; + regWidth = 1; /* 1字节位宽 */ + } + accelAttr :: sensorAttr { + chipName = "bmi160"; + chipIdRegister = 0x00; + chipIdValue = 0xd1; + } + accelRegConfig { + /* regAddr: 寄存器地址 + value: 寄存器值 + mask: 寄存器值的掩码 + len: 寄存器值的数据长度(字节) + delay: 配置寄存器延时(ms) + opsType:操作类型 0-无 1-读 2-写 3-读并检查 4-位更新 + calType: 计算类型 0-无 1-写 2-取反 3-异或 4-左移 5-右移 + shiftNum: 移动位数 + debug: 调试开关,0-调试关闭 1-调试打开 + save: 保存数据开关,0-不保存数据 1-保存数据 + */ + /* 传感器寄存器操作分组,按照分组进行有序配置 */ + /* 寄存器地址, 寄存器值, 寄存器值的掩码, 寄存器值的数据长度, 配置寄存器延时, 操作类型, 计算类型, 移动位数, 调试开关, 保存开关 */ + /* 初始化寄存器组 */ + initSeqConfig = [ + 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + /* 使能寄存器组 */ + enableSeqConfig = [ + 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0, + 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0 + ]; + /* 去使能寄存器组 */ + disableSeqConfig = [ + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + } + } + } +} +``` + +1. 加速度计传感器驱动操作接口实现 + +开发者需要根据每种类型的传感器实现归一化接口。 + +``` +/* 不使用函数暂时置空 */ +static int32_t SetAccelInfo(struct SensorBasicInfo *info) +{ + (void)info; + + return HDF_ERR_NOT_SUPPORT; +} +/* 下发使能寄存器组的配置 */ +static int32_t SetAccelEnable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_RUNNING; + + return HDF_SUCCESS; +} +/* 下发去使能寄存器组的配置 */ +static int32_t SetAccelDisable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_STOPPED; + + return HDF_SUCCESS; +} +/* 配置传感器采样率和数据上报间隔 */ +static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval) +{ + (void)interval; + + struct AccelDrvData *drvData = AccelGetDrvData(); + drvData->interval = samplingInterval; + + return HDF_SUCCESS; +} +/* 设置传感器工作模式,当前支持实时模式 */ +static int32_t SetAccelMode(int32_t mode) +{ + return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE; +} +/* 设置传感器可选配置 */ +static int32_t SetAccelOption(uint32_t option) +{ + (void)option; + return HDF_ERR_NOT_SUPPORT; +} +``` + +- 差异化处理接口 + + ``` + /* 器件探测时,如果探测成功,则注册差异化处理函数到accel驱动模型里 */ + int32_t DetectAccelBim160Chip(struct SensorCfgData *data) + { + int32_t ret; + struct AccelOpsCall ops; + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + + if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) { + return HDF_SUCCESS; + } + ret = InitAccelPreConfig(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: init BMI160 bus mux config", __func__); + return HDF_FAILURE; + } + if (DetectSensorDevice(data) != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* 差异化处理函数 */ + ops.Init = InitBmi160; + ops.ReadData = ReadBmi160Data; + ret = RegisterAccelChipOps(&ops); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: register BMI160 accel failed", __func__); + (void)ReleaseSensorBusHandle(&data->busCfg); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* 初始化处理函数 */ + static int32_t InitBmi160(struct SensorCfgData *data) + { + int32_t ret; + + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: bmi160 sensor init config failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* 数据处理函数 */ + int32_t ReadBmi160Data(struct SensorCfgData *data) + { + int32_t ret; + struct AccelData rawData = { 0, 0, 0 }; + int32_t tmp[ACCEL_AXIS_NUM]; + struct SensorReportEvent event; + + (void)memset_s(&event, sizeof(event), 0, sizeof(event)); + + ret = ReadBmi160RawData(data, &rawData, &event.timestamp); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + event.sensorId = SENSOR_TAG_ACCELEROMETER; + event.option = 0; + event.mode = SENSOR_WORK_MODE_REALTIME; + + rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G; + rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G; + rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G; + + tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + + event.dataLen = sizeof(tmp); + event.data = (uint8_t *)&tmp; + ret = ReportSensorEvent(&event); + return ret; + } + ``` + +- 数据处理函数 + +创建传感器定时器,按照配置的采样率定时采样,并上报给数据订阅者。 + +``` +/* 传感器定时工作线程 */ +static int32_t ReadAccelDataThreadWorker(void *arg) +{ + (void)arg; + int64_t interval; + struct AccelDrvData *drvData = AccelGetDrvData(); + + drvData->threadStatus = SENSOR_THREAD_START; + while (true) { + if (drvData->threadStatus == SENSOR_THREAD_RUNNING) { + if (drvData->ops.ReadData != NULL) { + (void)drvData->ops.ReadData(drvData->accelCfg); + } + interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT)); + OsalMSleep(interval); + } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) { + break; + } else { + OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT); + } + + if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) { + continue; + } + } + + return HDF_SUCCESS; +} +/* 创建传感器定时器和器件初始化 */ +static int32_t InitAccelConfig(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) { + HDF_LOGE("%s: accel thread have created", __func__); + return HDF_SUCCESS; + } + + ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + + CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM); + + ret = drvData->ops.Init(drvData->accelCfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + drvData->initStatus = true; + return HDF_SUCCESS; +} +``` + +- 主要的数据结构 + +``` +/* 传感器转换单位*/ +#define SENSOR_CONVERT_UNIT 1000 +#define SENSOR_1K_UNIT 1024 +/* 传感器2g对应灵敏度转换值 */ +#define BMI160_ACC_SENSITIVITY_2G 61 +/* 传感器数据采样寄存器地址 */ +#define BMI160_ACCEL_X_LSB_ADDR 0X12 +#define BMI160_ACCEL_X_MSB_ADDR 0X13 +#define BMI160_ACCEL_Y_LSB_ADDR 0X14 +#define BMI160_ACCEL_Y_MSB_ADDR 0X15 +#define BMI160_ACCEL_Z_LSB_ADDR 0X16 +#define BMI160_ACCEL_Z_MSB_ADDR 0X17 +/* 传感器数据维度 */ +enum AccelAxisNum { + ACCEL_X_AXIS = 0, + ACCEL_Y_AXIS = 1, + ACCEL_Z_AXIS = 2, + ACCEL_AXIS_NUM = 3, +}; +/* 传感器每个维度值 */ +struct AccelData { + int32_t x; + int32_t y; + int32_t z; +}; +/* 传感器私有数据结构体 */ +struct AccelDrvData { + bool detectFlag; + uint8_t threadStatus; + uint8_t initStatus; + int64_t interval; + struct SensorCfgData *accelCfg; + struct OsalThread thread; + struct AccelOpsCall ops; +}; +/* 差异化适配函数 */ +struct AccelOpsCall { + int32_t (*Init)(struct SensorCfgData *data); + int32_t (*ReadData)(struct SensorCfgData *data); +}; +``` + +## 测试指导 + +驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 + +``` +/* 标识是否上报传感器数据 */ +static int32_t g_sensorDataFlag = 0; +/* 保持获取的传感器接口实例地址 */ +static const struct SensorInterface *g_sensorDev = nullptr; + +/* 订阅者注册数据上报函数 */ +static int SensorTestDataCallback(struct SensorEvents *event) +{ + if (event == nullptr) { + return -1; + } + float *data = (float*)event->data; + printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, + event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); + if (*data > 1e-5) { + g_sensorDataFlag = 1; + } + return 0; +} +/* 用例执行前,初始化传感器接口实例 */ +void HdfSensorTest::SetUpTestCase() +{ + g_sensorDev = NewSensorInterfaceInstance(); + if (g_sensorDev == nullptr) { + printf("test sensorHdi get Module instace failed\n\r"); + } +} +/* 用例资源释放 */ +void HdfSensorTest::TearDownTestCase() +{ + if (g_sensorDev != nullptr) { + FreeSensorInterfaceInstance(); + g_sensorDev = nullptr; + } +} +/* 传感器驱动测试验证 */ +HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) +{ + int32_t sensorInterval = 1000000000; /* 数据采样率单位纳秒 */ + int32_t pollTime = 5; /* 数据采样时间单位秒 */ + int32_t accelSensorId = 1; /* 加速度传感器类型标识为1 */ + int32_t count = 0; + int ret; + struct SensorInformation *sensorInfo = nullptr; + + ret = g_sensorDev->Register(SensorTestDataCallback) + EXPECT_EQ(SENSOR_NULL_PTR, ret); + + ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); + EXPECT_EQ(0, ret); + if (sensorInfo == nullptr) { + EXPECT_NE(nullptr, sensorInfo); + return; + } + /* 打印获取的传感器列表 */ + for (int i = 0; i < count; i++) { + printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); + } + ret = g_sensorDev->Enable(accelSensorId); + EXPECT_EQ(0, ret); + g_sensorDataFlag = 0; + + ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); + EXPECT_EQ(0, ret); + /* 在时间pollTime内,观察输出打印数据 */ + OsalSleep(pollTime); + EXPECT_EQ(1, g_sensorDataFlag); + + ret = g_sensorDev->Disable(accelSensorId); + g_sensorDataFlag = 0; + EXPECT_EQ(0, ret); + + ret = g_sensorDev->Unregister(); + EXPECT_EQ(0, ret); +} +``` + diff --git a/zh-cn/device-dev/driver/driver-peripherals-touch-des.md b/zh-cn/device-dev/driver/driver-peripherals-touch-des.md new file mode 100644 index 0000000000000000000000000000000000000000..5f4c46ba8ba7880cc11846b81f618167626bc455 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-peripherals-touch-des.md @@ -0,0 +1,410 @@ +# TOUCHSCREEN + +- [概述](#section175431838101617) + - [接口说明](#section17667171301711) + +- [开发指导](#section65745222184) + - [开发步骤](#section865734181916) + +- [开发实例](#section263714411191) + - [设备描述配置](#section18249155619195) + - [板级配置及器件私有配置](#section3571192072014) + - [添加器件驱动](#section6356758162015) + + +## 概述 + +- **Touchscreen驱动主要任务** + + Touchscreen驱动用于驱动触摸屏使其正常工作,该驱动主要完成如下工作:对触摸屏驱动IC进行上电、配置硬件管脚并初始化其状态、注册中断、配置通信接口(I2C或SPI)、设定input相关配置、下载及更新固件等操作。 + + +- **Touchscreen驱动层次说明** + + 本节主要介绍基于input驱动模型开发touchscreen器件驱动,其整体的框架模型如[图1](#fig6251184817261)。 + + Input驱动模型基于HDF驱动框架、PLATFORM接口、OSAL接口进行开发,向上对接规范化的驱动接口HDI(Hardware Driver Interface)层,通过Input-HDI层对外提供硬件能力,即上层input service可以通过HDI接口层获取相应的驱动能力,进而操控touchscreen等输入设备。 + + +**图 1** 基于HDF驱动框架的input驱动模型 +![](figure/基于HDF驱动框架的input驱动模型.png "基于HDF驱动框架的input驱动模型") + +- **Input驱动模型介绍** + + Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。器件产生的数据借助平台数据通道能力从内核传递到用户态,驱动模型通过配置文件适配不同器件及硬件平台,提高开发者的器件驱动开发效率。如下部分为模型各部分的说明: + + (1)input设备管理:为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; + + (2)input平台驱动:指各类input设备的公共抽象驱动(例如触摸屏的公共驱动),负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; + + (3)input器件驱动:指各器件厂家的差异化驱动,通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; + + (4)input数据通道:提供一套通用的数据上报通道,各类别的input设备驱动均可用此通道上报input事件; + + (5)input配置解析:负责对input设备的板级配置及器件私有配置进行解析及管理。 + + +- **基于HDF驱动框架开发器件驱动的优势** + + 在HDF(Hardware Driver Foundation)[驱动管理框架](driver-hdf-development.md)的基础上,input驱动模型调用OSAL接口层和Platfom接口层提供的基础接口进行开发,包括bus通信接口、操作系统原生接口(memory、lock、thread、timer等)。由于OSAL接口和Platform接口屏蔽了芯片平台差异,所以基于input驱动模型实现的touchscreen驱动可以进行跨平台、跨OS迁移,以便逐步实现驱动的一次开发,多端部署。 + + +### 接口说明 + +Touchscreen器件的硬件接口相对简单,根据PIN脚的属性,可以简单分为如下三类: + +- 电源接口 +- IO控制接口 +- 通信接口 + +**图 2** Touchscreen器件常用管脚 +![](figure/Touchscreen器件常用管脚.png "Touchscreen器件常用管脚") + +如上图所示的三类接口,分别做简要说明如下: + +1. **电源接口** + - LDO\_1P8:1.8v数字电路 + - LDO\_3P3:3.3v模拟电路 + + 通常情况下,touchscreen驱动IC和LCD驱动IC是相互分离的,这种情况下,touchscreen驱动IC一般同时需要1.8v和3.3v两路供电。随着芯片演进,业内已有touchscreen驱动IC和LCD驱动IC集成在一颗IC中的芯片案例,对touchscreen而言,只需要关注1.8v供电即可,其内部需要的3.3v电源,会在驱动IC内部从LCD的VSP电源(典型值5.5V)中分出来。 + + +2. **IO控制接口** + - Reset:reset管脚,用于在系统休眠、唤醒时,由主机侧对驱动IC进行复位操作。 + - INT:中断管脚,需要在驱动初始化时,配置为输入上拉状态。在驱动IC检测到外部触摸信号后,通过操作中断管脚来触发中断,器件驱动则会在中断处理函数中进行报点数据读取等操作。 + +3. **通信接口** + - I2C:由于touchscreen的报点数据量相对较少,所以一般选用I2C方式传输数据。I2C的具体协议及对应操作接口,可以参考Platform接口层中的[“I2C”使用指南](drive-platform-i2c-des.md#section1695201514281)。 + - SPI:部分厂商,由于需要传递的数据不止报点坐标,而是需要获取基础容值,数据量较大,所以会选用SPI通信方式。SPI的具体协议及对应操作接口,可以参考Platform接口层中的[“SPI” 使用指南](drive-platform-spi-des.md#section71363452477)。 + + +## 开发指导 + +Input驱动模型是基于HDF框架、Platform接口和OSAL接口开发,不区分操作系统和芯片平台,为touchscreen等输入器件提供统一的驱动开发架构。 + +- 如下以touchscreen器件驱动为例,说明input驱动模型的完整加载流程: + + (1)设备描述配置:由开发者参考已有模板进行设备描述配置,包括驱动加载顺序、板级硬件信息、器件私有数据信息等。 + + (2)加载input设备管理驱动:input设备管理驱动由HDF驱动加载,完成设备manager的创建并对其初始化。 + + (3)加载平台驱动:平台驱动由HDF框架加载,主要完成板级配置解析及硬件初始化,并提供器件注册接口。 + + (4)加载器件驱动:器件驱动也由HDF框架加载,完成器件设备的实例化,包括器件私有配置解析和平台预留的差异化接口适配。 + + (5)器件设备向平台驱动注册:将实例化的器件设备向平台驱动注册,实现设备和驱动的绑定,并完成中断注册、上下电等器件初始化工作。 + + (6)input设备注册:在器件初始化完成后,实例化input设备,并将其注册到input manager进行管理。 + + +### 开发步骤 + +1. 设备描述配置 + + 目前Input驱动基于HDF驱动框架编写,驱动的加载启动由HDF驱动管理框架统一处理。首先需要在对应的配置文件中,将驱动信息注册进去,如是否加载、加载优先级,此后HDF驱动框架会逐一启动注册过的驱动模块。驱动的相关配置请参考[HDF驱动框架配置指导](driver-hdf-development.md#section1969312275533)。 + +2. 板级配置及Touchscreen器件私有配置 + + 配置对应的IO管脚功能,例如对单板上为touchscreen设计预留的I2C Pin脚,需设置对应的寄存器,使其选择I2C的通信功能。 + +3. 实现器件差异化适配接口 + + 根据硬件单板设计的通信接口,使用Platform接口层提供的管脚操作接口配置对应的复位管脚、中断管脚以及电源操作,对于GPIO的操作,可参考[GPIO操作接口指导](drive-platform-gpio-des.md#section259614242196) + + +## 开发实例 + +本实例提供touchscreen驱动开发示例,并简要对具体关键点进行开发说明。 + +### 设备描述配置 + +如下配置主要包含input驱动模型各模块层级信息,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md),HDF框架依据该配置信息实现对Input模型各模块的依次加载等。 + +``` +input :: host { + hostName = "input_host"; + priority = 100; + device_input_manager :: device { + device0 :: deviceNode { + policy = 2; // 向外发布服务 + priority = 100; // 加载优先级,在input模块内,manager模块优先级应为最高 + preload = 0; // 加载该驱动 0:加载 1:不加载 + permission = 0660; + moduleName = "HDF_INPUT_MANAGER"; + serviceName = "input_dev_manager"; + deviceMatchAttr = ""; + } + } + device_hdf_touch :: device { + device0 :: deviceNode { + policy = 2; + priority = 120; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH"; + serviceName = "event1"; + deviceMatchAttr = "touch_device1"; + } + } + + device_touch_chip :: device { + device0 :: deviceNode { + policy = 0; + priority = 130; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH_SAMPLE"; + serviceName = "hdf_touch_sample_service"; + deviceMatchAttr = "zsj_sample_5p5"; + } + } +} +``` + +### 板级配置及器件私有配置 + +如下配置包含板级硬件配置及器件私有数据配置,实际业务开发时,可根据具体需求增删及修改如下配置文件信息。 + +``` +root { + input_config { + touchConfig { + touch0 { + boardConfig { + match_attr = "touch_device1"; + inputAttr { + inputType = 0; // 0代表触摸屏 + solutionX = 480; + solutionY = 960; + devName = "main_touch"; // 设备名称 + } + busConfig { + busType = 0; // 0代表I2C + busNum = 6; + clkGpio = 86; + dataGpio = 87; + i2cClkIomux = [0x114f0048, 0x403]; // i2c_clk对应pin的寄存器配置 + i2cDataIomux = [0x114f004c, 0x403]; // i2c_data对应pin的寄存器配置 + } + pinConfig { + rstGpio = 3; + intGpio = 4; + rstRegCfg = [0x112f0094, 0x400]; // reset对应pin的寄存器配置 + intRegCfg = [0x112f0098, 0x400]; // interrupt对应pin的寄存器配置 + } + powerConfig { + vccType = 2; // 1代表LDO、2代表GPIO、3代表PMIC + vccNum = 20; // GPIO号为20 + vccValue = 1800; // 电压幅值为1800mV + vciType = 1; + vciNum = 12; + vciValue = 3300; + } + featureConfig { + capacitanceTest = 0; + gestureMode = 0; + gloverMOde = 0; + coverMode = 0; + chargerMode = 0; + knuckleMode = 0; + } + } + chipConfig { + template touchChip { + match_attr = ""; + chipName = "sample"; + vendorName = "zsj"; + chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 + busType = 0; + deviceAddr = 0x5D; + irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 + maxSpeed = 400; + chipVersion = 0; + powerSequence { + /* 上电时序的配置含义说明: + [类型, 状态, 方向 , 延时] + 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 + 0代表下电或拉低,1代表上电或拉高,2代表无操作 + 0代表输入方向,1代表输出方向,2代表无操作 + 代表延时多少毫秒, 例如20代表延时20ms + */ + powerOnSeq = [4, 0, 1, 0, + 3, 0, 1, 10, + 3, 1, 2, 60, + 4, 2, 0, 0]; + suspendSeq = [3, 0, 2, 10]; + resumeSeq = [3, 1, 2, 10]; + powerOffSeq = [3, 0, 2, 10, + 1, 0, 2, 20]; + } + } + chip0 :: touchChip { + match_attr = "zsj_sample_5p5"; + chipInfo = "ZIDN45100"; + chipVersion = 0; + } + } + } + } + } +} +``` + +### 添加器件驱动 + +在器件驱动中,主要实现了平台预留的差异化接口,以器件数据获取及解析进行示例说明。具体开发过程,需要根据实际使用的单板及器件进行适配。 + +``` +/* 将从器件中读取到的报点数据解析为坐标 */ +static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) +{ + int32_t resX = device->driver->boardCfg->attr.resolutionX; + int32_t resY = device->driver->boardCfg->attr.resolutionY; + + for (int32_t i = 0; i < pointNum; i++) { + frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].valid = true; + } +} +/* 从器件中获取报点数据 */ +static int32_t ChipDataHandle(ChipDevice *device) +{ + int32_t ret; + uint8_t touchStatus = 0; + uint8_t pointNum; + uint8_t buf[GT_POINT_SIZE * MAX_SUPPORT_POINT] = {0}; + InputI2cClient *i2cClient = &device->driver->i2cClient; + uint8_t reg[GT_ADDR_LEN] = {0}; + FrameData *frame = &device->driver->frameData; + reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; + ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); + if (ret < 0 || touchStatus == GT_EVENT_INVALID) { + return HDF_FAILURE; + } + OsalMutexLock(&device->driver->mutex); + (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData)); + if (touchStatus == GT_EVENT_UP) { + frame->realPointNum = 0; + frame->definedEvent = TOUCH_UP; + goto exit; + } + reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; + pointNum = touchStatus & GT_FINGER_NUM_MASK; + if (pointNum <= 0 || pointNum > MAX_SUPPORT_POINT) { + HDF_LOGE("%s: pointNum is invalid, %d", __func__, pointNum); + (void)ChipCleanBuffer(i2cClient); + OsalMutexUnlock(&device->driver->mutex); + return HDF_FAILURE; + } + frame->realPointNum = pointNum; + frame->definedEvent = TOUCH_DOWN; + /* 从寄存器中读取报点值 */ + (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); + /* 解析报点值 */ + ParsePointData(device, frame, buf, pointNum); +exit: + OsalMutexUnlock(&device->driver->mutex); + if (ChipCleanBuffer(i2cClient) != HDF_SUCCESS) { + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static struct TouchChipOps g_sampleChipOps = { + .Init = ChipInit, + .Detect = ChipDetect, + .Resume = ChipResume, + .Suspend = ChipSuspend, + .DataHandle = ChipDataHandle, +}; + +static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device) +{ + TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg)); + if (chipCfg == NULL) { + HDF_LOGE("%s: instance chip config failed", __func__); + return NULL; + } + (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg)); + /* 解析器件私有配置 */ + if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: parse chip config failed", __func__); + OsalMemFree(chipCfg); + chipCfg = NULL; + } + return chipCfg; +} + +static ChipDevice *ChipDeviceInstance(void) +{ + ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice)); + if (chipDev == NULL) { + HDF_LOGE("%s: instance chip device failed", __func__); + return NULL; + } + (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice)); + return chipDev; +} + +static void FreeChipConfig(TouchChipCfg *config) +{ + if (config->pwrSeq.pwrOn.buf != NULL) { + OsalMemFree(config->pwrSeq.pwrOn.buf); + } + if (config->pwrSeq.pwrOff.buf != NULL) { + OsalMemFree(config->pwrSeq.pwrOff.buf); + } + OsalMemFree(config); +} + +static int32_t HdfSampleChipInit(struct HdfDeviceObject *device) +{ + TouchChipCfg *chipCfg = NULL; + ChipDevice *chipDev = NULL; + HDF_LOGE("%s: enter", __func__); + if (device == NULL) { + return HDF_ERR_INVALID_PARAM; + } + /* 器件私有配置解析 */ + chipCfg = ChipConfigInstance(device); + if (chipCfg == NULL) { + return HDF_ERR_MALLOC_FAIL; + } + /* 器件设备实例化 */ + chipDev = ChipDeviceInstance(); + if (chipDev == NULL) { + goto freeCfg; + } + chipDev->chipCfg = chipCfg; + chipDev->ops = &g_sampleChipOps; + chipDev->chipName = chipCfg->chipName; + chipDev->vendorName = chipCfg->vendorName; + + /* 器件设备注册到平台驱动 */ + if (RegisterChipDevice(chipDev) != HDF_SUCCESS) { + goto freeDev; + } + HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName); + return HDF_SUCCESS; + +freeDev: + OsalMemFree(chipDev); +freeCfg: + FreeChipConfig(chipCfg); + return HDF_FAILURE; +} + +struct HdfDriverEntry g_touchSampleChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_SAMPLE", + .Init = HdfSampleChipInit, +}; + +HDF_INIT(g_touchSampleChipEntry); +``` + diff --git a/zh-cn/device-dev/driver/driver-peripherals.md b/zh-cn/device-dev/driver/driver-peripherals.md new file mode 100644 index 0000000000000000000000000000000000000000..12db978ab608630c7934c53e4c9cff9e613f8e43 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-peripherals.md @@ -0,0 +1,11 @@ +# 外设 + +- **[LCD](driver-peripherals-lcd-des.md)** + +- **[TOUCHSCREEN](driver-peripherals-touch-des.md)** + +- **[SENSOR](driver-peripherals-sensor-des.md)** + +- **[WLAN](driver-peripherals-external-des.md)** + + diff --git a/zh-cn/device-dev/driver/driver-platform-gpio-des.md b/zh-cn/device-dev/driver/driver-platform-gpio-des.md new file mode 100644 index 0000000000000000000000000000000000000000..d4e67c7a5167857f6a3091f277b3da9a98c26490 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-gpio-des.md @@ -0,0 +1,560 @@ +# GPIO + +- [概述](#section1635911016188) + - [接口说明](#section17715915181611) + +- [使用指导](#section259614242196) + - [使用流程](#section103477714216) + - [确定GPIO管脚号](#section370083272117) + - [使用API操作GPIO管脚](#section13604050132118) + +- [使用实例](#section25941262111) + +## 概述 + +GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。 + +GPIO接口定义了操作GPIO管脚的标准方法集合,包括: + +- 设置管脚方向: 方向可以是输入或者输出\(暂不支持高阻态\) + +- 读写管脚电平值: 电平值可以是低电平或高电平 +- 设置管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式 +- 使能和禁止管脚中断:禁止或使能管脚中断 + +### 接口说明 + +**表 1** GPIO驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

GPIO读写

+

GpioRead

+

读管脚电平值

+

GpioWrite

+

写管脚电平值

+

GPIO配置

+

GpioSetDir

+

设置管脚方向

+

GpioGetDir

+

获取管脚方向

+

GPIO中断设置

+

GpioSetIrq

+

设置管脚对应的中断服务函数

+

GpioUnSetIrq

+

取消管脚对应的中断服务函数

+

GpioEnableIrq

+

使能管脚中断

+

GpioDisableIrq

+

禁止管脚中断

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如[图1](#fig1399416053717)所示。 + +**图 1** GPIO使用流程图 + + +![](figure/zh-cn_image_0000001170187071.png) + +### 确定GPIO管脚号 + +不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。 + +- Hi3516DV300 + + 控制器管理12组GPIO管脚,每组8个。 + + GPIO号 = GPIO组索引 \(0\~11\) \* 每组GPIO管脚数\(8\) + 组内偏移 + + 举例:GPIO10\_3的GPIO号 = 10 \* 8 + 3 = 83 + +- Hi3518EV300 + + 控制器管理10组GPIO管脚,每组10个。 + + GPIO号 = GPIO组索引 \(0\~9\) \* 每组GPIO管脚数\(10\) + 组内偏移 + + 举例:GPIO7\_3的GPIO管脚号 = 7 \* 10 + 3 = 73 + + +### 使用API操作GPIO管脚 + +- 设置GPIO管脚方向 + + 在进行GPIO管脚读写前,需要先通过如下函数设置GPIO管脚方向: + + int32\_t GpioSetDir\(uint16\_t gpio, uint16\_t dir\); + + **表 2** GpioSetDir参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

待设置的GPIO管脚号

+

dir

+

待设置的方向值

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ + +- 读写GPIO管脚 + + 如果要读取一个GPIO管脚电平,通过以下函数完成: + + int32\_t GpioRead\(uint16\_t gpio, uint16\_t \*val\); + + **表 3** GpioRead参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

待读取的GPIO管脚号

+

val

+

接收读取电平值的指针

+

返回值

+

返回值描述

+

0

+

读取成功

+

负数

+

读取失败

+
+ + 如果要向GPIO管脚写入电平值,通过以下函数完成: + + int32\_t GpioWrite\(uint16\_t gpio, uint16\_t val\); + + **表 4** GpioWrite参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

待写入的GPIO管脚号

+

val

+

待写入的电平值

+

返回值

+

返回值描述

+

0

+

写入成功

+

负数

+

写入失败

+
+ + 示例代码: + + ``` + int32_t ret; + uint16_t val; + /* 将3号GPIO管脚配置为输出 */ + ret = GpioSetDir(3, GPIO_DIR_OUT); + if (ret != 0) { + HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); + return; + } + /* 向3号GPIO管脚写入低电平GPIO_VAL_LOW */ + ret = GpioWrite(3, GPIO_VAL_LOW); + if (ret != 0) { + HDF_LOGE("GpioWrite: failed, ret %d\n", ret); + return; + } + /* 将6号GPIO管脚配置为输入 */ + ret = GpioSetDir(6, GPIO_DIR_IN); + if (ret != 0) { + HDF_LOGE("GpioSetDir: failed, ret %d\n", ret); + return; + } + /* 读取6号GPIO管脚的电平值 */ + ret = GpioRead(6, &val); + ``` + + +- 设置GPIO中断 + + 如果要为一个GPIO管脚设置中断响应程序,使用如下函数: + + int32\_t GpioSetIrq\(uint16\_t gpio, uint16\_t mode, GpioIrqFunc func, void \*arg\); + + **表 5** GpioSetIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

mode

+

中断触发模式

+

func

+

中断服务程序

+

arg

+

传递给中断服务程序的入参

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ + >![](../public_sys-resources/icon-caution.gif) **注意:** + >同一时间,只能为某个GPIO管脚设置一个中断服务函数,如果重复调用GpioSetIrq函数,则之前设置的中断服务函数会被取代。 + + 当不再需要响应中断服务函数时,使用如下函数取消中断设置: + + int32\_t GpioUnSetIrq\(uint16\_t gpio\); + + **表 6** GpioUnSetIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

返回值

+

返回值描述

+

0

+

取消成功

+

负数

+

取消失败

+
+ + 在中断服务程序设置完成后,还需要先通过如下函数使能GPIO管脚的中断: + + int32\_t GpioEnableIrq\(uint16\_t gpio\); + + **表 7** GpioEnableIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

返回值

+

返回值描述

+

0

+

使能成功

+

负数

+

使能失败

+
+ + >![](../public_sys-resources/icon-caution.gif) **注意:** + >必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。 + + 如果要临时屏蔽此中断,可以通过如下函数禁止GPIO管脚中断: + + int32\_t GpioDisableIrq\(uint16\_t gpio\); + + **表 8** GpioDisableIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

返回值

+

返回值描述

+

0

+

禁止成功

+

负数

+

禁止失败

+
+ + 示例代码: + + ``` + /* 中断服务函数 + */ + int32_t MyCallBackFunc(uint16_t gpio, void *data) + { + HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); + return 0; + } + + int32_t ret; + /* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */ + ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); + if (ret != 0) { + HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); + return; + } + + /* 使能3号GPIO管脚中断 */ + ret = GpioEnableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); + return; + } + + /* 禁止3号GPIO管脚中断 */ + ret = GpioDisableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); + return; + } + + /* 取消3号GPIO管脚中断服务程序 */ + ret = GpioUnSetIrq(3); + if (ret != 0) { + HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); + return; + } + ``` + + +## 使用实例 + +本实例程序中,我们将测试一个GPIO管脚的中断触发:为管脚设置中断服务函数,触发方式为边沿触发,然后通过交替写高低电平到管脚,产生电平波动,制造触发条件,观察中断服务函数的执行。 + +首先需要选取一个空闲的GPIO管脚,本例程基于Hi3516DV300某开发板,GPIO管脚选择GPIO10\_3,换算成GPIO号为83。 + +读者可以根据自己使用的开发板,参考其原理图,选择一个空闲的GPIO管脚即可。 + +``` +#include "gpio_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +static uint32_t g_irqCnt; + +/* 中断服务函数*/ +static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) +{ + HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); + g_irqCnt++; /* 如果中断服务函数触发执行,则将全局中断计数加1 */ + return GpioDisableIrq(gpio); +} + +/* 测试用例函数 */ +static int32_t TestCaseGpioIrqEdge(void) +{ + int32_t ret; + uint16_t valRead; + uint16_t mode; + uint16_t gpio = 83; /* 待测试的GPIO管脚号 */ + uint32_t timeout; + + /* 将管脚方向设置为输出 */ + ret = GpioSetDir(gpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret); + return ret; + } + + /* 先禁止该管脚中断 */ + ret = GpioDisableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* 为管脚设置中断服务函数,触发模式为上升沿和下降沿共同触发 */ + mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING; + HDF_LOGE("%s: mode:%0x\n", __func__, mode); + ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* 使能此管脚中断 */ + ret = GpioEnableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret); + (void)GpioUnSetIrq(gpio); + return ret; + } + + g_irqCnt = 0; /* 清除全局计数器 */ + timeout = 0; /* 等待时间清零 */ + /* 等待此管脚中断服务函数触发,等待超时时间为1000毫秒 */ + while (g_irqCnt <= 0 && timeout < 1000) { + (void)GpioRead(gpio, &valRead); + (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); + HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout); + OsalMDelay(200); /* wait for irq trigger */ + timeout += 200; + } + (void)GpioUnSetIrq(gpio); + return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-i2c-des.md b/zh-cn/device-dev/driver/driver-platform-i2c-des.md new file mode 100644 index 0000000000000000000000000000000000000000..915c5f440eeb70bb1ebff2640306885b272c33e9 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-i2c-des.md @@ -0,0 +1,426 @@ +# I2C + +- [概述](#section5361140416) + - [接口说明](#section459052019177) + +- [使用指导](#section1695201514281) + - [使用流程](#section1338373417288) + - [打开I2C控制器](#section13751110132914) + - [进行I2C通信](#section9202183372916) + - [关闭I2C控制器](#section19481164133018) + +- [使用实例](#section5302202015300) + +## 概述 + +- I2C\(Inter Integrated Circuit\)总线是由Philips公司开发的一种简单、双向二线制同步串行总线。 +- I2C以主从方式工作,通常有一个主设备和一个或者多个从设备,主从设备通过SDA\(SerialData\)串行数据线以及SCL\(SerialClock\)串行时钟线两根线相连,如[图1 ](#fig1135561232714)所示。 + +- I2C数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。数据传输以字节为单位,高位在前,逐个bit进行传输。 +- I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址,当主设备需要和某一个从设备通信时,通过广播的方式,将从设备地址写到总线上,如果某个从设备符合此地址,将会发出应答信号,建立传输。 + +- I2C接口定义了完成I2C传输的通用方法集合,包括: + + - I2C控制器管理: 打开或关闭I2C控制器 + - I2C消息传输:通过消息传输结构体数组进行自定义传输 + + **图 1** I2C物理连线示意图 + ![](figure/I2C物理连线示意图.png "I2C物理连线示意图") + + +### 接口说明 + +**表 1** I2C驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

I2C控制器管理接口

+

I2cOpen

+

打开I2C控制器

+

I2cClose

+

关闭I2C控制器

+

I2c消息传输接口

+

I2cTransfer

+

自定义传输

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用I2C设备的一般流程如[图2](#fig166181128151112)所示。 + +**图 2** I2C设备使用流程图 + + +![](figure/zh-cn_image_0000001123509750.png) + +### 打开I2C控制器 + +在进行I2C通信前,首先要调用I2cOpen打开I2C控制器。 + +DevHandle I2cOpen\(int16\_t number\); + +**表 2** I2cOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

number

+

I2C控制器号

+

返回值

+

返回值描述

+

NULL

+

打开I2C控制器失败

+

设备句柄

+

打开的I2C控制器设备句柄

+
+ +假设系统中存在8个I2C控制器,编号从0到7,那么我们现在获取3号控制器 + +``` +DevHandle i2cHandle = NULL; /* I2C控制器句柄 / + +/* 打开I2C控制器 */ +i2cHandle = I2cOpen(3); +if (i2cHandle == NULL) { + HDF_LOGE("I2cOpen: failed\n"); + return; +} +``` + +### 进行I2C通信 + +消息传输 + +int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\); + +**表 3** I2cTransfer参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2C控制器设备句柄

+

msgs

+

待传输数据的消息结构体数组

+

count

+

消息数组长度

+

返回值

+

返回值描述

+

正整数

+

成功传输的消息结构体数目

+

负数

+

执行失败

+
+ +I2C传输消息类型为I2cMsg,每个传输消息结构体表示一次读或写,通过一个消息数组,可以执行若干次的读写组合操作。 + +``` +int32_t ret; +uint8_t wbuff[2] = { 0x12, 0x13 }; +uint8_t rbuff[2] = { 0 }; +struct I2cMsg msgs[2]; /* 自定义传输的消息结构体数组 */ +msgs[0].buf = wbuff; /* 写入的数据 */ +msgs[0].len = 2; /* 写入数据长度为2 */ +msgs[0].addr = 0x5A; /* 写入设备地址为0x5A */ +msgs[0].flags = 0; /* 传输标记为0,默认为写 */ +msgs[1].buf = rbuff; /* 要读取的数据 */ +msgs[1].len = 2; /* 读取数据长度为2 */ +msgs[1].addr = 0x5A; /* 读取设备地址为0x5A */ +msgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ置位 */ +/* 进行一次自定义传输,传输的消息个数为2 */ +ret = I2cTransfer(i2cHandle, msgs, 2); +if (ret != 2) { + HDF_LOGE("I2cTransfer: failed, ret %d\n", ret); + return; +} +``` + +>![](../public_sys-resources/icon-caution.gif) **注意:** +>- I2cMsg结构体中的设备地址不包含读写标志位,读写信息由flags成员变量的读写控制位传递。 +>- 本函数不对消息结构体个数count做限制,其最大个数度由具体I2C控制器决定。 +>- 本函数也不对每个消息结构体中的数据长度做限制,同样由具体I2C控制器决定。 +>- 本函数可能会引起系统休眠,不允许在中断上下文调用 + +### 关闭I2C控制器 + +I2C通信完成之后,需要关闭I2C控制器,关闭函数如下所示: + +void I2cClose\(DevHandle handle\); + +**表 4** I2cClose参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2C控制器设备句柄

+
+ +``` +I2cClose(i2cHandle); /* 关闭I2C控制器 */ +``` + +## 使用实例 + +本例程以操作开发板上的I2C设备为例,详细展示I2C接口的完整使用流程。 + +本例拟对Hi3516DV300某开发板上TouchPad设备进行简单的寄存器读写访问,基本硬件信息如下: + +- SOC:hi3516dv300。 + +- Touch IC:I2C地址为0x38, IC内部寄存器位宽为1字节。 + +- 原理图信息:TouchPad设备挂接在3号I2C控制器下;IC的复位管脚为3号GPIO。 + +本例程首先对Touch IC进行复位操作(开发板上电默认会给TouchIC供电,本例程不考虑供电),然后对其内部寄存器进行随机读写,测试I2C通路是否正常。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>本例程重点在于展示I2C设备访问流程,并验证I2C通路,所以对于设备寄存器读写值不做关注,读写寄存器导致的行为由设备自身决定。 + +示例如下: + +``` +#include "i2c_if.h" /* I2C标准接口头文件 */ +#include "gpio_if.h" /* GPIO标准接口头文件 */ +#include "hdf_log.h" /* 标准日志打印头文件 */ +#include "osal_io.h" /* 标准IO读写接口头文件 */ +#include "osal_time.h" /* 标准延迟&睡眠接口头文件 */ + +/* 定义一个表示TP设备的结构体,存储i2c及gpio相关硬件信息 */ +struct TpI2cDevice { + uint16_t rstGpio; /* 复位管脚 */ + uint16_t busId; /* I2C总线号 */ + uint16_t addr; /* I2C设备地址 */ + uint16_t regLen; /* 寄存器字节宽度 */ + DevHandle i2cHandle; /* I2C控制器句柄 */ +}; + +/* I2C管脚io配置,需要查阅SOC寄存器手册 */ +#define I2C3_DATA_REG_ADDR 0x112f008c /* 3号I2C控制器SDA管脚配置寄存器地址 */ +#define I2C3_CLK_REG_ADDR 0x112f0090 /* 3号I2C控制器SCL管脚配置寄存器地址 */ +#define I2C_REG_CFG 0x5f1 /* 3号I2C控制器SDA及SCL管脚配置值 */ + +static void TpSocIoCfg(void) +{ + /* 将3号I2C控制器对应两个管脚的IO功能设置为I2C */ + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR)); + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR)); +} + +/* 对TP的复位管脚进行初始化, 拉高维持20ms, 再拉底维持50ms,最后再拉高维持20ms, 完成复位动作 */ +static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice) +{ + int32_t ret; + + /* 设置复位管脚方向为输出 */ + ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret); + return ret; + } + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst low fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(50); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst high fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + return HDF_SUCCESS; +} + +/* 基于I2cTransfer方法封装一个寄存器读写的辅助函数, 通过flag表示读或写 */ +static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen, uint8_t flag) +{ + int index = 0; + unsigned char regBuf[4] = {0}; + struct I2cMsg msgs[2] = {0}; + + /* 单双字节寄存器长度适配 */ + if (tpDevice->regLen == 1) { + regBuf[index++] = regAddr & 0xFF; + } else { + regBuf[index++] = (regAddr >> 8) & 0xFF; + regBuf[index++] = regAddr & 0xFF; + } + + /* 填充I2cMsg消息结构 */ + msgs[0].addr = tpDevice->addr; + msgs[0].flags = 0; /* 标记为0,表示写入 */ + msgs[0].len = tpDevice->regLen; + msgs[0].buf = regBuf; + + msgs[1].addr = tpDevice->addr; + msgs[1].flags = (flag == 1) ? I2C_FLAG_READ : 0; /* 添加读标记位,表示读取 */ + msgs[1].len = dataLen; + msgs[1].buf = regData; + + if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) { + HDF_LOGE("%s: i2c read err", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +/* TP寄存器读函数 */ +static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1); +} + +/* TP寄存器写函数 */ +static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0); +} + +/* I2C例程总入口 */ +static int32_t TestCaseI2c(void) +{ + int32_t i; + int32_t ret; + unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC }; + unsigned char bufRead[7] = {0}; + static struct TpI2cDevice tpDevice; + + /* IO管脚功能配置 */ + TpSocIoCfg(); + + /* TP设备信息初始化 */ + tpDevice.rstGpio = 3; + tpDevice.busId = 3; + tpDevice.addr = 0x38; + tpDevice.regLen = 1; + tpDevice.i2cHandle = NULL; + + /* GPIO管脚初始化 */ + ret = TestCaseGpioInit(&tpDevice); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: gpio init fail!:%d", __func__, ret); + return ret; + } + + /* 打开I2C控制器 */ + tpDevice.i2cHandle = I2cOpen(tpDevice.busId); + if (tpDevice.i2cHandle == NULL) { + HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId); + return -1; + } + + /* 向TP-IC的0xD5寄存器连续写7字节数据 */ + ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + OsalMSleep(10); + + /* 从TP-IC的0xDO寄存器连续读7字节数据 */ + ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + + HDF_LOGE("%s: tp i2c write&read reg success!", __func__); + for (i = 0; i < 7; i++) { + HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]); + } + + /* 访问完毕关闭I2C控制器 */ + I2cClose(tpDevice.i2cHandle); + return ret; +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-mipidsi-des.md b/zh-cn/device-dev/driver/driver-platform-mipidsi-des.md new file mode 100644 index 0000000000000000000000000000000000000000..c7cf01ca02d5c96f9c97447abf11a0d7bdb79ee7 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-mipidsi-des.md @@ -0,0 +1,554 @@ +# MIPI DSI + +- [概述](#section16806142183217) + - [接口说明](#section129611916132011) + +- [使用指导](#section037231715335) + - [使用流程](#section49299119344) + - [获取MIPI-DSI操作句柄](#section5126155683811) + - [MIPI-DSI相应配置](#section201164274344) + - [发送/回读控制指令](#section199401342173415) + - [释放MIPI-DSI操作句柄](#section161011610357) + +- [使用实例](#section17470126123520) + +## 概述 + +- DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface \(MIPI\) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设\(通常是LCD或者类似的显示设备\),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。 + +- MIPI-DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。 +- 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。 + + **图 1** DSI发送、接收接口 + ![](figure/DSI发送-接收接口.png "DSI发送-接收接口") + + +### 接口说明 + +**表 1** MIPI-DSI API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

设置/获取当前MIPI-DSI相关配置

+

MipiDsiSetCfg

+

设置MIPI-DSI相关配置

+

MipiDsiGetCfg

+

获取当前MIPI-DSI相关配置

+

获取/释放MIPI-DSI操作句柄

+

MipiDsiOpen

+

获取MIPI-DSI操作句柄

+

MipiDsiClose

+

释放MIPI-DSI操作句柄

+

设置MIPI-DSI进入Low power模式/High speed模式

+

MipiDsiSetLpMode

+

设置MIPI-DSI进入Low power模式

+

MipiDsiSetHsMode

+

设置MIPI-DSI进入High speed模式

+

MIPI-DSI发送/回读指令

+

MipiDsiTx

+

MIPI-DSI发送相应指令的接口

+

MipiDsiRx

+

MIPI-DSI按期望长度回读的接口

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用 + +## 使用指导 + +### 使用流程 + +使用MIPI-DSI的一般流程如[图2](#fig99821771782)所示。 + +**图 2** MIPI-DSI使用流程图 + + +![](figure/zh-cn_image_0000001123514210.png) + +### 获取MIPI-DSI操作句柄 + +在进行MIPI-DSI进行通信前,首先要调用MipiDsiOpen获取操作句柄,该函数会返回指定通道ID的操作句柄。 + +DevHandle MipiDsiOpen\(uint8\_t id\); + +**表 2** MipiDsiOpen的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

id

+

MIPI DSI通道ID

+

返回值

+

返回值描述

+

NULL

+

获取失败

+

设备句柄

+

获取到指令通道的操作句柄, 类型为DevHandle

+
+ +假设系统中的MIPI-DSI通道为0,获取该通道操作句柄的示例如下: + +``` +DevHandle mipiDsiHandle = NULL; /* 设备句柄 */ +chnId = 0; /* MIPI-DSI通道ID */ + +/* 获取操作句柄 */ +mipiDsiHandle = MipiDsiOpen(chnId); +if (mipiDsiHandle == NULL) { + HDF_LOGE("MipiDsiOpen: failed\n"); + return; +} +``` + +### MIPI-DSI相应配置 + +- 写入MIPI-DSI配置 + +int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\); + +**表 3** MipiDsiSetCfg的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cfg

+

MIPI-DSI相应配置buf 指针

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ +``` +int32_t ret; +struct MipiCfg cfg = {0}; + +/* 当前对接的屏幕配置如下 */ +cfg.lane = DSI_4_LANES; +cfg.mode = DSI_CMD_MODE; +cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; +cfg.format = FORMAT_RGB_24_BIT; +cfg.pixelClk = 174; +cfg.phyDataRate = 384; +cfg.timingInfo.hsaPixels = 50; +cfg.timingInfo.hbpPixels = 55; +cfg.timingInfo.hlinePixels = 1200; +cfg.timingInfo.yResLines = 1800; +cfg.timingInfo.vbpLines = 33; +cfg.timingInfo.vsaLines = 76; +cfg.timingInfo.vfpLines = 120; +cfg.timingInfo.xResPixels = 1342; +/* 写入配置数据 */ +ret = MipiDsiSetCfg(g_handle, &cfg); +if (ret != 0) { + HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); + return -1; +} +``` + +- 获取当前MIPI-DSI的配置 + +int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); + +**表 4** MipiDsiGetCfg的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cfg

+

MIPI-DSI相应配置buf 指针

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +struct MipiCfg cfg; +memset(&cfg, 0, sizeof(struct MipiCfg)); +ret = MipiDsiGetCfg(g_handle, &cfg); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); + return HDF_FAILURE; +} +``` + +### 发送/回读控制指令 + +- 发送指令 + +int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); + +**表 5** MipiDsiTx的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cmd

+

需要发送的指令数据指针

+

返回值

+

返回值描述

+

0

+

发送成功

+

负数

+

发送失败

+
+ +``` +int32_t ret; +struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); +if (cmd == NULL) { + return HDF_FAILURE; +} +cmd->dtype = DTYPE_DCS_WRITE; +cmd->dlen = 1; +cmd->payload = OsalMemCalloc(sizeof(uint8_t)); +if (cmd->payload == NULL) { + HdfFree(cmd); + return HDF_FAILURE; +} +*(cmd->payload) = DTYPE_GEN_LWRITE; +MipiDsiSetLpMode(mipiHandle); +ret = MipiDsiTx(mipiHandle, cmd); +MipiDsiSetHsMode(mipiHandle); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret); + HdfFree(cmd->payload); + HdfFree(cmd); + return HDF_FAILURE; +} +HdfFree(cmd->payload); +HdfFree(cmd); +``` + +- 回读指令 + +int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); + +**表 6** MipiDsiRx的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cmd

+

需要回读的指令数据指针

+

readLen

+

期望回读的数据长度

+

out

+

回读的数据buf指针

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +uint8_t readVal = 0; + +struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); +if (cmdRead == NULL) { + return HDF_FAILURE; +} +cmdRead->dtype = DTYPE_DCS_READ; +cmdRead->dlen = 1; +cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); +if (cmdRead->payload == NULL) { + HdfFree(cmdRead); + return HDF_FAILURE; +} +*(cmdRead->payload) = DDIC_REG_STATUS; +MipiDsiSetLpMode(g_handle); +ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); +MipiDsiSetHsMode(g_handle); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + return HDF_FAILURE; +} +HdfFree(cmdRead->payload); +HdfFree(cmdRead); +``` + +### 释放MIPI-DSI操作句柄 + +MIPI-DSI使用完成之后,需要释放操作句柄,释放句柄的函数如下所示: + +void MipiDsiClose\(DevHandle handle\); + +该函数会释放掉由MipiDsiOpen申请的资源。 + +**表 7** MipiDsiClose的参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

MIPI-DSI操作句柄

+
+ +``` +MipiDsiClose(mipiHandle); /* 释放掉MIPI-DSI操作句柄 */ +``` + +## 使用实例 + +MIPI-DSI完整的使用示例如下所示: + +``` +#include "hdf.h" +#include "mipi_dsi_if.h" + +void PalMipiDsiTestSample(void) +{ + uint8_t chnId; + int32_t ret; + DevHandle handle = NULL; + + /* 设备通道编号 */ + chnId = 0; + /* 获取操作句柄 */ + handle = MipiDsiOpen(chnId); + if (handle == NULL) { + HDF_LOGE("MipiDsiOpen: failed!\n"); + return; + } + /* 配置相应参数 */ + struct MipiCfg cfg = {0}; + cfg.lane = DSI_4_LANES; + cfg.mode = DSI_CMD_MODE; + cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; + cfg.format = FORMAT_RGB_24_BIT; + cfg.pixelClk = 174; + cfg.phyDataRate = 384; + cfg.timingInfo.hsaPixels = 50; + cfg.timingInfo.hbpPixels = 55; + cfg.timingInfo.hlinePixels = 1200; + cfg.timingInfo.yResLines = 1800; + cfg.timingInfo.vbpLines = 33; + cfg.timingInfo.vsaLines = 76; + cfg.timingInfo.vfpLines = 120; + cfg.timingInfo.xResPixels = 1342; + /* 写入配置数据 */ + ret = MipiDsiSetCfg(g_handle, &cfg); + if (ret != 0) { + HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); + return; + } + /* 发送PANEL初始化指令 */ + struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmd == NULL) { + return; + } + cmd->dtype = DTYPE_DCS_WRITE; + cmd->dlen = 1; + cmd->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmd->payload == NULL) { + HdfFree(cmd); + return; + } + *(cmd->payload) = DTYPE_GEN_LWRITE; + MipiDsiSetLpMode(mipiHandle); + ret = MipiDsiTx(mipiHandle, cmd); + MipiDsiSetHsMode(mipiHandle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret); + HdfFree(cmd->payload); + HdfFree(cmd); + return; + } + HdfFree(cmd->payload); + HdfFree(cmd); + /* 回读panel状态寄存器 */ + uint8_t readVal = 0; + struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmdRead == NULL) { + return; + } + cmdRead->dtype = DTYPE_DCS_READ; + cmdRead->dlen = 1; + cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmdRead->payload == NULL) { + HdfFree(cmdRead); + return; + } + *(cmdRead->payload) = DDIC_REG_STATUS; + MipiDsiSetLpMode(g_handle); + ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); + MipiDsiSetHsMode(g_handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + return; + } + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + /* 释放MIPI DSI设备句柄 */ + MipiDsiClose(handle); +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-rtc-des.md b/zh-cn/device-dev/driver/driver-platform-rtc-des.md new file mode 100644 index 0000000000000000000000000000000000000000..fb55001feb78e4e003f25a829f51539e4893d310 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-rtc-des.md @@ -0,0 +1,944 @@ +# RTC + +- [概述](#section104842041574) + - [接口说明](#section3373340142215) + +- [使用指导](#section20636145604113) + - [使用流程](#section16919828134215) + - [创建RTC设备句柄](#section1131212144310) + - [销毁RTC设备句柄](#section10744117144314) + - [注册RTC定时报警回调函数](#section14839440184320) + - [操作RTC](#section161927578433) + +- [使用实例](#section1186111020456) + +## 概述 + +RTC\(real-time clock\)为操作系统中的实时时钟设备,为操作系统提供精准的实时时间和定时报警功能。当设备下电后,通过外置电池供电,RTC继续记录操作系统时间;设备上电后,RTC提供实时时钟给操作系统,确保断电后系统时间的连续性。 + +### 接口说明 + +**表 1** RTC设备API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

RTC句柄操作

+

RtcOpen

+

获取RTC设备驱动句柄

+

RtcClose

+

释放RTC设备驱动句柄

+

RTC时间操作接口

+

RtcReadTime

+

读RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

RtcWriteTime

+

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

RTC报警操作接口

+

RtcReadAlarm

+

读RTC报警时间信息

+

RtcWriteAlarm

+

写RTC报警时间信息

+

RtcRegisterAlarmCallback

+

注册报警超时回调函数

+

RtcAlarmInterruptEnable

+

使能/去使能RTC报警中断

+

RTC配置操作

+

RtcGetFreq

+

读RTC外接晶振频率

+

RtcSetFreq

+

配置RTC外接晶振频率

+

RtcReset

+

RTC复位

+

读写用户定义寄存器

+

RtcReadReg

+

读用户自定义寄存器

+

RtcWriteReg

+

写用户自定义寄存器

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +在操作系统启动过程中,驱动管理模块根据配置文件加载RTC驱动,RTC驱动会检测RTC器件并初始化驱动。 + +使用RTC设备的一般流程如[图1](#fig166181128151112)所示。 + +**图 1** RTC设备使用流程图 + + +![](figure/zh-cn_image_0000001123675706.png) + +### 创建RTC设备句柄 + +RTC驱动加载成功后,驱动开发者使用驱动框架提供的查询接口并调用RTC设备驱动接口。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>当前操作系统支持一个RTC设备。 + +DevHandle RtcOpen\(void\); + +**表 2** RtcOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

void

+

NA

+

返回值

+

返回值描述

+

handle

+

操作成功返回 指针类型

+

NULL

+

操作失败

+
+ +``` +DevHandle handle = NULL; + +/* 获取RTC句柄 */ +handle = RtcOpen(); +if (handle == NULL) { + /* 错误处理 */ +} +``` + +### 销毁RTC设备句柄 + +销毁RTC设备句柄,系统释放对应的资源。 + +void RtcClose\(DevHandle handle\); + +**表 3** RtcClose参数描述 + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+
+ +``` +/* 销毁RTC句柄 */ +RtcClose(handle); +``` + +### 注册RTC定时报警回调函数 + +系统启动后需要注册RTC定时报警回调函数,报警超时后触发回调函数。 + +int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\); + +**表 4** RtcRegisterAlarmCallback参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

cb

+

定时报警回调函数

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +注册RTC\_ALARM\_INDEX\_A的定时报警处理函数, 示例如下: + +``` +/* 用户注册RTC定时报警回调函数的方法 */ +int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) +{ + if (alarmIndex == RTC_ALARM_INDEX_A) { + /* 报警A的处理 */ + } else if (alarmIndex == RTC_ALARM_INDEX_B) { + /* 报警B的处理 */ + } else { + /* 错误处理 */ + } + return 0; +} +int32_t ret; +/* 注册报警A的定时回调函数 */ +ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); +if (ret != 0) { + /* 错误处理 */ +} +``` + +### 操作RTC + +- 读取RTC时间。 + +系统从RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒,则可以通过以下函数完成: + +int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\); + +**表 5** RtcReadTime参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

time

+

RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +struct RtcTime tm; + +/* 系统从RTC读取时间信息 */ +ret = RtcReadTime(handle, &tm); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置RTC时间 + +设置RTC时间,则可以通过以下函数完成: + +int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\); + +**表 6** RtcWriteTime参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

time

+

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 + +``` +int32_t ret; +struct RtcTime tm; + +/* 设置RTC时间为 UTC 2020/01/01 00:59:00 .000 */ +tm.year = 2020; +tm.month = 01; +tm.day = 01; +tm.hour= 00; +tm.minute = 59; +tm.second = 00; +tm.millisecond = 0; +/* 写RTC时间信息 */ +ret = RtcWriteTime(handle, &tm); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 读取RTC报警时间 + +如果需要读取定时报警时间,则可以通过以下函数完成: + +int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); + +**表 7** RtcReadAlarm参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

time

+

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +struct RtcTime alarmTime; + +/* 读RTC_ALARM_INDEX_A索引的RTC定时报警时间信息 */ +ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置RTC报警时间 + +根据报警索引设置RTC报警时间,通过以下函数完成: + +int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); + +**表 8** RtcWriteAlarm参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

time

+

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 + +``` +int32_t ret; +struct RtcTime alarmTime; + +/* 设置RTC报警时间为2020/01/01 00:59:59 .000 */ +alarmTime.year = 2020; +alarmTime.month = 01; +alarmTime.day = 01; +alarmTime.hour = 00; +alarmTime.minute = 59; +alarmTime.second = 59; +alarmTime.millisecond = 0; +/* 设置RTC_ALARM_INDEX_A索引的定时报警时间 */ +ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置定时报警中断使能或去使能 + +在启动报警操作前,需要先设置报警中断使能,报警超时后会触发告警回调函数,可以通过以下函数完成: + +int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\); + +**表 9** RtcAlarmInterruptEnable参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

enable

+

RTC报警中断配置,1:使能,0:去使能

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; + +/* 设置RTC报警中断使能 */ +ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 读取RTC外频 + +读取RTC外接晶体振荡频率,可以通过以下函数完成: + +int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\); + +**表 10** RtcGetFreq参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

freq

+

RTC的外接晶体振荡频率,单位(HZ)

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint32_t freq = 0; + +/* 读取RTC外接晶体振荡频率 */ +ret = RtcGetFreq(handle, &freq); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 配置RTC外频 + +配置RTC外接晶体振荡频率,可以通过以下函数完成: + +int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\); + +**表 11** RtcSetFreq参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

freq

+

RTC的外接晶体振荡频率,单位(HZ)

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint32_t freq = 32768; /* 32768 Hz */ + +/* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ +ret = RtcSetFreq(handle, freq); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 复位RTC + +复位RTC,复位RTC后各配置寄存器恢复默认值,可以通过以下函数完成: + +int32\_t RtcReset\(DevHandle handle\); + +**表 12** RtcReset参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; + +/* 复位RTC,复位RTC后各配置寄存器恢复默认值 */ +ret = RtcReset(handle); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 读取RTC自定义寄存器配置 + +按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: + +int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\); + +**表 13** RtcReadReg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

usrDefIndex

+

用户定义的寄存器对应索引

+

value

+

寄存器值

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义的第一个寄存器*/ +uint8_t value = 0; + +/* 按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值 */ +ret = RtcReadReg(handle, usrDefIndex, &value); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置RTC自定义寄存器配置 + +按照用户定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: + +int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\); + +**表 14** RtcWriteReg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

usrDefIndex

+

用户定义的寄存器对应索引

+

value

+

寄存器值

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义第一个寄存器*/ +uint8_t value = 0x10; + +/* 按照用户的定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值 */ +ret = RtcWriteReg(handle, usrDefIndex, value); +if (ret != 0) { + /* 错误处理 */ +} +``` + +## 使用实例 + +本实例提供RTC接口的完整使用流程: + +1. 系统启动,驱动管理模块会识别系统当前的RTC器件; +2. 驱动管理模块完成RTC设备的初始化和设备创建; +3. 用户通过不同API,对该RTC设备进行对应的操作; +4. 关闭RTC设备,释放设备资源。 + +示例如下: + +``` +#include "rtc_if.h" +int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) +{ + if (alarmIndex == RTC_ALARM_INDEX_A) { + /* 报警A的处理 */ + printf("RTC Alarm A callback function\n\r"); + } else if (alarmIndex == RTC_ALARM_INDEX_B) { + /* 报警B的处理 */ + printf("RTC Alarm B callback function\n\r"); + } else { + /* 错误处理 */ + } + return 0; +} + +void RtcTestSample(void) +{ + int32_t ret; + struct RtcTime tm; + struct RtcTime alarmTime; + uint32_t freq; + DevHandle handle = NULL; + + /* 获取RTC设备句柄 */ + handle = RtcOpen(); + if (handle == NULL) { + /* 错误处理 */ + } + /* 注册报警A的定时回调函数 */ + ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ + freq = 32768; /* 32768 Hz */ + ret = RtcSetFreq(handle, freq); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC报警中断使能 */ + ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC时间为2020/01/01 00:00:10 .990 */ + tm.year = 2020; + tm.month = 01; + tm.day = 01; + tm.hour= 0; + tm.minute = 0; + tm.second = 10; + tm.millisecond = 990; + /* 写RTC时间信息 */ + ret = RtcWriteTime(handle, &tm); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC报警时间为2020/01/01 00:00:30 .100 */ + alarmTime.year = 2020; + alarmTime.month = 01; + alarmTime.day = 01; + alarmTime.hour = 0; + alarmTime.minute = 0; + alarmTime.second = 30; + alarmTime.millisecond = 100; + /* 设置RTC_ALARM_INDEX_A索引定时报警时间信息, 定时时间到后会打印"RTC Alarm A callback function" */ + ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); + if (ret != 0) { + /* 错误处理 */ + } + + /* 读取RTC实时时间 */ + ret = RtcReadTime(handle, &tm); + if (ret != 0) { + /* 错误处理 */ + } + sleep(5) + printf("RTC read time:\n\r"); + printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", + tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); + /* 销毁RTC设备句柄 */ + RtcClose(handle); +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-sdio-des.md b/zh-cn/device-dev/driver/driver-platform-sdio-des.md new file mode 100644 index 0000000000000000000000000000000000000000..1d85e6496ea6abc547afcdc1536b5068eb1acdbc --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-sdio-des.md @@ -0,0 +1,1068 @@ +# SDIO + +- [概述](#section1155271783811) + - [接口说明](#section08064247248) + +- [使用指导](#section1878939192515) + - [使用流程](#section1490685512255) + - [打开SDIO控制器](#section10782428132616) + - [独占HOST](#section11263172312715) + - [使能SDIO设备](#section17861486271) + - [注册SDIO中断](#section521213262286) + - [进行SDIO通信](#section85661522153420) + - [释放SDIO中断](#section1683449352) + - [去使能SDIO设备](#section15379324143611) + - [释放HOST](#section536018263713) + - [关闭SDIO控制器](#section4752739183716) + +- [使用实例](#section376910122382) + +## 概述 + +- SDIO是安全数字输入输出接口(Secure Digital Input and Output)的缩写,是从SD内存卡接口的基础上演化出来的一种外设接口。SDIO接口兼容以前的SD内存卡,并且可以连接支持SDIO接口的设备。 +- SDIO的应用比较广泛,目前,有许多手机都支持SDIO功能,并且很多SDIO外设也被开发出来,使得手机外接外设更加容易。常见的SDIO外设有WLAN、GPS、CAMERA、蓝牙等。 +- SDIO总线有两端,其中一端是主机端(HOST),另一端是设备端(DEVICE)。所有的通信都是由HOST端发出命令开始的,在DEVICE端只要能解析HOST的命令,就可以同HOST进行通信了。SDIO的HOST可以连接多个DEVICE,如下图所示: + + - CLK信号:HOST给DEVICE的时钟信号。 + - VDD信号:电源信号。 + - VSS信号:Ground信号。 + - D0-3信号:4条数据线,其中,DAT1信号线复用为中断线,在1BIT模式下DAT0用来传输数据,在4BIT模式下DAT0-DAT3用来传输数据。 + - CMD信号:用于HOST发送命令和DEVICE回复响应。 + + **图 1** SDIO的HOST-DEVICE连接示意图 + + + ![](figure/zh-cn_image_0000001054280608.png) + +- SDIO接口定义了操作SDIO的通用方法集合,包括打开/关闭SDIO控制器、独占/释放HOST、使能/去使能设备、申请/释放中断、读写、获取/设置公共信息等。 + +### 接口说明 + +**表 1** SDIO驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

SDIO设备打开/关闭接口

+

SdioOpen

+

打开指定总线号的SDIO控制器

+

SdioClose

+

关闭SDIO控制器

+

SDIO读写接口

+

SdioReadBytes

+

从指定地址开始,增量读取指定长度的数据

+

SdioWriteBytes

+

从指定地址开始,增量写入指定长度的数据

+

SdioReadBytesFromFixedAddr

+

从固定地址读取指定长度的数据

+

SdioWriteBytesToFixedAddr

+

向固定地址写入指定长度的数据

+

SdioReadBytesFromFunc0

+

从SDIO function 0的指定地址空间读取指定长度的数据

+

SdioWriteBytesToFunc0

+

向SDIO function 0的指定地址空间写入指定长度的数据

+

SDIO设置块大小接口

+

SdioSetBlockSize

+

设置块的大小

+

SDIO获取/设置公共信息接口

+

SdioGetCommonInfo

+

获取公共信息

+

SdioSetCommonInfo

+

设置公共信息

+

SDIO刷新数据接口

+

SdioFlushData

+

刷新数据

+

SDIO独占/释放HOST接口

+

SdioClaimHost

+

独占Host

+

SdioReleaseHost

+

释放Host

+

SDIO使能/去使能功能设备接口

+

SdioEnableFunc

+

使能SDIO功能设备

+

SdioDisableFunc

+

去使能SDIO功能设备

+

SDIO申请/释放中断接口

+

SdioClaimIrq

+

申请中断

+

SdioReleaseIrq

+

释放中断

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,目前只支持在内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用SDIO的一般流程如[图2](#fig1343742311264)所示。 + +**图 2** SDIO使用流程图 + + +![](figure/zh-cn_image_0000001123540984.png) + +### 打开SDIO控制器 + +在使用SDIO进行通信前,首先要调用SdioOpen获取SDIO控制器的设备句柄,该函数会返回指定总线号的SDIO控制器的设备句柄。 + +DevHandle SdioOpen\(int16\_t mmcBusNum, struct SdioFunctionConfig \*config\); + +**表 2** SdioOpen函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

mmcBusNum

+

总线号

+

config

+

SDIO功能配置信息

+

返回值

+

返回值描述

+

NULL

+

获取SDIO控制器的设备句柄失败

+

设备句柄

+

SDIO控制器的设备句柄

+
+ +打开SDIO控制器的示例如下: + +``` +DevHandle handle = NULL; +struct SdioFunctionConfig config; +config.funcNr = 1; +config.vendorId = 0x123; +config.deviceId = 0x456; +/* 打开总线号为1的SDIO控制器 */ +handle = SdioOpen(1, &config); +if (handle == NULL) { + HDF_LOGE("SdioOpen: failed!\n"); +} +``` + +### 独占HOST + +获取到SDIO控制器的设备句柄之后,需要先独占HOST才能进行SDIO后续的一系列操作,独占HOST函数如下所示: + +void SdioClaimHost\(DevHandle handle\); + +**表 3** SdioClaimHost函数的参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+
+ +独占HOST示例如下: + +``` +SdioClaimHost(handle); /* 独占HOST */ +``` + +### 使能SDIO设备 + +在访问寄存器之前,需要先使能SDIO设备,使能SDIO设备的函数如下所示: + +int32\_t SdioEnableFunc\(DevHandle handle\); + +**表 4** SdioEnableFunc函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

返回值

+

返回值描述

+

0

+

SDIO使能成功

+

负数

+

SDIO使能失败

+
+ +使能SDIO设备的示例如下: + +``` +int32_t ret; +/* 使能SDIO设备 */ +ret = SdioEnableFunc(handle); +if (ret != 0) { + HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); +} +``` + +### 注册SDIO中断 + +在通信之前,还需要注册SDIO中断,注册SDIO中断函数如下图所示: + +int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\); + +**表 5** SdioClaimIrq函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

handler

+

中断服务函数指针

+

返回值

+

返回值描述

+

0

+

注册中断成功

+

负数

+

注册中断失败

+
+ +注册SDIO中的示例如下: + +``` +/* 中断服务函数需要根据各自平台的情况去实现 */ +static void SdioIrqFunc(void *data) +{ + if (data == NULL) { + HDF_LOGE("SdioIrqFunc: data is NULL.\n"); + return; + } + /* 需要开发者自行添加具体实现 */ +} + +int32_t ret; +/* 注册SDIO中断 */ +ret = SdioClaimIrq(handle, SdioIrqFunc); +if (ret != 0) { + HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); +} +``` + +### 进行SDIO通信 + +- 向SDIO设备增量写入指定长度的数据 + +对应的接口函数如下所示: + +int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 6** SdioWriteBytes函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

待写入数据的指针

+

addr

+

待写入数据的起始地址

+

size

+

待写入数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO写数据成功

+

负数

+

SDIO写数据失败

+
+ +向SDIO设备增量写入指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t wbuff[] = {1,2,3,4,5}; +uint32_t addr = 0x100 + 0x09; +/* 向SDIO设备起始地址0x109,增量写入5个字节的数据 */ +ret = SdioWriteBytes(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0])); +if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); +} +``` + +- 从SDIO设备增量读取指定长度的数据 + +对应的接口函数如下所示: + +int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 7** SdioReadBytes函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

接收读取数据的指针

+

addr

+

待读取数据的起始地址

+

size

+

待读取数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO读数据成功

+

负数

+

SDIO读数据失败

+
+ +从SDIO设备增量读取指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t rbuff[5] = {0}; +uint32_t addr = 0x100 + 0x09; +/* 从SDIO设备起始地址0x109,增量读取5个字节的数据 */ +ret = SdioReadBytes(handle, rbuff, addr, 5); +if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); +} +``` + +- 向SDIO设备的固定地址写入指定长度的数据 + + 对应的接口函数如下所示: + + int32\_t SdioWriteBytesToFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); + + **表 8** SdioWriteBytesToFixedAddr函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

待写入数据的指针

+

addr

+

待写入数据的固定地址

+

size

+

待写入数据的长度

+

scatterLen

+

集散表的长度。如果该字段不为0,则data为集散表类型。

+

返回值

+

返回值描述

+

0

+

SDIO写数据成功

+

负数

+

SDIO写数据失败

+
+ + 向SDIO设备的固定地址写入指定长度的数据的示例如下: + + ``` + int32_t ret; + uint8_t wbuff[] = {1,2,3,4,5}; + uint32_t addr = 0x100 + 0x09; + /* 向SDIO设备固定地址0x109写入5个字节的数据 */ + ret = SdioWriteBytesToFixedAddr(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0]), 0); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); + } + ``` + +- 从SDIO设备的固定地址读取指定长度的数据 + + 对应的接口函数如下所示: + + int32\_t SdioReadBytesFromFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); + + **表 9** SdioReadBytesFromFixedAddr函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

接收读取数据的指针

+

addr

+

待读取数据的起始地址

+

size

+

待读取数据的长度

+

scatterLen

+

集散表的长度。如果该字段不为0,则data为集散表类型。

+

返回值

+

返回值描述

+

0

+

SDIO读数据成功

+

负数

+

SDIO读数据失败

+
+ + 从SDIO设备的固定地址读取指定长度的数据的示例如下: + + ``` + int32_t ret; + uint8_t rbuff[5] = {0}; + uint32_t addr = 0x100 + 0x09; + /* 从SDIO设备固定地址0x109中读取5个字节的数据 */ + ret = SdioReadBytesFromFixedAddr(handle, rbuff, addr, 5, 0); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); + } + ``` + + +- 向SDIO function 0的指定地址空间写入指定长度的数据 + +当前只支持写入一个字节的数据,对应的接口函数如下所示: + +int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 10** SdioWriteBytesToFunc0函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

待写入数据的指针

+

addr

+

待写入数据的起始地址

+

size

+

待写入数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO写数据成功

+

负数

+

SDIO写数据失败

+
+ +向SDIO function 0的指定地址空间写入指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t wbuff = 1; +/* 向SDIO function 0地址0x2中写入1字节的数据 */ +ret = SdioWriteBytesToFunc0(handle, &wbuff, 0x2, 1); +if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); +} +``` + +- 从SDIO function 0的指定地址空间读取指定长度的数据 + +当前只支持读取一个字节的数据,对应的接口函数如下所示: + +int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 11** SdioReadBytesFromFunc0函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

接收读取数据的指针

+

addr

+

待读取数据的起始地址

+

size

+

待读取数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO读数据成功

+

负数

+

SDIO读数据失败

+
+ +从SDIO function 0的指定地址空间读取指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t rbuff; +/* 从SDIO function 0设备地址0x2中读取1字节的数据 */ +ret = SdioReadBytesFromFunc0(handle, &rbuff, 0x2, 1); +if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); +} +``` + +### 释放SDIO中断 + +通信完成之后,需要释放SDIO中断,函数如下所示: + +int32\_t SdioReleaseIrq\(DevHandle handle\); + +**表 12** SdioReleaseIrq函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

返回值

+

返回值描述

+

0

+

释放SDIO中断成功

+

负数

+

释放SDIO中断失败

+
+ +释放SDIO中断的示例如下: + +``` +int32_t ret; +/* 释放SDIO中断 */ +ret = SdioReleaseIrq(handle); +if (ret != 0) { + HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); +} +``` + +### 去使能SDIO设备 + +通信完成之后,还需要去使能SDIO设备,函数如下所示: + +int32\_t SdioDisableFunc\(DevHandle handle\); + +**表 13** SdioDisableFunc函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

返回值

+

返回值描述

+

0

+

去使能SDIO设备成功

+

负数

+

去使能SDIO设备失败

+
+ +去使能SDIO设备的示例如下: + +``` +int32_t ret; +/* 去使能SDIO设备 */ +ret = SdioDisableFunc(handle); +if (ret != 0) { + HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); +} +``` + +### 释放HOST + +通信完成之后,还需要释放去HOST,函数如下所示: + +void SdioReleaseHost\(DevHandle handle\); + +**表 14** SdioReleaseHost函数的参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+
+ +释放HOST的示例如下: + +``` +SdioReleaseHost(handle); /* 释放HOST */ +``` + +### 关闭SDIO控制器 + +SDIO通信完成之后,最后需要关闭SDIO控制器,函数如下所示: + +void SdioClose\(DevHandle handle\); + +该函数会释放掉申请的资源。 + +**表 15** SdioClose函数的参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+
+ +关闭SDIO控制器的示例如下: + +``` +SdioClose(handle); /* 关闭SDIO控制器 */ +``` + +## 使用实例 + +SDIO设备完整的使用示例如下所示,首先打开总线号为1的SDIO控制器,然后独占HOST、使能设备、注册中断,接着进行SDIO通信(读写等),通信完成之后,释放中断、去使能设备、释放HOST,最后关闭SDIO控制器。 + +``` +#include "hdf_log.h" +#include "sdio_if.h" + +#define TEST_FUNC_NUM 1 /* 本测试用例中,使用编号为1的I/O function */ +#define TEST_FBR_BASE_ADDR 0x100 /* 编号为1的I/O function的FBR基地址 */ +#define TEST_ADDR_OFFSET 9 /* 本测试用例中,需要读写的寄存器的地址偏移 */ +#define TEST_DATA_LEN 3 /* 本测试用例中,读写数据的长度 */ +#define TEST_BLOCKSIZE 2 /* 本测试用例中,数据块的大小,单位字节 */ + +/* 中断服务函数,需要根据各自平台的情况去实现 */ +static void SdioIrqFunc(void *data) +{ + if (data == NULL) { + HDF_LOGE("SdioIrqFunc: data is NULL.\n"); + return; + } + /* 需要开发者自行添加具体的实现 */ +} + +void SdioTestSample(void) +{ + int32_t ret; + DevHandle handle = NULL; + uint8_t data[TEST_DATA_LEN] = {0}; + struct SdioFunctionConfig config = {1, 0x123, 0x456}; + uint8_t val; + uint32_t addr; + + /* 打开总线号为1的SDIO设备 */ + handle = SdioOpen(1, &config); + if (handle == NULL) { + HDF_LOGE("SdioOpen: failed!\n"); + return; + } + /* 独占HOST */ + SdioClaimHost(handle); + /* 使能SDIO设备 */ + ret = SdioEnableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); + goto ENABLE_ERR; + } + /* 注册中断 */ + ret = SdioClaimIrq(handle, SdioIrqFunc); + if (ret != 0) { + HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); + goto CLAIM_IRQ_ERR; + } + /* 设置块大小为2字节 */ + ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE); + if (ret != 0) { + HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO设备增量地址读取3字节的数据 */ + addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET; + ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO设备增量地址写入3字节的数据 */ + ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO设备读取1字节的数据 */ + ret = SdioReadBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO设备写入1字节的数据 */ + ret = SdioWriteBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO设备固定地址读取3字节的数据 */ + ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO设备固定地址写入1字节的数据 */ + ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO function 0读取1字节的数据 */ + addr = 0x02; + ret = SdioReadBytesFromFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO function 0写入1字节的数据 */ + ret = SdioWriteBytesToFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } +COMM_ERR: + /* 释放中断 */ + ret = SdioReleaseIrq(handle); + if (ret != 0) { + HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); + } +CLAIM_IRQ_ERR: + /* 去使能SDIO设备 */ + ret = SdioDisableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); + } +ENABLE_ERR: + /* 释放HOST */ + SdioReleaseHost(handle); + /* 关闭SDIO设备 */ + SdioClose(handle); +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-spi-des.md b/zh-cn/device-dev/driver/driver-platform-spi-des.md new file mode 100644 index 0000000000000000000000000000000000000000..47581f9a40529bf796a1b544cb059d6e8032ff54 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-spi-des.md @@ -0,0 +1,566 @@ +# SPI + +- [概述](#section193356154511) + - [接口说明](#section232141411476) + +- [使用指导](#section71363452477) + - [使用流程](#section32846814820) + - [获取SPI设备句柄](#section1927265711481) + - [获取SPI设备属性](#section541133418493) + - [配置SPI设备属性](#section7870106145010) + - [进行SPI通信](#section13324155195013) + - [销毁SPI设备句柄](#section19661632135117) + +- [使用实例](#section06541058155120) + +## 概述 + +- SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线。 +- SPI是由Motorola公司开发,用于在主设备和从设备之间进行通信,常用于与闪存、实时时钟、传感器以及模数转换器等进行通信。 +- SPI以主从方式工作,通常有一个主设备和一个或者多个从设备。主设备和从设备之间一般用4根线相连,它们分别是: + - SCLK – 时钟信号,由主设备产生; + - MOSI – 主设备数据输出,从设备数据输入; + - MISO – 主设备数据输入,从设备数据输出; + - CS – 片选,从设备使能信号,由主设备控制。 + + +- 一个主设备和两个从设备的连接示意图如[图1](#fig15227181812587)所示,Device A和Device B共享主设备的SCLK、MISO和MOSI三根引脚,Device A的片选CS0连接主设备的CS0,Device B的片选CS1连接主设备的CS1。 + +**图 1** SPI主从设备连接示意图。 + + +![](figure/zh-cn_image_0000001123742254.png) + +- SPI通信通常由主设备发起,通过以下步骤完成一次通信: + +1. 通过CS选中要通信的从设备,在任意时刻,一个主设备上最多只能有一个从设备被选中。 +2. 通过SCLK给选中的从设备提供时钟信号。 +3. 基于SCLK时钟信号,主设备数据通过MOSI发送给从设备,同时通过MISO接收从设备发送的数据,完成通信。 + +- 根据SCLK时钟信号的CPOL(Clock Polarity,时钟极性)和CPHA(Clock Phase,时钟相位)的不同组合,SPI有以下四种工作模式: + - CPOL=0,CPHA=0 时钟信号idle状态为低电平,第一个时钟边沿采样数据。 + - CPOL=0,CPHA=1 时钟信号idle状态为低电平,第二个时钟边沿采样数据。 + - CPOL=1,CPHA=0 时钟信号idle状态为高电平,第一个时钟边沿采样数据。 + - CPOL=1,CPHA=1 时钟信号idle状态为高电平,第二个时钟边沿采样数据。 + + +- SPI接口定义了操作SPI设备的通用方法集合,包括: + - SPI设备句柄获取和释放。 + - SPI读写: 从SPI设备读取或写入指定长度数据。 + - SPI自定义传输:通过消息传输结构体执行任意读写组合过程。 + - SPI设备配置:获取和设置SPI设备属性。 + + +>![](../public_sys-resources/icon-note.gif) **说明:** +>当前只支持主机模式,不支持从机模式。 + +### 接口说明 + +**表 1** SPI驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

SPI设备句柄获取释放接口

+

SpiOpen

+

获取SPI设备句柄

+

SpiClose

+

释放SPI设备句柄

+

SPI读写接口

+

SpiRead

+

读取指定长度的数据

+

SpiWrite

+

写入指定长度的数据

+

SpiTransfer

+

SPI数据传输接口

+

SPI设备配置接口

+

+

SpiSetCfg

+

根据指定参数,配置SPI设备

+

SpiGetCfg

+

获取SPI设备配置参数

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用SPI的一般流程如[图2](#fig23885455594)所示。 + +**图 2** SPI使用流程图 + + +![](figure/zh-cn_image_0000001123703482.png) + +### 获取SPI设备句柄 + +在使用SPI进行通信时,首先要调用SpiOpen获取SPI设备句柄,该函数会返回指定总线号和片选号的SPI设备句柄。 + +DevHandle SpiOpen\(const struct SpiDevInfo \*info\); + +**表 2** SpiOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

info

+

SPI设备描述符

+

返回值

+

返回值描述

+

NULL

+

获取SPI设备句柄失败

+

设备句柄

+

对应的SPI设备句柄

+
+ +假设系统中的SPI设备总线号为0,片选号为0,获取该SPI设备句柄的示例如下: + +``` +struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ +DevHandle spiHandle = NULL; /* SPI设备句柄 */ +spiDevinfo.busNum = 0; /* SPI设备总线号 */ +spiDevinfo.csNum = 0; /* SPI设备片选号 */ + +/* 获取SPI设备句柄 */ +spiHandle = SpiOpen(&spiDevinfo); +if (spiHandle == NULL) { + HDF_LOGE("SpiOpen: failed\n"); + return; +} +``` + +### 获取SPI设备属性 + +在获取到SPI设备句柄之后,需要配置SPI设备属性。配置SPI设备属性之前,可以先获取SPI设备属性,获取SPI设备属性的函数如下所示: + +int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\); + +**表 3** SpiGetCfg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

cfg

+

SPI设备配置参数

+

返回值

+

返回值描述

+

0

+

获取配置成功

+

负数

+

获取配置失败

+
+ +``` +int32_t ret; +struct SpiCfg cfg = {0}; /* SPI配置信息*/ +ret = SpiGetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ +if (ret != 0) { + HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); +} +``` + +### 配置SPI设备属性 + +在获取到SPI设备句柄之后,需要配置SPI设备属性,配置SPI设备属性的函数如下所示: + +int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\); + +**表 4** SpiSetCfg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

cfg

+

SPI设备配置参数

+

返回值

+

返回值描述

+

0

+

配置成功

+

负数

+

配置失败

+
+ +``` +int32_t ret; +struct SpiCfg cfg = {0}; /* SPI配置信息*/ +cfg.mode = SPI_MODE_LOOP; /* 以回环模式进行通信 */ +cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* 以轮询的方式进行通信 */ +cfg.maxSpeedHz = 115200; /* 最大传输频率 */ +cfg.bitsPerWord = 8; /* 读写位宽为8个比特 */ +ret = SpiSetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ +if (ret != 0) { + HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); +} +``` + +### 进行SPI通信 + +- 向SPI设备写入指定长度的数据 + +如果只向SPI设备写一次数据,则可以通过以下函数完成: + +int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); + +**表 5** SpiWrite参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

buf

+

待写入数据的指针

+

len

+

待写入的数据长度

+

返回值

+

返回值描述

+

0

+

写入成功

+

负数

+

写入失败

+
+ +``` +int32_t ret; +uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78}; +/* 向SPI设备写入指定长度的数据 */ +ret = SpiWrite(spiHandle, wbuff, 4); +if (ret != 0) { + HDF_LOGE("SpiWrite: failed, ret %d\n", ret); +} +``` + +- 从SPI设备读取指定长度的数据 + +如果只读取一次数据,则可以通过以下函数完成: + +int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); + +**表 6** SpiRead参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

buf

+

待读取数据的指针

+

len

+

待读取的数据长度

+

返回值

+

返回值描述

+

0

+

读取成功

+

负数

+

读取失败

+
+ +``` +int32_t ret; +uint8_t rbuff[4] = {0}; +/* 从SPI设备读取指定长度的数据 */ +ret = SpiRead(spiHandle, rbuff, 4); +if (ret != 0) { + HDF_LOGE("SpiRead: failed, ret %d\n", ret); +} +``` + +- 自定义传输 + +如果需要发起一次自定义传输,则可以通过以下函数完成: + +int32\_t SpiTransfer\(DevHandle handle, struct SpiMsg \*msgs, uint32\_t count\); + +**表 7** SpiTransfer参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

msgs

+

待传输数据的数组

+

count

+

msgs数组长度

+

返回值

+

返回值描述

+

0

+

执行成功

+

负数

+

执行失败

+
+ +``` +int32_t ret; +uint8_t wbuff[1] = {0x12}; +uint8_t rbuff[1] = {0}; +struct SpiMsg msg; /* 自定义传输的消息*/ +msg.wbuf = wbuff; /* 写入的数据 */ +msg.rbuf = rbuff; /* 读取的数据 */ +msg.len = 1; /* 读取、写入数据的长度都是1 */ +msg.csChange = 1; /* 进行下一次传输前关闭片选 */ +msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ +msg.speed = 115200; /* 本次传输的速度 */ +/* 进行一次自定义传输,传输的msg个数为1 */ +ret = SpiTransfer(spiHandle, &msg, 1); +if (ret != 0) { + HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); +} +``` + +### 销毁SPI设备句柄 + +SPI通信完成之后,需要销毁SPI设备句柄,销毁SPI设备句柄的函数如下所示: + +void SpiClose\(DevHandle handle\); + +该函数会释放掉申请的资源。 + +**表 8** SpiClose参数描述 + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+
+ +``` +SpiClose(spiHandle); /* 销毁SPI设备句柄 */ +``` + +## 使用实例 + +SPI设备完整的使用示例如下所示,首先获取SPI设备句柄,然后配置SPI设备属性,接着调用读写接口进行数据传输,最后销毁SPI设备句柄。 + +``` +#include "hdf_log.h" +#include "spi_if.h" + +void SpiTestSample(void) +{ + int32_t ret; + struct SpiCfg cfg; /* SPI配置信息 */ + struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ + DevHandle spiHandle = NULL; /* SPI设备句柄 */ + struct SpiMsg msg; /* 自定义传输的消息 */ + uint8_t rbuff[4] = { 0 }; + uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; + uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; + + spiDevinfo.busNum = 0; /* SPI设备总线号 */ + spiDevinfo.csNum = 0; /* SPI设备片选号 */ + spiHandle = SpiOpen(&spiDevinfo); /* 根据spiDevinfo获取SPI设备句柄 */ + if (spiHandle == NULL) { + HDF_LOGE("SpiOpen: failed\n"); + return; + } + /* 获取SPI设备属性 */ + ret = SpiGetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); + goto err; + } + cfg.maxSpeedHz = 115200; /* 将最大时钟频率改为115200 */ + cfg.bitsPerWord = 8; /* 传输位宽改为8比特 */ + /* 配置SPI设备属性 */ + ret = SpiSetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); + goto err; + } + /* 向SPI设备写入指定长度的数据 */ + ret = SpiWrite(spiHandle, wbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiWrite: failed, ret %d\n", ret); + goto err; + } + /* 从SPI设备读取指定长度的数据 */ + ret = SpiRead(spiHandle, rbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiRead: failed, ret %d\n", ret); + goto err; + } + msg.wbuf = wbuff2; /* 写入的数据 */ + msg.rbuf = rbuff; /* 读取的数据 */ + msg.len = 4; /* 读取写入数据的长度为4 */ + msg.csChange = 1; /* 进行下一次传输前关闭片选 */ + msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ + msg.speed = 115200; /* 本次传输的速度 */ + /* 进行一次自定义传输,传输的msg个数为1 */ + ret = SpiTransfer(spiHandle, &msg, 1); + if (ret != 0) { + HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); + goto err; + } +err: + /* 销毁SPI设备句柄 */ + SpiClose(spiHandle); +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-uart-des.md b/zh-cn/device-dev/driver/driver-platform-uart-des.md new file mode 100644 index 0000000000000000000000000000000000000000..182cad984a49051847129210d7cce9e9db7bbcdd --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-uart-des.md @@ -0,0 +1,682 @@ +# UART + +- [概述](#section833012453535) + - [接口说明](#section1680292311549) + +- [使用指导](#section12779050105412) + - [使用流程](#section1858116395510) + - [获取UART设备句柄](#section124512065617) + - [UART设置波特率](#section86881004579) + - [UART获取波特率](#section897032965712) + - [UART设置设备属性](#section129141884588) + - [UART获取设备属性](#section18689637165812) + - [设置UART传输模式](#section72713435918) + - [向UART设备写入指定长度的数据](#section128001736155919) + - [从UART设备中读取指定长度的数据](#section92851601604) + - [销毁UART设备句柄](#section1477410521406) + +- [使用实例](#section35404241311) + +## 概述 + +- UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)的缩写,是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 +- UART应用比较广泛,常用于输出打印信息,也可以外接各种模块,如GPS、蓝牙等。 +- 两个UART设备的连接示意图如下,UART与其他模块一般用2线(图1)或4线(图2)相连,它们分别是: + - TX:发送数据端,和对端的RX相连; + - RX:接收数据端,和对端的TX相连; + - RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连; + - CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连; + + **图 1** 2线UART设备连接示意图 + + + ![](figure/zh-cn_image_0000001170262141.png) + + **图 2** 4线UART设备连接示意图 + + + ![](figure/zh-cn_image_0000001123582482.png) + + +- UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。 +- UART接口定义了操作UART端口的通用方法集合,包括获取、释放设备句柄、读写数据、获取和设置波特率、获取和设置设备属性。 + +### 接口说明 + +**表 1** UART驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

UART获取/释放设备句柄

+

+

UartOpen

+

UART获取设备句柄

+

UartClose

+

UART释放设备句柄

+

UART读写接口

+

+

UartRead

+

从UART设备中读取指定长度的数据

+

UartWrite

+

向UART设备中写入指定长度的数据

+

UART获取/设置波特率接口

+

UartGetBaud

+

UART获取波特率

+

UartSetBaud

+

UART设置波特率

+

UART获取/设置设备属性

+

+

UartGetAttribute

+

UART获取设备属性

+

UartSetAttribute

+

UART设置设备属性

+

UART设置传输模式

+

UartSetTransMode

+

UART设置传输模式

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用UART的一般流程如[图3](#fig1852173020185)所示。 + +**图 3** UART使用流程图 + + +![](figure/zh-cn_image_0000001170227689.png) + +### 获取UART设备句柄 + +在使用UART进行通信时,首先要调用UartOpen获取UART设备句柄,该函数会返回指定端口号的UART设备句柄。 + +DevHandle UartOpen\(uint32\_t port\); + +**表 2** UartOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

port

+

UART设备号

+

返回值

+

返回值描述

+

NULL

+

获取UART设备句柄失败

+

设备句柄

+

UART设备句柄

+
+ +假设系统中的UART端口号为3,获取该UART设备句柄的示例如下: + +``` +DevHandle handle = NULL; /* UART设备句柄 */ +uint32_t port = 3; /* UART设备端口号 */ +handle = UartOpen(port); +if (handle == NULL) { + HDF_LOGE("UartOpen: failed!\n"); + return; +} +``` + +### UART设置波特率 + +在通信之前,需要设置UART的波特率,设置波特率的函数如下所示: + +int32\_t UartSetBaud\(DevHandle handle, uint32\_t baudRate\); + +**表 3** UartSetBaud参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

baudRate

+

待设置的波特率值

+

返回值

+

返回值描述

+

0

+

UART设置波特率成功

+

负数

+

UART设置波特率失败

+
+ +假设需要设置的UART波特率为9600,设置波特率的实例如下: + +``` +int32_t ret; +/* 设置UART波特率 */ +ret = UartSetBaud(handle, 9600); +if (ret != 0) { + HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); +} +``` + +### UART获取波特率 + +设置UART的波特率后,可以通过获取波特率接口来查看UART当前的波特率,获取波特率的函数如下所示: + +int32\_t UartGetBaud\(DevHandle handle, uint32\_t \*baudRate\); + +**表 4** UartGetBaud参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

baudRate

+

接收波特率值的指针

+

返回值

+

返回值描述

+

0

+

UART获取波特率成功

+

负数

+

UART获取波特率失败

+
+ +获取波特率的实例如下: + +``` +int32_t ret; +uint32_t baudRate; +/* 获取UART波特率 */ +ret = UartGetBaud(handle, &baudRate); +if (ret != 0) { + HDF_LOGE("UartGetBaud: failed, ret %d\n", ret); +} +``` + +### UART设置设备属性 + +在通信之前,需要设置UART的设备属性,设置设备属性的函数如下图所示: + +int32\_t UartSetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); + +**表 5** UartSetAttribute参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

attribute

+

待设置的设备属性

+

返回值

+

返回值描述

+

0

+

UART设置设备属性成功

+

负数

+

UART设置设备属性失败

+
+ +设置UART的设备属性的实例如下: + +``` +int32_t ret; +struct UartAttribute attribute; +attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ +attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ +attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ +attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ +attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ +attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ +attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ +/* 设置UART设备属性 */ +ret = UartSetAttribute(handle, &attribute); +if (ret != 0) { + HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); +} +``` + +### UART获取设备属性 + +设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性,获取设备属性的函数如下图所示: + +int32\_t UartGetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); + +**表 6** UartGetAttribute参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

attribute

+

接收UART设备属性的指针

+

返回值

+

返回值描述

+

0

+

UART获取设备属性成功

+

负数

+

UART获取设备属性失败

+
+ +获取UART的设备属性的实例如下: + +``` +int32_t ret; +struct UartAttribute attribute; +/* 获取UART设备属性 */ +ret = UartGetAttribute(handle, &attribute); +if (ret != 0) { + HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret); +} +``` + +### 设置UART传输模式 + +在通信之前,需要设置UART的传输模式,设置传输模式的函数如下图所示: + +int32\_t UartSetTransMode\(DevHandle handle, enum UartTransMode mode\); + +**表 7** UartSetTransMode参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

mode

+

待设置的传输模式,

+

返回值

+

返回值描述

+

0

+

UART设置传输模式成功

+

负数

+

UART设置传输模式失败

+
+ +假设需要设置的UART传输模式为UART\_MODE\_RD\_BLOCK,设置传输模式的实例如下: + +``` +int32_t ret; +/* 设置UART传输模式 */ +ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); +if (ret != 0) { + HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); +} +``` + +### 向UART设备写入指定长度的数据 + +对应的接口函数如下所示: + +int32\_t UartWrite\(DevHandle handle, uint8\_t \*data, uint32\_t size\); + +**表 8** UartWrite参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

data

+

待写入数据的指针

+

size

+

待写入数据的长度

+

返回值

+

返回值描述

+

0

+

UART写数据成功

+

负数

+

UART写数据失败

+
+ +写入指定长度数据的实例如下: + +``` +int32_t ret; +uint8_t wbuff[5] = {1, 2, 3, 4, 5}; +/* 向UART设备写入指定长度的数据 */ +ret = UartWrite(handle, wbuff, 5); +if (ret != 0) { + HDF_LOGE("UartWrite: failed, ret %d\n", ret); +} +``` + +### 从UART设备中读取指定长度的数据 + +对应的接口函数如下所示: + +int32\_t UartRead\(DevHandle handle, uint8\_t \*data, uint32\_t size\); + +**表 9** UartRead参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

data

+

接收读取数据的指针

+

size

+

待读取数据的长度

+

返回值

+

返回值描述

+

非负数

+

UART读取到的数据长度

+

负数

+

UART读取数据失败

+
+ +读取指定长度数据的实例如下: + +``` +int32_t ret; +uint8_t rbuff[5] = {0}; +/* 从UART设备读取指定长度的数据 */ +ret = UartRead(handle, rbuff, 5); +if (ret < 0) { + HDF_LOGE("UartRead: failed, ret %d\n", ret); +} +``` + +>![](../public_sys-resources/icon-caution.gif) **注意:** +>UART返回值为非负值,表示UART读取成功。若返回值等于0,表示UART无有效数据可以读取。若返回值大于0,表示实际读取到的数据长度,该长度小于或等于传入的参数size的大小,并且不超过当前正在使用的UART控制器规定的最大单次读取数据长度的值。 + +### 销毁UART设备句柄 + +UART通信完成之后,需要销毁UART设备句柄,函数如下所示: + +void UartClose\(DevHandle handle\); + +该函数会释放申请的资源。 + +**表 10** UartClose参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+
+ +销毁UART设备句柄的实例如下: + +``` +UartClose(handle); /* 销毁UART设备句柄 * +``` + +## 使用实例 + +UART设备完整的使用示例如下所示,首先获取UART设备句柄,接着设置波特率、设备属性和传输模式,之后进行UART通信,最后销毁UART设备句柄。 + +``` +#include "hdf_log.h" +#include "uart_if.h" + +void UartTestSample(void) +{ + int32_t ret; + uint32_t port; + DevHandle handle = NULL; + uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; + uint8_t rbuff[5] = { 0 }; + struct UartAttribute attribute; + attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ + attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ + attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ + attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ + attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ + attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ + attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ + /* UART设备端口号,要填写实际平台上的端口号 */ + port = 1; + /* 获取UART设备句柄 */ + handle = UartOpen(port); + if (handle == NULL) { + HDF_LOGE("UartOpen: failed!\n"); + return; + } + /* 设置UART波特率为9600 */ + ret = UartSetBaud(handle, 9600); + if (ret != 0) { + HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); + goto _ERR; + } + /* 设置UART设备属性 */ + ret = UartSetAttribute(handle, &attribute); + if (ret != 0) { + HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); + goto _ERR; + } + /* 设置UART传输模式为非阻塞模式 */ + ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); + if (ret != 0) { + HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); + goto _ERR; + } + /* 向UART设备写入5字节的数据 */ + ret = UartWrite(handle, wbuff, 5); + if (ret != 0) { + HDF_LOGE("UartWrite: failed, ret %d\n", ret); + goto _ERR; + } + /* 从UART设备读取5字节的数据 */ + ret = UartRead(handle, rbuff, 5); + if (ret < 0) { + HDF_LOGE("UartRead: failed, ret %d\n", ret); + goto _ERR; + } +_ERR: + /* 销毁UART设备句柄 */ + UartClose(handle); +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-watchdog-des.md b/zh-cn/device-dev/driver/driver-platform-watchdog-des.md new file mode 100644 index 0000000000000000000000000000000000000000..b6eba28de3581722b16b58ed7a4e31e6b7054362 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-watchdog-des.md @@ -0,0 +1,557 @@ +# WATCHDOG + +- [概述](#section14918241977) + - [接口说明](#section20177131219818) + +- [使用指导](#section10103184312813) + - [使用流程](#section10181195910815) + - [打开看门狗设备](#section66089201107) + - [获取看门狗状态](#section786624341011) + - [设置超时时间](#section182386137111) + - [获取超时时间](#section1883310371114) + - [启动看门狗](#section82501405123) + - [喂狗](#section3547530101211) + - [停止看门狗](#section944595841217) + - [关闭看门狗设备](#section96561824121311) + +- [使用实例](#section1724514523135) + +## 概述 + +看门狗(watchdog),又叫看门狗计时器(watchdog timer),是一种硬件的计时设备,当系统的主程序发生某些错误时,导致未及时清除看门狗计时器的计时值,这时看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。 + +### 接口说明 + +**表 1** 看门狗 API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

打开/关闭看门狗

+

WatchdogOpen

+

打开看门狗设备

+

WatchdogClose

+

关闭看门狗设备

+

启动/停止看门狗

+

WatchdogStart

+

启动看门狗

+

WatchdogStop

+

停止看门狗

+

设置/获取超时时间

+

WatchdogSetTimeout

+

设置看门狗超时时间

+

WatchdogGetTimeout

+

获取看门狗超时时间

+

获取看门狗状态

+

WatchdogGetStatus

+

获取看门狗状态

+

清除看门狗定时器

+

WatchdogFeed

+

清除看门狗定时器(喂狗)

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及看门狗的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用看门狗的一般流程如[图1](#fig19134125410189)所示。 + +**图 1** 看门狗使用流程图 + + +![](figure/zh-cn_image_0000001170229891.png) + +### 打开看门狗设备 + +在操作看门狗之前,需要使用WatchdogOpen打开一个看门狗设备,一个系统可能有多个看门狗,通过ID号来打开指定的看门狗设备: + +int32\_t WatchdogOpen\(int16\_t wdtId\); + +**表 2** WatchdogOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

wdtId

+

看门狗设备号

+

返回值

+

返回值描述

+

NULL

+

打开失败

+

DevHandle类型指针

+

看门狗设备句柄

+
+ +``` +DevHandle handle = NULL; +handle = WatchdogOpen(0); /* 打开0号看门狗设备 */ +if (handle == NULL) { + HDF_LOGE("WatchdogOpen: failed, ret %d\n", ret); + return; +} +``` + +### 获取看门狗状态 + +int32\_t WatchdogGetStatus\(DevHandle handle, int32\_t \*status\); + +**表 3** WatchdogGetStatus参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

status

+

获取到的启动状态指针

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +int32_t status; +/* 获取Watchdog启动状态 */ +ret = WatchdogGetStatus(handle, &status); +if (ret != 0) { + HDF_LOGE("WatchdogGetStatus: failed, ret %d\n", ret); + return; +} +``` + +### 设置超时时间 + +int32\_t WatchdogSetTimeout\(PalHandle \*handle, uint32\_t seconds\); + +**表 4** WatchdogSetTimeout参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

seconds

+

超时时间,单位为秒

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ +``` +int32_t ret; +uint32_t timeOut = 60; +/* 设置超时时间,单位:秒 */ +ret = WatchdogSetTimeout(handle, timeOut); +if (ret != 0) { + HDF_LOGE("WatchdogSetTimeout: failed, ret %d\n", ret); + return; +} +``` + +### 获取超时时间 + +int32\_t WatchdogGetTimeout\(PalHandle \*handle, uint32\_t \*seconds\); + +**表 5** WatchdogGetTimeout参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

seconds

+

接收超时时间的指针,单位为秒

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +uint32_t timeOut; +/* 获取超时时间,单位:秒 */ +ret = WatchdogGetTimeout(handle, &timeOut); +if (ret != 0) { + HDF_LOGE("WatchdogGetTimeout: failed, ret %d\n", ret); + return; +} +``` + +### 启动看门狗 + +int32\_t WatchdogStart\(DevHandle handle\); + +**表 6** WatchdogStart参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

返回值

+

返回值描述

+

0

+

启动成功

+

负数

+

启动失败

+
+ +``` +int32_t ret; +/* 启动看门狗 */ +ret = WatchdogStart(handle); +if (ret != 0) { + HDF_LOGE("WatchdogStart: failed, ret %d\n", ret); + return; +} +``` + +### 喂狗 + +int32\_t WatchdogFeed\(DevHandle handle\); + +**表 7** WatchdogFeed参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

返回值

+

返回值描述

+

0

+

喂狗成功

+

负数

+

喂狗失败

+
+ +``` +int32_t ret; +/* 喂狗 */ +ret = WatchdogFeed(handle); +if (ret != 0) { + HDF_LOGE("WatchdogFeed: failed, ret %d\n", ret); + return; +} +``` + +### 停止看门狗 + +int32\_t WatchdogStop\(DevHandle handle\); + +**表 8** WatchdogStop参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

返回值

+

返回值描述

+

0

+

停止成功

+

负数

+

停止失败

+
+ +``` +int32_t ret; +/* 停止看门狗 */ +ret = WatchdogStop(handle); +if (ret != 0) { + HDF_LOGE("WatchdogStop: failed, ret %d\n", ret); + return; +} +``` + +### 关闭看门狗设备 + +当操作完毕时,使用WatchdogClose关闭打开的设备句柄: + +void WatchdogClose\(DevHandle handle\); + +**表 9** WatchdogClose参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+
+ +``` +/* 关闭看门狗 */ +ret = WatchdogClose(handle); +``` + +## 使用实例 + +本例程提供看门狗的完整使用流程。 + +在本例程中,我们打开一个看门狗设备,设置超时时间并启动计时: + +- 首先定期喂狗,即按时清除看门狗定时器,确保系统不会因定时器超时而复位。 +- 接着再停止喂狗,观察定时器到期后系统是否发生复位行为。 + +示例如下: + +``` +#include "watchdog_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +#define WATCHDOG_TEST_TIMEOUT 2 +#define WATCHDOG_TEST_FEED_TIME 6 + +static int32_t TestCaseWatchdog(void) +{ + int32_t i; + int32_t ret; + uint32_t timeout; + DevHandle handle = NULL; + + /* 打开0号看门狗设备 */ + handle = WatchdogOpen(0); + if (handle == NULL) { + HDF_LOGE("Open watchdog fail!"); + return -1; + } + + /* 设置超时时间 */ + ret = WatchdogSetTimeout(handle, WATCHDOG_TEST_TIMEOUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* 回读设置的超时时间值 */ + ret = WatchdogGetTimeout(handle, &timeout); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); + + /* 启动看门狗,开始计时 */ + ret = WatchdogStart(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* 每隔1S喂狗一次 */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); + ret = WatchdogFeed(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + OsalSleep(1); + } + /* 由于喂狗间隔小于超时时间,系统不会发生复位,此日志可以正常打印 */ + HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); + + /* 接下来持续不喂狗,使得看门狗计时器超时 */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: watiting dog buck %d times... \n", __func__, i); + OsalSleep(1); + } + + /* 当不喂狗时间到达之前设定的超时时间的时候,系统会发生复位,理论上观察不到此日志的打印 */ + HDF_LOGE("%s: dog has't buck!!! \n", __func__, i); + WatchdogClose(handle); + return -1; +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform.md b/zh-cn/device-dev/driver/driver-platform.md new file mode 100644 index 0000000000000000000000000000000000000000..a05dec17675ce06876d0550e383413fd53d07a71 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform.md @@ -0,0 +1,19 @@ +# 平台驱动 + +- **[GPIO](driver-platform-gpio-des.md)** + +- **[I2C](driver-platform-i2c-des.md)** + +- **[RTC](driver-platform-rtc-des.md)** + +- **[SDIO](driver-platform-sdio-des.md)** + +- **[SPI](driver-platform-spi-des.md)** + +- **[UART](driver-platform-uart-des.md)** + +- **[WATCHDOG](driver-platform-watchdog-des.md)** + +- **[MIPI DSI](driver-platform-mipidsi-des.md)** + + diff --git a/zh-cn/device-dev/driver/driver.md b/zh-cn/device-dev/driver/driver.md new file mode 100644 index 0000000000000000000000000000000000000000..a0825c12d1ed8456318aca70316eaf6500251dab --- /dev/null +++ b/zh-cn/device-dev/driver/driver.md @@ -0,0 +1,19 @@ +# 驱动使用指南 + +- **[HDF开发概述](driver-hdf-overview.md)** + +- **[驱动开发](driver-hdf-development.md)** + +- **[驱动服务管理](driver-hdf-servicemanage.md)** + +- **[驱动消息机制管理](driver-hdf-news.md)** + +- **[配置管理](driver-hdf-manage.md)** + +- **[HDF开发实例](driver-hdf-sample.md)** + +- **[平台驱动](driver-platform.md)** + +- **[外设](driver-peripherals.md)** + + diff --git "a/zh-cn/device-dev/driver/figures/DSI\345\217\221\351\200\201-\346\216\245\346\224\266\346\216\245\345\217\243.png" "b/zh-cn/device-dev/driver/figure/DSI\345\217\221\351\200\201-\346\216\245\346\224\266\346\216\245\345\217\243.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/DSI\345\217\221\351\200\201-\346\216\245\346\224\266\346\216\245\345\217\243.png" rename to "zh-cn/device-dev/driver/figure/DSI\345\217\221\351\200\201-\346\216\245\346\224\266\346\216\245\345\217\243.png" diff --git "a/zh-cn/device-dev/driver/figures/I2C\347\211\251\347\220\206\350\277\236\347\272\277\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/driver/figure/I2C\347\211\251\347\220\206\350\277\236\347\272\277\347\244\272\346\204\217\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/I2C\347\211\251\347\220\206\350\277\236\347\272\277\347\244\272\346\204\217\345\233\276.png" rename to "zh-cn/device-dev/driver/figure/I2C\347\211\251\347\220\206\350\277\236\347\272\277\347\244\272\346\204\217\345\233\276.png" diff --git "a/zh-cn/device-dev/driver/figures/MIPI-DSI\346\216\245\345\217\243.png" "b/zh-cn/device-dev/driver/figure/MIPI-DSI\346\216\245\345\217\243.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/MIPI-DSI\346\216\245\345\217\243.png" rename to "zh-cn/device-dev/driver/figure/MIPI-DSI\346\216\245\345\217\243.png" diff --git "a/zh-cn/device-dev/driver/figures/Sensor\351\251\261\345\212\250\346\250\241\345\236\213\345\233\276.png" "b/zh-cn/device-dev/driver/figure/Sensor\351\251\261\345\212\250\346\250\241\345\236\213\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/Sensor\351\251\261\345\212\250\346\250\241\345\236\213\345\233\276.png" rename to "zh-cn/device-dev/driver/figure/Sensor\351\251\261\345\212\250\346\250\241\345\236\213\345\233\276.png" diff --git "a/zh-cn/device-dev/driver/figures/TTL\346\216\245\345\217\243.png" "b/zh-cn/device-dev/driver/figure/TTL\346\216\245\345\217\243.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/TTL\346\216\245\345\217\243.png" rename to "zh-cn/device-dev/driver/figure/TTL\346\216\245\345\217\243.png" diff --git "a/zh-cn/device-dev/driver/figures/Touchscreen\345\231\250\344\273\266\345\270\270\347\224\250\347\256\241\350\204\232.png" "b/zh-cn/device-dev/driver/figure/Touchscreen\345\231\250\344\273\266\345\270\270\347\224\250\347\256\241\350\204\232.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/Touchscreen\345\231\250\344\273\266\345\270\270\347\224\250\347\256\241\350\204\232.png" rename to "zh-cn/device-dev/driver/figure/Touchscreen\345\231\250\344\273\266\345\270\270\347\224\250\347\256\241\350\204\232.png" diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001053405727.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001053405727.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001053405727.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001053405727.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054280608.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001054280608.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054280608.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001054280608.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054564784.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001054564784.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054564784.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001054564784.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001057902344.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001123509750.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001057902344.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001123509750.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001072553354.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001123514210.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001072553354.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001123514210.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054440624.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001123540984.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054440624.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001123540984.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054007499.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001123582482.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054007499.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001123582482.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054728498.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001123675706.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054728498.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001123675706.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054726248.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001123703482.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054726248.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001123703482.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054142582.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001123742254.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054142582.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001123742254.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001057342245.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001170187071.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001057342245.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001170187071.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054006983.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001170227689.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054006983.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001170227689.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001057622716.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001170229891.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001057622716.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001170229891.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001053926237.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001170262141.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001053926237.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001170262141.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001055299108.png b/zh-cn/device-dev/driver/figure/zh-cn_image_0000001170383063.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001055299108.png rename to zh-cn/device-dev/driver/figure/zh-cn_image_0000001170383063.png diff --git "a/zh-cn/device-dev/driver/figures/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204Display\351\251\261\345\212\250\346\250\241\345\236\213.png" "b/zh-cn/device-dev/driver/figure/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204Display\351\251\261\345\212\250\346\250\241\345\236\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204Display\351\251\261\345\212\250\346\250\241\345\236\213.png" rename to "zh-cn/device-dev/driver/figure/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204Display\351\251\261\345\212\250\346\250\241\345\236\213.png" diff --git "a/zh-cn/device-dev/driver/figures/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204input\351\251\261\345\212\250\346\250\241\345\236\213.png" "b/zh-cn/device-dev/driver/figure/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204input\351\251\261\345\212\250\346\250\241\345\236\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204input\351\251\261\345\212\250\346\250\241\345\236\213.png" rename to "zh-cn/device-dev/driver/figure/\345\237\272\344\272\216HDF\351\251\261\345\212\250\346\241\206\346\236\266\347\232\204input\351\251\261\345\212\250\346\250\241\345\236\213.png" diff --git "a/zh-cn/device-dev/driver/figures/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" "b/zh-cn/device-dev/driver/figure/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/driver/figures/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" rename to "zh-cn/device-dev/driver/figure/\346\216\245\345\217\243\345\210\206\345\270\203\345\233\2764.png" diff --git a/zh-cn/device-dev/driver/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/driver/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/driver/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/driver/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/driver/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/driver/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/driver/public_sys-resources/icon-note.gif b/zh-cn/device-dev/driver/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/driver/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/driver/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/driver/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/driver/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/driver/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/driver/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/driver/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/driver/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/driver/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/driver/public_sys-resources/icon-warning.gif and /dev/null differ diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index 2222c0fde7eae0be2288c10291da6172cf688401..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,583 +0,0 @@ -# 传感器驱动开发实例 - -基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](驱动开发.md)。加速度传感器选择通讯接口方式为I2C,厂家选择博世BMI160加速度传感器。 - -1. 加速度计传感器驱动入口注册 - -- 加速度计传感器驱动入口函数实现 - -``` -/* 注册加速度计传感器入口数据结构体对象 */ -struct HdfDriverEntry g_sensorAccelDevEntry = { - .moduleVersion = 1, /* 加速度计传感器模块版本号 */ - .moduleName = "HDF_SENSOR_ACCEL", /* 加速度计传感器模块名,要与device_info.hcs文件里的加速度计moduleName字段值一样*/ - .Bind = BindAccelDriver, /* 加速度计传感器绑定函数 */ - .Init = InitAccelDriver, /* 加速度计传感器初始化函数 */ - .Release = ReleaseAccelDriver, /* 加速度计传感器资源释放函数 */ -}; - -/* 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 */ -HDF_INIT(g_sensorAccelDevEntry); -``` - -- 加速度计传感器设备配置描述 - -加速度传感器模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](配置管理.md)介绍。 - -``` -/* 加速度计传感器设备HCS配置 */ -device_sensor_accel :: device { - device0 :: deviceNode { - policy = 1; /* policy字段是驱动服务发布的策略 */ - priority = 105; /* 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */ - preload = 2; /* 驱动按需加载字段,0表示加载,2表示不加载 */ - permission = 0664; /* 驱动创建设备节点权限 */ - moduleName = "HDF_SENSOR_ACCEL"; /* 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */ - serviceName = "sensor_accel"; /* 驱动对外发布服务的名称,必须唯一 */ - deviceMatchAttr = "hdf_sensor_accel_driver"; /* 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 */ - } -} -``` - -1. 加速度计传感器驱动初始化和去初始化 - -- 初始化入口函数init - -``` -/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */ -int32_t BindAccelDriver(struct HdfDeviceObject *device) -{ - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - - static struct IDeviceIoService service = { - .object = {0}, - .Dispatch = DispatchAccel, - }; - device->service = &service; - - return HDF_SUCCESS; -} -/*在探测到器件在位后,需要调用RegisterAccelChipOps注册差异化适配函数*/ -int32_t RegisterAccelChipOps(struct AccelOpsCall *ops) -{ - struct AccelDrvData *drvData = NULL; - - CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); - - drvData = AccelGetDrvData(); - drvData->ops.Init = ops->Init; - drvData->ops.ReadData = ops->ReadData; - return HDF_SUCCESS; -} -/* 挂载加速度计传感器驱动归一化的接口函数 */ -static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo) -{ - struct AccelDrvData *drvData = AccelGetDrvData(); - - (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); - deviceInfo->ops.GetInfo = SetAccelInfo; - deviceInfo->ops.Enable = SetAccelEnable; - deviceInfo->ops.Disable = SetAccelDisable; - deviceInfo->ops.SetBatch = SetAccelBatch; - deviceInfo->ops.SetMode = SetAccelMode; - deviceInfo->ops.SetOption = SetAccelOption; - - if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), - &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) { - HDF_LOGE("%s: copy sensor info failed", __func__); - return HDF_FAILURE; - } - /* 传感器类型标识可以在数据HCS配置文件里面配置,也可以在此处 */ - drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER; - drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER; - - return HDF_SUCCESS; -} -/* 传感器寄存器初始化操作 */ -static int32_t InitAccelAfterConfig(void) -{ - struct SensorDeviceInfo deviceInfo; - - if (InitAccelConfig() != HDF_SUCCESS) { - HDF_LOGE("%s: init accel config failed", __func__); - return HDF_FAILURE; - } - - if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: init accel ops failed", __func__); - return HDF_FAILURE; - } - - if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: add accel device failed", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} -/*通过器件探测函数,挂载器件差异化函数接口*/ -static int32_t DetectAccelChip(void) -{ - int32_t num; - int32_t ret; - int32_t loop; - struct AccelDrvData *drvData = AccelGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - - num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]); - for (loop = 0; loop < num; ++loop) { - if (g_accelDetectIfList[loop].DetectChip != NULL) { - ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg); - if (ret == HDF_SUCCESS) { - drvData->detectFlag = true; - break; - } - } - } - - if (loop == num) { - HDF_LOGE("%s: detect accel device failed", __func__); - drvData->detectFlag = false; - return HDF_FAILURE; - } - return HDF_SUCCESS; -} -/* 加速度计传感器驱动初始化入口函数,主要功能为对传感器私有数据的结构体对象进行初始化,传感器HCS数据配置对象空间分配,传感器HCS数据配置初始化入口函数调用,传感器设备探测是否在位功能,传感器数据上报定时器创建,传感器归一化接口挂载,传感器设备注册功能 */ -int32_t InitAccelDriver(struct HdfDeviceObject *device) -{ - /* 获取传感器私有数据结构体对象 */ - struct AccelDrvData *drvData = AccelGetDrvData(); - - /* 同类型传感器不同厂家设备探测时,判断此类型传感器是否已经在位,若已经在位,无需再继续探测,直接返回 */ - if (drvData->detectFlag) { - HDF_LOGE("%s: accel sensor have detected", __func__); - return HDF_SUCCESS; - } - - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - /* 分配存放传感器数据配置的私有结构体数据对象,需要在驱动释放时释放分配的资源空间 */ - drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg)); - if (drvData->accelCfg == NULL) { - HDF_LOGE("%s: malloc sensor config data failed", __func__); - return HDF_FAILURE; - } - - drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; - /* 初始化传感器配置数据主要是解析传感器通讯总线配置类型信息,传感器基本信息,传感器属性信息,传感器是否在位信息,寄存器分组信息 */ - if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: get sensor base config failed", __func__); - goto Base_CONFIG_EXIT; - } - - if (DetectAccelChip() != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor detect device no exist", __func__); - goto DETECT_CHIP_EXIT; - } - drvData->detectFlag = true; - if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: detect sensor device failed", __func__); - goto REG_CONFIG_EXIT; - } - - if (InitAccelAfterConfig() != HDF_SUCCESS) { - HDF_LOGE("%s: init accel after config failed", __func__); - goto INIT_EXIT; - } - - HDF_LOGI("%s: init accel driver success", __func__); - return HDF_SUCCESS; - -INIT_EXIT: - DestroySensorThread(&drvData->thread, &drvData->threadStatus); - (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); -REG_CONFIG_EXIT: - ReleaseSensorAllRegConfig(drvData->accelCfg); - (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); -DETECT_CHIP_EXIT: - drvData->detectFlag = false; -BASE_CONFIG_EXIT: - drvData->accelCfg->root = NULL; - drvData->accelCfg->regCfgGroup = NULL; - OsalMemFree(drvData->accelCfg); - drvData->accelCfg = NULL; - return HDF_FAILURE; -} - -/* 释放驱动初始化时分配的资源 */ -void ReleaseAccelDriver(struct HdfDeviceObject *device) -{ - (void)device; - struct AccelDrvData *drvData = NULL; - - drvData = AccelGetDrvData(); - (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus); - (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); - drvData->detectFlag = false; - - if (drvData->accelCfg != NULL) { - drvData->accelCfg->root = NULL; - drvData->accelCfg->regCfgGroup = NULL; - ReleaseSensorAllRegConfig(drvData->accelCfg); - (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); - OsalMemFree(drvData->accelCfg); - drvData->accelCfg = NULL; - } - - drvData->initStatus = false; -} -``` - -1. 加速度计传感器寄存器组配置信息 - -加速度计传感器数据配置只需要按照模板配置即可,基于模板配置的解析功能已经在**InitSensorConfigData**函数完成,只需初始化时调用即可。如果有新增配置项,需要同步修改此函数。 - -``` -加速度传感器数据配置模板(accel_config.hcs) -root { - sensorAccelConfig { - accelChipConfig { - /* 传感器设备信息模板 */ - template sensorInfo { - sensorName = "accelerometer"; /* 加速度计名字,字符最大长度16字节 */ - vendorName = "borsh_bmi160"; /* 传感器设备厂商,字符最大长度16字节 */ - firmwareVersion = "1.0"; /* 传感器固件版本号,默认1.0,字符最大长度16字节 */ - hardwareVersion = "1.0"; /* 传感器硬件版本号,默认1.0,字符最大长度16字节 */ - sensorTypeId = 1; /* 传感器类型编号,详见{@link SensorTypeTag} */ - sensorId = 1; /* 传感器的标识号,有传感器驱动开发者定义,推荐用{@link SensorTypeTag}枚举 */ - maxRange = 8; /* 传感器的最大量程,根据开发者需要配置 */ - precision = 0; /* 传感器的精度,与上报数据配合使用,上报数据结构体{@link SensorEvents } */ - power = 230; /* 传感器的功耗 */ - } - /* 传感器使用的总线类型和配置信息模板 */ - template sensorBusConfig { - busType = 0; /* 0:i2c 1:spi */ - busNum = 6; /* 芯片上分配给传感器的器件号 */ - busAddr = 0; /* 芯片上分配给传感器的地址 */ - regWidth = 1; /* 传感器寄存器地址宽度 */ - regBigEndian = 0; /* 传感器寄存器大小端 */ - } - /* 传感器设备属性模板 */ - template sensorAttr { - chipName = ""; /* 传感器芯片名字 */ - chipIdRegister = 0xf; /* 传感器在位检测寄存器地址 */ - chipIdValue = 0xd1; /* 校验传感器在位检测寄存器值 */ - } - } - } -} - -/* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */ -root { - sensorAccelConfig { - accel_bmi160_chip_config : accelChipConfig { - match_attr = "hdf_sensor_accel_driver"; /* 需要和加速度传感器设备配置match_attr字段保持一致 */ - accelInfo :: sensorInfo { - vendorName = "borsh_bmi160"; - sensorTypeId = 1; - sensorId = 1; - } - accelBusConfig :: sensorBusConfig { - busType = 0; /* i2c通讯方式 */ - busNum = 6; - busAddr = 0x68; - regWidth = 1; /* 1字节位宽 */ - } - accelAttr :: sensorAttr { - chipName = "bmi160"; - chipIdRegister = 0x00; - chipIdValue = 0xd1; - } - accelRegConfig { - /* regAddr: 寄存器地址 - value: 寄存器值 - mask: 寄存器值的掩码 - len: 寄存器值的数据长度(字节) - delay: 配置寄存器延时(ms) - opsType:操作类型 0-无 1-读 2-写 3-读并检查 4-位更新 - calType: 计算类型 0-无 1-写 2-取反 3-异或 4-左移 5-右移 - shiftNum: 移动位数 - debug: 调试开关,0-调试关闭 1-调试打开 - save: 保存数据开关,0-不保存数据 1-保存数据 - */ - /* 传感器寄存器操作分组,按照分组进行有序配置 */ - /* 寄存器地址, 寄存器值, 寄存器值的掩码, 寄存器值的数据长度, 配置寄存器延时, 操作类型, 计算类型, 移动位数, 调试开关, 保存开关 */ - /* 初始化寄存器组 */ - initSeqConfig = [ - 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0, - 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 - ]; - /* 使能寄存器组 */ - enableSeqConfig = [ - 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0, - 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0, - 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0 - ]; - /* 去使能寄存器组 */ - disableSeqConfig = [ - 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 - ]; - } - } - } -} -``` - -1. 加速度计传感器驱动操作接口实现 - -开发者需要根据每种类型的传感器实现归一化接口。 - -``` -/* 不使用函数暂时置空 */ -static int32_t SetAccelInfo(struct SensorBasicInfo *info) -{ - (void)info; - - return HDF_ERR_NOT_SUPPORT; -} -/* 下发使能寄存器组的配置 */ -static int32_t SetAccelEnable(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor disable config failed", __func__); - return HDF_FAILURE; - } - - drvData->threadStatus = SENSOR_THREAD_RUNNING; - - return HDF_SUCCESS; -} -/* 下发去使能寄存器组的配置 */ -static int32_t SetAccelDisable(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - - ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor disable config failed", __func__); - return HDF_FAILURE; - } - - drvData->threadStatus = SENSOR_THREAD_STOPPED; - - return HDF_SUCCESS; -} -/* 配置传感器采样率和数据上报间隔 */ -static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval) -{ - (void)interval; - - struct AccelDrvData *drvData = AccelGetDrvData(); - drvData->interval = samplingInterval; - - return HDF_SUCCESS; -} -/* 设置传感器工作模式,当前支持实时模式 */ -static int32_t SetAccelMode(int32_t mode) -{ - return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE; -} -/* 设置传感器可选配置 */ -static int32_t SetAccelOption(uint32_t option) -{ - (void)option; - return HDF_ERR_NOT_SUPPORT; -} -``` - -- 差异化处理接口 - - ``` - /* 器件探测时,如果探测成功,则注册差异化处理函数到accel驱动模型里 */ - int32_t DetectAccelBim160Chip(struct SensorCfgData *data) - { - int32_t ret; - struct AccelOpsCall ops; - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - - if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) { - return HDF_SUCCESS; - } - ret = InitAccelPreConfig(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: init BMI160 bus mux config", __func__); - return HDF_FAILURE; - } - if (DetectSensorDevice(data) != HDF_SUCCESS) { - return HDF_FAILURE; - } - - /* 差异化处理函数 */ - ops.Init = InitBmi160; - ops.ReadData = ReadBmi160Data; - ret = RegisterAccelChipOps(&ops); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: register BMI160 accel failed", __func__); - (void)ReleaseSensorBusHandle(&data->busCfg); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - /* 初始化处理函数 */ - static int32_t InitBmi160(struct SensorCfgData *data) - { - int32_t ret; - - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: bmi160 sensor init config failed", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - /* 数据处理函数 */ - int32_t ReadBmi160Data(struct SensorCfgData *data) - { - int32_t ret; - struct AccelData rawData = { 0, 0, 0 }; - int32_t tmp[ACCEL_AXIS_NUM]; - struct SensorReportEvent event; - - (void)memset_s(&event, sizeof(event), 0, sizeof(event)); - - ret = ReadBmi160RawData(data, &rawData, &event.timestamp); - if (ret != HDF_SUCCESS) { - return HDF_FAILURE; - } - - event.sensorId = SENSOR_TAG_ACCELEROMETER; - event.option = 0; - event.mode = SENSOR_WORK_MODE_REALTIME; - - rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G; - rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G; - rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G; - - tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - - event.dataLen = sizeof(tmp); - event.data = (uint8_t *)&tmp; - ret = ReportSensorEvent(&event); - return ret; - } - ``` - -- 数据处理函数 - -创建传感器定时器,按照配置的采样率定时采样,并上报给数据订阅者。 - -``` -/* 传感器定时工作线程 */ -static int32_t ReadAccelDataThreadWorker(void *arg) -{ - (void)arg; - int64_t interval; - struct AccelDrvData *drvData = AccelGetDrvData(); - - drvData->threadStatus = SENSOR_THREAD_START; - while (true) { - if (drvData->threadStatus == SENSOR_THREAD_RUNNING) { - if (drvData->ops.ReadData != NULL) { - (void)drvData->ops.ReadData(drvData->accelCfg); - } - interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT)); - OsalMSleep(interval); - } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) { - break; - } else { - OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT); - } - - if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) { - continue; - } - } - - return HDF_SUCCESS; -} -/* 创建传感器定时器和器件初始化 */ -static int32_t InitAccelConfig(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) { - HDF_LOGE("%s: accel thread have created", __func__); - return HDF_SUCCESS; - } - - ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel create thread failed", __func__); - drvData->threadStatus = SENSOR_THREAD_NONE; - return HDF_FAILURE; - } - - CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM); - - ret = drvData->ops.Init(drvData->accelCfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel create thread failed", __func__); - drvData->threadStatus = SENSOR_THREAD_NONE; - return HDF_FAILURE; - } - drvData->initStatus = true; - return HDF_SUCCESS; -} -``` - -- 主要的数据结构 - -``` -/* 传感器转换单位*/ -#define SENSOR_CONVERT_UNIT 1000 -#define SENSOR_1K_UNIT 1024 -/* 传感器2g对应灵敏度转换值 */ -#define BMI160_ACC_SENSITIVITY_2G 61 -/* 传感器数据采样寄存器地址 */ -#define BMI160_ACCEL_X_LSB_ADDR 0X12 -#define BMI160_ACCEL_X_MSB_ADDR 0X13 -#define BMI160_ACCEL_Y_LSB_ADDR 0X14 -#define BMI160_ACCEL_Y_MSB_ADDR 0X15 -#define BMI160_ACCEL_Z_LSB_ADDR 0X16 -#define BMI160_ACCEL_Z_MSB_ADDR 0X17 -/* 传感器数据维度 */ -enum AccelAxisNum { - ACCEL_X_AXIS = 0, - ACCEL_Y_AXIS = 1, - ACCEL_Z_AXIS = 2, - ACCEL_AXIS_NUM = 3, -}; -/* 传感器每个维度值 */ -struct AccelData { - int32_t x; - int32_t y; - int32_t z; -}; -/* 传感器私有数据结构体 */ -struct AccelDrvData { - bool detectFlag; - uint8_t threadStatus; - uint8_t initStatus; - int64_t interval; - struct SensorCfgData *accelCfg; - struct OsalThread thread; - struct AccelOpsCall ops; -}; -/* 差异化适配函数 */ -struct AccelOpsCall { - int32_t (*Init)(struct SensorCfgData *data); - int32_t (*ReadData)(struct SensorCfgData *data); -}; -``` - diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index a544f96506316543a7c9444cc156b80d2f366e7c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,16 +0,0 @@ -# 传感器驱动开发指导 - -- [开发步骤](#section18816105182315) - -Sensor驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同Sensor器件提供统一的驱动模型。本篇开发指导以加速度计传感器为例,介绍传感器驱动开发。 - -## 开发步骤 - -1. 加速度计传感器驱动注册。HDF驱动框架会提供统一的驱动管理模型,通过加速计传感器模块配置信息,识别并加载对应模块驱动。 -2. 加速度计传感器驱动初始化和去初始化。HDF驱动框架通过init入口函数,依次启动传感器设备驱动加载和分配传感器设备数据配置资源。HDF驱动框架通过release函数,释放驱动加载的资源和配置。 -3. 加速度计传感器寄存器组配置解析。不同类型传感器需要在hcs里配置器件对应的HCS配置文件,然后再设备驱动启动过程中探测器件是否在位,然后加载对应的配置文件,生成配置的结构体对象。 -4. 加速度计传感器驱动操作接口实现。实现各个类型传感器归一化驱动接口,如init,GetInfo,Enable,Disable,SetBatch,SetMode,SetOption,ReadSensorData等函数,完成传感器驱动配置下发和数据上报功能。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->传感器驱动模型已经提供一部分能力集,包括驱动设备管理能力,抽象总线和平台操作接口能力,通用配置操作接口能力,配置解析操作接口能力,接口参考[表2](传感器驱动开发概述.md#table1156812588320)。需要开发人员实现部分有:1、传感器部分操作接口([表3](传感器驱动开发概述.md#table1083014911336));2、传感器HCS差异化数据配置;3、驱动基本功能验证。 - diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index 6319a9086c6c8754c6a8d36cf9abc7827d24e20b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,244 +0,0 @@ -# 传感器驱动开发概述 - -- [简介](#section667413271505) -- [接口说明](#section7255104114110) - -## 简介 - -Sensor(传感器)驱动模块为上层Sensor服务系统提供稳定的Sensor基础能力API,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置等功能;基于HDF(**H**ardware **D**river **F**oundation)驱动框架开发的Sensor驱动模型,实现跨操作系统迁移,器件差异配置等功能。Sensor驱动模型如下图1所示: - -**图 1** Sensor驱动模型图 -![](figures/Sensor驱动模型图.png "Sensor驱动模型图") - -Sensor驱动模型对外开放的API接口能力如下: - -- 提供Sensor HDI(**H**ardware **D**river **I**nterface)能力接口,简化服务开发。 -- 提供Sensor驱动模型能力接口:依赖HDF驱动框架实现Sensor器件驱动的注册,加载,去注册,器件探测等能力,提供同一类型Sensor器件驱动归一接口, 寄存器配置解析操作接口,总线访问抽象接口,平台抽象接口。 -- 提供开发者实现的能力接口:依赖HDF驱动框架的HCS\(**H**DF **C**onfiguration **S**ource\)配置管理,根据同类型Sensor差异化配置,实现Sensor器件参数序列化配置和器件部分操作接口,简化Sensor器件驱动开发。 - -## 接口说明 - -Sensor驱动模型对HDI开放的API接口功能,参考表1。 - -**表 1** Sensor驱动模型对外API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

功能描述

-

查询操作

-

int32_t GetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)

-

获取系统中注册的所有传感器信息,一种类型传感器信息包括传感器名字、设备厂商、固件版本号、硬件版本号、传感器类型编号、传感器标识、最大量程、精度、功耗。

-

配置操作

-

int32_t Enable(int32_t sensorId)

-

使能一种传感器设备,只有数据订阅者使能传感器后,才能获取订阅的传感器数据。

-

int32_t Disable(int32_t sensorId)

-

去使能一种传感器设备。

-

int32_t SetBatch(iint32_t sensorId, int64_t samplingInterval, int64_t reportInterval)

-

设置一种传感器的数据采样间隔和数据上报间隔。

-

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

-

设置一种传感器的工作模式,不同的工作模式,上报数据方式不同。

-

int32_t SetOption(int32_t sensorId, uint32_t option)

-

设置一种传感器量程,精度等可选配置。

-

数据订阅操作

-

int32_t Register(RecordDataCallback cb)

-

订阅者注册传感器数据回调函数,系统会将获取到的传感器数据上报给订阅者。

-

int32_t Unregister(void)

-

订阅者去注册传感器数据回调函数。

-

接口实例

-

const struct SensorInterface *NewSensorInterfaceInstance(void)

-

创建传感器接口实例。

-

int32_t FreeSensorInterfaceInstance(void)

-

释放传感器接口实例。

-
- -Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无需实现,直接使用,参考表2: - -**表 2** Sensor驱动模型对驱动开发者开放的功能接口列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

功能描述

-

设备管理操作接口

-

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

-

添加当前类型的传感器设备到传感器设备管理。

-

int32_t DeleteSensorDevice(int32_t sensorId)

-

删除传感器设备管理里指定的传感器设备。

-

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

-

上报指定类型传感器的数据到用户侧。

-

Sensor抽象总线和平台操作接口

-

int32_t ReadSensor(struct SensorBusCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen)

-

按照配置的总线方式,读取传感器寄存器配置数据。

-

int32_t WriteSensor(struct SensorBusCfg *busCfg, uint8_t *writeData, uint16_t len)

-

按照配置的总线方式,传感器配置数据写入寄存器。

-

int32_t CreateSensorThread(struct OsalThread *thread, OsalThreadEntry threadEntry, char *name, void *entryPara)

-

创建指定传感器的定时线程,用于传感器数据上报处理。

-

void DestroySensorThread(struct OsalThread *thread, uint8_t *status);

-

销毁传感器创建的定时线程。

-

通用配置操作接口

-

int32_t SetSensorRegCfgArray(struct SensorBusCfg *busCfg, const struct SensorRegCfgGroupNode *group);

-

根据传感器总线类型信息,下发寄存器分组配置。

-

配置解析操作接口

-

-

int32_t GetSensorBaseConfigData(const struct DeviceResourceNode *node, struct SensorCfgData *config)

-

根据传感器设备HCS资源配置,获取传感器信息,总线配置信息,属性配置等基本配置信息,并初始化对应的基本配置数据结构体。

-

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

-

根据传感器设备HCS资源配置,解析寄存器分组信息,并初始化配置数据结构体。

-

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

-

释放传感器配置数据结构体里分配的资源。

-

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

-

获取传感器总线句柄信息。

-

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

-

释放传感器句柄信息。

-
- -Sensor驱动模型要求驱动开发者实现的接口功能,参考表3 - -**表 3** Sensor驱动模型要求驱动开发者实现的接口列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

功能描述

-

基本功能操作

-

int32_t init(void)

-

传感器器设备探测成功后,需要对传感器器设备初始化配置。

-

int32_t GetInfo(struct SensorBasicInfo *info)

-

从传感器器设备的HCS配置里,获取当前传感器设备的基本信息。

-

int32_t Enable(void)

-

根据当前传感器器设备的HCS配置,下发传感器设备使能操作组的寄存器配置。

-

int32_t Disable(void)

-

根据当前传感器器设备的HCS配置,下发传感器设备去使能操作组的寄存器配置。

-

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

-

根据数据采样率和数据上报间隔,配置当前传感器设备的数据上报线程处理时间。

-

int32_t SetMode(int32_t mode)

-

配置当前传感器设备数据上报方式。

-

int32_t SetOption(uint32_t option)

-

根据可选配置,下发量程,精度等寄存器配置。

-

void ReadSensorData(void)

-

实现传感器的数据读取函数。

-
- -接口实现参考[SENSOR](传感器驱动开发实例.md)章节。 - diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\346\265\213\350\257\225\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\346\265\213\350\257\225\346\214\207\345\257\274.md" deleted file mode 100755 index 7bf51251601d13df14cc81398af44c826228f2d9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\346\265\213\350\257\225\346\214\207\345\257\274.md" +++ /dev/null @@ -1,82 +0,0 @@ -# 传感器驱动测试指导 - -驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 - -``` -/* 标识是否上报传感器数据 */ -static int32_t g_sensorDataFlag = 0; -/* 保持获取的传感器接口实例地址 */ -static const struct SensorInterface *g_sensorDev = nullptr; - -/* 订阅者注册数据上报函数 */ -static int SensorTestDataCallback(struct SensorEvents *event) -{ - if (event == nullptr) { - return -1; - } - float *data = (float*)event->data; - printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, - event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); - if (*data > 1e-5) { - g_sensorDataFlag = 1; - } - return 0; -} -/* 用例执行前,初始化传感器接口实例 */ -void HdfSensorTest::SetUpTestCase() -{ - g_sensorDev = NewSensorInterfaceInstance(); - if (g_sensorDev == nullptr) { - printf("test sensorHdi get Module instace failed\n\r"); - } -} -/* 用例资源释放 */ -void HdfSensorTest::TearDownTestCase() -{ - if (g_sensorDev != nullptr) { - FreeSensorInterfaceInstance(); - g_sensorDev = nullptr; - } -} -/* 传感器驱动测试验证 */ -HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) -{ - int32_t sensorInterval = 1000000000; /* 数据采样率单位纳秒 */ - int32_t pollTime = 5; /* 数据采样时间单位秒 */ - int32_t accelSensorId = 1; /* 加速度传感器类型标识为1 */ - int32_t count = 0; - int ret; - struct SensorInformation *sensorInfo = nullptr; - - ret = g_sensorDev->Register(SensorTestDataCallback) - EXPECT_EQ(SENSOR_NULL_PTR, ret); - - ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); - EXPECT_EQ(0, ret); - if (sensorInfo == nullptr) { - EXPECT_NE(nullptr, sensorInfo); - return; - } - /* 打印获取的传感器列表 */ - for (int i = 0; i < count; i++) { - printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); - } - ret = g_sensorDev->Enable(accelSensorId); - EXPECT_EQ(0, ret); - g_sensorDataFlag = 0; - - ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); - EXPECT_EQ(0, ret); - /* 在时间pollTime内,观察输出打印数据 */ - OsalSleep(pollTime); - EXPECT_EQ(1, g_sensorDataFlag); - - ret = g_sensorDev->Disable(accelSensorId); - g_sensorDataFlag = 0; - EXPECT_EQ(0, ret); - - ret = g_sensorDev->Unregister(); - EXPECT_EQ(0, ret); -} -``` - diff --git "a/zh-cn/device-dev/driver/\345\244\226\350\256\276.md" "b/zh-cn/device-dev/driver/\345\244\226\350\256\276.md" deleted file mode 100755 index 26824613db5c020fc05e256f6b6aca62f34cbc47..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\345\244\226\350\256\276.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 外设 - -- **[LCD](LCD.md)** - -- **[TOUCHSCREEN](TOUCHSCREEN.md)** - -- **[SENSOR](SENSOR.md)** - -- **[WLAN](WLAN.md)** - - diff --git "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index b8d64e53b754037b4ec6335e683f32bfbd1b6a34..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,86 +0,0 @@ -# 看门狗使用实例 - -本例程提供看门狗的完整使用流程。 - -在本例程中,我们打开一个看门狗设备,设置超时时间并启动计时: - -- 首先定期喂狗,即按时清除看门狗定时器,确保系统不会因定时器超时而复位。 -- 接着再停止喂狗,观察定时器到期后系统是否发生复位行为。 - -示例如下: - -``` -#include "watchdog_if.h" -#include "hdf_log.h" -#include "osal_irq.h" -#include "osal_time.h" - -#define WATCHDOG_TEST_TIMEOUT 2 -#define WATCHDOG_TEST_FEED_TIME 6 - -static int32_t TestCaseWatchdog(void) -{ - int32_t i; - int32_t ret; - uint32_t timeout; - DevHandle handle = NULL; - - /* 打开0号看门狗设备 */ - handle = WatchdogOpen(0); - if (handle == NULL) { - HDF_LOGE("Open watchdog fail!"); - return -1; - } - - /* 设置超时时间 */ - ret = WatchdogSetTimeout(handle, WATCHDOG_TEST_TIMEOUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set timeout fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - - /* 回读设置的超时时间值 */ - ret = WatchdogGetTimeout(handle, &timeout); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); - - /* 启动看门狗,开始计时 */ - ret = WatchdogStart(handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - - /* 每隔1S喂狗一次 */ - for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { - HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); - ret = WatchdogFeed(handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - OsalSleep(1); - } - /* 由于喂狗间隔小于超时时间,系统不会发生复位,此日志可以正常打印 */ - HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); - - /* 接下来持续不喂狗,使得看门狗计时器超时 */ - for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { - HDF_LOGE("%s: watiting dog buck %d times... \n", __func__, i); - OsalSleep(1); - } - - /* 当不喂狗时间到达之前设定的超时时间的时候,系统会发生复位,理论上观察不到此日志的打印 */ - HDF_LOGE("%s: dog has't buck!!! \n", __func__, i); - WatchdogClose(handle); - return -1; -} -``` - diff --git "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index b8fd5753d462e8fd80df1f64d6d757d385d3998f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,391 +0,0 @@ -# 看门狗使用指导 - -- [使用流程](#section0719414187) -- [打开看门狗设备](#section198171379261) -- [获取看门狗状态](#section206592910275) -- [设置超时时间](#section19605128182714) -- [获取超时时间](#section11111516208) -- [启动看门狗](#section141174192814) -- [喂狗](#section179101435113910) -- [停止看门狗](#section15282123192816) -- [关闭看门狗设备](#section7857850173411) - -## 使用流程 - -使用看门狗的一般流程如[图1](#fig19134125410189)所示。 - -**图 1** 看门狗使用流程图 - - -![](figures/zh-cn_image_0000001057622716.png) - -## 打开看门狗设备 - -在操作看门狗之前,需要使用WatchdogOpen打开一个看门狗设备,一个系统可能有多个看门狗,通过ID号来打开指定的看门狗设备: - -int32\_t WatchdogOpen\(int16\_t wdtId\); - -**表 1** WatchdogOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

wdtId

-

看门狗设备号

-

返回值

-

返回值描述

-

NULL

-

打开失败

-

DevHandle类型指针

-

看门狗设备句柄

-
- -``` -DevHandle handle = NULL; -handle = WatchdogOpen(0); /* 打开0号看门狗设备 */ -if (handle == NULL) { - HDF_LOGE("WatchdogOpen: failed, ret %d\n", ret); - return; -} -``` - -## 获取看门狗状态 - -int32\_t WatchdogGetStatus\(DevHandle handle, int32\_t \*status\); - -**表 2** WatchdogGetStatus参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

status

-

获取到的启动状态指针

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -int32_t status; -/* 获取Watchdog启动状态 */ -ret = WatchdogGetStatus(handle, &status); -if (ret != 0) { - HDF_LOGE("WatchdogGetStatus: failed, ret %d\n", ret); - return; -} -``` - -## 设置超时时间 - -int32\_t WatchdogSetTimeout\(PalHandle \*handle, uint32\_t seconds\); - -**表 3** WatchdogSetTimeout参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

seconds

-

超时时间,单位为秒

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- -``` -int32_t ret; -uint32_t timeOut = 60; -/* 设置超时时间,单位:秒 */ -ret = WatchdogSetTimeout(handle, timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogSetTimeout: failed, ret %d\n", ret); - return; -} -``` - -## 获取超时时间 - -int32\_t WatchdogGetTimeout\(PalHandle \*handle, uint32\_t \*seconds\); - -**表 4** WatchdogGetTimeout参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

seconds

-

接收超时时间的指针,单位为秒

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -uint32_t timeOut; -/* 获取超时时间,单位:秒 */ -ret = WatchdogGetTimeout(handle, &timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogGetTimeout: failed, ret %d\n", ret); - return; -} -``` - -## 启动看门狗 - -int32\_t WatchdogStart\(DevHandle handle\); - -**表 5** WatchdogStart参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

返回值

-

返回值描述

-

0

-

启动成功

-

负数

-

启动失败

-
- -``` -int32_t ret; -/* 启动看门狗 */ -ret = WatchdogStart(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStart: failed, ret %d\n", ret); - return; -} -``` - -## 喂狗 - -int32\_t WatchdogFeed\(DevHandle handle\); - -**表 6** WatchdogFeed参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

返回值

-

返回值描述

-

0

-

喂狗成功

-

负数

-

喂狗失败

-
- -``` -int32_t ret; -/* 喂狗 */ -ret = WatchdogFeed(handle); -if (ret != 0) { - HDF_LOGE("WatchdogFeed: failed, ret %d\n", ret); - return; -} -``` - -## 停止看门狗 - -int32\_t WatchdogStop\(DevHandle handle\); - -**表 7** WatchdogStop参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

返回值

-

返回值描述

-

0

-

停止成功

-

负数

-

停止失败

-
- -``` -int32_t ret; -/* 停止看门狗 */ -ret = WatchdogStop(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStop: failed, ret %d\n", ret); - return; -} - -``` - -## 关闭看门狗设备 - -当操作完毕时,使用WatchdogClose关闭打开的设备句柄: - -void WatchdogClose\(DevHandle handle\); - -**表 8** WatchdogClose参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-
- -``` -/* 关闭看门狗 */ -ret = WatchdogClose(handle); -``` - diff --git "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\346\246\202\350\277\260.md" deleted file mode 100755 index 467e21ba08ef672247327cd100b8c2db7e4f9a01..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\346\246\202\350\277\260.md" +++ /dev/null @@ -1,78 +0,0 @@ -# 看门狗概述 - -- [简介](#section3579126111816) -- [接口说明](#section17429111981812) - -## 简介 - -看门狗(watchdog),又叫看门狗计时器(watchdog timer),是一种硬件的计时设备,当系统的主程序发生某些错误时,导致未及时清除看门狗计时器的计时值,这时看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。 - -## 接口说明 - -**表 1** 看门狗 API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

打开/关闭看门狗

-

WatchdogOpen

-

打开看门狗设备

-

WatchdogClose

-

关闭看门狗设备

-

启动/停止看门狗

-

WatchdogStart

-

启动看门狗

-

WatchdogStop

-

停止看门狗

-

设置/获取超时时间

-

WatchdogSetTimeout

-

设置看门狗超时时间

-

WatchdogGetTimeout

-

获取看门狗超时时间

-

获取看门狗状态

-

WatchdogGetStatus

-

获取看门狗状态

-

清除看门狗定时器

-

WatchdogFeed

-

清除看门狗定时器(喂狗)

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及看门狗的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git "a/zh-cn/device-dev/driver/\351\205\215\347\275\256\347\256\241\347\220\206.md" "b/zh-cn/device-dev/driver/\351\205\215\347\275\256\347\256\241\347\220\206.md" deleted file mode 100755 index 3fd2a0701a9c5e9f734021d7520e773f8c5e136e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\351\205\215\347\275\256\347\256\241\347\220\206.md" +++ /dev/null @@ -1,437 +0,0 @@ -# 配置管理 - -- [配置概述](#section59914284576) -- [配置语法](#section533713333580) -- [关键字](#section1316625413586) -- [基本结构](#section173481622115918) -- [数据类型](#section96521601302) -- [预处理](#section8164295515) -- [注释](#section0338205819610) -- [引用修改](#section179799204716) -- [节点复制](#section382424014712) -- [删除](#section165211112586) -- [属性引用](#section192841514490) -- [模板](#section520134294) -- [配置生成](#section106152531919) -- [hc-gen介绍](#section8260625101012) - -## 配置概述 - -HCS\(**H**DF **C**onfiguration **S**ource\)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。 - -HC-GEN**\(H**DF **C**onfiguration **G**enerator**\)**是HCS配置转换工具,可以将HDF配置文件转换为软件可读取的文件格式: - -- 在弱性能环境中,转换为配置树源码,驱动可直接调用C代码获取配置。 -- 在高性能环境中,转换为HCB\(**H**DF **C**onfiguration **B**inary\)二进制文件,驱动可使用HDF框架提供的配置解析接口获取配置。 - -以下是使用HCB模式的典型应用场景: - -**图 1** 配置使用流程图 - - -![](figures/zh-cn_image_0000001053405727.png) - -HCS经过HC-GEN编译生成HCB文件,HDF驱动框架中的HCS Parser模块会从HCB文件中重建配置树,HDF驱动模块使用HCS Parser提供的配置读取接口获取配置内容。 - -## 配置语法 - -HCS的语法介绍如下: - -## 关键字 - -HCS配置语法保留了以下关键字。 - -**表 1** HCS配置语法保留关键字 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

关键字

-

用途

-

说明

-

root

-

配置根节点

-

-

-

include

-

引用其他HCS配置文件

-

-

-

delete

-

删除节点或属性

-

只能用于操作include导入的配置树

-

template

-

定义模板节点

-

-

-

match_attr

-

用于标记节点的匹配查找属性

-

解析配置时可以使用该属性的值查找到对应节点

-
- -## 基本结构 - -HCS主要分为属性\(Attribute\)和节点\(Node\)两种结构。 - -**属性** - -属性即最小的配置单元,是一个独立的配置项。语法如下: - -``` - attribute_name = value; -``` - -- attribute\_name 是**字母、数字、下划线**的组合且必须以字母或下划线开头,字母区分大小写。 - -- value的可用格式如下: - - - 数字常量,支持二进制、八进制、十进制、十六进制数,具体参考数据类型节。 - - - 字符串,内容使用双引号\(""\)引用。 - - - 节点引用。 - - -- attribute 必须以分号\(;\)结束且必须属于一个node。 - - -**节点** - -节点是一组属性的集合,语法如下: - -``` - node_name { - module = "sample"; - ... - } -``` - -- node\_name 是**字母、数字、下划线**的组合且必须以字母或下划线开头,字母区分大小写。 - -- 大括号后无需添加结束符“;”。 - -- root为保留关键字,用于声明配置表的根节点。每个配置表必须以root节点开始。 - -- root节点中必须包含module属性,其值应该为一个字符串,用于表征该配置所属模块。 - -- 节点中可以增加match\_attr属性,其值为一个全局唯一的字符串。在解析配置时可以调用查找接口以该属性的值查找到包含该属性的节点。 - -## 数据类型 - -在属性定义中使用自动数据类型,不显式指定类型,属性支持的数据类型如下: - -**整型** - -整型长度自动推断,根据实际数据长度给与最小空间占用的类型。 - -- 二进制,0b前缀,示例:0b1010。 - -- 八进制,0前缀,示例:0664。 -- 十进制 ,无前缀,且支持有符号与无符号,示例:1024,+1024均合法。负值在读取时注意使用有符号数读取接口。 - -- 十六进制,0x前缀,示例:0xff00、0xFF。 - - -**字符串** - -字符串使用双引号\(""\)表示。 - -**数组** - -数组元素支持整型、字符串,不支持混合类型。整型数组中uint32\_t uint64\_t混用会向上转型为uint64\_t 数组。整型数组与字符串数组示例如下: - -``` -attr_foo = [0x01, 0x02, 0x03, 0x04]; -attr_bar = ["hello", "world"]; -``` - -**bool类型** - -bool类型中**true**表示真,**false**表示假。 - -## 预处理 - -**include** - -用于导入其他HCS文件。语法示例如下: - -``` -#include "foo.hcs" -#include "../bar.hcs" -``` - -- 文件名必须使用双引号\(""\),不在同一目录使用相对路径引用。被include文件也必须是合法的HCS文件。 -- 多个include,如果存在相同的节点,后者覆盖前者,其余的节点依次展开。 - -## 注释 - -支持两种注释风格。 - -- 单行注释。 - - ``` - // comment - ``` - -- 多行注释。 - - ``` - /* - comment - */ - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >多行注释不支持嵌套。 - - -## 引用修改 - -引用修改可以实现修改另外任意一个节点的内容,语法为: - -``` - node :& source_node -``` - -上述语句表示node中的内容是对source\_node节点内容的修改。示例如下: - -``` -root { - module = "sample"; - foo { - foo_ :& root.bar{ - attr = "foo"; - } - foo1 :& foo2 { - attr = 0x2; - } - foo2 { - attr = 0x1; - } - } - - bar { - attr = "bar"; - } -} -``` - -最终生成配置树为: - -``` -root { - module = "sample"; - foo { - foo2 { - attr = 0x2; - } - } - bar { - attr = "foo"; - } -} -``` - -在以上示例中,可以看到foo.foo\_节点通过引用将bar.attr属性的值修改为了"foo",foo.foo1节点通过引用将foo.foo2.attr属性的值修改为了0x2。foo.foo\_以及foo.foo1节点表示对目标节点内容的修改,其自身并不会存在最终生成的配置树中。 - -- 引用同级node,可以直接使用node名称,否则被引用的节点必须使用绝对路径,节点间使用“.”分隔,root表示根节点,格式为root开始的节点路径序列,例如root.foo.bar即为一个合法的绝对路径。 -- 如果出现修改冲突(即多处修改同一个属性),编译器将提示warning,因为这种情况下只会生效某一个修改而导致最终结果不确定。 - -## 节点复制 - -节点复制可以实现在节点定义时从另一个节点先复制内容,用于定义内容相似的节点。语法为: - -``` - node : source_node -``` - -上述语句表示在定义"node"节点时将另一个节点"source\_node"的属性复制过来。示例如下: - -``` -root { - module = "sample"; - foo { - attr_0 = 0x0; - } - bar:foo { - attr_1 = 0x1; - } -} -``` - -上述代码的最终生成配置树为: - -``` -root { - module = "sample"; - foo { - attr_0 = 0x0; - } - bar { - attr_1 = 0x1; - attr_0 = 0x0; - } -} -``` - -在上述示例中,编译后bar节点即包含attr\_0属性也包含attr\_1属性,在bar中对attr\_0的修改不会影响到foo。 - -在foo和bar在同级node中可不指定foo的路径,否则需要使用绝对路径引用,参考[引用修改](#section179799204716)。 - -## 删除 - -要对include导入的base配置树中不需要的节点或属性进行删除,可以使用delete关键字。下面的举例中sample1.hcs通过include导入了sample2.hcs中的配置内容,并使用delete删除了sample2.hcs中的attribute2属性和foo\_2节点,示例如下: - -``` -// sample2.hcs -root { - attr_1 = 0x1; - attr_2 = 0x2; - foo_2 { - t = 0x1; - } -} - -// sample1.hcs -#include "sample2.hcs" -root { - attr_2 = delete; - foo_2 : delete { - } -} -``` - -上述代码在生成过程中将会删除root.foo\_2节点与attr\_2,最终生成配置树为: - -``` -root { - attr_1 = 0x1; -} -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->在同一个HCS文件中不允许使用delete,建议直接删除不需要的属性。 - -## 属性引用 - -为了在解析配置时快速定位到关联的节点,可以把节点作为属性的右值,通过读取属性查找到对应节点。语法为: - -``` - attribute = &node; -``` - -上述语句表示attribute的值是一个节点node的引用,在解析时可以用这个attribute快速定位到node,便于关联和查询其他node。示例如下: - -``` -node1 { - attributes; -} - -node2 { - attr_1 = &node1; -} -``` - -## 模板 - -模板的用途在于生成严格一致的node结构,以便对同类型node进行遍历和管理。 - -使用template关键字定义模板node,子node通过双冒号“::”声明继承关系。子节点可以改写但不能新增和删除template中的属性,子节点中没有定义的属性将使用template中的定义作为默认值。示例如下: - -``` -root { - module = "sample"; - template foo { - attr_1 = 0x1; - attr_2 = 0x2; - } - - bar :: foo { - } - - bar_1 :: foo { - attr_1 = 0x2; - } -} -``` - -生成配置树如下: - -``` -root { - module = "sample"; - bar { - attr_1 = 0x1; - attr_2 = 0x2; - } - bar_1 { - attr_1 = 0x2; - attr_2 = 0x2; - } -} -``` - -在上述示例中,bar和bar\_1节点继承了foo节点,生成配置树节点结构与foo保持了完全一致,只是属性的值不同。 - -## 配置生成 - -hc-gen是配置生成的工具,可以对HCS配置语法进行检查并把HCS源文件转化成HCB二进制文件。 - -## hc-gen介绍 - -hc-gen参数说明: - -``` -Usage: hc-gen [Options] [File] -options: - -o output file name, default same as input - -a hcb align with four bytes - -b output binary output, default enable - -t output config in C language source file style - -i output binary hex dump in C language source file style - -p prefix of generated symbol name - -d decompile hcb to hcs - -V show verbose info - -v show version - -h show this help message -``` - -生成.c/.h 配置文件方法: - -``` -hc-gen -o [OutputCFileName] -t [SourceHcsFileName] -``` - -生成HCB 配置文件方法: - -``` -hc-gen -o [OutputHcbFileName] -b [SourceHcsFileName] -``` - -反编译HCB文件为HCS方法: - -``` -hc-gen -o [OutputHcsFileName] -d [SourceHcbFileName] -``` - diff --git "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\271\263\345\217\260.md" "b/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\271\263\345\217\260.md" deleted file mode 100755 index 7d5a5437f750b6c60b8b249c40c5ae1c6ab0d30b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\271\263\345\217\260.md" +++ /dev/null @@ -1,19 +0,0 @@ -# 驱动平台 - -- **[GPIO](GPIO.md)** - -- **[I2C](I2C.md)** - -- **[RTC](RTC.md)** - -- **[SDIO](SDIO.md)** - -- **[SPI](SPI.md)** - -- **[UART](UART.md)** - -- **[WATCHDOG](WATCHDOG.md)** - -- **[MIPI DSI](MIPI-DSI.md)** - - diff --git "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\274\200\345\217\221.md" "b/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\274\200\345\217\221.md" deleted file mode 100755 index e35139db59ca7df253ee0134e5afb379d596e300..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\274\200\345\217\221.md" +++ /dev/null @@ -1,175 +0,0 @@ -# 驱动开发 - -- [驱动模型介绍](#section157425168112) -- [驱动开发步骤](#section1969312275533) - -## 驱动模型介绍 - -HDF框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个host里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个node,HDF框架管理驱动模型如下图所示: - -**图 1** HDF框架管理驱动模型 - - -![](figures/zh-cn_image_0000001054564784.png) - -## 驱动开发步骤 - -基于HDF框架进行驱动的开发主要分为两个部分,驱动实现和驱动配置,详细开发流程如下所示: - -1. 驱动实现 - - 驱动实现包含驱动业务代码和驱动入口注册,具体写法如下: - - - 驱动业务代码 - - ``` - #include "hdf_device_desc.h" // HDF框架对驱动开放相关能力接口的头文件 - #include "hdf_log.h" // HDF 框架提供的日志接口头文件 - - #define HDF_LOG_TAG "sample_driver" // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签 - - //驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架 - int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver bind success"); - return 0; - } - - // 驱动自身业务初始的接口 - int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver Init success"); - return 0; - } - - // 驱动资源释放的接口 - void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver release success"); - return; - } - ``` - - - 驱动入口注册到HDF框架 - - ``` - // 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量 - struct HdfDriverEntry g_sampleDriverEntry = { - .moduleVersion = 1, - .moduleName = "sample_driver", - .Bind = HdfSampleDriverBind, - .Init = HdfSampleDriverInit, - .Release = HdfSampleDriverRelease, - }; - - // 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - HDF_INIT(g_sampleDriverEntry); - ``` - - -2. 驱动编译 - - 驱动代码的编译必须要使用HDF框架提供的Makefile模板进行编译。 - - ``` - include $(LITEOSTOPDIR)/../../drivers/adapter/lite/khdf/lite.mk #导入hdf预定义内容,必需 - MODULE_NAME := #生成的结果文件 - LOCAL_INCLUDE := #本驱动的头文件目录 - LOCAL_SRCS := #本驱动的源代码文件 - LOCAL_CFLAGS := #自定义的编译选项 - include $(HDF_DRIVER) #导入模板makefile完成编译 - ``` - - - 编译结果文件链接到内核镜像,添加到vendor目录下的hdf\_vendor.mk里面,示例如下: - - ``` - LITEOS_BASELIB += -lxxx #链接生成的静态库 - LIB_SUBDIRS += #驱动代码Makefile的目录 - ``` - - -3. 驱动配置 - - HDF使用HCS作为配置描述源码,HCS详细介绍参考[配置管理](配置管理.md)介绍。 - - 驱动配置包含两部分,HDF框架定义的驱动设备描述和驱动的私有配置信息,具体写法如下: - - - 驱动设备描述(必选) - - HDF框架加载驱动所需要的信息来源于HDF框架定义的驱动设备描述,因此基于HDF框架开发的驱动必须要在HDF框架定义的device\_info.hcs配置文件中添加对应的设备描述,驱动的设备描述填写如下所示: - - ``` - root { - device_info { - match_attr = "hdf_manager"; - template host { // host模板,继承该模板的节点(如下sample_host)如果使用模板中的默认值,则节点字段可以缺省 - hostName = ""; - priority = 100; - template device { - template deviceNode { - policy = 0; - priority = 100; - preload = 0; - permission = 0664; - moduleName = ""; - serviceName = ""; - deviceMatchAttr = ""; - } - } - } - sample_host :: host{ - hostName = "host0"; // host名称,host节点是用来存放某一类驱动的容器 - priority = 100; // host启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证host的加载顺序 - device_sample :: device { // sample设备节点 - device0 :: deviceNode { // sample驱动的DeviceNode节点 - policy = 1; // policy字段是驱动服务发布的策略,在驱动服务管理章节有详细介绍 - priority = 100; // 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 - preload = 0; // 驱动按需加载字段,在本章节最后的说明有详细介绍 - permission = 0664; // 驱动创建设备节点权限 - moduleName = "sample_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 - serviceName = "sample_service"; // 驱动对外发布服务的名称,必须唯一 - deviceMatchAttr = "sample_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 - } - } - } - } - } - ``` - - - 驱动私有配置信息(可选) - - 如果驱动有私有配置,则可以添加一个驱动的配置文件,用来填写一些驱动的默认配置信息,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init(参考[驱动开发](#li35182436435))传递给驱动,驱动的配置信息示例如下: - - ``` - root { - SampleDriverConfig { - sample_version = 1; - sample_bus = "I2C_0"; - match_attr = "sample_config"; //该字段的值必须和device_info.hcs中的deviceMatchAttr值一致 - } - } - ``` - - 配置信息定义之后,需要将该配置文件添加到板级配置入口文件hdf.hcs(这一块可以通过OpenHarmony驱动子系统在DevEco集成驱动开发套件工具一键式配置,具体使用方法参考驱动开发套件中的介绍),示例如下: - - ``` - #include "device_info/device_info.hcs" - #include "sample/sample_config.hcs" - ``` - - - ->![](public_sys-resources/icon-note.gif) **说明:** ->驱动加载方式支持按需加载和按序加载两种方式,具体使用方法如下: ->- 按需加载 -> ``` -> typedef enum { -> DEVICE_PRELOAD_ENABLE = 0, -> DEVICE_PRELOAD_ENABLE_STEP2, -> DEVICE_PRELOAD_DISABLE, -> DEVICE_PRELOAD_INVALID -> } DevicePreload; -> ``` -> 配置文件中preload 字段配成 0 (DEVICE\_PRELOAD\_ENABLE ),则系统启动过程中默认加载;配成1(DEVICE\_PRELOAD\_ENABLE\_STEP2),当系统支持快启的时候,则在系统系统完成之后再加载这一类驱动,否则和DEVICE\_PRELOAD\_ENABLE 含义相同;配成2(DEVICE\_PRELOAD\_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务(参考[消息机制](驱动消息机制管理.md))时,如果驱动服务不存在时,HDF框架会尝试动态加载该驱动。 ->- 按序加载(需要驱动为默认加载) -> 配置文件中的priority(取值范围为整数0到200)是用来表示host和驱动的优先级,不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高。 - diff --git "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\346\266\210\346\201\257\346\234\272\345\210\266\347\256\241\347\220\206.md" "b/zh-cn/device-dev/driver/\351\251\261\345\212\250\346\266\210\346\201\257\346\234\272\345\210\266\347\256\241\347\220\206.md" deleted file mode 100755 index ac271c2f1e520c0d8d1c31cf4ab5ab79ef498727..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\346\266\210\346\201\257\346\234\272\345\210\266\347\256\241\347\220\206.md" +++ /dev/null @@ -1,193 +0,0 @@ -# 驱动消息机制管理 - -- [使用场景](#section33014541954) -- [接口说明](#section538852311616) -- [开发步骤](#section946912121153) - -## 使用场景 - -当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。 - -## 接口说明 - -消息机制的功能主要有以下两种: - -1. 用户态应用发送消息到驱动。 -2. 用户态应用接收驱动主动上报事件。 - -**表 1** 消息机制接口 - - - - - - - - - - - - - - - - - - - -

方法

-

描述

-

struct HdfIoService *HdfIoServiceBind(const char *serviceName)

-

用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息。

-

void HdfIoServiceRecycle(struct HdfIoService *service);

-

释放驱动服务。

-

int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);

-

用户态程序注册接收驱动上报事件的操作方法。

-

int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);

-

驱动主动上报事件接口。

-
- -## 开发步骤 - -1. 将驱动配置信息中服务策略policy字段设置为2(SERVICE\_POLICY\_CAPACITY,参考[policy定义](驱动服务管理.md))。 - - ``` - device_sample :: Device { - policy = 2; - ... - } - ``` - -2. 配置驱动信息中的服务设备节点权限(permission字段)是框架给驱动创建设备节点的权限,默认是0666,驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。 -3. 在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。 - - ``` - // Dispatch是用来处理用户态发下来的消息 - int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) - { - HDF_LOGE("sample driver lite A dispatch"); - return 0; - } - int32_t SampleDriverBind(struct HdfDeviceObject *device) - { - HDF_LOGE("test for lite os sample driver A Open!"); - if (device == NULL) { - HDF_LOGE("test for lite os sample driver A Open failed!"); - return -1; - } - static struct ISampleDriverService sampleDriverA = { - .ioService.Dispatch = SampleDriverDispatch, - .ServiceA = SampleDriverServiceA, - .ServiceB = SampleDriverServiceB, - }; - device->service = (struct IDeviceIoService *)(&sampleDriverA); - return 0; - } - ``` - -4. 驱动定义消息处理函数中的cmd类型。 - - ``` - #define SAMPLE_WRITE_READ 1 // 读写操作码1 - ``` - -5. 用户态获取服务接口并发送消息到驱动。 - - ``` - int SendMsg(const char *testMsg) - { - if (testMsg == NULL) { - HDF_LOGE("test msg is null"); - return -1; - } - struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); - if (serv == NULL) { - HDF_LOGE("fail to get service"); - return -1; - } - struct HdfSBuf *data = HdfSBufObtainDefaultSize(); - if (data == NULL) { - HDF_LOGE("fail to obtain sbuf data"); - return -1; - } - struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); - if (reply == NULL) { - HDF_LOGE("fail to obtain sbuf reply"); - ret = HDF_DEV_ERR_NO_MEMORY; - goto out; - } - if (!HdfSbufWriteString(data, testMsg)) { - HDF_LOGE("fail to write sbuf"); - ret = HDF_FAILURE; - goto out; - } - int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); - if (ret != HDF_SUCCESS) { - HDF_LOGE("fail to send service call"); - goto out; - } - out: - HdfSBufRecycle(data); - HdfSBufRecycle(reply); - HdfIoServiceRecycle(serv); - return ret; - } - ``` - -6. 用户态接收该驱动上报的消息。 - 1. 用户态编写驱动上报消息的处理函数。 - - ``` - static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) - { - OsalTimespec time; - OsalGetTime(&time); - HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); - - const char *string = HdfSbufReadString(data); - if (string == NULL) { - HDF_LOGE("fail to read string in event data"); - return -1; - } - HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); - return 0; - } - ``` - - 2. 用户态注册接收驱动上报消息的操作方法。 - - ``` - int RegisterListen() - { - struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); - if (serv == NULL) { - HDF_LOGE("fail to get service"); - return -1; - } - static struct HdfDevEventlistener listener = { - .callBack = OnDevEventReceived, - .priv ="Service0" - }; - if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { - HDF_LOGE("fail to register event listener"); - return -1; - } - ...... - HdfDeviceUnregisterEventListener(serv, &listener); - HdfIoServiceRecycle(serv); - return 0; - } - ``` - - 3. 驱动上报事件。 - - ``` - int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) - { - ... // process api call here - return HdfDeviceSendEvent(deviceObject, cmdCode, data); - } - ``` - - - diff --git "a/zh-cn/device-dev/get-code/Docker\347\274\226\350\257\221\347\216\257\345\242\203.md" "b/zh-cn/device-dev/get-code/Docker\347\274\226\350\257\221\347\216\257\345\242\203.md" deleted file mode 100644 index c15f1861f152e8616fc86c629472fdef6a0df991..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/get-code/Docker\347\274\226\350\257\221\347\216\257\345\242\203.md" +++ /dev/null @@ -1,313 +0,0 @@ -# Docker编译环境 - -- [Docker环境介绍](#section107932281315) -- [环境准备](#section7337134183512) -- [独立Docker环境](#section2858536103611) - - [搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section319412277287) - - [编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section631485163615) - - [搭建Docker环境-标准系统类设备(参考内存≥128MB)](#section13585262391) - - [编译源码-标准系统类设备(参考内存≥128MB)](#section193711513406) - -- [基于HPM的Docker环境](#section485713518337) - - [搭建Docker环境](#section3295842510) - - [获取及编译源码](#section69141039143518) - - -## Docker环境介绍 - -OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下: - -- 独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。 -- 基于HPM的Docker环境:适用于使用HPM工具进行发行版编译的场景。 - -**表 1** Docker镜像介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Docker环境

-

系统类型

-

运行平台

-

Docker镜像仓库

-

标签

-

独立 Docker环境

-

轻量和小型系统

-

Ubuntu/Windows

-

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

-

0.0.5

-

标准系统

-

Ubuntu

-

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard

-

0.0.1

-

HPM Docker环境

-

轻量和小型系统

-

Ubuntu/Windows

-

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

-

0.0.3

-
- -## 环境准备 - -在使用docker环境前需要先完成以下操作: - -1. 安装Docker,Docker安装请参考[官方指导](https://docs.docker.com/engine/install/)。 -2. 获取OpenHarmony源码,请参考[获取源码](源码获取.md)。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >HPM Docker环境无需单独获取源码。 - - -## 独立Docker环境 - -OpenHarmony的Docker镜像托管在[HuaweiCloud SWR](https://console.huaweicloud.com/swr/?region=cn-south-1#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage)上。开发者可以通过该镜像在很大程度上简化编译前的环境配置。下文将介绍具体使用步骤。 - -### 搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) - -**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** - -1. 获取Docker镜像。 - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - -2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ubuntu下执行: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - windows下执行(假设源码目录为D:\\OpenHarmony): - - ``` - docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - -**方式二:通过Dockerfile 构建本地Docker镜像进行构建** - -1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 - - ``` - cd docs/docker - ./build.sh - ``` - -3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ubuntu下执行: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - windows下执行(假设源码目录为D:\\OpenHarmony): - - ``` - docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - -### 编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) - -通过如下编译脚本启动轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)的编译。下文以Hi3516平台为例说明具体编译步骤。 - -设置编译路径,选择当前路径。 - -``` -hb set - . -``` - -**图 1** 设置编译界面 - - -![](figures/zh-cn_image_0000001101413884.png) - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前开发板平台和编译界面的对应关系如下: ->- Hi3861:wifiiot\_hispark\_pegasus@hisilicon ->- Hi3516:ipcamera\_hispark\_taurus@hisilicon ->- Hi3518:ipcamera\_hispark\_aries@hisilicon - -1. 选择ipcamera\_hispark\_taurus@hisilicon并回车。 -2. 执行编译。 - - ``` - hb build -f - ``` - -3. 查看编译结果。 - - 编译结果文件生成在out/hispark\_taurus/ipcamera\_hispark\_taurus目录下。 - - -### 搭建Docker环境-标准系统类设备(参考内存≥128MB) - -**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** - -1. 获取Docker镜像。 - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - -2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - - -**方式二:通过Dockerfile 构建本地Docker镜像进行构建** - -1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 - - ``` - cd docs/docker/standard - ./build.sh - ``` - -3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ``` - docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 - ``` - - -### 编译源码-标准系统类设备(参考内存≥128MB) - -1. 在源码的根目录执行预处理脚本。 - - ``` - ../scripts/prepare.sh - ``` - -2. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 - - ``` - ./build.sh --product-name {product_name} - ``` - - \{product\_name\}为当前版本支持的平台。比如:Hi3516DV300等。 - - 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 - - ->![](public_sys-resources/icon-note.gif) **说明:** ->退出Docker执行exit命令即可。 - -## 基于HPM的Docker环境 - -docker\_dist是一个[HPM](https://hpm.harmonyos.com/)系统中的模板组件,能够帮助用户快速初始化HPM工程,利用docker镜像来快速编译OpenHarmony发行版,在很大程度上简化了编译前的环境配置。开发者在配置好Ubuntu和[hpm-cli](https://device.harmonyos.com/cn/docs/develop/bundles/oem_bundle_guide_prepare-0000001050129846)开发环境后,可以通过以下步骤来使用我们提供的Docker环境。 - -### 搭建Docker环境 - -1. 初始化安装模板。在任意工作目录中执行以下命令。 - - ``` - hpm init -t @ohos/docker_dist - ``` - -2. 修改publishAs。 - - 因为获取到的是模板类型的包,要把包的类型改为需要的类型。 在当前目录下打开bundle.json文件,把"publishAs"字段的值由"template"改为"distribution"。 - - -### 获取及编译源码 - -执行编译。自动安装docker只能在Ubuntu环境下执行,如果其他环境,需要用户自行安装docker,然后拉取镜像,执行编译。 - -- **自动安装docker(Ubuntu环境)** - - 以下命令可以帮助用户自动安装docker, 拉取镜像,并且在容器中开始运行对应解决方案的拉取和编译。 - - **方式一:** - - 命令后接参数指定解决方案,格式如下: - - ``` - hpm run docker solution={product} - ``` - - \{product\}为需编译的解决方案,如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus。 - - **方式二:** - - 设置环境变量来选择解决方案,再执行编译命令。 - - 1. 选择解决方案。 - - ``` - export solution={product} - ``` - - \{product\}为需编译的解决方案,如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus。 - - 2. 获取源码及执行编译。 - - ``` - hpm run docker - ``` - - - 以上两种方式以@ohos/hispark\_taurus为例,执行成功结果如下: - - ``` - ...... - ohos ipcamera_hispark_taurus build success! - @ohos/hispark_taurus: distribution building completed. - ``` - - -- **自行安装docker(非Ubuntu环境)** - - 自行安装docker相关操作如下: - - ``` - # 拉取镜像 - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# linux环境下的编译 - hpm run distWithDocker solution={product} - # windows下的编译,需要配置gitbash - hpm config set shellPath "gitbash路径" - hpm run distWithDocker solution={product} - ``` - - diff --git a/zh-cn/device-dev/get-code/IDE.md b/zh-cn/device-dev/get-code/IDE.md deleted file mode 100644 index 144b67418be2f44e4a5854bdb799be24b4142b7a..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/get-code/IDE.md +++ /dev/null @@ -1,17 +0,0 @@ -# IDE - -- [获取设备开发工具(HUAWEI DevEco Device Tool)](#section2452141120244) -- [获取应用开发工具(HUAWEI DevEco Studio)](#section0904101019258) - -## 获取设备开发工具(HUAWEI DevEco Device Tool) - -HUAWEI DevEco Device Tool是OpenHarmony面向智能设备开发者提供的一站式集成开发环境,支持OpenHarmony的组件按需定制,支持代码编辑、编译、烧录、调试等功能,支持C/C++语言,以插件的形式部署在Visual Studio Code上。具体可参见[获取工具](https://device.harmonyos.com/cn/ide)和[工具使用指南](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905)**。** - -Huawei DevEco Device Tool支持 OpenHarmony设备开发的演进路标如下: - -![](figures/3.png) - -## 获取应用开发工具(HUAWEI DevEco Studio) - -HUAWEI DevEco Studio(以下简称DevEco Studio)是面向华为终端全场景多设备的一站式集成开发环境(IDE),为开发者提供工程模板创建、开发、编译、调试、发布等E2E的OpenHarmony应用开发服务。通过使用DevEco Studio,开发者可以更高效的开发具备OpenHarmony分布式能力的应用,进而提升创新效率。具体可参见[获取工具](https://developer.harmonyos.com/cn/develop/deveco-studio)和[工具使用指南](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)。 - diff --git a/zh-cn/device-dev/get-code/Readme-CN.md b/zh-cn/device-dev/get-code/Readme-CN.md index a2dbbc91bbebb45f6609d07ca87191ed509e3ab4..82da2d561e3ade5ee95dbe4c1411c4114ad6ad2b 100755 --- a/zh-cn/device-dev/get-code/Readme-CN.md +++ b/zh-cn/device-dev/get-code/Readme-CN.md @@ -1,7 +1,9 @@ # 获取源码 -- [源码获取](源码获取.md) -- [获取工具](获取工具.md) - - [Docker编译环境](Docker编译环境.md) - - [IDE](IDE.md) +- [获取源码](sourcecode.md) + - [源码获取](sourcecode-acquire.md) + +- [获取工具](gettools.md) + - [Docker编译环境](gettools-acquire.md) + - [IDE](gettools-ide.md) diff --git a/zh-cn/device-dev/get-code/figures/3.png b/zh-cn/device-dev/get-code/figure/3-20.png similarity index 100% rename from zh-cn/device-dev/get-code/figures/3.png rename to zh-cn/device-dev/get-code/figure/3-20.png diff --git a/zh-cn/device-dev/get-code/figures/zh-cn_image_0000001101413884.png b/zh-cn/device-dev/get-code/figure/zh-cn_image_0000001101413884.png similarity index 100% rename from zh-cn/device-dev/get-code/figures/zh-cn_image_0000001101413884.png rename to zh-cn/device-dev/get-code/figure/zh-cn_image_0000001101413884.png diff --git a/zh-cn/device-dev/get-code/figures/zh-cn_image_0000001119755646.png b/zh-cn/device-dev/get-code/figure/zh-cn_image_0000001119755646.png similarity index 100% rename from zh-cn/device-dev/get-code/figures/zh-cn_image_0000001119755646.png rename to zh-cn/device-dev/get-code/figure/zh-cn_image_0000001119755646.png diff --git a/zh-cn/device-dev/get-code/figures/zh-cn_image_0000001119915556.png b/zh-cn/device-dev/get-code/figure/zh-cn_image_0000001119915556.png similarity index 100% rename from zh-cn/device-dev/get-code/figures/zh-cn_image_0000001119915556.png rename to zh-cn/device-dev/get-code/figure/zh-cn_image_0000001119915556.png diff --git a/zh-cn/device-dev/get-code/figures/zh-cn_image_0000001166715379.png b/zh-cn/device-dev/get-code/figure/zh-cn_image_0000001166715379.png similarity index 100% rename from zh-cn/device-dev/get-code/figures/zh-cn_image_0000001166715379.png rename to zh-cn/device-dev/get-code/figure/zh-cn_image_0000001166715379.png diff --git a/zh-cn/device-dev/get-code/gettools-acquire.md b/zh-cn/device-dev/get-code/gettools-acquire.md new file mode 100644 index 0000000000000000000000000000000000000000..942635e189a91797d3624a574a4d2892d52e6a7d --- /dev/null +++ b/zh-cn/device-dev/get-code/gettools-acquire.md @@ -0,0 +1,313 @@ +# Docker编译环境 + +- [Docker环境介绍](#section107932281315) +- [环境准备](#section7337134183512) +- [独立Docker环境](#section2858536103611) + - [搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section319412277287) + - [编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section631485163615) + - [搭建Docker环境-标准系统类设备(参考内存≥128MB)](#section13585262391) + - [编译源码-标准系统类设备(参考内存≥128MB)](#section193711513406) + +- [基于HPM的Docker环境](#section485713518337) + - [搭建Docker环境](#section3295842510) + - [获取及编译源码](#section69141039143518) + + +## Docker环境介绍 + +OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下: + +- 独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。 +- 基于HPM的Docker环境:适用于使用HPM工具进行发行版编译的场景。 + +**表 1** Docker镜像介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Docker环境

+

系统类型

+

运行平台

+

Docker镜像仓库

+

标签

+

独立 Docker环境

+

轻量和小型系统

+

Ubuntu/Windows

+

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

+

0.0.5

+

标准系统

+

Ubuntu

+

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard

+

0.0.1

+

HPM Docker环境

+

轻量和小型系统

+

Ubuntu/Windows

+

swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker

+

0.0.3

+
+ +## 环境准备 + +在使用docker环境前需要先完成以下操作: + +1. 安装Docker,Docker安装请参考[官方指导](https://docs.docker.com/engine/install/)。 +2. 获取OpenHarmony源码,请参考[获取源码](sourcecode-acquire.md)。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >HPM Docker环境无需单独获取源码。 + + +## 独立Docker环境 + +OpenHarmony的Docker镜像托管在[HuaweiCloud SWR](https://console.huaweicloud.com/swr/?region=cn-south-1#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage)上。开发者可以通过该镜像在很大程度上简化编译前的环境配置。下文将介绍具体使用步骤。 + +### 搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) + +**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** + +1. 获取Docker镜像。 + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + +2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ubuntu下执行: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + windows下执行(假设源码目录为D:\\OpenHarmony): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +**方式二:通过Dockerfile 构建本地Docker镜像进行构建** + +1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 + + ``` + cd docs/docker + ./build.sh + ``` + +3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ubuntu下执行: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + windows下执行(假设源码目录为D:\\OpenHarmony): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +### 编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) + +通过如下编译脚本启动轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)的编译。下文以Hi3516平台为例说明具体编译步骤。 + +设置编译路径,选择当前路径。 + +``` +hb set + . +``` + +**图 1** 设置编译界面 + + +![](figure/zh-cn_image_0000001101413884.png) + +>![](../public_sys-resources/icon-note.gif) **说明:** +>当前开发板平台和编译界面的对应关系如下: +>- Hi3861:wifiiot\_hispark\_pegasus@hisilicon +>- Hi3516:ipcamera\_hispark\_taurus@hisilicon +>- Hi3518:ipcamera\_hispark\_aries@hisilicon + +1. 选择ipcamera\_hispark\_taurus@hisilicon并回车。 +2. 执行编译。 + + ``` + hb build -f + ``` + +3. 查看编译结果。 + + 编译结果文件生成在out/hispark\_taurus/ipcamera\_hispark\_taurus目录下。 + + +### 搭建Docker环境-标准系统类设备(参考内存≥128MB) + +**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** + +1. 获取Docker镜像。 + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**方式二:通过Dockerfile 构建本地Docker镜像进行构建** + +1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +### 编译源码-标准系统类设备(参考内存≥128MB) + +1. 在源码的根目录执行预处理脚本。 + + ``` + ../scripts/prepare.sh + ``` + +2. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 + + ``` + ./build.sh --product-name {product_name} + ``` + + \{product\_name\}为当前版本支持的平台。比如:Hi3516DV300等。 + + 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 + + +>![](../public_sys-resources/icon-note.gif) **说明:** +>退出Docker执行exit命令即可。 + +## 基于HPM的Docker环境 + +docker\_dist是一个[HPM](https://hpm.harmonyos.com/)系统中的模板组件,能够帮助用户快速初始化HPM工程,利用docker镜像来快速编译OpenHarmony发行版,在很大程度上简化了编译前的环境配置。开发者在配置好Ubuntu和[hpm-cli](../bundles/bundles-guide-prepare.md)开发环境后,可以通过以下步骤来使用我们提供的Docker环境。 + +### 搭建Docker环境 + +1. 初始化安装模板。在任意工作目录中执行以下命令。 + + ``` + hpm init -t @ohos/docker_dist + ``` + +2. 修改publishAs。 + + 因为获取到的是模板类型的包,要把包的类型改为需要的类型。 在当前目录下打开bundle.json文件,把"publishAs"字段的值由"template"改为"distribution"。 + + +### 获取及编译源码 + +执行编译。自动安装docker只能在Ubuntu环境下执行,如果其他环境,需要用户自行安装docker,然后拉取镜像,执行编译。 + +- **自动安装docker(Ubuntu环境)** + + 以下命令可以帮助用户自动安装docker, 拉取镜像,并且在容器中开始运行对应解决方案的拉取和编译。 + + **方式一:** + + 命令后接参数指定解决方案,格式如下: + + ``` + hpm run docker solution={product} + ``` + + \{product\}为需编译的解决方案,如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus。 + + **方式二:** + + 设置环境变量来选择解决方案,再执行编译命令。 + + 1. 选择解决方案。 + + ``` + export solution={product} + ``` + + \{product\}为需编译的解决方案,如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus。 + + 2. 获取源码及执行编译。 + + ``` + hpm run docker + ``` + + + 以上两种方式以@ohos/hispark\_taurus为例,执行成功结果如下: + + ``` + ...... + ohos ipcamera_hispark_taurus build success! + @ohos/hispark_taurus: distribution building completed. + ``` + + +- **自行安装docker(非Ubuntu环境)** + + 自行安装docker相关操作如下: + + ``` + # 拉取镜像 + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# linux环境下的编译 + hpm run distWithDocker solution={product} + # windows下的编译,需要配置gitbash + hpm config set shellPath "gitbash路径" + hpm run distWithDocker solution={product} + ``` + + diff --git a/zh-cn/device-dev/get-code/gettools-ide.md b/zh-cn/device-dev/get-code/gettools-ide.md new file mode 100644 index 0000000000000000000000000000000000000000..8217ddc1222045e4633d5cd05289e20169ce90e4 --- /dev/null +++ b/zh-cn/device-dev/get-code/gettools-ide.md @@ -0,0 +1,17 @@ +# IDE + +- [获取设备开发工具(HUAWEI DevEco Device Tool)](#section2452141120244) +- [获取应用开发工具(HUAWEI DevEco Studio)](#section0904101019258) + +## 获取设备开发工具(HUAWEI DevEco Device Tool) + +HUAWEI DevEco Device Tool是OpenHarmony面向智能设备开发者提供的一站式集成开发环境,支持OpenHarmony的组件按需定制,支持代码编辑、编译、烧录、调试等功能,支持C/C++语言,以插件的形式部署在Visual Studio Code上。具体可参见[获取工具](https://device.harmonyos.com/cn/ide)和[工具使用指南](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905)**。** + +Huawei DevEco Device Tool支持 OpenHarmony设备开发的演进路标如下: + +![](figure/3-20.png) + +## 获取应用开发工具(HUAWEI DevEco Studio) + +HUAWEI DevEco Studio(以下简称DevEco Studio)是面向华为终端全场景多设备的一站式集成开发环境(IDE),为开发者提供工程模板创建、开发、编译、调试、发布等E2E的OpenHarmony应用开发服务。通过使用DevEco Studio,开发者可以更高效的开发具备OpenHarmony分布式能力的应用,进而提升创新效率。具体可参见[获取工具](https://developer.harmonyos.com/cn/develop/deveco-studio)和[工具使用指南](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)。 + diff --git a/zh-cn/device-dev/get-code/gettools.md b/zh-cn/device-dev/get-code/gettools.md new file mode 100644 index 0000000000000000000000000000000000000000..4e35772567489dde5083791a9ac2596331588446 --- /dev/null +++ b/zh-cn/device-dev/get-code/gettools.md @@ -0,0 +1,7 @@ +# 获取工具 + +- **[Docker编译环境](gettools-acquire.md)** + +- **[IDE](gettools-ide.md)** + + diff --git a/zh-cn/device-dev/get-code/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/get-code/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/get-code/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/get-code/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/get-code/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/get-code/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/get-code/public_sys-resources/icon-note.gif b/zh-cn/device-dev/get-code/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/get-code/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/get-code/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/get-code/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/get-code/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/get-code/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/get-code/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/get-code/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/get-code/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/get-code/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/get-code/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/zh-cn/device-dev/get-code/sourcecode-acquire.md b/zh-cn/device-dev/get-code/sourcecode-acquire.md new file mode 100644 index 0000000000000000000000000000000000000000..622d4cd83b108673913067f2dea6ff3b883403dc --- /dev/null +++ b/zh-cn/device-dev/get-code/sourcecode-acquire.md @@ -0,0 +1,426 @@ +# 源码获取 + +- [OpenHarmony介绍](#section6370143622110) +- [源码获取概述](#section12763342204) +- [获取方式1:从代码仓库获取](#section537312010229) + - [适用场景](#section10881513459) + - [前提条件](#section102871547153314) + - [操作步骤](#section429012478331) + +- [获取方式2:从HPM获取](#section463013147412) + - [适用场景](#section26661067443) + - [前提条件](#section17544943123315) + - [操作步骤](#section954619433333) + +- [获取方式3:从镜像站点获取](#section1186691118430) +- [源码目录简介](#section1072115612811) + +## OpenHarmony介绍 + +OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展。 + +开源代码仓库地址:[https://openharmony.gitee.com](https://openharmony.gitee.com) + +>![](../public_sys-resources/icon-note.gif) **说明:** +>当前的OpenHarmony源代码仅支持在Linux环境下编译。 + +## 源码获取概述 + +本文档将介绍如何获取OpenHarmony源码并说明OpenHarmony的源码目录结构。OpenHarmony的代码以[组件](../bundles/bundles-standard-rules.md)的形式开放,开发者可以通过如下其中一种方式获取: + +- **获取方式1**:从代码仓库获取。通过repo或git工具从代码仓库中下载,此方式可获取最新代码。 +- **获取方式2**:通过HPM包管理器获取。在[HPM](https://hpm.harmonyos.com)网站,查找满足需求的开源发行版,直接下载(或者定制后下载),再通过hpm-cli命令工具将所需的组件及工具链下载、安装到本地。 +- **获取方式3**:从镜像站点下载归档后的发行版压缩文件。如果要获取旧版本的源码,也可通过此方式获取,此方式下载速度较快。 + +## 获取方式1:从代码仓库获取 + +### 适用场景 + +- 基于OpenHarmony的稳定分支建立自己的基线,分发下游客户。 + +- 已经完成自身软件与OpenHarmony的对接,需要进行OpenHarmony官方认证。 + +- 芯片/模组/app通过OpenHarmony官方认证后,贡献代码到OpenHarmony社区。 + +- 修复OpenHarmony的问题。 + +- 学习OpenHarmony的源码。 + + +### 前提条件 + +1. 注册码云gitee账号。 +2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 +3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)并配置用户信息。 + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. 安装码云repo工具,可以执行如下命令。 + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### 操作步骤 + +**获取轻量/小型/标准系统(2.0 Canary)源码** + +>![](../public_sys-resources/icon-note.gif) **说明:** +>主干代码为开发分支,开发者可通过主干代码获取最新特性。release分支代码相对比较稳定,开发者可基于release分支代码进行商用功能开发。 + +- **OpenHarmony主干代码获取** + + 方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 + + ``` + repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify + repo sync -c + repo forall -c 'git lfs pull' + ``` + + 方式二:通过repo + https 下载。 + + ``` + repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify + repo sync -c + repo forall -c 'git lfs pull' + ``` + + +- **OpenHarmony release 分支最新代码获取** + + >![](../public_sys-resources/icon-note.gif) **说明:** + >当前通过release分支只能获取轻量和小型系统源码。 + + 通过repo下载。 + + ``` + repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify + repo sync -c + repo forall -c 'git lfs pull' + ``` + +- OpenHarmony其他版本源码获取方式请参考版本[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md)。 + +## 获取方式2:从HPM获取 + +### 适用场景 + +对于刚接触OpenHarmony的新用户,希望能够参考一些示例解决方案从而进行快速开发。可以在[HPM](https://hpm.harmonyos.com)网站获取下载开源发行版,也可以在开源发行版的基础上定制(添加或删除组件)。然后通过包管理器命令行工具(hpm-cli)将需要的组件及相关的编译工具链全部下载、安装到本地。 + +### 前提条件 + +先要在本地安装Node.js和hpm命令行工具,安装步骤如下: + +1. 安装Node.js。 + + 官网下载并在本地安装Node.js. + + 推荐安装 [Node.js](https://nodejs.org/) 12.x \(包含 npm 6.14.4\)或更高版本 \(推荐 12.13.0+\)。 + +2. 通过Node.js自带的npm安装hpm命令行工具。 + + 打开CMD,执行以下命令: + + ``` + npm install -g @ohos/hpm-cli + ``` + +3. 安装完成后执行如下命令,显示hpm版本,即安装成功。 + + ``` + hpm -V 或 hpm --version + ``` + +4. 如果升级hpm的版本,请执行如下命令: + + ``` + npm update -g @ohos/hpm-cli + ``` + + +### 操作步骤 + +1. 查找发行版。 + 1. 打开包管理页面[HPM](https://hpm.harmonyOS.com),设定搜索的对象为“发行版“,如下图所示。 + 2. 在搜索框输入关键字搜索,如“摄像头”。 + 3. 结果中显示与关键字匹配的发行版,可以进一步根据组件类别等过滤条件(如:适配的开发板,内核)精确筛选。 + 4. 查找合适的发行版,点击查看发行版的详情介绍。 + + **图 1** 包管理 + + + ![](figure/zh-cn_image_0000001119915556.png) + + +2. 了解发行版详情。 + + 1. 仔细阅读发行版的说明信息,以了解使用场景、特性、组件构成、使用方法以及如何进行定制化,如下图所示。 + 2. 点击「直接下载」,将发行版下载到本地。 + 3. 点击「定制组件」,将对发行版包含的组件进行定制(添加/删除)。 + + **图 2** 发行版示例 + + + ![](figure/zh-cn_image_0000001119755646.png) + +3. 定制组件。 + 1. 进入发行版的定制页面,如下图所示。 + 2. 通过关闭开关移除可选组件,或者通过“添加组件”增加新的组件。 + 3. 在右边填写您的项目基本信息,包括名称、版本、描述等信息。 + 4. 点击“下载“,系统会根据您的选择,生成相应的OpenHarmony代码结构文件\(如my\_cust\_dist.zip\),保存至本地文件。 + + **图 3** 组件定制 + + + ![](figure/zh-cn_image_0000001166715379.png) + + +4. 下载安装组件。 + 1. 解压下载的压缩文件,用命令行工具CMD(Linux下的Shell终端) + 2. 在解压后的文件目录下执行hpm install指令 + 3. 下载的组件存在工程目录下的ohos\_bundles文件夹中(部分组件安装后会将源码复制到指定目录下)。 + + +## 获取方式3:从镜像站点获取 + +为了获得更好的下载性能,您可以选择从以下站点的镜像库获取源码或者对应的解决方案。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 本部分只提供OpenHarmony Master最新版本和LTS最新版本的源码获取方式, 其他版本源码获取方式以及具体版本信息请参考[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md) +>- 当前Master 1.0版本已经不再维护。 + +**表 1** 源码获取路径 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

LTS版本源码

+

版本信息

+

下载站点

+

SHA256校验码

+

全量代码(轻量和小型系统)

+

1.1.1

+

站点

+

SHA256 校验码

+

Hi3861解决方案(二进制)

+

1.1.1

+

站点

+

SHA256 校验码

+

Hi3518解决方案(二进制)

+

1.1.1

+

站点

+

SHA256 校验码

+

Hi3516解决方案(二进制)

+

1.1.1

+

站点

+

SHA256 校验码

+

RELEASE-NOTES

+

1.1.1

+

站点

+

-

+

Master版本源码

+

版本信息

+

下载站点

+

SHA256校验码

+

全量代码(标准系统)

+

2.0 Canary

+

站点1站点2

+

SHA256校验码

+

全量代码(轻量和小型系统)

+

1.0(不再维护)

+

站点

+

SHA256 校验码

+

Hi3861解决方案(二进制)

+

1.0(不再维护)

+

站点

+

SHA256 校验码

+

Hi3518解决方案(二进制)

+

1.0(不再维护)

+

站点

+

SHA256 校验码

+

Hi3516解决方案(二进制)

+

1.0(不再维护)

+

站点

+

SHA256 校验码

+

RELEASE-NOTES

+

1.0(不再维护)

+

站点

+

-

+

编译工具链

+

版本信息

+

下载站点

+

SHA256校验码

+

编译工具链获取清单

+

-

+

站点

+

-

+
+ +## 源码目录简介 + +下表是OpenHarmony源码的目录及简单说明: + +**表 2** 源码目录 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

目录名

+

描述

+

applications

+

应用程序样例,包括camera等

+

base

+

基础软件服务子系统集&硬件服务子系统集

+

build

+

组件化编译、构建和配置脚本

+

docs

+

说明文档

+

domains

+

增强软件服务子系统集

+

drivers

+

驱动子系统

+

foundation

+

系统基础能力子系统集

+

kernel

+

内核子系统

+

prebuilts

+

编译器及工具链子系统

+

test

+

测试子系统

+

third_party

+

开源第三方组件

+

utils

+

常用的工具集

+

vendor

+

厂商提供的软件

+

build.py

+

编译脚本文件

+
+ diff --git a/zh-cn/device-dev/get-code/sourcecode.md b/zh-cn/device-dev/get-code/sourcecode.md new file mode 100644 index 0000000000000000000000000000000000000000..c5803f640fa69090e16fb33f1bd504282c61b207 --- /dev/null +++ b/zh-cn/device-dev/get-code/sourcecode.md @@ -0,0 +1,5 @@ +# 获取源码 + +- **[源码获取](sourcecode-acquire.md)** + + diff --git "a/zh-cn/device-dev/get-code/\346\272\220\347\240\201\350\216\267\345\217\226.md" "b/zh-cn/device-dev/get-code/\346\272\220\347\240\201\350\216\267\345\217\226.md" deleted file mode 100755 index 3b2c0526b4ee8ef6ef2e967f4b5d8a011011906c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/get-code/\346\272\220\347\240\201\350\216\267\345\217\226.md" +++ /dev/null @@ -1,426 +0,0 @@ -# 源码获取 - -- [OpenHarmony介绍](#section6370143622110) -- [源码获取概述](#section12763342204) -- [获取方式1:从代码仓库获取](#section537312010229) - - [适用场景](#section10881513459) - - [前提条件](#section102871547153314) - - [操作步骤](#section429012478331) - -- [获取方式2:从HPM获取](#section463013147412) - - [适用场景](#section26661067443) - - [前提条件](#section17544943123315) - - [操作步骤](#section954619433333) - -- [获取方式3:从镜像站点获取](#section1186691118430) -- [源码目录简介](#section1072115612811) - -## OpenHarmony介绍 - -OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展。 - -开源代码仓库地址:[https://openharmony.gitee.com](https://openharmony.gitee.com) - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前的OpenHarmony源代码仅支持在Linux环境下编译。 - -## 源码获取概述 - -本文档将介绍如何获取OpenHarmony源码并说明OpenHarmony的源码目录结构。OpenHarmony的代码以[组件](../bundles/概述.md)的形式开放,开发者可以通过如下其中一种方式获取: - -- **获取方式1**:从代码仓库获取。通过repo或git工具从代码仓库中下载,此方式可获取最新代码。 -- **获取方式2**:通过HPM包管理器获取。在[HPM](https://hpm.harmonyos.com)网站,查找满足需求的开源发行版,直接下载(或者定制后下载),再通过hpm-cli命令工具将所需的组件及工具链下载、安装到本地。 -- **获取方式3**:从镜像站点下载归档后的发行版压缩文件。如果要获取旧版本的源码,也可通过此方式获取,此方式下载速度较快。 - -## 获取方式1:从代码仓库获取 - -### 适用场景 - -- 基于OpenHarmony的稳定分支建立自己的基线,分发下游客户。 - -- 已经完成自身软件与OpenHarmony的对接,需要进行OpenHarmony官方认证。 - -- 芯片/模组/app通过OpenHarmony官方认证后,贡献代码到OpenHarmony社区。 - -- 修复OpenHarmony的问题。 - -- 学习OpenHarmony的源码。 - - -### 前提条件 - -1. 注册码云gitee账号。 -2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 -3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)并配置用户信息。 - - ``` - git config --global user.name "yourname" - git config --global user.email "your-email-address" - git config --global credential.helper store - ``` - -4. 安装码云repo工具,可以执行如下命令。 - - ``` - curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 - chmod a+x /usr/local/bin/repo - pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests - ``` - - -### 操作步骤 - -**获取轻量/小型/标准系统(2.0 Canary)源码** - ->![](public_sys-resources/icon-note.gif) **说明:** ->主干代码为开发分支,开发者可通过主干代码获取最新特性。release分支代码相对比较稳定,开发者可基于release分支代码进行商用功能开发。 - -- **OpenHarmony主干代码获取** - - 方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 - - ``` - repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify - repo sync -c - repo forall -c 'git lfs pull' - ``` - - 方式二:通过repo + https 下载。 - - ``` - repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify - repo sync -c - repo forall -c 'git lfs pull' - ``` - - -- **OpenHarmony release 分支最新代码获取** - - >![](public_sys-resources/icon-note.gif) **说明:** - >当前通过release分支只能获取轻量和小型系统源码。 - - 通过repo下载。 - - ``` - repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify - repo sync -c - repo forall -c 'git lfs pull' - ``` - -- **OpenHarmony** 其他版本源码获取方式请参考版本[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md)。 - -## 获取方式2:从HPM获取 - -### 适用场景 - -对于刚接触OpenHarmony的新用户,希望能够参考一些示例解决方案从而进行快速开发。可以在[HPM](https://hpm.harmonyos.com)网站获取下载开源发行版,也可以在开源发行版的基础上定制(添加或删除组件)。然后通过包管理器命令行工具(hpm-cli)将需要的组件及相关的编译工具链全部下载、安装到本地。 - -### 前提条件 - -先要在本地安装Node.js和hpm命令行工具,安装步骤如下: - -1. 安装Node.js。 - - 官网下载并在本地安装Node.js. - - 推荐安装 [Node.js](https://nodejs.org/) 12.x \(包含 npm 6.14.4\)或更高版本 \(推荐 12.13.0+\)。 - -2. 通过Node.js自带的npm安装hpm命令行工具。 - - 打开CMD,执行以下命令: - - ``` - npm install -g @ohos/hpm-cli - ``` - -3. 安装完成后执行如下命令,显示hpm版本,即安装成功。 - - ``` - hpm -V 或 hpm --version - ``` - -4. 如果升级hpm的版本,请执行如下命令: - - ``` - npm update -g @ohos/hpm-cli - ``` - - -### 操作步骤 - -1. 查找发行版。 - 1. 打开包管理页面[HPM](https://hpm.harmonyOS.com),设定搜索的对象为“发行版“,如下图所示。 - 2. 在搜索框输入关键字搜索,如“摄像头”。 - 3. 结果中显示与关键字匹配的发行版,可以进一步根据组件类别等过滤条件(如:适配的开发板,内核)精确筛选。 - 4. 查找合适的发行版,点击查看发行版的详情介绍。 - - **图 1** 包管理 - - - ![](figures/zh-cn_image_0000001119915556.png) - - -2. 了解发行版详情。 - - 1. 仔细阅读发行版的说明信息,以了解使用场景、特性、组件构成、使用方法以及如何进行定制化,如下图所示。 - 2. 点击「直接下载」,将发行版下载到本地。 - 3. 点击「定制组件」,将对发行版包含的组件进行定制(添加/删除)。 - - **图 2** 发行版示例 - - - ![](figures/zh-cn_image_0000001119755646.png) - -3. 定制组件。 - 1. 进入发行版的定制页面,如下图所示。 - 2. 通过关闭开关移除可选组件,或者通过“添加组件”增加新的组件。 - 3. 在右边填写您的项目基本信息,包括名称、版本、描述等信息。 - 4. 点击“下载“,系统会根据您的选择,生成相应的OpenHarmony代码结构文件\(如my\_cust\_dist.zip\),保存至本地文件。 - - **图 3** 组件定制 - - - ![](figures/zh-cn_image_0000001166715379.png) - - -4. 下载安装组件。 - 1. 解压下载的压缩文件,用命令行工具CMD(Linux下的Shell终端) - 2. 在解压后的文件目录下执行hpm install指令 - 3. 下载的组件存在工程目录下的ohos\_bundles文件夹中(部分组件安装后会将源码复制到指定目录下)。 - - -## 获取方式3:从镜像站点获取 - -为了获得更好的下载性能,您可以选择从以下站点的镜像库获取源码或者对应的解决方案。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 本部分只提供**OpenHarmony** Master最新版本和LTS最新版本的源码获取方式, 其他版本源码获取方式以及具体版本信息请参考[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md) ->- 当前Master 1.0版本已经不再维护。 - -**表 1** 源码获取路径 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LTS版本源码

-

版本信息

-

下载站点

-

SHA256校验码

-

全量代码(轻量和小型系统)

-

1.1.1

-

站点

-

SHA256 校验码

-

Hi3861解决方案(二进制)

-

1.1.1

-

站点

-

SHA256 校验码

-

Hi3518解决方案(二进制)

-

1.1.1

-

站点

-

SHA256 校验码

-

Hi3516解决方案(二进制)

-

1.1.1

-

站点

-

SHA256 校验码

-

RELEASE-NOTES

-

1.1.1

-

站点

-

-

-

Master版本源码

-

版本信息

-

下载站点

-

SHA256校验码

-

全量代码(标准系统)

-

2.0 Canary

-

站点1站点2

-

SHA256校验码

-

全量代码(轻量和小型系统)

-

1.0(不再维护)

-

站点

-

SHA256 校验码

-

Hi3861解决方案(二进制)

-

1.0(不再维护)

-

站点

-

SHA256 校验码

-

Hi3518解决方案(二进制)

-

1.0(不再维护)

-

站点

-

SHA256 校验码

-

Hi3516解决方案(二进制)

-

1.0(不再维护)

-

站点

-

SHA256 校验码

-

RELEASE-NOTES

-

1.0(不再维护)

-

站点

-

-

-

编译工具链

-

版本信息

-

下载站点

-

SHA256校验码

-

编译工具链获取清单

-

-

-

站点

-

-

-
- -## 源码目录简介 - -下表是OpenHarmony源码的目录及简单说明: - -**表 2** 源码目录 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

目录名

-

描述

-

applications

-

应用程序样例,包括camera等

-

base

-

基础软件服务子系统集&硬件服务子系统集

-

build

-

组件化编译、构建和配置脚本

-

docs

-

说明文档

-

domains

-

增强软件服务子系统集

-

drivers

-

驱动子系统

-

foundation

-

系统基础能力子系统集

-

kernel

-

内核子系统

-

prebuilts

-

编译器及工具链子系统

-

test

-

测试子系统

-

third_party

-

开源第三方组件

-

utils

-

常用的工具集

-

vendor

-

厂商提供的软件

-

build.py

-

编译脚本文件

-
- diff --git "a/zh-cn/device-dev/get-code/\350\216\267\345\217\226\345\267\245\345\205\267.md" "b/zh-cn/device-dev/get-code/\350\216\267\345\217\226\345\267\245\345\205\267.md" deleted file mode 100755 index eeb55c7156473c57f088d2bce54464b13fd8ca92..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/get-code/\350\216\267\345\217\226\345\267\245\345\205\267.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 获取工具 - -- **[Docker编译环境](Docker编译环境.md)** - -- **[IDE](IDE.md)** - - diff --git a/zh-cn/device-dev/glossary/Readme-CN.md b/zh-cn/device-dev/glossary/Readme-CN.md index 1e55e64c536877c21128a54e333b2802f36fa1da..e69d48c93789ee931046637f2f6262f867c7a4ef 100755 --- a/zh-cn/device-dev/glossary/Readme-CN.md +++ b/zh-cn/device-dev/glossary/Readme-CN.md @@ -1,4 +1,4 @@ -# glossary +# 术语 -- [术语](术语.md) +- [术语](glossary.md) diff --git "a/zh-cn/device-dev/glossary/\346\234\257\350\257\255.md" b/zh-cn/device-dev/glossary/glossary.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/glossary/\346\234\257\350\257\255.md" rename to zh-cn/device-dev/glossary/glossary.md diff --git a/zh-cn/device-dev/glossary/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/glossary/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/glossary/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/glossary/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/glossary/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/glossary/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/glossary/public_sys-resources/icon-note.gif b/zh-cn/device-dev/glossary/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/glossary/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/glossary/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/glossary/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/glossary/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/glossary/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/glossary/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/glossary/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/glossary/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/glossary/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/glossary/public_sys-resources/icon-warning.gif and /dev/null differ diff --git "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\345\267\245\344\275\234\346\265\201\347\250\213\350\247\243\346\236\220.md" "b/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\345\267\245\344\275\234\346\265\201\347\250\213\350\247\243\346\236\220.md" deleted file mode 100644 index 90604006df166670190abe945a505eb3e81408b2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\345\267\245\344\275\234\346\265\201\347\250\213\350\247\243\346\236\220.md" +++ /dev/null @@ -1,18 +0,0 @@ -# Input模型工作流程解析 - -为了让开发者更清晰的了解Input模型工作流程,本节将对input模型加载的关键流程代码进行说明。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本章节为Input模型工作流程说明,开发者无需进行开发。 - -- **[私有配置信息解析](私有配置信息解析.md)** - -- **[管理驱动层初始化及注册驱动至HDF框架](管理驱动层初始化及注册驱动至HDF框架.md)** - -- **[公共驱动层初始化及注册驱动至HDF框架](公共驱动层初始化及注册驱动至HDF框架.md)** - -- **[器件驱动层初始化及注册驱动至HDF框架](器件驱动层初始化及注册驱动至HDF框架.md)** - -- **[具体调用逻辑串联函数](具体调用逻辑串联函数.md)** - - diff --git "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\347\256\200\344\273\213.md" "b/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\347\256\200\344\273\213.md" deleted file mode 100644 index 2ad3264215219982f95f0ebd29fd39bc2b480e71..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\347\256\200\344\273\213.md" +++ /dev/null @@ -1,12 +0,0 @@ -# Input模型简介 - -Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。其中: - -- 设备管理层:主要为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; -- 公共驱动层:负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; -- 器件驱动层:通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; - -此外,Input模型预先实现了数据通道以及设备配置信息解析等函数。 - -关于Input模型的详细介绍请参考《[Touchscreen开发概述](../driver/Touchscreen开发概述.md)》。 - diff --git "a/zh-cn/device-dev/guide/LED\345\244\226\350\256\276\346\216\247\345\210\266.md" "b/zh-cn/device-dev/guide/LED\345\244\226\350\256\276\346\216\247\345\210\266.md" deleted file mode 100755 index fc94423bf4b226c2284c93a126c88618ba864537..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/LED\345\244\226\350\256\276\346\216\247\345\210\266.md" +++ /dev/null @@ -1,9 +0,0 @@ -# LED外设控制 - -- **[概述](概述.md)** - -- **[开发](开发.md)** - -- **[验证](验证.md)** - - diff --git a/zh-cn/device-dev/guide/Readme-CN.md b/zh-cn/device-dev/guide/Readme-CN.md index 6afa218aca591d6e446fe35e60821022c6a5459b..aa2470b29a038a4c9b924c787a6cb564b5c97abb 100755 --- a/zh-cn/device-dev/guide/Readme-CN.md +++ b/zh-cn/device-dev/guide/Readme-CN.md @@ -1,74 +1,39 @@ -# 开发示例 +# 设备开发指南 + +- [WLAN连接类产品](device-wifi.md) + - [LED外设控制](device-wifi-led-outcontrol.md) + - [集成三方SDK](device-wifi-sdk.md) + +- [无屏摄像头类产品](device-iotcamera.md) + - [概述](device-iotcamera-control-overview.md) + - [示例开发](device-iotcamera-control-demo.md) + - [拍照开发指导](device-iotcamera-control-demo-photodevguide.md) + - [录像开发指导](device-iotcamera-control-demo-videodevguide.md) + + - [应用实例](device-iotcamera-control-example.md) + +- [带屏摄像头类产品](device-camera.md) + - [屏幕和摄像头控制](device-camera-control.md) + - [概述](device-camera-control-overview.md) + - [示例开发](device-camera-control-demo.md) + - [拍照开发指导](device-camera-control-demo-photoguide.md) + - [录像开发指导](device-camera-control-demo-videoguide.md) + - [预览开发指导](device-camera-control-demo-previewguide.md) + + - [应用实例](device-camera-control-example.md) + + - [视觉应用开发](device-camera-visual.md) + - [概述](device-camera-visual-overview.md) + - [开发准备](device-camera-visual-prepare.md) + - [添加页面](device-camera-visual-addpage.md) + - [开发首页](device-camera-visual-first-page.md) + - [开发详情页](device-camera-visual-details.md) + - [调试打包](device-camera-visual-debug.md) + - [真机运行](device-camera-visual-run.md) + - [常见问题](device-camera-visual-faqs.md) + +- [时钟应用开发指导](device-clock-guide.md) +- [平台驱动开发示例](device-driver-demo.md) +- [外设驱动开发示例](device-outerdriver-demo.md) -- [WLAN连接类产品](WLAN连接类产品.md) - - [LED外设控制](LED外设控制.md) - - [概述](概述.md) - - [开发](开发.md) - - [验证](验证.md) - - - [集成三方SDK](集成三方SDK.md) - -- [无屏摄像头类产品](无屏摄像头类产品.md) - - [摄像头控制](摄像头控制.md) - - [概述](概述-0.md) - - [示例开发](示例开发.md) - - [拍照开发指导](拍照开发指导.md) - - [录像开发指导](录像开发指导.md) - - - [应用实例](应用实例.md) - -- [带屏摄像头类产品](带屏摄像头类产品.md) - - [屏幕和摄像头控制](屏幕和摄像头控制.md) - - [概述](概述-1.md) - - [示例开发](示例开发-2.md) - - [拍照开发指导](拍照开发指导-3.md) - - [录像开发指导](录像开发指导-4.md) - - [预览开发指导](预览开发指导.md) - - - [应用实例](应用实例-5.md) - - - [视觉应用开发](视觉应用开发.md) - - [概述](概述-6.md) - - [开发准备](开发准备.md) - - [添加页面](添加页面.md) - - [开发首页](开发首页.md) - - [开发详情页](开发详情页.md) - - [调试打包](调试打包.md) - - [真机运行](真机运行.md) - - [常见问题](常见问题.md) - -- [时钟应用开发示例](时钟应用开发示例.md) - - [概述](概述-7.md) - - [开发准备](开发准备-8.md) - - [开发步骤](开发步骤.md) - - [签名打包](签名打包.md) - - [真机运行](真机运行-9.md) - -- [平台驱动开发示例](平台驱动开发示例.md) - - [概述](概述-10.md) - - [环境准备](环境准备.md) - - [开发](开发-11.md) - - [编译及烧录](编译及烧录.md) - -- [外设驱动开发示例](外设驱动开发示例.md) - - [概述](概述-12.md) - - [硬件资源介绍](硬件资源介绍.md) - - [Input模型简介](Input模型简介.md) - - - [环境搭建](环境搭建.md) - - [TouchScreen器件驱动开发](TouchScreen器件驱动开发.md) - - [配置设备描述信息](配置设备描述信息.md) - - [配置Touchscreen器件信息](配置Touchscreen器件信息.md) - - [适配器件私有驱动](适配器件私有驱动.md) - - - [编译及烧录](编译及烧录-13.md) - - [调试验证](调试验证.md) - - [开机日志分析](开机日志分析.md) - - - [Input模型工作流程解析](Input模型工作流程解析.md) - - [私有配置信息解析](私有配置信息解析.md) - - [管理驱动层初始化及注册驱动至HDF框架](管理驱动层初始化及注册驱动至HDF框架.md) - - [公共驱动层初始化及注册驱动至HDF框架](公共驱动层初始化及注册驱动至HDF框架.md) - - [器件驱动层初始化及注册驱动至HDF框架](器件驱动层初始化及注册驱动至HDF框架.md) - - [具体调用逻辑串联函数](具体调用逻辑串联函数.md) diff --git "a/zh-cn/device-dev/guide/TouchScreen\345\231\250\344\273\266\351\251\261\345\212\250\345\274\200\345\217\221.md" "b/zh-cn/device-dev/guide/TouchScreen\345\231\250\344\273\266\351\251\261\345\212\250\345\274\200\345\217\221.md" deleted file mode 100644 index ef2d3835fa3e16bf4f94ec4d40017dba3cafd5b0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/TouchScreen\345\231\250\344\273\266\351\251\261\345\212\250\345\274\200\345\217\221.md" +++ /dev/null @@ -1,17 +0,0 @@ -# TouchScreen器件驱动开发 - -基于Input模型适配一款触摸屏IC需要完成的工作有: - -1.配置设备描述信息。驱动注册到HDF框架所需要的设备驱动描述信息,如驱动是否加载以及加载次序等; - -2.配置器件私有信息、平台硬件信息。器件私有信息包括上下电时序等,平台硬件信息包括器件连接主板的GPIO端口信息等。 - -3.适配器件私有驱动。 Input模型对Input设备开发流程进行了抽象,开发者只需要适配器件驱动层,无需改动管理驱动层以及公共驱动层。 - -- **[配置设备描述信息](配置设备描述信息.md)** - -- **[配置Touchscreen器件信息](配置Touchscreen器件信息.md)** - -- **[适配器件私有驱动](适配器件私有驱动.md)** - - diff --git "a/zh-cn/device-dev/guide/WLAN\350\277\236\346\216\245\347\261\273\344\272\247\345\223\201.md" "b/zh-cn/device-dev/guide/WLAN\350\277\236\346\216\245\347\261\273\344\272\247\345\223\201.md" deleted file mode 100755 index 08afdfcafc40033c66ba69f0f0580ab2e73d13ae..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/WLAN\350\277\236\346\216\245\347\261\273\344\272\247\345\223\201.md" +++ /dev/null @@ -1,7 +0,0 @@ -# WLAN连接类产品 - -- **[LED外设控制](LED外设控制.md)** - -- **[集成三方SDK](集成三方SDK.md)** - - diff --git a/zh-cn/device-dev/guide/device-camera-control-demo-photoguide.md b/zh-cn/device-dev/guide/device-camera-control-demo-photoguide.md new file mode 100644 index 0000000000000000000000000000000000000000..0cae9c359bf6c5b036a4f947635d7c2ca289b65a --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-control-demo-photoguide.md @@ -0,0 +1,396 @@ +# 拍照开发指导 + +- [使用场景](#zh-cn_topic_0000001052170554_section1963312376119) +- [接口说明](#zh-cn_topic_0000001052170554_section56549532016) +- [约束与限制](#zh-cn_topic_0000001052170554_section1165911177314) +- [开发步骤](#zh-cn_topic_0000001052170554_section138543918214) + +## 使用场景 + +使用Camera产生图片帧(拍照)。 + +## 接口说明 + +**表 1** API列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

类名

+

接口名

+

描述

+

CameraKit

+

int32_t GetCameraIds(std::list<string> cameraList)

+

获取cameraId列表

+

CameraKit

+

CameraAbility& GetCameraAbility(string cameraId)

+

获取指定camera的能力

+

CameraKit

+

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

+

注册camera设备状态回调

+

CameraKit

+

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

+

去注册camera设备状态回调

+

CameraKit

+

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

+

创建camera实例

+

Camera

+

string GetCameraId()

+

获取cameraID

+

Camera

+

CameraConfig& GetCameraConfig()

+

获取camera配置信息

+

Camera

+

FrameConfig& GetFrameConfig(int32_t type)

+

获取捕获帧类型

+

Camera

+

void Configure(CameraConfig& config)

+

配置camera

+

Camera

+

void Release()

+

释放camera

+

Camera

+

int TriggerLoopingCapture(FrameConfig& frameConfig)

+

开始循环帧捕获

+

Camera

+

void StopLoopingCapture()

+

停止循环帧捕获

+

Camera

+

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

+

抓图

+

CameraConfig

+

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

+

设置帧状态回调

+

CameraConfig

+

static CameraConfig* CreateCameraConfig()

+

创建camera配置信息实例

+

CameraAbility

+

std::list<Size> GetSupportedSizes(int format)

+

根据类型获取支持输出图像尺寸大小

+

CameraAbility

+

std::list<T> GetParameterRange(uint32_t key)

+

获取支持的参数范围

+

CameraDevice

+

CameraDeviceCallback()

+

camera设备回调类构造函数

+

CameraDevice

+

void OnCameraStatus​(std::string cameraId, int32_t status)

+

camera设备状态变化时的回调

+

CameraStateCallback

+

CameraStateCallback​()

+

camera状态回调类构造函数

+

CameraStateCallback

+

void OnConfigured​(Camera& camera)

+

camera配置成功回调

+

CameraStateCallback

+

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

+

camera配置失败回调

+

CameraStateCallback

+

void OnCreated​(Camera& camera)

+

camera创建成功回调

+

CameraStateCallback

+

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

+

camera创建失败回调

+

CameraStateCallback

+

void OnReleased​(Camera& camera)

+

camera释放回调

+

FrameStateCallback

+

FrameStateCallback​()

+

帧状态回调类构造函数

+

FrameStateCallback

+

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

+

拍照帧完成回调

+

FrameStateCallback

+

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

+

拍照帧异常回调

+

FrameConfig

+

int32_t GetFrameConfigType()

+

获取帧配置类型

+

FrameConfig

+

std::list<OHOS::Surface> GetSurfaces()

+

获取帧配置的surface

+

FrameConfig

+

void AddSurface(OHOS::AGP::UISurface& surface);

+

添加surface

+

FrameConfig

+

void RemoveSurface(OHOS::AGP::UISurface& surface);

+

删除surface

+
+ +## 约束与限制 + +无。 + +## 开发步骤 + +1. 实现设备状态回调的派生类,用户在设备状态发生变更(如新插入相机设备/相机掉线)时,自定义操作。 + + ``` + class SampleCameraDeviceCallback : public CameraDeviceCallback { + void OnCameraStatus(std::string cameraId, int32_t status) override + { + //do something when camera is available/unavailable + } + }; + ``` + +2. 实现帧事件回调的派生类,这里在拿到帧数据以后将其转存为文件。 + + ``` + static void SampleSaveCapture(const char *p, uint32_t size) + { + cout << "Start saving picture" << endl; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm *ltm = localtime(&tv.tv_sec); + if (ltm != nullptr) { + ostringstream ss("Capture_"); + ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; + + ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); + cout << "write " << size << " bytes" << endl; + pic.write(p, size); + cout << "Saving picture end" << endl; + } + } + + class TestFrameStateCallback : public FrameStateCallback { + void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override + { + cout << "Receive frame complete inform." << endl; + if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { + cout << "Capture frame received." << endl; + list surfaceList = fc.GetSurfaces(); + for (Surface *surface : surfaceList) { + SurfaceBuffer *buffer = surface->AcquireBuffer(); + if (buffer != nullptr) { + char *virtAddr = static_cast(buffer->GetVirAddr()); + if (virtAddr != nullptr) { + SampleSaveCapture(virtAddr, buffer->GetSize()); + } + surface->ReleaseBuffer(buffer); + } + delete surface; + } + delete &fc; + } + } + }; + ``` + +3. 实现相机状态回调的派生类,当相机状态发生变化(配置成功/失败,创建成功/失败\)时,自定义操作。 + + ``` + class SampleCameraStateMng : public CameraStateCallback { + public: + SampleCameraStateMng() = delete; + SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} + ~SampleCameraStateMng() + { + if (recordFd_ != -1) { + close(recordFd_); + } + } + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} + void OnReleased(Camera &c) override {} + }; + ``` + +4. 创建CameraKit,用于创建和获取camera信息。 + + ``` + CameraKit *camKit = CameraKit::GetInstance(); + list camList = camKit->GetCameraIds(); + string camId; + for (auto &cam : camList) { + cout << "camera name:" << cam << endl; + const CameraAbility *ability = camKit->GetCameraAbility(cam); + /* find camera which fits user's ability */ + list sizeList = ability->GetSupportedSizes(0); + if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { + camId = cam; + break; + } + } + ``` + +5. 创建Camera实例。 + + ``` + EventHandler eventHdlr; // Create a thread to handle callback events + SampleCameraStateMng CamStateMng(eventHdlr); + + camKit->CreateCamera(camId, CamStateMng, eventHdlr); + ``` + +6. 根据[步骤1](#zh-cn_topic_0000001052170554_li378084192111)、[步骤2](#zh-cn_topic_0000001052170554_li8716104682913)、[步骤3](#zh-cn_topic_0000001052170554_li6671035102514)中的回调设计,camera实例创建成功后会进行配置操作,主流程中app需要设计同步机制。 + + ``` + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + + void Capture() + { + if (cam_ == nullptr) { + cout << "Camera is not ready." << endl; + return; + } + FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); + Surface *surface = Surface::CreateSurface(); + if (surface == nullptr) { + delete fc; + return; + } + surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ + fc->AddSurface(*surface); + cam_->TriggerSingleCapture(*fc); + } + ``` + + diff --git "a/zh-cn/device-dev/guide/\351\242\204\350\247\210\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/guide/device-camera-control-demo-previewguide.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\351\242\204\350\247\210\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/guide/device-camera-control-demo-previewguide.md diff --git "a/zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274-4.md" b/zh-cn/device-dev/guide/device-camera-control-demo-videoguide.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274-4.md" rename to zh-cn/device-dev/guide/device-camera-control-demo-videoguide.md diff --git a/zh-cn/device-dev/guide/device-camera-control-demo.md b/zh-cn/device-dev/guide/device-camera-control-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..3d42880861d0a17d7ab59f6bead3d0b312d65f3e --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-control-demo.md @@ -0,0 +1,9 @@ +# 示例开发 + +- **[拍照开发指导](device-camera-control-demo-photoguide.md)** + +- **[录像开发指导](device-camera-control-demo-videoguide.md)** + +- **[预览开发指导](device-camera-control-demo-previewguide.md)** + + diff --git a/zh-cn/device-dev/guide/device-camera-control-example.md b/zh-cn/device-dev/guide/device-camera-control-example.md new file mode 100644 index 0000000000000000000000000000000000000000..a092908acd9e92234b09634c4cdef1cf1a3d3c94 --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-control-example.md @@ -0,0 +1,63 @@ +# 应用实例 + +本示例将运行源码中的camera示例代码,通过本示例可以实现对开发板拍照、录像及预览功能的控制。 + +- 本示例源码路径为“applications/sample/camera/media/camera\_sample.cpp”。 +- 在运行本示例前需先完成编译烧录、运行镜像等步骤,相关操作请参考[Hi3516快速入门](../quick-start/quickstart-lite-introduction-hi3516.md#section26131214194212)。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >开发板启动后默认会加载launcher应用,应用的图形界面默认显示在媒体图层上方,会影响camera\_sample的演示结果,因此需要在编译或是打包时去掉launcher应用。 + >**修改方法:**将“build/lite/components/applications.json”中camera\_sample\_app组件的targets中"//applications/sample/camera/launcher:launcher\_hap"整行注释或删除。 + +- 本示例编译结果路径为“out/hi3516dv300/ipcamera\_hi3516dv300\_liteos/dev\_tools/bin”,为让文件能在单板中执行,可将示例文件通过读卡器复制至TF卡中,或者修改camera\_sample的编译脚本将结果文件复制至rootfs.img中。 + + 修改源码路径“applications/sample/camera/media/BUILD.gn”中第一处的output\_dir。 + + - 修改前:output\_dir = "$root\_out\_dir/dev\_ools" + - 修改后:output\_dir = "$root\_out\_dir/" + + 重新执行源码仓编译并烧写入单板后,可在单板bin目录下找到camera\_sample文件。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >实例运行拍照和录像功能需要插入TF卡\(最大容量支持128GB\),系统启动后自动将TF卡挂载至/sdcard目录,如果在启动后插入则需要手动挂载。查看拍照和录像内容可将TF卡中内容复制到电脑中进行查看,预览功能无需TF卡。 + +- 接下来可通过以下步骤运行示例: + +1. 通过cd命令进入可执行程序的末端路径,启动camera\_sample,执行命令如下图。 + + **图 1** 启动示例 + ![](figure/启动示例.png "启动示例") + + 运行后的控制命令如串口打印所示,按s键停止当前操作(包括录像和预览),按q键退出示例程序。 + +2. 按1进行拍照,拍照的文件格式为jpg,存储在/sdcard,文件名Capture\* + + **图 2** 输入拍照指令后串口打印日志 + ![](figure/输入拍照指令后串口打印日志.png "输入拍照指令后串口打印日志") + + 若想查看保存文件,可在退出程序后进入文件系统查看,退出后重新进入请回到步骤1。 + + **图 3** 查看文件图 + ![](figure/查看文件图.png "查看文件图") + +3. 按2进行录像,录像的文件格式为mp4,存储在/sdcard,文件名Record\*,按s键停止 + + **图 4** 输入录像指令后串口打印日志 + ![](figure/输入录像指令后串口打印日志.png "输入录像指令后串口打印日志") + +4. 按3进行预览,预览图像直接送至显示屏,按s键停止。 + + **图 5** 输入预览指令后串口打印日志 + ![](figure/输入预览指令后串口打印日志.png "输入预览指令后串口打印日志") + + 预览效果如下 + + **图 6** 预览效果 + ![](figure/预览效果.jpg "预览效果") + +5. 按q键退出 + + **图 7** 输出退出指令后串口打印日志 + ![](figure/输出退出指令后串口打印日志.png "输出退出指令后串口打印日志") + + diff --git a/zh-cn/device-dev/guide/device-camera-control-overview.md b/zh-cn/device-dev/guide/device-camera-control-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..0bf698b5356079826b7ad124648f76965a4b5770 --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-control-overview.md @@ -0,0 +1,10 @@ +# 概述 + +本文档将介绍如何基于IoT Camera开发板(Hi3516DV300),利用其摄像头和屏幕,完成拍照、录像和视频预览功能。 + +通过本文档,开发者能够对OpenHarmony的摄像控制有更深入的了解,可参照本例尝试完成“智能猫眼”、“智能后视镜”、“智能带屏音箱”等设备的开发。 + +若开发者想先查看示例效果,请进入[应用实例](device-camera-control-example.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 + +相机应用开发的基本概念请参考:[相机开发概述](../subsystems/subsys-multimedia-camera-overview.md)。 + diff --git a/zh-cn/device-dev/guide/device-camera-control.md b/zh-cn/device-dev/guide/device-camera-control.md new file mode 100644 index 0000000000000000000000000000000000000000..a3e406a2e3c71d213ec842dc8d0722c366570022 --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-control.md @@ -0,0 +1,9 @@ +# 屏幕和摄像头控制 + +- **[概述](device-camera-control-overview.md)** + +- **[示例开发](device-camera-control-demo.md)** + +- **[应用实例](device-camera-control-example.md)** + + diff --git a/zh-cn/device-dev/guide/device-camera-visual-addpage.md b/zh-cn/device-dev/guide/device-camera-visual-addpage.md new file mode 100644 index 0000000000000000000000000000000000000000..3929ffbf6aee8d1ecf8ff07da1e3ceeadfa7b2db --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-visual-addpage.md @@ -0,0 +1,34 @@ +# 添加页面 + +- [创建首页面](#section16935511143715) +- [创建详情页](#section122131729173819) + +## 创建首页面 + +空气质量监测App包含两个界面(Page),工程创建完成后会生成一个名为index的Page,可以作为首页。工程目录如下图所示: + +**图 1** 工程目录 +![](figure/工程目录.png "工程目录") + +## 创建详情页 + +新增一个Page,作为详情页,具体步骤如下: + +1. pages目录右键 ,弹出的菜单中选择New、JS Page。 + + **图 2** 添加页面 + ![](figure/添加页面.png "添加页面") + +2. 输入Page名称。 + + **图 3** 输入页面名称 + ![](figure/输入页面名称.png "输入页面名称") + +3. 确认创建结果。 + + 详情页创建完成后应用工程目录如下图所示,每个Page包括三个文件:布局文件hml、样式文件css、业务逻辑代码js。 + + **图 4** 完整工程目录 + ![](figure/完整工程目录.png "完整工程目录") + + diff --git a/zh-cn/device-dev/guide/device-camera-visual-debug.md b/zh-cn/device-dev/guide/device-camera-visual-debug.md new file mode 100644 index 0000000000000000000000000000000000000000..30505bcb3ebf9e4daf0bb1d6adb2b544f19209be --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-visual-debug.md @@ -0,0 +1,4 @@ +# 调试打包 + +代码编写完成后,可以进行调试和打包;应用调试及打包方法可以参考[《DevEco Studio使用指南》](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)的[应用调测](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404)和[编译构建](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201)章节。IPCamera应用暂时不支持签名模式,所以需要将应用发布为未签名的应用安装包。 + diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\350\257\246\346\203\205\351\241\265.md" b/zh-cn/device-dev/guide/device-camera-visual-details.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\345\274\200\345\217\221\350\257\246\346\203\205\351\241\265.md" rename to zh-cn/device-dev/guide/device-camera-visual-details.md diff --git "a/zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230.md" b/zh-cn/device-dev/guide/device-camera-visual-faqs.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230.md" rename to zh-cn/device-dev/guide/device-camera-visual-faqs.md diff --git a/zh-cn/device-dev/guide/device-camera-visual-first-page.md b/zh-cn/device-dev/guide/device-camera-visual-first-page.md new file mode 100644 index 0000000000000000000000000000000000000000..354097ab25c36055562f5c6469393e8f73fba01d --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-visual-first-page.md @@ -0,0 +1,581 @@ +# 开发首页 + +应用首页主要展示城市的空气质量概况。首页总共有两屏(可以根据需求设置多屏),每屏显示一个城市的空气质量信息:主要包括AQI指数、城市名称、污染物指数、更新时间和信息来源等数据。 + +从第一章节中的[显示效果图](device-camera-visual-overview.md#fig18250512195914)分析可知,首页由三部分组成: + +- 标题栏:位于页面正上方,位置固定,包括应用退出按钮和页面标题。 +- 信息栏:主要展示城市的空气信息指标等内容;该页面根据用户需求可设置多屏,且能循环滑动。 +- 页面位置指示器:主要功能是标识当前页面,位置固定在页面底部的中间。 + +综上,我们可搭建一个纵向三行排列的弹性页面布局来实现首页的功能。 + +1. 在hml文件中添加一个根节点div,注意每个hml文件中有且只能有一个根节点,代码如下: + + ``` +
+
+ ``` + + class="container"表示组件使用的样式,container是index.css文件中的一个样式类,代码如下: + + ``` + .container { + flex-direction: column; + height: 480px; + width: 960px; + } + ``` + + 在这个样式类中,我们分别设置了根组件div的高度和宽度(注意在应用的开发过程中,除部分组件(text)外必须显式指定组件的高度和宽度,否则可能无法显示)、并将flex-direction属性设置为column,该属性表示div的子组件是垂直方向从上到下排列;这样就可以实现本节开头所说的纵向三行排列的弹性页面布局。 + +2. 实现标题栏:标题栏包括一个退出按钮和一个标题,两个控件是横向排列;首先添加一个div,并设置flex-direction的属性为row,表示子组件是水平方向从左往右排列;然后依次添加一个image和text组件,代码如下: + + ``` +
+
+ + + 空气质量 + +
+
+ ``` + + 设置组件的高度、边距、颜色等属性。 + + ``` + .header { + width: 960px; + height: 72px; + } + .back { + width: 36px; + height: 36px; + margin-left: 39px; + margin-top: 23px; + } + .title { + width: 296px; + height: 40px; + margin-top: 20px; + margin-left: 21px; + color: #e6e6e6; + } + ``` + + onclick="exitApp" 设置了div组件的click事件,当在标题栏上触发点击事件时,就会执行函数exitApp,该函数位于index.js文件中,代码如下: + + ``` + exitApp() { + console.log('start exit'); + app.terminate(); + console.log('end exit'); + } + ``` + + app.terminate\(\)函数实现了程序退出功能;在使用该函数前,需要引入app模块,在js文件的最上方写如下代码: + + ``` + import app from '@system.app' + ``` + + 代码编写完成后,在模拟器中运行项目,显示效果如下图所示: + + **图 1** 标题栏效果 + ![](figure/标题栏效果.png "标题栏效果") + +3. 实现城市空气质量信息的多屏左右滑动,需要使用“swiper”组件。 + + 在根节点中添加一个子节点swiper,代码片段如下: + + ``` +
+
+ + + 空气质量 + +
+ + +
+ ``` + + - class="swiper"设置了组件的高度和宽度,代码如下: + + ``` + .swiper { + height: 385px; + width: 960px; + } + ``` + + + - index="\{\{swiperPage\}\}" duration="500" onchange="swiperChange" 这些代码用来设置组件的属性和事件。其中,duration="500" 表示设置swiper的页面滑动的动画时长为500ms。 + - index="\{\{swiperPage\}\}"设置了swiper子组件索引值,\{\{swiperPage\}\}这种写法表示index的值是和js代码中的swiperPage变量动态绑定的,index的值会随着swiperPage变动而改变。 + - onchange="swiperChange" 设置了swiper组件的change事件和函数swiperChange绑定,对应的js代码如下: + + ``` + //引入router模块,用户页面跳转 + import router from'@system.router' + import app from '@system.app' + + export default { + //定义参数 + data: { + //默认是第一页 + swiperPage: 0 + }, + onInit () { + }, + exitApp(){ + console.log('start exit'); + app.terminate(); + console.log('end exit'); + }, + //swiper滑动回调事件,保存当前swiper的index值,每次滑动都会将index值保存在swiperPage变量中 + swiperChange (e) { + this.swiperPage = e.index; + } + } + ``` + + +4. 设置一个城市的空气质量信息为一屏,在一屏内,要展示多种信息,分别使用不同的控件进行展示。 + + 在swiper中添加两个子组件stack(绝对布局),每个stack组件内分别添加text、image、progress等组件来显示对应的信息 ,页面结构如下: + + ``` + + + + ------空气质量 + ------城市名称 + -----进度条 + -------云朵图片 + --------AQI数值 + AQI------AQI +
--------空气指标详细信息 +
+
--------更新时间和网站等信息 +
+
+ + + + + + + + +
+
+
+ ``` + + 代码编写完成后,模拟器运行效果如下: + + **图 2** 标题栏和信息栏效果 + ![](figure/标题栏和信息栏效果.png "标题栏和信息栏效果") + +5. 添加页面位置指示器:由于当前swiper不支持设置indicator,需要开发者自己来实现该效果。在根节点中添加一个子组件div,并设置相应样式;然后在该div中添加两个子组件div,设置两个div的border-radius,并在swiper滑动事件中动态改变对应div的背景色来实现该效果。 + + ``` +
+
+
+
+ ``` + + **图 3** 页面位置指示器效果图 + ![](figure/页面位置指示器效果图.png "页面位置指示器效果图") + +6. 所有组件设置样式、动画效果和数据动态绑定,完整代码如下所示: + + - **index.hml文件** + + ``` +
+
+ + + 空气质量 + +
+ + + {{airData[0].airQuality}} + + {{airData[0].location}} + + + + {{airData[0].detailData}} + + + AQI + +
+
+ + CO + + + 100 + +
+
+ + NO2 + + + 90 + +
+
+ + PM10 + + + 120 + +
+
+ + PM2.5 + + + 40 + +
+
+ + SO2 + + + 150 + +
+ +
+ +
+ + {{airData[1].airQuality}} + + {{airData[1].location}} + + + + {{airData[1].detailData}} + + + AQI + +
+
+ + CO + + + 10 + +
+
+ + NO2 + + + 50 + +
+
+ + PM10 + + + 60 + +
+
+ + PM2.5 + + + 40 + +
+
+ + SO2 + + + 150 + +
+ +
+ +
+
+
+
+
+
+
+ ``` + + - **index.css文件** + + css文件中定义了许多class,每个class用于定义组件的位置、大小、字体、颜色、背景色等信息。同时,每一个子组件都叠加在父组件中,父组件的样式会影响子组件的呈现。 + + ``` + .aqi-value { + text-align: center; + font-size: 65px; + color: #f0ffff; + width: 156px; + height: 92px; + top: 134px; + left: 210px; + } + .aqi { + text-align: center; + color: #a2c4a2; + width: 156px; + height: 45px; + top: 90px; + left: 210px; + } + .airquality { + top: 222px; + text-align: center; + width: 156px; + height: 45px; + left: 210px; + } + .image { + top: 285px; + left: 274px; + width: 32px; + height: 32px; + } + .location-text { + text-align: center; + color: #ffffff; + width: 200px; + height: 52px; + font-size: 40px; + left: 380px; + top: 16px; + } + .container { + flex-direction: column; + height: 480px; + width: 960px; + } + .circle-progress { + center-x: 128px; + center-y: 128px; + radius: 128px; + startAngle: 198; + totalAngle: 320; + strokeWidth: 24px; + width: 256px; + height: 256px; + left: 160px; + top: 58px; + } + .detail { + width: 256px; + height: 265px; + left: 544px; + top: 58px; + flex-direction: column; + } + .text-wrapper { + width: 256px; + height: 35px; + margin-top: 6px; + } + .gas-name { + width: 128px; + height: 35px; + text-align: left; + } + .gas-value { + width: 128px; + height: 35px; + text-align: right; + } + .btn { + width: 180px; + height: 50px; + margin-top: 6px; + margin-left: 38px; + background-color: #1a1a1a; + color: #1085CE; + } + .footer { + top: 326px; + width: 960px; + height: 28px; + } + .header { + width: 960px; + height: 72px; + } + .back { + width: 36px; + height: 36px; + margin-left: 39px; + margin-top: 23px; + } + .title { + width: 296px; + height: 40px; + margin-top: 20px; + margin-left: 21px; + color: #e6e6e6; + } + .swiper { + height: 385px; + width: 960px; + } + .images { + width: 60px; + height: 15px; + margin-left: 450px; + } + .update-time { + width: 480px; + height: 28px; + font-size: 20px; + color: #A9A9A9; + text-align: right; + } + .info-source { + width: 450px; + height: 28px; + font-size: 20px; + color: #A9A9A9; + text-align: left; + margin-left: 24px; + } + .circle-div { + width: 12px; + height: 12px; + border-radius: 6px; + } + ``` + + - **index.js:** + + js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:根据数值动态改变文字、进度条颜色、页面跳转。 + + ``` + //导入router和app模块 + import router from '@system.router' + import app from '@system.app' + + export default { + data: { + //页面绑定数据 + textColor1: '#00ff00', + textColor2: '#00ff00', + bgColor1: '#669966', + bgColor2: '#669966', + swiperPage: 0, + percent1: 40, + percent2: 90, + iconUncheckedColor: '#262626', + iconcheckedColor: '#ffffff', + iconcheckedBR: '6px', + src1: 'common/cloud_green.png', + src2: 'common/cloud_green.png', + airData: [{ + location: '东莞', + airQuality: '良', + detailData: 40 + }, { + location: '深圳', + airQuality: '差', + detailData: 90 + }] + }, + onInit () { + //根据数值的不同,设置不同的字体、背景颜色和图片 + if(this.airData[0].detailData > 100){ + this.src1 = 'common/cloud_red.png'; + this.textColor1 = '#ff0000'; + this.bgColor1 = '#9d7462'; + } else if(50 < this.airData[0].detailData && this.airData[0].detailData <= 100){ + this.src1 = 'common/cloud_yellow.png'; + this.textColor1 = '#ecf19a'; + 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; + if(this.swiperPage == 0){ + this.iconcheckedColor = '#ffffff'; + this.iconUncheckedColor = '#262626'; + }else{ + this.iconcheckedColor = '#262626'; + this.iconUncheckedColor = '#ffffff'; + } + } + }, + //跳转到详情页面 + openDetail () { + router.replace({ + uri: 'pages/detail/detail', + params: {selectedCityIndex:this.swiperPage} + }); + }, + //退出应用 + exitApp(){ + console.log('start exit'); + app.terminate(); + console.log('end exit'); + }, + //页面滑动事件,滑动时改变最新的标识 + swiperChange (e) { + this.swiperPage = e.index; + if(e.index == 0){ + this.iconcheckedColor = '#ffffff'; + this.iconUncheckedColor = '#262626'; + }else{ + this.iconcheckedColor = '#262626'; + this.iconUncheckedColor = '#ffffff'; + } + } + } + ``` + + diff --git a/zh-cn/device-dev/guide/device-camera-visual-overview.md b/zh-cn/device-dev/guide/device-camera-visual-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..a7e9895e2dceb1911879973ef697791cc59e649d --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-visual-overview.md @@ -0,0 +1,15 @@ +# 概述 + +- [效果展示](#section3997224182313) + +本文将介绍如何快速搭建基于OpenHarmony系统的行车记录仪(Hi3516DV300开发板)应用开发环境,并基于一个简易的APP示例逐步展示应用的创建、开发、调试和安装等流程。接下来本文以空气质量监测(AirQuality)App为例进行说明。 + +## 效果展示 + +空气质量监测App是一款展示城市空气质量信息的应用,有两个页面组成:首页和详情页,在DevEco Studio模拟器中的显示效果如下图所示: + +**图 1** 空气质量监测 App显示效果图 + + +![](figure/Video_2020-07-25_173141.gif) + diff --git a/zh-cn/device-dev/guide/device-camera-visual-prepare.md b/zh-cn/device-dev/guide/device-camera-visual-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..55ed7451c0ecdf7d2ab9fd9f896374287a1c5efb --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-visual-prepare.md @@ -0,0 +1,27 @@ +# 开发准备 + +- [准备开发环境](#section1912530122716) +- [创建项目](#section1456035192720) + +## 准备开发环境 + +首先需要下载和配置DevEco Studio,具体操作请参考[《DevEco Studio使用指南》](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)。 + +## 创建项目 + +1. 通过如下两种方式,打开工程创建向导界面。 + - 如果当前未打开任何工程,可以在DevEco Studio的欢迎页,选择**Create HarmonyOS Project**开始创建一个新工程。 + - 如果已经打开了工程,可以在菜单栏选择**File \> New \> New Project**来创建一个新工程。 + +2. 选择“Smart Vision”下的“Empty Feature Ability”模板。 + + ![](figure/zh-cn_image_0000001082434703.png) + +3. 点击**Next**,进入到工程配置阶段,需要根据向导配置工程的基本信息。 + - **Project Name**:工程的名称,可以自定义。 + - **Package Name**:软件包名称,默认情况下,应用ID也会使用该名称,应用发布时,应用ID需要唯一。 + - **Save Location**:工程文件本地存储路径,存储路径中不能包含中文字符和空格。 + - **Compatible API Version**:兼容的SDK版本。 + +4. 点击**Finish**,工具会自动生成示例代码和相关资源,等待工程创建完成。 + diff --git a/zh-cn/device-dev/guide/device-camera-visual-run.md b/zh-cn/device-dev/guide/device-camera-visual-run.md new file mode 100644 index 0000000000000000000000000000000000000000..3e7c3f1d165781cccae6694ca9327357317a6e40 --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-visual-run.md @@ -0,0 +1,29 @@ +# 真机运行 + +应用编译打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[Hi3516快速入门](../quick-start/quickstart-lite-introduction-hi3516.md#section26131214194212)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载三方应用。 + +1. 将IDE编译的未签名应用安装包和安装工具(镜像文件生成目录中的dev\_tools)放在sdcard中,将sdcard插入开发板卡槽。 +2. 应用安装默认要校验签名,需要执行以下命令,关闭签名校验。 + + ``` + ./sdcard/dev_tools/bin/bm set -s disable + ``` + +3. 执行以下命令,安装应用。 + + ``` + ./sdcard/dev_tools/bin/bm install -p /sdcard/airquality.hap + ``` + + 其中dev\_tools目录中是安装工具,airquality.hap为应用安装包,此处替换为实际工程的安装包名称。 + +4. 应用安装完成后,可点击桌面应用图标启动应用,进行操作。 + + **图 1** 桌面 + ![](figure/桌面.png "桌面") + +5. 卸载应用(可选)。 + + 长按桌面应用图标,在弹出的菜单中点击“卸载”按钮即可卸载应用。 + + diff --git a/zh-cn/device-dev/guide/device-camera-visual.md b/zh-cn/device-dev/guide/device-camera-visual.md new file mode 100644 index 0000000000000000000000000000000000000000..ca4e46538b7894fdc3ce840b2b67f185d6e47d29 --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera-visual.md @@ -0,0 +1,19 @@ +# 视觉应用开发 + +- **[概述](device-camera-visual-overview.md)** + +- **[开发准备](device-camera-visual-prepare.md)** + +- **[添加页面](device-camera-visual-addpage.md)** + +- **[开发首页](device-camera-visual-first-page.md)** + +- **[开发详情页](device-camera-visual-details.md)** + +- **[调试打包](device-camera-visual-debug.md)** + +- **[真机运行](device-camera-visual-run.md)** + +- **[常见问题](device-camera-visual-faqs.md)** + + diff --git a/zh-cn/device-dev/guide/device-camera.md b/zh-cn/device-dev/guide/device-camera.md new file mode 100644 index 0000000000000000000000000000000000000000..7239a00d3a42e683c3c015e5e22a3a2dc5a12cec --- /dev/null +++ b/zh-cn/device-dev/guide/device-camera.md @@ -0,0 +1,7 @@ +# 带屏摄像头类产品 + +- **[屏幕和摄像头控制](device-camera-control.md)** + +- **[视觉应用开发](device-camera-visual.md)** + + diff --git a/zh-cn/device-dev/guide/device-clock-guide.md b/zh-cn/device-dev/guide/device-clock-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..a615280a6e27bcf8c37efb75c72ac494e638ad11 --- /dev/null +++ b/zh-cn/device-dev/guide/device-clock-guide.md @@ -0,0 +1,332 @@ +# 时钟应用开发指导 + +- [概述](#section11522349121115) +- [开发准备](#section6592121861218) +- [开发步骤](#section19901741111312) +- [签名打包](#section10601181101516) +- [真机运行](#section092721731511) +- [常见问题](#section1122413460153) + - [hdc\_std连接不到设备](#section1922725151614) + - [hdc\_std运行不了](#section15657547131615) + + +## 概述 + +本文将介绍如何快速搭建基于OpenHarmony标准系统(Hi3516DV300开发板)的应用开发环境,并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过[本链接](https://gitee.com/openharmony/app_samples/tree/master/common/Clock)获取。 + +时钟App是一款显示实时时间的应用,显示效果如下图所示: + +**图 1** 时钟应用显示效果图 + + +![](figure/Clock.png) + +## 开发准备 + +首先需要下载和配置DevEco Studio,具体操作请参考[DevEco Studio 使用指南](../../application-dev/quick-start/DevEco-Studio(OpenHarmony)使用指南.md)。 + +## 开发步骤 + +应用的功能是通过表盘和数字显示实时时间。 + +从[显示效果图](device-clock-guide.md#fig7763172132019)分析可知,页面由两个部分组成: + +- 表盘栏:主要展示一个动态的钟表,且钟表指针能准确转动。 +- 数字时间栏:主要以数字形式显示当前时间。 + +综上,我们可搭建一个纵向两行排列的弹性页面布局来实现界面的功能。具体开发步骤如下: + +1. 在hml文件中添加一个根节点div,注意每个hml文件中有且只能有一个根节点,代码如下: + + ``` +
+
+ ``` + + class="container"表示组件使用的样式,container是index.css文件中的一个样式类,代码如下: + + ``` + .container { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + } + ``` + + 在这个样式类中,我们分别设置了根组件div的高度和宽度(注意在应用的开发过程中,除部分组件(text)外必须显式指定组件的高度和宽度,否则可能无法显示)、并将flex-direction属性设置为column,该属性表示div的子组件是垂直方向从上到下排列;这样就可以实现本节开头所说的纵向两行排列的弹性页面布局。 + +2. 实现时钟转动,需要使用“stack”组件。“stack”组件的功能是堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。 + + 在根组件下添加一个stack容器,代码片段如下: + + ``` +
+ + + + + + +
+ ``` + + style="transform : rotate\(\{\{ second \* 6 \}\}deg\) 这类代码用来设置组件的旋转事件。其中transform是设置动画平移/旋转/缩放的属性,rotate是旋转动画属性,支持设置x轴和y轴两个维度的选中参数。 + + 在css文件中设置"stack"组件样式的高度、宽度、位置等属性,代码如下: + + ``` + .stack { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 50%; + } + ``` + + 在css文件中设置"clock-bg"组件样式的高度、宽度等属性,代码如下: + + ``` + .clock-bg { + width: 80%; + height: 80%; + object-fit: scale-down; + } + ``` + + 在css文件中设置"clock-hand"组件为时针、分针和秒针的高度、宽度等属性,代码如下: + + ``` + .clock-hand { + width: 25%; + height: 65%; + object-fit: contain; + } + ``` + + index.js中会有一个定时器实时刷新时分秒变量,从而触发时间界面自动更新。对应的js代码如下: + + ``` + export default { + timer: undefined, + //定义参数 + data: { + hour: 0, //定义小时 + minute: 0, //定义分钟 + second: 0 //定义秒 + }, + onInit () { + this.updateTime(); + this.timer = setInterval(this.updateTime, 1000)//设置1s的定时器 + }, + updateTime: function () { + var nowTime = new Date() + this.hour = nowTime.getHours() + this.minute = nowTime.getMinutes() + this.second = nowTime.getSeconds() + if (this.hour < 10) { + this.hour = '0' + this.hour + } + if (this.minute < 10) { + this.minute = '0' + this.minute + } + if (this.second < 10) { + this.second = '0' + this.second + } + }, + } + ``` + +3. 显示数字时间,在钟表下面以数字形式显示当前时间。在根布局内末尾加上text组件,页面结构如下: + + ``` + {{ hour }}:{{ minute }}:{{ second }} + ``` + + class="digit-clock"设置了组件的高度和宽度以及字体大小,其代码如下: + + ``` + .digit-clock { + font-size: 58px; + width: 100%; + margin-top: 0px; + text-align: center; + } + ``` + +4. 所有组件设置样式、动画效果和数据动态绑定,完整代码如下所示: + - **index.hml文件** + + ``` +
+ + + + + + + {{ hour }}:{{ minute }}:{{ second }} +
+ ``` + + + - **index.css文件** + + ``` + .container { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + } + + .stack { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 50%; + } + + .digit-clock { + font-size: 58px; + width: 100%; + margin-top: 0px; + text-align: center; + } + + .clock-bg { + width: 80%; + height: 80%; + object-fit: scale-down; + } + + .clock-hand { + width: 25%; + height: 65%; + object-fit: contain; + } + ``` + + + - **index.js:** + + js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:定时获取系统时间。 + + ``` + export default { + timer: undefined, + data: { + hour: 0, + minute: 0, + second: 0 + }, + onInit() { + this.updateTime() + this.timer = setInterval(this.updateTime, 1000) + }, + updateTime: function () { + var nowTime = new Date() + this.hour = nowTime.getHours() + this.minute = nowTime.getMinutes() + this.second = nowTime.getSeconds() + if (this.hour < 10) { + this.hour = '0' + this.hour + } + if (this.minute < 10) { + this.minute = '0' + this.minute + } + if (this.second < 10) { + this.second = '0' + this.second + } + }, + onDestroy() { + clearInterval(this.timer); + } + } + ``` + + + +## 签名打包 + +代码编写完成后,在真机设备上运行应用,需要先对应用进行签名,然后再进行打包,具体操作请参考[签名打包指导](../../application-dev/quick-start/配置OpenHarmony应用签名信息.md)。 + +## 真机运行 + +应用签名打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony系统烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[标准系统Hi3516快速入门](../quick-start/quickstart-standard.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载应用。 + +1. 从开发者工具代码仓路径中获取hdc客户端。 + + ``` + developtools/hdc_standard/prebuilt/windows/hdc_std.exe + ``` + + 修改名称为hdc.exe,并将工具路径加入系统环境path变量中。 + +2. 启动cmd命令窗口,执行以下命令,推送hap应用包到设备目录下并安装。 + + ``` + hdc smode + hdc target mount + hdc file send clock.hap /data/clock.hap + hdc shell chmod 666 /data/clock.hap + hdc shell bm install -p /data/clock.hap + ``` + +3. 启动应用。执行以下命令,其中ohos.samples.clock为应用包名,MainAbility为应用启动的Ability。 + + ``` + hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock + ``` + +4. 卸载应用(可选)。执行以下命令,其中ohos.samples.clock为应用包名。 + + ``` + hdc shell bm uninstall -n ohos.samples.clock + ``` + + +## 常见问题 + +### hdc\_std连接不到设备 + +- **现象描述** + + 执行 "hdc\_std list targets"命令后结果为:\[Empty\] + +- **可能原因和解决方法** + 1. 设备没有被识别: + + 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 + + 2. hdc\_std工作异常: + + 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 + + 3. hdc\_std与设备不匹配: + + 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 + + + +### hdc\_std运行不了 + +- **现象描述** + + 点击hdc\_std.exe文件无法运行。 + +- **可能原因和解决方法** + + hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 + + diff --git a/zh-cn/device-dev/guide/device-driver-demo.md b/zh-cn/device-dev/guide/device-driver-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..73e75ffda88df9a190e7e818a90852cb29c26734 --- /dev/null +++ b/zh-cn/device-dev/guide/device-driver-demo.md @@ -0,0 +1,453 @@ +# 平台驱动开发示例 + +- [概述](#section194201316174215) +- [环境准备](#section6926133918422) +- [开发](#section65801539470) + - [文件说明](#section0708184454414) + - [实例化驱动入口](#section85325864412) + - [设置相关参数](#section8155172019453) + - [添加控制器](#section1335374114452) + +- [编译及烧录](#section164824754712) + +## 概述 + +本文档将以I2C驱动为例,介绍如何基于HDF驱动框架完成平台驱动开发。 + +>![](../public_sys-resources/icon-caution.gif) **注意:** +>本例仅作为平台驱动开发示例参考,开发者不可直接用于商用集成。 + +HDF驱动框架为常用外围设备提供了标准的驱动框架,驱动开发者只需将驱动适配至HDF驱动框架,即可通过HDF驱动框架提供的接口操作外围设备。 + +本文以I2C为例。其时序流程如[图1](#fig148041484161)所示。 + +**图 1** I2C时序流程图 + + +![](figure/zh-cn_image_0000001169991055.png) + +- User Business:用户业务驱动。 +- i2cManagerEntry:I2C管理器入口,注册I2cManager到HDF驱动框架。 +- I2cManager:I2C管理器,管理I2C控制器。 +- I2cCntlr:I2C控制器。 +- i2cDriverEntry:I2C控制器入口,注册I2cCntlr到HDF驱动框架。 + +## 环境准备 + +环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/quickstart-standard.md)。 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 + +## 开发 + +### 文件说明 + +本例中涉及的文件及路径如下表: + +**表 1** 文件说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

说明

+

文件路径

+

操作

+

示例文件

+

/drivers/adapter/khdf/linux/platform/i2c/i2c_sample.c

+

新增文件

+

设备服务文件

+

/drivers/adapter/khdf/linux/hcs/device_info/device_info.hcs

+

+

追加内容

+

+

配置参数文件

+

/drivers/adapter/khdf/linux/hcs/platform/i2c_config.hcs

+

编译文件

+

/drivers/adapter/khdf/linux/platform/i2c/Makefile

+

依赖头文件

+

/drivers/framework/include/core/hdf_device_desc.h

+

作为头文件引用

+

+

核心层头文件

+

/drivers/framework/support/platform/include/i2c_core.h

+

HCS配置入口文件

+

/drivers/adapter/khdf/linux/hcs/hdf.hcs

+

HCS配置文件总入口

+
+ +>![](../public_sys-resources/icon-caution.gif) **注意:** +>本例程涉及的文件路径均作为演示,驱动开发者应根据实际情况确定具体的源文件存放位置。 + +### 实例化驱动入口 + +实例化一个HdfDriverEntry 对象作为驱动入口。驱动入口必须为HdfDriverEntry(在hdf\_device\_desc.h中定义)类型的全局变量,且moduleName要和device\_info.hcs中保持一致。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 + +I2C驱动中没有实现Bind方法,因为I2C控制器由manager管理,而在manager中已经实现了Bind方法,因此I2C驱动中无需再绑定服务。 + +实例化驱动入口的示例代码如下: + +``` +/* 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量 */ +struct HdfDriverEntry g_sampleI2cDriverEntry = { + .moduleVersion = 1, + .Init = SampleI2cInit, + .Release = SampleI2cRelease, + .moduleName = "demo_i2c_driver", +}; +/* 调用HDF_INIT将驱动入口注册到HDF框架中 */ +HDF_INIT(g_sampleI2cDriverEntry); +``` + +### 设置相关参数 + +通过配置device\_info.hcs,并从HCS获取并解析设备的配置参数以确保驱动能够正确加载。 + +1. 添加设备服务节点(必选)。 + + 编辑device\_info.hcs,在device\_i2c :: device下添加驱动设备服务节点,示例如下: + + ``` + root { + device_info { + match_attr = "hdf_manager"; + device_i2c :: device { // i2c设备节点 + device2 :: deviceNode { // i2c驱动的DeviceNode节点 + policy = 0; // policy字段是驱动服务发布的策略 + priority = 55; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "demo_i2c_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 + serviceName = "DEMO_I2C_DRIVER"; // 驱动对外发布服务的名称,必须唯一 + deviceMatchAttr = "demo_i2c_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的 + // match_attr值相等 + } + } + } + } + + ``` + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >配置文件中的priority(取值范围为整数0到200)是用来表示host和驱动的优先级,不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高,驱动的priority值相同则不保证加载顺序。 + +2. 添加配置参数(可选)。 + + 有时驱动可能会需要私有配置信息,以确保寄存器的配置可以满足不同产品的需求。如需要私有配置信息,则可以添加一个驱动的配置文件,用来存放一些驱动的默认配置信息,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init(参考[驱动开发](../driver/driver-hdf-development.md))传递给驱动。驱动开发者可新建配置文件,并在板级驱动hdf.hcs中引用新建的配置文件,本例中直接在原有的配置文件i2c\_config.hcs内添加配置参数。 + + 本例中编辑i2c\_config.hcs,添加配置参数: + + ``` + root { + platform { + i2c_config_demo { + match_attr = "demo_i2c_config"; // 该字段的值必须和device_info.hcs中的deviceMatchAttr值一致 + + template i2c_controller { // 参数模板 + bus = 0; + reg_pbase = 0x120b0000; + reg_size = 0xd1; + } + + controller_demo_0 :: i2c_controller { // 两个I2C示例控制器 + bus = 8; + } + controller_demo_1 :: i2c_controller { + bus = 9; + } + } + } + } + ``` + + match\_attr字段必须与device\_info.hcs中的deviceMatch\_Attr保持一致,在此文件中配置驱动需要的参数,通过match\_attr可匹配至对应的驱动,该驱动即可在Bind或Init中调用DeviceResourceGetIfaceInstance\(\)函数获取这些配置参数。 + + 若配置文件为新文件,则需要在板级配置入口文件hdf.hcs中引用该配置文件,例如: + + ``` + #include "device_info/device_info.hcs" + #include "i2c/i2c_config.hcs" + ``` + + 由于本例中在原有的i2c\_config.hcs内添加配置参数,没有新建配置文件,因此无需再将i2c\_config.hcs添加至板级配置入口文件中。 + +3. 驱动从HCS获取配置参数。 + + 在本例中,驱动需要通过HCS获取寄存器物理基地址、寄存器大小、总线号等参数,从而对控制器进行正确配置。 + + ``` + /* 从HCS获取配置参数 */ + static int32_t SampleI2cReadDrs(struct SampleI2cCntlr *sampleCntlr, const struct DeviceResourceNode *node) + { + int32_t ret; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { // 确保GetUint32方法可用 + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return HDF_FAILURE; + } + + ret = drsOps->GetUint32(node, "reg_pbase", &sampleCntlr->regBasePhy, 0); // 从HCS读取物理基地址reg_pbase + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regBase fail!", __func__); + return ret; + } + + ret = drsOps->GetUint16(node, "reg_size", &sampleCntlr->regSize, 0); // 从HCS读取寄存器大小reg_size + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regsize fail!", __func__); + return ret; + } + + ret = drsOps->GetUint16(node, "bus", (uint16_t *)&sampleCntlr->bus, 0); // 从HCS读取总线号bus + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read bus fail!", __func__); + return ret; + } + + return HDF_SUCCESS; + } + ``` + + +### 添加控制器 + +初始化控制器硬件,并调用核心层接口完成向核心层添加、删除设备,以及钩子函数的实现等。 + +1. 定义结构体,实现钩子函数并赋值至函数指针。 + + I2cMethod结构体在i2c\_core.h中定义,其中通过函数指针的方式定义了I2C需要实现的方法,transfer方法为用于传输的钩子函数,在驱动中需要做具体实现并对函数指针赋值。 + + 示例代码如下: + + ``` + /* 自定义设备结构体,继承父类I2cCntlr */ + struct SampleI2cCntlr { + struct I2cCntlr cntlr; + OsalSpinlock spin; + volatile unsigned char *regBase; + uint16_t regSize; + int16_t bus; + uint32_t regBasePhy; + }; + + /* 消息结构体,继承父类I2cMsg */ + struct SampleTransferData { + struct I2cMsg *msgs; + int16_t index; + int16_t count; + }; + /* 钩子函数实现 */ + static int32_t SampleI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count) + { + int32_t ret = HDF_SUCCESS; + struct SampleI2cCntlr *sampleCntlr = NULL; + struct SampleTransferData td; + + if (cntlr == NULL || cntlr->priv == NULL) { + HDF_LOGE("SampleI2cTransfer: cntlr lor sampleCntlr is null!"); + return HDF_ERR_INVALID_OBJECT; + } + sampleCntlr = (struct SampleI2cCntlr *)cntlr; + + if (msgs == NULL || count <= 0) { + HDF_LOGE("SampleI2cTransfer: err parms! count:%d", count); + return HDF_ERR_INVALID_PARAM; + } + td.msgs = msgs; + td.count = count; + td.index = 0; + + HDF_LOGE("Successfully transmitted!"); // 表示此处传输成功 + + td.index = count; // 经过处理,最后实际发送msg个数等于count,返回已发送个数,此句代替已省略的处理过程 + return (td.index > 0) ? td.index : ret; + } + /* 钩子函数赋值 */ + static struct I2cMethod g_method = { + .transfer = SampleI2cTransfer, + }; + ``` + +2. 编写驱动初始化函数。 + + 本例中使用SampleI2cInit作为驱动初始化函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Init,以供HDF驱动框架调用从而达到初始化驱动的目的。该函数中需要对从HCS获取的配置参数进行解析,并按照这些参数创建控制器。示例如下: + + ``` + /* 解析参数,申请内存并创建控制器 */ + static int32_t SampleI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) + { + int32_t ret; + struct SampleI2cCntlr *sampleCntlr = NULL; + (void)device; + + sampleCntlr = (struct SampleI2cCntlr *)OsalMemCalloc(sizeof(*sampleCntlr)); + if (sampleCntlr == NULL) { + HDF_LOGE("%s: malloc sampleCntlr fail!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + ret = SampleI2cReadDrs(sampleCntlr, node); // 从HCS获取配置参数 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read drs fail! ret:%d", __func__, ret); + goto __ERR__; + } + + sampleCntlr->regBase = OsalIoRemap(sampleCntlr->regBasePhy, sampleCntlr->regSize); + if (sampleCntlr->regBase == NULL) { + HDF_LOGE("%s: ioremap regBase fail!", __func__); + ret = HDF_ERR_IO; + goto __ERR__; + } + + HDF_LOGE("The controller has been initialized!"); // 表示此处省略的控制器初始化操作已经成功 + + sampleCntlr->cntlr.priv = (void *)node; + sampleCntlr->cntlr.busId = sampleCntlr->bus; + sampleCntlr->cntlr.ops = &g_method; + (void)OsalSpinInit(&sampleCntlr->spin); // 初始化自旋锁 + ret = I2cCntlrAdd(&sampleCntlr->cntlr); // 向核心层添加控制器 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: add i2c controller fail:%d!", __func__, ret); + goto __ERR__; + } + + return HDF_SUCCESS; + __ERR__: // 错误处理 + if (sampleCntlr != NULL) { + if (sampleCntlr->regBase != NULL) { + OsalIoUnmap((void *)sampleCntlr->regBase); // 取消地址映射 + sampleCntlr->regBase = NULL; + } + OsalMemFree(sampleCntlr); // 释放内存 + sampleCntlr = NULL; + } + return ret; + } + /* 驱动入口初始化函数 */ + static int32_t SampleI2cInit(struct HdfDeviceObject *device) + { + int32_t ret; + const struct DeviceResourceNode *childNode = NULL; + + HDF_LOGE("%s: Enter", __func__); + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is NULL", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + ret = HDF_SUCCESS; + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + ret = SampleI2cParseAndInit(device, childNode); // 调用解析参数和创建控制器的函数 + if (ret != HDF_SUCCESS) { + break; + } + } + return ret; + } + ``` + +3. 编写驱动释放函数。 + + 本例中使用SampleI2cRelease作为驱动释放函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,将调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。示例如下: + + ``` + /* 删除控制器函数 */ + static void SampleI2cRemoveByNode(const struct DeviceResourceNode *node) + { + int32_t ret; + int16_t bus; + struct I2cCntlr *cntlr = NULL; + struct SampleI2cCntlr *sampleCntlr = NULL; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return; + } + + ret = drsOps->GetUint16(node, "bus", (uint16_t *)&bus, 0); // 从HCS获取I2C总线号 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read bus fail!", __func__); + return; + } + + cntlr = I2cCntlrGet(bus); + if (cntlr != NULL && cntlr->priv == node) { // 根据I2C总线号删除控制器 + I2cCntlrPut(cntlr); + I2cCntlrRemove(cntlr); + sampleCntlr = (struct SampleI2cCntlr *)cntlr; + OsalIoUnmap((void *)sampleCntlr->regBase); + OsalMemFree(sampleCntlr); + } + return; + } + /* 释放资源 */ + static void SampleI2cRelease(struct HdfDeviceObject *device) + { + const struct DeviceResourceNode *childNode = NULL; + + HDF_LOGI("%s: enter", __func__); + + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is NULL", __func__); + return; + } + + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + SampleI2cRemoveByNode(childNode); // 调用删除控制器函数 + } + } + ``` + + +## 编译及烧录 + +1. 编辑Makefile,添加源文件: + + ``` + include drivers/hdf/khdf/platform/platform.mk + + obj-y += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_core.o \ + $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_if.o \ + ./i2c_adapter.o \ + ./i2c_sample.o + ``` + + "./i2c\_sample.o"为本示例中在Makefile中追加的内容。 + +2. 编译及烧录。 + + 具体操作请参考[标准系统快速入门编译及烧录章节](../quick-start/quickstart-standard.md)。 + + diff --git a/zh-cn/device-dev/guide/device-iotcamera-control-demo-photodevguide.md b/zh-cn/device-dev/guide/device-iotcamera-control-demo-photodevguide.md new file mode 100644 index 0000000000000000000000000000000000000000..31edc27814baddb754614c87ca0225979ef408ff --- /dev/null +++ b/zh-cn/device-dev/guide/device-iotcamera-control-demo-photodevguide.md @@ -0,0 +1,396 @@ +# 拍照开发指导 + +- [使用场景](#zh-cn_topic_0000001052170554_section1963312376119) +- [接口说明](#zh-cn_topic_0000001052170554_section56549532016) +- [约束与限制](#zh-cn_topic_0000001052170554_section1165911177314) +- [开发步骤](#zh-cn_topic_0000001052170554_section138543918214) + +## 使用场景 + +使用Camera产生图片帧(拍照)。 + +## 接口说明 + +**表 1** API列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

类名

+

接口名

+

描述

+

CameraKit

+

int32_t GetCameraIds(std::list<string> cameraList)

+

获取cameraId列表

+

CameraKit

+

CameraAbility& GetCameraAbility(string cameraId)

+

获取指定camera的能力

+

CameraKit

+

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

+

注册camera设备状态回调

+

CameraKit

+

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

+

去注册camera设备状态回调

+

CameraKit

+

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

+

创建camera实例

+

Camera

+

string GetCameraId()

+

获取cameraID

+

Camera

+

CameraConfig& GetCameraConfig()

+

获取camera配置信息

+

Camera

+

FrameConfig& GetFrameConfig(int32_t type)

+

获取捕获帧类型

+

Camera

+

void Configure(CameraConfig& config)

+

配置camera

+

Camera

+

void Release()

+

释放camera

+

Camera

+

int TriggerLoopingCapture(FrameConfig& frameConfig)

+

开始循环帧捕获

+

Camera

+

void StopLoopingCapture()

+

停止循环帧捕获

+

Camera

+

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

+

抓图

+

CameraConfig

+

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

+

设置帧状态回调

+

CameraConfig

+

static CameraConfig* CreateCameraConfig()

+

创建camera配置信息实例

+

CameraAbility

+

std::list<Size> GetSupportedSizes(int format)

+

根据类型获取支持输出图像尺寸大小

+

CameraAbility

+

std::list<T> GetParameterRange(uint32_t key)

+

获取支持的参数范围

+

CameraDevice

+

CameraDeviceCallback()

+

camera设备回调类构造函数

+

CameraDevice

+

void OnCameraStatus​(std::string cameraId, int32_t status)

+

camera设备状态变化时的回调

+

CameraStateCallback

+

CameraStateCallback​()

+

camera状态回调类构造函数

+

CameraStateCallback

+

void OnConfigured​(Camera& camera)

+

camera配置成功回调

+

CameraStateCallback

+

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

+

camera配置失败回调

+

CameraStateCallback

+

void OnCreated​(Camera& camera)

+

camera创建成功回调

+

CameraStateCallback

+

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

+

camera创建失败回调

+

CameraStateCallback

+

void OnReleased​(Camera& camera)

+

camera释放回调

+

FrameStateCallback

+

FrameStateCallback​()

+

帧状态回调类构造函数

+

FrameStateCallback

+

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

+

拍照帧完成回调

+

FrameStateCallback

+

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

+

拍照帧异常回调

+

FrameConfig

+

int32_t GetFrameConfigType()

+

获取帧配置类型

+

FrameConfig

+

std::list<OHOS::Surface> GetSurfaces()

+

获取帧配置的surface

+

FrameConfig

+

void AddSurface(OHOS::AGP::UISurface& surface);

+

添加surface

+

FrameConfig

+

void RemoveSurface(OHOS::AGP::UISurface& surface);

+

删除surface

+
+ +## 约束与限制 + +无。 + +## 开发步骤 + +1. 实现设备状态回调的派生类,用户在设备状态发生变更(如新插入相机设备/相机掉线)时,自定义操作。 + + ``` + class SampleCameraDeviceCallback : public CameraDeviceCallback { + void OnCameraStatus(std::string cameraId, int32_t status) override + { + //do something when camera is available/unavailable + } + }; + ``` + +2. 实现帧事件回调的派生类,这里在拿到帧数据以后将其转存为文件。 + + ``` + static void SampleSaveCapture(const char *p, uint32_t size) + { + cout << "Start saving picture" << endl; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm *ltm = localtime(&tv.tv_sec); + if (ltm != nullptr) { + ostringstream ss("Capture_"); + ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; + + ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); + cout << "write " << size << " bytes" << endl; + pic.write(p, size); + cout << "Saving picture end" << endl; + } + } + + class TestFrameStateCallback : public FrameStateCallback { + void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override + { + cout << "Receive frame complete inform." << endl; + if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { + cout << "Capture frame received." << endl; + list surfaceList = fc.GetSurfaces(); + for (Surface *surface : surfaceList) { + SurfaceBuffer *buffer = surface->AcquireBuffer(); + if (buffer != nullptr) { + char *virtAddr = static_cast(buffer->GetVirAddr()); + if (virtAddr != nullptr) { + SampleSaveCapture(virtAddr, buffer->GetSize()); + } + surface->ReleaseBuffer(buffer); + } + delete surface; + } + delete &fc; + } + } + }; + ``` + +3. 实现相机状态回调的派生类,当相机状态发生变化(配置成功/失败,创建成功/失败\)时,自定义操作。 + + ``` + class SampleCameraStateMng : public CameraStateCallback { + public: + SampleCameraStateMng() = delete; + SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} + ~SampleCameraStateMng() + { + if (recordFd_ != -1) { + close(recordFd_); + } + } + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} + void OnReleased(Camera &c) override {} + }; + ``` + +4. 创建CameraKit,用于创建和获取camera信息。 + + ``` + CameraKit *camKit = CameraKit::GetInstance(); + list camList = camKit->GetCameraIds(); + string camId; + for (auto &cam : camList) { + cout << "camera name:" << cam << endl; + const CameraAbility *ability = camKit->GetCameraAbility(cam); + /* find camera which fits user's ability */ + list sizeList = ability->GetSupportedSizes(0); + if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { + camId = cam; + break; + } + } + ``` + +5. 创建Camera实例。 + + ``` + EventHandler eventHdlr; // Create a thread to handle callback events + SampleCameraStateMng CamStateMng(eventHdlr); + + camKit->CreateCamera(camId, CamStateMng, eventHdlr); + ``` + +6. 根据[步骤1](#zh-cn_topic_0000001052170554_li378084192111)、[步骤2](#zh-cn_topic_0000001052170554_li8716104682913)、[步骤3](#zh-cn_topic_0000001052170554_li6671035102514)中的回调设计,camera实例创建成功后会进行配置操作,主流程中app需要设计同步机制。 + + ``` + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + + void Capture() + { + if (cam_ == nullptr) { + cout << "Camera is not ready." << endl; + return; + } + FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); + Surface *surface = Surface::CreateSurface(); + if (surface == nullptr) { + delete fc; + return; + } + surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ + fc->AddSurface(*surface); + cam_->TriggerSingleCapture(*fc); + } + ``` + + diff --git "a/zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/guide/device-iotcamera-control-demo-videodevguide.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/guide/device-iotcamera-control-demo-videodevguide.md diff --git a/zh-cn/device-dev/guide/device-iotcamera-control-demo.md b/zh-cn/device-dev/guide/device-iotcamera-control-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..26be96c626e2e70310352f98858114ba071b1bae --- /dev/null +++ b/zh-cn/device-dev/guide/device-iotcamera-control-demo.md @@ -0,0 +1,7 @@ +# 示例开发 + +- **[拍照开发指导](device-iotcamera-control-demo-photodevguide.md)** + +- **[录像开发指导](device-iotcamera-control-demo-videodevguide.md)** + + diff --git a/zh-cn/device-dev/guide/device-iotcamera-control-example.md b/zh-cn/device-dev/guide/device-iotcamera-control-example.md new file mode 100644 index 0000000000000000000000000000000000000000..8f7e480ded6a00d4f830b0bde6413d9412cf7e2d --- /dev/null +++ b/zh-cn/device-dev/guide/device-iotcamera-control-example.md @@ -0,0 +1,45 @@ +# 应用实例 + +- 开发板介绍、编译烧录、运行镜像等操作请参考[Hi3518快速入门](../quick-start/quickstart-lite-introduction-hi3518.md#section14815247616),编译结果包含示例,结果文件为out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample,可将文件通过读卡器复制至TF卡中,或者修改camera\_sample的编译脚本将结果文件复制至rootfs.img中。 + + 修改applications/sample/camera/media/BUILD.gn中的output\_dir。 + + - 修改前:output\_dir = "$root\_out\_dir/dev\_tools" + - 修改后:output\_dir = "$root\_out\_dir/" + + 重新执行源码仓编译并烧写入单板后,可在单板bin目录下找到camera\_sample文件。 + +- 相机示例代码为applications/sample/camera/media/camera\_sample.cpp。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >实例运行拍照和录像功能需要插入TF卡\(最大容量支持128GB\),系统启动后时自动将TF卡挂载至/sdcard目录,如果在启动后插入则需要手动挂载。查看拍照和录像内容可将TF卡中内容复制到电脑中进行查看,预览功能无需TF卡。 + + +1. 通过cd命令进入可执行程序的末端路径,启动camera\_sample,执行命令如下图。 + + **图 1** 启动示例 + ![](figure/启动示例.png "启动示例") + + 运行后的控制命令如串口打印所示,按s键停止当前操作(包括录像和预览),按q键退出示例程序。 + +2. 按1进行拍照,拍照的文件格式为jpg,存储在/sdcard,文件名Capture\* + + **图 2** 输入拍照指令后串口打印日志 + ![](figure/输入拍照指令后串口打印日志.png "输入拍照指令后串口打印日志") + + 若想查看保存文件,可在退出程序后进入文件系统查看,退出后重新进入请回到步骤1。 + + **图 3** 查看文件图 + ![](figure/查看文件图.png "查看文件图") + +3. 按2进行录像,录像的文件格式为mp4,存储在/sdcard,文件名Record\*,按s键停止 + + **图 4** 输入录像指令后串口打印日志 + ![](figure/输入录像指令后串口打印日志.png "输入录像指令后串口打印日志") + +4. 按q键退出 + + **图 5** 输出退出指令后串口打印日志 + ![](figure/输出退出指令后串口打印日志.png "输出退出指令后串口打印日志") + + diff --git a/zh-cn/device-dev/guide/device-iotcamera-control-overview.md b/zh-cn/device-dev/guide/device-iotcamera-control-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..03fef3f55e4efd17bb96166a158e592c0f1316f5 --- /dev/null +++ b/zh-cn/device-dev/guide/device-iotcamera-control-overview.md @@ -0,0 +1,10 @@ +# 概述 + +本文档将介绍如何基于IoT Camera开发板,利用开发套件中自带的摄像头,完成拍照、录像功能。 + +开发者可通过执行示例应用,对开发板的外设控制有了更深入了解后,可使用开发板完成摄像头等设备。 + +若开发者想先查看示例效果,请进入[应用实例](device-iotcamera-control-example.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 + +相机开发基本概念可参考:[相机开发概述](../subsystems/subsys-multimedia-camera-overview.md)。 + diff --git a/zh-cn/device-dev/guide/device-iotcamera-control.md b/zh-cn/device-dev/guide/device-iotcamera-control.md new file mode 100644 index 0000000000000000000000000000000000000000..776d324bf5be97b63ce546443cc3cf5ebdd08a71 --- /dev/null +++ b/zh-cn/device-dev/guide/device-iotcamera-control.md @@ -0,0 +1,9 @@ +# 摄像头控制 + +- **[概述](device-iotcamera-control-overview.md)** + +- **[示例开发](device-iotcamera-control-demo.md)** + +- **[应用实例](device-iotcamera-control-example.md)** + + diff --git a/zh-cn/device-dev/guide/device-iotcamera.md b/zh-cn/device-dev/guide/device-iotcamera.md new file mode 100644 index 0000000000000000000000000000000000000000..4823d578306a683d5db28277ac38be5410051e8e --- /dev/null +++ b/zh-cn/device-dev/guide/device-iotcamera.md @@ -0,0 +1,5 @@ +# 无屏摄像头类产品 + +- **[摄像头控制](device-iotcamera-control.md)** + + diff --git a/zh-cn/device-dev/guide/device-outerdriver-demo.md b/zh-cn/device-dev/guide/device-outerdriver-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..9526546a58e1da063e682b36e30a6a5f887ea6e7 --- /dev/null +++ b/zh-cn/device-dev/guide/device-outerdriver-demo.md @@ -0,0 +1,483 @@ +# 外设驱动开发示例 + +- [概述](#section86753818426) + - [硬件资源简介](#section123071189431) + - [Input模型简介](#section53684425430) + +- [环境搭建](#section661075474418) +- [TouchScreen器件驱动开发](#section15233162984520) + - [配置设备描述信息](#section16761205604515) + - [配置Touchscreen器件信息](#section156331030144617) + - [适配器件私有驱动](#section17127331595) + +- [编译及烧录](#section16465031164711) +- [调试验证](#section62577313482) +- [Input模型工作流程解析](#section1578569154917) + - [私有配置信息解析](#section1310113815495) + - [管理驱动层初始化及注册驱动至HDF框架](#section614512119500) + - [公共驱动层初始化及注册驱动至HDF框架](#section16194201755019) + - [器件驱动层初始化及注册驱动至HDF框架](#section1090743312505) + - [具体调用逻辑串联函数](#section81801147529) + + +## 概述 + +本文档将介绍如何基于Hi3516DV300开发板完成基于HDF\_Input模型的触摸屏器件驱动开发,从而使开发者快速入门,进行基于的外设驱动开发。 + +### 硬件资源简介 + +Hi3516DV300开发板套件所提供的触摸屏器件IC为GT911,该器件采用标准I2C与主机通信,通过6pin软排线与主板连接。6pin分布以及实物连接图如下图所示: + +![](figure/绘图1.png) + +### Input模型简介 + +Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。其中: + +- 设备管理层:主要为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; +- 公共驱动层:负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; +- 器件驱动层:通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; + +此外,Input模型预先实现了数据通道以及设备配置信息解析等函数。 + +关于Input模型的详细介绍请参考《[Touchscreen开发概述](../driver/driver-peripherals-touch-des.md#section175431838101617)》。 + +## 环境搭建 + +环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/quickstart-standard.md)。 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 + +## TouchScreen器件驱动开发 + +基于Input模型适配一款触摸屏IC需要完成的具体工作见下。 + +### 配置设备描述信息 + +驱动注册到HDF框架所需要的设备驱动描述信息,如驱动是否加载以及加载次序等。 + +配置文件路径:./drivers/adapter/khdf/linux/hcs/device\_info/device\_info.hcs + +device\_info.hcs中的信息主要提供给HDF框架使用,包含了Input模型各层驱动注册到HDF框架所必需的信息,开发者无特殊场景需求无需改动。各驱动层私有配置信息通过“deviceMatchAttr”字段与input\_config.hcs中的“match\_attr”相关内容进行匹配。 + +配置文件中与input模块相关的内容如下所示,相关字段的详细含义可以参考《[驱动配置](../driver/driver-hdf-development.md)》: + +``` +input :: host { + hostName = "input_host"; + priority = 100; + device_input_manager :: device { // Input管理层设备描述信息 + device0 :: deviceNode { + policy = 2; // 向内核用户态均发布服务 + priority = 100; // input管理层驱动优先级默认为100 + preload = 0; // 加载该驱动 + permission = 0660; // 驱动创建设备节点权限 + moduleName = "HDF_INPUT_MANAGER"; // 与驱动入口的moduleName匹配 + serviceName = "hdf_input_host"; // HDF框架生成的节点名 + deviceMatchAttr = ""; // manager目前不需要私有配置,因此为空 + } + } + + device_hdf_touch :: device { // Input公共驱动层设备描述信息 + device0 :: deviceNode { + policy = 2; // 向内核用户态均发布服务 + priority = 120; // input公共驱动优先级默认为120 + preload = 0; // 加载该驱动 + permission = 0660; // 驱动创建设备节点权限 + moduleName = "HDF_TOUCH"; // 与驱动入口的moduleName匹配 + serviceName = "hdf_input_event1"; // HDF框架生成的节点名 + deviceMatchAttr = "touch_device1"; // 与私有配置信息中的“match_attr”字段保持一致 + } + } + + device_touch_chip :: device { // Input器件驱动层信息 + device0 :: deviceNode { + policy = 0; // 向内核用户态均不发布服务 + priority = 130; // input器件驱动优先级默认为130 + preload = 0; // 加载该驱动 + permission = 0660; // 驱动创建设备节点权限 + moduleName = "HDF_TOUCH_GT911"; // 与驱动入口的moduleName匹配 + serviceName = "hdf_touch_gt911_service";// HDF框架生成的节点名 + deviceMatchAttr = "zsj_gt911_5p5"; //与私有配置信息中的“match_attr”字段保持一致 + } + } + } +``` + +该配置文件中需要重点关注的字段有: + +“priority”决定驱动加载顺序; + +“preload”决定驱动是否加载; + +“moduleName ”需要与驱动注册入口处的“moduleName ”字段保持一致; + +“serviceName ”HDF框架依据该字段创建节点名; + +“deviceMatchAttr ”需要与私有配置信息中的“match\_attr”字段保持一致。 + +通过配置设备描述信息,使得HDF框架通过moduleName与注册至驱动入口的代码相匹配,保证了驱动的正常加载,通过priority字段保证了各驱动的加载顺序。 + +### 配置Touchscreen器件信息 + +器件私有信息包括上下电时序等,平台硬件信息包括器件连接主板的GPIO端口信息等。 + +配置文件路径:./drivers/adapter/khdf/linux/hcs/input/input\_config.hcs + +input\_config.hcs中的信息由驱动代码进行读取解析,主要由公共驱动层的私有配置信息及器件驱动层的私有配置信息组成。文件中的配置包含板级硬件信息及器件私有配置信息,实际业务开发时,可根据具体需求增删及修改对应内容。 + +``` +root { + input_config { + touchConfig { + touch0 { // 第一款触摸屏 + boardConfig { // 板级硬件信息 + match_attr = "touch_device1"; // 与设备描述配置信息中公共驱动层私有配置信息的“match_attr”字段保持一致 + inputAttr { + /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */ + inputType = 0; // input类型为touch + solutionX = 480; // 分辨率X信息 + solutionY = 960; // 分辨率Y信息 + devName = "main_touch"; // 设备名称 + } + busConfig { + /* 0:i2c 1:spi */ + busType = 0; // GT911采用I2C通信 + busNum = 6; // 与主机芯片第6路I2C通信 + clkGpio = 86; // 主机芯片SCL管脚 + dataGpio = 87; // 主机芯片SDA管脚 + i2cClkIomux = [0x114f0048, 0x403]; // SCL管脚配置信息 + i2cDataIomux = [0x114f004c, 0x403]; // SDA管脚配置信息 + } + pinConfig { + rstGpio = 3; // 复位管脚连接主机芯片的3号管脚 + intGpio = 4; // 中断管脚连接主机芯片的4号管脚 + rstRegCfg = [0x112f0094, 0x400]; // 复位管脚配置信息 + intRegCfg = [0x112f0098, 0x400]; // 中断管脚配置信息 + } + powerConfig { + /* 0:unused 1:ldo 2:gpio 3:pmic */ + vccType = 2; // GPIO供电 + vccNum = 20; // gpio20 + vccValue = 1800; // 电压幅值为1800mV + vciType = 1; // LDO供电 + vciNum = 12; // ldo12 + vciValue = 3300; // 电压幅值为3300mV + } + + featureConfig { + capacitanceTest = 0; // 容值测试 + gestureMode = 0; // 手势模式 + gloverMode = 0; // 手套模式 + coverMode = 0; // 皮套模式 + chargerMode = 0; // 充电模式 + knuckleMode = 0; // 指关节模式 + } + } + chipConfig { // 器件私有信息配置 + template touchChip { // 模板 + match_attr = ""; + chipName = "gt911"; // 触摸屏IC型号 + vendorName = "zsj"; // 供应商 + chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 + busType = 0; // 0代表I2C,1代表SPI + deviceAddr = 0x5D; // 器件IC通信地址 + irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 + maxSpeed = 400; // 最大通信速率为400Hz + chipVersion = 0; // 触摸屏IC版本号 + powerSequence { + /* 上电时序的配置含义说明: + [类型, 状态, 方向 , 延时] + 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 + 0代表下电或拉低,1代表上电或拉高,2代表无操作 + 0代表输入方向,1代表输出方向,2代表无操作 + 代表延时多少毫秒, 例如20代表延时20ms + */ + powerOnSeq = [4, 0, 1, 0, // 中断管脚配置为输出,且进行拉低 + 3, 0, 1, 10, // 复位管脚配置为输出,且进行拉低,延时10ms + 3, 1, 2, 60, // 复位管脚无操作,且进行拉高,延时60ms + 4, 2, 0, 0]; // 中断管脚配置为输入 + suspendSeq = [3, 0, 2, 10]; // 复位管脚无操作,且进行拉低,延时10ms + resumeSeq = [3, 1, 2, 10]; // 复位管脚无操作,且进行拉高,延时10ms + powerOffSeq = [3, 0, 2, 10, // 复位管脚无操作,且进行拉低,延时10ms + 1, 0, 2, 20]; // 电源正极管脚无操作,且进行拉低,延时20ms + } + } + + chip0 :: touchChip { + match_attr = "zsj_gt911_5p5"; // 与设备描述配置信息中器件私有配置信息的“match_attr”字段保持一致 + chipInfo = "ZIDN45100"; // 产品名+模组编号+芯片编号的组合信息 用于给用户态区分当前器件 + chipVersion = 0; // IC型号的版本 + } + } + } + } + } +} +``` + +示例中“touchConfig”包含了“touch0”,"touch0"包含了“boardConfig”与“chipConfig”;“boardConfig”字段包含了Hi3516DV300板级硬件信息,“chipConfig”包含了触摸屏器件的私有信息,如果需要替换触摸屏器件,重新配置“chipConfig”对应的字段信息即可。同时产品可以配置多款触摸屏,示例中用“touch0”代表了套件中默认的触摸屏的硬件接口以及器件的配置信息,如产品需要配置副屏,可在与“touch0”并列的位置配置“touch1”的信息。 + +### 适配器件私有驱动 + +Input模型对Input设备开发流程进行了抽象,开发者只需要适配器件驱动层,无需改动管理驱动层以及公共驱动层。 + +Input模型由三层驱动组成,开发者适配一款全新触摸屏驱动只需要适配器件驱动层即可,重点实现差异化接口,本小节以代码示例的形式展示开发者需要重点完成的工作。 + +1. 触摸屏器件差异化接口适配 + + 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c + + ``` + static struct TouchChipOps g_gt911ChipOps = { // 器件IC接口 + .Init = ChipInit, // 初始化 + .Detect = ChipDetect, // 器件检测 + .Resume = ChipResume, // 唤醒 + .Suspend = ChipSuspend, // 休眠 + .DataHandle = ChipDataHandle, // 器件数据读取 + .UpdateFirmware = UpdateFirmware, // 固件升级 + }; + + /* 不同触摸屏厂家使用的IC不一样,对应的寄存器操作也不一样,因此器件驱动层代码重点适配差异化接口部分,如下示例代码展示了GT911的数据解析*/ + + static int32_t ChipDataHandle(ChipDevice *device) + { + ... + /* GT911获取坐标之前需先读取状态寄存器 */ + reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; + ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); + if (ret < 0 || touchStatus == GT_EVENT_INVALID) { + return HDF_FAILURE; + } + ... + /* 根据状态寄存器的值读取数据寄存器数据 */ + reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; + pointNum = touchStatus & GT_FINGER_NUM_MASK; + if (pointNum == 0 || pointNum > MAX_SUPPORT_POINT) { + HDF_LOGE("%s: pointNum is invalid, %u", __func__, pointNum); + (void)ChipCleanBuffer(i2cClient); + OsalMutexUnlock(&device->driver->mutex); + return HDF_FAILURE; + } + frame->realPointNum = pointNum; + frame->definedEvent = TOUCH_DOWN; + (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); + /* 对获取的数据进行解析 */ + ParsePointData(device, frame, buf, pointNum); + ... + } + static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) + { + ... + /* 每个坐标值由两个字节组成,对获取的单字节数据进行拼接得到最终的坐标值 */ + for (i = 0; i < pointNum; i++) { + frame->fingers[i].trackId = buf[GT_POINT_SIZE * i + GT_TRACK_ID]; + frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + /* 对解析出来的坐标值进行打印 */ + HDF_LOGD("%s: x = %d, y = %d", __func__, frame->fingers[i].x, frame->fingers[i].y); + } + } + ``` + +2. 器件层驱动初始化及注册驱动至HDF框架 + + 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c + + ``` + static int32_t HdfGoodixChipInit(struct HdfDeviceObject *device) + { + ... + /* 器件配置结构体内存申请、配置信息解析及挂载 */ + chipCfg = ChipConfigInstance(device); + ... + /* 器件实例化 */ + chipDev = ChipDeviceInstance(); + ... + /* 器件信息挂载及器件私有操作挂载 */ + chipDev->chipCfg = chipCfg; + chipDev->ops = &g_gt911ChipOps; + ... + /* 注册器件驱动至平台驱动 */ + RegisterChipDevice(chipDev); + ... + } + struct HdfDriverEntry g_touchGoodixChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_GT911", // 该moduleName与device_info.hcs文件中器件驱动层的moduleName信息相匹配 + .Init = HdfGoodixChipInit, // 器件驱动初始化函数 + }; + HDF_INIT(g_touchGoodixChipEntry); // 注册器件驱动至HDF框架 + ``` + + 器件私有驱动层主要实现了各器件厂商差异较大的部分,如器件休眠唤醒、数据解析以及固件升级等。 + + 至此,基于HDF框架及Input模型的触摸屏驱动适配完成。 + + +## 编译及烧录 + +1. 编辑Makefile文件,添加本示例中的内容: + + 文件路径:./drivers/adapter/khdf/linux/model/input/Makefile + + 添加内容如下: + + ``` + obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \ + $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o + ``` + + 其中touch\_gt911.o为本示例中追加的内容。 + +2. 具体编译及烧录操作请参考[标准系统快速入门编译及烧录章节](../nottoctopics/zh-cn_topic_0000001135402541.md#section375234715135)。 + +## 调试验证 + +如下所示为开机启动日志部分截取 + +``` +[I/HDF_INPUT_DRV] HdfInputManagerInit: enter // 管理驱动层初始化 +[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // 初始化成功 +[I/osal_cdev] add cdev hdf_input_host success +[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // 公共驱动层初始化 +[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // 初始化成功 +[I/osal_cdev] add cdev hdf_input_event1 success +[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // 器件驱动层初始化 +[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060 +[I/HDF_INPUT_DRV] Product_ID: 911_1060, x_sol = 960, y_sol = 480 +[I/HDF_LOG_TAG] ChipDriverInit: chipDetect succ, ret = 0 +[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch +[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // 初始化成功 +``` + +## Input模型工作流程解析 + +为了让开发者更清晰的了解Input模型工作流程,本节将对input模型加载的关键流程代码进行说明。 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>本章节为Input模型工作流程说明,开发者无需进行开发。 + +### 私有配置信息解析 + +示例代码路径:./drivers/framework/model/input/driver/input\_config\_parser.c + +根据OSAL提供的配置解析函数,可以将hcs文件中各字段含义进行解析,具体请参考input\_config\_parser.c中各函数的实现。如果提供的模板不能满足需求,在hcs文件中添加相应信息后,需要根据添加的字段开发相应的解析函数。 + +``` +static int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode, BoardAttrCfg *attr) +{ + int32_t ret; + ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0); // 获取inputType字段信息,保存在BoardAttrCfg结构体中 + CHECK_PARSER_RET(ret, "GetUint8"); + ... + return HDF_SUCCESS; +} +``` + +### 管理驱动层初始化及注册驱动至HDF框架 + +示例代码路径:./drivers/framework/model/input/driver/hdf\_input\_device\_manager.c + +``` +static int32_t HdfInputManagerInit(struct HdfDeviceObject *device) +{ + /* 分配内存给manager,manager中将存放所有input设备 */ + g_inputManager = InputManagerInstance(); + ... +} +struct HdfDriverEntry g_hdfInputEntry = { + .moduleVersion = 1, + .moduleName = "HDF_INPUT_MANAGER", + .Bind = HdfInputManagerBind, + .Init = HdfInputManagerInit, + .Release = HdfInputManagerRelease, +}; + +HDF_INIT(g_hdfInputEntry); //驱动注册入口 +``` + +### 公共驱动层初始化及注册驱动至HDF框架 + +示例代码路径:./drivers/framework/model/input/driver/hdf\_touch.c + +``` +static int32_t HdfTouchDriverProbe(struct HdfDeviceObject *device) +{ + ... + /* 板级信息结构体内存申请及hcs配置信息解析 */ + boardCfg = BoardConfigInstance(device); + ... + /* 公共驱动结构体内存申请 */ + touchDriver = TouchDriverInstance(); + ... + /* 依据解析出的板级信息进行公共资源初始化,如IIC初始化 */ + ret = TouchDriverInit(touchDriver, boardCfg); + if (ret == HDF_SUCCESS) { + ... + /* 添加驱动至公共驱动层驱动管理链表,当设备与驱动进行绑定时使用该链表进行查询 */ + AddTouchDriver(touchDriver); + ... + } + ... +} +struct HdfDriverEntry g_hdfTouchEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH", + .Bind = HdfTouchDriverBind, + .Init = HdfTouchDriverProbe, + .Release = HdfTouchDriverRelease, +}; + +HDF_INIT(g_hdfTouchEntry); //驱动注册入口 +``` + +### 器件驱动层初始化及注册驱动至HDF框架 + +具体请参考[适配器件私有驱动](#section17127331595)器件层驱动初始化及注册驱动至HDF框架部分。 + +### 具体调用逻辑串联函数 + +Input模型管理层驱动init函数初始化了设备管理链表,公共驱动层初始化函数完成了相关结构体的内存申请。器件驱动相关信息通过RegisterChipDevice函数对公共驱动层相关结构体进行信息填充,同时完成了相关硬件信息的初始化(如中断注册等),绑定设备与驱动组成inputDev通过RegisterInputDevice函数向驱动管理层进行注册,在RegisterInputDevice函数中主要实现了将inputDev向设备管理链表的添加等功能。如下所示为两个函数的实现部分: + +``` +//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_touch.c +int32_t RegisterChipDevice(ChipDevice *chipDev) +{ + ... + /* 绑定设备与驱动,从而通过InputDeviceInstance函数创建inputDev */ + DeviceBindDriver(chipDev); + ... + /* 主要包含器件中断注册及中断处理函数,中断处理函数中有数据上报用户态的数据通道 */ + ChipDriverInit(chipDev); + ... + /* 申请内存实例化InputDev */ + inputDev = InputDeviceInstance(chipDev); + ... + /* 将InputDev设备注册至input驱动管理层 */ + RegisterInputDevice(inputDev); + ... +} + +//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_input_device_manager.c +int32_t RegisterInputDevice(InputDevice *inputDev) +{ + ... + /* 申请ID,该ID对于不同input设备唯一 */ + ret = AllocDeviceID(inputDev); + ... + /* 该函数包含了对hid类设备的特殊处理,对于触摸屏驱动,该函数无实质操作; */ + CreateDeviceNode(inputDev); + /* 内核态数据传送至用户态需使用IOService能力,需要申请buffer */ + AllocPackageBuffer(inputDev); + /* 将input设备添加进设备全局管理链表 */ + AddInputDevice(inputDev); + ... +} +``` + diff --git a/zh-cn/device-dev/guide/device-wifi-led-outcontrol.md b/zh-cn/device-dev/guide/device-wifi-led-outcontrol.md new file mode 100644 index 0000000000000000000000000000000000000000..2d4970fa19c09b4fc4140751446e32bbed4e7ee3 --- /dev/null +++ b/zh-cn/device-dev/guide/device-wifi-led-outcontrol.md @@ -0,0 +1,110 @@ +# LED外设控制 + +- [概述](#section14639174516337) +- [开发](#section13857170163412) +- [验证](#section1949121910344) + +## 概述 + +OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力,包含I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。本文介绍如何通过调用OpenHarmony的NDK接口,实现对GPIO控制,达到LED闪烁的效果。其他的IOT外设控制,开发者可根据API指导文档完成,此处不逐一介绍。 + +## 开发 + +1. 请先完成[《Hi3861快速入门》](../quick-start/quickstart-lite-introduction-hi3861.md#section19352114194115)。 + + LED控制参考示例存放于applications/sample/wifi-iot/app/iothardware/led\_example.c文件中。 + +2. 实现IOT外设控制,首先需要通过查阅原理图明确接线关系。经过查阅,hispark pegasus的LED与芯片的9号管脚相连。 + + ``` + #define LED_TEST_GPIO 9 + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >开发板原理图,请开发者联系Hi3861购买渠道客服获取。 + +3. 使用GPIO前,需要完成GPIO管脚初始化,明确管脚用途,并创建任务,使LED周期性亮灭,达到闪烁的效果。 + + ``` + static void LedExampleEntry(void) + { + osThreadAttr_t attr; + + /* 管脚初始化 */ + IoTGpioInit(LED_TEST_GPIO); + /* 配置9号管脚为输出方向 */ + IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT); + + attr.name = "LedTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = LED_TASK_STACK_SIZE; + attr.priority = LED_TASK_PRIO; + + /* 启动任务 */ + if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) { + printf("[LedExample] Failed to create LedTask!\n"); + } + } + ``` + +4. 在循环任务中通过周期性亮灭形式实现LED闪烁。 + + ``` + static void *LedTask(const char *arg) + { + (void)arg; + while (1) { + switch (g_ledState) { + case LED_ON: + IoTGpioSetOutputVal(LED_TEST_GPIO, 1); + usleep(LED_INTERVAL_TIME_US); + break; + case LED_OFF: + IoTGpioSetOutputVal(LED_TEST_GPIO, 0); + usleep(LED_INTERVAL_TIME_US); + break; + case LED_SPARK: + IoTGpioSetOutputVal(LED_TEST_GPIO, 0); + usleep(LED_INTERVAL_TIME_US); + IoTGpioSetOutputVal(LED_TEST_GPIO, 1); + usleep(LED_INTERVAL_TIME_US); + break; + default: + usleep(LED_INTERVAL_TIME_US); + break; + } + } + return NULL; + } + ``` + +5. 在代码最下方,使用OpenHarmony启动恢复模块接口SYS\_RUN\(\)启动业务。(SYS\_RUN定义在ohos\_init.h文件中) + + ``` + SYS_RUN(LedExampleEntry); + ``` + +6. 修改applications/sample/wifi-iot/app/BUILD.gn文件,使led\_example.c参与编译。 + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("app") { + features = [ + "iothardware:led_example" + ] + } + ``` + + +## 验证 + +编译过程请参考《[Hi3861快速入门-源码编译](../quick-start/quickstart-lite-steps-board3861-connection.md#section191121332125319)》,烧录过程请参考《[Hi3861快速入门-镜像烧录](../quick-start/quickstart-lite-steps-board3861-connection.md#section19458165166)》。 + +完成以上两步后,按下RST键复位模组,可发现LED在周期性闪烁,与预期相符,验证完毕。 + +**图 1** LED闪烁图 +![](figure/LED闪烁图.gif "LED闪烁图") + diff --git a/zh-cn/device-dev/guide/device-wifi-sdk.md b/zh-cn/device-dev/guide/device-wifi-sdk.md new file mode 100644 index 0000000000000000000000000000000000000000..8106f68cd6202a165547b6db59ae734fe01e6e6b --- /dev/null +++ b/zh-cn/device-dev/guide/device-wifi-sdk.md @@ -0,0 +1,325 @@ +# 集成三方SDK + +- [规划目录结构](#section1736472718351) +- [构建业务libs](#section442815485351) +- [编写适配代码](#section3984721113613) +- [代码编写](#section830417531286) +- [脚本编写](#section13500201173710) +- [编写业务代码](#section8754114803918) +- [运行](#section7737749184012) +- [结束](#section153301392411) + +OpenHarmony致力于打造一套更加开放完善的IoT生态系统,为此OpenHarmony规划了一组目录,用于将各厂商的SDK集成到OpenHarmony中。本文档基于Hi3861开发板,向平台开发者介绍将SDK集成到OpenHarmony的方法。 + +## 规划目录结构 + +三方SDK通常由静态库和适配代码构成。SDK的业务逻辑通过硬件模组工具链编译得到静态库libs,每款模组都有其对应的libs。SDK的南向API与OpenHarmony 的API存在使用差异,该差异可通过adapter适配代码屏蔽,不同模组可共用一套adapter。 + +基于以上特征,在OpenHarmony目录结构中,可以对三方SDK目录做如下划分。 + +- 适配代码adapter,放置到domains/iot/link/ 目录下,与模组解耦。 +- 业务库libs,放置到device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/ 目录下,与模组绑定。 + +平台开发者在适配前,务必先依次完成以下步骤,下面以demolink SDK举例,进行介绍。 + +1. 创建厂商目录,domains/iot/link/demolink/、device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/ ,用于厂商隔离。 +2. 创建domains/iot/link/demolink/BUILD.gn ,用于构建适配代码。 +3. 创建device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录,用于存放业务库libs。 + +``` +. +├── domains +│ └── iot +│ └── link +│ ├── demolink +│ │ └── BUILD.gn +│ ├── libbuild +│ │ └── BUILD.gn +│ └── BUILD.gn +└── device + └── hisilicon + └── hispark_pegasus + └── sdk_liteos + └── 3rd_sdk + └── demolink + └── libs +``` + +## 构建业务libs + +平台SDK业务一般以静态库的形式提供,平台厂商在获取到OpenHarmony代码后,需要根据对应的硬件模组vendor,编译业务libs,并将编译结果放置在device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录下。下面介绍业务libs的构建方法。 + +OpenHarmony已规划用于编译业务libs的目录domains/iot/link/libbuild/ ,该目录中包含domains/iot/link/libbuild/BUILD.gn和domains/iot/link/BUILD.gn文件,目录结构如下。 + +``` +. +└── domains + └── iot + └── link + ├── demolink + │ └── BUILD.gn + ├── libbuild + │ └── BUILD.gn + └── BUILD.gn +``` + +平台开发者在构建libs前,务必先完成如下步骤。 + +1. 在domains/iot/link/libbuild/ 目录下放置业务源码文件,包括.c和.h文件。 + + ``` + . + └── domains + └── iot + └── link + ├── demolink + │ ├── demosdk_adapter.c + │ ├── demosdk_adapter.h + │ └── BUILD.gn + ├── libbuild + │ ├── demosdk.c + │ ├── demosdk.h + │ └── BUILD.gn + └── BUILD.gn + ``` + +2. 适配domains/iot/link/libbuild/BUILD.gn,在编译完成后还原该文件。 + + 在BUILD.gn中,sources为需要参与构建的源文件,include\_dirs为依赖的头文件路径,构建的目标结果是生成静态库libdemosdk.a。 + + ``` + static_library("demosdk") { + sources = [ + "demosdk.c" + ] + include_dirs = [ + "//domains/iot/link/libbuild", + "//domains/iot/link/demolink" + ] + } + ``` + +3. 适配domains/iot/link/BUILD.gn,在编译完成后还原该文件。 + + 此BUILD.gn文件用于指定构建条目,需要在features中填入所有需参与编译的静态库条目,使domains/iot/link/libbuild/BUILD.gn参与到构建中来。 + + ``` + import("//build/lite/config/subsystem/lite_subsystem.gni") + import("//build/lite/config/component/lite_component.gni") + lite_subsystem("iot") { + subsystem_components = [ + ":link" + ] + } + lite_component("link") { + features = [ + "libbuild:demosdk" + ] + } + ``` + + +完成以上3点后,需在代码根目录下执行命令“hb build -T //domains/iot/link:iot”,等待执行完成,检查out/hispark\_pegasus/wifiiot\_hispark\_pegasus/libs/目录下是否生成了目标库文件。 + +![](figure/zh-cn_image_0000001078563230.png) + +将库文件拷贝到device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录下,并将domains/iot/link/libbuild/ 目录中的.c和.h文件清除。 + +## 编写适配代码 + +## 代码编写 + +平台SDK中使用的API通常与OpenHarmony API存在差异,无法直接使用,需要一层适配代码adapter进行中间转换。本节以domains/iot/link/demolink/demosdk\_adapter.c中的任务创建接口DemoSdkCreateTask举例,向开发者演示如何在OpenHarmony上编写适配代码。 + +1. 查看待适配接口DemoSdkCreateTask的描述、参数、返回值。 + + ``` + struct TaskPara { + char *name; + void *(*func)(char* arg); + void *arg; + unsigned char prio; + unsigned int size; + }; + + /* + * IoT OS 创建线程接口 + * 返回值: 返回0 成功, 其他 失败 + */ + int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para); + ``` + +2. 查看OpenHarmony API接口文档,选取一个功能类似的接口,并比对参数及用法上的差异。例如本文选取osThreadNew ,通过和DemoSdkCreateTask接口比对,可以发现两接口依赖的参数基本一致,只是参数所归属的结构体不同。 + + ``` + typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) + } osThreadAttr_t; + + /// Create a thread and add it to Active Threads. + /// \param[in] func thread function. + /// \param[in] argument pointer that is passed to the thread function as start argument. + /// \param[in] attr thread attributes; NULL: default values. + /// \return thread ID for reference by other functions or NULL in case of error. + osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + ``` + +3. 完成代码差异转换。 + + ``` + int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para) + { + osThreadAttr_t attr = {0}; + osThreadId_t threadId; + if (handle == 0 || para == 0) { + return DEMOSDK_ERR; + } + if (para->func == 0) { + return DEMOSDK_ERR; + } + if (para->name == 0) { + return DEMOSDK_ERR; + } + attr.name = para->name; + attr.priority = para->prio; + attr.stack_size = para->size; + threadId = osThreadNew((osThreadFunc_t)para->func, para->arg, &attr); + if (threadId == 0) { + printf("osThreadNew fail\n"); + return DEMOSDK_ERR; + } + *(unsigned int *)handle = (unsigned int)threadId; + return DEMOSDK_OK; + } + ``` + + +## 脚本编写 + +开发者在完成代码适配后,还需要在adapter同级目录下新建BUILD.gn文件。该文件可在整包构建时,将适配代码编译成静态库,并链接到bin包中去。在domains/iot/link/demolink/BUILD.gn中,sources中为需要参与构建的源文件,include\_dirs中为依赖的头文件路径,构建目标结果是生产静态库libdemolinkadapter.a。 + +``` +import("//build/lite/config/component/lite_component.gni") +static_library("demolinkadapter") { + sources = [ + "demosdk_adapter.c" + ] + include_dirs = [ + "//kernel/liteos-m/kal/cmsis", + "//domains/iot/link/demolink" + ] +} +``` + +修改domains/iot/link/BUILD.gn文件,使domain/iot/hilink/BUILD.gn参与到构建系统中。 + +``` +import("//build/lite/config/subsystem/lite_subsystem.gni") +import("//build/lite/config/component/lite_component.gni") +lite_subsystem("iot") { + subsystem_components = [ + ":link" + ] +} +lite_component("link") { + features = [ + "demolink:demolinkadapter" + ] +} +``` + +## 编写业务代码 + +业务libs库和适配代码准备就绪后,还需要编写业务入口函数,调起三方SDK的业务入口。 + +下面以demolink举例,介绍如何在applications/sample/wifi-iot/app/路径下编写代码,调起demosdk的入口函数。 + +1. 目录创建 + + 开发者编写业务时,务必先在applications/sample/wifi-iot/app/ 路径下新建一个目录(或一套目录结构),用于存放业务源码文件。 + + 例如:在app下新增业务目录demolink,并在其中创建业务入口代码helloworld.c和编译构建文件BUILD.gn,如下。 + + ``` + . + └── applications + └── sample + └── wifi-iot + └── app + │── demolink + │ │── helloworld.c + │ └── BUILD.gn + └── BUILD.gn + ``` + +2. 编写业务代码。 + + 在helloworld.c文件中编写业务入口函数DemoSdkMain,并调起demolink的业务DemoSdkEntry,最后通过SYS\_RUN\(\)调用入口函数完成业务启动。 + + ``` + #include "hos_init.h" + #include "demosdk.h" + + void DemoSdkMain(void) + { + DemoSdkEntry(); + } + + SYS_RUN(DemoSdkMain); + ``` + +3. 编写构建脚本 + + 新增applications/sample/wifi-iot/app/demolink/BUILD.gn文件,指定源码和头文件路径,编译输出静态库文件libexample\_demolink.a。 + + ``` + static_library("example_demolink") { + sources = [ + "helloworld.c" + ] + include_dirs = [ + "//utils/native/lite/include", + "//domains/iot/link/libbuild" + ] + } + ``` + + 修改applications/sample/wifi-iot/app/BUILD.gn,使demolink参与编译。 + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("app") { + features = [ + "demolink:example_demolink" + ] + } + ``` + + +## 运行 + +在代码根目录下,执行命令“hb build”编译输出版本包。最后启动运行,运行结果如图所示,与demolink预期相符。 + +``` +ready to OS start +sdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00 +formatting spiffs... +FileSystem mount ok. +wifi init success! +it is demosdk entry. +it is demo biz: hello world. +it is demo biz: hello world. +``` + +## 结束 + +至此,三方SDK集成已介绍完毕。 + diff --git a/zh-cn/device-dev/guide/device-wifi.md b/zh-cn/device-dev/guide/device-wifi.md new file mode 100644 index 0000000000000000000000000000000000000000..3f85bc6f6c8626e1314093b28146dc989ee55167 --- /dev/null +++ b/zh-cn/device-dev/guide/device-wifi.md @@ -0,0 +1,7 @@ +# WLAN连接类产品 + +- **[LED外设控制](device-wifi-led-outcontrol.md)** + +- **[集成三方SDK](device-wifi-sdk.md)** + + diff --git a/zh-cn/device-dev/guide/device.md b/zh-cn/device-dev/guide/device.md new file mode 100644 index 0000000000000000000000000000000000000000..1cb2d60315d1a1a78b6b1452c4a4167bbc48ab8a --- /dev/null +++ b/zh-cn/device-dev/guide/device.md @@ -0,0 +1,15 @@ +# 设备开发指南 + +- **[WLAN连接类产品](device-wifi.md)** + +- **[无屏摄像头类产品](device-iotcamera.md)** + +- **[带屏摄像头类产品](device-camera.md)** + +- **[时钟应用开发指导](device-clock-guide.md)** + +- **[平台驱动开发示例](device-driver-demo.md)** + +- **[外设驱动开发示例](device-outerdriver-demo.md)** + + diff --git a/zh-cn/device-dev/guide/figures/Clock.png b/zh-cn/device-dev/guide/figure/Clock.png similarity index 100% rename from zh-cn/device-dev/guide/figures/Clock.png rename to zh-cn/device-dev/guide/figure/Clock.png diff --git "a/zh-cn/device-dev/guide/figures/LED\351\227\252\347\203\201\345\233\276.gif" "b/zh-cn/device-dev/guide/figure/LED\351\227\252\347\203\201\345\233\276.gif" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/LED\351\227\252\347\203\201\345\233\276.gif" rename to "zh-cn/device-dev/guide/figure/LED\351\227\252\347\203\201\345\233\276.gif" diff --git a/zh-cn/device-dev/guide/figures/Video_2020-07-25_173141.gif b/zh-cn/device-dev/guide/figure/Video_2020-07-25_173141.gif old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/guide/figures/Video_2020-07-25_173141.gif rename to zh-cn/device-dev/guide/figure/Video_2020-07-25_173141.gif diff --git a/zh-cn/device-dev/guide/figures/zh-cn_image_0000001078563230.png b/zh-cn/device-dev/guide/figure/zh-cn_image_0000001078563230.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/guide/figures/zh-cn_image_0000001078563230.png rename to zh-cn/device-dev/guide/figure/zh-cn_image_0000001078563230.png diff --git a/zh-cn/device-dev/guide/figures/zh-cn_image_0000001082434703.png b/zh-cn/device-dev/guide/figure/zh-cn_image_0000001082434703.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/guide/figures/zh-cn_image_0000001082434703.png rename to zh-cn/device-dev/guide/figure/zh-cn_image_0000001082434703.png diff --git a/zh-cn/device-dev/guide/figures/zh-cn_image_0000001161922745.png b/zh-cn/device-dev/guide/figure/zh-cn_image_0000001169991055.png similarity index 100% rename from zh-cn/device-dev/guide/figures/zh-cn_image_0000001161922745.png rename to zh-cn/device-dev/guide/figure/zh-cn_image_0000001169991055.png diff --git "a/zh-cn/device-dev/guide/figures/\345\220\257\345\212\250\347\244\272\344\276\213.png" "b/zh-cn/device-dev/guide/figure/\345\220\257\345\212\250\347\244\272\344\276\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\345\220\257\345\212\250\347\244\272\344\276\213.png" rename to "zh-cn/device-dev/guide/figure/\345\220\257\345\212\250\347\244\272\344\276\213.png" diff --git "a/zh-cn/device-dev/guide/figures/\345\256\214\346\225\264\345\267\245\347\250\213\347\233\256\345\275\225.png" "b/zh-cn/device-dev/guide/figure/\345\256\214\346\225\264\345\267\245\347\250\213\347\233\256\345\275\225.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\345\256\214\346\225\264\345\267\245\347\250\213\347\233\256\345\275\225.png" rename to "zh-cn/device-dev/guide/figure/\345\256\214\346\225\264\345\267\245\347\250\213\347\233\256\345\275\225.png" diff --git "a/zh-cn/device-dev/guide/figures/\345\267\245\347\250\213\347\233\256\345\275\225.png" "b/zh-cn/device-dev/guide/figure/\345\267\245\347\250\213\347\233\256\345\275\225.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\345\267\245\347\250\213\347\233\256\345\275\225.png" rename to "zh-cn/device-dev/guide/figure/\345\267\245\347\250\213\347\233\256\345\275\225.png" diff --git "a/zh-cn/device-dev/guide/figures/\346\237\245\347\234\213\346\226\207\344\273\266\345\233\276.png" "b/zh-cn/device-dev/guide/figure/\346\237\245\347\234\213\346\226\207\344\273\266\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\346\237\245\347\234\213\346\226\207\344\273\266\345\233\276.png" rename to "zh-cn/device-dev/guide/figure/\346\237\245\347\234\213\346\226\207\344\273\266\345\233\276.png" diff --git "a/zh-cn/device-dev/guide/figures/\346\240\207\351\242\230\346\240\217\345\222\214\344\277\241\346\201\257\346\240\217\346\225\210\346\236\234.png" "b/zh-cn/device-dev/guide/figure/\346\240\207\351\242\230\346\240\217\345\222\214\344\277\241\346\201\257\346\240\217\346\225\210\346\236\234.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\346\240\207\351\242\230\346\240\217\345\222\214\344\277\241\346\201\257\346\240\217\346\225\210\346\236\234.png" rename to "zh-cn/device-dev/guide/figure/\346\240\207\351\242\230\346\240\217\345\222\214\344\277\241\346\201\257\346\240\217\346\225\210\346\236\234.png" diff --git "a/zh-cn/device-dev/guide/figures/\346\240\207\351\242\230\346\240\217\346\225\210\346\236\234.png" "b/zh-cn/device-dev/guide/figure/\346\240\207\351\242\230\346\240\217\346\225\210\346\236\234.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\346\240\207\351\242\230\346\240\217\346\225\210\346\236\234.png" rename to "zh-cn/device-dev/guide/figure/\346\240\207\351\242\230\346\240\217\346\225\210\346\236\234.png" diff --git "a/zh-cn/device-dev/guide/figures/\346\241\214\351\235\242.png" "b/zh-cn/device-dev/guide/figure/\346\241\214\351\235\242.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\346\241\214\351\235\242.png" rename to "zh-cn/device-dev/guide/figure/\346\241\214\351\235\242.png" diff --git "a/zh-cn/device-dev/guide/figures/\346\267\273\345\212\240\351\241\265\351\235\242.png" "b/zh-cn/device-dev/guide/figure/\346\267\273\345\212\240\351\241\265\351\235\242.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\346\267\273\345\212\240\351\241\265\351\235\242.png" rename to "zh-cn/device-dev/guide/figure/\346\267\273\345\212\240\351\241\265\351\235\242.png" diff --git "a/zh-cn/device-dev/guide/figures/\347\273\230\345\233\2761.png" "b/zh-cn/device-dev/guide/figure/\347\273\230\345\233\2761.png" similarity index 100% rename from "zh-cn/device-dev/guide/figures/\347\273\230\345\233\2761.png" rename to "zh-cn/device-dev/guide/figure/\347\273\230\345\233\2761.png" diff --git "a/zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\345\275\225\345\203\217\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" "b/zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\345\275\225\345\203\217\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\345\275\225\345\203\217\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" rename to "zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\345\275\225\345\203\217\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" diff --git "a/zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\346\213\215\347\205\247\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" "b/zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\346\213\215\347\205\247\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\346\213\215\347\205\247\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" rename to "zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\346\213\215\347\205\247\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" diff --git "a/zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\351\241\265\351\235\242\345\220\215\347\247\260.png" "b/zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\351\241\265\351\235\242\345\220\215\347\247\260.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\351\241\265\351\235\242\345\220\215\347\247\260.png" rename to "zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\351\241\265\351\235\242\345\220\215\347\247\260.png" diff --git "a/zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\351\242\204\350\247\210\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" "b/zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\351\242\204\350\247\210\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\350\276\223\345\205\245\351\242\204\350\247\210\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" rename to "zh-cn/device-dev/guide/figure/\350\276\223\345\205\245\351\242\204\350\247\210\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" diff --git "a/zh-cn/device-dev/guide/figures/\350\276\223\345\207\272\351\200\200\345\207\272\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" "b/zh-cn/device-dev/guide/figure/\350\276\223\345\207\272\351\200\200\345\207\272\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\350\276\223\345\207\272\351\200\200\345\207\272\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" rename to "zh-cn/device-dev/guide/figure/\350\276\223\345\207\272\351\200\200\345\207\272\346\214\207\344\273\244\345\220\216\344\270\262\345\217\243\346\211\223\345\215\260\346\227\245\345\277\227.png" diff --git "a/zh-cn/device-dev/guide/figures/\351\241\265\351\235\242\344\275\215\347\275\256\346\214\207\347\244\272\345\231\250\346\225\210\346\236\234\345\233\276.png" "b/zh-cn/device-dev/guide/figure/\351\241\265\351\235\242\344\275\215\347\275\256\346\214\207\347\244\272\345\231\250\346\225\210\346\236\234\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\351\241\265\351\235\242\344\275\215\347\275\256\346\214\207\347\244\272\345\231\250\346\225\210\346\236\234\345\233\276.png" rename to "zh-cn/device-dev/guide/figure/\351\241\265\351\235\242\344\275\215\347\275\256\346\214\207\347\244\272\345\231\250\346\225\210\346\236\234\345\233\276.png" diff --git "a/zh-cn/device-dev/guide/figures/\351\242\204\350\247\210\346\225\210\346\236\234.jpg" "b/zh-cn/device-dev/guide/figure/\351\242\204\350\247\210\346\225\210\346\236\234.jpg" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/figures/\351\242\204\350\247\210\346\225\210\346\236\234.jpg" rename to "zh-cn/device-dev/guide/figure/\351\242\204\350\247\210\346\225\210\346\236\234.jpg" diff --git a/zh-cn/device-dev/guide/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/guide/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/guide/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/guide/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/guide/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/guide/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/guide/public_sys-resources/icon-note.gif b/zh-cn/device-dev/guide/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/guide/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/guide/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/guide/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/guide/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/guide/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/guide/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/guide/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/guide/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/guide/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/guide/public_sys-resources/icon-warning.gif and /dev/null differ diff --git "a/zh-cn/device-dev/guide/\345\205\254\345\205\261\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" "b/zh-cn/device-dev/guide/\345\205\254\345\205\261\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" deleted file mode 100644 index 31de19a1b135135ed4b6481331284bdb35200aee..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\205\254\345\205\261\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" +++ /dev/null @@ -1,35 +0,0 @@ -# 公共驱动层初始化及注册驱动至HDF框架 - -示例代码路径:./drivers/framework/model/input/driver/hdf\_touch.c - -``` -static int32_t HdfTouchDriverProbe(struct HdfDeviceObject *device) -{ - ... - /* 板级信息结构体内存申请及hcs配置信息解析 */ - boardCfg = BoardConfigInstance(device); - ... - /* 公共驱动结构体内存申请 */ - touchDriver = TouchDriverInstance(); - ... - /* 依据解析出的板级信息进行公共资源初始化,如IIC初始化 */ - ret = TouchDriverInit(touchDriver, boardCfg); - if (ret == HDF_SUCCESS) { - ... - /* 添加驱动至公共驱动层驱动管理链表,当设备与驱动进行绑定时使用该链表进行查询 */ - AddTouchDriver(touchDriver); - ... - } - ... -} -struct HdfDriverEntry g_hdfTouchEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH", - .Bind = HdfTouchDriverBind, - .Init = HdfTouchDriverProbe, - .Release = HdfTouchDriverRelease, -}; - -HDF_INIT(g_hdfTouchEntry); //驱动注册入口 -``` - diff --git "a/zh-cn/device-dev/guide/\345\205\267\344\275\223\350\260\203\347\224\250\351\200\273\350\276\221\344\270\262\350\201\224\345\207\275\346\225\260.md" "b/zh-cn/device-dev/guide/\345\205\267\344\275\223\350\260\203\347\224\250\351\200\273\350\276\221\344\270\262\350\201\224\345\207\275\346\225\260.md" deleted file mode 100644 index 9fc526d2109ecffd5cec6f672a85e5f8f6b173f0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\205\267\344\275\223\350\260\203\347\224\250\351\200\273\350\276\221\344\270\262\350\201\224\345\207\275\346\225\260.md" +++ /dev/null @@ -1,40 +0,0 @@ -# 具体调用逻辑串联函数 - -Input模型管理层驱动init函数初始化了设备管理链表,公共驱动层初始化函数完成了相关结构体的内存申请。器件驱动相关信息通过RegisterChipDevice函数对公共驱动层相关结构体进行信息填充,同时完成了相关硬件信息的初始化(如中断注册等),绑定设备与驱动组成inputDev通过RegisterInputDevice函数向驱动管理层进行注册,在RegisterInputDevice函数中主要实现了将inputDev向设备管理链表的添加等功能。如下所示为两个函数的实现部分: - -``` -//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_touch.c -int32_t RegisterChipDevice(ChipDevice *chipDev) -{ - ... - /* 绑定设备与驱动,从而通过InputDeviceInstance函数创建inputDev */ - DeviceBindDriver(chipDev); - ... - /* 主要包含器件中断注册及中断处理函数,中断处理函数中有数据上报用户态的数据通道 */ - ChipDriverInit(chipDev); - ... - /* 申请内存实例化InputDev */ - inputDev = InputDeviceInstance(chipDev); - ... - /* 将InputDev设备注册至input驱动管理层 */ - RegisterInputDevice(inputDev); - ... -} - -//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_input_device_manager.c -int32_t RegisterInputDevice(InputDevice *inputDev) -{ - ... - /* 申请ID,该ID对于不同input设备唯一 */ - ret = AllocDeviceID(inputDev); - ... - /* 该函数包含了对hid类设备的特殊处理,对于触摸屏驱动,该函数无实质操作; */ - CreateDeviceNode(inputDev); - /* 内核态数据传送至用户态需使用IOService能力,需要申请buffer */ - AllocPackageBuffer(inputDev); - /* 将input设备添加进设备全局管理链表 */ - AddInputDevice(inputDev); - ... -} -``` - diff --git "a/zh-cn/device-dev/guide/\345\231\250\344\273\266\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" "b/zh-cn/device-dev/guide/\345\231\250\344\273\266\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" deleted file mode 100644 index 4cfddfa469ff7d5812667549270c01baf14befe0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\231\250\344\273\266\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 器件驱动层初始化及注册驱动至HDF框架 - -具体请参考[3.3章节](适配器件私有驱动.md)器件层驱动初始化及注册驱动至HDF框架部分。 - diff --git "a/zh-cn/device-dev/guide/\345\244\226\350\256\276\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/guide/\345\244\226\350\256\276\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100644 index 8b083827126708b7db7f7d283ed2f34fa392a9ae..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\244\226\350\256\276\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 外设驱动开发示例 - -- **[概述](概述-12.md)** - -- **[环境搭建](环境搭建.md)** - -- **[TouchScreen器件驱动开发](TouchScreen器件驱动开发.md)** - -- **[编译及烧录](编译及烧录-13.md)** - -- **[调试验证](调试验证.md)** - -- **[Input模型工作流程解析](Input模型工作流程解析.md)** - - diff --git "a/zh-cn/device-dev/guide/\345\261\217\345\271\225\345\222\214\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" "b/zh-cn/device-dev/guide/\345\261\217\345\271\225\345\222\214\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" deleted file mode 100755 index 7fed33d8a7778766da71be14c1704a1ebb08b0b6..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\261\217\345\271\225\345\222\214\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 屏幕和摄像头控制 - -- **[概述](概述-1.md)** - -- **[示例开发](示例开发-2.md)** - -- **[应用实例](应用实例-5.md)** - - diff --git "a/zh-cn/device-dev/guide/\345\270\246\345\261\217\346\221\204\345\203\217\345\244\264\347\261\273\344\272\247\345\223\201.md" "b/zh-cn/device-dev/guide/\345\270\246\345\261\217\346\221\204\345\203\217\345\244\264\347\261\273\344\272\247\345\223\201.md" deleted file mode 100755 index 0dacd47e009d1b132a2d52dda4d6c6aaa59e10cb..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\270\246\345\261\217\346\221\204\345\203\217\345\244\264\347\261\273\344\272\247\345\223\201.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 带屏摄像头类产品 - -- **[屏幕和摄像头控制](屏幕和摄像头控制.md)** - -- **[视觉应用开发](视觉应用开发.md)** - - diff --git "a/zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" "b/zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" deleted file mode 100644 index 24be5472457cc6266e3a7f55040bdc377de2639d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" +++ /dev/null @@ -1,39 +0,0 @@ -# 常见问题 - -- [hdc\_std连接不到设备](#section1221016541119) -- [hdc\_std运行不了](#section219185710311) - -## hdc\_std连接不到设备 - -- **现象描述** - - 执行 "hdc\_std list targets"命令后结果为:\[Empty\] - -- **可能原因和解决方法** - 1. 设备没有被识别: - - 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 - - 2. hdc\_std工作异常: - - 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 - - 如果一直获取不到设备信息,请在任务管理器中查询是否有adb进程,该进程可能会对hdc产生干扰,可以将其杀掉后重复执行上面的步骤。 - - 3. hdc\_std与设备不匹配: - - 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 - - - -## hdc\_std运行不了 - -- **现象描述** - - 点击hdc\_std.exe文件无法运行。 - -- **可能原因和解决方法** - - hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 - - diff --git "a/zh-cn/device-dev/guide/\345\271\263\345\217\260\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/guide/\345\271\263\345\217\260\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100644 index 5dc1dd07b55fff2f60df94e5d132d3f02dc1db71..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\271\263\345\217\260\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 平台驱动开发示例 - -- **[概述](概述-10.md)** - -- **[环境准备](环境准备.md)** - -- **[开发](开发-11.md)** - -- **[编译及烧录](编译及烧录.md)** - - diff --git "a/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213-5.md" "b/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213-5.md" deleted file mode 100755 index a5da7138f9cbb55e51201fe4f6da8df0c9de54d5..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213-5.md" +++ /dev/null @@ -1,63 +0,0 @@ -# 应用实例 - -本示例将运行源码中的camera示例代码,通过本示例可以实现对开发板拍照、录像及预览功能的控制。 - -- 本示例源码路径为“applications/sample/camera/media/camera\_sample.cpp”。 -- 在运行本示例前需先完成编译烧录、运行镜像等步骤,相关操作请参考[Hi3516快速入门](../quick-start/Hi3516开发板介绍.md) - - >![](public_sys-resources/icon-note.gif) **说明:** - >开发板启动后默认会加载launcher应用,应用的图形界面默认显示在媒体图层上方,会影响camera\_sample的演示结果,因此需要在编译或是打包时去掉launcher应用。 - >**修改方法:**将“build/lite/components/applications.json”中camera\_sample\_app组件的targets中"//applications/sample/camera/launcher:launcher\_hap"整行注释或删除。 - -- 本示例编译结果路径为“out/hi3516dv300/ipcamera\_hi3516dv300\_liteos/dev\_tools/bin”,为让文件能在单板中执行,可将示例文件通过读卡器复制至TF卡中,或者修改camera\_sample的编译脚本将结果文件复制至rootfs.img中。 - - 修改源码路径“applications/sample/camera/media/BUILD.gn”中第一处的output\_dir。 - - - 修改前:output\_dir = "$root\_out\_dir/dev\_ools" - - 修改后:output\_dir = "$root\_out\_dir/" - - 重新执行源码仓编译并烧写入单板后,可在单板bin目录下找到camera\_sample文件。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >实例运行拍照和录像功能需要插入TF卡\(最大容量支持128GB\),系统启动后自动将TF卡挂载至/sdcard目录,如果在启动后插入则需要手动挂载。查看拍照和录像内容可将TF卡中内容复制到电脑中进行查看,预览功能无需TF卡。 - -- 接下来可通过以下步骤运行示例: - -1. 通过cd命令进入可执行程序的末端路径,启动camera\_sample,执行命令如下图。 - - **图 1** 启动示例 - ![](figures/启动示例.png "启动示例") - - 运行后的控制命令如串口打印所示,按s键停止当前操作(包括录像和预览),按q键退出示例程序。 - -2. 按1进行拍照,拍照的文件格式为jpg,存储在/sdcard,文件名Capture\* - - **图 2** 输入拍照指令后串口打印日志 - ![](figures/输入拍照指令后串口打印日志.png "输入拍照指令后串口打印日志") - - 若想查看保存文件,可在退出程序后进入文件系统查看,退出后重新进入请回到步骤1。 - - **图 3** 查看文件图 - ![](figures/查看文件图.png "查看文件图") - -3. 按2进行录像,录像的文件格式为mp4,存储在/sdcard,文件名Record\*,按s键停止 - - **图 4** 输入录像指令后串口打印日志 - ![](figures/输入录像指令后串口打印日志.png "输入录像指令后串口打印日志") - -4. 按3进行预览,预览图像直接送至显示屏,按s键停止。 - - **图 5** 输入预览指令后串口打印日志 - ![](figures/输入预览指令后串口打印日志.png "输入预览指令后串口打印日志") - - 预览效果如下 - - **图 6** 预览效果 - ![](figures/预览效果.jpg "预览效果") - -5. 按q键退出 - - **图 7** 输出退出指令后串口打印日志 - ![](figures/输出退出指令后串口打印日志.png "输出退出指令后串口打印日志") - - diff --git "a/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 21cb165165fec20314a38415096eb0959a94869d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,45 +0,0 @@ -# 应用实例 - -- 开发板介绍、编译烧录、运行镜像等操作请参考[Hi3518快速入门](../quick-start/Hi3518开发板介绍.md),编译结果包含示例,结果文件为out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample,可将文件通过读卡器复制至TF卡中,或者修改camera\_sample的编译脚本将结果文件复制至rootfs.img中。 - - 修改applications/sample/camera/media/BUILD.gn中的output\_dir。 - - - 修改前:output\_dir = "$root\_out\_dir/dev\_tools" - - 修改后:output\_dir = "$root\_out\_d_i_r/" - - 重新执行源码仓编译并烧写入单板后,可在单板bin目录下找到camera\_sample文件。 - -- 相机示例代码为applications/sample/camera/media/camera\_sample.cpp。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >实例运行拍照和录像功能需要插入TF卡\(最大容量支持128GB\),系统启动后时自动将TF卡挂载至/sdcard目录,如果在启动后插入则需要手动挂载。查看拍照和录像内容可将TF卡中内容复制到电脑中进行查看,预览功能无需TF卡。 - - -1. 通过cd命令进入可执行程序的末端路径,启动camera\_sample,执行命令如下图。 - - **图 1** 启动示例 - ![](figures/启动示例.png "启动示例") - - 运行后的控制命令如串口打印所示,按s键停止当前操作(包括录像和预览),按q键退出示例程序。 - -2. 按1进行拍照,拍照的文件格式为jpg,存储在/sdcard,文件名Capture\* - - **图 2** 输入拍照指令后串口打印日志 - ![](figures/输入拍照指令后串口打印日志.png "输入拍照指令后串口打印日志") - - 若想查看保存文件,可在退出程序后进入文件系统查看,退出后重新进入请回到步骤1。 - - **图 3** 查看文件图 - ![](figures/查看文件图.png "查看文件图") - -3. 按2进行录像,录像的文件格式为mp4,存储在/sdcard,文件名Record\*,按s键停止 - - **图 4** 输入录像指令后串口打印日志 - ![](figures/输入录像指令后串口打印日志.png "输入录像指令后串口打印日志") - -4. 按q键退出 - - **图 5** 输出退出指令后串口打印日志 - ![](figures/输出退出指令后串口打印日志.png "输出退出指令后串口打印日志") - - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221-11.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221-11.md" deleted file mode 100644 index a7dedada78968ebaaf7e6f721e9ec4d7cf41994c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221-11.md" +++ /dev/null @@ -1,396 +0,0 @@ -# 开发 - -- [实例化驱动入口](#section6586911816) -- [设置相关参数](#section114323217503) -- [添加控制器](#section115187812516) - -平台驱动开发包含以下几步: - -1. 实例化驱动入口: 实例化一个HdfDriverEntry 对象作为驱动入口。 -2. 设置相关参数:通过配置device\_info.hcs,并从HCS获取并解析设备的配置参数以确保驱动能够正确加载。 -3. 添加控制器:初始化控制器硬件,并调用核心层接口完成向核心层添加、删除设备,以及钩子函数的实现等。 - -本例中涉及的文件及路径如下表: - -**表 1** 文件说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

说明

-

文件路径

-

操作

-

示例文件

-

/drivers/adapter/khdf/linux/platform/i2c/i2c_sample.c

-

新增文件

-

设备服务文件

-

/drivers/adapter/khdf/linux/hcs/device_info/device_info.hcs

-

-

追加内容

-

-

配置参数文件

-

/drivers/adapter/khdf/linux/hcs/platform/i2c_config.hcs

-

编译文件

-

/drivers/adapter/khdf/linux/platform/i2c/Makefile

-

依赖头文件

-

/drivers/framework/include/core/hdf_device_desc.h

-

作为头文件引用

-

-

核心层头文件

-

/drivers/framework/support/platform/include/i2c_core.h

-

HCS配置入口文件

-

/drivers/adapter/khdf/linux/hcs/hdf.hcs

-

HCS配置文件总入口

-
- ->![](public_sys-resources/icon-caution.gif) **注意:** ->本例程涉及的文件路径均作为演示,驱动开发者应根据实际情况确定具体的源文件存放位置。 - -## 实例化驱动入口 - -驱动入口必须为HdfDriverEntry(在hdf\_device\_desc.h中定义)类型的全局变量,且moduleName要和device\_info.hcs中保持一致。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - -I2C驱动中没有实现Bind方法,因为I2C控制器由manager管理,而在manager中已经实现了Bind方法,因此I2C驱动中无需再绑定服务。 - -实例化驱动入口的示例代码如下: - -``` -/* 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量 */ -struct HdfDriverEntry g_sampleI2cDriverEntry = { - .moduleVersion = 1, - .Init = SampleI2cInit, - .Release = SampleI2cRelease, - .moduleName = "demo_i2c_driver", -}; -/* 调用HDF_INIT将驱动入口注册到HDF框架中 */ -HDF_INIT(g_sampleI2cDriverEntry); -``` - -## 设置相关参数 - -1. 添加设备服务节点(必选)。 - - 编辑device\_info.hcs,在device\_i2c :: device下添加驱动设备服务节点,示例如下: - - ``` - root { - device_info { - match_attr = "hdf_manager"; - device_i2c :: device { // i2c设备节点 - device2 :: deviceNode { // i2c驱动的DeviceNode节点 - policy = 0; // policy字段是驱动服务发布的策略 - priority = 55; // 驱动启动优先级 - permission = 0644; // 驱动创建设备节点权限 - moduleName = "demo_i2c_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 - serviceName = "DEMO_I2C_DRIVER"; // 驱动对外发布服务的名称,必须唯一 - deviceMatchAttr = "demo_i2c_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的 - // match_attr值相等 - } - } - } - } - - ``` - - >![](public_sys-resources/icon-notice.gif) **须知:** - >配置文件中的priority(取值范围为整数0到200)是用来表示host和驱动的优先级,不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高,驱动的priority值相同则不保证加载顺序。 - -2. 添加配置参数(可选)。 - - 有时驱动可能会需要私有配置信息,以确保寄存器的配置可以满足不同产品的需求。如需要私有配置信息,则可以添加一个驱动的配置文件,用来存放一些驱动的默认配置信息,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init(参考[驱动开发](../driver/驱动开发.md))传递给驱动。驱动开发者可新建配置文件,并在板级驱动hdf.hcs中引用新建的配置文件,本例中直接在原有的配置文件i2c\_config.hcs内添加配置参数。 - - 本例中编辑i2c\_config.hcs,添加配置参数: - - ``` - root { - platform { - i2c_config_demo { - match_attr = "demo_i2c_config"; // 该字段的值必须和device_info.hcs中的deviceMatchAttr值一致 - - template i2c_controller { // 参数模板 - bus = 0; - reg_pbase = 0x120b0000; - reg_size = 0xd1; - } - - controller_demo_0 :: i2c_controller { // 两个I2C示例控制器 - bus = 8; - } - controller_demo_1 :: i2c_controller { - bus = 9; - } - } - } - } - ``` - - match\_attr字段必须与device\_info.hcs中的deviceMatch\_Attr保持一致,在此文件中配置驱动需要的参数,通过match\_attr可匹配至对应的驱动,该驱动即可在Bind或Init中调用DeviceResourceGetIfaceInstance\(\)函数获取这些配置参数。 - - 若配置文件为新文件,则需要在板级配置入口文件hdf.hcs中引用该配置文件,例如: - - ``` - #include "device_info/device_info.hcs" - #include "i2c/i2c_config.hcs" - ``` - - 由于本例中在原有的i2c\_config.hcs内添加配置参数,没有新建配置文件,因此无需再将i2c\_config.hcs添加至板级配置入口文件中。 - -3. 驱动从HCS获取配置参数。 - - 在本例中,驱动需要通过HCS获取寄存器物理基地址、寄存器大小、总线号等参数,从而对控制器进行正确配置。 - - ``` - /* 从HCS获取配置参数 */ - static int32_t SampleI2cReadDrs(struct SampleI2cCntlr *sampleCntlr, const struct DeviceResourceNode *node) - { - int32_t ret; - struct DeviceResourceIface *drsOps = NULL; - - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL) { // 确保GetUint32方法可用 - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return HDF_FAILURE; - } - - ret = drsOps->GetUint32(node, "reg_pbase", &sampleCntlr->regBasePhy, 0); // 从HCS读取物理基地址reg_pbase - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regBase fail!", __func__); - return ret; - } - - ret = drsOps->GetUint16(node, "reg_size", &sampleCntlr->regSize, 0); // 从HCS读取寄存器大小reg_size - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regsize fail!", __func__); - return ret; - } - - ret = drsOps->GetUint16(node, "bus", (uint16_t *)&sampleCntlr->bus, 0); // 从HCS读取总线号bus - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read bus fail!", __func__); - return ret; - } - - return HDF_SUCCESS; - } - ``` - - -## 添加控制器 - -1. 定义结构体,实现钩子函数并赋值至函数指针。 - - I2cMethod结构体在i2c\_core.h中定义,其中通过函数指针的方式定义了I2C需要实现的方法,transfer方法为用于传输的钩子函数,在驱动中需要做具体实现并对函数指针赋值。 - - 示例代码如下: - - ``` - /* 自定义设备结构体,继承父类I2cCntlr */ - struct SampleI2cCntlr { - struct I2cCntlr cntlr; - OsalSpinlock spin; - volatile unsigned char *regBase; - uint16_t regSize; - int16_t bus; - uint32_t regBasePhy; - }; - - /* 消息结构体,继承父类I2cMsg */ - struct SampleTransferData { - struct I2cMsg *msgs; - int16_t index; - int16_t count; - }; - /* 钩子函数实现 */ - static int32_t SampleI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count) - { - int32_t ret = HDF_SUCCESS; - struct SampleI2cCntlr *sampleCntlr = NULL; - struct SampleTransferData td; - - if (cntlr == NULL || cntlr->priv == NULL) { - HDF_LOGE("SampleI2cTransfer: cntlr lor sampleCntlr is null!"); - return HDF_ERR_INVALID_OBJECT; - } - sampleCntlr = (struct SampleI2cCntlr *)cntlr; - - if (msgs == NULL || count <= 0) { - HDF_LOGE("SampleI2cTransfer: err parms! count:%d", count); - return HDF_ERR_INVALID_PARAM; - } - td.msgs = msgs; - td.count = count; - td.index = 0; - - HDF_LOGE("Successfully transmitted!"); // 表示此处传输成功 - - td.index = count; // 经过处理,最后实际发送msg个数等于count,返回已发送个数,此句代替已省略的处理过程 - return (td.index > 0) ? td.index : ret; - } - /* 钩子函数赋值 */ - static struct I2cMethod g_method = { - .transfer = SampleI2cTransfer, - }; - ``` - -2. 编写驱动初始化函数。 - - 本例中使用SampleI2cInit作为驱动初始化函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Init,以供HDF驱动框架调用从而达到初始化驱动的目的。该函数中需要对从HCS获取的配置参数进行解析,并按照这些参数创建控制器。示例如下: - - ``` - /* 解析参数,申请内存并创建控制器 */ - static int32_t SampleI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) - { - int32_t ret; - struct SampleI2cCntlr *sampleCntlr = NULL; - (void)device; - - sampleCntlr = (struct SampleI2cCntlr *)OsalMemCalloc(sizeof(*sampleCntlr)); - if (sampleCntlr == NULL) { - HDF_LOGE("%s: malloc sampleCntlr fail!", __func__); - return HDF_ERR_MALLOC_FAIL; - } - - ret = SampleI2cReadDrs(sampleCntlr, node); // 从HCS获取配置参数 - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read drs fail! ret:%d", __func__, ret); - goto __ERR__; - } - - sampleCntlr->regBase = OsalIoRemap(sampleCntlr->regBasePhy, sampleCntlr->regSize); - if (sampleCntlr->regBase == NULL) { - HDF_LOGE("%s: ioremap regBase fail!", __func__); - ret = HDF_ERR_IO; - goto __ERR__; - } - - HDF_LOGE("The controller has been initialized!"); // 表示此处省略的控制器初始化操作已经成功 - - sampleCntlr->cntlr.priv = (void *)node; - sampleCntlr->cntlr.busId = sampleCntlr->bus; - sampleCntlr->cntlr.ops = &g_method; - (void)OsalSpinInit(&sampleCntlr->spin); // 初始化自旋锁 - ret = I2cCntlrAdd(&sampleCntlr->cntlr); // 向核心层添加控制器 - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: add i2c controller fail:%d!", __func__, ret); - goto __ERR__; - } - - return HDF_SUCCESS; - __ERR__: // 错误处理 - if (sampleCntlr != NULL) { - if (sampleCntlr->regBase != NULL) { - OsalIoUnmap((void *)sampleCntlr->regBase); // 取消地址映射 - sampleCntlr->regBase = NULL; - } - OsalMemFree(sampleCntlr); // 释放内存 - sampleCntlr = NULL; - } - return ret; - } - /* 驱动入口初始化函数 */ - static int32_t SampleI2cInit(struct HdfDeviceObject *device) - { - int32_t ret; - const struct DeviceResourceNode *childNode = NULL; - - HDF_LOGE("%s: Enter", __func__); - if (device == NULL || device->property == NULL) { - HDF_LOGE("%s: device or property is NULL", __func__); - return HDF_ERR_INVALID_OBJECT; - } - - ret = HDF_SUCCESS; - DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { - ret = SampleI2cParseAndInit(device, childNode); // 调用解析参数和创建控制器的函数 - if (ret != HDF_SUCCESS) { - break; - } - } - return ret; - } - ``` - -3. 编写驱动释放函数。 - - 本例中使用SampleI2cRelease作为驱动释放函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,将调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。示例如下: - - ``` - /* 删除控制器函数 */ - static void SampleI2cRemoveByNode(const struct DeviceResourceNode *node) - { - int32_t ret; - int16_t bus; - struct I2cCntlr *cntlr = NULL; - struct SampleI2cCntlr *sampleCntlr = NULL; - struct DeviceResourceIface *drsOps = NULL; - - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL) { - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return; - } - - ret = drsOps->GetUint16(node, "bus", (uint16_t *)&bus, 0); // 从HCS获取I2C总线号 - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read bus fail!", __func__); - return; - } - - cntlr = I2cCntlrGet(bus); - if (cntlr != NULL && cntlr->priv == node) { // 根据I2C总线号删除控制器 - I2cCntlrPut(cntlr); - I2cCntlrRemove(cntlr); - sampleCntlr = (struct SampleI2cCntlr *)cntlr; - OsalIoUnmap((void *)sampleCntlr->regBase); - OsalMemFree(sampleCntlr); - } - return; - } - /* 释放资源 */ - static void SampleI2cRelease(struct HdfDeviceObject *device) - { - const struct DeviceResourceNode *childNode = NULL; - - HDF_LOGI("%s: enter", __func__); - - if (device == NULL || device->property == NULL) { - HDF_LOGE("%s: device or property is NULL", __func__); - return; - } - - DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { - SampleI2cRemoveByNode(childNode); // 调用删除控制器函数 - } - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221.md" deleted file mode 100755 index 18b3247aefef1bb7d1c24a961900349325110ad6..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221.md" +++ /dev/null @@ -1,91 +0,0 @@ -# 开发 - -1. 请先完成[《Hi3861快速入门》](../quick-start/Hi3861开发板介绍.md)。 - - LED控制参考示例存放于applications/sample/wifi-iot/app/iothardware/led\_example.c文件中。 - -2. 实现IOT外设控制,首先需要通过查阅原理图明确接线关系。经过查阅,hispark pegasus的LED与芯片的9号管脚相连。 - - ``` - #define LED_TEST_GPIO 9 - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >开发板原理图,请开发者联系Hi3861购买渠道客服获取。 - -3. 使用GPIO前,需要完成GPIO管脚初始化,明确管脚用途,并创建任务,使LED周期性亮灭,达到闪烁的效果。 - - ``` - static void LedExampleEntry(void) - { - osThreadAttr_t attr; - - /* 管脚初始化 */ - IoTGpioInit(LED_TEST_GPIO); - /* 配置9号管脚为输出方向 */ - IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT); - - attr.name = "LedTask"; - attr.attr_bits = 0U; - attr.cb_mem = NULL; - attr.cb_size = 0U; - attr.stack_mem = NULL; - attr.stack_size = LED_TASK_STACK_SIZE; - attr.priority = LED_TASK_PRIO; - - /* 启动任务 */ - if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) { - printf("[LedExample] Falied to create LedTask!\n"); - } - } - ``` - -4. 在循环任务中通过周期性亮灭形式实现LED闪烁。 - - ``` - static void *LedTask(const char *arg) - { - (void)arg; - while (1) { - switch (g_ledState) { - case LED_ON: - IoTGpioSetOutputVal(LED_TEST_GPIO, 1); - usleep(LED_INTERVAL_TIME_US); - break; - case LED_OFF: - IoTGpioSetOutputVal(LED_TEST_GPIO, 0); - usleep(LED_INTERVAL_TIME_US); - break; - case LED_SPARK: - IoTGpioSetOutputVal(LED_TEST_GPIO, 0); - usleep(LED_INTERVAL_TIME_US); - IoTGpioSetOutputVal(LED_TEST_GPIO, 1); - usleep(LED_INTERVAL_TIME_US); - break; - default: - usleep(LED_INTERVAL_TIME_US); - break; - } - } - return NULL; - } - ``` - -5. 在代码最下方,使用OpenHarmony启动恢复模块接口SYS\_RUN\(\)启动业务。(SYS\_RUN定义在ohos\_init.h文件中) - - ``` - SYS_RUN(LedExampleEntry); - ``` - -6. 修改applications/sample/wifi-iot/app/BUILD.gn文件,使led\_example.c参与编译。 - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("app") { - features = [ - "iothardware:led_example" - ] - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207-8.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207-8.md" deleted file mode 100755 index 52eed11deb14636b5a5cf069cf7fc7dbc62196e1..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207-8.md" +++ /dev/null @@ -1,8 +0,0 @@ -# 开发准备 - -- [准备开发环境和创建工程](#section1912530122716) - -## 准备开发环境和创建工程 - -首先需要下载和配置DevEco Studio,具体操作请参考[DevEco Studio 使用指南](../../application-dev/quick-start/DevEco-Studio(OpenHarmony)使用指南.md)。 - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207.md" deleted file mode 100755 index f24d68a539b1f575c5cec0da870f718138055562..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207.md" +++ /dev/null @@ -1,27 +0,0 @@ -# 开发准备 - -- [准备开发环境](#section1912530122716) -- [创建项目](#section1456035192720) - -## 准备开发环境 - -首先需要下载和配置DevEco Studio,具体操作请参考[《DevEco Studio使用指南》](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)。 - -## 创建项目 - -1. 通过如下两种方式,打开工程创建向导界面。 - - 如果当前未打开任何工程,可以在DevEco Studio的欢迎页,选择**Create HarmonyOS Project**开始创建一个新工程。 - - 如果已经打开了工程,可以在菜单栏选择**File \> New \> New Project**来创建一个新工程。 - -2. 选择“Smart Vision”下的“Empty Feature Ability”模板。 - - ![](figures/zh-cn_image_0000001082434703.png) - -3. 点击**Next**,进入到工程配置阶段,需要根据向导配置工程的基本信息。 - - **Project Name**:工程的名称,可以自定义。 - - **Package Name**:软件包名称,默认情况下,应用ID也会使用该名称,应用发布时,应用ID需要唯一。 - - **Save Location**:工程文件本地存储路径,存储路径中不能包含中文字符和空格。 - - **Compatible API Version**:兼容的SDK版本。 - -4. 点击**Finish**,工具会自动生成示例代码和相关资源,等待工程创建完成。 - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\346\255\245\351\252\244.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221\346\255\245\351\252\244.md" deleted file mode 100644 index ae738663fd4e90e5df3427c9a46dcb6755054fba..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\346\255\245\351\252\244.md" +++ /dev/null @@ -1,230 +0,0 @@ -# 开发步骤 - -应用的功能是通过表盘和数字显示实时时间。 - -从第一章节中的[显示效果图](概述-7.md#fig7763172132019)分析可知,页面由两个部分组成: - -- 表盘栏:主要展示一个动态的钟表,且钟表指针能准确转动。 -- 数字时间栏:主要以数字形式显示当前时间。 - -综上,我们可搭建一个纵向两行排列的弹性页面布局来实现界面的功能。具体开发步骤如下: - -1. 在hml文件中添加一个根节点div,注意每个hml文件中有且只能有一个根节点,代码如下: - - ``` -
-
- ``` - - class="container"表示组件使用的样式,container是index.css文件中的一个样式类,代码如下: - - ``` - .container { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - } - ``` - - 在这个样式类中,我们分别设置了根组件div的高度和宽度(注意在应用的开发过程中,除部分组件(text)外必须显式指定组件的高度和宽度,否则可能无法显示)、并将flex-direction属性设置为column,该属性表示div的子组件是垂直方向从上到下排列;这样就可以实现本节开头所说的纵向两行排列的弹性页面布局。 - -2. 实现时钟转动,需要使用“stack”组件。“stack”组件的功能是堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。 - - 在根组件下添加一个stack容器,代码片段如下: - - ``` -
- - - - - - -
- ``` - - style="transform : rotate\(\{\{ second \* 6 \}\}deg\) 这类代码用来设置组件的旋转事件。其中transform是设置动画平移/旋转/缩放的属性,rotate是旋转动画属性,支持设置x轴和y轴两个维度的选中参数。 - - 在css文件中设置"stack"组件样式的高度、宽度、位置等属性,代码如下: - - ``` - .stack { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 50%; - } - ``` - - 在css文件中设置"clock-bg"组件样式的高度、宽度等属性,代码如下: - - ``` - .clock-bg { - width: 80%; - height: 80%; - object-fit: scale-down; - } - ``` - - 在css文件中设置"clock-hand"组件为时针、分针和秒针的高度、宽度等属性,代码如下: - - ``` - .clock-hand { - width: 25%; - height: 65%; - object-fit: contain; - } - ``` - - index.js中会有一个定时器实时刷新时分秒变量,从而触发时间界面自动更新。对应的js代码如下: - - ``` - export default { - timer: undefined, - //定义参数 - data: { - hour: 0, //定义小时 - minute: 0, //定义分钟 - second: 0 //定义秒 - }, - onInit () { - this.updateTime(); - this.timer = setInterval(this.updateTime, 1000)//设置1s的定时器 - }, - updateTime: function () { - var nowTime = new Date() - this.hour = nowTime.getHours() - this.minute = nowTime.getMinutes() - this.second = nowTime.getSeconds() - if (this.hour < 10) { - this.hour = '0' + this.hour - } - if (this.minute < 10) { - this.minute = '0' + this.minute - } - if (this.second < 10) { - this.second = '0' + this.second - } - }, - } - ``` - -3. 显示数字时间,在钟表下面以数字形式显示当前时间。在根布局内末尾加上text组件,页面结构如下: - - ``` - {{ hour }}:{{ minute }}:{{ second }} - ``` - - class="digit-clock"设置了组件的高度和宽度以及字体大小,其代码如下: - - ``` - .digit-clock { - font-size: 58px; - width: 100%; - margin-top: 0px; - text-align: center; - } - ``` - -4. 所有组件设置样式、动画效果和数据动态绑定,完整代码如下所示: - - - **index.hml文件** - - ``` -
- - - - - - - {{ hour }}:{{ minute }}:{{ second }} -
- ``` - - - **index.css文件** - - ``` - .container { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - } - - .stack { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 50%; - } - - .digit-clock { - font-size: 58px; - width: 100%; - margin-top: 0px; - text-align: center; - } - - .clock-bg { - width: 80%; - height: 80%; - object-fit: scale-down; - } - - .clock-hand { - width: 25%; - height: 65%; - object-fit: contain; - } - ``` - - - **index.js:** - - js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:定时获取系统时间。 - - ``` - export default { - timer: undefined, - data: { - hour: 0, - minute: 0, - second: 0 - }, - onInit() { - this.updateTime() - this.timer = setInterval(this.updateTime, 1000) - }, - updateTime: function () { - var nowTime = new Date() - this.hour = nowTime.getHours() - this.minute = nowTime.getMinutes() - this.second = nowTime.getSeconds() - if (this.hour < 10) { - this.hour = '0' + this.hour - } - if (this.minute < 10) { - this.minute = '0' + this.minute - } - if (this.second < 10) { - this.second = '0' + this.second - } - }, - onDestroy() { - clearInterval(this.timer); - } - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\351\246\226\351\241\265.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221\351\246\226\351\241\265.md" deleted file mode 100755 index c80d70f94f323a6a705bb2b1dd1c5823eb490b7d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\351\246\226\351\241\265.md" +++ /dev/null @@ -1,581 +0,0 @@ -# 开发首页 - -应用首页主要展示城市的空气质量概况。首页总共有两屏(可以根据需求设置多屏),每屏显示一个城市的空气质量信息:主要包括AQI指数、城市名称、污染物指数、更新时间和信息来源等数据。 - -从第一章节中的[显示效果图](概述-6.md#fig18250512195914)分析可知,首页由三部分组成: - -- 标题栏:位于页面正上方,位置固定,包括应用退出按钮和页面标题。 -- 信息栏:主要展示城市的空气信息指标等内容;该页面根据用户需求可设置多屏,且能循环滑动。 -- 页面位置指示器:主要功能是标识当前页面,位置固定在页面底部的中间。 - -综上,我们可搭建一个纵向三行排列的弹性页面布局来实现首页的功能。 - -1. 在hml文件中添加一个根节点div,注意每个hml文件中有且只能有一个根节点,代码如下: - - ``` -
-
- ``` - - class="container"表示组件使用的样式,container是index.css文件中的一个样式类,代码如下: - - ``` - .container { - flex-direction: column; - height: 480px; - width: 960px; - } - ``` - - 在这个样式类中,我们分别设置了根组件div的高度和宽度(注意在应用的开发过程中,除部分组件(text)外必须显式指定组件的高度和宽度,否则可能无法显示)、并将flex-direction属性设置为column,该属性表示div的子组件是垂直方向从上到下排列;这样就可以实现本节开头所说的纵向三行排列的弹性页面布局。 - -2. 实现标题栏:标题栏包括一个退出按钮和一个标题,两个控件是横向排列;首先添加一个div,并设置flex-direction的属性为row,表示子组件是水平方向从左往右排列;然后依次添加一个image和text组件,代码如下: - - ``` -
-
- - - 空气质量 - -
-
- ``` - - 设置组件的高度、边距、颜色等属性。 - - ``` - .header { - width: 960px; - height: 72px; - } - .back { - width: 36px; - height: 36px; - margin-left: 39px; - margin-top: 23px; - } - .title { - width: 296px; - height: 40px; - margin-top: 20px; - margin-left: 21px; - color: #e6e6e6; - } - ``` - - onclick="exitApp" 设置了div组件的click事件,当在标题栏上触发点击事件时,就会执行函数exitApp,该函数位于index.js文件中,代码如下: - - ``` - exitApp() { - console.log('start exit'); - app.terminate(); - console.log('end exit'); - } - ``` - - app.terminate\(\)函数实现了程序退出功能;在使用该函数前,需要引入app模块,在js文件的最上方写如下代码: - - ``` - import app from '@system.app' - ``` - - 代码编写完成后,在模拟器中运行项目,显示效果如下图所示: - - **图 1** 标题栏效果 - ![](figures/标题栏效果.png "标题栏效果") - -3. 实现城市空气质量信息的多屏左右滑动,需要使用“swiper”组件。 - - 在根节点中添加一个子节点swiper,代码片段如下: - - ``` -
-
- - - 空气质量 - -
- - -
- ``` - - - class="swiper"设置了组件的高度和宽度,代码如下: - - ``` - .swiper { - height: 385px; - width: 960px; - } - ``` - - - - index="\{\{swiperPage\}\}" duration="500" onchange="swiperChange" 这些代码用来设置组件的属性和事件。其中,duration="500" 表示设置swiper的页面滑动的动画时长为500ms。 - - index="\{\{swiperPage\}\}"设置了swiper子组件索引值,\{\{swiperPage\}\}这种写法表示index的值是和js代码中的swiperPage变量动态绑定的,index的值会随着swiperPage变动而改变。 - - onchange="swiperChange" 设置了swiper组件的change事件和函数swiperChange绑定,对应的js代码如下: - - ``` - //引入router模块,用户页面跳转 - import router from'@system.router' - import app from '@system.app' - - export default { - //定义参数 - data: { - //默认是第一页 - swiperPage: 0 - }, - onInit () { - }, - exitApp(){ - console.log('start exit'); - app.terminate(); - console.log('end exit'); - }, - //swiper滑动回调事件,保存当前swiper的index值,每次滑动都会将index值保存在swiperPage变量中 - swiperChange (e) { - this.swiperPage = e.index; - } - } - ``` - - -4. 设置一个城市的空气质量信息为一屏,在一屏内,要展示多种信息,分别使用不同的控件进行展示。 - - 在swiper中添加两个子组件stack(绝对布局),每个stack组件内分别添加text、image、progress等组件来显示对应的信息 ,页面结构如下: - - ``` - - - - ------空气质量 - ------城市名称 - -----进度条 - -------云朵图片 - --------AQI数值 - AQI------AQI -
--------空气指标详细信息 -
-
--------更新时间和网站等信息 -
-
- - - - - - - - -
-
-
- ``` - - 代码编写完成后,模拟器运行效果如下: - - **图 2** 标题栏和信息栏效果 - ![](figures/标题栏和信息栏效果.png "标题栏和信息栏效果") - -5. 添加页面位置指示器:由于当前swiper不支持设置indicator,需要开发者自己来实现该效果。在根节点中添加一个子组件div,并设置相应样式;然后在该div中添加两个子组件div,设置两个div的border-radius,并在swiper滑动事件中动态改变对应div的背景色来实现该效果。 - - ``` -
-
-
-
- ``` - - **图 3** 页面位置指示器效果图 - ![](figures/页面位置指示器效果图.png "页面位置指示器效果图") - -6. 所有组件设置样式、动画效果和数据动态绑定,完整代码如下所示: - - - **index.hml文件** - - ``` -
-
- - - 空气质量 - -
- - - {{airData[0].airQuality}} - - {{airData[0].location}} - - - - {{airData[0].detailData}} - - - AQI - -
-
- - CO - - - 100 - -
-
- - NO2 - - - 90 - -
-
- - PM10 - - - 120 - -
-
- - PM2.5 - - - 40 - -
-
- - SO2 - - - 150 - -
- -
- -
- - {{airData[1].airQuality}} - - {{airData[1].location}} - - - - {{airData[1].detailData}} - - - AQI - -
-
- - CO - - - 10 - -
-
- - NO2 - - - 50 - -
-
- - PM10 - - - 60 - -
-
- - PM2.5 - - - 40 - -
-
- - SO2 - - - 150 - -
- -
- -
-
-
-
-
-
-
- ``` - - - **index.css文件** - - css文件中定义了许多class,每个class用于定义组件的位置、大小、字体、颜色、背景色等信息。同时,每一个子组件都叠加在父组件中,父组件的样式会影响子组件的呈现。 - - ``` - .aqi-value { - text-align: center; - font-size: 65px; - color: #f0ffff; - width: 156px; - height: 92px; - top: 134px; - left: 210px; - } - .aqi { - text-align: center; - color: #a2c4a2; - width: 156px; - height: 45px; - top: 90px; - left: 210px; - } - .airquality { - top: 222px; - text-align: center; - width: 156px; - height: 45px; - left: 210px; - } - .image { - top: 285px; - left: 274px; - width: 32px; - height: 32px; - } - .location-text { - text-align: center; - color: #ffffff; - width: 200px; - height: 52px; - font-size: 40px; - left: 380px; - top: 16px; - } - .container { - flex-direction: column; - height: 480px; - width: 960px; - } - .circle-progress { - center-x: 128px; - center-y: 128px; - radius: 128px; - startAngle: 198; - totalAngle: 320; - strokeWidth: 24px; - width: 256px; - height: 256px; - left: 160px; - top: 58px; - } - .detail { - width: 256px; - height: 265px; - left: 544px; - top: 58px; - flex-direction: column; - } - .text-wrapper { - width: 256px; - height: 35px; - margin-top: 6px; - } - .gas-name { - width: 128px; - height: 35px; - text-align: left; - } - .gas-value { - width: 128px; - height: 35px; - text-align: right; - } - .btn { - width: 180px; - height: 50px; - margin-top: 6px; - margin-left: 38px; - background-color: #1a1a1a; - color: #1085CE; - } - .footer { - top: 326px; - width: 960px; - height: 28px; - } - .header { - width: 960px; - height: 72px; - } - .back { - width: 36px; - height: 36px; - margin-left: 39px; - margin-top: 23px; - } - .title { - width: 296px; - height: 40px; - margin-top: 20px; - margin-left: 21px; - color: #e6e6e6; - } - .swiper { - height: 385px; - width: 960px; - } - .images { - width: 60px; - height: 15px; - margin-left: 450px; - } - .update-time { - width: 480px; - height: 28px; - font-size: 20px; - color: #A9A9A9; - text-align: right; - } - .info-source { - width: 450px; - height: 28px; - font-size: 20px; - color: #A9A9A9; - text-align: left; - margin-left: 24px; - } - .circle-div { - width: 12px; - height: 12px; - border-radius: 6px; - } - ``` - - - **index.js:** - - js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:根据数值动态改变文字、进度条颜色、页面跳转。 - - ``` - //导入router和app模块 - import router from '@system.router' - import app from '@system.app' - - export default { - data: { - //页面绑定数据 - textColor1: '#00ff00', - textColor2: '#00ff00', - bgColor1: '#669966', - bgColor2: '#669966', - swiperPage: 0, - percent1: 40, - percent2: 90, - iconUncheckedColor: '#262626', - iconcheckedColor: '#ffffff', - iconcheckedBR: '6px', - src1: 'common/cloud_green.png', - src2: 'common/cloud_green.png', - airData: [{ - location: '东莞', - airQuality: '良', - detailData: 40 - }, { - location: '深圳', - airQuality: '差', - detailData: 90 - }] - }, - onInit () { - //根据数值的不同,设置不同的字体、背景颜色和图片 - if(this.airData[0].detailData > 100){ - this.src1 = 'common/cloud_red.png'; - this.textColor1 = '#ff0000'; - this.bgColor1 = '#9d7462'; - } else if(50 < this.airData[0].detailData && this.airData[0].detailData <= 100){ - this.src1 = 'common/cloud_yellow.png'; - this.textColor1 = '#ecf19a'; - 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; - if(this.swiperPage == 0){ - this.iconcheckedColor = '#ffffff'; - this.iconUncheckedColor = '#262626'; - }else{ - this.iconcheckedColor = '#262626'; - this.iconUncheckedColor = '#ffffff'; - } - } - }, - //跳转到详情页面 - openDetail () { - router.replace({ - uri: 'pages/detail/detail', - params: {selectedCityIndex:this.swiperPage} - }); - }, - //退出应用 - exitApp(){ - console.log('start exit'); - app.terminate(); - console.log('end exit'); - }, - //页面滑动事件,滑动时改变最新的标识 - swiperChange (e) { - this.swiperPage = e.index; - if(e.index == 0){ - this.iconcheckedColor = '#ffffff'; - this.iconUncheckedColor = '#262626'; - }else{ - this.iconcheckedColor = '#262626'; - this.iconUncheckedColor = '#ffffff'; - } - } - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\345\274\200\346\234\272\346\227\245\345\277\227\345\210\206\346\236\220.md" "b/zh-cn/device-dev/guide/\345\274\200\346\234\272\346\227\245\345\277\227\345\210\206\346\236\220.md" deleted file mode 100644 index 469d6a3566fe136c2bb59993abde4b12551e4c03..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\346\234\272\346\227\245\345\277\227\345\210\206\346\236\220.md" +++ /dev/null @@ -1,19 +0,0 @@ -# 开机日志分析 - -如下所示为开机启动日志部分截取 - -``` -[I/HDF_INPUT_DRV] HdfInputManagerInit: enter // 管理驱动层初始化 -[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // 初始化成功 -[I/osal_cdev] add cdev hdf_input_host success -[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // 公共驱动层初始化 -[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // 初始化成功 -[I/osal_cdev] add cdev hdf_input_event1 success -[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // 器件驱动层初始化 -[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060 -[I/HDF_INPUT_DRV] Product_ID: 911_1060, x_sol = 960, y_sol = 480 -[I/HDF_LOG_TAG] ChipDriverInit: chipDetect succ, ret = 0 -[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch -[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // 初始化成功 -``` - diff --git "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-3.md" "b/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-3.md" deleted file mode 100755 index 83e445c0ed119ba040d2544e9793831a2cd2b05b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-3.md" +++ /dev/null @@ -1,395 +0,0 @@ -# 拍照开发指导 - -- [使用场景](#zh-cn_topic_0000001052170554_section1963312376119) -- [接口说明](#zh-cn_topic_0000001052170554_section56549532016) -- [约束与限制](#zh-cn_topic_0000001052170554_section1165911177314) -- [开发步骤](#zh-cn_topic_0000001052170554_section138543918214) - -## 使用场景 - -使用Camera产生图片帧(拍照)。 - -## 接口说明 - -**表 1** API列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

类名

-

接口名

-

描述

-

CameraKit

-

int32_t GetCameraIds(std::list<string> cameraList)

-

获取cameraId列表

-

CameraKit

-

CameraAbility& GetCameraAbility(string cameraId)

-

获取指定camera的能力

-

CameraKit

-

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

-

注册camera设备状态回调

-

CameraKit

-

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

-

去注册camera设备状态回调

-

CameraKit

-

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

-

创建camera实例

-

Camera

-

string GetCameraId()

-

获取cameraID

-

Camera

-

CameraConfig& GetCameraConfig()

-

获取camera配置信息

-

Camera

-

FrameConfig& GetFrameConfig(int32_t type)

-

获取捕获帧类型

-

Camera

-

void Configure(CameraConfig& config)

-

配置camera

-

Camera

-

void Release()

-

释放camera

-

Camera

-

int TriggerLoopingCapture(FrameConfig& frameConfig)

-

开始循环帧捕获

-

Camera

-

void StopLoopingCapture()

-

停止循环帧捕获

-

Camera

-

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

-

抓图

-

CameraConfig

-

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

-

设置帧状态回调

-

CameraConfig

-

static CameraConfig* CreateCameraConfig()

-

创建camera配置信息实例

-

CameraAbility

-

std::list<Size> GetSupportedSizes(int format)

-

根据类型获取支持输出图像尺寸大小

-

CameraAbility

-

std::list<T> GetParameterRange(uint32_t key)

-

获取支持的参数范围

-

CameraDevice

-

CameraDeviceCallback()

-

camera设备回调类构造函数

-

CameraDevice

-

void OnCameraStatus​(std::string cameraId, int32_t status)

-

camera设备状态变化时的回调

-

CameraStateCallback

-

CameraStateCallback​()

-

camera状态回调类构造函数

-

CameraStateCallback

-

void OnConfigured​(Camera& camera)

-

camera配置成功回调

-

CameraStateCallback

-

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

-

camera配置失败回调

-

CameraStateCallback

-

void OnCreated​(Camera& camera)

-

camera创建成功回调

-

CameraStateCallback

-

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

-

camera创建失败回调

-

CameraStateCallback

-

void OnReleased​(Camera& camera)

-

camera释放回调

-

FrameStateCallback

-

FrameStateCallback​()

-

帧状态回调类构造函数

-

FrameStateCallback

-

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

-

拍照帧完成回调

-

FrameStateCallback

-

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

-

拍照帧异常回调

-

FrameConfig

-

int32_t GetFrameConfigType()

-

获取帧配置类型

-

FrameConfig

-

std::list<OHOS::Surface> GetSurfaces()

-

获取帧配置的surface

-

FrameConfig

-

void AddSurface(OHOS::AGP::UISurface& surface);

-

添加surface

-

FrameConfig

-

void RemoveSurface(OHOS::AGP::UISurface& surface);

-

删除surface

-
- -## 约束与限制 - -无。 - -## 开发步骤 - -1. 实现设备状态回调的派生类,用户在设备状态发生变更(如新插入相机设备/相机掉线)时,自定义操作。 - - ``` - class SampleCameraDeviceCallback : public CameraDeviceCallback { - void OnCameraStatus(std::string cameraId, int32_t status) override - { - //do something when camera is available/unavailable - } - }; - ``` - -2. 实现帧事件回调的派生类,这里在拿到帧数据以后将其转存为文件。 - - ``` - static void SampleSaveCapture(const char *p, uint32_t size) - { - cout << "Start saving picture" << endl; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm *ltm = localtime(&tv.tv_sec); - if (ltm != nullptr) { - ostringstream ss("Capture_"); - ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; - - ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); - cout << "write " << size << " bytes" << endl; - pic.write(p, size); - cout << "Saving picture end" << endl; - } - } - - class TestFrameStateCallback : public FrameStateCallback { - void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override - { - cout << "Receive frame complete inform." << endl; - if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { - cout << "Capture frame received." << endl; - list surfaceList = fc.GetSurfaces(); - for (Surface *surface : surfaceList) { - SurfaceBuffer *buffer = surface->AcquireBuffer(); - if (buffer != nullptr) { - char *virtAddr = static_cast(buffer->GetVirAddr()); - if (virtAddr != nullptr) { - SampleSaveCapture(virtAddr, buffer->GetSize()); - } - surface->ReleaseBuffer(buffer); - } - delete surface; - } - delete &fc; - } - } - }; - ``` - -3. 实现相机状态回调的派生类,当相机状态发生变化(配置成功/失败,创建成功/失败\)时,自定义操作。 - - ``` - class SampleCameraStateMng : public CameraStateCallback { - public: - SampleCameraStateMng() = delete; - SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} - ~SampleCameraStateMng() - { - if (recordFd_ != -1) { - close(recordFd_); - } - } - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} - void OnReleased(Camera &c) override {} - }; - ``` - -4. 创建CameraKit,用于创建和获取camera信息。 - - ``` - CameraKit *camKit = CameraKit::GetInstance(); - list camList = camKit->GetCameraIds(); - string camId; - for (auto &cam : camList) { - cout << "camera name:" << cam << endl; - const CameraAbility *ability = camKit->GetCameraAbility(cam); - /* find camera which fits user's ability */ - list sizeList = ability->GetSupportedSizes(0); - if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { - camId = cam; - break; - } - } - ``` - -5. 创建Camera实例。 - - ``` - EventHandler eventHdlr; // Create a thread to handle callback events - SampleCameraStateMng CamStateMng(eventHdlr); - - camKit->CreateCamera(camId, CamStateMng, eventHdlr); - ``` - -6. 根据[步骤1](#zh-cn_topic_0000001052170554_li378084192111)、[步骤2](#zh-cn_topic_0000001052170554_li8716104682913)、[步骤3](#zh-cn_topic_0000001052170554_li6671035102514)中的回调设计,camera实例创建成功后会进行配置操作,主流程中app需要设计同步机制。 - - ``` - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - - void Capture() - { - if (cam_ == nullptr) { - cout << "Camera is not ready." << endl; - return; - } - FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); - Surface *surface = Surface::CreateSurface(); - if (surface == nullptr) { - delete fc; - } - surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ - fc->AddSurface(*surface); - cam_->TriggerSingleCapture(*fc); - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index e59c365a5c6fe2e58a8333157758418d1508175c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,395 +0,0 @@ -# 拍照开发指导 - -- [使用场景](#zh-cn_topic_0000001052170554_section1963312376119) -- [接口说明](#zh-cn_topic_0000001052170554_section56549532016) -- [约束与限制](#zh-cn_topic_0000001052170554_section1165911177314) -- [开发步骤](#zh-cn_topic_0000001052170554_section138543918214) - -## 使用场景 - -使用Camera产生图片帧(拍照)。 - -## 接口说明 - -**表 1** API列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

类名

-

接口名

-

描述

-

CameraKit

-

int32_t GetCameraIds(std::list<string> cameraList)

-

获取cameraId列表

-

CameraKit

-

CameraAbility& GetCameraAbility(string cameraId)

-

获取指定camera的能力

-

CameraKit

-

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

-

注册camera设备状态回调

-

CameraKit

-

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

-

去注册camera设备状态回调

-

CameraKit

-

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

-

创建camera实例

-

Camera

-

string GetCameraId()

-

获取cameraID

-

Camera

-

CameraConfig& GetCameraConfig()

-

获取camera配置信息

-

Camera

-

FrameConfig& GetFrameConfig(int32_t type)

-

获取捕获帧类型

-

Camera

-

void Configure(CameraConfig& config)

-

配置camera

-

Camera

-

void Release()

-

释放camera

-

Camera

-

int TriggerLoopingCapture(FrameConfig& frameConfig)

-

开始循环帧捕获

-

Camera

-

void StopLoopingCapture()

-

停止循环帧捕获

-

Camera

-

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

-

抓图

-

CameraConfig

-

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

-

设置帧状态回调

-

CameraConfig

-

static CameraConfig* CreateCameraConfig()

-

创建camera配置信息实例

-

CameraAbility

-

std::list<Size> GetSupportedSizes(int format)

-

根据类型获取支持输出图像尺寸大小

-

CameraAbility

-

std::list<T> GetParameterRange(uint32_t key)

-

获取支持的参数范围

-

CameraDevice

-

CameraDeviceCallback()

-

camera设备回调类构造函数

-

CameraDevice

-

void OnCameraStatus​(std::string cameraId, int32_t status)

-

camera设备状态变化时的回调

-

CameraStateCallback

-

CameraStateCallback​()

-

camera状态回调类构造函数

-

CameraStateCallback

-

void OnConfigured​(Camera& camera)

-

camera配置成功回调

-

CameraStateCallback

-

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

-

camera配置失败回调

-

CameraStateCallback

-

void OnCreated​(Camera& camera)

-

camera创建成功回调

-

CameraStateCallback

-

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

-

camera创建失败回调

-

CameraStateCallback

-

void OnReleased​(Camera& camera)

-

camera释放回调

-

FrameStateCallback

-

FrameStateCallback​()

-

帧状态回调类构造函数

-

FrameStateCallback

-

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

-

拍照帧完成回调

-

FrameStateCallback

-

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

-

拍照帧异常回调

-

FrameConfig

-

int32_t GetFrameConfigType()

-

获取帧配置类型

-

FrameConfig

-

std::list<OHOS::Surface> GetSurfaces()

-

获取帧配置的surface

-

FrameConfig

-

void AddSurface(OHOS::AGP::UISurface& surface);

-

添加surface

-

FrameConfig

-

void RemoveSurface(OHOS::AGP::UISurface& surface);

-

删除surface

-
- -## 约束与限制 - -无。 - -## 开发步骤 - -1. 实现设备状态回调的派生类,用户在设备状态发生变更(如新插入相机设备/相机掉线)时,自定义操作。 - - ``` - class SampleCameraDeviceCallback : public CameraDeviceCallback { - void OnCameraStatus(std::string cameraId, int32_t status) override - { - //do something when camera is available/unavailable - } - }; - ``` - -2. 实现帧事件回调的派生类,这里在拿到帧数据以后将其转存为文件。 - - ``` - static void SampleSaveCapture(const char *p, uint32_t size) - { - cout << "Start saving picture" << endl; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm *ltm = localtime(&tv.tv_sec); - if (ltm != nullptr) { - ostringstream ss("Capture_"); - ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; - - ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); - cout << "write " << size << " bytes" << endl; - pic.write(p, size); - cout << "Saving picture end" << endl; - } - } - - class TestFrameStateCallback : public FrameStateCallback { - void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override - { - cout << "Receive frame complete inform." << endl; - if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { - cout << "Capture frame received." << endl; - list surfaceList = fc.GetSurfaces(); - for (Surface *surface : surfaceList) { - SurfaceBuffer *buffer = surface->AcquireBuffer(); - if (buffer != nullptr) { - char *virtAddr = static_cast(buffer->GetVirAddr()); - if (virtAddr != nullptr) { - SampleSaveCapture(virtAddr, buffer->GetSize()); - } - surface->ReleaseBuffer(buffer); - } - delete surface; - } - delete &fc; - } - } - }; - ``` - -3. 实现相机状态回调的派生类,当相机状态发生变化(配置成功/失败,创建成功/失败\)时,自定义操作。 - - ``` - class SampleCameraStateMng : public CameraStateCallback { - public: - SampleCameraStateMng() = delete; - SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} - ~SampleCameraStateMng() - { - if (recordFd_ != -1) { - close(recordFd_); - } - } - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} - void OnReleased(Camera &c) override {} - }; - ``` - -4. 创建CameraKit,用于创建和获取camera信息。 - - ``` - CameraKit *camKit = CameraKit::GetInstance(); - list camList = camKit->GetCameraIds(); - string camId; - for (auto &cam : camList) { - cout << "camera name:" << cam << endl; - const CameraAbility *ability = camKit->GetCameraAbility(cam); - /* find camera which fits user's ability */ - list sizeList = ability->GetSupportedSizes(0); - if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { - camId = cam; - break; - } - } - ``` - -5. 创建Camera实例。 - - ``` - EventHandler eventHdlr; // Create a thread to handle callback events - SampleCameraStateMng CamStateMng(eventHdlr); - - camKit->CreateCamera(camId, CamStateMng, eventHdlr); - ``` - -6. 根据[步骤1](#zh-cn_topic_0000001052170554_li378084192111)、[步骤2](#zh-cn_topic_0000001052170554_li8716104682913)、[步骤3](#zh-cn_topic_0000001052170554_li6671035102514)中的回调设计,camera实例创建成功后会进行配置操作,主流程中app需要设计同步机制。 - - ``` - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - - void Capture() - { - if (cam_ == nullptr) { - cout << "Camera is not ready." << endl; - return; - } - FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); - Surface *surface = Surface::CreateSurface(); - if (surface == nullptr) { - delete fc; - } - surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ - fc->AddSurface(*surface); - cam_->TriggerSingleCapture(*fc); - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" "b/zh-cn/device-dev/guide/\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" deleted file mode 100755 index 65f7df79807efc4e7fb9d33879b707e1d6ec1ce3..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 摄像头控制 - -- **[概述](概述-0.md)** - -- **[示例开发](示例开发.md)** - -- **[应用实例](应用实例.md)** - - diff --git "a/zh-cn/device-dev/guide/\346\227\240\345\261\217\346\221\204\345\203\217\345\244\264\347\261\273\344\272\247\345\223\201.md" "b/zh-cn/device-dev/guide/\346\227\240\345\261\217\346\221\204\345\203\217\345\244\264\347\261\273\344\272\247\345\223\201.md" deleted file mode 100755 index 7d723b1bfd0ea849891a1cc8faade79f4802c0d2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\227\240\345\261\217\346\221\204\345\203\217\345\244\264\347\261\273\344\272\247\345\223\201.md" +++ /dev/null @@ -1,5 +0,0 @@ -# 无屏摄像头类产品 - -- **[摄像头控制](摄像头控制.md)** - - diff --git "a/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100644 index 3cbff6960f629645fc6f4cca541d7e0dcbee0722..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 时钟应用开发示例 - -- **[概述](概述-7.md)** - -- **[开发准备](开发准备-8.md)** - -- **[开发步骤](开发步骤.md)** - -- **[签名打包](签名打包.md)** - -- **[真机运行](真机运行-9.md)** - -- **[常见问题](常见问题-10.md)** - - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-0.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-0.md" deleted file mode 100755 index e3d5da250e043ac86136b0d8ad5a220f946fefc2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-0.md" +++ /dev/null @@ -1,10 +0,0 @@ -# 概述 - -本文档将介绍如何基于IoT Camera开发板,利用开发套件中自带的摄像头,完成拍照、录像功能。 - -开发者可通过执行示例应用,对开发板的外设控制有了更深入了解后,可使用开发板完成摄像头等设备。 - -若开发者想先查看示例效果,请进入[应用实例](应用实例.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 - -相机开发基本概念可参考:[相机开发概述](../subsystems/相机开发概述.md)。 - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-1.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-1.md" deleted file mode 100755 index f265cdb276c1d92bf06280ad54ba3fb5f210f46d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-1.md" +++ /dev/null @@ -1,10 +0,0 @@ -# 概述 - -本文档将介绍如何基于IoT Camera开发板(Hi3516DV300),利用其摄像头和屏幕,完成拍照、录像和视频预览功能。 - -通过本文档,开发者能够对OpenHarmony的摄像控制有更深入的了解,可参照本例尝试完成“智能猫眼”、“智能后视镜”、“智能带屏音箱”等设备的开发。 - -若开发者想先查看示例效果,请进入[应用实例](应用实例-5.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 - -相机应用开发的基本概念请参考:[相机开发概述](../subsystems/相机开发概述.md)。 - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-10.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-10.md" deleted file mode 100644 index 16734e3f17205895f57f82921da60c53d475f77a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-10.md" +++ /dev/null @@ -1,26 +0,0 @@ -# 概述 - -- [场景介绍](#section191543223549) - -本文档将以I2C驱动为例,介绍如何基于HDF驱动框架完成平台驱动开发。 - ->![](public_sys-resources/icon-caution.gif) **注意:** ->本例仅作为平台驱动开发示例参考,开发者不可直接用于商用集成。 - -## 场景介绍 - -HDF驱动框架为常用外围设备提供了标准的驱动框架,驱动开发者只需将驱动适配至HDF驱动框架,即可通过HDF驱动框架提供的接口操作外围设备。 - -本文以I2C为例。其时序流程如[图1](#fig148041484161)所示。 - -**图 1** I2C时序流程图 - - -![](figures/zh-cn_image_0000001161922745.png) - -- User Business:用户业务驱动。 -- i2cManagerEntry:I2C管理器入口,注册I2cManager到HDF驱动框架。 -- I2cManager:I2C管理器,管理I2C控制器。 -- I2cCntlr:I2C控制器。 -- i2cDriverEntry:I2C控制器入口,注册I2cCntlr到HDF驱动框架。 - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-12.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-12.md" deleted file mode 100644 index 0606b801b5eb33741f1c9cb78d67edf52318712a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-12.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 概述 - -本文档将介绍如何基于Hi3516DV300开发板完成基于HDF\_Input模型的触摸屏器件驱动开发,从而使开发者快速入门,进行基于的外设驱动开发。 - -- **[硬件资源介绍](硬件资源介绍.md)** - -- **[Input模型简介](Input模型简介.md)** - - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-6.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-6.md" deleted file mode 100755 index 7f8de10aa751682d4f464e131f414fd2f1c920ce..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-6.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 概述 - -- [效果展示](#section3997224182313) - -本文将介绍如何快速搭建基于OpenHarmony系统的行车记录仪(Hi3516DV300开发板)应用开发环境,并基于一个简易的APP示例逐步展示应用的创建、开发、调试和安装等流程。接下来本文以空气质量监测(AirQuality)App为例进行说明。 - -## 效果展示 - -空气质量监测App是一款展示城市空气质量信息的应用,有两个页面组成:首页和详情页,在DevEco Studio模拟器中的显示效果如下图所示: - -**图 1** 空气质量监测 App显示效果图 - - -![](figures/Video_2020-07-25_173141.gif) - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-7.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-7.md" deleted file mode 100755 index e032aa00bcccc4972464e760e165742db5ffdf61..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-7.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 概述 - -- [效果展示](#section3997224182313) - -本文将介绍如何快速搭建基于OpenHarmony标准系统(Hi3516DV300开发板)的应用开发环境,并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过[本链接](https://gitee.com/openharmony/app_samples/tree/master/common/Clock)获取。 - -## 效果展示 - -时钟App是一款显示实时时间的应用,显示效果如下图所示: - -**图 1** 时钟应用显示效果图 - - -![](figures/Clock.png) - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260.md" deleted file mode 100755 index 875da92ed1dd39a87faab8a658718423a7ce9d1f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 概述 - -OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力,包含I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。本文介绍如何通过调用OpenHarmony的NDK接口,实现对GPIO控制,达到LED闪烁的效果。其他的IOT外设控制,开发者可根据API指导文档完成,此处不逐一介绍。 - diff --git "a/zh-cn/device-dev/guide/\346\267\273\345\212\240\351\241\265\351\235\242.md" "b/zh-cn/device-dev/guide/\346\267\273\345\212\240\351\241\265\351\235\242.md" deleted file mode 100755 index 8733bfb1e6d4795483ae7e763c0e6fed857fdc64..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\267\273\345\212\240\351\241\265\351\235\242.md" +++ /dev/null @@ -1,34 +0,0 @@ -# 添加页面 - -- [创建首页面](#section16935511143715) -- [创建详情页](#section122131729173819) - -## 创建首页面 - -空气质量监测App包含两个界面(Page),工程创建完成后会生成一个名为index的Page,可以作为首页。工程目录如下图所示: - -**图 1** 工程目录 -![](figures/工程目录.png "工程目录") - -## 创建详情页 - -新增一个Page,作为详情页,具体步骤如下: - -1. pages目录右键 ,弹出的菜单中选择New、JS Page。 - - **图 2** 添加页面 - ![](figures/添加页面.png "添加页面") - -2. 输入Page名称。 - - **图 3** 输入页面名称 - ![](figures/输入页面名称.png "输入页面名称") - -3. 确认创建结果。 - - 详情页创建完成后应用工程目录如下图所示,每个Page包括三个文件:布局文件hml、样式文件css、业务逻辑代码js。 - - **图 4** 完整工程目录 - ![](figures/完整工程目录.png "完整工程目录") - - diff --git "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/zh-cn/device-dev/guide/\347\216\257\345\242\203\345\207\206\345\244\207.md" deleted file mode 100644 index c6ae1a18427ed3bdec92f853ac9d49905d4901a5..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\345\207\206\345\244\207.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 环境准备 - -环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/标准系统入门.md)。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 - diff --git "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\346\220\255\345\273\272.md" "b/zh-cn/device-dev/guide/\347\216\257\345\242\203\346\220\255\345\273\272.md" deleted file mode 100644 index 381ddaa88c0c7136b378691ceae0f1594d54aec7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\346\220\255\345\273\272.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 环境搭建 - -环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/标准系统入门.md)。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 - diff --git "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214-9.md" "b/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214-9.md" deleted file mode 100644 index 30bb3b0801d1ea859f8e3a64d956fbeb91f0e381..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214-9.md" +++ /dev/null @@ -1,35 +0,0 @@ -# 真机运行 - -应用签名打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony系统烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[标准系统Hi3516快速入门](../quick-start/标准系统入门.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载应用。 - -1. 从开发者工具代码仓路径中获取hdc客户端。 - - ``` - developtools/hdc_standard/prebuilt/windows/hdc_std.exe - ``` - - 修改名称为hdc.exe,并将工具路径加入系统环境path变量中。 - -2. 启动cmd命令窗口,执行以下命令,推送hap应用包到设备目录下并安装。 - - ``` - hdc smode - hdc target mount - hdc file send clock.hap /data/clock.hap - hdc shell chmod 666 /data/clock.hap - hdc shell bm install -p /data/clock.hap - ``` - -3. 启动应用。执行以下命令,其中ohos.samples.clock为应用包名,MainAbility为应用启动的Ability。 - - ``` - hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock - ``` - -4. 卸载应用(可选)。执行以下命令,其中ohos.samples.clock为应用包名。 - - ``` - hdc shell bm uninstall -n ohos.samples.clock - ``` - - diff --git "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214.md" "b/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214.md" deleted file mode 100755 index 973019fcce8af2d9c0fde13a096d5c4067df3e6d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214.md" +++ /dev/null @@ -1,29 +0,0 @@ -# 真机运行 - -应用编译打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/tool_install-0000001050164976),然后将OpenHarmony烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[Hi3516快速入门](../quick-start/Hi3516开发板介绍.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载三方应用。 - -1. 将IDE编译的未签名应用安装包和安装工具(镜像文件生成目录中的dev\_tools)放在sdcard中,将sdcard插入开发板卡槽。 -2. 应用安装默认要校验签名,需要执行以下命令,关闭签名校验。 - - ``` - ./sdcard/dev_tools/bin/bm set -s disable - ``` - -3. 执行以下命令,安装应用。 - - ``` - ./sdcard/dev_tools/bin/bm install -p /sdcard/airquality.hap - ``` - - 其中dev\_tools目录中是安装工具,airquality.hap为应用安装包,此处替换为实际工程的安装包名称。 - -4. 应用安装完成后,可点击桌面应用图标启动应用,进行操作。 - - **图 1** 桌面 - ![](figures/桌面.png "桌面") - -5. 卸载应用(可选)。 - - 长按桌面应用图标,在弹出的菜单中点击“卸载”按钮即可卸载应用。 - - diff --git "a/zh-cn/device-dev/guide/\347\241\254\344\273\266\350\265\204\346\272\220\344\273\213\347\273\215.md" "b/zh-cn/device-dev/guide/\347\241\254\344\273\266\350\265\204\346\272\220\344\273\213\347\273\215.md" deleted file mode 100644 index 18b33bd5af0271b644fe30b8585e3f6be22a3b55..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\241\254\344\273\266\350\265\204\346\272\220\344\273\213\347\273\215.md" +++ /dev/null @@ -1,6 +0,0 @@ -# 硬件资源介绍 - -Hi3516DV300开发板套件所提供的触摸屏器件IC为GT911,该器件采用标准I2C与主机通信,通过6pin软排线与主板连接。6pin分布以及实物连接图如下图所示: - -![](figures/绘图1.png) - diff --git "a/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-2.md" "b/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-2.md" deleted file mode 100755 index eb01bec406aeb05019daeeb14148eaf702bfc598..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-2.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 示例开发 - -- **[拍照开发指导](拍照开发指导-3.md)** - -- **[录像开发指导](录像开发指导-4.md)** - -- **[预览开发指导](预览开发指导.md)** - - diff --git "a/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221.md" "b/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221.md" deleted file mode 100755 index e8128ecaaca0f0b5311d51b7e8f1cd8dc01c00a0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 示例开发 - -- **[拍照开发指导](拍照开发指导.md)** - -- **[录像开发指导](录像开发指导.md)** - - diff --git "a/zh-cn/device-dev/guide/\347\247\201\346\234\211\351\205\215\347\275\256\344\277\241\346\201\257\350\247\243\346\236\220.md" "b/zh-cn/device-dev/guide/\347\247\201\346\234\211\351\205\215\347\275\256\344\277\241\346\201\257\350\247\243\346\236\220.md" deleted file mode 100644 index a472a6dfdfba6d50c291b37dcc1718f56dabaaed..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\247\201\346\234\211\351\205\215\347\275\256\344\277\241\346\201\257\350\247\243\346\236\220.md" +++ /dev/null @@ -1,17 +0,0 @@ -# 私有配置信息解析 - -示例代码路径:./drivers/framework/model/input/driver/input\_config\_parser.c - -根据OSAL提供的配置解析函数,可以将hcs文件中各字段含义进行解析,具体请参考input\_config\_parser.c中各函数的实现。如果提供的模板不能满足需求,在hcs文件中添加相应信息后,需要根据添加的字段开发相应的解析函数。 - -``` -static int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode, BoardAttrCfg *attr) -{ - int32_t ret; - ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0); // 获取inputType字段信息,保存在BoardAttrCfg结构体中 - CHECK_PARSER_RET(ret, "GetUint8"); - ... - return HDF_SUCCESS; -} -``` - diff --git "a/zh-cn/device-dev/guide/\347\255\276\345\220\215\346\211\223\345\214\205.md" "b/zh-cn/device-dev/guide/\347\255\276\345\220\215\346\211\223\345\214\205.md" deleted file mode 100644 index a6fd6f965525ad87ae4b3be7b1987a97ddc0fa39..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\255\276\345\220\215\346\211\223\345\214\205.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 签名打包 - -代码编写完成后,在真机设备上运行应用,需要先对应用进行签名,然后再进行打包,具体操作请参考[签名打包指导](../../application-dev/quick-start/配置OpenHarmony应用签名信息.md)。 - diff --git "a/zh-cn/device-dev/guide/\347\256\241\347\220\206\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" "b/zh-cn/device-dev/guide/\347\256\241\347\220\206\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" deleted file mode 100644 index 73b05bf0b039741952505f3c30c5440a28c1e25b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\256\241\347\220\206\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" +++ /dev/null @@ -1,22 +0,0 @@ -# 管理驱动层初始化及注册驱动至HDF框架 - -示例代码路径:./drivers/framework/model/input/driver/hdf\_input\_device\_manager.c - -``` -static int32_t HdfInputManagerInit(struct HdfDeviceObject *device) -{ - /* 分配内存给manager,manager中将存放所有input设备 */ - g_inputManager = InputManagerInstance(); - ... -} -struct HdfDriverEntry g_hdfInputEntry = { - .moduleVersion = 1, - .moduleName = "HDF_INPUT_MANAGER", - .Bind = HdfInputManagerBind, - .Init = HdfInputManagerInit, - .Release = HdfInputManagerRelease, -}; - -HDF_INIT(g_hdfInputEntry); //驱动注册入口 -``` - diff --git "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225-13.md" "b/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225-13.md" deleted file mode 100644 index 587404009f050d03eeb8b95d221ea1beb2f3e062..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225-13.md" +++ /dev/null @@ -1,17 +0,0 @@ -# 编译及烧录 - -1. 编辑Makefile文件,添加本示例中的内容: - - 文件路径:./drivers/adapter/khdf/linux/model/input/Makefile - - 添加内容如下: - - ``` - obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \ - $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o - ``` - - 其中touch\_gt911.o为本示例中追加的内容。 - -2. 具体编译及烧录操作请参考[标准系统快速入门编译及烧录章节](../quick-start/标准系统入门.md)。 - diff --git "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225.md" "b/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225.md" deleted file mode 100644 index 92d839390d5dcacac6fdc98cb576d3e6312a0c69..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225.md" +++ /dev/null @@ -1,20 +0,0 @@ -# 编译及烧录 - -1. 编辑Makefile,添加源文件: - - ``` - include drivers/hdf/khdf/platform/platform.mk - - obj-y += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_core.o \ - $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_if.o \ - ./i2c_adapter.o \ - ./i2c_sample.o - ``` - - "./i2c\_sample.o"为本示例中在Makefile中追加的内容。 - -2. 编译及烧录。 - - 具体操作请参考[标准系统快速入门编译及烧录章节](../quick-start/标准系统入门.md)。 - - diff --git "a/zh-cn/device-dev/guide/\350\247\206\350\247\211\345\272\224\347\224\250\345\274\200\345\217\221.md" "b/zh-cn/device-dev/guide/\350\247\206\350\247\211\345\272\224\347\224\250\345\274\200\345\217\221.md" deleted file mode 100755 index b4a8975ab2b1883c7e69e324500c9fc516bb9b7e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\350\247\206\350\247\211\345\272\224\347\224\250\345\274\200\345\217\221.md" +++ /dev/null @@ -1,19 +0,0 @@ -# 视觉应用开发 - -- **[概述](概述-6.md)** - -- **[开发准备](开发准备.md)** - -- **[添加页面](添加页面.md)** - -- **[开发首页](开发首页.md)** - -- **[开发详情页](开发详情页.md)** - -- **[调试打包](调试打包.md)** - -- **[真机运行](真机运行.md)** - -- **[常见问题](常见问题.md)** - - diff --git "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\346\211\223\345\214\205.md" "b/zh-cn/device-dev/guide/\350\260\203\350\257\225\346\211\223\345\214\205.md" deleted file mode 100755 index 5015bd5755d4a5750aeeac6e699c6d8070dc9827..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\346\211\223\345\214\205.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 调试打包 - -代码编写完成后,可以进行调试和打包;应用调试及打包方法可以参考[《DevEco Studio使用指南》](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)的[应用调测](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/debug_overview-0000001053822404)和[编译构建](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201)章节。IPCamera应用暂时不支持签名模式,所以需要将应用发布为未签名的应用安装包。 - diff --git "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\351\252\214\350\257\201.md" "b/zh-cn/device-dev/guide/\350\260\203\350\257\225\351\252\214\350\257\201.md" deleted file mode 100644 index f339b20a630cc498481d71394a3f46225e537dfa..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\351\252\214\350\257\201.md" +++ /dev/null @@ -1,5 +0,0 @@ -# 调试验证 - -- **[开机日志分析](开机日志分析.md)** - - diff --git "a/zh-cn/device-dev/guide/\351\200\202\351\205\215\345\231\250\344\273\266\347\247\201\346\234\211\351\251\261\345\212\250.md" "b/zh-cn/device-dev/guide/\351\200\202\351\205\215\345\231\250\344\273\266\347\247\201\346\234\211\351\251\261\345\212\250.md" deleted file mode 100644 index b719de9bacbb19722563054b8aafa6584550bf1c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\200\202\351\205\215\345\231\250\344\273\266\347\247\201\346\234\211\351\251\261\345\212\250.md" +++ /dev/null @@ -1,99 +0,0 @@ -# 适配器件私有驱动 - -Input模型由三层驱动组成,开发者适配一款全新触摸屏驱动只需要适配器件驱动层即可,重点实现差异化接口,本小节以代码示例的形式展示开发者需要重点完成的工作。 - -1. 触摸屏器件差异化接口适配 - - 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c - - ``` - static struct TouchChipOps g_gt911ChipOps = { // 器件IC接口 - .Init = ChipInit, // 初始化 - .Detect = ChipDetect, // 器件检测 - .Resume = ChipResume, // 唤醒 - .Suspend = ChipSuspend, // 休眠 - .DataHandle = ChipDataHandle, // 器件数据读取 - .UpdateFirmware = UpdateFirmware, // 固件升级 - }; - - /* 不同触摸屏厂家使用的IC不一样,对应的寄存器操作也不一样,因此器件驱动层代码重点适配差异化接口部分,如下示例代码展示了GT911的数据解析*/ - - static int32_t ChipDataHandle(ChipDevice *device) - { - ... - /* GT911获取坐标之前需先读取状态寄存器 */ - reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; - ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); - if (ret < 0 || touchStatus == GT_EVENT_INVALID) { - return HDF_FAILURE; - } - ... - /* 根据状态寄存器的值读取数据寄存器数据 */ - reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; - pointNum = touchStatus & GT_FINGER_NUM_MASK; - if (pointNum == 0 || pointNum > MAX_SUPPORT_POINT) { - HDF_LOGE("%s: pointNum is invalid, %u", __func__, pointNum); - (void)ChipCleanBuffer(i2cClient); - OsalMutexUnlock(&device->driver->mutex); - return HDF_FAILURE; - } - frame->realPointNum = pointNum; - frame->definedEvent = TOUCH_DOWN; - (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); - /* 对获取的数据进行解析 */ - ParsePointData(device, frame, buf, pointNum); - ... - } - static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) - { - ... - /* 每个坐标值由两个字节组成,对获取的单字节数据进行拼接得到最终的坐标值 */ - for (i = 0; i < pointNum; i++) { - frame->fingers[i].trackId = buf[GT_POINT_SIZE * i + GT_TRACK_ID]; - frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - /* 对解析出来的坐标值进行打印 */ - HDF_LOGD("%s: x = %d, y = %d", __func__, frame->fingers[i].x, frame->fingers[i].y); - } - } - ``` - -2. 器件层驱动初始化及注册驱动至HDF框架 - - 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c - - ``` - static int32_t HdfGoodixChipInit(struct HdfDeviceObject *device) - { - ... - /* 器件配置结构体内存申请、配置信息解析及挂载 */ - chipCfg = ChipConfigInstance(device); - ... - /* 器件实例化 */ - chipDev = ChipDeviceInstance(); - ... - /* 器件信息挂载及器件私有操作挂载 */ - chipDev->chipCfg = chipCfg; - chipDev->ops = &g_gt911ChipOps; - ... - /* 注册器件驱动至平台驱动 */ - RegisterChipDevice(chipDev); - ... - } - struct HdfDriverEntry g_touchGoodixChipEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH_GT911", // 该moduleName与device_info.hcs文件中器件驱动层的moduleName信息相匹配 - .Init = HdfGoodixChipInit, // 器件驱动初始化函数 - }; - HDF_INIT(g_touchGoodixChipEntry); // 注册器件驱动至HDF框架 - ``` - - 器件私有驱动层主要实现了各器件厂商差异较大的部分,如器件休眠唤醒、数据解析以及固件升级等。 - - 至此,基于HDF框架及Input模型的触摸屏驱动适配完成。 - - diff --git "a/zh-cn/device-dev/guide/\351\205\215\347\275\256Touchscreen\345\231\250\344\273\266\344\277\241\346\201\257.md" "b/zh-cn/device-dev/guide/\351\205\215\347\275\256Touchscreen\345\231\250\344\273\266\344\277\241\346\201\257.md" deleted file mode 100644 index a56381458292b83a64324abba06a4a7301d7a25f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\205\215\347\275\256Touchscreen\345\231\250\344\273\266\344\277\241\346\201\257.md" +++ /dev/null @@ -1,98 +0,0 @@ -# 配置Touchscreen器件信息 - -配置文件路径:./drivers/adapter/khdf/linux/hcs/input/input\_config.hcs - -input\_config.hcs中的信息由驱动代码进行读取解析,主要由公共驱动层的私有配置信息及器件驱动层的私有配置信息组成。文件中的配置包含板级硬件信息及器件私有配置信息,实际业务开发时,可根据具体需求增删及修改对应内容。 - -``` -root { - input_config { - touchConfig { - touch0 { // 第一款触摸屏 - boardConfig { // 板级硬件信息 - match_attr = "touch_device1"; // 与设备描述配置信息中公共驱动层私有配置信息的“match_attr”字段保持一致 - inputAttr { - /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */ - inputType = 0; // input类型为touch - solutionX = 480; // 分辨率X信息 - solutionY = 960; // 分辨率Y信息 - devName = "main_touch"; // 设备名称 - } - busConfig { - /* 0:i2c 1:spi */ - busType = 0; // GT911采用I2C通信 - busNum = 6; // 与主机芯片第6路I2C通信 - clkGpio = 86; // 主机芯片SCL管脚 - dataGpio = 87; // 主机芯片SDA管脚 - i2cClkIomux = [0x114f0048, 0x403]; // SCL管脚配置信息 - i2cDataIomux = [0x114f004c, 0x403]; // SDA管脚配置信息 - } - pinConfig { - rstGpio = 3; // 复位管脚连接主机芯片的3号管脚 - intGpio = 4; // 中断管脚连接主机芯片的4号管脚 - rstRegCfg = [0x112f0094, 0x400]; // 复位管脚配置信息 - intRegCfg = [0x112f0098, 0x400]; // 中断管脚配置信息 - } - powerConfig { - /* 0:unused 1:ldo 2:gpio 3:pmic */ - vccType = 2; // GPIO供电 - vccNum = 20; // gpio20 - vccValue = 1800; // 电压幅值为1800mV - vciType = 1; // LDO供电 - vciNum = 12; // ldo12 - vciValue = 3300; // 电压幅值为3300mV - } - - featureConfig { - capacitanceTest = 0; // 容值测试 - gestureMode = 0; // 手势模式 - gloverMode = 0; // 手套模式 - coverMode = 0; // 皮套模式 - chargerMode = 0; // 充电模式 - knuckleMode = 0; // 指关节模式 - } - } - chipConfig { // 器件私有信息配置 - template touchChip { // 模板 - match_attr = ""; - chipName = "gt911"; // 触摸屏IC型号 - vendorName = "zsj"; // 供应商 - chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 - busType = 0; // 0代表I2C,1代表SPI - deviceAddr = 0x5D; // 器件IC通信地址 - irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 - maxSpeed = 400; // 最大通信速率为400Hz - chipVersion = 0; // 触摸屏IC版本号 - powerSequence { - /* 上电时序的配置含义说明: - [类型, 状态, 方向 , 延时] - 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 - 0代表下电或拉低,1代表上电或拉高,2代表无操作 - 0代表输入方向,1代表输出方向,2代表无操作 - 代表延时多少毫秒, 例如20代表延时20ms - */ - powerOnSeq = [4, 0, 1, 0, // 中断管脚配置为输出,且进行拉低 - 3, 0, 1, 10, // 复位管脚配置为输出,且进行拉低,延时10ms - 3, 1, 2, 60, // 复位管脚无操作,且进行拉高,延时60ms - 4, 2, 0, 0]; // 中断管脚配置为输入 - suspendSeq = [3, 0, 2, 10]; // 复位管脚无操作,且进行拉低,延时10ms - resumeSeq = [3, 1, 2, 10]; // 复位管脚无操作,且进行拉高,延时10ms - powerOffSeq = [3, 0, 2, 10, // 复位管脚无操作,且进行拉低,延时10ms - 1, 0, 2, 20]; // 电源正极管脚无操作,且进行拉低,延时20ms - } - } - - chip0 :: touchChip { - match_attr = "zsj_gt911_5p5"; // 与设备描述配置信息中器件私有配置信息的“match_attr”字段保持一致 - chipInfo = "ZIDN45100"; // 产品名+模组编号+芯片编号的组合信息 用于给用户态区分当前器件 - chipVersion = 0; // IC型号的版本 - } - } - } - } - } -} -``` - -示例中“touchConfig”包含了“touch0”,"touch0"包含了“boardConfig”与“chipConfig”;“boardConfig”字段包含了Hi3516DV300板级硬件信息,“chipConfig”包含了触摸屏器件的私有信息,如果需要替换触摸屏器件,重新配置“chipConfig”对应的字段信息即可。同时产品可以配置多款触摸屏,示例中用“touch0”代表了套件中默认的触摸屏的硬件接口以及器件的配置信息,如产品需要配置副屏,可在与“touch0”并列的位置配置“touch1”的信息。 - diff --git "a/zh-cn/device-dev/guide/\351\205\215\347\275\256\350\256\276\345\244\207\346\217\217\350\277\260\344\277\241\346\201\257.md" "b/zh-cn/device-dev/guide/\351\205\215\347\275\256\350\256\276\345\244\207\346\217\217\350\277\260\344\277\241\346\201\257.md" deleted file mode 100644 index 4183826a4fa9d0afa0ce01ff2ead4d3c1a0dac70..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\205\215\347\275\256\350\256\276\345\244\207\346\217\217\350\277\260\344\277\241\346\201\257.md" +++ /dev/null @@ -1,64 +0,0 @@ -# 配置设备描述信息 - -配置文件路径:./drivers/adapter/khdf/linux/hcs/device\_info/device\_info.hcs - -device\_info.hcs中的信息主要提供给HDF框架使用,包含了Input模型各层驱动注册到HDF框架所必需的信息,开发者无特殊场景需求无需改动。各驱动层私有配置信息通过“deviceMatchAttr”字段与input\_config.hcs中的“match\_attr”相关内容进行匹配。 - -配置文件中与input模块相关的内容如下所示,相关字段的详细含义可以参考《[驱动配置](../driver/驱动开发.md)》: - -``` -input :: host { - hostName = "input_host"; - priority = 100; - device_input_manager :: device { // Input管理层设备描述信息 - device0 :: deviceNode { - policy = 2; // 向内核用户态均发布服务 - priority = 100; // input管理层驱动优先级默认为100 - preload = 0; // 加载该驱动 - permission = 0660; // 驱动创建设备节点权限 - moduleName = "HDF_INPUT_MANAGER"; // 与驱动入口的moduleName匹配 - serviceName = "hdf_input_host"; // HDF框架生成的节点名 - deviceMatchAttr = ""; // manager目前不需要私有配置,因此为空 - } - } - - device_hdf_touch :: device { // Input公共驱动层设备描述信息 - device0 :: deviceNode { - policy = 2; // 向内核用户态均发布服务 - priority = 120; // input公共驱动优先级默认为120 - preload = 0; // 加载该驱动 - permission = 0660; // 驱动创建设备节点权限 - moduleName = "HDF_TOUCH"; // 与驱动入口的moduleName匹配 - serviceName = "hdf_input_event1"; // HDF框架生成的节点名 - deviceMatchAttr = "touch_device1"; // 与私有配置信息中的“match_attr”字段保持一致 - } - } - - device_touch_chip :: device { // Input器件驱动层信息 - device0 :: deviceNode { - policy = 0; // 向内核用户态均不发布服务 - priority = 130; // input器件驱动优先级默认为130 - preload = 0; // 加载该驱动 - permission = 0660; // 驱动创建设备节点权限 - moduleName = "HDF_TOUCH_GT911"; // 与驱动入口的moduleName匹配 - serviceName = "hdf_touch_gt911_service";// HDF框架生成的节点名 - deviceMatchAttr = "zsj_gt911_5p5"; //与私有配置信息中的“match_attr”字段保持一致 - } - } - } -``` - -该配置文件中需要重点关注的字段有: - -“priority”决定驱动加载顺序; - -“preload”决定驱动是否加载; - -“moduleName ”需要与驱动注册入口处的“moduleName ”字段保持一致; - -“serviceName ”HDF框架依据该字段创建节点名; - -“deviceMatchAttr ”需要与私有配置信息中的“match\_attr”字段保持一致。 - -通过配置设备描述信息,使得HDF框架通过moduleName与注册至驱动入口的代码相匹配,保证了驱动的正常加载,通过priority字段保证了各驱动的加载顺序。 - diff --git "a/zh-cn/device-dev/guide/\351\233\206\346\210\220\344\270\211\346\226\271SDK.md" "b/zh-cn/device-dev/guide/\351\233\206\346\210\220\344\270\211\346\226\271SDK.md" deleted file mode 100755 index 355c2b275b3e532be944d3b46dee2cc073060f73..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\233\206\346\210\220\344\270\211\346\226\271SDK.md" +++ /dev/null @@ -1,325 +0,0 @@ -# 集成三方SDK - -- [规划目录结构](#section1736472718351) -- [构建业务libs](#section442815485351) -- [编写适配代码](#section3984721113613) -- [代码编写](#section830417531286) -- [脚本编写](#section13500201173710) -- [编写业务代码](#section8754114803918) -- [运行](#section7737749184012) -- [结束](#section153301392411) - -OpenHarmony致力于打造一套更加开放完善的IoT生态系统,为此OpenHarmony规划了一组目录,用于将各厂商的SDK集成到OpenHarmony中。本文档基于Hi3861开发板,向平台开发者介绍将SDK集成到OpenHarmony的方法。 - -## 规划目录结构 - -三方SDK通常由静态库和适配代码构成。SDK的业务逻辑通过硬件模组工具链编译得到静态库libs,每款模组都有其对应的libs。SDK的南向API与OpenHarmony 的API存在使用差异,该差异可通过adapter适配代码屏蔽,不同模组可共用一套adapter。 - -基于以上特征,在OpenHarmony目录结构中,可以对三方SDK目录做如下划分。 - -- 适配代码adapter,放置到domains/iot/link/ 目录下,与模组解耦。 -- 业务库libs,放置到device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/ 目录下,与模组绑定。 - -平台开发者在适配前,务必先依次完成以下步骤,下面以demolink SDK举例,进行介绍。 - -1. 创建厂商目录,domains/iot/link/demolink/、device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/ ,用于厂商隔离。 -2. 创建domains/iot/link/demolink/BUILD.gn ,用于构建适配代码。 -3. 创建device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录,用于存放业务库libs。 - -``` -. -├── domains -│ └── iot -│ └── link -│ ├── demolink -│ │ └── BUILD.gn -│ ├── libbuild -│ │ └── BUILD.gn -│ └── BUILD.gn -└── device - └── hisilicon - └── hispark_pegasus - └── sdk_liteos - └── 3rd_sdk - └── demolink - └── libs -``` - -## 构建业务libs - -平台SDK业务一般以静态库的形式提供,平台厂商在获取到OpenHarmony代码后,需要根据对应的硬件模组vendor,编译业务libs,并将编译结果放置在device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录下。下面介绍业务libs的构建方法。 - -OpenHarmony已规划用于编译业务libs的目录domains/iot/link/libbuild/ ,该目录中包含domains/iot/link/libbuild/BUILD.gn和domains/iot/link/BUILD.gn文件,目录结构如下。 - -``` -. -└── domains - └── iot - └── link - ├── demolink - │ └── BUILD.gn - ├── libbuild - │ └── BUILD.gn - └── BUILD.gn -``` - -平台开发者在构建libs前,务必先完成如下步骤。 - -1. 在domains/iot/link/libbuild/ 目录下放置业务源码文件,包括.c和.h文件。 - - ``` - . - └── domains - └── iot - └── link - ├── demolink - │ ├── demosdk_adapter.c - │ ├── demosdk_adapter.h - │ └── BUILD.gn - ├── libbuild - │ ├── demosdk.c - │ ├── demosdk.h - │ └── BUILD.gn - └── BUILD.gn - ``` - -2. 适配domains/iot/link/libbuild/BUILD.gn,在编译完成后还原该文件。 - - 在BUILD.gn中,sources为需要参与构建的源文件,include\_dirs为依赖的头文件路径,构建的目标结果是生成静态库libdemosdk.a。 - - ``` - static_library("demosdk") { - sources = [ - "demosdk.c" - ] - include_dirs = [ - "//domains/iot/link/libbuild", - "//domains/iot/link/demolink" - ] - } - ``` - -3. 适配domains/iot/link/BUILD.gn,在编译完成后还原该文件。 - - 此BUILD.gn文件用于指定构建条目,需要在features中填入所有需参与编译的静态库条目,使domains/iot/link/libbuild/BUILD.gn参与到构建中来。 - - ``` - import("//build/lite/config/subsystem/lite_subsystem.gni") - import("//build/lite/config/component/lite_component.gni") - lite_subsystem("iot") { - subsystem_components = [ - ":link" - ] - } - lite_component("link") { - features = [ - "libbuild:demosdk" - ] - } - ``` - - -完成以上3点后,需在代码根目录下执行命令“hb build -T //domains/iot/link:iot”,等待执行完成,检查out/hispark\_pegasus/wifiiot\_hispark\_pegasus/libs/目录下是否生成了目标库文件。 - -![](figures/zh-cn_image_0000001078563230.png) - -将库文件拷贝到device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录下,并将domains/iot/link/libbuild/ 目录中的.c和.h文件清除。 - -## 编写适配代码 - -## 代码编写 - -平台SDK中使用的API通常与OpenHarmony API存在差异,无法直接使用,需要一层适配代码adapter进行中间转换。本节以domains/iot/link/demolink/demosdk\_adapter.c中的任务创建接口DemoSdkCreateTask举例,向开发者演示如何在OpenHarmony上编写适配代码。 - -1. 查看待适配接口DemoSdkCreateTask的描述、参数、返回值。 - - ``` - struct TaskPara { - char *name; - void *(*func)(char* arg); - void *arg; - unsigned char prio; - unsigned int size; - }; - - /* - * IoT OS 创建线程接口 - * 返回值: 返回0 成功, 其他 失败 - */ - int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para); - ``` - -2. 查看OpenHarmony API接口文档,选取一个功能类似的接口,并比对参数及用法上的差异。例如本文选取osThreadNew ,通过和DemoSdkCreateTask接口比对,可以发现两接口依赖的参数基本一致,只是参数所归属的结构体不同。 - - ``` - typedef struct { - const char *name; ///< name of the thread - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block - void *stack_mem; ///< memory for stack - uint32_t stack_size; ///< size of stack - osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) - TZ_ModuleId_t tz_module; ///< TrustZone module identifier - uint32_t reserved; ///< reserved (must be 0) - } osThreadAttr_t; - - /// Create a thread and add it to Active Threads. - /// \param[in] func thread function. - /// \param[in] argument pointer that is passed to the thread function as start argument. - /// \param[in] attr thread attributes; NULL: default values. - /// \return thread ID for reference by other functions or NULL in case of error. - osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); - ``` - -3. 完成代码差异转换。 - - ``` - int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para) - { - osThreadAttr_t attr = {0}; - osThreadId_t threadId; - if (handle == 0 || para == 0) { - return DEMOSDK_ERR; - } - if (para->func == 0) { - return DEMOSDK_ERR; - } - if (para->name == 0) { - return DEMOSDK_ERR; - } - attr.name = para->name; - attr.priority = para->prio; - attr.stack_size = para->size; - threadId = osThreadNew((osThreadFunc_t)para->func, para->arg, &attr); - if (threadId == 0) { - printf("osThreadNew fail\n"); - return DEMOSDK_ERR; - } - *(unsigned int *)handle = (unsigned int)threadId; - return DEMOSDK_OK; - } - ``` - - -## 脚本编写 - -开发者在完成代码适配后,还需要在adapter同级目录下新建BUILD.gn文件。该文件可在整包构建时,将适配代码编译成静态库,并链接到bin包中去。在domains/iot/link/demolink/BUILD.gn中,sources中为需要参与构建的源文件,include\_dirs中为依赖的头文件路径,构建目标结果是生产静态库libdemolinkadapter.a。 - -``` -import("//build/lite/config/component/lite_component.gni") -static_library("demolinkadapter") { - sources = [ - "demosdk_adapter.c" - ] - include_dirs = [ - "//kernel/liteos-m/kal/cmsis", - "//domains/iot/link/demolink" - ] -} -``` - -修改domains/iot/link/BUILD.gn文件,使domain/iot/hilink/BUILD.gn参与到构建系统中。 - -``` -import("//build/lite/config/subsystem/lite_subsystem.gni") -import("//build/lite/config/component/lite_component.gni") -lite_subsystem("iot") { - subsystem_components = [ - ":link" - ] -} -lite_component("link") { - features = [ - "demolink:demolinkadapter" - ] -} -``` - -## 编写业务代码 - -业务libs库和适配代码准备就绪后,还需要编写业务入口函数,调起三方SDK的业务入口。 - -下面以demolink举例,介绍如何在applications/sample/wifi-iot/app/路径下编写代码,调起demosdk的入口函数。 - -1. 目录创建 - - 开发者编写业务时,务必先在applications/sample/wifi-iot/app/ 路径下新建一个目录(或一套目录结构),用于存放业务源码文件。 - - 例如:在app下新增业务目录demolink,并在其中创建业务入口代码helloworld.c和编译构建文件BUILD.gn,如下。 - - ``` - . - └── applications - └── sample - └── wifi-iot - └── app - │── demolink - │ │── helloworld.c - │ └── BUILD.gn - └── BUILD.gn - ``` - -2. 编写业务代码。 - - 在helloworld.c文件中编写业务入口函数DemoSdkMain,并调起demolink的业务DemoSdkEntry,最后通过SYS\_RUN\(\)调用入口函数完成业务启动。 - - ``` - #include "hos_init.h" - #include "demosdk.h" - - void DemoSdkMain(void) - { - DemoSdkEntry(); - } - - SYS_RUN(DemoSdkMain); - ``` - -3. 编写构建脚本 - - 新增applications/sample/wifi-iot/app/demolink/BUILD.gn文件,指定源码和头文件路径,编译输出静态库文件libexample\_demolink.a。 - - ``` - static_library("example_demolink") { - sources = [ - "helloworld.c" - ] - include_dirs = [ - "//utils/native/lite/include", - "//domains/iot/link/libbuild" - ] - } - ``` - - 修改applications/sample/wifi-iot/app/BUILD.gn,使demolink参与编译。 - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("app") { - features = [ - "demolink:example_demolink" - ] - } - ``` - - -## 运行 - -在代码根目录下,执行命令“hb build”编译输出版本包。最后启动运行,运行结果如图所示,与demolink预期相符。 - -``` -ready to OS start -sdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00 -formatting spiffs... -FileSystem mount ok. -wifi init success! -it is demosdk entry. -it is demo biz: hello world. -it is demo biz: hello world. -``` - -## 结束 - -至此,三方SDK集成已介绍完毕。 - diff --git "a/zh-cn/device-dev/guide/\351\252\214\350\257\201.md" "b/zh-cn/device-dev/guide/\351\252\214\350\257\201.md" deleted file mode 100755 index e9be36acdfb301de6902f16081f4e792cdebe00d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\252\214\350\257\201.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 验证 - -编译过程请参考《[Hi3861快速入门-源码编译](../quick-start/运行Hello-World.md)》,烧录过程请参考《[Hi3861快速入门-镜像烧录](../quick-start/WLAN联网.md)》。 - -完成以上两步后,按下RST键复位模组,可发现LED在周期性闪烁,与预期相符,验证完毕。 - -**图 1** LED闪烁图 -![](figures/LED闪烁图.gif "LED闪烁图") - diff --git "a/zh-cn/device-dev/kernel-contribution/OpenHarmony\345\206\205\346\240\270\346\226\207\346\241\243\345\205\261\345\273\272ToDo-List.md" "b/zh-cn/device-dev/kernel-contribution/OpenHarmony\345\206\205\346\240\270\346\226\207\346\241\243\345\205\261\345\273\272ToDo-List.md" deleted file mode 100644 index ce1082a69f28edf6313a5883728bf45c2b6b3389..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel-contribution/OpenHarmony\345\206\205\346\240\270\346\226\207\346\241\243\345\205\261\345\273\272ToDo-List.md" +++ /dev/null @@ -1,245 +0,0 @@ -# OpenHarmony文档共建计划--内核文档共建 - - - -| 2021-06-28-2021-07-30 | 2021-07-05 | 2021-07-05-2021-07-30 | 2021-08-01-2021-08-31 | -| --------------------------------- | -------------------------------- | -------------------------- | --------------------- | -| **任务招募** | **线上会议** | **文档共建** | **结项发布** | -| ToDo List、文档模板、共建手册大纲 | 文档共建介绍、写作规范、常见操作 | 小组周进展跟踪、导师辅导制 | 发布共建后内核文档 | - -- [如何参与](#section_register) -- [文档共建范围](#section_outline_summary) -- [文档大纲及认领明细](section_outline_detail) - -## 共建活动ToDoList - -OpenHarmony文档共建活动是由OpenHarmony社区举办,旨在进一步丰富和完善现有文档,提升文档体验**,**更好地服务于广大开发者。本次文档共建活动有共建移植文档、内核文档、Qemu仿真文档。详情请参考共建手册大纲:《基于Qemu运行OpenHarmony》、 《小型系统三方芯片移植指南》、《OpenHarmony内核开发指南》。 - -即日起开发者可自主选择并认领感兴趣的任务,获得社区资深**技术导师**和**文档导师**的指导。根据项目的难易程度和完成情况,参与者还将获得"**OpenHarmony 文档共建贡献者** " 荣誉及周边纪念品。 - -1. **活动时间:** 2021-06-28~2021-07-30 - -2. **招募对象:** - - - 技术写作者 - - - 文档验证/审核者 - - - 小组组织人员 - -3. **招募要求:** -- 熟悉嵌入式、物联网等OS开发相关知识 - -- 有扎实的C语言编程经验 - -- 有较强的文字写作能力、逻辑思维能力 - -4. **参与方式:** - - - Gitee社区内认领任务反馈 - - 开发者加入内核文档共建招募活动微信群 -5. 共建激励规则 - -**卓越贡献奖** - -- **奖励对象:**审核通过&内容被采纳的contributor。 - -- **奖励礼品:**OpenHarmonyT恤、帽子等周边纪念品。 - - - -## 如何参与 -- 方式1 [Issue回帖](https://gitee.com/openharmony/docs/issues/I3Y9MU?from=project-issue) -- 方式2 微信交流群报名 -- 方式3 邮件反馈 @neeen @rtos_yuan ,邮件主题:OpenHarmony轻内核文档共建报名 -3种方式均可报名,建议同时提供邮箱,方便后续发送线上会议交流通知。 - - -## 文档共建范围 - -### 1、基于Qemu运行OpenHarmony---招募内容写作 - -- 背景 - - - 对于想体验OpenHarmony的开发者,手头不一定有现成的开发板,基于Qemu可以降低入门体验门槛。 - - - 已经支持Qemu,但是没有对应的文档, 快速入门只有3861、3516、3518等板子。 - -- 文档计划 - - LiteOS-A、LiteOS-M Qemu使用教程第一时间上社区,社区化运作文档,降低社区开发者体验OpenHarmony开发的门槛。 - -- **访问[《基于Qemu运行OpenHarmony 文档大纲》](#section_qemu_outline_detail)。** - -### 2、小型系统三方芯片移植指南---招募内容体验&验证 - -社区支持的开发板有限,三方芯片、开发板移植需要更丰富的开发板场景案例。 -- 文档计划 - - - 鼓励开发者完善移植文档,支持社区开发者移植支持更多的开发板、支持手头的开发板能运行起来。 - - 鼓励移植经验文档回馈社区。 - -- **访问[《小型系统三方芯片移植指南 文档大纲》](#porting_tutorial_outline_detail)。** - -### 3、小型系统内核开发指南(LiteOS-A核)---招募内容体验&验证 - -- 文档计划 - - - 优化后内核文档初稿完成,鼓励开发者体验新内容,验证内容。 - - 社区化文档运作,鼓励社区开发者参与文档的优化编写,文档问题反馈。 - -- **访问[《OpenHarmony 内核开发指南(LiteOS-A核) 文档大纲》](#kernel_a_tutorial_outline_detail)。** - - - - -## 文档大纲及认领明细 - -✨**文档大纲用于维护文档的组成章节、章节意图,编写责任人,及PR合入状态**。 - -✨**使用对号[✔]表示文档的完成状态,第一个对号表示文档开发完成,第二个对号表示文档开发完成**。 - -### 一、基于Qemu运行OpenHarmony 文档大纲 - -#### 1 Qemu简介 [@rtos_yuan](https://gitee.com/rtos_yuan) [✔] [@mgy917](https://gitee.com/mgy917) [✔] - - - -#### 2 开发环境准备 [@mgy917](https://gitee.com/mgy917) [✔] [@rtos_yuan](https://gitee.com/rtos_yuan) [✔] - -- 2.1 OpenHarmony开发环境准备 - - - 环境搭建 - - 获取OpenHarmony源码 - -- 2.2 Qemu软件安装 - - 开发者根据需求,选择运行LiteOS-A、LiteOS-M的Qemu软件。 - - - Qemu软件编译安装 - - Qemu-Virt软件 - - Qemu-Riscv32软件 [@zhushengle](https://gitee.com/zhushengle) [✔] - - - -#### 3 Qemu工程源码介绍 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - -* 3.1 Qemu工程源码介绍 - -#### 4 编译运行LiteOS-A Qemu Virt工程 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - -- 4.1 编译构建LiteOS-A -- 4.2 运行镜像 - - 准备Flash镜像 - - 配置主机网桥 - - 运行程序 - -#### 5 编译运行LiteOS-M Qemu Riscv工程 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - -- 4.1 编译构建LiteOS-M -- 4.2 运行程序 - -### 二、小型系统三方芯片移植指南 ---招募内容体验&验证 - -#### 1 移植准备 [@arvinzzz](https://gitee.com/arvinzzz) [✔] [@rtos_yuan](https://gitee.com/rtos_yuan) [✔] - - - -##### 1.1 移植须知 - -##### 1.2 编译构建 - -#### 2 内核移植 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - -- 2.1 LiteOS-A内核 - - - - - 2.1.1 移植概述 - - 2.1.2 内核基础适配 - - 2.1.3 内核移植验证 - -- 2.2 Linux内核 - - - -#### 3 板级移植 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - - - -### 三、小型系统内核开发指南(LiteOS-A核)---招募内容体验&验证 - -#### 1 认识LiteOS-A内核 [@kkup180](https://gitee.com/kkup180) [✔] [@mgy917](https://gitee.com/mgy917) [✔] - - - -- 1.1 简介 -- 1.2 内核架构 -- 1.3 CPU体系架构支持 - -#### 2 基础内核 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - - - -- 2.1 中断及异常处理 -- 2.2 进程管理 -- 2.3 线程管理 -- 2.4 调度 -- 2.5 内存管理 - - 2.5.1 堆内存管理 - - 2.5.2 虚拟内存管理 - - 2.5.3 物理内存管理 - - 2.5.4 虚实映射 -- 2.6 IPC - - 2.6.1 事件 - - 2.6.2 信号量 - - 2.6.3 互斥锁 - - 2.6.4 消息队列 - - 2.6.5 读写锁 - - 2.6.6 futex - - 2.6.7 信号 -- 2.7 系统调用 -- 2.8 时间管理 -- 2.9 软件定时器 -- 2.10 原子操作 -#### 3 扩展组件 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - - - -- 3.1 ELF内核加载器 -- 3.2 VDSO -- 3.3 LiteIPC -- 3.4 CPUP -- 3.5 C++支持 -#### 4 文件系统 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - - - -- 4.1 vfs - -- 4.2 支持的文件系统 - - 4.2.1 FAT - - 4.2.2 jffs2 - - 4.2.3 nfs - - 4.2.4 ramfs - - 4.2.5 procfs -- 4.3 适配新的文件系统 -#### 5 内核启动 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] -- 5.1 运行机制 -#### 6 用户态启动 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] -- 6.1 用户态根进程启动 -- 6.2 用户态程序运行 -#### 7 调测 [@waitForContributor](https://gitee.com/openharmony/docs/issues)[ ?] - - - -- 7.1 内存调测 -- 7.2 Trace -- 7.3 魔法键 -- 7.4 Dying gasp -- 7.5 常见问题定位方法 -#### 8 附录 [@rtos_yuan](https://gitee.com/rtos_yuan) [✔] [@harylee](https://gitee.com/harylee)[✔] -- 8.1 基本数据结构 - - 8.1.1 双向链表 - - 8.1.2 位操作 - diff --git "a/zh-cn/device-dev/kernel-contribution/template/\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/zh-cn/device-dev/kernel-contribution/template/\345\270\270\350\247\201\351\227\256\351\242\230.md" deleted file mode 100644 index 976524f98b7145daf34642bd563c4d442de35cd6..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel-contribution/template/\345\270\270\350\247\201\351\227\256\351\242\230.md" +++ /dev/null @@ -1,51 +0,0 @@ -# 常见问题 - -** *【写作要求】*** - - -*可选。描述开发过程遇到的各类问题以及解决方案,以提高开发效率。* - - -- * 如果无常见问题,删除此章节。* - -- * 如果有常见问题,建议单独章节,后续具备扩展性。* - -- * 如果有常见问题,问题少于1屏且未来扩充可能性不大,可放在“开发指导”。* - - -*具体写作要求见下,完成写作后,请逐项自检下。* - - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| **N1** | **整体要求** | | -| N1.1 | 问题是否对外呈现(考虑重要性、出现概率等),请在部门内部CCB达成一致。 | | -| N1.2 | 每个问题描述里一般只问一个问题,避免多个问题合在一个问题描述。 | | -| N1.3 | 如果问题比较多,可以对问题进行分类。 | | -| **N2** | **单个问题要求** | | -| N2.1 | 标题:1句话描述问题场景、现象。 | | -| N2.2 | 现象描述:以用户视角黑盒描述问题出现的场景、现象、条件、概率等。描述问题现象清晰,没有歧义。 | | -| N2.3 | 可能原因:明确问题根本的原因。 | | -| N2.4 | 处理步骤-1:明确处理问题的步骤,step by step操作,具体要求同“开发步骤”部分。 | | -| N2.5 | 处理步骤-2:答复必须是严谨、明确的解决方法,口径与产品宣传一致,不能是参考建议这类含糊的回答。 | | -| N2.6 | 处理步骤-3:如果问题与能力版本有关联性的,需要明确。 | | - - -## 1.XX问题(简单问题) - -XXX - - -## 2.XX问题(复杂问题) - -**现象描述** - -XXX - -**可能原因** - -XXX - -**解决办法** - -XXX diff --git "a/zh-cn/device-dev/kernel-contribution/template/\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/kernel-contribution/template/\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100644 index 54133ebda8d12e93b00dfd1c9be5f062874cbe77..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel-contribution/template/\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,49 +0,0 @@ -# 开发实例 - -** *【写作要求】*** - - -*必选。描述开发完成后,基于一个任务整体做代码段的描述。* - - -- * 标题名称不变。如果“开发指导”是多场景,标题名称可以调整为拍照开发实例、预览开发指导等。* - -- * 标题可合并。如果产品链接到示例代码或内容少于1屏,可合并到“开发指导”,整本统一。* - - -*具体写作要求见下,完成写作后,请逐项自检下。* - - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| M1.1 | 有任务的场景介绍,且和代码端内容呼应。 | | -| M1.2 | 代码段顺利指导完成操作,无缺失。 | | -| M1.3 | 代码涉及开发者拷贝的命令,必须用可编辑的报文呈现,避免截图(DOCS插入Screen)。 | | -| M1.4 | 代码中关键段用蓝色(RGB:0.0.255)突出显示,关键步骤要有注释说明。 | | -| M1.5 | 代码显示符合代码缩进要求。 | | - - -**【写作样例---节选】** - - -SDIO设备完整的使用示例如下所示,首先打开总线号为1的SDIO控制器,然后独占HOST、使能设备、注册中断,接着进行SDIO通信(读写等),通信完成之后,释放中断、去使能设备、释放HOST,最后关闭SDIO控制器。 -``` -#include "hdf_log.h" -#include "sdio_if.h" - -#define TEST_FUNC_NUM 1 /* 本测试用例中,使用编号为1的I/O function */ -#define TEST_FBR_BASE_ADDR 0x100 /* 编号为1的I/O function的FBR基地址 */ -#define TEST_ADDR_OFFSET 9 /* 本测试用例中,需要读写的寄存器的地址偏移 */ -#define TEST_DATA_LEN 3 /* 本测试用例中,读写数据的长度 */ -#define TEST_BLOCKSIZE 2 /* 本测试用例中,数据块的大小,单位字节 */ - -/* 中断服务函数,需要根据各自平台的情况去实现 */ -static void SdioIrqFunc(void *data) -{ - if (data == NULL) { - HDF_LOGE("SdioIrqFunc: data is NULL.\n"); - return; - } - /* 需要开发者自行添加具体的实现 */ -} -``` diff --git "a/zh-cn/device-dev/kernel-contribution/template/\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/kernel-contribution/template/\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100644 index 2b4b6a3a9381255de70fbcd23281176f0e38560b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel-contribution/template/\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,128 +0,0 @@ -# 开发指导 - -** *【写作要求】*** - - -*必选。* *描述各个场景下,开发者如何完成开发任务。* *可根据多场景任务增加章节。写作要求见下,完成写作后,请逐项自检。* - - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| H.1.1 | 如果有多个场景,请写起多个“开发指导”章节,如音频播放开发指导、音量管理开发指导、短音播放开发指导。 | | -| H.1.2 | 标题尽量使用“动词+名词”的句式表述任务操作。 | | - - -## 场景介绍 - -** *【写作要求】*** - -*必选。* *描述在什么情景下解决什么问题,最终达到什么样的效果。*应用SCQA描述方法: - -- S:situation(情景),由大家都熟悉的的情景,事实引入。 - -- C:complication(冲突),但是实际情况往往和我们的要求有冲突。 - -- Q:question(疑问),怎么办? - -- A:answer(回答),我们的解决方案是 … - -*写作要求见下,完成写作后,请逐项自检。* - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| I.1.1 | 背景原因、什么时候在哪、做了什么操作、最终解决什么问题或操作效果都明确。 | | - -**【写作样例】** - -音频播放的主要工作是将音频数据转码为可听见的音频模拟信号并通过输出设备进行播放,同时对播放任务进行管理。 - - -## 接口说明 - -** *【写作要求】*** - -*必选。* *描述本开发指导相关的接口有哪些,旨在要开发者在开发前有大体了解,提升开发效率。* *写作要求见下,完成写作后,请逐项自检。* - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| J.1.1 | 不在本开发任务的接口无需提供。 | | -| J.1.2 | 如果接口太多,超过10个,可以提供主要的接口 | | - -**【写作样例】** - -音频播放开放能力如下:AudioRenderer类,具体的API详见接口文档。 - -**表1** 音频播放API接口功能介绍 - -| 接口名 | 描述 | -| -------- | -------- | -| AudioRenderer(AudioRendererInfo audioRendererInfo, PlayMode pm) throws IllegalArgumentException | 构造函数,设置播放相关音频参数和播放模式,使用默认播放设备 | -| AudioRenderer(AudioRendererInfo audioRendererInfo, PlayMode pm, AudioDeviceDescriptor outputDevice) throws IllegalArgumentException | 构造函数,设置播放相关音频参数、播放模式和播放设备 | -| boolean play() | 播放音频流 | -| boolean write(byte[] data, int offset, int size) | 将音频数据以byte流写入音频接收器以进行播放 | - - -## 开发步骤 - -** *【写作要求】*** - - * 必选。描述* *开发的整体过程,便于开发者快速完成开发。* * 具体 写作要求见下,完成写作后,请逐项自检下。* -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| **K.1** | **如何写好步骤** | | -| K.1.1 | 步骤完整:提供必须的步骤,顺利指导完成操作,无缺失。 | | -| K.1.2 | 脉络清楚:文档逻辑清晰、合理。文档前面的概述、准备、操作围绕一条线描述,不能章节断裂或前后矛盾的现象。 | | -| K.1.3 | 任务句式:标题或句子尽量使用“动词+名词”的句式表述动作。 | | -| K.1.4 | 预防提前:操作过程中的限制、易错的、有潜在风险的,要提前描述,使用DOCS平台的“插入> 说明 > 须知”描述。 | | -| K.1.5 | 步骤清晰-1:无论步骤简单或复杂,都需要写步骤目的,即为什么做。 | | -| K.1.6 | 步骤清晰-2:明确在什么环境下,使用什么工具,做什么操作,怎么做该操作。 | | -| K.1.7 | 步骤具体:如果操作可选,要明确可选条件。 | | -| K.1.8 | 在开发步骤执行完成后,及时明确操作正确的标准。 | | -| **K.2** | **如何写好代码段** | | -| K.2.1 | 代码涉及开发者拷贝的命令,必须用可编辑的报文呈现,避免截图(DOCS插入Screen)。 | | -| K.2.2 | 代码中关键段用蓝色(RGB:0.0.255)突出显示,关键步骤要有注释说明。 | | -| K.2.3 | 代码显示符合代码缩进要求。 | | -| K.2.4 | 步骤涉及接口调用,清晰给出接口及其使用说明或示例代码,代码来源于具体实例。 | | - -**【写作样例】** - -1. 构造音频流参数的数据结构AudioStreamInfo,推荐使用AudioStreamInfo.Builder类来构造,模板如下,模板中设置的均为AudioStreamInfo.Builder类的默认值,根据音频流的具体规格来设置具体参数。 - ``` - AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder().sampleRate( AudioStreamInfo.SAMPLE_RATE_UNSPECIFIED) .audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_NONE) .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_INVALID) .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_INVALID) .streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_UNKNOWN) .build(); - ``` - - 以真实的播放pcm流为例: - ``` - AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder().sampleRate(44100)//44.1kHz .audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_MAY_DUCK)//混音 .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT)//16-bit PCM .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_OUT_STEREO)//双声道 .streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA)//媒体类音频 .build(); - ``` - -2. 使用步骤1创建的音频流构建音频播放的参数结构AudioRendererInfo,推荐使用AudioRendererInfo.Builder类来构造,模板如下,模板中设置的均为AudioRendererInfo.Builder类的默认值,根据音频播放的具体规格来设置具体参数。 - ``` - AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(audioStreamInfo) .audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_NONE) .bufferSizeInBytes(0) .distributedDeviceId("") .isOffload(false) .sessionID(AudioRendererInfo.SESSION_ID_UNSPECIFIED) .build(); - ``` - - 以真实的播放pcm流为例: - ``` - AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(audioStreamInfo) .audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM)//pcm格式的输出流 .bufferSizeInBytes(100) .distributedDeviceId("E54***5E8")//使用分布式设备E54***5E8播放 .isOffload(false)//false表示分段传输buffer并播放,true表示整个音频流一次性传输到HAL层播放 .build(); - ``` - -3. 根据要播放音频流指定PlayMode,不同的PlayMode在写数据时存在差异,详情见步骤7,其余播放流程是无区别的。并通过构造函数获取AudioRenderer类的实例化对象。 - .... - -4. 播放任务结束后,调用AudioRenderer实例化对象的release()释放资源。 - - -## 调测验证(可选) - -** *【写作要求】*** - -*可选。* *描述开发完成后,进行调测验证,确保最终操作成功。* *操作步骤要求同“开发指导”,其他具体写作要求见下,完成写作后,请逐项自检下。* - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| L1.1 | 仅进行最后的业务调测,每个小任务的操作结果,在开发步骤执行完成后,及时验证操作结果。 | | -| L1.2 | 明确开发成功标准。 | | - -**【写作样例---节选】** - -![1624266401415](C:\Users\LWX104~1\AppData\Local\Temp\1624266401415.png) diff --git "a/zh-cn/device-dev/kernel-contribution/template/\346\220\255\345\273\272\347\216\257\345\242\203.md" "b/zh-cn/device-dev/kernel-contribution/template/\346\220\255\345\273\272\347\216\257\345\242\203.md" deleted file mode 100644 index 743adf6abcf01ab23d2112c2cffd2fb99d3db197..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel-contribution/template/\346\220\255\345\273\272\347\216\257\345\242\203.md" +++ /dev/null @@ -1,82 +0,0 @@ -# 搭建环境 - -** *【写作要求】*** - - -*条件必选。* *如果在快速入门里已提供此部分,此章节可以不提供。明确如何搭建开发环境(如开发工具、编译工具)*。 - - -## 环境要求 - -** *【写作要求】*** - -*必选。* *明确开发环境所需要的软硬件配置,* *旨在要用户提前准备环境。*如果软硬件内容比较多,可以再增加子标题。写作要求见下,完成写作后,请逐项自检。 - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| E.1.1 | 分别明确开发的软硬环境和手机的开发环境,下载路径。 | | -| E1.2 | 明确具体的版本号。 | | - - -**【写作样例】** - - -**表1** 环境要求 - -| 项目 | PC | 手机 | -| -------- | -------- | -------- | -| 硬件 | - 内存:8G及以上
- 硬盘:100G及以上
- 分辨率:1280\*800 | 处理器不低于kirin 980的华为手机 | -| 软件 | 操作系统:Windows10 64位  或 Mac 10。 | 系统软件版本不低于EMUI_10.0.0 | - - -## 安装环境 - -** *【写作要求】*** - -必选。描述安装环境的具体步骤,如果内容比较多,可以区分安装环境章节,如:安装编译基础环境、安装编译工具环境、安装gcc_riscv32(WLAN模组类编译工具链)。 - -写作要求见下,完成写作后,请逐项自检。 - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| **F.1** | **如何写好步骤** | | -| F.1.1 | 步骤完整:提供必须的步骤,顺利指导完成操作,无缺失。 | | -| F.1.2 | 脉络清楚:文档逻辑清晰、合理。文档前面的概述、准备、操作围绕一条线描述,不能章节断裂或前后矛盾的现象。 | | -| F.1.3 | 任务句式:标题或句子尽量使用“动词+名词”的句式表述动作。 | | -| F.1.4 | 预防提前:操作过程中的限制、易错的、有潜在风险的,要提前描述,使用DOCS平台的“插入> 说明 > 须知”描述。 | | -| F.1.5 | 步骤清晰-1:无论步骤简单或复杂,都需要写步骤目的,即为什么做。 | | -| F.1.6 | 步骤清晰-2:明确在什么环境下,使用什么工具,做什么操作,怎么做该操作。 | | -| F.1.7 | 步骤具体:如果操作可选,要明确可选条件。 | | -| F.1.8 | 在开发步骤执行完成后,及时明确操作正确的标准。 | | -| **F.2** | **如何写好代码段** | | -| F.2.1 | 代码涉及开发者拷贝的命令,必须用可编辑的报文呈现,避免截图(DOCS插入Screen)。 | | -| F.2.2 | 代码中关键段用蓝色(RGB:0.0.255)突出显示,关键步骤要有注释说明。 | | -| F.2.3 | 代码显示符合代码缩进要求。 | | -| F.2.4 | 步骤涉及接口调用,清晰给出接口及其使用说明或示例代码,代码来源于具体实例。 | | - -**【写作样例】** - -1. 双击下载的exe文件,进入DevEco Studio安装向导。 - -2. 配置DevEco Studio安装路径,点击Next。 - -3. 配置DevEco Studio安装选项,点击Next。 - - Create Desktop Shortcut:配置是否创建桌面快捷方式,根据操作系统位数进行选择。 - - Update PATH variable:配置是否将启动器路径添加到环境变量PATH中,需要从命令行启动DevEco Studio时,需要勾选Add launchers dir to the PATH。 - - Update context menu:配置是否将DevEco Studio功能添加至上下文菜单。勾选后,右键上下文菜单将出现“Open Folder as Project”选项。 - -4. 配置桌面快捷方式的开始菜单文件夹,点击Install。 - -5. 等待DevEco Studio安装完成后,点击Finish。 - - -## 检验环境是否搭建成功 - -** *【写作要求】*** - -*必选。* *环境搭建完成后,需要明确给出环境搭建是否成功的检验标准*。 - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| G.1.1 | 仅进行最后的结果验证,每个小任务的操作结果,在开发步骤执行完成后,及时验证操作结果。 | | -| G1.2 | 明确搭建成功的标准。 | | diff --git "a/zh-cn/device-dev/kernel-contribution/template/\346\246\202\350\277\260.md" "b/zh-cn/device-dev/kernel-contribution/template/\346\246\202\350\277\260.md" deleted file mode 100644 index c3ab6dfa23f8ee7ea737e10d460553c498632a77..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel-contribution/template/\346\246\202\350\277\260.md" +++ /dev/null @@ -1,169 +0,0 @@ -# 概述 - -* **【开发指南总体** **写作要求】*** - - -* 适用于鸿蒙南北向子系统开发、应用侧的设备开发、南向开发指南。* - - -* 章节调整:本模板知识点内容结构可以根据产品内容多少微调,具体操作方式见下。* - - -| 章节 | 可选/必选说明 | 备注 | -| -------- | -------- | -------- | -| 概述 | 必选,标题名称不变 | - | -| 搭建环境 | 可选,如果快速入门已有,可不用提供,否则需提供。 | - | -| 开发指导 | 必选,可根据多场景任务增加章节。 | 拍照开发指导
预览开发指导
录像开发指导 | -| 开发实例 | 必选。
- 标题名称可自定义。如果“开发指导”是多场景,标题名称可以调整为拍照开发实例、预览开发实例等。
- 标题可合并。如果产品链接到示例代码或内容少于1屏,可合并到“开发指导”,整本统一。 | - | -| 常见问题 | 可选,标题不变。
- 如果无常见问题,删除此章节。
- 如果有常见问题,建议单独章节,后续具备扩展性。
- 如果有常见问题,问题少于1屏,未来扩充可能行不大,可放在“开发指导”。 | - | -| 参考 | 可选,根据实际需要补充。 | - | - - - * 整体写作要求见下,完成写作后,请逐项自检。* -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| **A.1** | **用语要求** | | -| A.1.1 | 行文风格:文档在官方网站发布,用语正式,避免口语化。 | | -| A.1.2 | 合规要求:不能使用Android特有概念等存在合规和法务风险的词汇。敏感词汇包含但不限于:Android、Google、EMUI、Activity、AOSP、provider、binder、APK、Dalvik、AVD、ADT、DDMS、adb、AAPT、AndroidManifest、NDK、ART、dex、ANR、Cursor、Blacklist、Whitelist、Master、Slave、L0、L1、轻鸿蒙、富鸿蒙等。 | | -| A.1.3 | 内容简洁:内容采用信息必备、最小化原则,旨在指导开发者在尽量短的时间完成操作。 | | -| A.1.4 | 内容正确:文档的代码、需要设置的参数等需要跟产品实际情况实时保持一致。 | | -| A.1.5 | 用语准确:应当确切,不能出现多义性的描述。 | | -| A.1.6 | 用语一致:同一叫法,全文保持一致,术语与术语库保持一致,正文中缩略语首次出现要给出全称。 | | -| A.1.7 | 用语具体:如表示数量或程度时,避免用笼统的“多”“少”“大”,建议用具体数字表示。 | | -| **A.2** | **格式要求** | | -| A.2.1 | 标点符号正确、句尾有符号结尾。 | | -| A.2.2 | 内容尽量用项目列表或分类的方式清晰呈现。不要有单个项目列表;不要有多余空行。 | | -| A.2.3 | 英文字母和中文字之间不要有空格。 | | -| A.2.4 | 链接必须有效,具体,可直接跳转或下载。 | | -| A.2.5 | 如果是内容的辅助说明,请使用“说明”式样;如果提前申明事项,,请使用“须知”式样。To D的资料不用“注意”格式。 | | -| **A.3** | **表格** | | -| A.3.1 | 表格有表注,表头风格一致,采用名词或名词词组形式。 | | -| A.3.2 | 表格有表头,至少为2行2列,避免出现单行或单列表。 | | -| A.3.3 | 表格无内容用“_”,不出现空白的单元格。 | | -| **A.4** | **图形** | | -| A.4.2 | 符合华为调性,避免互联网化,避免涉及宗教信仰类截图。 | | -| A.4.3 | 图文并茂,行文应力求简明,如有可能,配以适当的图,表。 | | -| A.4.4 | 图形有图注(不可直接粘贴图形),图注风格一致,采用名词或名词词组形式。 | | -| A.4.5 | 图形应清晰可辩识,信息表达完整,易于阅读。如流程图不可缺少“开始”和“结束”。 | | -| A.4.6 | 图形逻辑清晰,图文配合使用,切忌图文分离。 | | -| A.4.7 | 图片的高度建议在640px左右,宽度不超过820px,一般为.png格式,图片的大小建议不超过150k。 | | -| A.4.8 | 图形建议尽量不要用文字,中文图用中文,英文图用英文。 | | - - -## 基本概念 - -*【 **写作要求】*** - -*必选,描述本开发任务相关的基本概念,帮助开发者更好的理解开发任务。* *写作要求见下,完成写作后,请逐项自检。* - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| B.1.1 | 业界通用的概念不用再此赘述。 | | -| B.1.2 | 注意使用业界通用术语来表达,不用华为研发内部语言。 | | -| B.1.3 | 基本概念要黑盒描述,不用体现具体细节。 | | - - -【写作样例】 - - -鸿蒙系统音频模块支持音频业务的开发,提供音频相关的功能,主要包括音频播放、音频采集、音量管理和短音播放等。 - - -在进行应用的开发前,开发者应了解以下基本概念: - - -- 采样 - 采样就是把模拟信号数字化的过程,所有的模拟信号都需要通过采样转换为可以用0101来表示的数字信号。 - -- 采样率 - 采样率为每秒从连续信号中提取并组成离散信号的采样次数,单位用赫兹(Hz)来表示。通常人耳能听到频率范围大约在20Hz~20kHz之间的声音。常用的音频采样频率有:8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz、96kHz、192kHz等。 - -- 声道 - 声道是指声音在录制或播放时在不同空间位置采集或回放的相互独立的音频信号,所以声道数也就是声音录制时的音源数量或回放时相应的扬声器数量。 - -- 音频帧 - 音频数据是流式的,本身没有明确的一帧帧的概念,在实际的应用中,为了音频算法处理/传输的方便,一般约定俗成取2.5ms~60ms为单位的数据量为一帧音频。这个时间被称之为“采样时间”,其长度没有特别的标准,它是根据编解码器和具体应用的需求来决定的。 - - -## 运作机制 - -*【 **写作要求】*** - -*可选。如果机制比较简单,通过前面基本概念就可以说清楚,此章节可以不用提供,删除标题即可。* - -*描述实现原理介绍机制,如关键步骤相关接口调用时机和触发时机,帮助开发者了解该功能的基本运作原理,以便更好的理解开发任务和定位问题。* - -* 写作要求见下,完成写作后,请逐项自检。* - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| C.1.1 | 仅描述开发任务相关的原理。 | | -| C.1.2 | 尽量图文配合,一般使用时序图、流程图等形式。文字描述与图形描述匹配。 | | -| C.1.3 | 原理要黑盒描述,注意不要泄密。 | | - -【写作样例-1】 - -- 信号量初始化,为配置的N个信号量申请内存(N值可以由用户自行配置,受内存限制),并把所有的信号量初始化成未使用,并加入到未使用链表中供系统使用。 - -- 信号量创建,从未使用的信号量链表中获取一个信号量资源,并设定初值。 - -- 信号量申请,若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其它任务释放该信号量,等待的超时时间可设定。当任务被一个信号量阻塞时,将该任务挂到信号量等待任务队列的队尾。 - -- 信号量释放,若没有任务等待该信号量,则直接将计数器加1返回。否则唤醒该信号量等待任务队列上的第一个任务。 - -- 信号量删除,将正在使用的信号量置为未使用信号量,并挂回到未使用链表。 - -- 信号量允许多个任务在同一时刻访问同一资源,但会限制同一时刻访问此资源的最大任务数目。访问同一资源的任务数达到该资源的最大数量时,会阻塞其他试图获取该资源的任务,直到有任务释放该信号量。 - ![1624266502700](C:\Users\LWX104~1\AppData\Local\Temp\1624266502700.png) - - 【写作样例-2】 - - **互斥锁运作原理** - - 多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢? - - 用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。 - - **图2** 互斥锁运作示意图 - ![1624266485662](C:\Users\LWX104~1\AppData\Local\Temp\1624266485662.png) - - -## 约束与限制 - -* **【写作要求】*** - -*必选。* *描述本开发任务过程中* *的约束条件,以及此操作约束带来相应的负面影响,包括但不限于如下几方面:* - -* **功能限制:*** - -- * 功能使用范围(明确不支持的场景)。* - -- *规格限制。* - -* **操作限制** **:*** - -- * 已知问题的操作。* - -- * 潜在风险的操作(如引起性能降低)。* - -- * 引起性能降低的操作*。 - -* 写作要求见下,完成写作后,请逐项自检。* - -| 要求项 | 内容要求 | 是否满足 | -| -------- | -------- | -------- | -| D.1.1 | 明确功能限制或操作限制。 | | -| D.1.2 | 约束对指导任务开发有影响或体验有感知,否则不用体现。 | | -| D.1.3 | 容易出错的操作在步骤里描述,不在此体现。 | | - -**【写作样例】** - -**互斥锁的约束与限制:** - -- 两个任务不能对同一把互斥锁加锁。如果某任务对已被持有的互斥锁加锁,则该任务会被挂起,直到持有该锁的任务对互斥锁解锁,才能执行对这把互斥锁的加锁操作。 - -- 互斥锁不能在中断服务程序中使用。 - -- Huawei LiteOS作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。 - -- 持有互斥锁的过程中,不得再调用LOS_TaskPriSet等接口更改持有互斥锁任务的优先级。 diff --git "a/zh-cn/device-dev/kernel/C++\346\224\257\346\214\201.md" "b/zh-cn/device-dev/kernel/C++\346\224\257\346\214\201.md" deleted file mode 100644 index 86080372577209de5d8bdb01955b3e6834525b1c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/C++\346\224\257\346\214\201.md" +++ /dev/null @@ -1,86 +0,0 @@ -# C++支持 - -- [基本概念](#section11374125415814) - - [运行机制](#section125251720195) - -- [开发指导](#section166302407911) - - [接口说明](#section1881825119919) - - [开发流程](#section76371145108) - - [编程实例](#section994427141111) - - -## 基本概念 - -C++作为目前使用最广泛的编程语言之一,支持类、封装、重载等特性,是在C语言基础上开发的一种面向对象的编程语言。 - -### 运行机制 - -C++代码的识别主要由编译器支持,系统主要对全局对象进行构造函数调用,进行初始化操作。 - -## 开发指导 - -### 接口说明 - -**表 1** C++支持接口 - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

使用C++特性的前置条件

-

LOS_CppSystemInit

-

C++构造函数初始化

-
- -### 开发流程 - -使用C++特性之前,需要调用函数LOS\_CppSystemInit,实现C++构造函数初始化,其中被初始化的构造函数存在init\_array这个段中,段区间通过变量\_\_init\_array\_start\_\_、\_\_init\_array\_end\_\_传递。 - -**表 2** 参数说明 - - - - - - - - - - - - - -

参数

-

参数说明

-

__init_array_start__

-

init_array段起始位置

-

__init_array_end__

-

init_array段结束位置

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->调用该函数时,一定要在c++业务前。另外部分与系统资源强相关的类或接口,如std::thread,std::mutex等,在三方编译器使用的c库非musl c时,存在兼容性问题,不建议使用。 - -### 编程实例 - -``` -void app_init(void) -{ -...... -/* 启动阶段C++初始化 */ -LOS_CppSystemInit((UINTPTR)&__init_array_start__, (UINTPTR)&__init_array_end__); -/* C++业务 */ -...... -} -``` - diff --git "a/zh-cn/device-dev/kernel/CMSIS\346\224\257\346\214\201.md" "b/zh-cn/device-dev/kernel/CMSIS\346\224\257\346\214\201.md" deleted file mode 100644 index 4f64bc6b8ca9b68a2f5b19dd23c7548555cb71b6..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/CMSIS\346\224\257\346\214\201.md" +++ /dev/null @@ -1,487 +0,0 @@ -# CMSIS支持 - -- [基本概念](#section131091144111615) -- [开发指导](#section57653573161) - - [接口说明](#section1795910417173) - - [开发流程](#section48301225131720) - - [编程实例](#section524434761713) - - -## 基本概念 - -[CMSIS](https://developer.arm.com/tools-and-software/embedded/cmsis)是Cortex Microcontroller Software Interface Standard(Cortex微控制器软件接口标准)的缩写,是对于那些基于ARM Cortex处理器的微控制器独立于供应商的硬件抽象层。它包含多个组件层,其中之一是RTOS层,该层定义了一套通用及标准化的RTOS API接口,减少了应用开发者对特定RTOS的依赖,方便用户软件的移植重用。该套API有2个版本,分别为版本1(CMSIS-RTOS v1)和版本2(CMSIS-RTOS v2),OpenHarmony LiteOS-M仅提供其版本2的实现。 - -## 开发指导 - -### 接口说明 - -CMSIS-RTOS v2提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** CMSIS-RTOS v2接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

内核信息与控制

-

osKernelGetInfo

-

获取RTOS内核信息。

-

osKernelGetState

-

获取当前的RTOS内核状态。

-

osKernelGetSysTimerCount

-

获取RTOS内核系统计时器计数。

-

osKernelGetSysTimerFreq

-

获取RTOS内核系统计时器频率。

-

osKernelInitialize

-

初始化RTOS内核。

-

osKernelLock

-

锁定RTOS内核调度程序。

-

osKernelUnlock

-

解锁RTOS内核调度程序。

-

osKernelRestoreLock

-

恢复RTOS内核调度程序锁定状态。

-

osKernelResume

-

恢复RTOS内核调度程序。(暂未实现)

-

osKernelStart

-

启动RTOS内核调度程序。

-

osKernelSuspend

-

挂起RTOS内核调度程序。(暂未实现)

-

osKernelGetTickCount

-

获取RTOS内核滴答计数。

-

osKernelGetTickFreq

-

获取RTOS内核滴答频率。

-

线程管理

-

osThreadDetach

-

分离线程(线程终止时可以回收线程存储)。(暂未实现)

-

osThreadEnumerate

-

枚举活动线程。(暂未实现)

-

osThreadExit

-

终止当前正在运行的线程的执行。

-

osThreadGetCount

-

获取活动线程的数量。

-

osThreadGetId

-

返回当前正在运行的线程的线程ID。

-

osThreadGetName

-

获取线程的名称。

-

osThreadGetPriority

-

获取线程的当前优先级。

-

osThreadGetStackSize

-

获取线程的堆栈大小。

-

osThreadGetStackSpace

-

根据执行期间的堆栈水印记录获取线程的可用堆栈空间。

-

osThreadGetState

-

获取线程的当前线程状态。

-

osThreadJoin

-

等待指定线程终止。(暂未实现)

-

osThreadNew

-

创建一个线程并将其添加到活动线程中。

-

osThreadResume

-

恢复线程的执行。

-

osThreadSetPriority

-

更改线程的优先级。

-

osThreadSuspend

-

暂停执行线程。

-

osThreadTerminate

-

终止线程的执行。

-

osThreadYield

-

将控制权传递给处于就绪状态的下一个线程。

-

线程标志

-

osThreadFlagsSet

-

设置线程的指定线程标志。(暂未实现)

-

osThreadFlagsClear

-

清除当前正在运行的线程的指定线程标志。(暂未实现)

-

osThreadFlagsGet

-

获取当前正在运行的线程的当前线程标志。(暂未实现)

-

osThreadFlagsWait

-

等待当前正在运行的线程的一个或多个线程标志发出信号。(暂未实现)

-

事件标志

-

osEventFlagsGetName

-

获取事件标志对象的名称。(暂未实现)

-

osEventFlagsNew

-

创建并初始化事件标志对象。

-

osEventFlagsDelete

-

删除事件标志对象。

-

osEventFlagsSet

-

设置指定的事件标志。

-

osEventFlagsClear

-

清除指定的事件标志。

-

osEventFlagsGet

-

获取当前事件标志。

-

osEventFlagsWait

-

等待一个或多个事件标志被发出信号。

-

通用等待函数

-

osDelay

-

等待超时(时间延迟)。

-

osDelayUntil

-

等到指定时间。

-

计时器管理

-

osTimerDelete

-

删除计时器。

-

osTimerGetName

-

获取计时器的名称。(暂未实现)

-

osTimerIsRunning

-

检查计时器是否正在运行。

-

osTimerNew

-

创建和初始化计时器。

-

osTimerStart

-

启动或重新启动计时器。

-

osTimerStop

-

停止计时器。

-

互斥管理

-

osMutexAcquire

-

获取互斥或超时(如果已锁定)。

-

osMutexDelete

-

删除互斥对象。

-

osMutexGetName

-

获取互斥对象的名称。(暂未实现)

-

osMutexGetOwner

-

获取拥有互斥对象的线程。

-

osMutexNew

-

创建并初始化Mutex对象。

-

osMutexRelease

-

释放由osMutexAcquire获取的Mutex。

-

信号量

-

osSemaphoreAcquire

-

获取信号量令牌或超时(如果没有可用的令牌)。

-

osSemaphoreDelete

-

删除一个信号量对象。

-

osSemaphoreGetCount

-

获取当前信号量令牌计数。

-

osSemaphoreGetName

-

获取信号量对象的名称。(暂未实现)

-

osSemaphoreNew

-

创建并初始化一个信号量对象。

-

osSemaphoreRelease

-

释放信号量令牌,直到初始最大计数。

-

内存池

-

osMemoryPoolAlloc

-

从内存池分配一个内存块。

-

osMemoryPoolDelete

-

删除内存池对象。

-

osMemoryPoolFree

-

将分配的内存块返回到内存池。

-

osMemoryPoolGetBlockSize

-

获取内存池中的内存块大小。

-

osMemoryPoolGetCapacity

-

获取内存池中最大的内存块数。

-

osMemoryPoolGetCount

-

获取内存池中使用的内存块数。

-

osMemoryPoolGetName

-

获取内存池对象的名称。

-

osMemoryPoolGetSpace

-

获取内存池中可用的内存块数。

-

osMemoryPoolNew

-

创建并初始化一个内存池对象。

-

消息队列

-

osMessageQueueDelete

-

删除消息队列对象。

-

osMessageQueueGet

-

从队列获取消息,或者如果队列为空,则从超时获取消息。

-

osMessageQueueGetCapacity

-

获取消息队列中的最大消息数。

-

osMessageQueueGetCount

-

获取消息队列中排队的消息数。

-

osMessageQueueGetMsgSize

-

获取内存池中的最大消息大小。

-

osMessageQueueGetName

-

获取消息队列对象的名称。(暂未实现)

-

osMessageQueueGetSpace

-

获取消息队列中消息的可用插槽数。

-

osMessageQueueNew

-

创建和初始化消息队列对象。

-

osMessageQueuePut

-

如果队列已满,则将消息放入队列或超时。

-

osMessageQueueReset

-

将消息队列重置为初始空状态。(暂未实现)

-
- -### 开发流程 - -CMSIS-RTOS2组件可以作为库或源代码提供(下图显示了库)。通过添加CMSIS-RTOS2组件(通常是一些配置文件),可以将基于CMSIS的应用程序扩展为具有RTOS功能。只需包含cmsis\_os2.h头文件就可以访问RTOS API函数,这使用户应用程序能够处理RTOS内核相关事件,而在更换内核时无需重新编译源代码。 - -静态对象分配需要访问RTOS对象控制块定义。特定于实现的头文件(下图中的os\_xx .h)提供对此类控制块定义的访问。对于OpenHarmony LiteOS-M内核,由文件名以los\_开头的头文件提供,这些文件包含OpenHarmony LiteOS-M内核的这些定义。 - -![](figures/zh-cn_image_0000001121429646.png) - -### 编程实例 - -``` -#include ... -#include "cmsis_os2.h" - -/*---------------------------------------------------------------------------- - * 应用程序主线程 - *---------------------------------------------------------------------------*/ -void app_main (void *argument) { - // ... - for (;;) {} -} - -int main (void) { - // 系统初始化 - MySystemInit(); - // ... - - osKernelInitialize(); // 初始化CMSIS-RTOS - osThreadNew(app_main, NULL, NULL); // 创建应用程序主线程 - osKernelStart(); // 开始执行线程 - for (;;) {} -} -``` - diff --git a/zh-cn/device-dev/kernel/FAT-20.md b/zh-cn/device-dev/kernel/FAT-20.md deleted file mode 100644 index 7b8620cb01f87d0e84a8f72b5b253536ac440ed9..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/FAT-20.md +++ /dev/null @@ -1,176 +0,0 @@ -# FAT - -- [基本概念](#section1772629121418) -- [开发指导](#section1149072811148) - - [驱动适配](#section19174939191414) - - [开发流程](#section131211626151513) - - [编程实例](#section206071303163) - - [实例描述](#section45337345313) - - [示例代码](#section119813171539) - - [结果验证](#section7987101232311) - - -## 基本概念 - -FAT文件系统是File Allocation Table(文件配置表)的简称,主要包括DBR区、FAT区、DATA区三个区域。其中,FAT区各个表项记录存储设备中对应簇的信息,包括簇是否被使用、文件下一个簇的编号、是否文件结尾等。FAT文件系统有FAT12、FAT16、FAT32等多种格式,其中,12、16、32表示对应格式中FAT表项的字节数。FAT文件系统支持多种介质,特别在可移动存储介质(U盘、SD卡、移动硬盘等)上广泛使用,使嵌入式设备和Windows、Linux等桌面系统保持很好的兼容性,方便用户管理操作文件。 - -OpenHarmony内核支持FAT12、FAT16与FAT32三种格式的FAT文件系统,具有代码量小、资源占用小、可裁切、支持多种物理介质等特性,并且与Windows、Linux等系统保持兼容,支持多设备、多分区识别等功能。OpenHarmony内核支持硬盘多分区,可以在主分区以及逻辑分区上创建FAT文件系统。 - -## 开发指导 - -### 驱动适配 - -FAT文件系统的使用需要底层MMC相关驱动的支持。在一个带MMC存储设备的板子上运行FATFS,需要: - -1、适配板端EMMC驱动,实现disk\_status、disk\_initialize、disk\_read、disk\_write、disk\_ioctl接口; - -2、新增fs\_config.h文件,配置FS\_MAX\_SS(存储设备最大sector大小)、FF\_VOLUME\_STRS(分区名)等信息,例如: - -``` -#define FF_VOLUME_STRS "system", "inner", "update", "user" -#define FS_MAX_SS 512 -#define FAT_MAX_OPEN_FILES 50 -``` - -### 开发流程 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- FATFS文件与目录操作: -> - 单个文件大小不超过4G。 -> - 支持同时打开的文件数最大为FAT\_MAX\_OPEN\_FILES,文件夹数最大为FAT\_MAX\_OPEN\_DIRS。 -> - 暂不支持根目录管理,文件/目录名均以分区名开头,例如“user/testfile”就是在“user”分区下名为“testfile”的文件或目录。 -> - 若需要同时多次打开同一文件,必须全部使用只读方式(O\_RDONLY)。以可写方式(O\_RDWR、O\_WRONLY等)只能打开一次。 -> - 读写指针未分离,例如以O\_APPEND(追加写)方式打开文件后,读指针也在文件尾,从头读文件前需要用户手动置位。 -> - 暂不支持文件与目录的权限管理。 -> - stat及fstat接口暂不支持查询修改时间、创建时间和最后访问时间。微软FAT协议不支持1980年以前的时间。 ->- FATFS分区挂载与卸载: -> - 支持以只读属性挂载分区。当mount函数的入参为MS\_RDONLY时,所有的带有写入的接口,如write、mkdir、unlink,以及非O\_RDONLY属性的open,将均被拒绝。 -> - mount支持通过MS\_REMOUNT标记修改已挂载分区的权限。 -> - 在umount操作前,需确保所有目录及文件全部关闭。 -> - umount2支持通过MNT\_FORCE参数强制关闭所有文件与文件夹并umount,但可能造成数据丢失,请谨慎使用。 ->- FATFS支持重新划分存储设备分区、格式化分区,对应接口为fatfs\_fdisk与fatfs\_format: -> - 在fatfs\_format操作之前,若需要格式化的分区已挂载,需确保分区中的所有目录及文件全部关闭,并且分区umount。 -> - 在fatfs\_fdisk操作前,需要该设备中的所有分区均已umount。 -> - fatfs\_fdisk与fatfs\_format会造成设备数据丢失,请谨慎使用。 - -### 编程实例 - -### 实例描述 - -本实例实现以下功能: - -1. 创建目录“user/test” -2. 在“user/test”目录下创建文件“file.txt” -3. 在文件起始位置写入“Hello OpenHarmony!” -4. 将文件内容刷入设备中 -5. 设置偏移到文件起始位置 -6. 读取文件内容 -7. 关闭文件 -8. 删除文件 -9. 删除目录 - -### 示例代码 - -前提条件: - -- 系统已将MMC设备分区挂载到user目录 - -代码实现如下: - -``` -#include -#include -#include "sys/stat.h" -#include "fcntl.h" -#include "unistd.h" - -#define LOS_OK 0 -#define LOS_NOK -1 - -int FatfsTest(void) -{ - int ret; - int fd = -1; - ssize_t len; - off_t off; - char dirName[20] = "user/test"; - char fileName[20] = "user/test/file.txt"; - char writeBuf[20] = "Hello OpenHarmony!"; - char readBuf[20] = {0}; - - /* 创建目录“user/test” */ - ret = mkdir(dirName, 0777); - if (ret != LOS_OK) { - printf("mkdir failed.\n"); - return LOS_NOK; - } - - /* 创建可读写文件"user/test/file.txt" */ - fd = open(fileName, O_RDWR | O_CREAT, 0777); - if (fd < 0) { - printf("open file failed.\n"); - return LOS_NOK; - } - - /* 将writeBuf中的内容写入文件 */ - len = write(fd, writeBuf, strlen(writeBuf)); - if (len != strlen(writeBuf)) { - printf("write file failed.\n"); - return LOS_NOK; - } - - /* 将文件内容刷入存储设备中 */ - ret = fsync(fd); - if (ret != LOS_OK) { - printf("fsync failed.\n"); - return LOS_NOK; - } - - /* 将读写指针偏移至文件头 */ - off = lseek(fd, 0, SEEK_SET); - if (off != 0) { - printf("lseek failed.\n"); - return LOS_NOK; - } - - /* 将文件内容读出至readBuf中,读取长度为readBuf大小 */ - len = read(fd, readBuf, sizeof(readBuf)); - if (len != strlen(writeBuf)) { - printf("read file failed.\n"); - return LOS_NOK; - } - printf("%s\n", readBuf); - - /* 关闭文件 */ - ret = close(fd); - if (ret != LOS_OK) { - printf("close failed.\n"); - return LOS_NOK; - } - - /* 删除文件"user/test/file.txt" */ - ret = unlink(fileName); - if (ret != LOS_OK) { - printf("unlink failed.\n"); - return LOS_NOK; - } - - /* 删除目录“user/test” */ - ret = rmdir(dirName); - if (ret != LOS_OK) { - printf("rmdir failed.\n"); - return LOS_NOK; - } - - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -Hello OpenHarmony! -``` - diff --git a/zh-cn/device-dev/kernel/IPC.md b/zh-cn/device-dev/kernel/IPC.md deleted file mode 100644 index 14c3d35d893aa9d29c15274d40231c9393ee0fa0..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/IPC.md +++ /dev/null @@ -1,11 +0,0 @@ -# IPC - -- **[事件](事件.md)** - -- **[互斥锁](互斥锁.md)** - -- **[消息队列](消息队列.md)** - -- **[信号量](信号量.md)** - - diff --git "a/zh-cn/device-dev/kernel/Linux\345\206\205\346\240\270\347\274\226\350\257\221\344\270\216\346\236\204\345\273\272\346\214\207\345\257\274.md" "b/zh-cn/device-dev/kernel/Linux\345\206\205\346\240\270\347\274\226\350\257\221\344\270\216\346\236\204\345\273\272\346\214\207\345\257\274.md" deleted file mode 100755 index 1dec4cb1447cc02fce0739300e12aeef80e135c7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/Linux\345\206\205\346\240\270\347\274\226\350\257\221\344\270\216\346\236\204\345\273\272\346\214\207\345\257\274.md" +++ /dev/null @@ -1,47 +0,0 @@ -# Linux内核编译与构建指导 - -- [开发示例1](#section19369206113115) - - [场景1:版本级编译原生方式](#section1025111193220) - - [场景2:单独编译修改后的内核](#section17446652173211) - - -## 开发示例1 - -以hi3516dv300开源开发板+ubuntu x86主机开发环境为例。 - -### 场景1:版本级编译原生方式 - -使用工程的全量编译命令,编译生成uImage内核镜像 - -``` -./build.sh --product-name Hi3516DV300 # 编译hi3516dv300的uImage内核镜像 -``` - -### 场景2:单独编译修改后的内核 - -1. 准备工作 - - 1. 按[开发板Patch使用指导](OpenHarmony开发板Patch使用指导.md)打入所需补丁。 - 2. 准备编译环境,可以使用开源arm clang/gcc编译器。 - - 进入工程主目录配置环境变量: - - ``` - export PATH=`pwd`/prebuilts/clang/host/linux-x86/clang-r353983c/bin:`pwd`/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/:$PATH # 配置编译环境 - MAKE_OPTIONES="ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CC=clang HOSTCC=clang" # 使用工程项目自带的clang环境 - ``` - -2. 修改内核代码或内核config (OpenHarmony提供对应平台的defconfig供参考)。 -3. 创建编译目录及生成内核.config。 - - ``` - make ${MAKE_OPTIONES} hi3516dv300_emmc_smp_hos_l2_defconfig # 使用自带的默认config 构建内核 - ``` - -4. 编译生成对应的内核Image。 - - ``` - make ${MAKE_OPTIONES} -j32 uImage # 编译uImage内核镜像 - ``` - - diff --git a/zh-cn/device-dev/kernel/LittleFS.md b/zh-cn/device-dev/kernel/LittleFS.md deleted file mode 100644 index 1f8ad2cec85fe0c0b5c45076a705e5f12045fa8c..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/LittleFS.md +++ /dev/null @@ -1,7 +0,0 @@ -# LittleFS - -- **[基本概念](基本概念-21.md)** - -- **[开发指导](开发指导-22.md)** - - diff --git a/zh-cn/device-dev/kernel/NFS.md b/zh-cn/device-dev/kernel/NFS.md deleted file mode 100755 index d319329c44d3c54e4597a68ce64465886143c7b2..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/NFS.md +++ /dev/null @@ -1,163 +0,0 @@ -# NFS - -- [概述](#section18322139164413) -- [注意事项](#section532912331467) -- [开发指导](#section166873374711) - -## 概述 - -NFS是Network File System(网络文件系统)的缩写。它最大的功能是可以通过网络,让不同的机器、不同的操作系统彼此分享其他用户的文件。因此,用户可以简单地将它看做是一个文件系统服务,在一定程度上相当于Windows环境下的共享文件夹。 - -NFS客户端用户,能够将网络远程的NFS服务端分享的目录挂载到本地端的机器中,运行程序和共享文件,但不占用当前的系统资源,所以,在本地端的机器看起来,远程服务端的目录就好像是自己的一个磁盘一样。 - -## 注意事项 - -- 当前NFS文件不支持权限控制,请在创建NFS目录和文件时使用777权限。 - -- 当前NFS文件不支读阻塞和写阻塞。 - -- 当前NFS文件不支持信号功能。 - -- 当前NFS文件系统mount路径长度(不包含IP的长度)不超过255个字符,超过时返回ENAMETOOLONG错误。 - -- 当前NFS文件支持的操作有:open, close, read, write, seek, dup, dup2, sync, opendir, closedir, readdir, readdir\_r, rewinddir, scandir, statfs, remove, unlink, mkdir, rmdir, rename, stat, stat64, seek64, mmap, mount, umount。 - -- 当前NFS支持TCP和UDP两种传输层协议,默认使用TCP。 - -- open打开一个文件,参数有O\_TRUNC时,必须同时拥有写的权限,才会将文件中的内容清空。 - -- 在文件未关闭的情况下,rename\(\)函数重命名A为B之后,不会改变文件fd。 - -- NFS功能目前处于beta测试阶段,可能存在功能不稳定的情况,建议您不要用于正式商用产品当中。 - - -## 开发指导 - -1. **搭建NFS服务器**。 - - 这里以Ubuntu操作系统为例,说明服务器端设置步骤。 - - 1. 安装NFS服务器软件。 - - 设置好Ubuntu系统的下载源,保证网络连接好的情况下执行: - - ``` - sudo apt-get install nfs-kernel-server - ``` - - 2. 创建用于挂载的目录并设置完全权限 - - ``` - mkdir /home/sqbin/nfs - sudo chmod 777 /home/sqbin/nfs - ``` - - 3. 设置和启动NFS server。 - - 修改NFS配置文件/etc/exports,添加如下一行: - - ``` - /home/sqbin/nfs *(rw,no_root_squash,async) - ``` - - 其中/home/sqbin/nfs是NFS共享的根目录。 - - 执行以下命令启动NFS server: - - ``` - sudo /etc/init.d/nfs-kernel-server start - ``` - - 执行以下命令重启NFS server: - - ``` - sudo /etc/init.d/nfs-kernel-server restart - ``` - - -2. **设置单板为NFS客户端**。 - - 本指导中的NFS客户端指运行OpenHarmony内核的设备。 - - 1. 硬件连接设置。 - - OpenHarmony内核设备连接到NFS服务器的网络。设置两者IP,使其处于同一网段。比如,设置NFS服务器的IP为10.67.212.178/24,设置OpenHarmony内核设备IP为10.67.212.3/24,注意:此IP为内网私有IP地址,用户使用时有差异,以用户实际IP为准。 - - OpenHarmony内核设备上的IP信息可通过ifconfig命令查看。 - - 2. 启动网络,确保单板到NFS服务器之间的网络通畅。 - - 启动以太网或者其他类型网络,使用ping命令检查到服务器的网络是否通畅。 - - ``` - OHOS # ping 10.67.212.178 - [0]Reply from 10.67.212.178: time=1ms TTL=63 - [1]Reply from 10.67.212.178: time=0ms TTL=63 - [2]Reply from 10.67.212.178: time=1ms TTL=63 - [3]Reply from 10.67.212.178: time=1ms TTL=63 - --- 10.67.212.178 ping statistics --- - 4 packets transmitted, 4 received, 0 loss - ``` - - 客户端NFS初始化,运行命令: - - ``` - OHOS # mkdir /nfs - OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 - ``` - - 将从串口得到如下回应信息,表明初始化NFS客户端成功。 - - ``` - OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 - Mount nfs on 10.67.212.178:/home/sqbin/nfs, uid:1011, gid:1000 - Mount nfs finished. - ``` - - 该命令将服务器10.67.212.178上的/home/sqbin/nfs目录mount在OpenHarmony内核设备上的/nfs上。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >本例默认nfs server已经配置可用,即示例中服务器10.67.212.178上的/home/sqbin/nfs已配置可访问。 - - mount命令的格式为: - - ``` - mount nfs - ``` - - 其中“SERVER\_IP“表示服务器的IP地址;“SERVER\_PATH“表示服务器端NFS共享目录路径;“CLIENT\_PATH“表示设备上的NFS路径。 - - 如果不想有NFS访问权限限制,请在Linux命令行将NFS根目录权限设置成777: - - ``` - chmod -R 777 /home/sqbin/nfs - ``` - - 至此,NFS客户端设置完毕。NFS文件系统已成功挂载。 - - -3. **利用NFS共享文件**。 - - 在NFS服务器下新建目录dir,并保存。在OpenHarmony内核下运行ls命令: - - ``` - OHOS # ls /nfs - ``` - - 则可从串口得到如下回应: - - ``` - OHOS # ls /nfs - Directory /nfs: - drwxr-xr-x 0 u:0 g:0 dir - ``` - - 可见,刚刚在NFS服务器上新建的dir目录已同步到客户端\(OpenHarmony内核系统\)的/nfs目录,两者保持同步。 - - 同样地,在客户端\(OpenHarmony内核系统\)上创建文件和目录,在NFS服务器上也可以访问,读者可自行体验。 - - **平台差异性:** - - 目前,NFS客户端仅支持NFS v3部分规范要求,因此对于规范支持不全的服务器,无法完全兼容。在开发测试过程中,建议使用Linux的NFS server,因为其对NFS支持很完善。 - - diff --git "a/zh-cn/device-dev/kernel/OpenHarmony\345\274\200\345\217\221\346\235\277Patch\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/kernel/OpenHarmony\345\274\200\345\217\221\346\235\277Patch\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 25eadc954a75a4ec4e0f5855b95e9d2e527d31a7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/OpenHarmony\345\274\200\345\217\221\346\235\277Patch\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,17 +0,0 @@ -# OpenHarmony开发板Patch使用指导 - -Patch文件位于工程项目源码路径:kernel/linux/patches/linux-4.19,存放特定芯片架构驱动补丁。 - -如需使用特定芯片平台驱动的Patch,需要在内核仓代码完成对芯片平台驱动补丁合入。 - -合入芯片平台驱动补丁,针对不同芯片平台合入对应的patch: - -以Hi3516dv300为例: - -``` -patch -p1 < device/hisilicon/hi3516dv300/sdk_linux/open_source/linux/hisi_linux-4.19_hos_l2.patch -``` - ->![](public_sys-resources/icon-notice.gif) **须知:** ->由于OpenHarmony的编译构建流程中会拷贝kernel/linux-4.19的代码环境后进行打补丁动作,在使用OpenHarmony的版本级编译命令前,需要kernel/linux-4.19保持原代码环境。 - diff --git a/zh-cn/device-dev/kernel/Readme-CN.md b/zh-cn/device-dev/kernel/Readme-CN.md index 8b5a59ad1b9f2ddb7beb2c0424b72dd5bc53d432..3149ba1128ab511901f59a3614f077695b183cf0 100755 --- a/zh-cn/device-dev/kernel/Readme-CN.md +++ b/zh-cn/device-dev/kernel/Readme-CN.md @@ -1,166 +1,152 @@ # 内核使用指南 -- [轻量和小型系统内核](轻量和小型系统内核.md) - - [轻量系统内核](轻量系统内核.md) - - [基础内核](基础内核.md) - - [进程](进程.md) - - [线程](线程.md) - - [内存](内存.md) - - [网络](网络.md) - - - [文件系统](文件系统.md) - - [VFS](VFS.md) - - [NFS](NFS.md) - - [RAMFS](RAMFS.md) - - [FAT](FAT.md) - - [JFFS2](JFFS2.md) - - - [标准库](标准库.md) - - [标准库](标准库-0.md) - - [与Linux标准库的差异](与Linux标准库的差异.md) - - - [调测](调测.md) - - [Shell介绍](Shell介绍.md) - - [Shell命令开发指导](Shell命令开发指导.md) - - [Shell命令编程实例](Shell命令编程实例.md) - - [Shell命令使用详解](Shell命令使用详解.md) - - [系统命令](系统命令.md) - - [cpup](cpup.md) - - [date](date.md) - - [dmesg](dmesg.md) - - [exec](exec.md) - - [free](free.md) - - [help](help.md) - - [hwi](hwi.md) - - [kill](kill.md) - - [log](log.md) - - [memcheck](memcheck.md) - - [oom](oom.md) - - [pmm](pmm.md) - - [reset](reset.md) - - [sem](sem.md) - - [stack](stack.md) - - [su](su.md) - - [swtmr](swtmr.md) - - [systeminfo](systeminfo.md) - - [task](task.md) - - [uname](uname.md) - - [vmm](vmm.md) - - [watch](watch.md) - - - [文件命令](文件命令.md) - - [cat](cat.md) - - [cd](cd.md) - - [chgrp](chgrp.md) - - [chmod](chmod.md) - - [chown](chown.md) - - [cp](cp.md) - - [format](format.md) - - [ls](ls.md) - - [lsfd](lsfd.md) - - [mkdir](mkdir.md) - - [mount](mount.md) - - [partinfo](partinfo.md) - - [partition](partition.md) - - [pwd](pwd.md) - - [rm](rm.md) - - [rmdir](rmdir.md) - - [statfs](statfs.md) - - [sync](sync.md) - - [touch](touch.md) - - [writeproc](writeproc.md) - - [umount](umount.md) - - - [网络命令](网络命令.md) - - [arp](arp.md) - - [dhclient](dhclient.md) - - [dns](dns.md) - - [ifconfig](ifconfig.md) - - [ipdebug](ipdebug.md) - - [netstat](netstat.md) - - [ntpdate](ntpdate.md) - - [ping](ping.md) - - [ping6](ping6.md) - - [telnet](telnet.md) - - [tftp](tftp.md) - - - [魔法键使用方法](魔法键使用方法.md) - - [用户态异常信息说明](用户态异常信息说明.md) - - - [小型系统内核](小型系统内核.md) - - [认识LiteOS-M内核](认识LiteOS-M内核.md) - - [快速入门](快速入门.md) - - [基础内核](基础内核-1.md) - - [中断管理](中断管理.md) - - [基本概念](基本概念.md) - - [开发指导](开发指导.md) - - - [任务管理](任务管理.md) - - [基本概念](基本概念-2.md) - - [开发指导](开发指导-3.md) - - - [内存管理](内存管理.md) - - [基本概念](基本概念-4.md) - - [静态内存](静态内存.md) - - [动态内存](动态内存.md) - - - [IPC](IPC.md) - - [事件](事件.md) - - [基本概念](基本概念-5.md) - - [开发指导](开发指导-6.md) - - - [互斥锁](互斥锁.md) - - [基本概念](基本概念-7.md) - - [开发指导](开发指导-8.md) - - - [消息队列](消息队列.md) - - [基本概念](基本概念-9.md) - - [开发指导](开发指导-10.md) - - - [信号量](信号量.md) - - [基本概念](基本概念-11.md) - - [开发指导](开发指导-12.md) - - - [时间管理](时间管理.md) - - [基本概念](基本概念-13.md) - - [开发指导](开发指导-14.md) - - - [软件定时器](软件定时器.md) - - [基本概念](基本概念-15.md) - - [开发指导](开发指导-16.md) - - - [扩展组件](扩展组件.md) - - [C++支持](C++支持.md) - - [CPUP](CPUP.md) - - [基本概念](基本概念-17.md) - - [开发指导](开发指导-18.md) - - - [文件系统](文件系统-19.md) - - [FAT](FAT-20.md) - - [LittleFS](LittleFS.md) - - [基本概念](基本概念-21.md) - - [开发指导](开发指导-22.md) - - - [内核调测](内核调测.md) - - [内存调测](内存调测.md) - - [内存信息统计](内存信息统计.md) - - [内存泄漏检测](内存泄漏检测.md) - - [踩内存检测](踩内存检测.md) - - - [异常调测](异常调测.md) - - [Trace调测](Trace调测.md) - - - [附录](附录.md) - - [内核编码规范](内核编码规范.md) - - [基本数据结构](基本数据结构.md) - - [双向链表](双向链表.md) - - - [标准库支持](标准库支持.md) - - [CMSIS支持](CMSIS支持.md) - - [POSIX支持](POSIX支持.md) - -- [标准系统内核](标准系统内核.md) - - [Linux内核概述](Linux内核概述.md) - - [OpenHarmony开发板Patch使用指导](OpenHarmony开发板Patch使用指导.md) - - [Linux内核编译与构建指导](Linux内核编译与构建指导.md) +- [轻量和小型系统内核](kernel-lite.md) + + - [轻量系统内核](kernel-lite-mini.md) + - [内核概述](kernel-lite-mini-m.md) + - [基础内核](kernel-lite-mini-basic.md) + - [中断管理](kernel-lite-mini-basic-interrupt.md) + - [基本概念](kernel-lite-mini-basic-interrupt-concept.md) + - [开发指导](kernel-lite-mini-basic-interrupt-guide.md) + - [任务管理](kernel-lite-mini-basic-task.md) + - [基本概念](kernel-lite-mini-basic-task-basic.md) + - [开发指导](kernel-lite-mini-basic-task-guide.md) + - [内存管理](kernel-lite-mini-basic-memory.md) + - [基本概念](kernel-lite-mini-basic-memory-basic.md) + - [静态内存](kernel-lite-mini-basic-memory-static.md) + - [动态内存](kernel-lite-mini-basic-memory-dynamic.md) + - [内核通信机制](kernel-lite-mini-basic-ipc.md) + - [事件](kernel-lite-mini-basic-ipc-event.md) + - [基本概念](kernel-lite-mini-basic-ipc-event-guide.md) + - [开发指导](kernel-lite-mini-basic-ipc-event-basic.md) + - [互斥锁](kernel-lite-mini-basic-ipc-mutex.md) + - [基本概念](kernel-lite-mini-basic-ipc-mutex-basic.md) + - [开发指导](kernel-lite-mini-basic-ipc-mutex-guide.md) + - [消息队列](kernel-lite-mini-basic-ipc-queue.md) + - [基本概念](kernel-lite-mini-basic-ipc-queue-basic.md) + - [开发指导](kernel-lite-mini-basic-ipc-queue-guide.md) + - [信号量](kernel-lite-mini-basic-ipc-sem.md) + - [基本概念](kernel-lite-mini-basic-ipc-sem-basic.md) + - [开发指导](kernel-lite-mini-basic-ipc-sem-guide.md) + - [时间管理](kernel-lite-basic-mini-time.md) + - [基本概念](kernel-lite-mini-basic-time-basic.md) + - [开发指导](kernel-lite-mini-basic-time-guide.md) + - [软件定时器](kernel-lite-mini-basic-soft.md) + - [基本概念](kernel-lite-mini-basic-soft-basic.md) + - [开发指导](kernel-lite-mini-basic-soft-guide.md) + - [扩展组件](kernel-lite-mini-extend.md) + - [C++支持](kernel-lite-mini-extend-support.md) + - [CPU占用率](kernel-lite-mini-extend-cpup.md) + - [基本概念](kernel-lite-mini-extend-cpup-basic.md) + - [开发指导](kernel-lite-mini-extend-cpup-guide.md) + - [文件系统](kernel-lite-mini-extend-file.md) + - [FAT](kernel-lite-mini-extend-file-fat.md) + - [LittleFS](kernel-lite-mini-extend-file-lit.md) + - [基本概念](kernel-lite-mini-extend-file-lit-basic.md) + - [开发指导](kernel-lite-mini-extend-file-lit-guide.md) + - [内核调测](kernel-lite-mini-inner.md) + - [内存调测](kernel-lite-mini-inner-debug.md) + - [内存信息统计](kernel-lite-mini-inner-debug-mes.md) + - [内存泄漏检测](kernel-lite-mini-inner-debug-det.md) + - [踩内存检测](kernel-lite-mini-inner-debug-cet.md) + - [异常调测](kernel-lite-mini-inner-exception.md) + - [Trace调测](kernel-lite-mini-inner-trace.md) + - [附录](kernel-lite-mini-app.md) + - [内核编码规范](kernel-lite-mini-app-code.md) + - [基本数据结构](kernel-lite-mini-app-data.md) + - [双向链表](kernel-lite-mini-app-data-list.md) + - [标准库支持](kernel-lite-mini-app-lib.md) + - [CMSIS支持](kernel-lite-mini-app-lib-cmsis.md) + - [POSIX支持](kernel-lite-mini-app-lib-posix.md) + + - [小型系统内核](kernel-lite-small.md) + - [基础内核](kernel-lite-small-basic.md) + - [进程](kernel-lite-small-process.md) + - [线程](kernel-lite-small-thread.md) + - [内存](kernel-lite-small-memory.md) + - [网络](kernel-lite-small-net.md) + + - [文件系统](kernel-lite-small-file.md) + - [VFS](kernel-lite-small-file-vfs.md) + - [NFS](kernel-lite-small-file-nfs.md) + - [RAMFS](kernel-lite-small-file-ramfs.md) + - [FAT](kernel-lite-small-file-fat.md) + - [JFFS2](kernel-lite-small-file-jffs.md) + + - [标准库](kernel-lite-small-lib.md) + - [标准库](kernel-lite-small-lib-standard.md) + - [与Linux标准库的差异](kernel-lite-small-lib-differ.md) + + - [调测](kernel-lite-small-shell.md) + - [Shell介绍](kernel-lite-small-shell-des.md) + - [Shell命令开发指导](kernel-lite-small-shell-guide.md) + - [Shell命令编程实例](kernel-lite-small-shell-sample.md) + - [Shell命令使用详解](kernel-lite-small-shell-cmd.md) + - [系统命令](kernel-lite-small-shell-cmd-sys.md) + - [cpup](kernel-lite-small-shell-cmd-sys-cpup.md) + - [date](kernel-lite-small-shell-cmd-sys-date.md) + - [dmesg](kernel-lite-small-shell-cmd-sys-demsg.md) + - [exec](kernel-lite-small-shell-cmd-sys-exec.md) + - [free](kernel-lite-small-shell-cmd-sys-free.md) + - [help](kernel-lite-small-shell-cmd-sys-help.md) + - [hwi](kernel-lite-small-shell-cmd-sys-hwi.md) + - [kill](kernel-lite-small-shell-cmd-sys-kill.md) + - [log](kernel-lite-small-shell-cmd-sys-log.md) + - [memcheck](kernel-lite-small-shell-cmd-sys-mem.md) + - [oom](kernel-lite-small-shell-cmd-sys-oom.md) + - [pmm](kernel-lite-small-shell-cmd-sys-pmm.md) + - [reset](kernel-lite-small-shell-cmd-sys-reset.md) + - [sem](kernel-lite-small-shell-cmd-sys-sem.md) + - [stack](kernel-lite-small-shell-cmd-sys-stack.md) + - [su](kernel-lite-small-shell-cmd-sys-su.md) + - [swtmr](kernel-lite-small-shell-cmd-sys-swymr.md) + - [systeminfo](kernel-lite-small-shell-cmd-sys-sys.md) + - [task](kernel-lite-small-shell-cmd-sys-task.md) + - [uname](kernel-lite-small-shell-cmd-sys-uname.md) + - [vmm](kernel-lite-small-shell-cmd-sys-vmm.md) + - [watch](kernel-lite-small-shell-cmd-sys-watch.md) + + - [文件命令](kernel-lite-small-shell-cmd-file.md) + - [cat](kernel-lite-small-shell-cmd-file-cat.md) + - [cd](kernel-lite-small-shell-cmd-file-cd.md) + - [chgrp](kernel-lite-small-shell-cmd-file-chgrp.md) + - [chmod](kernel-lite-small-shell-cmd-file-chmod.md) + - [chown](kernel-lite-small-shell-cmd-file-chown.md) + - [cp](kernel-lite-small-shell-cmd-file-cp.md) + - [format](kernel-lite-small-shell-cmd-file-format.md) + - [ls](kernel-lite-small-shell-cmd-file-is.md) + - [lsfd](kernel-lite-small-shell-cmd-file-isfd.md) + - [mkdir](kernel-lite-small-shell-cmd-file-mkdir.md) + - [mount](kernel-lite-small-shell-cmd-file-mount.md) + - [partinfo](kernel-lite-small-shell-cmd-file-part.md) + - [partition](kernel-lite-small-shell-cmd-file-partion.md) + - [pwd](kernel-lite-small-shell-cmd-file-pwd.md) + - [rm](kernel-lite-small-shell-cmd-file-rm.md) + - [rmdir](kernel-lite-small-shell-cmd-file-rmdir.md) + - [statfs](kernel-lite-small-shell-cmd-file-sta.md) + - [sync](kernel-lite-small-shell-cmd-file-sync.md) + - [touch](kernel-lite-small-shell-cmd-file-touch.md) + - [writeproc](kernel-lite-small-shell-cmd-file-write.md) + - [umount](kernel-lite-small-shell-cmd-file-umount.md) + + - [网络命令](kernel-lite-small-shell-cmd-net.md) + - [arp](kernel-lite-small-shell-cmd-net-arp.md) + - [dhclient](kernel-lite-small-shell-cmd-net-dh.md) + - [dns](kernel-lite-small-shell-cmd-net-dns.md) + - [ifconfig](kernel-lite-small-shell-cmd-net-ipc.md) + - [ipdebug](kernel-lite-small-shell-cmd-net-ipd.md) + - [netstat](kernel-lite-small-shell-cmd-net-net.md) + - [ntpdate](kernel-lite-small-shell-cmd-net-ntp.md) + - [ping](kernel-lite-small-shell-cmd-net-ping.md) + - [ping6](kernel-lite-small-shell-cmd-net-ping6.md) + - [telnet](kernel-lite-small-shell-cmd-net-tel.md) + - [tftp](kernel-lite-small-shell-cmd-net-tftp.md) + + - [魔法键使用方法](kernel-lite-small-shell-cmd-mag.md) + - [用户态异常信息说明](kernel-lite-small-shell-cmd-abn.md) + +- [标准系统内核](kernel-standard.md) + - [Linux内核概述](kernel-standard-des.md) + - [OpenHarmony开发板Patch使用指导](kernel-standard-patch.md) + - [Linux内核编译与构建指导](kernel-standard-build.md) diff --git "a/zh-cn/device-dev/kernel/Shell\344\273\213\347\273\215.md" "b/zh-cn/device-dev/kernel/Shell\344\273\213\347\273\215.md" deleted file mode 100755 index f72e4f67cbb241de5b34b5fff11df56ef70ae2ef..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/Shell\344\273\213\347\273\215.md" +++ /dev/null @@ -1,36 +0,0 @@ -# Shell介绍 - -- [注意事项](#section12298165312328) - -OpenHarmony内核提供的Shell支持调试常用的基本功能,包含系统、文件、网络和动态加载相关命令。同时OpenHarmony内核的Shell支持添加新的命令,可以根据需求来进行定制。 - -- 系统相关命令:提供查询系统任务、内核信号量、系统软件定时器、CPU占用率、当前中断等相关信息的能力。 - -- 文件相关命令:支持基本的ls、cd等功能。 - -- 网络相关命令:支持查询接到开发板的其他设备的IP、查询本机IP、测试网络连接、设置开发板的AP和station模式等相关功能。 - - 新增命令的详细流程可参见[开发指导](Shell命令开发指导.md)和[编程实例](Shell命令编程实例.md)。 - - -## 注意事项 - -在使用Shell功能的过程中,需要注意以下几点: - -- Shell功能支持使用exec命令来运行可执行文件。 -- Shell功能支持默认模式下英文输入。如果出现用户在UTF-8格式下输入了中文字符的情况,只能通过回退三次来删除。 - -- Shell功能支持shell命令、文件名及目录名的Tab键联想补全。若有多个匹配项,则根据共同字符, 打印多个匹配项。对于过多的匹配项(打印多于24行),将会进行打印询问(Display all num possibilities?(y/n)),用户可输入y选择全部打印,或输入n退出打印,选择全部打印并打印超过24行后,会进行--More--提示,此时按回车键继续打印,按q键退出(支持Ctrl+c退出\)。 - -- Shell端工作目录与系统工作目录是分开的,即通过Shell端cd pwd等命令是对Shell端工作目录进行操作,通过chdir getcwd等命令是对系统工作目录进行操作,两个工作目录相互之间没有联系。当文件系统操作命令入参是相对路径时要格外注意。 - -- 在使用网络Shell指令前,需要先调用tcpip\_init函数完成网络初始化并完成telnet连接后才能起作用,内核默认不初始化tcpip\_init。 - -- 不建议使用Shell命令对/dev目录下的设备文件进行操作,这可能会引起不可预知的结果。 - -- Shell功能不符合POSIX标准,仅供调试使用。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >Shell功能仅供调试使用,在Debug版本中开启(使用时通过menuconfig在配置项中开启"LOSCFG\_DEBUG\_VERSION"编译开关进行相关控制),商用产品中禁止包含该功能。 - - diff --git "a/zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\344\275\277\347\224\250\350\257\246\350\247\243.md" "b/zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\344\275\277\347\224\250\350\257\246\350\247\243.md" deleted file mode 100755 index 2faa37c7405c336830f2cb2270275d44766497a6..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\344\275\277\347\224\250\350\257\246\350\247\243.md" +++ /dev/null @@ -1,13 +0,0 @@ -# Shell命令使用详解 - -本章节介绍了系统关键命令的功能、格式、参数范围、使用指南和使用实例。 - -不在本文档范围内的命令,详见[help](help.md)命令的输出内容,也可以通过命令的“-h | --help”选项,查看该命令的使用帮助。 - -- **[系统命令](系统命令.md)** - -- **[文件命令](文件命令.md)** - -- **[网络命令](网络命令.md)** - - diff --git "a/zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index b8d1e6d8861489d99b76f84a56b9b0d2d09aecee..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,167 +0,0 @@ -# Shell命令开发指导 - -- [开发指导](#section22071515161018) - -## 开发指导 - -新增Shell命令的典型开发流程如下: - -1. 包含如下头文件: - - ``` - #include "shell.h" - #include "shcmd.h" - ``` - -2. 注册命令。用户可以选择静态注册命令方式和系统运行时动态注册命令方式,静态注册命令方式一般用在系统常用命令注册,动态注册命令方式一般用在用户命令注册。 - - 1. 静态注册命令方式: - - 1. 通过宏的方式注册。 - - 这个宏的原型为: - - ``` - SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) - ``` - - **表 1** SHELLCMD\_ENTRY参数详解 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

描述

-

l

-

静态注册全局变量名(注意:不与系统中其他symbol重名)。

-

cmdType

-

命令类型:

-
  • CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。

    -
  • CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。

    -
-

cmdKey

-

命令关键字,函数在Shell中访问的名称。

-

paraNum

-

调用的执行函数的入参最大个数,暂不支持。

-

cmdHook

-

命令执行函数地址,即命令实际执行函数。

-
- - 如: - - ``` - SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) - ``` - - 2. 在build/mk/liteos\_tables\_ldflags.mk中添加相应选项: - - 如:上述“ls”命令注册时,需在build/mk/liteos\_tables\_ldflags.mk中添加“-uls\_shellcmd”。其中-u后面跟SHELLCMD\_ENTRY的第一个参数。 - - - 2. 动态注册命令方式: - - 注册函数原型: - - ``` - UINT32 osCmdReg(CmdT ype cmdType, CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) - ``` - - **表 2** UINT32 osCmdReg参数详解 - - - - - - - - - - - - - - - - - - - -

参数

-

描述

-

cmdType

-

命令类型:

-
  • CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。

    -
  • CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。

    -
-

cmdKey

-

命令关键字,函数在Shell中访问的名称。

-

paraNum

-

调用的执行函数的入参最大个数,暂不支持该参数;当前为默认值XARGS(0xFFFFFFFF)。

-

cmdHook

-

命令执行函数地址,即命令实际执行函数。

-
- - 如: - - ``` - osCmdReg(CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) - ``` - - - >![](public_sys-resources/icon-note.gif) **说明:** - >命令关键字必须是唯一的,也即两个不同的命令项不能拥有相同的命令关键字,否则只会执行其中一个。 - >Shell在执行用户命令时,如果存在多个命令关键字相同的命令,只会执行其中在"help"命令中排序在最前面的一个。 - -3. 添加内置命令函数原型。 - - ``` - UINT32 osShellCmdLs(UINT32 argc, CHAR **argv) - ``` - - **表 3** osShellCmdLs参数说明 - - - - - - - - - - - - - -

参数

-

参数描述

-

argc

-

Shell命令中,参数个数。

-

argv

-

为指针数组,每个元素指向一个字符串,可以根据选择命令类型,决定是否要把命令关键字传入给注册函数。

-
- -4. 输入Shell命令,有两种输入方式: - - 在串口工具中直接输入Shell命令。 - - - 在telnet工具中输入Shell命令(telnet使用方式详见[telnet](telnet.md))。 - - - diff --git a/zh-cn/device-dev/kernel/VFS.md b/zh-cn/device-dev/kernel/VFS.md deleted file mode 100755 index 0a16319ccd1b2bc85ec7f546416d13a925806124..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/VFS.md +++ /dev/null @@ -1,171 +0,0 @@ -# VFS - -- [概述](#section132540468341) -- [基本概念](#section229417111227) -- [运作机制](#section18114182834215) -- [注意事项](#section18311145173712) -- [开发指导](#section422619258380) -- [编程实例](#section180311121420) -- [结果验证](#section16772334714) - -## 概述 - -## 基本概念 - -VFS是Virtual File System(虚拟文件系统)的缩写,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层,为用户提供统一的类Unix文件操作接口。 - -由于不同类型的文件系统接口不统一,若系统中有多个文件系统类型,访问不同的文件系统就需要使用不同的非标准接口。而通过在系统中添加VFS层,提供统一的抽象接口,屏蔽了底层异构类型的文件系统的差异,使得访问文件系统的系统调用不用关心底层的存储介质和文件系统类型,提高开发效率。VFS和各个具体文件系统的关系如下: - -**图 1** VFS和各个文件系统的关系 -![](figures/VFS和各个文件系统的关系.png "VFS和各个文件系统的关系") - -OpenHarmony内核中,VFS框架是通过在内存中的树结构来实现的,树的每个结点都是一个inode结构体。设备注册和文件系统挂载后会根据路径在树中生成相应的结点。VFS最主要是两个功能: - -- 查找节点。 -- 统一调用(标准)。 - -## 运作机制 - -通过VFS层,可以使用标准的Unix文件操作函数(如open、read、write等)来实现对不同介质上不同文件系统的访问。 - -VFS框架内存中的inode树结点有三种类型: - -- 虚拟结点:作为VFS框架的虚拟文件,保持树的连续性,如/usr、/usr/bin。 -- 设备结点:/dev目录下,对应一个设备,如/dev/mmcblk0。 -- 挂载点:挂载具体文件系统,如/vs/sd、/mnt。 - -**图 2** 文件系统树形结构 -![](figures/文件系统树形结构.png "文件系统树形结构") - -## 注意事项 - -- VFS下的所有文件系统,创建的目录名和文件名最多只可以有255个字节,能支持的全路径长度最长为259字节,超过这个路径长度的文件和目录无法创建。 - -- 目前仅有jffs2文件系统支持完整的权限控制。 - -- inode\_find\(\)函数调用后会使查找到的inode节点连接数+1,调用完成后需要调用inode\_release\(\)使连接数-1,所以一般inode\_find\(\)要和inode\_release\(\)配套使用。 - -- 设备分为字符设备和块设备,为了块设备上的文件系统系统数据安全,需挂载相应文件系统后通过文件系统接口操作数据。 - -- los\_vfs\_init\(\)只能调用一次,多次调用将会造成文件系统异常。 - -- 目前OpenHarmony内核所有的文件系统中的文件名和目录名中只可以出现“-” 与“\_”两种特殊字符,使用其他特殊字符可能造成的后果不可预知,请谨慎为之。 - -- OpenHarmony内核支持open\(\)+O\_DIRECTORY的方法获取目录数据信息。 - -- 挂载点必须为空目录,不能重复挂载至同一挂载点或挂载至其他挂载点下的目录或文件,错误挂载可能损坏设备及系统。 - -- open打开一个文件时,参数O\_RDWR、O\_WRONLY、O\_RDONLY互斥,只能出现一个,若出现2个或以上作为open的参数,文件读写操作会被拒绝,并返回EACCESS错误码,禁止使用。 - -- OpenHarmony内核文件系统在umount操作之前,需确保所有目录及文件全部关闭,否则umount会失败。如果强制umount,可能导致包括但不限于文件系统损坏、设备损坏等问题。 - -- SD卡移除前,需确保所有目录及文件全部关闭,并进行umount操作。如果强制拔卡,可能导致包括但不限于SD数据丢失、SD卡损坏等问题。 - - -## 开发指导 - -**开发流程** - -推荐驱动开发人员使用VFS框架来注册/卸载设备,即调用register\_driver\(\)、register\_blockdriver\(\)接口生成设备结点,应用层使用open\(\)、read\(\)操作设备(字符设备)文件来调用驱动。 - -**文件描述符** - -本系统中,进程的文件描述符最多有256个(File和Socket描述符合并统计),系统文件描述符共640个,系统文件描述符规格: - -- File描述符,普通文件描述符,系统总规格为512。 - -- Socket描述符,系统总规格为128。 - - -**VFS支持的操作** - -open, close, read, write, seek, ioctl, fcntl, mmap, sync, dup, dup2, truncate, opendir, closedir, readdir, rewinddir, mount, umount, statfs, unlink, remove, mkdir, rmdir, rename, stat, utime, seek64, fallocate, fallocate64, truncate64, chmod, chown。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 当前只提供修改jffs2文件以及vfs设备节点属性的接口,各个系统对只读等属性有各自的处理方式。 ->- 在OpenHarmony内核中属性并不冲突(可以任意修改)。 ->- 在OpenHarmony内核中只读属性文件/目录不允许被删除。 ->- 在OpenHarmony内核中只读属性文件/目录允许rename。 ->- 只读文件不允许以O\_CREAT、O\_TRUNC,以及有含有写的权限的方式打开。 ->- 在OpenHarmony内核中设置的系统文件加上隐藏属性,在Windows中只能通过命令行找到(在显示,不显示隐藏文件的属性情况下都不能看到)。 - -## 编程实例 - -``` -/* 说明:展示创建目录,和遍历目录的操作 */ -#include -#include -#include -#include -#include -#include - -int main() -{ - int ret; - char *dirname = "/test"; - char *pathname0 = "/test/test0"; - char *pathname1 = "/test/test1"; - char *pathname2 = "/test/test2"; - struct dirent **namelist; - int num; - - ret = mkdir(dirname, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", dirname, errno); - goto EXIT; - } - - ret = mkdir(pathname0, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", pathname0, errno); - goto EXIT0; - } - - ret = mkdir(pathname1, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", pathname1, errno); - goto EXIT1; - } - - ret = mkdir(pathname2, 0777); - if ((ret < 0) && (errno != EEXIST)) { - printf("mkdir failed. path=%s, errno=%d\n", pathname2, errno); - goto EXIT2; - } - - num = scandir(dirname, &namelist, NULL, alphasort); - if (num < 0) { - perror("scandir"); - } else { - while (num--) { - printf("%s\n", namelist[num]->d_name); - free(namelist[num]); - } - free(namelist); - } - - printf("fs_demo exit.\n"); - return 0; - -EXIT2: - remove(pathname2); -EXIT1: - remove(pathname1); -EXIT0: - remove(pathname0); -EXIT: - remove(dirname); - return 0; -} -``` - -## 结果验证 - -``` -OHOS # test2 -test1 -test0 -fs_demo exit. -``` - diff --git a/zh-cn/device-dev/kernel/arp.md b/zh-cn/device-dev/kernel/arp.md deleted file mode 100755 index 2cf3628efa4968b0e5ba3d9ee4cd520a97392441..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/arp.md +++ /dev/null @@ -1,114 +0,0 @@ -# arp - -- [命令功能](#section201149459368) -- [命令格式](#section579813484364) -- [参数说明](#section168065311366) -- [使用指南](#section19190125723612) -- [使用实例](#section10383416372) - -## 命令功能 - -在以太网中,主机之间的通信是直接使用MAC地址(非IP地址)来通信的,所以,对于使用IP通信的协议,必须能够将IP地址转换成MAC地址,才能在局域网(以太网)内通信。解决这个问题的方法就是主机存储一张IP和MAC地址对应的表,即ARP缓存,主机要往一个局域网内的目的IP地址发送IP包时,就可以从ARP缓存表中查询到目的MAC地址。ARP缓存是由TCP/IP协议栈维护的,用户可通过ARP命令查看和修改ARP表。 - -## 命令格式 - -arp - -arp \[_-i IF_\] -s _IPADDR HWADDR_ - -arp \[_-i IF_\] -d _IPADDR_ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-

打印整个ARP缓存的内容。

-

N/A

-

-i IF

-

指定的网络接口(可选参数)。

-

N/A

-

-s IPADDR

-

HWADDR

-

增加一条ARP表项,后面的参数是局域网中另一台主机的IP地址及其对应的MAC地址。

-

N/A

-

-d IPADDR

-

删除一条ARP表项。

-

N/A

-
- -## 使用指南 - -- arp命令用来查询和修改TCP/IP协议栈的ARP缓存表,增加非同一子网内的IP地址的ARP表项是没有意义的,协议栈会返回失败。 -- 命令需要启动TCP/IP协议栈后才能使用。 - -## 使用实例 - -举例: - -1. 输入arp - - **图 1** 打印整个 ARP 缓存表 - - - ![](figures/Snipaste_2021-01-26_10-38-58.png) - - **表 2** 参数说明 - - - - - - - - - - - - - - - - - - - -

参数

-

说明

-

Address

-

表示网络设备的IPv4地址。

-

HWaddress

-

表示网络设备的MAC地址。

-

Iface

-

表示该ARP表项使用的接口名。

-

Type

-

表示该ARP表项是动态的还是静态的,动态是指ARP表项由协议栈自动创建,静态是指ARP表项是由用户增加的。

-
- - diff --git a/zh-cn/device-dev/kernel/cat.md b/zh-cn/device-dev/kernel/cat.md deleted file mode 100755 index ef609b4dc074a005ff49eb4718b5b8bc069867d8..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/cat.md +++ /dev/null @@ -1,53 +0,0 @@ -# cat - -- [命令功能](#section16710153391315) -- [命令格式](#section1699392313158) -- [参数说明](#section1677217374136) -- [使用指南](#section186772414131) -- [使用实例](#section12158131814561) -- [输出说明](#section183926225561) - -## 命令功能 - -cat用于显示文本文件的内容。 - -## 命令格式 - -cat \[_pathname_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

pathname

-

文件路径。

-

已存在的文件。

-
- -## 使用指南 - -cat用于显示文本文件的内容。 - -## 使用实例 - -举例:cat hello-harmony.txt - -## 输出说明 - -**图 1** 查看 hello-harmony.txt 文件的信息 -![](figures/查看-hello-harmony-txt-文件的信息.png "查看-hello-harmony-txt-文件的信息") - diff --git a/zh-cn/device-dev/kernel/cd.md b/zh-cn/device-dev/kernel/cd.md deleted file mode 100755 index 8acd5da837df72b9755ac1e90032c26ece690a6b..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/cd.md +++ /dev/null @@ -1,57 +0,0 @@ -# cd - -- [命令功能](#section11690184921316) -- [命令格式](#section75695409569) -- [参数说明](#section71961353181311) -- [使用指南](#section3629759111317) -- [使用实例](#section211620301412) -- [输出说明](#section1968117214577) - -## 命令功能 - -cd命令用来改变当前目录。 - -## 命令格式 - -cd \[_path_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

path

-

文件路径。

-

用户必须具有指定目录中的执行(搜索)许可权。

-
- -## 使用指南 - -- 未指定目录参数时,会跳转至根目录。 -- cd后加路径名时,跳转至该路径。 -- 路径名以 /(斜杠)开头时,表示根目录。 -- .(点)表示当前目录。 -- ..(点点)表示父目录。 - -## 使用实例 - -举例:cd .. - -## 输出说明 - -**图 1** 显示结果如下 -![](figures/显示结果如下.png "显示结果如下") - diff --git a/zh-cn/device-dev/kernel/chgrp.md b/zh-cn/device-dev/kernel/chgrp.md deleted file mode 100755 index dc292bf35fdd9f18d169039d5f8c7cc10fffe446..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/chgrp.md +++ /dev/null @@ -1,60 +0,0 @@ -# chgrp - -- [命令功能](#section6103119161418) -- [命令格式](#section186958132141) -- [参数说明](#section81796174141) -- [使用指南](#section14330152417140) -- [使用实例](#section951823119149) -- [输出说明](#section14271133125715) - -## 命令功能 - -chgrp用于修改文件的群组。 - -## 命令格式 - -chgrp \[_group_\] \[_pathname_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

group

-

文件群组。

-

[0,0xFFFFFFFF]

-

pathname

-

文件路径。

-

已存在的文件。

-
- -## 使用指南 - -在需要修改的文件名前加上文件群组值就可以修改该文件的所属组。 - -## 使用实例 - -举例:chgrp 100 hello-harmony.txt - -## 输出说明 - -**图 1** 修改 hello-harmony.txt 文件的群组为100 -![](figures/修改-hello-harmony-txt-文件的群组为100.png "修改-hello-harmony-txt-文件的群组为100") - diff --git a/zh-cn/device-dev/kernel/chmod.md b/zh-cn/device-dev/kernel/chmod.md deleted file mode 100755 index a77659fcddfc8998b2f1d62b32b06cbbba2be19f..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/chmod.md +++ /dev/null @@ -1,60 +0,0 @@ -# chmod - -- [命令功能](#section13992936121418) -- [命令格式](#section63342439147) -- [参数说明](#section894414671411) -- [使用指南](#section182415221419) -- [使用实例](#section8518195718147) -- [输出说明](#section127391818158) - -## 命令功能 - -chmod用于修改文件操作权限。 - -## 命令格式 - -chmod \[_mode_\] \[_pathname_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

mode

-

文件或文件夹权限,用8进制表示对应User、Group、及Other(拥有者、群组、其他组)的权限。

-

[0,777]

-

pathname

-

文件路径。

-

已存在的文件。

-
- -## 使用指南 - -在需要修改的文件名前加上文件权限值就可以修改该文件的权限值。 - -## 使用实例 - -举例:chmod 666 hello-harmony.txt - -## 输出说明 - -**图 1** 修改 hello-harmony.txt 文件的权限为666 -![](figures/修改-hello-harmony-txt-文件的权限为666.png "修改-hello-harmony-txt-文件的权限为666") - diff --git a/zh-cn/device-dev/kernel/chown.md b/zh-cn/device-dev/kernel/chown.md deleted file mode 100755 index 467da9d89cedc0b704a913bd20cd84fa1f95654d..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/chown.md +++ /dev/null @@ -1,70 +0,0 @@ -# chown - -- [命令功能](#section247414691513) -- [命令格式](#section14773151018159) -- [参数说明](#section598731391517) -- [使用指南](#section16524152071510) -- [使用实例](#section17901152561510) -- [输出说明](#section15513163115816) - -## 命令功能 - -chmod用于将指定文件的拥有者改为指定的用户或组。 - -## 命令格式 - -chown \[_owner_\] \[_group_\] \[_pathname_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

owner

-

文件拥有者。

-

[0,0xFFFFFFFF]

-

group

-

文件群组。

-

1、为空。

-

2、[0,0xFFFFFFFF]

-

pathname

-

文件路径。

-

已存在的文件。

-
- -## 使用指南 - -- 在需要修改的文件名前加上文件拥有者和文件群组就可以分别修改该文件的拥有者和群组。 -- 当owner或group值为-1时则表示对应的owner或group不修改。 -- group参数可以为空。 - -## 使用实例 - -举例:chown 100 200 hello-harmony.txt - -## 输出说明 - -**图 1** 修改 hello-harmony.txt 文件的uid为100,gid为200 -![](figures/修改-hello-harmony-txt-文件的uid为100-gid为200.png "修改-hello-harmony-txt-文件的uid为100-gid为200") - diff --git a/zh-cn/device-dev/kernel/cp.md b/zh-cn/device-dev/kernel/cp.md deleted file mode 100755 index eab217ee504586612e96af7bd6f3ac9869a6f435..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/cp.md +++ /dev/null @@ -1,68 +0,0 @@ -# cp - -- [命令功能](#section6841203041513) -- [命令格式](#section24286359150) -- [参数说明](#section558617385152) -- [使用指南](#section16128156162) -- [使用实例](#section19354171211618) -- [输出说明](#section16754183195914) - -## 命令功能 - -拷贝文件,创建一份副本。 - -## 命令格式 - -cp \[_SOURCEFILE_\] \[_DESTFILE_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

SOURCEFILE

-

源文件路径。

-

目前只支持文件,不支持目录。

-

DESTFILE

-

目的文件路径。

-

支持目录以及文件。

-
- -## 使用指南 - -- 同一路径下,源文件与目的文件不能重名。 -- 源文件必须存在,且不为目录。 -- 源文件路径支持“\*”和“?”通配符,“\*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。 -- 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。 -- 目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。 -- 目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。 -- 目的文件不存在时创建新文件,已存在则覆盖。 - -拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。 - -## 使用实例 - -举例:cp hello-harmony.txt ./tmp/ - -## 输出说明 - -**图 1** 显示结果如下 -![](figures/显示结果如下-0.png "显示结果如下-0") - diff --git a/zh-cn/device-dev/kernel/cpup.md b/zh-cn/device-dev/kernel/cpup.md deleted file mode 100755 index c2bf2bba4636e7a8c5ec0d36b281fc49c1ad5d15..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/cpup.md +++ /dev/null @@ -1,65 +0,0 @@ -# cpup - -- [命令功能](#section1842161614217) -- [命令格式](#section5629527427) -- [参数说明](#section133651361023) -- [使用指南](#section156611948521) -- [使用实例](#section68501605319) -- [输出说明](#section19871522144219) - -## 命令功能 - -cpup命令用于查询系统CPU的占用率。 - -## 命令格式 - -cpup \[_mode_\] \[_taskID_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

mode

-

● 缺省:显示系统最近10s内的CPU占用率。

-

● 0:显示系统最近10s内的CPU占用率。

-

● 1:显示系统最近1s内的CPU占用率。

-

● 其他数字:显示系统启动至今总的CPU 占用率。

-

[0,0xFFFFFFFF]

-

taskID

-

任务ID号

-

[0,0xFFFFFFFF]

-
- -## 使用指南 - -- 参数缺省时,显示系统10s前的CPU占用率。 -- 只有一个参数时,该参数为mode,显示系统相应时间前的CPU占用率。 -- 输入两个参数时,第一个参数为mode,第二个参数为taskID,显示对应ID号任务的相应时间前的CPU占用率。 - -## 使用实例 - -举例:输入cpup 1 5 - -## 输出说明 - -**图 1** 指令输出结果 -![](figures/指令输出结果.png "指令输出结果") - diff --git a/zh-cn/device-dev/kernel/date.md b/zh-cn/device-dev/kernel/date.md deleted file mode 100755 index d359856e2043798eae4396e86919a098171ddce4..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/date.md +++ /dev/null @@ -1,94 +0,0 @@ -# date - -- [命令功能](#section56472016338) -- [命令格式](#section16635112512316) -- [参数说明](#section15896030039) -- [使用指南](#section116361036636) -- [使用实例](#section021711411237) -- [输出说明](#section17950184414312) - -## 命令功能 - -date命令用于查询及设置系统日期和时间。 - -## 命令格式 - -date - -date --help - -date +\[_Format_\] - -date -s_ _\[_YY/MM/DD_\] - -date_ _-s_ _\[_hh:mm:ss_\]__ - -date -r \[_Filename_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

使用帮助。

-

N/A

-

+Format

-

根据Format格式打印日期和时间。

-

--help中列出的占位符。

-

-s YY/MM/DD

-

设置系统时间,用“/”分割的年月日。

-

>= 1970/01/01

-

-s hh:mm:ss

-

设置系统时间,用“:”分割的时分秒。

-

N/A

-

-r Filename

-

查询Filename文件的修改时间。

-

N/A

-
- -## 使用指南 - -- date参数缺省时,默认显示当前系统日期和时间。 -- --help、+Format、-s、-r不能混合使用。 - -## 使用实例 - -举例: - -输入date +%Y--%m--%d。 - -## 输出说明 - -**图 1** 按指定格式打印系统日期 -![](figures/按指定格式打印系统日期.png "按指定格式打印系统日期") - diff --git a/zh-cn/device-dev/kernel/dhclient.md b/zh-cn/device-dev/kernel/dhclient.md deleted file mode 100755 index 360efdc8085aa1f4c0585e1bc926eaa0fceba7aa..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/dhclient.md +++ /dev/null @@ -1,138 +0,0 @@ -# dhclient - -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section12742311179) - -## 命令功能 - -设置和查看dhclient的参数。 - -## 命令格式 - -dhclient <_netif name_\> - -dhclient -x <_netif name_\> - -dhclient -gb <_netif name_\> - -dhclient -sv <_vendor_\> - -dhclient -gv - -dhclient -gd <_index_\> - -dhclient -sd <_dns\_ip_\> - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

<netif name>

-

启动对应网卡的dhcp请求。

-

网卡名字,eth0。

-

-x <netif name>

-

关闭对应网卡的dhcp功能。

-

网卡名字,eth0。

-

-gb <netif name>

-

查看对应网卡的dhcp请求是否完成。

-

网卡名字,eth0。

-

-sv <vendor>

-

设置dhcp请求的厂商信息。

-

厂商信息,长度是32个字符。

-

-gv

-

查看dhcp请求的厂商信息。

-

N/A

-

-gd <index>

-

获取第index个dns server的信息。

-

index,0或者1。

-

-sd <dns_ip>

-

设置主dns server的ip。

-

dns的ip地址。

-
- -## 使用指南 - -dhclient eth0 - -dhclient -x eth0 - -dhclient -gb eth0 - -dhclient -sv MFSI - -dhclient -gv - -dhclient -gd 0 - -dhclient -sd 8.8.8.8 - -## 使用实例 - -![](figures/zh-cn_image_0000001053224218.png) - -## 输出说明 - -**表 2** 输出说明 - - - - - - - - - - - - - -

输出

-

说明

-

dhclient: set vendor info [MFSI] success

-

设置厂商信息MFSI信息成功。

-

dns[0]: 192.168.1.100

-

dns server ip地址为192.168.1.100。

-
- diff --git a/zh-cn/device-dev/kernel/dmesg.md b/zh-cn/device-dev/kernel/dmesg.md deleted file mode 100755 index 197e38fdfffb35ce283113c49a392b50799f9d67..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/dmesg.md +++ /dev/null @@ -1,113 +0,0 @@ -# dmesg - -- [命令功能](#section4643204919313) -- [命令格式](#section6553153635) -- [参数说明](#section208971157532) -- [使用指南](#section213115219413) -- [使用实例](#section13736564418) -- [输出说明](#section194005101413) - -## 命令功能 - -dmesg命令用于控制内核dmesg缓存区。 - -## 命令格式 - -dmesg - -dmesg \[_-c/-C/-D/-E/-L/-U_\] - -dmesg -s \[_size_\] - -dmesg -l \[_level_\] - -dmesg \> \[_fileA_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-c

-

打印缓存区内容并清空缓存区。

-

N/A

-

-C

-

清空缓存区。

-

N/A

-

-D/-E

-

关闭/开启控制台打印。

-

N/A

-

-L/-U

-

关闭/开启串口打印。

-

N/A

-

-s size

-

设置缓存区大小 size是要设置的大小。

-

N/A

-

-l level

-

设置缓存等级。

-

0 - 5

-

> fileA

-

将缓存区内容写入文件。

-

N/A

-
- -## 使用指南 - -- 该命令依赖于LOSCFG\_SHELL\_DMESG,使用时通过menuconfig在配置项中开启"Enable Shell dmesg": - - Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell dmesg - -- dmesg参数缺省时,默认打印缓存区内容。 -- 各“ - ”选项不能混合使用。 - 1. 写入文件需确保已挂载文件系统。 - 2. 关闭串口打印会影响shell使用,建议先连接telnet再尝试关闭串口。 - - -## 使用实例 - -举例: - -输入dmesg \> /usr/dmesg.log。 - -## 输出说明 - -**图 1** dmesg重定向到文件。 -![](figures/dmesg重定向到文件.png "dmesg重定向到文件") - diff --git a/zh-cn/device-dev/kernel/exec.md b/zh-cn/device-dev/kernel/exec.md deleted file mode 100755 index a3b0933672ad5f5347812edf8ed4844bcd2e0621..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/exec.md +++ /dev/null @@ -1,60 +0,0 @@ -# exec - -- [命令功能](#section4643204919313) -- [命令格式](#section6553153635) -- [参数说明](#section208971157532) -- [使用指南](#section213115219413) -- [使用实例](#section13736564418) -- [输出说明](#section194005101413) - -## 命令功能 - -exec命令属于shell内置命令,目前实现最基础的执行用户态程序的功能。 - -## 命令格式 - -exec <_executable-file_\> - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

executable-file

-

有效的可执行文件。

-

N/A

-
- -## 使用指南 - -该命令当前仅支持执行有效的二进制程序,程序成功执行,默认后台运行,但与Shell共用终端,可能会导致程序打印输出与Shell输出交错显示。 - -## 使用实例 - -举例: - -输入exec helloworld。 - -## 输出说明 - -``` -OHOS # exec helloworld -OHOS # hello world! -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->可执行文件执行后,先打印“OHOS \#”提示符原因:目前Shell “exec”命令执行均为后台执行,结果可能导致提示符提前打印。 - diff --git "a/zh-cn/device-dev/kernel/figure/Cow\346\234\272\345\210\266\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/Cow\346\234\272\345\210\266\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..bee6020f58b7127c24d0adc1da77fe1761b386de Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/Cow\346\234\272\345\210\266\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/PID\344\270\2723\347\232\204\350\277\233\347\250\213\350\231\232\346\213\237\345\206\205\345\255\230\344\275\277\347\224\250\344\277\241\346\201\257.png" "b/zh-cn/device-dev/kernel/figure/PID\344\270\2723\347\232\204\350\277\233\347\250\213\350\231\232\346\213\237\345\206\205\345\255\230\344\275\277\347\224\250\344\277\241\346\201\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/PID\344\270\2723\347\232\204\350\277\233\347\250\213\350\231\232\346\213\237\345\206\205\345\255\230\344\275\277\347\224\250\344\277\241\346\201\257.png" rename to "zh-cn/device-dev/kernel/figure/PID\344\270\2723\347\232\204\350\277\233\347\250\213\350\231\232\346\213\237\345\206\205\345\255\230\344\275\277\347\224\250\344\277\241\346\201\257.png" diff --git "a/zh-cn/device-dev/kernel/figures/POSIX\346\216\245\345\217\243\346\241\206\346\236\266.png" "b/zh-cn/device-dev/kernel/figure/POSIX\346\216\245\345\217\243\346\241\206\346\236\266.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/POSIX\346\216\245\345\217\243\346\241\206\346\236\266.png" rename to "zh-cn/device-dev/kernel/figure/POSIX\346\216\245\345\217\243\346\241\206\346\236\266.png" diff --git a/zh-cn/device-dev/kernel/figures/Snipaste_2021-01-26_10-38-58-1.png b/zh-cn/device-dev/kernel/figure/Snipaste_2021-01-26_10-38-58-18.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/Snipaste_2021-01-26_10-38-58-1.png rename to zh-cn/device-dev/kernel/figure/Snipaste_2021-01-26_10-38-58-18.png diff --git a/zh-cn/device-dev/kernel/figures/Snipaste_2021-01-26_10-38-58-2.png b/zh-cn/device-dev/kernel/figure/Snipaste_2021-01-26_10-38-58-19.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/Snipaste_2021-01-26_10-38-58-2.png rename to zh-cn/device-dev/kernel/figure/Snipaste_2021-01-26_10-38-58-19.png diff --git a/zh-cn/device-dev/kernel/figures/Snipaste_2021-01-26_10-38-58.png b/zh-cn/device-dev/kernel/figure/Snipaste_2021-01-26_10-38-58.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/Snipaste_2021-01-26_10-38-58.png rename to zh-cn/device-dev/kernel/figure/Snipaste_2021-01-26_10-38-58.png diff --git "a/zh-cn/device-dev/kernel/figures/VFS\345\222\214\345\220\204\344\270\252\346\226\207\344\273\266\347\263\273\347\273\237\347\232\204\345\205\263\347\263\273.png" "b/zh-cn/device-dev/kernel/figure/VFS\345\222\214\345\220\204\344\270\252\346\226\207\344\273\266\347\263\273\347\273\237\347\232\204\345\205\263\347\263\273.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/VFS\345\222\214\345\220\204\344\270\252\346\226\207\344\273\266\347\263\273\347\273\237\347\232\204\345\205\263\347\263\273.png" rename to "zh-cn/device-dev/kernel/figure/VFS\345\222\214\345\220\204\344\270\252\346\226\207\344\273\266\347\263\273\347\273\237\347\232\204\345\205\263\347\263\273.png" diff --git "a/zh-cn/device-dev/kernel/figures/dmesg\351\207\215\345\256\232\345\220\221\345\210\260\346\226\207\344\273\266.png" "b/zh-cn/device-dev/kernel/figure/dmesg\351\207\215\345\256\232\345\220\221\345\210\260\346\226\207\344\273\266.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/dmesg\351\207\215\345\256\232\345\220\221\345\210\260\346\226\207\344\273\266.png" rename to "zh-cn/device-dev/kernel/figure/dmesg\351\207\215\345\256\232\345\220\221\345\210\260\346\226\207\344\273\266.png" diff --git "a/zh-cn/device-dev/kernel/figures/lsfd\350\276\223\345\207\272\350\257\264\346\230\216.png" "b/zh-cn/device-dev/kernel/figure/lsfd\350\276\223\345\207\272\350\257\264\346\230\216.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/lsfd\350\276\223\345\207\272\350\257\264\346\230\216.png" rename to "zh-cn/device-dev/kernel/figure/lsfd\350\276\223\345\207\272\350\257\264\346\230\216.png" diff --git "a/zh-cn/device-dev/kernel/figures/statfs\350\276\223\345\207\272\350\257\264\346\230\216.png" "b/zh-cn/device-dev/kernel/figure/statfs\350\276\223\345\207\272\350\257\264\346\230\216.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/statfs\350\276\223\345\207\272\350\257\264\346\230\216.png" rename to "zh-cn/device-dev/kernel/figure/statfs\350\276\223\345\207\272\350\257\264\346\230\216.png" diff --git "a/zh-cn/device-dev/kernel/figures/umount\350\276\223\345\207\272\347\244\272\344\276\213.png" "b/zh-cn/device-dev/kernel/figure/umount\350\276\223\345\207\272\347\244\272\344\276\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/umount\350\276\223\345\207\272\347\244\272\344\276\213.png" rename to "zh-cn/device-dev/kernel/figure/umount\350\276\223\345\207\272\347\244\272\344\276\213.png" diff --git "a/zh-cn/device-dev/kernel/figures/watch-task-\347\273\223\346\236\234.png" "b/zh-cn/device-dev/kernel/figure/watch-task-\347\273\223\346\236\234.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/watch-task-\347\273\223\346\236\234.png" rename to "zh-cn/device-dev/kernel/figure/watch-task-\347\273\223\346\236\234.png" diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001051690323.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001051690323.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001051690323.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001051690323.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052370303.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052370303.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052370303.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052370303.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052370305.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052370305.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052370305.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052370305.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052370307.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052370307.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052370307.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052370307.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052530298.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052530298.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052530298.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052530298.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052810300.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052810300.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052810300.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052810300.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052810304.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052810304.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001052810304.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001052810304.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001053224218.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001053224218.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001053224218.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001053224218.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001053710680.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001053710680.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001053710680.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001053710680.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001053826366.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001053826366.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001053826366.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001053826366.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001054624363.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001054624363.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001054624363.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001054624363.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001121429646.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001121429646.png similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001121429646.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001121429646.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124146302.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124146302.png similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124146302.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124146302.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124147160.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124147160.png similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124147160.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124147160.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124306828.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124306828.png similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124306828.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124306828.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124307264.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124307264.png similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124307264.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124307264.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124310992.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124310992.png similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001124310992.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001124310992.png diff --git a/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132085260.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132085260.png new file mode 100644 index 0000000000000000000000000000000000000000..4bc250489d5cfba6848f63abd9a1ea12502fd9df Binary files /dev/null and b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132085260.png differ diff --git a/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132778524.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132778524.png new file mode 100644 index 0000000000000000000000000000000000000000..7836a009e5e3cb6351c807daf9b927c7d3b71a86 Binary files /dev/null and b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132778524.png differ diff --git a/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132935054.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132935054.png new file mode 100644 index 0000000000000000000000000000000000000000..238a15fa82b6095a13ee54bd3014ed3c08c21b4e Binary files /dev/null and b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001132935054.png differ diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001170790681.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001170790681.png similarity index 100% rename from zh-cn/device-dev/kernel/figures/zh-cn_image_0000001170790681.png rename to zh-cn/device-dev/kernel/figure/zh-cn_image_0000001170790681.png diff --git "a/zh-cn/device-dev/kernel/figures/\344\272\213\344\273\266\350\277\220\344\275\234\345\216\237\347\220\206\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\344\272\213\344\273\266\350\277\220\344\275\234\345\216\237\347\220\206\345\233\276.png" similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\344\272\213\344\273\266\350\277\220\344\275\234\345\216\237\347\220\206\345\233\276.png" rename to "zh-cn/device-dev/kernel/figure/\344\272\213\344\273\266\350\277\220\344\275\234\345\216\237\347\220\206\345\233\276.png" diff --git "a/zh-cn/device-dev/kernel/figure/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..37559a2a230b4d0a17fa07aaac2ea5ed3923b4df Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\344\273\245\344\270\211\347\247\215\346\226\271\345\274\217\346\230\276\347\244\272\345\206\205\345\255\230\344\275\277\347\224\250\346\203\205\345\206\265.png" "b/zh-cn/device-dev/kernel/figure/\344\273\245\344\270\211\347\247\215\346\226\271\345\274\217\346\230\276\347\244\272\345\206\205\345\255\230\344\275\277\347\224\250\346\203\205\345\206\265.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\344\273\245\344\270\211\347\247\215\346\226\271\345\274\217\346\230\276\347\244\272\345\206\205\345\255\230\344\275\277\347\224\250\346\203\205\345\206\265.png" rename to "zh-cn/device-dev/kernel/figure/\344\273\245\344\270\211\347\247\215\346\226\271\345\274\217\346\230\276\347\244\272\345\206\205\345\255\230\344\275\277\347\224\250\346\203\205\345\206\265.png" diff --git "a/zh-cn/device-dev/kernel/figure/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..75c79e501c27a2c41ff011133197eb646981b0f3 Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\344\277\241\345\217\267\345\217\221\351\200\201\345\244\261\350\264\245.png" "b/zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\345\217\221\351\200\201\345\244\261\350\264\245.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\344\277\241\345\217\267\345\217\221\351\200\201\345\244\261\350\264\245.png" rename to "zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\345\217\221\351\200\201\345\244\261\350\264\245.png" diff --git "a/zh-cn/device-dev/kernel/figures/\344\277\241\345\217\267\345\217\221\351\200\201\347\273\223\346\236\234\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\345\217\221\351\200\201\347\273\223\346\236\234\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\344\277\241\345\217\267\345\217\221\351\200\201\347\273\223\346\236\234\345\233\276.png" rename to "zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\345\217\221\351\200\201\347\273\223\346\236\234\345\233\276.png" diff --git "a/zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..02437a72c3de38cbddf5233282ef9354220002bf Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204uid\344\270\272100-gid\344\270\272200.png" "b/zh-cn/device-dev/kernel/figure/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204uid\344\270\272100-gid\344\270\272200.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204uid\344\270\272100-gid\344\270\272200.png" rename to "zh-cn/device-dev/kernel/figure/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204uid\344\270\272100-gid\344\270\272200.png" diff --git "a/zh-cn/device-dev/kernel/figures/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\346\235\203\351\231\220\344\270\272666.png" "b/zh-cn/device-dev/kernel/figure/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\346\235\203\351\231\220\344\270\272666.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\346\235\203\351\231\220\344\270\272666.png" rename to "zh-cn/device-dev/kernel/figure/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\346\235\203\351\231\220\344\270\272666.png" diff --git "a/zh-cn/device-dev/kernel/figures/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\347\276\244\347\273\204\344\270\272100.png" "b/zh-cn/device-dev/kernel/figure/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\347\276\244\347\273\204\344\270\272100.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\347\276\244\347\273\204\344\270\272100.png" rename to "zh-cn/device-dev/kernel/figure/\344\277\256\346\224\271-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\347\276\244\347\273\204\344\270\272100.png" diff --git "a/zh-cn/device-dev/kernel/figure/\345\205\203\346\225\260\346\215\256\345\255\230\345\202\250\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\345\205\203\346\225\260\346\215\256\345\255\230\345\202\250\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..8566e16dbc675362366f07cf9497c2d9073d6f56 Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\345\205\203\346\225\260\346\215\256\345\255\230\345\202\250\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\345\220\257\345\212\250\346\265\201\347\250\213.png" "b/zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\345\220\257\345\212\250\346\265\201\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..6c211cb88534ae6a28e6dbdaed8bd1b2717d7366 Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\345\220\257\345\212\250\346\265\201\347\250\213.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\345\206\205\346\240\270\346\236\266\346\236\204\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\346\236\266\346\236\204\345\233\276.png" similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\206\205\346\240\270\346\236\266\346\236\204\345\233\276.png" rename to "zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\346\236\266\346\236\204\345\233\276.png" diff --git "a/zh-cn/device-dev/kernel/figures/\345\207\272\347\216\260\345\206\205\345\255\230\350\266\212\347\225\214.png" "b/zh-cn/device-dev/kernel/figure/\345\207\272\347\216\260\345\206\205\345\255\230\350\266\212\347\225\214.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\207\272\347\216\260\345\206\205\345\255\230\350\266\212\347\225\214.png" rename to "zh-cn/device-dev/kernel/figure/\345\207\272\347\216\260\345\206\205\345\255\230\350\266\212\347\225\214.png" diff --git "a/zh-cn/device-dev/kernel/figures/\345\210\207\346\215\242\345\210\260\344\270\272uid\344\270\2721000-gid\344\270\2721000\347\232\204\347\224\250\346\210\267.png" "b/zh-cn/device-dev/kernel/figure/\345\210\207\346\215\242\345\210\260\344\270\272uid\344\270\2721000-gid\344\270\2721000\347\232\204\347\224\250\346\210\267.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\210\207\346\215\242\345\210\260\344\270\272uid\344\270\2721000-gid\344\270\2721000\347\232\204\347\224\250\346\210\267.png" rename to "zh-cn/device-dev/kernel/figure/\345\210\207\346\215\242\345\210\260\344\270\272uid\344\270\2721000-gid\344\270\2721000\347\232\204\347\224\250\346\210\267.png" diff --git "a/zh-cn/device-dev/kernel/figures/\345\210\233\345\273\272-share-\347\233\256\345\275\225.png" "b/zh-cn/device-dev/kernel/figure/\345\210\233\345\273\272-share-\347\233\256\345\275\225.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\210\233\345\273\272-share-\347\233\256\345\275\225.png" rename to "zh-cn/device-dev/kernel/figure/\345\210\233\345\273\272-share-\347\233\256\345\275\225.png" diff --git "a/zh-cn/device-dev/kernel/figures/\345\210\233\345\273\272\344\270\200\344\270\252\345\220\215\344\270\272-file-c-\347\232\204\346\226\207\344\273\266.png" "b/zh-cn/device-dev/kernel/figure/\345\210\233\345\273\272\344\270\200\344\270\252\345\220\215\344\270\272-file-c-\347\232\204\346\226\207\344\273\266.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\210\233\345\273\272\344\270\200\344\270\252\345\220\215\344\270\272-file-c-\347\232\204\346\226\207\344\273\266.png" rename to "zh-cn/device-dev/kernel/figure/\345\210\233\345\273\272\344\270\200\344\270\252\345\220\215\344\270\272-file-c-\347\232\204\346\226\207\344\273\266.png" diff --git "a/zh-cn/device-dev/kernel/figures/\345\210\240\351\231\244\344\270\200\344\270\252\345\220\215\344\270\272-dir-\347\232\204\347\233\256\345\275\225.png" "b/zh-cn/device-dev/kernel/figure/\345\210\240\351\231\244\344\270\200\344\270\252\345\220\215\344\270\272-dir-\347\232\204\347\233\256\345\275\225.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\210\240\351\231\244\344\270\200\344\270\252\345\220\215\344\270\272-dir-\347\232\204\347\233\256\345\275\225.png" rename to "zh-cn/device-dev/kernel/figure/\345\210\240\351\231\244\344\270\200\344\270\252\345\220\215\344\270\272-dir-\347\232\204\347\233\256\345\275\225.png" diff --git "a/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" "b/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" new file mode 100644 index 0000000000000000000000000000000000000000..955aff65c1c8365cc6c932a5e89ef944384bb489 Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" differ diff --git "a/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..e67cd13c295d19b6ce45c4749644eea42ada7f05 Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\345\217\221\351\200\201\344\277\241\345\217\267\347\273\231\346\214\207\345\256\232\350\277\233\347\250\213.png" "b/zh-cn/device-dev/kernel/figure/\345\217\221\351\200\201\344\277\241\345\217\267\347\273\231\346\214\207\345\256\232\350\277\233\347\250\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\217\221\351\200\201\344\277\241\345\217\267\347\273\231\346\214\207\345\256\232\350\277\233\347\250\213.png" rename to "zh-cn/device-dev/kernel/figure/\345\217\221\351\200\201\344\277\241\345\217\267\347\273\231\346\214\207\345\256\232\350\277\233\347\250\213.png" diff --git "a/zh-cn/device-dev/kernel/figure/\345\240\206\346\240\210\345\210\206\346\236\220\345\216\237\347\220\206\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\345\240\206\346\240\210\345\210\206\346\236\220\345\216\237\347\220\206\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..6ac9200e867f2c87d14ef89ca8c15102e83d4c10 Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\345\240\206\346\240\210\345\210\206\346\236\220\345\216\237\347\220\206\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\345\275\223\345\211\215\346\262\241\346\234\211\345\206\205\345\255\230\350\266\212\347\225\214.png" "b/zh-cn/device-dev/kernel/figure/\345\275\223\345\211\215\346\262\241\346\234\211\345\206\205\345\255\230\350\266\212\347\225\214.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\345\275\223\345\211\215\346\262\241\346\234\211\345\206\205\345\255\230\350\266\212\347\225\214.png" rename to "zh-cn/device-dev/kernel/figure/\345\275\223\345\211\215\346\262\241\346\234\211\345\206\205\345\255\230\350\266\212\347\225\214.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\214\207\344\273\244\350\276\223\345\207\272\347\273\223\346\236\234.png" "b/zh-cn/device-dev/kernel/figure/\346\214\207\344\273\244\350\276\223\345\207\272\347\273\223\346\236\234.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\214\207\344\273\244\350\276\223\345\207\272\347\273\223\346\236\234.png" rename to "zh-cn/device-dev/kernel/figure/\346\214\207\344\273\244\350\276\223\345\207\272\347\273\223\346\236\234.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\214\211\346\214\207\345\256\232\346\240\274\345\274\217\346\211\223\345\215\260\347\263\273\347\273\237\346\227\245\346\234\237.png" "b/zh-cn/device-dev/kernel/figure/\346\214\211\346\214\207\345\256\232\346\240\274\345\274\217\346\211\223\345\215\260\347\263\273\347\273\237\346\227\245\346\234\237.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\214\211\346\214\207\345\256\232\346\240\274\345\274\217\346\211\223\345\215\260\347\263\273\347\273\237\346\227\245\346\234\237.png" rename to "zh-cn/device-dev/kernel/figure/\346\214\211\346\214\207\345\256\232\346\240\274\345\274\217\346\211\223\345\215\260\347\263\273\347\273\237\346\227\245\346\234\237.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\226\207\344\273\266\347\263\273\347\273\237\346\240\221\345\275\242\347\273\223\346\236\204.png" "b/zh-cn/device-dev/kernel/figure/\346\226\207\344\273\266\347\263\273\347\273\237\346\240\221\345\275\242\347\273\223\346\236\204.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\226\207\344\273\266\347\263\273\347\273\237\346\240\221\345\275\242\347\273\223\346\236\204.png" rename to "zh-cn/device-dev/kernel/figure/\346\226\207\344\273\266\347\263\273\347\273\237\346\240\221\345\275\242\347\273\223\346\236\204.png" diff --git "a/zh-cn/device-dev/kernel/figure/\346\227\245\345\277\227\346\226\271\345\274\217\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\346\227\245\345\277\227\346\226\271\345\274\217\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..caf4127a296227a121ef155f9354d1f3ef3837dd Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\346\227\245\345\277\227\346\226\271\345\274\217\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213-0.png" "b/zh-cn/device-dev/kernel/figure/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213-17.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213-0.png" rename to "zh-cn/device-dev/kernel/figure/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213-17.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213.png" "b/zh-cn/device-dev/kernel/figure/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213.png" rename to "zh-cn/device-dev/kernel/figure/\346\230\276\347\244\272\347\273\223\346\236\234\345\246\202\344\270\213.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\344\277\241\346\201\257.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\344\277\241\346\201\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\344\277\241\346\201\257.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213-hello-harmony-txt-\346\226\207\344\273\266\347\232\204\344\277\241\346\201\257.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\345\275\223\345\211\215\347\263\273\347\273\237\350\267\257\345\276\204\344\270\213\347\232\204\347\233\256\345\275\225-\346\230\276\347\244\272\347\232\204\345\206\205\345\256\271\345\246\202\344\270\213.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\345\275\223\345\211\215\347\263\273\347\273\237\350\267\257\345\276\204\344\270\213\347\232\204\347\233\256\345\275\225-\346\230\276\347\244\272\347\232\204\345\206\205\345\256\271\345\246\202\344\270\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\345\275\223\345\211\215\347\263\273\347\273\237\350\267\257\345\276\204\344\270\213\347\232\204\347\233\256\345\275\225-\346\230\276\347\244\272\347\232\204\345\206\205\345\256\271\345\246\202\344\270\213.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\345\275\223\345\211\215\347\263\273\347\273\237\350\267\257\345\276\204\344\270\213\347\232\204\347\233\256\345\275\225-\346\230\276\347\244\272\347\232\204\345\206\205\345\256\271\345\246\202\344\270\213.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\345\275\223\345\211\215\350\267\257\345\276\204.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\345\275\223\345\211\215\350\267\257\345\276\204.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\345\275\223\345\211\215\350\267\257\345\276\204.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\345\275\223\345\211\215\350\267\257\345\276\204.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\347\211\251\347\220\206\351\241\265\344\275\277\347\224\250\346\203\205\345\206\265.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\347\211\251\347\220\206\351\241\265\344\275\277\347\224\250\346\203\205\345\206\265.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\347\211\251\347\220\206\351\241\265\344\275\277\347\224\250\346\203\205\345\206\265.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\347\211\251\347\220\206\351\241\265\344\275\277\347\224\250\346\203\205\345\206\265.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\347\263\273\347\273\237\350\265\204\346\272\220\344\275\277\347\224\250\346\203\205\345\206\265.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\347\263\273\347\273\237\350\265\204\346\272\220\344\275\277\347\224\250\346\203\205\345\206\265.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\347\263\273\347\273\237\350\265\204\346\272\220\344\275\277\347\224\250\346\203\205\345\206\265.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\347\263\273\347\273\237\350\265\204\346\272\220\344\275\277\347\224\250\346\203\205\345\206\265.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\350\277\233\347\250\213PID.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\350\277\233\347\250\213PID.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\347\234\213\350\277\233\347\250\213PID.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\347\234\213\350\277\233\347\250\213PID.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\344\273\273\345\212\241\351\203\250\345\210\206\344\277\241\346\201\257.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\344\273\273\345\212\241\351\203\250\345\210\206\344\277\241\346\201\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\344\273\273\345\212\241\351\203\250\345\210\206\344\277\241\346\201\257.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\344\273\273\345\212\241\351\203\250\345\210\206\344\277\241\346\201\257.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\345\257\271\345\272\224-ID-\347\232\204\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\344\277\241\346\201\257.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\345\257\271\345\272\224-ID-\347\232\204\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\344\277\241\346\201\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\345\257\271\345\272\224-ID-\347\232\204\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\344\277\241\346\201\257.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\345\257\271\345\272\224-ID-\347\232\204\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\344\277\241\346\201\257.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\346\211\200\346\234\211\345\234\250\347\224\250\347\232\204\344\277\241\345\217\267\351\207\217\344\277\241\346\201\257.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\346\211\200\346\234\211\345\234\250\347\224\250\347\232\204\344\277\241\345\217\267\351\207\217\344\277\241\346\201\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\346\211\200\346\234\211\345\234\250\347\224\250\347\232\204\344\277\241\345\217\267\351\207\217\344\277\241\346\201\257.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\346\211\200\346\234\211\345\234\250\347\224\250\347\232\204\344\277\241\345\217\267\351\207\217\344\277\241\346\201\257.png" diff --git "a/zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\346\211\200\346\234\211\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\347\233\270\345\205\263\344\277\241\346\201\257.png" "b/zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\346\211\200\346\234\211\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\347\233\270\345\205\263\344\277\241\346\201\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\346\237\245\350\257\242\346\211\200\346\234\211\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\347\233\270\345\205\263\344\277\241\346\201\257.png" rename to "zh-cn/device-dev/kernel/figure/\346\237\245\350\257\242\346\211\200\346\234\211\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250\347\233\270\345\205\263\344\277\241\346\201\257.png" diff --git "a/zh-cn/device-dev/kernel/figures/\347\224\250-rm--r-\345\210\240\351\231\244\347\233\256\345\275\225-sd.png" "b/zh-cn/device-dev/kernel/figure/\347\224\250-rm--r-\345\210\240\351\231\244\347\233\256\345\275\225-sd.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\347\224\250-rm--r-\345\210\240\351\231\244\347\233\256\345\275\225-sd.png" rename to "zh-cn/device-dev/kernel/figure/\347\224\250-rm--r-\345\210\240\351\231\244\347\233\256\345\275\225-sd.png" diff --git "a/zh-cn/device-dev/kernel/figures/\347\224\250-rm-\345\221\275\344\273\244\345\210\240\351\231\244\346\226\207\344\273\266-log1-txt.png" "b/zh-cn/device-dev/kernel/figure/\347\224\250-rm-\345\221\275\344\273\244\345\210\240\351\231\244\346\226\207\344\273\266-log1-txt.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\347\224\250-rm-\345\221\275\344\273\244\345\210\240\351\231\244\346\226\207\344\273\266-log1-txt.png" rename to "zh-cn/device-dev/kernel/figure/\347\224\250-rm-\345\221\275\344\273\244\345\210\240\351\231\244\346\226\207\344\273\266-log1-txt.png" diff --git "a/zh-cn/device-dev/kernel/figures/\347\272\277\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\347\272\277\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\347\272\277\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" rename to "zh-cn/device-dev/kernel/figure/\347\272\277\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" diff --git "a/zh-cn/device-dev/kernel/figures/\350\276\223\345\205\245-telnet-on.png" "b/zh-cn/device-dev/kernel/figure/\350\276\223\345\205\245-telnet-on.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\350\276\223\345\205\245-telnet-on.png" rename to "zh-cn/device-dev/kernel/figure/\350\276\223\345\205\245-telnet-on.png" diff --git "a/zh-cn/device-dev/kernel/figures/\350\277\233\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\350\277\233\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figures/\350\277\233\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" rename to "zh-cn/device-dev/kernel/figure/\350\277\233\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" diff --git "a/zh-cn/device-dev/kernel/figure/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figure/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..f7ffdd153fcfffcc4fdf97a51b66c11c502c6a9c Binary files /dev/null and "b/zh-cn/device-dev/kernel/figure/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/zh-cn/device-dev/kernel/figures/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figures/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index 7cc6c5fa458d60bdf1ad1d7494ab3982adc8d1f0..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git "a/zh-cn/device-dev/kernel/figures/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figures/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index cf0684595b4e7b07dfebf6c55c867a97e1e71663..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git "a/zh-cn/device-dev/kernel/figures/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figures/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index fc4591567b7f1643e1c065df5860af3e7aff2a3b..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git "a/zh-cn/device-dev/kernel/figures/\345\206\205\346\240\270\345\220\257\345\212\250\346\265\201\347\250\213.png" "b/zh-cn/device-dev/kernel/figures/\345\206\205\346\240\270\345\220\257\345\212\250\346\265\201\347\250\213.png" deleted file mode 100644 index cb86acd9c05059302f21ac10a3d8604b6e742652..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\345\206\205\346\240\270\345\220\257\345\212\250\346\265\201\347\250\213.png" and /dev/null differ diff --git "a/zh-cn/device-dev/kernel/figures/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" "b/zh-cn/device-dev/kernel/figures/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" deleted file mode 100644 index c32b7cf60be9ed557f5c3139aed303b105a4e2d9..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" and /dev/null differ diff --git "a/zh-cn/device-dev/kernel/figures/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276.png" "b/zh-cn/device-dev/kernel/figures/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276.png" deleted file mode 100644 index 96a1c33d124ad5cd67afa331154840ad7b59c9ab..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276.png" and /dev/null differ diff --git "a/zh-cn/device-dev/kernel/figures/\345\240\206\346\240\210\345\210\206\346\236\220\345\216\237\347\220\206\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figures/\345\240\206\346\240\210\345\210\206\346\236\220\345\216\237\347\220\206\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index ce4103b3f82838d3593e7d04523b402b4283effa..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\345\240\206\346\240\210\345\210\206\346\236\220\345\216\237\347\220\206\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git "a/zh-cn/device-dev/kernel/figures/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/kernel/figures/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index b21c09ee49ceda81474ce085aae1f67feea17f3a..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/kernel/figures/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git a/zh-cn/device-dev/kernel/format.md b/zh-cn/device-dev/kernel/format.md deleted file mode 100755 index ecddf4e03134b2a3a3503bd30d1c7f3a26989ad7..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/format.md +++ /dev/null @@ -1,69 +0,0 @@ -# format - -- [命令功能](#section1922331919169) -- [命令格式](#section249226169) -- [参数说明](#section985173416177) -- [使用指南](#section1510162714162) -- [使用实例](#section25691431161611) -- [输出说明](#section17368112365920) - -## 命令功能 - -format指令用于格式化磁盘。 - -## 命令格式 - -format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

dev_inodename

-

设备名。

-

sectors

-

分配的单元内存或扇区大小,如果输入0表示参数为空。(取值必须为0或2的幂,fat32下最大值为128,取值0表示自动选择合适的簇大小,不同size的分区,可用的簇大小范围不同,错误的簇大小指定可能导致格式化失败)。

-

option

-
格式化选项,用来选择文件系统的类型,有如下几种参数选择:
  • 0x01:FMT_FAT
  • 0x02:FMT_FAT32
  • 0x07:FMT_ANY
  • 0x08:FMT_ERASE (USB不支持该选项)
-
-

传入其他值皆为非法值,将由系统自动选择格式化方式。若格式化U盘时低格位为 1,会出现错误打印。

-

label

-

该参数为可选参数,输入值应为字符串,用来指定卷标名。当输入字符串"null"时,则把之前设置的卷标名清空。

-
- -## 使用指南 - -- format指令用于格式化磁盘,设备名可以在dev目录下查找。format时必须安装存储卡。 -- format只能格式化U盘、sd和mmc卡,对Nand flash和Nor flash格式化不起作用。 -- sectors参数必须传入合法值,传入非法参数可能引发异常。 - -## 使用实例 - -举例:输入format /dev/mmcblk0 128 2 - -## 输出说明 - -结果如下 - -![](figures/zh-cn_image_0000001052370307.png) - diff --git a/zh-cn/device-dev/kernel/free.md b/zh-cn/device-dev/kernel/free.md deleted file mode 100755 index 56734efb792eaa38e825d4cfd42edcd6baf12b0f..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/free.md +++ /dev/null @@ -1,119 +0,0 @@ -# free - -- [命令功能](#section175151514841) -- [命令格式](#section8488721749) -- [参数说明](#section27272181949) -- [使用指南](#section148661259410) -- [使用实例](#section68081530242) -- [输出说明](#section171235517543) - -## 命令功能 - -free命令可显示系统内存的使用情况,同时显示系统的text段、data段、rodata段、bss段大小。 - -## 命令格式 - -free \[_-k | -m_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

无参数

-

以Byte为单位显示。

-

N/A

-

-k

-

以KB为单位显示。

-

N/A

-

-m

-

以MB为单位显示。

-

N/A

-
- -## 使用指南 - -无。 - -## 使用实例 - -举例:分别输入free、free -k、free -m. - -## 输出说明 - -**图 1** 以三种方式显示内存使用情况 -![](figures/以三种方式显示内存使用情况.png "以三种方式显示内存使用情况") - -**表 2** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

total

-

表示系统动态内存池总量。

-

used

-

表示已使用内存总量。

-

free

-

表示未被分配的内存大小。

-

heap

-

表示已分配堆大小。

-

text

-

表示代码段大小。

-

data

-

表示数据段大小。

-

rodata

-

表示只读数据段大小。

-

bss

-

表示未初始化全局变量占用内存大小。

-
- diff --git a/zh-cn/device-dev/kernel/hwi.md b/zh-cn/device-dev/kernel/hwi.md deleted file mode 100755 index d2ab70ddb335746aaba995bc090b946b4217d45b..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/hwi.md +++ /dev/null @@ -1,94 +0,0 @@ -# hwi - -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) - -## 命令功能 - -hwi命令查询当前中断信息 - -## 命令格式 - -hwi - -## 参数说明 - -无。 - -## 使用指南 - -- 输入hwi即显示当前中断号、中断次数及注册中断名称。 -- 若开关LOSCFG\_CPUP\_INCLUDE\_IRQ打开,则还会显示各个中断的处理时间(cycles)、CPU占用率以及中断类型。 - -## 使用实例 - -举例:输入hwi - -## 输出说明 - -1. 显示中断信息(LOSCFG\_CPUP\_INCLUDE\_IRQ关闭) - - ![](figures/zh-cn_image_0000001053826366.png) - -2. 显示中断信息(LOSCFG\_CPUP\_INCLUDE\_IRQ打开) - - ![](figures/zh-cn_image_0000001052810304.png) - - **表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

InterruptNo

-

中断号。

-

Count

-

中断次数。

-

Name

-

注册中断名称。

-

CYCLECOST

-

中断的处理时间(cycles)。

-

CPUUSE

-

CPU占用率。

-

CPUUSE10s

-

最近10s CPU占用率。

-

CPUUSE1s

-

最近1s CPU占用率。

-

mode

-

中断类型:

-
  • normal: 非共享中断。
  • shared: 共享中断。
-
- - diff --git a/zh-cn/device-dev/kernel/kernel-lite-basic-mini-time.md b/zh-cn/device-dev/kernel/kernel-lite-basic-mini-time.md new file mode 100644 index 0000000000000000000000000000000000000000..1cded0a67f9982198d4b112d092b821657d51b1b --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-basic-mini-time.md @@ -0,0 +1,7 @@ +# 时间管理 + +- **[基本概念](kernel-lite-mini-basic-time-basic.md)** + +- **[开发指导](kernel-lite-mini-basic-time-guide.md)** + + diff --git "a/zh-cn/device-dev/kernel/\345\206\205\346\240\270\347\274\226\347\240\201\350\247\204\350\214\203.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-app-code.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\206\205\346\240\270\347\274\226\347\240\201\350\247\204\350\214\203.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-app-code.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-app-data-list.md b/zh-cn/device-dev/kernel/kernel-lite-mini-app-data-list.md new file mode 100644 index 0000000000000000000000000000000000000000..d219cc86b000959550b333309dcacc0aca028c30 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-app-data-list.md @@ -0,0 +1,191 @@ +# 双向链表 + +- [基本概念](#section1990715203418) +- [功能说明](#section848334511411) +- [开发流程](#section01781261552) +- [编程实例](#section67569495514) + - [实例描述](#section48761994551) + - [示例代码](#section1280202685519) + - [结果验证](#section5811249105512) + + +## 基本概念 + +双向链表是指含有往前和往后两个方向的链表,即每个结点中除存放下一个节点指针外,还增加一个指向前一个节点的指针。其头指针head是唯一确定的。 + +从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点,这种数据结构形式使得双向链表在查找时更加方便,特别是大量数据的遍历。由于双向链表具有对称性,能方便地完成各种插入、删除等操作,但需要注意前后方向的操作。 + +## 功能说明 + +双向链表模块为用户提供下面几种功能,接口详细信息可以查看API参考。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

初始化链表

+

LOS_ListInit

+

将指定双向链表节点初始化为双向链表

+

LOS_DL_LIST_HEAD

+

定义一个双向链表节点并以该节点初始化为双向链表

+

增加节点

+

LOS_ListAdd

+

将指定节点插入到双向链表头端

+

LOS_ListTailInsert

+

将指定节点插入到双向链表尾端

+

删除节点

+

LOS_ListDelete

+

将指定节点从链表中删除

+

LOS_ListDelInit

+

将指定节点从链表中删除,并使用该节点初始化链表

+

判断双向链表是否为空

+

LOS_ListEmpty

+

判断链表是否为空

+

获取结构体信息

+

LOS_DL_LIST_ENTRY

+

获取包含链表的结构体地址,接口的第一个入参表示的是链表中的某个节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称

+

LOS_OFF_SET_OF

+

获取指定结构体内的成员相对于结构体起始地址的偏移量

+

遍历双向链表

+

LOS_DL_LIST_FOR_EACH

+

遍历双向链表

+

LOS_DL_LIST_FOR_EACH_SAFE

+

遍历双向链表,并存储当前节点的后继节点用于安全校验

+

遍历包含双向链表的结构体

+

LOS_DL_LIST_FOR_EACH_ENTRY

+

遍历指定双向链表,获取包含该链表节点的结构体地址

+

LOS_DL_LIST_FOR_EACH_ENTRY_SAFE

+

遍历指定双向链表,获取包含该链表节点的结构体地址,并存储包含当前节点的后继节点的结构体地址

+
+ +## 开发流程 + +双向链表的典型开发流程: + +1. 调用LOS\_ListInit/LOS\_DL\_LIST\_HEAD初始双向链表。 +2. 调用LOS\_ListAdd向链表插入节点。 +3. 调用LOS\_ListTailInsert向链表尾部插入节点。 +4. 调用LOS\_ListDelete删除指定节点。 +5. 调用LOS\_ListEmpty判断链表是否为空。 +6. 调用LOS\_ListDelInit删除指定节点并以此节点初始化链表。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 需要注意节点指针前后方向的操作。 +>- 链表操作接口,为底层接口,不对入参进行判空,需要使用者确保传参合法。 +>- 如果链表节点的内存是动态申请的,删除节点时,要注意释放内存。 + +## 编程实例 + +### 实例描述 + +本实例实现如下功能: + +1. 初始化双向链表。 +2. 增加节点。 +3. 删除节点。 +4. 测试操作是否成功。 + +### 示例代码 + +示例代码如下: + +``` +#include "stdio.h" +#include "los_list.h" + +static UINT32 ListSample(VOID) +{ + LOS_DL_LIST listHead = {NULL,NULL}; + LOS_DL_LIST listNode1 = {NULL,NULL}; + LOS_DL_LIST listNode2 = {NULL,NULL}; + + //首先初始化链表 + printf("Initial head\n"); + LOS_ListInit(&listHead); + + //添加节点1和节点2,并校验他们的相互关系 + LOS_ListAdd(&listHead, &listNode1); + if (listNode1.pstNext == &listHead && listNode1.pstPrev == &listHead) { + printf("Add listNode1 success\n"); + } + + LOS_ListTailInsert(&listHead, &listNode2); + if (listNode2.pstNext == &listHead && listNode2.pstPrev == &listNode1) { + printf("Tail insert listNode2 success\n"); + } + + //删除两个节点 + LOS_ListDelete(&listNode1); + LOS_ListDelete(&listNode2); + + //确认链表为空 + if (LOS_ListEmpty(&listHead)) { + printf("Delete success\n"); + } + + return LOS_OK; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +Initial head +Add listNode1 success +Tail insert listNode2 success +Delete success +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-app-data.md b/zh-cn/device-dev/kernel/kernel-lite-mini-app-data.md new file mode 100644 index 0000000000000000000000000000000000000000..78fda11861f02826b54e3ba8f97ef0f9308d413f --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-app-data.md @@ -0,0 +1,5 @@ +# 基本数据结构 + +- **[双向链表](kernel-lite-mini-app-data-list.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-app-lib-cmsis.md b/zh-cn/device-dev/kernel/kernel-lite-mini-app-lib-cmsis.md new file mode 100644 index 0000000000000000000000000000000000000000..fb77b086298240bc85ad0755df727f0b3a844b3c --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-app-lib-cmsis.md @@ -0,0 +1,487 @@ +# CMSIS支持 + +- [基本概念](#section131091144111615) +- [开发指导](#section57653573161) + - [接口说明](#section1795910417173) + - [开发流程](#section48301225131720) + - [编程实例](#section524434761713) + + +## 基本概念 + +[CMSIS](https://developer.arm.com/tools-and-software/embedded/cmsis)是Cortex Microcontroller Software Interface Standard(Cortex微控制器软件接口标准)的缩写,是对于那些基于ARM Cortex处理器的微控制器独立于供应商的硬件抽象层。它包含多个组件层,其中之一是RTOS层,该层定义了一套通用及标准化的RTOS API接口,减少了应用开发者对特定RTOS的依赖,方便用户软件的移植重用。该套API有2个版本,分别为版本1(CMSIS-RTOS v1)和版本2(CMSIS-RTOS v2),OpenHarmony LiteOS-M仅提供其版本2的实现。 + +## 开发指导 + +### 接口说明 + +CMSIS-RTOS v2提供下面几种功能,接口详细信息可以查看API参考。 + +**表 1** CMSIS-RTOS v2接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

内核信息与控制

+

osKernelGetInfo

+

获取RTOS内核信息。

+

osKernelGetState

+

获取当前的RTOS内核状态。

+

osKernelGetSysTimerCount

+

获取RTOS内核系统计时器计数。

+

osKernelGetSysTimerFreq

+

获取RTOS内核系统计时器频率。

+

osKernelInitialize

+

初始化RTOS内核。

+

osKernelLock

+

锁定RTOS内核调度程序。

+

osKernelUnlock

+

解锁RTOS内核调度程序。

+

osKernelRestoreLock

+

恢复RTOS内核调度程序锁定状态。

+

osKernelResume

+

恢复RTOS内核调度程序。(暂未实现)

+

osKernelStart

+

启动RTOS内核调度程序。

+

osKernelSuspend

+

挂起RTOS内核调度程序。(暂未实现)

+

osKernelGetTickCount

+

获取RTOS内核滴答计数。

+

osKernelGetTickFreq

+

获取RTOS内核滴答频率。

+

线程管理

+

osThreadDetach

+

分离线程(线程终止时可以回收线程存储)。(暂未实现)

+

osThreadEnumerate

+

枚举活动线程。(暂未实现)

+

osThreadExit

+

终止当前正在运行的线程的执行。

+

osThreadGetCount

+

获取活动线程的数量。

+

osThreadGetId

+

返回当前正在运行的线程的线程ID。

+

osThreadGetName

+

获取线程的名称。

+

osThreadGetPriority

+

获取线程的当前优先级。

+

osThreadGetStackSize

+

获取线程的堆栈大小。

+

osThreadGetStackSpace

+

根据执行期间的堆栈水印记录获取线程的可用堆栈空间。

+

osThreadGetState

+

获取线程的当前线程状态。

+

osThreadJoin

+

等待指定线程终止。(暂未实现)

+

osThreadNew

+

创建一个线程并将其添加到活动线程中。

+

osThreadResume

+

恢复线程的执行。

+

osThreadSetPriority

+

更改线程的优先级。

+

osThreadSuspend

+

暂停执行线程。

+

osThreadTerminate

+

终止线程的执行。

+

osThreadYield

+

将控制权传递给处于就绪状态的下一个线程。

+

线程标志

+

osThreadFlagsSet

+

设置线程的指定线程标志。(暂未实现)

+

osThreadFlagsClear

+

清除当前正在运行的线程的指定线程标志。(暂未实现)

+

osThreadFlagsGet

+

获取当前正在运行的线程的当前线程标志。(暂未实现)

+

osThreadFlagsWait

+

等待当前正在运行的线程的一个或多个线程标志发出信号。(暂未实现)

+

事件标志

+

osEventFlagsGetName

+

获取事件标志对象的名称。(暂未实现)

+

osEventFlagsNew

+

创建并初始化事件标志对象。

+

osEventFlagsDelete

+

删除事件标志对象。

+

osEventFlagsSet

+

设置指定的事件标志。

+

osEventFlagsClear

+

清除指定的事件标志。

+

osEventFlagsGet

+

获取当前事件标志。

+

osEventFlagsWait

+

等待一个或多个事件标志被发出信号。

+

通用等待函数

+

osDelay

+

等待超时(时间延迟)。

+

osDelayUntil

+

等到指定时间。

+

计时器管理

+

osTimerDelete

+

删除计时器。

+

osTimerGetName

+

获取计时器的名称。(暂未实现)

+

osTimerIsRunning

+

检查计时器是否正在运行。

+

osTimerNew

+

创建和初始化计时器。

+

osTimerStart

+

启动或重新启动计时器。

+

osTimerStop

+

停止计时器。

+

互斥管理

+

osMutexAcquire

+

获取互斥或超时(如果已锁定)。

+

osMutexDelete

+

删除互斥对象。

+

osMutexGetName

+

获取互斥对象的名称。(暂未实现)

+

osMutexGetOwner

+

获取拥有互斥对象的线程。

+

osMutexNew

+

创建并初始化Mutex对象。

+

osMutexRelease

+

释放由osMutexAcquire获取的Mutex。

+

信号量

+

osSemaphoreAcquire

+

获取信号量令牌或超时(如果没有可用的令牌)。

+

osSemaphoreDelete

+

删除一个信号量对象。

+

osSemaphoreGetCount

+

获取当前信号量令牌计数。

+

osSemaphoreGetName

+

获取信号量对象的名称。(暂未实现)

+

osSemaphoreNew

+

创建并初始化一个信号量对象。

+

osSemaphoreRelease

+

释放信号量令牌,直到初始最大计数。

+

内存池

+

osMemoryPoolAlloc

+

从内存池分配一个内存块。

+

osMemoryPoolDelete

+

删除内存池对象。

+

osMemoryPoolFree

+

将分配的内存块返回到内存池。

+

osMemoryPoolGetBlockSize

+

获取内存池中的内存块大小。

+

osMemoryPoolGetCapacity

+

获取内存池中最大的内存块数。

+

osMemoryPoolGetCount

+

获取内存池中使用的内存块数。

+

osMemoryPoolGetName

+

获取内存池对象的名称。

+

osMemoryPoolGetSpace

+

获取内存池中可用的内存块数。

+

osMemoryPoolNew

+

创建并初始化一个内存池对象。

+

消息队列

+

osMessageQueueDelete

+

删除消息队列对象。

+

osMessageQueueGet

+

从队列获取消息,或者如果队列为空,则从超时获取消息。

+

osMessageQueueGetCapacity

+

获取消息队列中的最大消息数。

+

osMessageQueueGetCount

+

获取消息队列中排队的消息数。

+

osMessageQueueGetMsgSize

+

获取内存池中的最大消息大小。

+

osMessageQueueGetName

+

获取消息队列对象的名称。(暂未实现)

+

osMessageQueueGetSpace

+

获取消息队列中消息的可用插槽数。

+

osMessageQueueNew

+

创建和初始化消息队列对象。

+

osMessageQueuePut

+

如果队列已满,则将消息放入队列或超时。

+

osMessageQueueReset

+

将消息队列重置为初始空状态。(暂未实现)

+
+ +### 开发流程 + +CMSIS-RTOS2组件可以作为库或源代码提供(下图显示了库)。通过添加CMSIS-RTOS2组件(通常是一些配置文件),可以将基于CMSIS的应用程序扩展为具有RTOS功能。只需包含cmsis\_os2.h头文件就可以访问RTOS API函数,这使用户应用程序能够处理RTOS内核相关事件,而在更换内核时无需重新编译源代码。 + +静态对象分配需要访问RTOS对象控制块定义。特定于实现的头文件(下图中的os\_xx .h)提供对此类控制块定义的访问。对于OpenHarmony LiteOS-M内核,由文件名以los\_开头的头文件提供,这些文件包含OpenHarmony LiteOS-M内核的这些定义。 + +![](figure/zh-cn_image_0000001132778524.png) + +### 编程实例 + +``` +#include ... +#include "cmsis_os2.h" + +/*---------------------------------------------------------------------------- + * 应用程序主线程 + *---------------------------------------------------------------------------*/ +void app_main (void *argument) { + // ... + for (;;) {} +} + +int main (void) { + // 系统初始化 + MySystemInit(); + // ... + + osKernelInitialize(); // 初始化CMSIS-RTOS + osThreadNew(app_main, NULL, NULL); // 创建应用程序主线程 + osKernelStart(); // 开始执行线程 + for (;;) {} +} +``` + diff --git "a/zh-cn/device-dev/kernel/POSIX\346\224\257\346\214\201.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-app-lib-posix.md similarity index 100% rename from "zh-cn/device-dev/kernel/POSIX\346\224\257\346\214\201.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-app-lib-posix.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-app-lib.md b/zh-cn/device-dev/kernel/kernel-lite-mini-app-lib.md new file mode 100644 index 0000000000000000000000000000000000000000..b2f157ae194d8a266d79477623dd40191882f753 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-app-lib.md @@ -0,0 +1,7 @@ +# 标准库支持 + +- **[CMSIS支持](kernel-lite-mini-app-lib-cmsis.md)** + +- **[POSIX支持](kernel-lite-mini-app-lib-posix.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-app.md b/zh-cn/device-dev/kernel/kernel-lite-mini-app.md new file mode 100644 index 0000000000000000000000000000000000000000..1d46fa1186b838599b3ec26dbc154a99ff20a111 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-app.md @@ -0,0 +1,9 @@ +# 附录 + +- **[内核编码规范](kernel-lite-mini-app-code.md)** + +- **[基本数据结构](kernel-lite-mini-app-data.md)** + +- **[标准库支持](kernel-lite-mini-app-lib.md)** + + diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt-concept.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt-concept.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..346332358b3a116c07f195a0b5013617d500ef57 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt-guide.md @@ -0,0 +1,130 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section11841123033618) +- [编程实例](#section460018317164) + - [结果验证](#section1048572415182) + + +当产生中断请求时,CPU暂停当前的任务,转而去响应外设请求。用户可以根据需要注册对应的中断处理程序,指定CPU响应中断请求时所执行的具体操作。 + +## 接口说明 + +OpenHarmony LiteOS-M内核的中断模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表 1** 中断模块接口 + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

创建、删除中断

+

HalHwiCreate

+

中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,会调用该中断处理程序。

+

HalHwiDelete

+

根据指定的中断号,删除中断。

+

打开、关闭中断

+

LOS_IntUnLock

+

开中断,使能当前处理器所有中断响应。

+

LOS_IntLock

+

关中断,关闭当前处理器所有中断响应。

+

LOS_IntRestore

+

恢复到使用LOS_IntLock、LOS_IntUnLock操作之前的中断状态。

+
+ +## 开发流程 + +1. 调用中断创建接口HalHwiCreate创建中断。 +2. 调用TestHwiTrigger接口触发指定中断(该接口在测试套中定义,通过写中断控制器的相关寄存器模拟外部中断,一般的外设设备,不需要执行这一步)。 +3. 调用HalHwiDelete接口删除指定中断,此接口根据实际情况使用,判断是否需要删除中断。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 根据具体硬件,配置支持的最大中断数及可设置的中断优先级个数。 +>- 中断处理程序耗时不能过长,否则会影响CPU对中断的及时响应。 +>- 中断响应过程中不能直接、间接执行引起调度的LOS\_Schedule等函数。 +>- 中断恢复LOS\_IntRestore\(\)的入参必须是与之对应的LOS\_IntLock\(\)的返回值(即关中断之前的CPSR值)。Cortex-M系列处理器中0-15中断为内部使用,因此不建议用户去申请和创建。 + +## 编程实例 + +本实例实现如下功能: + +1. 创建中断。 +2. 触发中断。 +3. 删除中断。 + +代码实现如下,演示如何创建中断和删除中断,当指定的中断号HWI\_NUM\_TEST产生中断时,会调用中断处理函数: + +``` +#include "los_interrupt.h" + +/*创建中断*/ +#define HWI_NUM_TEST 7 + +STATIC VOID HwiUsrIrq(VOID) +{ + printf("in the func HwiUsrIrq \n"); +} + +static UINT32 Example_Interrupt(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + /*创建中断*/ + ret = HalHwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, arg); + if(ret == LOS_OK){ + printf("Hwi create success!\n"); + } else { + printf("Hwi create failed!\n"); + return LOS_NOK; + } + + /* 延时50个Ticks, 当有硬件中断发生时,会调用函数HwiUsrIrq*/ + LOS_TaskDelay(50); + + /*删除中断*/ + ret = HalHwiDelete(HWI_NUM_TEST); + if(ret == LOS_OK){ + printf("Hwi delete success!\n"); + } else { + printf("Hwi delete failed!\n"); + return LOS_NOK; + } + return LOS_OK; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +Hwi create success! +Hwi delete success!. +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt.md new file mode 100644 index 0000000000000000000000000000000000000000..3b10c0482f68e943142f978ef11aac6d5c536b4e --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-interrupt.md @@ -0,0 +1,7 @@ +# 中断管理 + +- **[基本概念](kernel-lite-mini-basic-interrupt-concept.md)** + +- **[开发指导](kernel-lite-mini-basic-interrupt-guide.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event-basic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..91a6c20c0e1a5260d405a66966c859bc36cb290c --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event-basic.md @@ -0,0 +1,194 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section783435801510) +- [编程实例](#section460018317164) + - [实例描述](#section896412438910) + - [示例代码](#section149077554912) + - [结果验证](#section4461439172017) + + +## 接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

事件检测

+

LOS_EventPoll

+

根据eventID,eventMask(事件掩码),mode(事件读取模式),检查用户期待的事件是否发生。

+
须知:

当mode含LOS_WAITMODE_CLR,且用户期待的事件发生时,此时eventID中满足要求的事件会被清零,这种情况下eventID既是入参也是出参。其他情况eventID只作为入参。

+
+

初始化

+

LOS_EventInit

+

事件控制块初始化。

+

事件读

+

LOS_EventRead

+

读事件(等待事件),任务会根据timeOut(单位:tick)进行阻塞等待;

+

未读取到事件时,返回值为0;

+

正常读取到事件时,返回正值(事件发生的集合);

+

其他情况返回特定错误码。

+

事件写

+

LOS_EventWrite

+

写一个特定的事件到事件控制块。

+

事件清除

+

LOS_EventClear

+

根据events掩码,清除事件控制块中的事件。

+

事件销毁

+

LOS_EventDestroy

+

事件控制块销毁。

+
+ +## 开发流程 + +事件的典型开发流程: + +1. 初始化事件控制块 +2. 阻塞读事件控制块 +3. 写入相关事件 +4. 阻塞任务被唤醒,读取事件并检查是否满足要求 +5. 处理事件控制块 +6. 事件控制块销毁 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 进行事件读写操作时,事件的第25位为保留位,不可以进行位设置。 +>- 对同一事件反复写入,算作一次写入。 + +## 编程实例 + +### 实例描述 + +示例中,任务Example\_TaskEntry创建一个任务Example\_Event,Example\_Event读事件阻塞,Example\_TaskEntry向该任务写事件。可以通过示例日志中打印的先后顺序理解事件操作时伴随的任务切换。 + +1. 在任务Example\_TaskEntry创建任务Example\_Event,其中任务Example\_Event优先级高于Example\_TaskEntry。 +2. 在任务Example\_Event中读事件0x00000001,阻塞,发生任务切换,执行任务Example\_TaskEntry。 +3. 在任务Example\_TaskEntry向任务Example\_Event写事件0x00000001,发生任务切换,执行任务Example\_Event。 +4. Example\_Event得以执行,直到任务结束。 +5. Example\_TaskEntry得以执行,直到任务结束。 + +### 示例代码 + +示例代码如下: + +``` +#include "los_event.h" +#include "los_task.h" +#include "securec.h" + +/* 任务ID */ +UINT32 g_testTaskId; + +/* 事件控制结构体 */ +EVENT_CB_S g_exampleEvent; + +/* 等待的事件类型 */ +#define EVENT_WAIT 0x00000001 + +/* 用例任务入口函数 */ +VOID Example_Event(VOID) +{ + UINT32 ret; + UINT32 event; + + /* 超时等待方式读事件,超时时间为100 ticks, 若100 ticks后未读取到指定事件,读事件超时,任务直接唤醒 */ + printf("Example_Event wait event 0x%x \n", EVENT_WAIT); + + event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, 100); + if (event == EVENT_WAIT) { + printf("Example_Event,read event :0x%x\n", event); + } else { + printf("Example_Event,read event timeout\n"); + } +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + + /* 事件初始化 */ + ret = LOS_EventInit(&g_exampleEvent); + if (ret != LOS_OK) { + printf("init event failed .\n"); + return -1; + } + + /* 创建任务 */ + (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; + task1.pcName = "EventTsk1"; + task1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId, &task1); + if (ret != LOS_OK) { + printf("task create failed.\n"); + return LOS_NOK; + } + + /* 写g_testTaskId 等待事件 */ + printf("Example_TaskEntry write event.\n"); + + ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); + if (ret != LOS_OK) { + printf("event write failed.\n"); + return LOS_NOK; + } + + /* 清标志位 */ + printf("EventMask:%d\n", g_exampleEvent.uwEventID); + LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); + printf("EventMask:%d\n", g_exampleEvent.uwEventID); + + /* 删除任务 */ + ret = LOS_TaskDelete(g_testTaskId); + if (ret != LOS_OK) { + printf("task delete failed.\n"); + return LOS_NOK; + } + + return LOS_OK; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +Example_Event wait event 0x1 +Example_TaskEntry write event. +Example_Event,read event :0x1 +EventMask:1 +EventMask:0 +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..47befc62231ddb127477e813a4d104f0b9d2f1be --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event-guide.md @@ -0,0 +1,52 @@ +# 基本概念 + +- [运行机制](#section1735611583011) + - [事件控制块](#section1161415384467) + - [事件运作原理](#section187761153144617) + + +事件(Event)是一种任务间的通信机制,可用于任务间的同步操作。事件的特点是: + +- 任务间的事件同步,可以一对多,也可以多对多。一对多表示一个任务可以等待多个事件,多对多表示多个任务可以等待多个事件。但是一次写事件最多触发一个任务从阻塞中醒来。 +- 事件读超时机制。 +- 只做任务间同步,不传输具体数据。 + +提供了事件初始化、事件读写、事件清零、事件销毁等接口。 + +## 运行机制 + +### 事件控制块 + +``` +/** + * 事件控制块数据结构 + */ +typedef struct tagEvent { + UINT32 uwEventID; /* 事件集合,表示已经处理(写入和清零)的事件集合 */ + LOS_DL_LIST stEventList; /* 等待特定事件的任务链表 */ +} EVENT_CB_S, *PEVENT_CB_S; +``` + +### 事件运作原理 + +**事件初始化:**会创建一个事件控制块,该控制块维护一个已处理的事件集合,以及等待特定事件的任务链表。 + +**写事件:**会向事件控制块写入指定的事件,事件控制块更新事件集合,并遍历任务链表,根据任务等待具体条件满足情况决定是否唤醒相关任务。 + +**读事件:**如果读取的事件已存在时,会直接同步返回。其他情况会根据超时时间以及事件触发情况,来决定返回时机:等待的事件条件在超时时间耗尽之前到达,阻塞任务会被直接唤醒,否则超时时间耗尽该任务才会被唤醒。 + +读事件条件满足与否取决于入参eventMask和mode,eventMask即需要关注的事件。mode是具体处理方式,分以下三种情况: + +LOS\_WAITMODE\_AND:表示eventMask中所有事件都发生时,才返回。 + +LOS\_WAITMODE\_OR:表示eventMask中任何事件发生时,就返回。 + +LOS\_WAITMODE\_CLR:事件读取成功后,对应读取到的事件会被清零。需要配合LOS\_WAITMODE\_AND或者LOS\_WAITMODE\_OR来使用。 + +**事件清零:**根据指定掩码,去对事件控制块的事件集合进行清零操作。当掩码为0时,表示将事件集合全部清零。当掩码为0xffff时,表示不清除任何事件,保持事件集合原状。 + +**事件销毁:**销毁指定的事件控制块。 + +**图 1** 事件运作原理图 +![](figure/事件运作原理图.png "事件运作原理图") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event.md new file mode 100644 index 0000000000000000000000000000000000000000..4f18b0192293cbdfa74b9107939fbe332b9999ce --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-event.md @@ -0,0 +1,7 @@ +# 事件 + +- **[基本概念](kernel-lite-mini-basic-ipc-event-guide.md)** + +- **[开发指导](kernel-lite-mini-basic-ipc-event-basic.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex-basic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..1d2973462485dce46a4a02e8a25396b0670a020f --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex-basic.md @@ -0,0 +1,19 @@ +# 基本概念 + +- [运行机制](#section115161649726) + +互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。 + +任意时刻互斥锁的状态只有两种,开锁或闭锁。当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。当该任务释放它时,该互斥锁被开锁,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。 + +多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。另外互斥锁可以解决信号量存在的优先级翻转问题。 + +## 运行机制 + +多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢? + +用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。 + +**图 1** 互斥锁运作示意图 +![](figure/互斥锁运作示意图.png "互斥锁运作示意图") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..053174daa324f172faeab2d5d47ea6651163c8e7 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex-guide.md @@ -0,0 +1,205 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section783435801510) +- [编程实例](#section1426719434114) + - [实例描述](#section896412438910) + - [示例代码](#section149077554912) + - [结果验证](#section2059413981311) + + +## 接口说明 + +**表 1** 互斥锁模块接口 + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

互斥锁的创建和删除

+

LOS_MuxCreate

+

创建互斥锁

+

LOS_MuxDelete

+

删除指定的互斥锁

+

互斥锁的申请和释放

+

LOS_MuxPend

+

申请指定的互斥锁

+

LOS_MuxPost

+

释放指定的互斥锁

+
+ +## 开发流程 + +互斥锁典型场景的开发流程: + +1. 创建互斥锁LOS\_MuxCreate。 +2. 申请互斥锁LOS\_MuxPend。 + + 申请模式有三种:无阻塞模式、永久阻塞模式、定时阻塞模式。 + + - 无阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有任务持有,或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务,则申请成功。 + - 永久阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该互斥锁,阻塞任务才会重新得以执行。 + - 定时阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该互斥锁,或者用户指定时间超时后,阻塞任务才会重新得以执行。 + +3. 释放互斥锁LOS\_MuxPost。 + - 如果有任务阻塞于指定互斥锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; + - 如果没有任务阻塞于指定互斥锁,则互斥锁释放成功。 + +4. 删除互斥锁LOS\_MuxDelete。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 两个任务不能对同一把互斥锁加锁。如果某任务对已被持有的互斥锁加锁,则该任务会被挂起,直到持有该锁的任务对互斥锁解锁,才能执行对这把互斥锁的加锁操作。 +>- 互斥锁不能在中断服务程序中使用。 +>- LiteOS-M内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。 +>- 持有互斥锁的过程中,不得再调用LOS\_TaskPriSet等接口更改持有互斥锁任务的优先级。 + +## 编程实例 + +### 实例描述 + +本实例实现如下流程。 + +1. 任务Example\_TaskEntry创建一个互斥锁,锁任务调度,创建两个任务Example\_MutexTask1、Example\_MutexTask2。Example\_MutexTask2优先级高于Example\_MutexTask1,解锁任务调度。 +2. Example\_MutexTask2被调度,以永久阻塞模式申请互斥锁,并成功获取到该互斥锁,然后任务休眠100Tick,Example\_MutexTask2挂起,Example\_MutexTask1被唤醒。 +3. Example\_MutexTask1以定时阻塞模式申请互斥锁,等待时间为10Tick,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。10Tick超时时间到达后,Example\_MutexTask1被唤醒,以永久阻塞模式申请互斥锁,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。 +4. 100Tick休眠时间到达后,Example\_MutexTask2被唤醒, 释放互斥锁,唤醒Example\_MutexTask1。Example\_MutexTask1成功获取到互斥锁后,释放,删除互斥锁。 + +### 示例代码 + +示例代码如下: + +``` +#include +#include "los_mux.h" + +/* 互斥锁句柄id */ +UINT32 g_testMux; +/* 任务ID */ +UINT32 g_testTaskId01; +UINT32 g_testTaskId02; + +VOID Example_MutexTask1(VOID) +{ + UINT32 ret; + + printf("task1 try to get mutex, wait 10 ticks.\n"); + /* 申请互斥锁 */ + ret = LOS_MuxPend(g_testMux, 10); + + if (ret == LOS_OK) { + printf("task1 get mutex g_testMux.\n"); + /* 释放互斥锁 */ + LOS_MuxPost(g_testMux); + return; + } + if (ret == LOS_ERRNO_MUX_TIMEOUT ) { + printf("task1 timeout and try to get mutex, wait forever.\n"); + /* 申请互斥锁 */ + ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); + if (ret == LOS_OK) { + printf("task1 wait forever, get mutex g_testMux.\n"); + /* 释放互斥锁 */ + LOS_MuxPost(g_testMux); + /* 删除互斥锁 */ + LOS_MuxDelete(g_testMux); + printf("task1 post and delete mutex g_testMux.\n"); + return; + } + } + return; +} + +VOID Example_MutexTask2(VOID) +{ + printf("task2 try to get mutex, wait forever.\n"); + /* 申请互斥锁 */ + (VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); + + printf("task2 get mutex g_testMux and suspend 100 ticks.\n"); + + /* 任务休眠100Ticks */ + LOS_TaskDelay(100); + + printf("task2 resumed and post the g_testMux\n"); + /* 释放互斥锁 */ + LOS_MuxPost(g_testMux); + return; +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + TSK_INIT_PARAM_S task2; + + /* 创建互斥锁 */ + LOS_MuxCreate(&g_testMux); + + /* 锁任务调度 */ + LOS_TaskLock(); + + /* 创建任务1 */ + memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; + task1.pcName = "MutexTsk1"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("task1 create failed.\n"); + return LOS_NOK; + } + + /* 创建任务2 */ + memset(&task2, 0, sizeof(TSK_INIT_PARAM_S)); + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; + task2.pcName = "MutexTsk2"; + task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task2.usTaskPrio = 4; + ret = LOS_TaskCreate(&g_testTaskId02, &task2); + if (ret != LOS_OK) { + printf("task2 create failed.\n"); + return LOS_NOK; + } + + /* 解锁任务调度 */ + LOS_TaskUnlock(); + + return LOS_OK; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +task2 try to get mutex, wait forever. +task2 get mutex g_testMux and suspend 100 ticks. +task1 try to get mutex, wait 10 ticks. +task1 timeout and try to get mutex, wait forever. +task2 resumed and post the g_testMux +task1 wait forever, get mutex g_testMux. +task1 post and delete mutex g_testMux. +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex.md new file mode 100644 index 0000000000000000000000000000000000000000..e081c4154426c896c2f722f49d9e62e7a526dcdf --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-mutex.md @@ -0,0 +1,7 @@ +# 互斥锁 + +- **[基本概念](kernel-lite-mini-basic-ipc-mutex-basic.md)** + +- **[开发指导](kernel-lite-mini-basic-ipc-mutex-guide.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue-basic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..06f38749defa69e8e6fc678643d342e07675f90d --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue-basic.md @@ -0,0 +1,67 @@ +# 基本概念 + +- [运行机制](#section1582619446311) + - [队列控制块](#section1648304614720) + - [队列运作原理](#section15384012164811) + + +队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 + +任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息。任务也能够往队列里写入消息,当队列已经写满消息时,挂起写入任务;当队列中有空闲消息节点时,挂起的写入任务被唤醒并写入消息。 + +可以通过调整读队列和写队列的超时时间来调整读写接口的阻塞模式,如果将读队列和写队列的超时时间设置为0,就不会挂起任务,接口会直接返回,这就是非阻塞模式。反之,如果将都队列和写队列的超时时间设置为大于0的时间,就会以阻塞模式运行。 + +消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用,可以使用队列实现任务异步通信,队列具有如下特性: + +- 消息以先进先出的方式排队,支持异步读写。 +- 读队列和写队列都支持超时机制。 +- 每读取一条消息,就会将该消息节点设置为空闲。 +- 发送消息类型由通信双方约定,可以允许不同长度(不超过队列的消息节点大小)的消息。 +- 一个任务能够从任意一个消息队列接收和发送消息。 +- 多个任务能够从同一个消息队列接收和发送消息。 +- 创建队列时所需的队列空间,接口内系统自行动态申请内存。 + +## 运行机制 + +### 队列控制块 + +``` +/** + * 队列控制块数据结构 + */ +typedef struct +{ + UINT8 *queue; /* 队列消息内存空间的指针 */ + UINT16 queueState; /* 队列状态 */ + UINT16 queueLen; /* 队列中消息节点个数,即队列长度 */ + UINT16 queueSize; /* 消息节点大小 */ + UINT16 queueID; /* 队列ID */ + UINT16 queueHead; /* 消息头节点位置(数组下标)*/ + UINT16 queueTail; /* 消息尾节点位置(数组下标)*/ + UINT16 readWriteableCnt[OS_READWRITE_LEN]; /* 数组下标0的元素表示队列中可读消息数, + 数组下标1的元素表示队列中可写消息数 */ + LOS_DL_LIST readWriteList[OS_READWRITE_LEN]; /* 读取或写入消息的任务等待链表, + 下标0:读取链表,下标1:写入链表 */ + LOS_DL_LIST memList; /* 内存块链表 */ +} LosQueueCB; +``` + +每个队列控制块中都含有队列状态,表示该队列的使用情况: + +- OS\_QUEUE\_UNUSED:队列未被使用。 +- OS\_QUEUE\_INUSED:队列被使用中。 + +### 队列运作原理 + +- 创建队列时,创建队列成功会返回队列ID。 +- 在队列控制块中维护着一个消息头节点位置Head和一个消息尾节点位置Tail,用于表示当前队列中消息的存储情况。Head表示队列中被占用的消息节点的起始位置。Tail表示被占用的消息节点的结束位置,也是空闲消息节点的起始位置。队列刚创建时,Head和Tail均指向队列起始位置。 +- 写队列时,根据readWriteableCnt\[1\]判断队列是否可以写入,不能对已满(readWriteableCnt\[1\]为0)队列进行写操作。写队列支持两种写入方式:向队列尾节点写入,也可以向队列头节点写入。尾节点写入时,根据Tail找到起始空闲消息节点作为数据写入对象,如果Tail已经指向队列尾部则采用回卷方式。头节点写入时,将Head的前一个节点作为数据写入对象,如果Head指向队列起始位置则采用回卷方式。 +- 读队列时,根据readWriteableCnt\[0\]判断队列是否有消息需要读取,对全部空闲(readWriteableCnt\[0\]为0)队列进行读操作会引起任务挂起。如果队列可以读取消息,则根据Head找到最先写入队列的消息节点进行读取。如果Head已经指向队列尾部则采用回卷方式。 +- 删除队列时,根据队列ID找到对应队列,把队列状态置为未使用,把队列控制块置为初始状态,并释放队列所占内存。 + +图 1 队列读写数据操作示意图 + +![](figure/zh-cn_image_0000001132935054.png) + +上图对读写队列做了示意,图中只画了尾节点写入方式,没有画头节点写入,但是两者是类似的。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..6c161853b669ecdd896c3a11cd01deb5d6bdf624 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue-guide.md @@ -0,0 +1,199 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section783435801510) +- [编程实例](#section460018317164) + - [实例描述](#section2148236125814) + - [示例代码](#section121451047155716) + - [结果验证](#section2742182082117) + + +## 接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

创建/删除消息队列

+

LOS_QueueCreate

+

创建一个消息队列,由系统动态申请队列空间。

+

LOS_QueueDelete

+

根据队列ID删除一个指定队列。

+

读/写队列(不带拷贝)

+

LOS_QueueRead

+

读取指定队列头节点中的数据(队列节点中的数据实际上是一个地址)。

+

LOS_QueueWrite

+

向指定队列尾节点中写入入参bufferAddr的值(即buffer的地址)。

+

LOS_QueueWriteHead

+

向指定队列头节点中写入入参bufferAddr的值(即buffer的地址)。

+

读/写队列(带拷贝)

+

LOS_QueueReadCopy

+

读取指定队列头节点中的数据。

+

LOS_QueueWriteCopy

+

向指定队列尾节点中写入入参bufferAddr中保存的数据。

+

LOS_QueueWriteHeadCopy

+

向指定队列头节点中写入入参bufferAddr中保存的数据。

+

获取队列信息

+

LOS_QueueInfoGet

+

获取指定队列的信息,包括队列ID、队列长度、消息节点大小、头节点、尾节点、可读节点数量、可写节点数量、等待读操作的任务、等待写操作的任务。

+
+ +## 开发流程 + +1. 用LOS\_QueueCreate创建队列。创建成功后,可以得到队列ID。 +2. 通过LOS\_QueueWrite或者LOS\_QueueWriteCopy写队列。 +3. 通过LOS\_QueueRead或者LOS\_QueueReadCopy读队列。 +4. 通过LOS\_QueueInfoGet获取队列信息。 +5. 通过LOS\_QueueDelete删除队列。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 系统支持的最大队列数是指:整个系统的队列资源总个数,而非用户能使用的个数。例如:系统软件定时器多占用一个队列资源,那么用户能使用的队列资源就会减少一个。 +>- 创建队列时传入的队列名和flags暂时未使用,作为以后的预留参数。 +>- 队列接口函数中的入参timeOut是相对时间。 +>- LOS\_QueueReadCopy和LOS\_QueueWriteCopy及LOS\_QueueWriteHeadCopy是一组接口,LOS\_QueueRead和LOS\_QueueWrite及LOS\_QueueWriteHead是一组接口,每组接口需要配套使用。 +>- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,用户必须保证调用LOS\_QueueRead获取到的指针所指向的内存区域在读队列期间没有被异常修改或释放,否则可能导致不可预知的后果。 +>- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,也就意味着实际写和读的消息长度仅仅是一个指针数据,因此用户使用这组接口之前,需确保创建队列时的消息节点大小,为一个指针的长度,避免不必要的浪费和读取失败。 + +## 编程实例 + +### 实例描述 + +创建一个队列,两个任务。任务1调用写队列接口发送消息,任务2通过读队列接口接收消息。 + +1. 通过LOS\_TaskCreate创建任务1和任务2。 +2. 通过LOS\_QueueCreate创建一个消息队列。 +3. 在任务1 SendEntry中发送消息。 +4. 在任务2 RecvEntry中接收消息。 +5. 通过LOS\_QueueDelete删除队列。 + +### 示例代码 + +示例代码如下: + +``` +#include "los_task.h" +#include "los_queue.h" +static UINT32 g_queue; +#define BUFFER_LEN 50 + +VOID SendEntry(VOID) +{ + UINT32 ret = 0; + CHAR abuf[] = "test message"; + UINT32 len = sizeof(abuf); + + ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); + if(ret != LOS_OK) { + printf("send message failure, error: %x\n", ret); + } +} + +VOID RecvEntry(VOID) +{ + UINT32 ret = 0; + CHAR readBuf[BUFFER_LEN] = {0}; + UINT32 readLen = BUFFER_LEN; + + //休眠1s + usleep(1000000); + ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); + if(ret != LOS_OK) { + printf("recv message failure, error: %x\n", ret); + } + + printf("recv message: %s\n", readBuf); + + ret = LOS_QueueDelete(g_queue); + if(ret != LOS_OK) { + printf("delete the queue failure, error: %x\n", ret); + } + + printf("delete the queue success!\n"); +} + +UINT32 ExampleQueue(VOID) +{ + printf("start queue example\n"); + UINT32 ret = 0; + UINT32 task1, task2; + TSK_INIT_PARAM_S initParam = {0}; + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; + initParam.usTaskPrio = 9; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + initParam.pcName = "SendQueue"; + + LOS_TaskLock(); + ret = LOS_TaskCreate(&task1, &initParam); + if(ret != LOS_OK) { + printf("create task1 failed, error: %x\n", ret); + return ret; + } + + initParam.pcName = "RecvQueue"; + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; + ret = LOS_TaskCreate(&task2, &initParam); + if(ret != LOS_OK) { + printf("create task2 failed, error: %x\n", ret); + return ret; + } + + ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); + if(ret != LOS_OK) { + printf("create queue failure, error: %x\n", ret); + } + + printf("create the queue success!\n"); + LOS_TaskUnlock(); + return ret; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +start test example +create the queue success! +recv message: test message +delete the queue success! +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue.md new file mode 100644 index 0000000000000000000000000000000000000000..a278033961591f72c9adc5629729eb06f922b266 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-queue.md @@ -0,0 +1,7 @@ +# 消息队列 + +- **[基本概念](kernel-lite-mini-basic-ipc-queue-basic.md)** + +- **[开发指导](kernel-lite-mini-basic-ipc-queue-guide.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem-basic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..79c4d7e6f5765673641968df9142a9db722fd0c2 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem-basic.md @@ -0,0 +1,53 @@ +# 基本概念 + +- [运行机制](#section1794010261861) + - [信号量控制块](#section11372149164815) + - [信号量运作原理](#section139726510491) + + +信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。 + +一个信号量的数据结构中,通常有一个计数值,用于对有效资源数的计数,表示剩下的可被使用的共享资源数,其值的含义分两种情况: + +- 0,表示该信号量当前不可获取,因此可能存在正在等待该信号量的任务。 +- 正值,表示该信号量当前可被获取。 + +以同步为目的的信号量和以互斥为目的的信号量在使用上有如下不同: + +- 用作互斥时,初始信号量计数值不为0,表示可用的共享资源个数。在需要使用共享资源前,先获取信号量,然后使用一个共享资源,使用完毕后释放信号量。这样在共享资源被取完,即信号量计数减至0时,其他需要获取信号量的任务将被阻塞,从而保证了共享资源的互斥访问。另外,当共享资源数为1时,建议使用二值信号量,一种类似于互斥锁的机制。 +- 用作同步时,初始信号量计数值为0。任务1获取信号量而阻塞,直到任务2或者某中断释放信号量,任务1才得以进入Ready或Running态,从而达到了任务间的同步。 + +## 运行机制 + +### 信号量控制块 + +``` +/** + * 信号量控制块数据结构 + */ +typedef struct { + UINT16 semStat; /* 信号量状态 */ + UINT16 semType; /* 信号量类型 */ + UINT16 semCount; /* 信号量计数 */ + UINT16 semId; /* 信号量索引号 */ + LOS_DL_LIST semList; /* 挂接阻塞于该信号量的任务 */ +} LosSemCB; +``` + +### 信号量运作原理 + +信号量初始化,为配置的N个信号量申请内存(N值可以由用户自行配置,通过LOSCFG\_BASE\_IPC\_SEM\_LIMIT宏实现),并把所有信号量初始化成未使用,加入到未使用链表中供系统使用。 + +信号量创建,从未使用的信号量链表中获取一个信号量,并设定初值。 + +信号量申请,若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其它任务释放该信号量,等待的超时时间可设定。当任务被一个信号量阻塞时,将该任务挂到信号量等待任务队列的队尾。 + +信号量释放,若没有任务等待该信号量,则直接将计数器加1返回。否则唤醒该信号量等待任务队列上的第一个任务。 + +信号量删除,将正在使用的信号量置为未使用信号量,并挂回到未使用链表。 + +信号量允许多个任务在同一时刻访问共享资源,但会限制同一时刻访问此资源的最大任务数目。当访问资源的任务数达到该资源允许的最大数量时,会阻塞其他试图获取该资源的任务,直到有任务释放该信号量。 + +**图 1** 信号量运作示意图 +![](figure/信号量运作示意图.png "信号量运作示意图") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..81715063b36a075044c4b1e2b98c14b7a2c67c15 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem-guide.md @@ -0,0 +1,206 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section783435801510) +- [编程实例](#section460018317164) + - [实例描述](#section22061718111412) + - [示例代码](#section1775922321416) + - [结果验证](#section160404016213) + + +## 接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

创建/删除信号量

+

LOS_SemCreate

+

创建信号量,返回信号量ID

+

LOS_BinarySemCreate

+

创建二值信号量,其计数值最大为1

+

LOS_SemDelete

+

删除指定的信号量

+

申请/释放信号量

+

LOS_SemPend

+

申请指定的信号量,并设置超时时间

+

LOS_SemPost

+

释放指定的信号量

+
+ +## 开发流程 + +1. 创建信号量LOS\_SemCreate,若要创建二值信号量则调用LOS\_BinarySemCreate。 +2. 申请信号量LOS\_SemPend。 +3. 释放信号量LOS\_SemPost。 +4. 删除信号量LOS\_SemDelete。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>由于中断不能被阻塞,因此不能在中断中使用阻塞模式申请信号量。 + +## 编程实例 + +### 实例描述 + +本实例实现如下功能: + +1. 测试任务ExampleSem创建一个信号量,锁任务调度,创建两个任务ExampleSemTask1、ExampleSemTask2, ExampleSemTask2优先级高于ExampleSemTask1,两个任务中申请同一信号量,解锁任务调度后两任务阻塞,测试任务ExampleSem释放信号量。 +2. ExampleSemTask2得到信号量,被调度,然后任务休眠20Tick,ExampleSemTask2延迟,ExampleSemTask1被唤醒。 +3. ExampleSemTask1定时阻塞模式申请信号量,等待时间为10Tick,因信号量仍被ExampleSemTask2持有,ExampleSemTask1挂起,10Tick后仍未得到信号量,ExampleSemTask1被唤醒,试图以永久阻塞模式申请信号量,ExampleSemTask1挂起。 +4. 20Tick后ExampleSemTask2唤醒, 释放信号量后,ExampleSemTask1得到信号量被调度运行,最后释放信号量。 +5. ExampleSemTask1执行完,40Tick后任务ExampleSem被唤醒,执行删除信号量。 + +### 示例代码 + +示例代码如下: + +``` +#include "los_sem.h" +#include "securec.h" + +/* 任务ID */ +static UINT32 g_testTaskId01; +static UINT32 g_testTaskId02; + +/* 测试任务优先级 */ +#define TASK_PRIO_TEST 5 + +/* 信号量结构体id */ +static UINT32 g_semId; + +VOID ExampleSemTask1(VOID) +{ + UINT32 ret; + + printf("ExampleSemTask1 try get sem g_semId, timeout 10 ticks.\n"); + + /* 定时阻塞模式申请信号量,定时时间为10ticks */ + ret = LOS_SemPend(g_semId, 10); + + /* 申请到信号量 */ + if (ret == LOS_OK) { + LOS_SemPost(g_semId); + return; + } + /* 定时时间到,未申请到信号量 */ + if (ret == LOS_ERRNO_SEM_TIMEOUT) { + printf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n"); + + /*永久阻塞模式申请信号量*/ + ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); + printf("ExampleSemTask1 wait_forever and get sem g_semId.\n"); + if (ret == LOS_OK) { + LOS_SemPost(g_semId); + return; + } + } +} + +VOID ExampleSemTask2(VOID) +{ + UINT32 ret; + printf("ExampleSemTask2 try get sem g_semId wait forever.\n"); + + /* 永久阻塞模式申请信号量 */ + ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); + + if (ret == LOS_OK) { + printf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n"); + } + + /* 任务休眠20 ticks */ + LOS_TaskDelay(20); + + printf("ExampleSemTask2 post sem g_semId.\n"); + /* 释放信号量 */ + LOS_SemPost(g_semId); + return; +} + +UINT32 ExampleSem(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + TSK_INIT_PARAM_S task2; + + /* 创建信号量 */ + LOS_SemCreate(0, &g_semId); + + /* 锁任务调度 */ + LOS_TaskLock(); + + /* 创建任务1 */ + (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1; + task1.pcName = "TestTask1"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = TASK_PRIO_TEST; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("task1 create failed .\n"); + return LOS_NOK; + } + + /* 创建任务2 */ + (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2; + task2.pcName = "TestTask2"; + task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task2.usTaskPrio = (TASK_PRIO_TEST - 1); + ret = LOS_TaskCreate(&g_testTaskId02, &task2); + if (ret != LOS_OK) { + printf("task2 create failed.\n"); + return LOS_NOK; + } + + /* 解锁任务调度 */ + LOS_TaskUnlock(); + + ret = LOS_SemPost(g_semId); + + /* 任务休眠400 ticks */ + LOS_TaskDelay(400); + + /* 删除信号量 */ + LOS_SemDelete(g_semId); + return LOS_OK; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +ExampleSemTask2 try get sem g_semId wait forever. +ExampleSemTask2 get sem g_semId and then delay 20 ticks. +ExampleSemTask1 try get sem g_semId, timeout 10 ticks. + +ExampleSemTask1 timeout and try get sem g_semId wait forever. +ExampleSemTask2 post sem g_semId. +ExampleSemTask1 wait_forever and get sem g_semId. +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem.md new file mode 100644 index 0000000000000000000000000000000000000000..1b1afc6945e99589fb8185863fe4ce76b968a38d --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc-sem.md @@ -0,0 +1,7 @@ +# 信号量 + +- **[基本概念](kernel-lite-mini-basic-ipc-sem-basic.md)** + +- **[开发指导](kernel-lite-mini-basic-ipc-sem-guide.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc.md new file mode 100644 index 0000000000000000000000000000000000000000..2acba70e2f90c17310c5ce4a77c8d12a9658afc7 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-ipc.md @@ -0,0 +1,11 @@ +# 内核通信机制 + +- **[事件](kernel-lite-mini-basic-ipc-event.md)** + +- **[互斥锁](kernel-lite-mini-basic-ipc-mutex.md)** + +- **[消息队列](kernel-lite-mini-basic-ipc-queue.md)** + +- **[信号量](kernel-lite-mini-basic-ipc-sem.md)** + + diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-4.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-basic.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-4.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-basic.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-dynamic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-dynamic.md new file mode 100644 index 0000000000000000000000000000000000000000..c9f32f97ad19a097af45e8d43620c068241e3991 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-dynamic.md @@ -0,0 +1,227 @@ +# 动态内存 + +- [运行机制](#section328282013571) +- [开发指导](#section7921151015814) + - [使用场景](#section326917198583) + - [接口说明](#section1032331584) + - [开发流程](#section07271773592) + - [编程实例](#section84931234145913) + - [结果验证](#section165233233917) + + +## 运行机制 + +动态内存管理,即在内存资源充足的情况下,根据用户需求,从系统配置的一块比较大的连续内存(内存池,也是堆内存)中分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。与静态内存相比,动态内存管理的优点是按需分配,缺点是内存池中容易出现碎片。 + +OpenHarmony LiteOS-M动态内存在TLSF算法的基础上,对区间的划分进行了优化,获得更优的性能,降低了碎片率。动态内存核心算法框图如下: + +**图 1** 动态内存核心算法 +![](figure/动态内存核心算法.png "动态内存核心算法") + +根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:\[4, 127\]和\[27, 231\],如上图size class所示: + +1. 对\[4,127\]区间的内存进行等分,如上图绿色部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。\[4,127\]区间的31个小区间内存对应31个比特位进行标记链表是否为空。 +2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,见上图蓝色的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。总共24\*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。 + +例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间\[40,43\],第10个空闲链表,位图标记的第10比特位。把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间\[2^9,2^9+2^6\],第31+2\*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。 + +内存管理结构如下图所示: + +**图 2** 动态内存管理结构图 +![](figure/动态内存管理结构图.png "动态内存管理结构图") + +- 内存池池头部分 + + 内存池池头部分包含内存池信息、位图标记数组和空闲链表数组。内存池信息包含内存池起始地址及堆区域总大小,内存池属性。位图标记数组有7个32位无符号整数组成,每个比特位标记对应的空闲链表是否挂载空闲内存块节点。空闲内存链表包含223个空闲内存头节点信息,每个空闲内存头节点信息维护内存节点头和空闲链表中的前驱、后继空闲内存节点。 + +- 内存池节点部分 + + 包含3种类型节点:未使用空闲内存节点,已使用内存节点和尾节点。每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。空闲内存节点和已使用内存节点后面的内存区域是数据域,尾节点没有数据域。 + + +## 开发指导 + +### 使用场景 + +动态内存管理的主要工作是动态分配并管理用户申请到的内存区间。动态内存管理主要用于用户需要使用大小不等的内存块的场景,当用户需要使用内存时,可以通过操作系统的动态内存申请函数索取指定大小的内存块,一旦使用完毕,通过动态内存释放函数归还所占用内存,使之可以重复使用。 + +### 接口说明 + +OpenHarmony LiteOS-M的动态内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 + +**表 1** 动态内存模块接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

初始化和删除内存池

+

LOS_MemInit

+

初始化一块指定的动态内存池,大小为size。

+

LOS_MemDeInit

+

删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效。

+

申请、释放动态内存

+

LOS_MemAlloc

+

从指定动态内存池中申请size长度的内存。

+

LOS_MemFree

+

释放从指定动态内存中申请的内存。

+

LOS_MemRealloc

+

按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块。

+

LOS_MemAllocAlign

+

从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存。

+

获取内存池信息

+

LOS_MemPoolSizeGet

+

获取指定动态内存池的总大小。

+

LOS_MemTotalUsedGet

+

获取指定动态内存池的总使用量大小。

+

LOS_MemInfoGet

+

获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小。

+

LOS_MemPoolList

+

打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。仅打开LOSCFG_MEM_MUL_POOL时有效。

+

获取内存块信息

+

LOS_MemFreeNodeShow

+

打印指定内存池的空闲内存块的大小及数量。

+

LOS_MemUsedNodeShow

+

打印指定内存池的已使用内存块的大小及数量。

+

检查指定内存池的完整性

+

LOS_MemIntegrityCheck

+

对指定内存池做完整性检查,仅打开LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK时有效。

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 由于动态内存管理需要管理控制块数据结构来管理内存,这些数据结构会额外消耗内存,故实际用户可使用内存总量小于配置项OS\_SYS\_MEM\_SIZE的大小。 +>- 对齐分配内存接口LOS\_MemAllocAlign/LOS\_MemMallocAlign因为要进行地址对齐,可能会额外消耗部分内存,故存在一些遗失内存,当系统释放该对齐内存时,同时回收由于对齐导致的遗失内存。 + +### 开发流程 + +本节介绍使用动态内存的典型场景开发流程。 + +1. 初始化LOS\_MemInit。 + + 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。注:EndNode作为内存池末尾的节点,size为0。 + + +1. 申请任意大小的动态内存LOS\_MemAlloc。 + + 判断动态内存池中是否存在大于申请量大小的空闲内存块空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。如果空闲内存块大于申请量,需要对内存块进行分割,剩余的部分作为空闲内存块挂载到空闲内存链表上。 + + +1. 释放动态内存LOS\_MemFree。 + + 回收内存块,供下一次使用。调用LOS\_MemFree释放内存块,则会回收内存块,并且将其标记为FreeNode。在回收内存块时,相邻的FreeNode会自动合并。 + + +### 编程实例 + +本实例执行以下步骤: + +1. 初始化一个动态内存池。 +2. 从动态内存池中申请一个内存块。 +3. 在内存块中存放一个数据。 +4. 打印出内存块中的数据。 +5. 释放该内存块。 + +示例代码如下: + +``` +#include "los_memory.h" + +VOID Example_DynMem(VOID) +{ + UINT32 *mem = NULL; + UINT32 ret; + + /*初始化内存池*/ + ret = LOS_MemInit(g_testPool, TEST_POOL_SIZE); + if (LOS_OK == ret) { + printf("Mem init success!\n"); + } else { + printf("Mem init failed!\n"); + return; + } + + /*分配内存*/ + mem = (UINT32 *)LOS_MemAlloc(g_testPool, 4); + if (NULL == mem) { + printf("Mem alloc failed!\n"); + return; + } + printf("Mem alloc success!\n"); + + /*赋值*/ + *mem = 828; + printf("*mem = %d\n", *mem); + + /*释放内存*/ + ret = LOS_MemFree(g_testPool, mem); + if (LOS_OK == ret) { + printf("Mem free success!\n"); + } else { + printf("Mem free failed!\n"); + } + + return; +} +``` + +### 结果验证 + +输出结果如下: + +``` +Mem init success! +Mem alloc success! +*mem = 828 +Mem free success! +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-static.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-static.md new file mode 100644 index 0000000000000000000000000000000000000000..b52510e80b57ef577efaa7babfebc808d6041ca5 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory-static.md @@ -0,0 +1,182 @@ +# 静态内存 + +- [运行机制](#section165473517522) +- [开发指导](#section57511620165218) + - [使用场景](#section215474911529) + - [接口说明](#section79231214539) + - [开发流程](#section1388511316548) + - [编程实例](#section17801515105519) + - [结果验证](#section11818154112319) + + +## 运行机制 + +静态内存实质上是一个静态数组,静态内存池内的块大小在初始化时设定,初始化后块大小不可变更。 + +静态内存池由一个控制块LOS\_MEMBOX\_INFO和若干相同大小的内存块LOS\_MEMBOX\_NODE构成。控制块位于内存池头部,用于内存块管理,包含内存块大小uwBlkSize,内存块数量uwBlkNum,已分配使用的内存块数量uwBlkCnt和空闲内存块链表stFreeList。内存块的申请和释放以块大小为粒度,每个内存块包含指向下一个内存块的指针pstNext。 + +**图 1** 静态内存示意图 +![](figure/静态内存示意图.png "静态内存示意图") + +## 开发指导 + +### 使用场景 + +当用户需要使用固定长度的内存时,可以通过静态内存分配的方式获取内存,一旦使用完毕,通过静态内存释放函数归还所占用内存,使之可以重复使用。 + +### 接口说明 + +OpenHarmony LiteOS-M的静态内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 + +**表 1** 静态内存模块接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

初始化静态内存池

+

LOS_MemboxInit

+

初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小。

+

清除静态内存块内容

+

LOS_MemboxClr

+

清零从静态内存池中申请的静态内存块的内容。

+

申请、释放静态内存

+

LOS_MemboxAlloc

+

从指定的静态内存池中申请一块静态内存块。

+

LOS_MemboxFree

+

释放从静态内存池中申请的一块静态内存块。

+

获取、打印静态内存池信息

+

LOS_MemboxStatisticsGet

+

获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小。

+

LOS_ShowBox

+

打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址。

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>初始化后的内存池的内存块数量,不等于总大小除于内存块大小,因为内存池的控制块和每个内存块的控制头,都存在内存开销,设置总大小时,需要将这些因素考虑进去。 + +### 开发流程 + +本节介绍使用静态内存的典型场景开发流程。 + +1. 规划一片内存区域作为静态内存池。 +2. 调用LOS\_MemboxInit初始化静态内存池。 + + 初始化会将入参指定的内存区域分割为N块(N值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。 + +3. 调用LOS\_MemboxAlloc接口分配静态内存。 + + 系统将会从空闲链表中获取第一个空闲块,并返回该内存块的起始地址。 + +4. 调用LOS\_MemboxClr接口。 + + 将入参地址对应的内存块清零。 + +5. 调用LOS\_MemboxFree接口。 + + 将该内存块加入空闲链表。 + + +### 编程实例 + +本实例执行以下步骤: + +1. 初始化一个静态内存池。 +2. 从静态内存池中申请一块静态内存。 +3. 在内存块存放一个数据。 +4. 打印出内存块中的数据。 +5. 清除内存块中的数据。 +6. 释放该内存块。 + + 示例代码如下: + + +``` +#include "los_membox.h" + +VOID Example_StaticMem(VOID) +{ + UINT32 *mem = NULL; + UINT32 blkSize = 10; + UINT32 boxSize = 100; + UINT32 boxMem[1000]; + UINT32 ret; + + /*内存池初始化*/ + ret = LOS_MemboxInit(&boxMem[0], boxSize, blkSize); + if(ret != LOS_OK) { + printf("Membox init failed!\n"); + return; + } else { + printf("Membox init success!\n"); + } + + /*申请内存块*/ + mem = (UINT32 *)LOS_MemboxAlloc(boxMem); + if (NULL == mem) { + printf("Mem alloc failed!\n"); + return; + } + printf("Mem alloc success!\n"); + + /*赋值*/ + *mem = 828; + printf("*mem = %d\n", *mem); + + /*清除内存内容*/ + LOS_MemboxClr(boxMem, mem); + printf("Mem clear success \n *mem = %d\n", *mem); + + /*释放内存*/ + ret = LOS_MemboxFree(boxMem, mem); + if (LOS_OK == ret) { + printf("Mem free success!\n"); + } else { + printf("Mem free failed!\n"); + } + + return; +} +``` + +### 结果验证 + +输出结果如下: + +``` +Membox init success! +Mem alloc success! +*mem = 828 +Mem clear success +*mem = 0 +Mem free success! +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory.md new file mode 100644 index 0000000000000000000000000000000000000000..e0f1da7e35707537406eccc8b425c8697e5e06e0 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-memory.md @@ -0,0 +1,9 @@ +# 内存管理 + +- **[基本概念](kernel-lite-mini-basic-memory-basic.md)** + +- **[静态内存](kernel-lite-mini-basic-memory-static.md)** + +- **[动态内存](kernel-lite-mini-basic-memory-dynamic.md)** + + diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-15.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft-basic.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-15.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft-basic.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..0e9f963c0c631b7b8b8284dfa4f16e54d1de273d --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft-guide.md @@ -0,0 +1,218 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section783435801510) +- [编程实例](#section460018317164) + - [实例描述](#section3741753191918) + - [示例代码](#section20760101182016) + - [结果验证](#section11244112818172) + + +## 接口说明 + +OpenHarmony LiteOS-M内核的软件定时器模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表 1** 软件定时器接口 + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

创建、删除定时器

+

LOS_SwtmrCreate

+

创建定时器

+

LOS_SwtmrDelete

+

删除定时器

+

启动、停止定时器

+

LOS_SwtmrStart

+

启动定时器

+

LOS_SwtmrStop

+

停止定时器

+

获得软件定时器剩余Tick数

+

LOS_SwtmrTimeGet

+

获得软件定时器剩余Tick数

+
+ +## 开发流程 + +软件定时器的典型开发流程: + +1. 配置软件定时器。 + - 确认配置项LOSCFG\_BASE\_CORE\_SWTMR和LOSCFG\_BASE\_IPC\_QUEUE为1打开状态; + - 配置LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数; + - 配置OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度; + +2. 创建定时器LOS\_SwtmrCreate。 + - 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器; + - 返回函数运行结果,成功或失败; + +3. 启动定时器LOS\_SwtmrStart。 +4. 获得软件定时器剩余Tick数LOS\_SwtmrTimeGet。 +5. 停止定时器LOS\_SwtmrStop。 +6. 删除定时器LOS\_SwtmrDelete。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口或操作。 +>- 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为0,且不允许修改 。 +>- 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数。例如:系统软件定时器多占用一个软件定时器资源数,那么用户能使用的软件定时器资源就会减少一个。 +>- 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源。 +>- 创建单次不自删除属性的定时器,用户需要调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 + +## 编程实例 + +### 实例描述 + +在下面的例子中,演示如下功能: + +1. 软件定时器创建、启动、删除、暂停、重启操作。 +2. 单次软件定时器,周期软件定时器使用方法。 + +### 示例代码 + +前提条件: + +- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMR配置项打开。 +- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMR\_ALIGN配置项关闭,示例代码中演示代码不涉及定时器对齐。 +- 配置好LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数。 +- 配置好OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度。 + +代码实现如下: + +``` +#include "los_swtmr.h" + +/* Timer count */ +UINT32 g_timerCount1 = 0; +UINT32 g_timerCount2 = 0; + +/* 任务ID */ +UINT32 g_testTaskId01; + +void Timer1_Callback(UINT32 arg) // 回调函数1 +{ + UINT32 tick_last1; + g_timerCount1++; + tick_last1=(UINT32)LOS_TickCountGet(); // 获取当前Tick数 + printf("g_timerCount1=%d, tick_last1=%d\n", g_timerCount1, tick_last1); +} + +void Timer2_Callback(UINT32 arg) // 回调函数2 +{ + UINT32 tick_last2; + tick_last2=(UINT32)LOS_TickCountGet(); + g_timerCount2++; + printf("g_timerCount2=%d tick_last2=%d\n", g_timerCount2, tick_last2); +} + +void Timer_example(void) +{ + UINT32 id1; // timer id + UINT32 id2; // timer id + UINT32 uwTick; + + /*创建单次软件定时器,Tick数为1000,启动到1000Tick数时执行回调函数1 */ + LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); + + /*创建周期性软件定时器,每100Tick数执行回调函数2 */ + LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); + printf("create Timer1 success\n"); + + LOS_SwtmrStart (id1); //启动单次软件定时器 + printf("start Timer1 sucess\n"); + + LOS_TaskDelay(200); //延时200Tick数 + LOS_SwtmrTimeGet(id1, &uwTick); // 获得单次软件定时器剩余Tick数 + printf("uwTick =%d\n", uwTick); + + LOS_SwtmrStop(id1); // 停止软件定时器 + printf("stop Timer1 sucess\n"); + + LOS_SwtmrStart(id1); + LOS_TaskDelay(1000); + + LOS_SwtmrDelete(id1); // 删除软件定时器 + printf("delete Timer1 sucess\n"); + + LOS_SwtmrStart(id2); // 启动周期性软件定时器 + printf("start Timer2\n"); + + LOS_TaskDelay(1000); + LOS_SwtmrStop(id2); + LOS_SwtmrDelete(id2); +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + + /* 锁任务调度 */ + LOS_TaskLock(); + + /* 创建任务1 */ + memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Timer_example; + task1.pcName = "TimerTsk"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("TimerTsk create failed.\n"); + return LOS_NOK; + } + + /* 解锁任务调度 */ + LOS_TaskUnlock(); + + return LOS_OK; +} +``` + +### 结果验证 + +编译烧录运行,输出结果如下: + +``` +create Timer1 success +start Timer1 sucess +uwTick =798 +stop Timer1 sucess +g_timerCount1=1, tick_last1=1208 +delete Timer1 sucess +start Timer2 +g_timerCount2=1 tick_last2=1313 +g_timerCount2=2 tick_last2=1413 +g_timerCount2=3 tick_last2=1513 +g_timerCount2=4 tick_last2=1613 +g_timerCount2=5 tick_last2=1713 +g_timerCount2=6 tick_last2=1813 +g_timerCount2=7 tick_last2=1913 +g_timerCount2=8 tick_last2=2013 +g_timerCount2=9 tick_last2=2113 +g_timerCount2=10 tick_last2=2213 +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft.md new file mode 100644 index 0000000000000000000000000000000000000000..0aef7971458b34cc5b9b903ca9317026ee5c7a62 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-soft.md @@ -0,0 +1,7 @@ +# 软件定时器 + +- **[基本概念](kernel-lite-mini-basic-soft-basic.md)** + +- **[开发指导](kernel-lite-mini-basic-soft-guide.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task-basic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..074596f401185126a3ea5701b115aba2887cebcf --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task-basic.md @@ -0,0 +1,96 @@ +# 基本概念 + +- [任务相关概念](#section673132352511) +- [任务运行机制](#section176294469251) + +从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。 + +OpenHarmony LiteOS-M的任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。任务模块具有如下特性: + +- 支持多任务。 +- 一个任务表示一个线程。 +- 抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。 +- 相同优先级任务支持时间片轮转调度方式。 +- 共有32个优先级\[0-31\],最高优先级为0,最低优先级为31。 + +## 任务相关概念 + +**任务状态** + +任务有多种运行状态。系统初始化完成后,创建的任务就可以在系统中竞争一定的资源,由内核进行调度。 + +任务状态通常分为以下四种: + +- 就绪(Ready):该任务在就绪队列中,只等待CPU。 +- 运行(Running):该任务正在执行。 +- 阻塞(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、任务正在等待信号量、读写队列或者等待事件等。 +- 退出态(Dead):该任务运行结束,等待系统回收资源。 + +**任务状态迁移** + +**图 1** 任务状态示意图 +![](figure/任务状态示意图.png "任务状态示意图") + +**任务状态迁移说明:** + +- 就绪态→运行态 + + 任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行,从而进入运行态,同时该任务从就绪队列中移出。 + +- 运行态→阻塞态 + + 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,该任务会从就绪队列中删除,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。 + +- 阻塞态→就绪态(阻塞态→运行态) + + 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。 + +- 就绪态→阻塞态 + + 任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务从就绪队列中删除,不会参与任务调度,直到该任务被恢复。 + +- 运行态→就绪态 + + 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。 + +- 运行态→退出态 + + 运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。 + +- 阻塞态→退出态 + + 阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。 + + +**任务ID** + +任务ID,在任务创建时通过参数返回给用户,是任务的重要标识。系统中的ID号是唯一的。用户可以通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。 + +**任务优先级** + +优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,就绪队列中最高优先级的任务将得到执行。 + +**任务入口函数** + +新任务得到调度后将执行的函数。该函数由用户实现,在任务创建时,通过任务创建结构体设置。 + +**任务栈** + +每个任务都拥有一个独立的栈空间,我们称为任务栈。栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。 + +**任务上下文** + +任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当这个任务挂起时,其他任务继续执行,可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。因此在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。 + +**任务控制块TCB** + +每个任务都含有一个任务控制块\(TCB\)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。 + +**任务切换** + +任务切换包含获取就绪队列中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。 + +## 任务运行机制 + +用户创建任务时,系统会初始化任务栈,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..6b42cf5b4a99c1316d0388e23795ba3794b73d86 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task-guide.md @@ -0,0 +1,306 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section783435801510) +- [编程实例](#section460018317164) + - [结果验证](#section189023104457) + + +任务创建后,内核可以执行锁任务调度,解锁任务调度,挂起,恢复,延时等操作,同时也可以设置任务优先级,获取任务优先级。 + +## 接口说明 + +OpenHarmony LiteOS-M内核的任务管理模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表 1** 任务管理模块接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

创建和删除任务

+

LOS_TaskCreateOnly

+

创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态。

+

LOS_TaskCreate

+

创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务。

+

LOS_TaskDelete

+

删除指定的任务。

+

控制任务状态

+

LOS_TaskResume

+

恢复挂起的任务,使该任务进入ready状态。

+

LOS_TaskSuspend

+

挂起指定的任务,然后切换任务

+

LOS_TaskDelay

+

任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态。传入参数为Tick数目。

+

LOS_Msleep

+

传入参数为毫秒数,转换为Tick数目,调用LOS_TaskDelay。

+

LOS_TaskYield

+

当前任务时间片设置为0,释放CPU,触发调度运行就绪任务队列中优先级最高的任务。

+

控制任务调度

+

LOS_TaskLock

+

锁任务调度,但任务仍可被中断打断。

+

LOS_TaskUnlock

+

解锁任务调度。

+

LOS_Schedule

+

触发任务调度。

+

控制任务优先级

+

LOS_CurTaskPriSet

+

设置当前任务的优先级。

+

LOS_TaskPriSet

+

设置指定任务的优先级。

+

LOS_TaskPriGet

+

获取指定任务的优先级。

+

获取任务信息

+

LOS_CurTaskIDGet

+

获取当前任务的ID。

+

LOS_NextTaskIDGet

+

获取任务就绪队列中优先级最高的任务的ID。

+

LOS_NewTaskIDGet

+

等同LOS_NextTaskIDGet。

+

LOS_CurTaskNameGet

+

获取当前任务的名称。

+

LOS_TaskNameGet

+

获取指定任务的名称。

+

LOS_TaskStatusGet

+

获取指定任务的状态。

+

LOS_TaskInfoGet

+

获取指定任务的信息,包括任务状态、优先级、任务栈大小、栈顶指针SP、任务入口函数、已使用的任务栈大小等。

+

LOS_TaskIsRunning

+

获取任务模块是否已经开始调度运行。

+

任务信息维测

+

LOS_TaskSwitchInfoGet

+

获取任务切换信息,需要开启宏LOSCFG_BASE_CORE_EXC_TSK_SWITCH。

+
+ +## 开发流程 + +以创建任务为例,讲解开发流程。 + +1. 锁任务调度LOS\_TaskLock,防止高优先级任务调度。 +2. 创建任务LOS\_TaskCreate。 +3. 解锁任务LOS\_TaskUnlock,让任务按照优先级进行调度。 +4. 延时任务LOS\_TaskDelay,任务延时等待。 +5. 挂起指定的任务LOS\_TaskSuspend,任务挂起等待恢复操作。 +6. 恢复挂起的任务LOS\_TaskResume。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 执行Idle任务时,会对待回收链表中的任务控制块和任务栈进行回收。 +>- 任务名是指针,并没有分配空间,在设置任务名时,禁止将局部变量的地址赋值给任务名指针。 +>- 任务栈的大小按8字节大小对齐。确定任务栈大小的原则是,够用就行,多了浪费,少了任务栈溢出。 +>- 挂起当前任务时,如果已经锁任务调度,则无法挂起。 +>- Idle任务及软件定时器任务不能被挂起或者删除。 +>- 在中断处理函数中或者在锁任务的情况下,执行LOS\_TaskDelay会失败。 +>- 锁任务调度,并不关中断,因此任务仍可被中断打断。 +>- 锁任务调度必须和解锁任务调度配合使用。 +>- 设置任务优先级时可能会发生任务调度。 +>- 可配置的系统最大任务数是指:整个系统的任务总个数,而非用户能使用的任务个数。例如:系统软件定时器多占用一个任务资源,那么用户能使用的任务资源就会减少一个。 +>- LOS\_CurTaskPriSet和LOS\_TaskPriSet接口不能在中断中使用,也不能用于修改软件定时器任务的优先级。 +>- LOS\_TaskPriGet接口传入的task ID对应的任务未创建或者超过最大任务数,统一返回-1。 +>- 在删除任务时要保证任务申请的资源(如互斥锁、信号量等)已被释放。 + +## 编程实例 + +本实例介绍基本的任务操作方法,包含2个不同优先级任务的创建、任务延时、任务锁与解锁调度、挂起和恢复等操作,阐述任务优先级调度的机制以及各接口的应用。示例代码如下: + +``` +UINT32 g_taskHiId; +UINT32 g_taskLoId; +#define TSK_PRIOR_HI 4 +#define TSK_PRIOR_LO 5 + +UINT32 Example_TaskHi(VOID) +{ + UINT32 ret; + + printf("Enter TaskHi Handler.\n"); + + /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务(TaskLo任务) */ + ret = LOS_TaskDelay(100); + if (ret != LOS_OK) { + printf("Delay TaskHi Failed.\n"); + return LOS_NOK; + } + + /* 100个Ticks时间到了后,该任务恢复,继续执行 */ + printf("TaskHi LOS_TaskDelay Done.\n"); + + /* 挂起自身任务 */ + ret = LOS_TaskSuspend(g_taskHiId); + if (ret != LOS_OK) { + printf("Suspend TaskHi Failed.\n"); + return LOS_NOK; + } + printf("TaskHi LOS_TaskResume Success.\n"); + return ret; +} + +/* 低优先级任务入口函数 */ +UINT32 Example_TaskLo(VOID) +{ + UINT32 ret; + + printf("Enter TaskLo Handler.\n"); + + /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务 */ + ret = LOS_TaskDelay(100); + if (ret != LOS_OK) { + printf("Delay TaskLo Failed.\n"); + return LOS_NOK; + } + + printf("TaskHi LOS_TaskSuspend Success.\n"); + + /* 恢复被挂起的任务g_taskHiId */ + ret = LOS_TaskResume(g_taskHiId); + if (ret != LOS_OK) { + printf("Resume TaskHi Failed.\n"); + return LOS_NOK; + } + return ret; +} + +/* 任务测试入口函数,创建两个不同优先级的任务 */ +UINT32 Example_TskCaseEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S initParam; + + /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ + LOS_TaskLock(); + + printf("LOS_TaskLock() Success!\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; + initParam.usTaskPrio = TSK_PRIOR_HI; + initParam.pcName = "TaskHi"; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + + /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ + ret = LOS_TaskCreate(&g_taskHiId, &initParam); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + + printf("Example_TaskHi create Failed!\n"); + return LOS_NOK; + } + + printf("Example_TaskHi create Success!\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; + initParam.usTaskPrio = TSK_PRIOR_LO; + initParam.pcName = "TaskLo"; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + + /* 创建低优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ + ret = LOS_TaskCreate(&g_taskLoId, &initParam); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + printf("Example_TaskLo create Failed!\n"); + return LOS_NOK; + } + + printf("Example_TaskLo create Success!\n"); + + /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ + LOS_TaskUnlock(); + + return LOS_OK; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +LOS_TaskLock() Success! +Example_TaskHi create Success! +Example_TaskLo create Success! +Enter TaskHi Handler. +Enter TaskLo Handler. +TaskHi LOS_TaskDelay Done. +TaskHi LOS_TaskSuspend Success. +TaskHi LOS_TaskResume Success. +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task.md new file mode 100644 index 0000000000000000000000000000000000000000..8ca91b1f10c4e6e638621cde1fc9338c0667bdb5 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-task.md @@ -0,0 +1,7 @@ +# 任务管理 + +- **[基本概念](kernel-lite-mini-basic-task-basic.md)** + +- **[开发指导](kernel-lite-mini-basic-task-guide.md)** + + diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-13.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-time-basic.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-13.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-basic-time-basic.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic-time-guide.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-time-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..a0328b1c7ddea9644fa8c861fa9ac72453b72ae8 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic-time-guide.md @@ -0,0 +1,159 @@ +# 开发指导 + +- [接口说明](#section158501652121514) +- [开发流程](#section783435801510) +- [编程实例](#section460018317164) + - [实例描述](#section127752801718) + - [示例代码](#section321653551711) + - [结果验证](#section4366193318167) + + +用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系时,需要使用到时间管理模块的接口。 + +## 接口说明 + +OpenHarmony LiteOS-M内核的时间管理提供下面几种功能,接口详细信息可以查看API参考。 + +**表 1** 时间管理接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

时间转换

+

LOS_MS2Tick

+

毫秒转换成Tick

+

LOS_Tick2MS

+

Tick转化为毫秒

+

OsCpuTick2MS

+

Cycle数目转化为毫秒,使用2个

+

UINT32类型的数值分别表示结果数值的高、低32位。

+

OsCpuTick2US

+

Cycle数目转化为微秒,使用2个

+

UINT32类型的数值分别表示结果数值的高、低32位。

+

时间统计

+

LOS_SysClockGet

+

获取系统时钟

+

LOS_TickCountGet

+

获取自系统启动以来的Tick数

+

LOS_CyclePerTickGet

+

每个Tick多少Cycle数

+
+ +## 开发流程 + +时间管理的典型开发流程: + +1. 根据实际需求,完成板级配置适配,并配置系统主时钟频率OS\_SYS\_CLOCK(单位Hz)和LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND。OS\_SYS\_CLOCK的默认值基于硬件平台配置。 +2. 调用时钟转换/统计接口。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 时间管理不是单独的功能模块,依赖于OS\_SYS\_CLOCK和LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND两个配置选项。 +>- 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间使用。 +>- 配置选项维护在开发板工程的文件target\_config.h。 + +## 编程实例 + +### 实例描述 + +在下面的例子中,介绍了时间管理的基本方法,包括: + +1. 时间转换:将毫秒数转换为Tick数,或将Tick数转换为毫秒数。 +2. 时间统计:每Tick的Cycle数、自系统启动以来的Tick数和延迟后的Tick数。 + +### 示例代码 + +前提条件: + +- 使用每秒的Tick数LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND的默认值100。 +- 配好OS\_SYS\_CLOCK系统主时钟频率。 + +时间转换: + +``` +VOID Example_TransformTime(VOID) +{ + UINT32 ms; + UINT32 tick; + + tick = LOS_MS2Tick(10000); // 10000ms转换为tick + dprintf("tick = %d \n", tick); + ms = LOS_Tick2MS(100); // 100tick转换为ms + dprintf("ms = %d \n", ms); +} +``` + +时间统计和时间延迟: + +``` +VOID Example_GetTime(VOID) +{ + UINT32 cyclePerTick; + UINT64 tickCount; + + cyclePerTick = LOS_CyclePerTickGet(); + if(0 != cyclePerTick) { + dprintf("LOS_CyclePerTickGet = %d \n", cyclePerTick); + } + + tickCount = LOS_TickCountGet(); + if(0 != tickCount) { + dprintf("LOS_TickCountGet = %d \n", (UINT32)tickCount); + } + + LOS_TaskDelay(200); + tickCount = LOS_TickCountGet(); + if(0 != tickCount) { + dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)tickCount); + } +} +``` + +### 结果验证 + +编译运行得到的结果为: + +时间转换: + +``` +tick = 1000 +ms = 1000 +``` + +时间统计和时间延迟: + +``` +LOS_CyclePerTickGet = 495000 +LOS_TickCountGet = 1 +LOS_TickCountGet after delay = 201 +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-basic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..fd6774bee47339f547587c7461b536ac5b8373e1 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-basic.md @@ -0,0 +1,15 @@ +# 基础内核 + +- **[中断管理](kernel-lite-mini-basic-interrupt.md)** + +- **[任务管理](kernel-lite-mini-basic-task.md)** + +- **[内存管理](kernel-lite-mini-basic-memory.md)** + +- **[内核通信机制](kernel-lite-mini-basic-ipc.md)** + +- **[时间管理](kernel-lite-basic-mini-time.md)** + +- **[软件定时器](kernel-lite-mini-basic-soft.md)** + + diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-17.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-cpup-basic.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-17.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-extend-cpup-basic.md diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-18.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-cpup-guide.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-18.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-extend-cpup-guide.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-extend-cpup.md b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-cpup.md new file mode 100644 index 0000000000000000000000000000000000000000..e49d8a7175b407625353d87a11996a65bf990992 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-cpup.md @@ -0,0 +1,7 @@ +# CPU占用率 + +- **[基本概念](kernel-lite-mini-extend-cpup-basic.md)** + +- **[开发指导](kernel-lite-mini-extend-cpup-guide.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-fat.md b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-fat.md new file mode 100644 index 0000000000000000000000000000000000000000..d96f14f3435c61968447f9b3cbfb62ccd0fce5c7 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-fat.md @@ -0,0 +1,176 @@ +# FAT + +- [基本概念](#section1772629121418) +- [开发指导](#section1149072811148) + - [驱动适配](#section19174939191414) + - [开发流程](#section131211626151513) + - [编程实例](#section206071303163) + - [实例描述](#section45337345313) + - [示例代码](#section119813171539) + - [结果验证](#section7987101232311) + + +## 基本概念 + +FAT文件系统是File Allocation Table(文件配置表)的简称,主要包括DBR区、FAT区、DATA区三个区域。其中,FAT区各个表项记录存储设备中对应簇的信息,包括簇是否被使用、文件下一个簇的编号、是否文件结尾等。FAT文件系统有FAT12、FAT16、FAT32等多种格式,其中,12、16、32表示对应格式中FAT表项的字节数。FAT文件系统支持多种介质,特别在可移动存储介质(U盘、SD卡、移动硬盘等)上广泛使用,使嵌入式设备和Windows、Linux等桌面系统保持很好的兼容性,方便用户管理操作文件。 + +OpenHarmony内核支持FAT12、FAT16与FAT32三种格式的FAT文件系统,具有代码量小、资源占用小、可裁切、支持多种物理介质等特性,并且与Windows、Linux等系统保持兼容,支持多设备、多分区识别等功能。OpenHarmony内核支持硬盘多分区,可以在主分区以及逻辑分区上创建FAT文件系统。 + +## 开发指导 + +### 驱动适配 + +FAT文件系统的使用需要底层MMC相关驱动的支持。在一个带MMC存储设备的板子上运行FATFS,需要: + +1、适配板端EMMC驱动,实现disk\_status、disk\_initialize、disk\_read、disk\_write、disk\_ioctl接口; + +2、新增fs\_config.h文件,配置FS\_MAX\_SS(存储设备最大sector大小)、FF\_VOLUME\_STRS(分区名)等信息,例如: + +``` +#define FF_VOLUME_STRS "system", "inner", "update", "user" +#define FS_MAX_SS 512 +#define FAT_MAX_OPEN_FILES 50 +``` + +### 开发流程 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- FATFS文件与目录操作: +> - 单个文件大小不超过4G。 +> - 支持同时打开的文件数最大为FAT\_MAX\_OPEN\_FILES,文件夹数最大为FAT\_MAX\_OPEN\_DIRS。 +> - 暂不支持根目录管理,文件/目录名均以分区名开头,例如“user/testfile”就是在“user”分区下名为“testfile”的文件或目录。 +> - 若需要同时多次打开同一文件,必须全部使用只读方式(O\_RDONLY)。以可写方式(O\_RDWR、O\_WRONLY等)只能打开一次。 +> - 读写指针未分离,例如以O\_APPEND(追加写)方式打开文件后,读指针也在文件尾,从头读文件前需要用户手动置位。 +> - 暂不支持文件与目录的权限管理。 +> - stat及fstat接口暂不支持查询修改时间、创建时间和最后访问时间。微软FAT协议不支持1980年以前的时间。 +>- FATFS分区挂载与卸载: +> - 支持以只读属性挂载分区。当mount函数的入参为MS\_RDONLY时,所有的带有写入的接口,如write、mkdir、unlink,以及非O\_RDONLY属性的open,将均被拒绝。 +> - mount支持通过MS\_REMOUNT标记修改已挂载分区的权限。 +> - 在umount操作前,需确保所有目录及文件全部关闭。 +> - umount2支持通过MNT\_FORCE参数强制关闭所有文件与文件夹并umount,但可能造成数据丢失,请谨慎使用。 +>- FATFS支持重新划分存储设备分区、格式化分区,对应接口为fatfs\_fdisk与fatfs\_format: +> - 在fatfs\_format操作之前,若需要格式化的分区已挂载,需确保分区中的所有目录及文件全部关闭,并且分区umount。 +> - 在fatfs\_fdisk操作前,需要该设备中的所有分区均已umount。 +> - fatfs\_fdisk与fatfs\_format会造成设备数据丢失,请谨慎使用。 + +### 编程实例 + +### 实例描述 + +本实例实现以下功能: + +1. 创建目录“user/test” +2. 在“user/test”目录下创建文件“file.txt” +3. 在文件起始位置写入“Hello OpenHarmony!” +4. 将文件内容刷入设备中 +5. 设置偏移到文件起始位置 +6. 读取文件内容 +7. 关闭文件 +8. 删除文件 +9. 删除目录 + +### 示例代码 + +前提条件: + +- 系统已将MMC设备分区挂载到user目录 + +代码实现如下: + +``` +#include +#include +#include "sys/stat.h" +#include "fcntl.h" +#include "unistd.h" + +#define LOS_OK 0 +#define LOS_NOK -1 + +int FatfsTest(void) +{ + int ret; + int fd = -1; + ssize_t len; + off_t off; + char dirName[20] = "user/test"; + char fileName[20] = "user/test/file.txt"; + char writeBuf[20] = "Hello OpenHarmony!"; + char readBuf[20] = {0}; + + /* 创建目录“user/test” */ + ret = mkdir(dirName, 0777); + if (ret != LOS_OK) { + printf("mkdir failed.\n"); + return LOS_NOK; + } + + /* 创建可读写文件"user/test/file.txt" */ + fd = open(fileName, O_RDWR | O_CREAT, 0777); + if (fd < 0) { + printf("open file failed.\n"); + return LOS_NOK; + } + + /* 将writeBuf中的内容写入文件 */ + len = write(fd, writeBuf, strlen(writeBuf)); + if (len != strlen(writeBuf)) { + printf("write file failed.\n"); + return LOS_NOK; + } + + /* 将文件内容刷入存储设备中 */ + ret = fsync(fd); + if (ret != LOS_OK) { + printf("fsync failed.\n"); + return LOS_NOK; + } + + /* 将读写指针偏移至文件头 */ + off = lseek(fd, 0, SEEK_SET); + if (off != 0) { + printf("lseek failed.\n"); + return LOS_NOK; + } + + /* 将文件内容读出至readBuf中,读取长度为readBuf大小 */ + len = read(fd, readBuf, sizeof(readBuf)); + if (len != strlen(writeBuf)) { + printf("read file failed.\n"); + return LOS_NOK; + } + printf("%s\n", readBuf); + + /* 关闭文件 */ + ret = close(fd); + if (ret != LOS_OK) { + printf("close failed.\n"); + return LOS_NOK; + } + + /* 删除文件"user/test/file.txt" */ + ret = unlink(fileName); + if (ret != LOS_OK) { + printf("unlink failed.\n"); + return LOS_NOK; + } + + /* 删除目录“user/test” */ + ret = rmdir(dirName); + if (ret != LOS_OK) { + printf("rmdir failed.\n"); + return LOS_NOK; + } + + return LOS_OK; +} +``` + +### 结果验证 + +编译运行得到的结果为: + +``` +Hello OpenHarmony! +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit-basic.md b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..17423ee5c40ff14e3d771ae1459055e49c1b52f8 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit-basic.md @@ -0,0 +1,72 @@ +# 基本概念 + +- [运行机制](#section10284121317365) + - [日志方式](#section13804114513361) + - [Cow机制](#section172771130193610) + - [LittleFS掉电保护](#section42941021173614) + + +LittleFS主要用在微控制器和Flash上,是一种嵌入式文件系统,具有掉电恢复、擦写均衡、节省ROM/RAM空间等特点。 + +## 运行机制 + +最经典的掉电保护方法有两种,一种是使用日志,一种是通过COW方式。LittleFS结合了两种方法,并优化了两种方案的缺点,提供了一套掉电保护策略 + +### 日志方式 + +**图 1** 日志方式示意图 +![](figure/日志方式示意图.png "日志方式示意图") + +具体步骤为: + +1. 写入数据之前,先在日志区存储开始标志,记录要写入的数据位置和大小; +2. 待写入的数据写入日志区; +3. 待写入的数据写入数据区; +4. 写入完成之后,在日志区记录结束标志。 + +模拟掉电场景: + +1. 步骤1完成,步骤2没有完成;重启之后,保持原来的数据,日志无效; +2. 步骤1,2完成了,步骤3没有完成,尝试把步骤2的数据写入到数据区; +3. 步骤1,2,3完成了,步骤4没有完成,同样尝试把步骤2的数据写入到数据区; + +### Cow机制 + +**图 2** Cow机制示意图 +![](figure/Cow机制示意图.png "Cow机制示意图") + +具体步骤为: + +1. 想更新节点F的数据,先申请一个新的节点,把F的旧数据拷贝过去,然后更新新的数据; +2. 把父节点的指针指向新的节点,去掉旧节点的指针。 + +模拟掉电场景: + +步骤1完成了,步骤2没有完成,则使用旧的数据,新的节点变成孤儿节点。 + +### LittleFS掉电保护 + +LittleFS结合了日志方式和COW机制两种方式进行掉电保护,并且优化了两种方案。 + +文件系统有三要素,超级块,inode,以及数据,对应LittleFS来说,它把超级块以及inode通过日志的方式存储,两种采用统一的存储结构,后文称两者为元数据;普通数据则采用cow的方式存储,采用czt逆序链表的方式。 + +![](figure/zh-cn_image_0000001124307264.png) + +**元数据的存储** + +元数据(对应root,dir)采用双block的方式存储,互为备份,每个block都有一个revision序号,值越大,表示block的数据越新,每个block默认可以存储最多0xff个文件的数据,如果超过这个值,则需要compact(压缩)。 + +Compact是干什么呢? 即当数据的大小大于某个值的时候,把数据整合,剔除同一个id的旧的数据,然后写入到备份block里面。如图所示: + +**图 3** 元数据存储示意图 +![](figure/元数据存储示意图.png "元数据存储示意图") + +**普通数据的存储** + +LittleFS的数据采用链表的方式逆向管理。 + +![](figure/zh-cn_image_0000001132085260.png) + +1. 采用逆向的指针,这样常规的追加数据,不需要额外的开销来重新建立所有的索引; +2. 每个偶数block有多个指针,指向更远的数据,这样可以在检索的时候加快速度。 + diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-22.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit-guide.md similarity index 100% rename from "zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-22.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit-guide.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit.md b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit.md new file mode 100644 index 0000000000000000000000000000000000000000..b0ffac3d6795718298342eb939196b45636ad6d0 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file-lit.md @@ -0,0 +1,7 @@ +# LittleFS + +- **[基本概念](kernel-lite-mini-extend-file-lit-basic.md)** + +- **[开发指导](kernel-lite-mini-extend-file-lit-guide.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file.md b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file.md new file mode 100644 index 0000000000000000000000000000000000000000..c7ee5fabfdca2b92b4cba55758bf298edb554a72 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-file.md @@ -0,0 +1,204 @@ +# 文件系统 + +当前支持的文件系统有FATFS与LittleFS,支持的功能如下表所示: + +**表 1** ****功能列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

FATFS

+

LITTELFS

+

文件操作

+

open

+

打开文件

+

支持

+

支持

+

close

+

关闭文件

+

支持

+

支持

+

read

+

读取文件内容

+

支持

+

支持

+

write

+

往文件写入内容

+

支持

+

支持

+

lseek

+

设置文件偏移位置

+

支持

+

支持

+

unlink

+

删除文件

+

支持

+

支持

+

rename

+

重命名文件

+

支持

+

支持

+

fstat

+

通过文件句柄获取文件信息

+

支持

+

支持

+

stat

+

通过文件路径名获取文件信息

+

支持

+

支持

+

fsync

+

文件内容刷入存储设备

+

支持

+

支持

+

目录操作

+

mkdir

+

创建目录

+

支持

+

支持

+

opendir

+

打开目录

+

支持

+

支持

+

readdir

+

读取目录项内容

+

支持

+

支持

+

closedir

+

关闭目录

+

支持

+

支持

+

rmdir

+

删除目录

+

支持

+

支持

+

分区操作

+

mount

+

分区挂载

+

支持

+

支持

+

umount

+

分区卸载

+

支持

+

支持

+

umount2

+

分区卸载,可通过MNT_FORCE参数进行强制卸载

+

支持

+

不支持

+

statfs

+

获取分区信息

+

支持

+

不支持

+
+ +- **[FAT](kernel-lite-mini-extend-file-fat.md)** + +- **[LittleFS](kernel-lite-mini-extend-file-lit.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-extend-support.md b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-support.md new file mode 100644 index 0000000000000000000000000000000000000000..c0b1ed529142bba08729d4cc769f47554b4136ec --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-extend-support.md @@ -0,0 +1,86 @@ +# C++支持 + +- [基本概念](#section11374125415814) + - [运行机制](#section125251720195) + +- [开发指导](#section166302407911) + - [接口说明](#section1881825119919) + - [开发流程](#section76371145108) + - [编程实例](#section994427141111) + + +## 基本概念 + +C++作为目前使用最广泛的编程语言之一,支持类、封装、重载等特性,是在C语言基础上开发的一种面向对象的编程语言。 + +### 运行机制 + +C++代码的识别主要由编译器支持,系统主要对全局对象进行构造函数调用,进行初始化操作。 + +## 开发指导 + +### 接口说明 + +**表 1** C++支持接口 + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

使用C++特性的前置条件

+

LOS_CppSystemInit

+

C++构造函数初始化

+
+ +### 开发流程 + +使用C++特性之前,需要调用函数LOS\_CppSystemInit,实现C++构造函数初始化,其中被初始化的构造函数存在init\_array这个段中,段区间通过变量\_\_init\_array\_start\_\_、\_\_init\_array\_end\_\_传递。 + +**表 2** 参数说明 + + + + + + + + + + + + + +

参数

+

参数说明

+

__init_array_start__

+

init_array段起始位置

+

__init_array_end__

+

init_array段结束位置

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>调用该函数时,一定要在c++业务前。另外部分与系统资源强相关的类或接口,如std::thread,std::mutex等,在三方编译器使用的c库非musl c时,存在兼容性问题,不建议使用。 + +### 编程实例 + +``` +void app_init(void) +{ +...... +/* 启动阶段C++初始化 */ +LOS_CppSystemInit((UINTPTR)&__init_array_start__, (UINTPTR)&__init_array_end__); +/* C++业务 */ +...... +} +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-extend.md b/zh-cn/device-dev/kernel/kernel-lite-mini-extend.md new file mode 100644 index 0000000000000000000000000000000000000000..1d413abe902d5f6d590db74545381a6349dc1c23 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-extend.md @@ -0,0 +1,9 @@ +# 扩展组件 + +- **[C++支持](kernel-lite-mini-extend-support.md)** + +- **[CPU占用率](kernel-lite-mini-extend-cpup.md)** + +- **[文件系统](kernel-lite-mini-extend-file.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-cet.md b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-cet.md new file mode 100644 index 0000000000000000000000000000000000000000..20a2b532d3a54324a02c9dd10fb8f3fdfed7487e --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-cet.md @@ -0,0 +1,85 @@ +# 踩内存检测 + +- [基础概念](#section17368154517335) +- [功能配置](#section4696190123420) +- [开发指导](#section672362973417) + - [开发流程](#section026014863416) + - [编程实例](#section186311302356) + - [示例代码](#section12709533354) + - [结果验证](#section81214126369) + + +## 基础概念 + +踩内存检测机制作为内核的可选功能,用于检测动态内存池的完整性。通过该机制,可以及时发现内存池是否发生了踩内存问题,并给出错误信息,便于及时发现系统问题,提高问题解决效率,降低问题定位成本。 + +## 功能配置 + +LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。 + +1. 开启这个功能,每次申请内存,会实时检测内存池的完整性。 +2. 如果不开启该功能,也可以调用LOS\_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。 + +由于该功能只会检测出哪个内存节点被破坏了,并给出前节点信息(因为内存分布是连续的,当前节点最有可能被前节点破坏)。如果要进一步确认前节点在哪里申请的,需开启内存泄漏检测功能,通过LR记录,辅助定位。 + +>![](../public_sys-resources/icon-caution.gif) **注意:** +>开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS\_MemIntegrityCheck接口检测。 + +## 开发指导 + +### 开发流程 + +通过调用LOS\_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。 + +### 编程实例 + +本实例实现如下功能: + +1. 申请两个物理上连续的内存块; +2. 通过memset构造越界访问,踩到下个节点的头4个字节; +3. 调用LOS\_MemIntegrityCheck检测是否发生踩内存。 + +### 示例代码 + +代码实现如下: + +``` +#include +#include +#include "los_memory.h" +#include "los_config.h" + +void MemIntegrityTest(void) +{ + /* 申请两个物理连续的内存块 */ + void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); + void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); + /* 第一个节点内存块大小是8字节,那么12字节的清零,会踩到第二个内存节点的节点头,构造踩内存场景 */ + memset(ptr1, 0, 8 + 4); + LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR); +} +``` + +### 结果验证 + +编译运行输出log如下: + +``` +[ERR][OsMemMagicCheckPrint], 2028, memory check error! +memory used but magic num wrong, magic num = 0x00000000 /* 提示信息,检测到哪个字段被破坏了,用例构造了将下个节点的头4个字节清零,即魔鬼数字字段 */ + + broken node head: 0x20003af0 0x00000000 0x80000020, prev node head: 0x20002ad4 0xabcddcba 0x80000020 +/* 被破坏节点和其前节点关键字段信息,分别为其前节点地址、节点的魔鬼数字、节点的sizeAndFlag;可以看出被破坏节点的魔鬼数字字段被清零,符合用例场景 */ + + broken node head LR info: /* 节点的LR信息需要开启内存检测功能才有有效输出 */ + LR[0]:0x0800414e + LR[1]:0x08000cc2 + LR[2]:0x00000000 + + pre node head LR info: /* 通过LR信息,可以在汇编文件中查找前节点是哪里申请,然后排查其使用的准确性 */ + LR[0]:0x08004144 + LR[1]:0x08000cc2 + LR[2]:0x00000000 +[ERR]Memory interity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* 被破坏节点和其前节点的地址 */ +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-det.md b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-det.md new file mode 100644 index 0000000000000000000000000000000000000000..7f49df4fc87257c46fbfdcdaa9dad954d1962484 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-det.md @@ -0,0 +1,128 @@ +# 内存泄漏检测 + +- [基础概念](#section1026719436293) +- [功能配置](#section13991354162914) +- [开发指导](#section95828159308) + - [开发流程](#section369844416304) + - [编程实例](#section460801313313) + - [示例代码](#section96539275311) + - [结果验证](#section20527343183119) + + +## 基础概念 + +内存泄漏检测机制作为内核的可选功能,用于辅助定位动态内存泄漏问题。开启该功能,动态内存机制会自动记录申请内存时的函数调用关系(下文简称LR)。如果出现泄漏,就可以利用这些记录的信息,找到内存申请的地方,方便进一步确认。 + +## 功能配置 + +1. LOSCFG\_MEM\_LEAKCHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。 +2. LOSCFG\_MEM\_RECORD\_LR\_CNT:记录的LR层数,默认3层;每层LR消耗sizeof\(void \*\)字节数的内存。 +3. LOSCFG\_MEM\_OMIT\_LR\_CNT:忽略的LR层数,默认4层,即从调用LOS\_MemAlloc的函数开始记录,可根据实际情况调整。为啥需要这个配置?有3点原因如下: + - LOS\_MemAlloc接口内部也有函数调用; + - 外部可能对LOS\_MemAlloc接口有封装; + - LOSCFG\_MEM\_RECORD\_LR\_CNT 配置的LR层数有限; + + +正确配置这个宏,将无效的LR层数忽略,就可以记录有效的LR层数,节省内存消耗。 + +## 开发指导 + +### 开发流程 + +该调测功能可以分析关键的代码逻辑中是否存在内存泄漏。开启这个功能,每次申请内存时,会记录LR信息。在需要检测的代码段前后,调用LOS\_MemUsedNodeShow接口,每次都会打印指定内存池已使用的全部节点信息,对比前后两次的节点信息,新增的节点信息就是疑似泄漏的内存节点。通过LR,可以找到具体申请的代码位置,进一步确认是否泄漏。 + +调用LOS\_MemUsedNodeShow接口输出的节点信息格式如下:每1行为一个节点信息;第1列为节点地址,可以根据这个地址,使用GDB等手段查看节点完整信息;第2列为节点的大小,等于节点头大小+数据域大小;第3\~5列为函数调用关系LR地址,可以根据这个值,结合汇编文件,查看该节点具体申请的位置。 + +``` +node size LR[0] LR[1] LR[2] +0x10017320: 0x528 0x9b004eba 0x9b004f60 0x9b005002 +0x10017848: 0xe0 0x9b02c24e 0x9b02c246 0x9b008ef0 +0x10017928: 0x50 0x9b008ed0 0x9b068902 0x9b0687c4 +0x10017978: 0x24 0x9b008ed0 0x9b068924 0x9b0687c4 +0x1001799c: 0x30 0x9b02c24e 0x9b02c246 0x9b008ef0 +0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 +``` + +>![](../public_sys-resources/icon-caution.gif) **注意:** +>开启内存检测会影响内存申请的性能,且每个内存节点都会记录LR地址,内存开销也加大。 + +### 编程实例 + +本实例实现如下功能:构建内存泄漏代码段。 + +1. 调用LOS\_MemUsedNodeShow接口,输出全部节点信息打印; +2. 申请内存,但没有释放,模拟内存泄漏; +3. 再次调用LOS\_MemUsedNodeShow接口,输出全部节点信息打印; +4. 将两次log进行对比,得出泄漏的节点信息; +5. 通过LR地址,找出泄漏的代码位置; + +### 示例代码 + +代码实现如下: + +``` +#include +#include +#include "los_memory.h" +#include "los_config.h" + +void MemLeakTest(void) +{ + LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR); + void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); + void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); + LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR); +} +``` + +### 结果验证 + +编译运行输出log如下: + +``` +node size LR[0] LR[1] LR[2] +0x20001b04: 0x24 0x08001a10 0x080035ce 0x080028fc +0x20002058: 0x40 0x08002fe8 0x08003626 0x080028fc +0x200022ac: 0x40 0x08000e0c 0x08000e56 0x0800359e +0x20002594: 0x120 0x08000e0c 0x08000e56 0x08000c8a +0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220 + +node size LR[0] LR[1] LR[2] +0x20001b04: 0x24 0x08001a10 0x080035ce 0x080028fc +0x20002058: 0x40 0x08002fe8 0x08003626 0x080028fc +0x200022ac: 0x40 0x08000e0c 0x08000e56 0x0800359e +0x20002594: 0x120 0x08000e0c 0x08000e56 0x08000c8a +0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220 +0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 +0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 +``` + +对比两次log,差异如下,这些内存节点就是疑似泄漏的内存块: + +``` +0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 +0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 +``` + +部分汇编文件如下: + +``` + MemLeakTest: + 0x80041d4: 0xb510 PUSH {R4, LR} + 0x80041d6: 0x4ca8 LDR.N R4, [PC, #0x2a0] ; g_memStart + 0x80041d8: 0x0020 MOVS R0, R4 + 0x80041da: 0xf7fd 0xf93e BL LOS_MemUsedNodeShow ; 0x800145a + 0x80041de: 0x2108 MOVS R1, #8 + 0x80041e0: 0x0020 MOVS R0, R4 + 0x80041e2: 0xf7fd 0xfbd9 BL LOS_MemAlloc ; 0x8001998 + 0x80041e6: 0x2108 MOVS R1, #8 + 0x80041e8: 0x0020 MOVS R0, R4 + 0x80041ea: 0xf7fd 0xfbd5 BL LOS_MemAlloc ; 0x8001998 + 0x80041ee: 0x0020 MOVS R0, R4 + 0x80041f0: 0xf7fd 0xf933 BL LOS_MemUsedNodeShow ; 0x800145a + 0x80041f4: 0xbd10 POP {R4, PC} + 0x80041f6: 0x0000 MOVS R0, R0 +``` + +其中,通过查找0x080041ee,就可以发现该内存节点是在MemLeakTest接口里申请的且是没有释放的。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-mes.md b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-mes.md new file mode 100644 index 0000000000000000000000000000000000000000..0dd4f930425a171933e8dafe2f690804111ff257 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug-mes.md @@ -0,0 +1,107 @@ +# 内存信息统计 + +- [基础概念](#section52691565235) +- [功能配置](#section470611682411) +- [开发指导](#section9368374243) + - [开发流程](#section679912407257) + - [编程实例](#section1025453412611) + - [示例代码](#section165277971315) + - [结果验证](#section3460102414271) + + +## 基础概念 + +内存信息包括内存池大小、内存使用量、剩余内存大小、最大空闲内存、内存水线、内存节点数统计、碎片率等。 + +- 内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小; + +- 碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-最大空闲内存块大小/剩余内存大小)来度量; + +- 其他参数:通过调用接口(详见[内存管理](kernel-lite-mini-basic-memory.md)章节接口说明),扫描内存池的节点信息,统计出相关信息。 + +## 功能配置 + +LOSCFG\_MEM\_WATERLINE:开关宏,默认打开;若关闭这个功能,在target\_config.h中将这个宏定义为0。如需获取内存水线,需要打开该配置。 + +## 开发指导 + +### 开发流程 + +关键结构体介绍: + +``` +typedef struct { + UINT32 totalUsedSize; // 内存池的内存使用量 + UINT32 totalFreeSize; // 内存池的剩余内存大小 + UINT32 maxFreeNodeSize; // 内存池的最大空闲内存块大小 + UINT32 usedNodeNum; // 内存池的非空闲内存块个数 + UINT32 freeNodeNum; // 内存池的空闲内存块个数 +#if (LOSCFG_MEM_WATERLINE == 1) // 默认打开,如需关闭,在target_config.h中将该宏设置为0 + UINT32 usageWaterLine; // 内存池的水线值 +#endif +} LOS_MEM_POOL_STATUS; +``` + +- 内存水线获取:调用LOS\_MemInfoGet接口,第1个参数是内存池首地址,第2个参数是LOS\_MEM\_POOL\_STATUS类型的句柄,其中字段usageWaterLine即水线值。 + +- 内存碎片率计算:同样调用LOS\_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 + +### 编程实例 + +本实例实现如下功能: + +1.创建一个监控线程,用于获取内存池的信息; + +2.调用LOS\_MemInfoGet接口,获取内存池的基础信息; + +3.利用公式算出使用率及碎片率。 + +### 示例代码 + +代码实现如下: + +``` +#include +#include +#include "los_task.h" +#include "los_memory.h" +#include "los_config.h" + +void MemInfoTaskFunc(void) +{ + LOS_MEM_POOL_STATUS poolStatus = {0}; + LOS_MemInfoGet(pool, &poolStatus); + /* 算出内存池当前的碎片率百分比 */ + unsigned char fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize; + /* 算出内存池当前的使用率百分比 */ + unsigned char usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool); + printf("usage = %d, fragment = %d, maxFreeSize = %d, totalFreeSize = %d, waterLine = %d\n", usage, fragment, poolStatus.maxFreeNodeSize, + poolStatus.totalFreeSize, poolStatus.usageWaterLine); +} + +int MemTest(void) +{ + unsigned int ret; + unsigned int taskID; + TSK_INIT_PARAM_S taskStatus = {0}; + taskStatus.pfnTaskEntry = (TSK_ENTRY_FUNC)MemInfoTaskFunc; + taskStatus.uwStackSize = 0x1000; + taskStatus.pcName = "memInfo"; + taskStatus.usTaskPrio = 10; + ret = LOS_TaskCreate(&taskID, &taskStatus); + if (ret != LOS_OK) { + printf("task create failed\n"); + return -1; + } + return 0; +} +``` + +### 结果验证 + +编译运行输出的结果如下: + +``` +usage = 22, fragment = 3, maxFreeSize = 49056, totalFreeSize = 50132, waterLine = 1414 +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug.md b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug.md new file mode 100644 index 0000000000000000000000000000000000000000..0c4474cd15eb7b42235cdcc139be9a8f6dccb6b7 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-debug.md @@ -0,0 +1,11 @@ +# 内存调测 + +内存调测方法旨在辅助定位动态内存相关问题,提供了基础的动态内存池信息统计手段,向用户呈现内存池水线、碎片率等信息;提供了内存泄漏检测手段,方便用户准确定位存在内存泄漏的代码行,也可以辅助分析系统各个模块内存的使用情况;提供了踩内存检测手段,可以辅助定位越界踩内存的场景。 + +- **[内存信息统计](kernel-lite-mini-inner-debug-mes.md)** + +- **[内存泄漏检测](kernel-lite-mini-inner-debug-det.md)** + +- **[踩内存检测](kernel-lite-mini-inner-debug-cet.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-inner-exception.md b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-exception.md new file mode 100644 index 0000000000000000000000000000000000000000..5828d645f139907f9d8763226b3f4dbb269b2965 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-exception.md @@ -0,0 +1,329 @@ +# 异常调测 + +- [基本概念](#section2741911123412) +- [运行机制](#section16618124317346) +- [接口说明](#section16111931351) +- [使用指导](#section16317163520350) + - [开发流程](#section13457839133618) + - [定位流程](#section197332323815) + + +## 基本概念 + +OpenHarmony LiteOS-M提供异常接管调测手段,帮助开发者定位分析问题。异常接管是操作系统对运行期间发生的异常情况进行处理的一系列动作,例如打印异常发生时异常类型、发生异常时的系统状态、当前函数的调用栈信息、CPU现场信息、任务调用堆栈等信息。 + +## 运行机制 + +栈帧用于保存函数调用过程中的函数参数、变量、返回值等信息。调用函数时,会创建子函数的栈帧,同时将函数入参、局部变量、寄存器入栈。栈帧从高地址向低地址生长。以ARM32 CPU架构为例,每个栈帧中都会保存PC、LR、SP和FP寄存器的历史值。LR链接寄存器(Link Register)指向函数的返回地址,FP帧指针寄存器(Frame Point)指向当前函数的父函数的栈帧起始地址。利用FP寄存器可以得到父函数的栈帧,从栈帧中获取父函数的FP,就可以得到祖父函数的栈帧,以此类推,可以追溯程序调用栈,得到函数间的调用关系。 + +当系统发生异常时,系统打印异常函数的栈帧中保存的寄存器内容,以及父函数、祖父函数的栈帧中的LR链接寄存器、FP帧指针寄存器内容,用户就可以据此追溯函数间的调用关系,定位异常原因。 + +堆栈分析原理如下图所示,实际堆栈信息根据不同CPU架构有所差异,此处仅做示意。 + +**图 1** 堆栈分析原理示意图 +![](figure/堆栈分析原理示意图.png "堆栈分析原理示意图") + +图中不同颜色的寄存器表示不同的函数。可以看到函数调用过程中,寄存器的保存。通过FP寄存器,栈回溯到异常函数的父函数,继续按照规律对栈进行解析,推出函数调用关系,方便用户定位问题。 + +## 接口说明 + +OpenHarmony LiteOS-M内核的回溯栈模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表 1** 回溯栈模块接口 + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

回溯栈接口

+

LOS_BackTrace

+

打印调用处的函数调用栈关系。

+

LOS_RecordLR

+

在无法打印的场景,用该接口获取调用处的函数调用栈关系。

+
+ +## 使用指导 + +### 开发流程 + +开启异常调测的典型流程如下: + +1. 配置异常接管相关宏。 + + 需要在target\_config.h头文件中修改配置: + + + + + + + + + + + + + + + + +

配置项

+

含义

+

设置值

+

LOSCFG_BACKTRACE_DEPTH

+

函数调用栈深度,默认15层

+

15

+

LOSCFG_BACKTRACE_TYPE

+

回溯栈类型:

+

0:表示关闭该功能;

+

1:表示支持Cortex-m系列硬件的函数调用栈解析;

+

2:表示用于Risc-v系列硬件的函数调用栈解析;

+

根据工具链类型设置1或2

+
+ + +1. 使用示例中有问题的代码,编译、运行工程,在串口终端中查看异常信息输出。示例代码模拟异常代码,实际产品开发时使用异常调测机制定位异常问题。 + + 本示例演示异常输出,包含1个任务,该任务入口函数模拟若干函数调用,最终调用一个模拟异常的函数。代码实现如下: + + ``` + #include + #include "los_config.h" + #include "los_interrupt.h" + #include "los_task.h" + + UINT32 g_taskExcId; + #define TSK_PRIOR 4 + + /* 模拟异常函数 */ + + UINT32 Get_Result_Exception_0(UINT16 dividend){ + UINT32 divisor = 0; + UINT32 result = dividend / divisor; + return result; + } + + UINT32 Get_Result_Exception_1(UINT16 dividend){ + return Get_Result_Exception_0(dividend); + } + + UINT32 Get_Result_Exception_2(UINT16 dividend){ + return Get_Result_Exception_1(dividend); + } + + UINT32 Example_Exc(VOID) + { + UINT32 ret; + + printf("Enter Example_Exc Handler.\r\n"); + + /* 模拟函数调用 */ + ret = Get_Result_Exception_2(TSK_PRIOR); + printf("Divided result =%u.\r\n", ret); + + printf("Exit Example_Exc Handler.\r\n"); + return ret; + } + + + /* 任务测试入口函数,创建一个会发生异常的任务 */ + UINT32 Example_Exc_Entry(VOID) + { + UINT32 ret; + TSK_INIT_PARAM_S initParam; + + /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ + LOS_TaskLock(); + + printf("LOS_TaskLock() Success!\r\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Exc; + initParam.usTaskPrio = TSK_PRIOR; + initParam.pcName = "Example_Exc"; + initParam.uwStackSize = LOSCFG_SECURE_STACK_DEFAULT_SIZE; + /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ + ret = LOS_TaskCreate(&g_taskExcId, &initParam); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + + printf("Example_Exc create Failed!\r\n"); + return LOS_NOK; + } + + printf("Example_Exc create Success!\r\n"); + + /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ + LOS_TaskUnlock(); + + return LOS_OK; + } + ``` + + +1. 上述代码串口终端输出异常信息如下: + + ``` + entering kernel init... + LOS_TaskLock() Success! + Example_Exc create Success! + Entering scheduler + Enter Example_Exc Handler. + *************Exception Information************** + Type = 10 + ThrdPid = 4 + Phase = exc in task + FaultAddr = 0xabababab + Current task info: + Task name = Example_Exc + Task ID = 4 + Task SP = 0x200051ac + Task ST = 0x20004ff0 + Task SS = 0x200 + Exception reg dump: + PC = 0x80037da + LR = 0x80037fe + SP = 0x20005190 + R0 = 0x4 + R1 = 0x40 + R2 = 0x4 + R3 = 0x0 + R4 = 0x4040404 + R5 = 0x5050505 + R6 = 0x6060606 + R7 = 0x20005190 + R8 = 0x8080808 + R9 = 0x9090909 + R10 = 0x10101010 + R11 = 0x11111111 + R12 = 0x12121212 + PriMask = 0x0 + xPSR = 0x41000000 + ----- backtrace start ----- + backtrace 0 -- lr = 0x800381a + backtrace 1 -- lr = 0x8003836 + backtrace 2 -- lr = 0x8005a4e + backtrace 3 -- lr = 0x8000494 + backtrace 4 -- lr = 0x8008620 + backtrace 5 -- lr = 0x800282c + backtrace 6 -- lr = 0x80008a0 + backtrace 7 -- lr = 0x80099f8 + backtrace 8 -- lr = 0x800a01a + backtrace 9 -- lr = 0x800282c + backtrace 10 -- lr = 0x80008a0 + backtrace 11 -- lr = 0x80099f8 + backtrace 12 -- lr = 0x8009bf0 + backtrace 13 -- lr = 0x8009c52 + backtrace 14 -- lr = 0x80099aa + ----- backtrace end ----- + + TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID name + --- -------- -------- --------- ---------- ---------- ---------- --------- ----- ---- + 0 0 Pend 0x2d0 0x104 0x200029bc 0x200027f0 0x0 0xffff Swt_Task + 1 31 Ready 0x500 0x44 0x20002f84 0x20002ac8 0x0 0xffff IdleCore000 + 2 6 Ready 0x1000 0x44 0x20003f94 0x20002fd8 0x0 0xffff TaskSampleEntry1 + 3 7 Ready 0x1000 0x44 0x20004f9c 0x20003fe0 0x0 0xffff TaskSampleEntry2 + 4 4 Running 0x200 0xec 0x200051ac 0x20004ff0 0x0 0xffff Example_Exc + + OS exception NVIC dump: + interrupt enable register, base address: 0xe000e100, size: 0x20 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt pending register, base address: 0xe000e200, size: 0x20 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt active register, base address: 0xe000e300, size: 0x20 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt priority register, base address: 0xe000e400, size: 0xf0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt exception register, base address: 0xe000ed18, size: 0xc + 0x0 0x0 0xf0f00000 + interrupt shcsr register, base address: 0xe000ed24, size: 0x4 + 0x70008 + interrupt control register, base address: 0xe000ed04, size: 0x4 + 0x400f806 + + memory pools check: + system heap memcheck over, all passed! + memory pool check end! + ``` + + +### 定位流程 + +异常接管一般的定位步骤如下: + +1. 打开编译后生成的镜像反汇编(asm)文件。如果默认没有生成,可以使用objdump工具生成,命令为: + + ``` + arm-none-eabi-objdump -S -l XXX.elf + ``` + + +1. 搜索PC指针(指向当前正在执行的指令)在asm中的位置,找到发生异常的函数。 + + PC地址指向发生异常时程序正在执行的指令。在当前执行的二进制文件对应的asm文件中,查找PC值0x80037da,找到当前CPU正在执行的指令行,反汇编如下所示: + + ``` + UINT32 Get_Result_Exception_0(UINT16 dividend){ + 80037c8: b480 push {r7} + 80037ca: b085 sub sp, #20 + 80037cc: af00 add r7, sp, #0 + 80037ce: 4603 mov r3, r0 + 80037d0: 80fb strh r3, [r7, #6] + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:10 + UINT32 divisor = 0; + 80037d2: 2300 movs r3, #0 + 80037d4: 60fb str r3, [r7, #12] + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:11 + UINT32 result = dividend / divisor; + 80037d6: 88fa ldrh r2, [r7, #6] + 80037d8: 68fb ldr r3, [r7, #12] + 80037da: fbb2 f3f3 udiv r3, r2, r3 + 80037de: 60bb str r3, [r7, #8] + ``` + + +1. 可以看到: + 1. 异常时CPU正在执行的指令是udiv r3, r2, r3,其中r3取值为0,导致发生除零异常。 + 2. 异常发生在函数Get\_Result\_Exception\_0中。 + +2. 根据LR值查找异常函数的父函数。 + + 包含LR值0x80037fe的反汇编如下所示: + + ``` + 080037ec : + Get_Result_Exception_1(): + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:15 + UINT32 Get_Result_Exception_1(UINT16 dividend){ + 80037ec: b580 push {r7, lr} + 80037ee: b082 sub sp, #8 + 80037f0: af00 add r7, sp, #0 + 80037f2: 4603 mov r3, r0 + 80037f4: 80fb strh r3, [r7, #6] + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:16 + return Get_Result_Exception_0(dividend); + 80037f6: 88fb ldrh r3, [r7, #6] + 80037f8: 4618 mov r0, r3 + 80037fa: f7ff ffe5 bl 80037c8 + 80037fe: 4603 mov r3, r0 + ``` + + +1. LR值80037fe上一行是bl 80037c8 ,此处调用了异常函数,调用异常函数的父函数为Get\_Result\_Exception\_1\(\)。 +2. 重复步骤3,解析异常信息中backtrace start至backtrace end之间的LR值,得到调用产生异常的函数调用栈关系,找到异常原因。 + diff --git "a/zh-cn/device-dev/kernel/Trace\350\260\203\346\265\213.md" b/zh-cn/device-dev/kernel/kernel-lite-mini-inner-trace.md similarity index 100% rename from "zh-cn/device-dev/kernel/Trace\350\260\203\346\265\213.md" rename to zh-cn/device-dev/kernel/kernel-lite-mini-inner-trace.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-inner.md b/zh-cn/device-dev/kernel/kernel-lite-mini-inner.md new file mode 100644 index 0000000000000000000000000000000000000000..63cd8f58de79e139b236f5ce8c56b2ca5df8c260 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-inner.md @@ -0,0 +1,9 @@ +# 内核调测 + +- **[内存调测](kernel-lite-mini-inner-debug.md)** + +- **[异常调测](kernel-lite-mini-inner-exception.md)** + +- **[Trace调测](kernel-lite-mini-inner-trace.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-m.md b/zh-cn/device-dev/kernel/kernel-lite-mini-m.md new file mode 100644 index 0000000000000000000000000000000000000000..3548ae04b61c2ea2c20c5f024694568f9099ea74 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-m.md @@ -0,0 +1,62 @@ +# 内核概述 + +- [内核简介](#section1429342661510) + - [cpu体系架构支持](#section48891456112819) + - [运行机制](#section4599142312817) + + +## 内核简介 + +OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系统内核,具有小体积、低功耗、高性能的特点。其代码结构简单,主要包括内核最小功能集、内核抽象层、可选组件以及工程目录等。OpenHarmony LiteOS-M内核架构包含硬件相关层以及硬件无关层,如下图所示,其中Kernel Arch模块属于硬件相关层,该模块按不同编译工具链、芯片架构分类,提供统一的HAL(Hardware Abstraction Layer)接口,提升了硬件易适配性,满足AIoT类型丰富的硬件和编译工具链的拓展;Components等其他模块属于硬件无关层,其中Kernel Task等内核模块提供基础能力,Components模块提供网络、文件系统等组件能力,Utils模块提供错误处理、调测等能力,KAL(Kernel Abstraction Layer)模块提供统一的标准接口。 + +**图 1** 内核架构图 +![](figure/内核架构图.png "内核架构图") + +### cpu体系架构支持 + +CPU体系架构分为通用架构定义和特定架构定义两层,通用架构定义层为所有体系架构都需要支持和实现的接口,特定架构定义层为特定体系架构所特有的部分。在新增一个体系架构的时候,必须需要实现通用架构定义层,如果该体系架构还有特有的功能,可以在特定架构定义层来实现。 + +**表 1** CPU体系架构规则 + + + + + + + + + + + + + + + + + + + + +

规则

+

通用体系架构层

+

特定体系架构层

+

头文件位置

+

kernel/arch/include

+

kernel/arch/<arch>/<arch>/<toolchain>/

+

头文件命名

+

los_<function>.h

+

los_arch_<function>.h

+

函数命名

+

Halxxxx

+

Halxxxx

+
+ +LiteOS-M已经支持ARM Cortex-M3、ARM Cortex-M4、ARM Cortex-M7、ARM Cortex-M33、RISC-V等主流架构,如果需要扩展CPU体系架构,请参考[芯片架构适配点](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E7%A7%BB%E6%A4%8D%E6%A6%82%E8%BF%B0.md#%E8%8A%AF%E7%89%87%E6%9E%B6%E6%9E%84%E9%80%82%E9%85%8D%E7%82%B9)。 + +### 运行机制 + +在开发板配置文件target\_config.h配置系统时钟、每秒Tick数,可以对任务、内存、IPC、异常处理模块进行裁剪配置。系统启动时,根据配置进行指定模块的初始化。内核启动流程包含外设初始化、系统时钟配置、内核初始化、操作系统启动等,详见内核启动流程图。 + +**图 2** 内核启动流程 +![](figure/内核启动流程.png "内核启动流程") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini-start.md b/zh-cn/device-dev/kernel/kernel-lite-mini-start.md new file mode 100644 index 0000000000000000000000000000000000000000..13cd49841e858d07c4d6d15e197d2902b9183b51 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini-start.md @@ -0,0 +1,47 @@ +# 快速入门 + +- [搭建开发环境](#section157851447151716) +- [获取OpenHarmony源码](#section381985201816) +- [获取示例工程源码](#section204717216181) +- [编译运行](#section9772514181917) + +OpenHarmony LiteOS-M内核的编译构建系统是一个基于gn和ninja的组件化构建系统,支持按组件配置、裁剪和拼装,按需构建出定制化的产品。编译构建系统的详细信息可以参考[考编译构建概](../subsystems/subsys-build-mini-lite.md#section10958256161119)。本文主要介绍如何基于gn和ninja编译LiteOS-M工程。 + +## 搭建开发环境 + +在搭建各个开发板环境前,需要完成OpenHarmony系统基础环境搭建。系统基础环境主要是指OpenHarmony的编译环境和开发环境,详细介绍请参考官方站点[搭建系统基础环境](../quick-start/quickstart-lite-env-setup-des.md)。开发者需要根据环境搭建文档,完成下述软件的安装:Python3.7+、gn、ninja、hb。对于LiteOS-M内核,还需要安装ARM GCC编译工具链。 + +## 获取OpenHarmony源码 + +开发者需要在Linux服务器上通过Git克隆获取OpenHarmony最新源码,详细的源码获取方式,请见[源码获取](../get-code/sourcecode-acquire.md)。获取OpenHarmony完整仓代码后,假设克隆目录为\~/openHarmony。 + +## 获取示例工程源码 + +以开发板Nucleo-F767Zi为例,演示如何编译运行OpenHarmony LiteOS-M内核工程。在本地目录,执行下述命令克隆示例代码。 + +``` +git clone https://gitee.com/harylee/nucleo_f767zi.git +``` + +假设克隆到的代码目录为\~/nucleo\_f767zi。 执行如下命令把代码目录的device、vendor目录复制到openHarmony工程的相应目录。 + +``` +cp -r ~/nucleo_f767zi/device/st ~/openHarmony/device/st +cp -r ~/nucleo_f767zi/vendor/st ~/openHarmony/vendor/st +``` + +关于示例代码目录的说明,可以参考资料站点[板级目录规范](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E7%A7%BB%E6%A4%8D%E6%A6%82%E8%BF%B0-0.md#section6204129143013)。如果需要自行移植开发板,请参考[板级系统移植](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E6%9D%BF%E7%BA%A7%E7%B3%BB%E7%BB%9F%E7%A7%BB%E6%A4%8D.md)。 + +## 编译运行 + +编译运行前,把交叉编译工具链bin目录配置到PATH环境变量中或者在device/st/nucleo\_f767zi/liteos\_m/config.gni文件中把board\_toolchain\_path配置项设置为交叉编译工具链bin目录。 在OpenHarmony根目录,执行hb set设置产品路径,选择nucleo\_f767zi产品,然后执行hb build开启编译。如下: + +``` +user@dev:~/OpenHarmony$ hb set +[OHOS INFO] Input code path: # 直接按回车,然后选择nucleo_f767zi产品即可 +OHOS Which product do you need? nucleo_f767zi@st +user@dev:~/OpenHarmony$ hb build +``` + +最终的镜像生成在\~/openHarmony/out/nucleo\_f767zi/目录中,通过STM32 ST-LINK Utility软件将镜像文件下载至单板查看运行效果。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-mini.md b/zh-cn/device-dev/kernel/kernel-lite-mini.md new file mode 100644 index 0000000000000000000000000000000000000000..f531579ddb9a8bb0962474d074255d56cd3f9958 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-mini.md @@ -0,0 +1,13 @@ +# 轻量系统内核 + +- **[内核概述](kernel-lite-mini-m.md)** + +- **[基础内核](kernel-lite-mini-basic.md)** + +- **[扩展组件](kernel-lite-mini-extend.md)** + +- **[内核调测](kernel-lite-mini-inner.md)** + +- **[附录](kernel-lite-mini-app.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-basic.md b/zh-cn/device-dev/kernel/kernel-lite-small-basic.md new file mode 100644 index 0000000000000000000000000000000000000000..d9cac957f9948081206b93faba73c481d99474e9 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-basic.md @@ -0,0 +1,11 @@ +# 基础内核 + +- **[进程](kernel-lite-small-process.md)** + +- **[线程](kernel-lite-small-thread.md)** + +- **[内存](kernel-lite-small-memory.md)** + +- **[网络](kernel-lite-small-net.md)** + + diff --git a/zh-cn/device-dev/kernel/FAT.md b/zh-cn/device-dev/kernel/kernel-lite-small-file-fat.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/FAT.md rename to zh-cn/device-dev/kernel/kernel-lite-small-file-fat.md diff --git a/zh-cn/device-dev/kernel/JFFS2.md b/zh-cn/device-dev/kernel/kernel-lite-small-file-jffs.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/JFFS2.md rename to zh-cn/device-dev/kernel/kernel-lite-small-file-jffs.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-file-nfs.md b/zh-cn/device-dev/kernel/kernel-lite-small-file-nfs.md new file mode 100644 index 0000000000000000000000000000000000000000..dec5a7023b1d9dcb34d1367fa7446129bfd76ee9 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-file-nfs.md @@ -0,0 +1,163 @@ +# NFS + +- [概述](#section18322139164413) +- [注意事项](#section532912331467) +- [开发指导](#section166873374711) + +## 概述 + +NFS是Network File System(网络文件系统)的缩写。它最大的功能是可以通过网络,让不同的机器、不同的操作系统彼此分享其他用户的文件。因此,用户可以简单地将它看做是一个文件系统服务,在一定程度上相当于Windows环境下的共享文件夹。 + +NFS客户端用户,能够将网络远程的NFS服务端分享的目录挂载到本地端的机器中,运行程序和共享文件,但不占用当前的系统资源,所以,在本地端的机器看起来,远程服务端的目录就好像是自己的一个磁盘一样。 + +## 注意事项 + +- 当前NFS文件不支持权限控制,请在创建NFS目录和文件时使用777权限。 + +- 当前NFS文件不支读阻塞和写阻塞。 + +- 当前NFS文件不支持信号功能。 + +- 当前NFS文件系统mount路径长度(不包含IP的长度)不超过255个字符,超过时返回ENAMETOOLONG错误。 + +- 当前NFS文件支持的操作有:open, close, read, write, seek, dup, dup2, sync, opendir, closedir, readdir, readdir\_r, rewinddir, scandir, statfs, remove, unlink, mkdir, rmdir, rename, stat, stat64, seek64, mmap, mount, umount。 + +- 当前NFS支持TCP和UDP两种传输层协议,默认使用TCP。 + +- open打开一个文件,参数有O\_TRUNC时,必须同时拥有写的权限,才会将文件中的内容清空。 + +- 在文件未关闭的情况下,rename\(\)函数重命名A为B之后,不会改变文件fd。 + +- NFS功能目前处于beta测试阶段,可能存在功能不稳定的情况,建议您不要用于正式商用产品当中。 + + +## 开发指导 + +1. **搭建NFS服务器**。 + + 这里以Ubuntu操作系统为例,说明服务器端设置步骤。 + + 1. 安装NFS服务器软件。 + + 设置好Ubuntu系统的下载源,保证网络连接好的情况下执行: + + ``` + sudo apt-get install nfs-kernel-server + ``` + + 2. 创建用于挂载的目录并设置完全权限 + + ``` + mkdir /home/sqbin/nfs + sudo chmod 777 /home/sqbin/nfs + ``` + + 3. 设置和启动NFS server。 + + 修改NFS配置文件/etc/exports,添加如下一行: + + ``` + /home/sqbin/nfs *(rw,no_root_squash,async) + ``` + + 其中/home/sqbin/nfs是NFS共享的根目录。 + + 执行以下命令启动NFS server: + + ``` + sudo /etc/init.d/nfs-kernel-server start + ``` + + 执行以下命令重启NFS server: + + ``` + sudo /etc/init.d/nfs-kernel-server restart + ``` + + +2. **设置单板为NFS客户端**。 + + 本指导中的NFS客户端指运行OpenHarmony内核的设备。 + + 1. 硬件连接设置。 + + OpenHarmony内核设备连接到NFS服务器的网络。设置两者IP,使其处于同一网段。比如,设置NFS服务器的IP为10.67.212.178/24,设置OpenHarmony内核设备IP为10.67.212.3/24,注意:此IP为内网私有IP地址,用户使用时有差异,以用户实际IP为准。 + + OpenHarmony内核设备上的IP信息可通过ifconfig命令查看。 + + 2. 启动网络,确保单板到NFS服务器之间的网络通畅。 + + 启动以太网或者其他类型网络,使用ping命令检查到服务器的网络是否通畅。 + + ``` + OHOS # ping 10.67.212.178 + [0]Reply from 10.67.212.178: time=1ms TTL=63 + [1]Reply from 10.67.212.178: time=0ms TTL=63 + [2]Reply from 10.67.212.178: time=1ms TTL=63 + [3]Reply from 10.67.212.178: time=1ms TTL=63 + --- 10.67.212.178 ping statistics --- + 4 packets transmitted, 4 received, 0 loss + ``` + + 客户端NFS初始化,运行命令: + + ``` + OHOS # mkdir /nfs + OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 + ``` + + 将从串口得到如下回应信息,表明初始化NFS客户端成功。 + + ``` + OHOS # mount 10.67.212.178:/home/sqbin/nfs /nfs nfs 1011 1000 + Mount nfs on 10.67.212.178:/home/sqbin/nfs, uid:1011, gid:1000 + Mount nfs finished. + ``` + + 该命令将服务器10.67.212.178上的/home/sqbin/nfs目录mount在OpenHarmony内核设备上的/nfs上。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >本例默认nfs server已经配置可用,即示例中服务器10.67.212.178上的/home/sqbin/nfs已配置可访问。 + + mount命令的格式为: + + ``` + mount nfs + ``` + + 其中“SERVER\_IP“表示服务器的IP地址;“SERVER\_PATH“表示服务器端NFS共享目录路径;“CLIENT\_PATH“表示设备上的NFS路径。 + + 如果不想有NFS访问权限限制,请在Linux命令行将NFS根目录权限设置成777: + + ``` + chmod -R 777 /home/sqbin/nfs + ``` + + 至此,NFS客户端设置完毕。NFS文件系统已成功挂载。 + + +3. **利用NFS共享文件**。 + + 在NFS服务器下新建目录dir,并保存。在OpenHarmony内核下运行ls命令: + + ``` + OHOS # ls /nfs + ``` + + 则可从串口得到如下回应: + + ``` + OHOS # ls /nfs + Directory /nfs: + drwxr-xr-x 0 u:0 g:0 dir + ``` + + 可见,刚刚在NFS服务器上新建的dir目录已同步到客户端\(OpenHarmony内核系统\)的/nfs目录,两者保持同步。 + + 同样地,在客户端\(OpenHarmony内核系统\)上创建文件和目录,在NFS服务器上也可以访问,读者可自行体验。 + + **平台差异性:** + + 目前,NFS客户端仅支持NFS v3部分规范要求,因此对于规范支持不全的服务器,无法完全兼容。在开发测试过程中,建议使用Linux的NFS server,因为其对NFS支持很完善。 + + diff --git a/zh-cn/device-dev/kernel/RAMFS.md b/zh-cn/device-dev/kernel/kernel-lite-small-file-ramfs.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/RAMFS.md rename to zh-cn/device-dev/kernel/kernel-lite-small-file-ramfs.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-file-vfs.md b/zh-cn/device-dev/kernel/kernel-lite-small-file-vfs.md new file mode 100644 index 0000000000000000000000000000000000000000..c7d197be36132aa914eaa399d9e16945e6f11ccd --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-file-vfs.md @@ -0,0 +1,171 @@ +# VFS + +- [概述](#section132540468341) +- [基本概念](#section229417111227) +- [运作机制](#section18114182834215) +- [注意事项](#section18311145173712) +- [开发指导](#section422619258380) +- [编程实例](#section180311121420) +- [结果验证](#section16772334714) + +## 概述 + +## 基本概念 + +VFS是Virtual File System(虚拟文件系统)的缩写,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层,为用户提供统一的类Unix文件操作接口。 + +由于不同类型的文件系统接口不统一,若系统中有多个文件系统类型,访问不同的文件系统就需要使用不同的非标准接口。而通过在系统中添加VFS层,提供统一的抽象接口,屏蔽了底层异构类型的文件系统的差异,使得访问文件系统的系统调用不用关心底层的存储介质和文件系统类型,提高开发效率。VFS和各个具体文件系统的关系如下: + +**图 1** VFS和各个文件系统的关系 +![](figure/VFS和各个文件系统的关系.png "VFS和各个文件系统的关系") + +OpenHarmony内核中,VFS框架是通过在内存中的树结构来实现的,树的每个结点都是一个inode结构体。设备注册和文件系统挂载后会根据路径在树中生成相应的结点。VFS最主要是两个功能: + +- 查找节点。 +- 统一调用(标准)。 + +## 运作机制 + +通过VFS层,可以使用标准的Unix文件操作函数(如open、read、write等)来实现对不同介质上不同文件系统的访问。 + +VFS框架内存中的inode树结点有三种类型: + +- 虚拟结点:作为VFS框架的虚拟文件,保持树的连续性,如/usr、/usr/bin。 +- 设备结点:/dev目录下,对应一个设备,如/dev/mmcblk0。 +- 挂载点:挂载具体文件系统,如/vs/sd、/mnt。 + +**图 2** 文件系统树形结构 +![](figure/文件系统树形结构.png "文件系统树形结构") + +## 注意事项 + +- VFS下的所有文件系统,创建的目录名和文件名最多只可以有255个字节,能支持的全路径长度最长为259字节,超过这个路径长度的文件和目录无法创建。 + +- 目前仅有jffs2文件系统支持完整的权限控制。 + +- inode\_find\(\)函数调用后会使查找到的inode节点连接数+1,调用完成后需要调用inode\_release\(\)使连接数-1,所以一般inode\_find\(\)要和inode\_release\(\)配套使用。 + +- 设备分为字符设备和块设备,为了块设备上的文件系统系统数据安全,需挂载相应文件系统后通过文件系统接口操作数据。 + +- los\_vfs\_init\(\)只能调用一次,多次调用将会造成文件系统异常。 + +- 目前OpenHarmony内核所有的文件系统中的文件名和目录名中只可以出现“-” 与“\_”两种特殊字符,使用其他特殊字符可能造成的后果不可预知,请谨慎为之。 + +- OpenHarmony内核支持open\(\)+O\_DIRECTORY的方法获取目录数据信息。 + +- 挂载点必须为空目录,不能重复挂载至同一挂载点或挂载至其他挂载点下的目录或文件,错误挂载可能损坏设备及系统。 + +- open打开一个文件时,参数O\_RDWR、O\_WRONLY、O\_RDONLY互斥,只能出现一个,若出现2个或以上作为open的参数,文件读写操作会被拒绝,并返回EACCESS错误码,禁止使用。 + +- OpenHarmony内核文件系统在umount操作之前,需确保所有目录及文件全部关闭,否则umount会失败。如果强制umount,可能导致包括但不限于文件系统损坏、设备损坏等问题。 + +- SD卡移除前,需确保所有目录及文件全部关闭,并进行umount操作。如果强制拔卡,可能导致包括但不限于SD数据丢失、SD卡损坏等问题。 + + +## 开发指导 + +**开发流程** + +推荐驱动开发人员使用VFS框架来注册/卸载设备,即调用register\_driver\(\)、register\_blockdriver\(\)接口生成设备结点,应用层使用open\(\)、read\(\)操作设备(字符设备)文件来调用驱动。 + +**文件描述符** + +本系统中,进程的文件描述符最多有256个(File和Socket描述符合并统计),系统文件描述符共640个,系统文件描述符规格: + +- File描述符,普通文件描述符,系统总规格为512。 + +- Socket描述符,系统总规格为128。 + + +**VFS支持的操作** + +open, close, read, write, seek, ioctl, fcntl, mmap, sync, dup, dup2, truncate, opendir, closedir, readdir, rewinddir, mount, umount, statfs, unlink, remove, mkdir, rmdir, rename, stat, utime, seek64, fallocate, fallocate64, truncate64, chmod, chown。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 当前只提供修改jffs2文件以及vfs设备节点属性的接口,各个系统对只读等属性有各自的处理方式。 +>- 在OpenHarmony内核中属性并不冲突(可以任意修改)。 +>- 在OpenHarmony内核中只读属性文件/目录不允许被删除。 +>- 在OpenHarmony内核中只读属性文件/目录允许rename。 +>- 只读文件不允许以O\_CREAT、O\_TRUNC,以及有含有写的权限的方式打开。 +>- 在OpenHarmony内核中设置的系统文件加上隐藏属性,在Windows中只能通过命令行找到(在显示,不显示隐藏文件的属性情况下都不能看到)。 + +## 编程实例 + +``` +/* 说明:展示创建目录,和遍历目录的操作 */ +#include +#include +#include +#include +#include +#include + +int main() +{ + int ret; + char *dirname = "/test"; + char *pathname0 = "/test/test0"; + char *pathname1 = "/test/test1"; + char *pathname2 = "/test/test2"; + struct dirent **namelist; + int num; + + ret = mkdir(dirname, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", dirname, errno); + goto EXIT; + } + + ret = mkdir(pathname0, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", pathname0, errno); + goto EXIT0; + } + + ret = mkdir(pathname1, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", pathname1, errno); + goto EXIT1; + } + + ret = mkdir(pathname2, 0777); + if ((ret < 0) && (errno != EEXIST)) { + printf("mkdir failed. path=%s, errno=%d\n", pathname2, errno); + goto EXIT2; + } + + num = scandir(dirname, &namelist, NULL, alphasort); + if (num < 0) { + perror("scandir"); + } else { + while (num--) { + printf("%s\n", namelist[num]->d_name); + free(namelist[num]); + } + free(namelist); + } + + printf("fs_demo exit.\n"); + return 0; + +EXIT2: + remove(pathname2); +EXIT1: + remove(pathname1); +EXIT0: + remove(pathname0); +EXIT: + remove(dirname); + return 0; +} +``` + +## 结果验证 + +``` +OHOS # test2 +test1 +test0 +fs_demo exit. +``` + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-file.md b/zh-cn/device-dev/kernel/kernel-lite-small-file.md new file mode 100644 index 0000000000000000000000000000000000000000..e88e5dd77b3a3a41c0d9fc63e0c52cf09d75205b --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-file.md @@ -0,0 +1,54 @@ +# 文件系统 + +OpenHarmony轻内核支持的文件系统有:VFS(虚拟文件系统)、NFS、RAMFS、FAT、JFFS2。 + +**各个文件系统功能概述:** + +**表 1** 文件系统功能概述 + + + + + + + + + + + + + + + + + + + + + + +

文件系统

+

功能特点概述

+

VFS

+

VFS是Virtual File System(虚拟文件系统)的缩写,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层,为用户提供统一的类Unix文件操作接口。

+

NFS

+

NFS是Network File System(网络文件系统)的缩写。它最大的功能是可以通过网络,让不同的机器、不同的操作系统彼此分享其他用户的文件。

+

RAMFS

+

RAMFS是一种基于RAM的文件系统。RAMFS文件系统把所有的文件都放在RAM中,所以读/写操作发生在RAM中,避免了对存储器的读写损耗,也提高了数据读写速度。RAMFS是基于RAM的动态文件系统的一种存储缓冲机制。

+

FAT

+

FAT文件系统是File Allocation Table(文件配置表)的简称,有FAT12、FAT16、FAT32。在可移动存储介质(U盘、SD卡、移动硬盘等)上多使用FAT文件系统,使设备与Windows、Linux等桌面系统之间保持很好的兼容性。

+

JFFS2

+

JFFS2是Journalling Flash File System Version 2(日志文件系统)的缩写,是MTD设备上的日志型文件系统。主要应用于对NOR_FLASH闪存的文件管理。OpenHarmony内核的JFFS2支持多分区。

+
+ +- **[VFS](kernel-lite-small-file-vfs.md)** + +- **[NFS](kernel-lite-small-file-nfs.md)** + +- **[RAMFS](kernel-lite-small-file-ramfs.md)** + +- **[FAT](kernel-lite-small-file-fat.md)** + +- **[JFFS2](kernel-lite-small-file-jffs.md)** + + diff --git "a/zh-cn/device-dev/kernel/\344\270\216Linux\346\240\207\345\207\206\345\272\223\347\232\204\345\267\256\345\274\202.md" b/zh-cn/device-dev/kernel/kernel-lite-small-lib-differ.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/\344\270\216Linux\346\240\207\345\207\206\345\272\223\347\232\204\345\267\256\345\274\202.md" rename to zh-cn/device-dev/kernel/kernel-lite-small-lib-differ.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-lib-standard.md b/zh-cn/device-dev/kernel/kernel-lite-small-lib-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..9af746232e7fec8dc578856a3d16335453b22dfd --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-lib-standard.md @@ -0,0 +1,197 @@ +# 标准库 + +- [框架流程](#section1247343413257) +- [操作实例](#section4807125622614) +- [常见问题](#section1219455217277) + +OpenHarmony内核使用**musl libc**库,支持标准POSIX接口,开发者可基于POSIX标准接口开发内核之上的组件及应用。 + +## 框架流程 + +**图 1** POSIX接口框架 +![](figure/POSIX接口框架.png "POSIX接口框架") + +**musl libc**库支持POSIX标准,涉及的系统调用相关接口由OpenHarmony内核适配支持 ,以满足接口对外描述的功能要求。 + +标准库支持接口的详细情况请参考C库的API文档,其中也涵盖了与POSIX标准之间的差异说明。 + +## 操作实例 + +在本示例中,主线程创建了THREAD\_NUM个子线程,每个子线程启动后等待被主线程唤醒,主线程成功唤醒所有子线程后,子线程继续执行直至生命周期结束,同时主线程通过pthread\_join方法等待所有线程执行结束。 + +``` +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define THREAD_NUM 3 +int g_startNum = 0; /* 启动的线程数 */ +int g_wakenNum = 0; /* 唤醒的线程数 */ + +struct testdata { + pthread_mutex_t mutex; + pthread_cond_t cond; +} g_td; + +/* + * 子线程入口函数 + */ +static void *ChildThreadFunc(void *arg) +{ + int rc; + pthread_t self = pthread_self(); + + /* 获取mutex锁 */ + rc = pthread_mutex_lock(&g_td.mutex); + if (rc != 0) { + printf("ERROR:take mutex lock failed, error code is %d!\n", rc); + goto EXIT; + } + + /* g_startNum计数加一,用于统计已经获得mutex锁的子线程个数 */ + g_startNum++; + + /* 等待cond条件变量 */ + rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); + if (rc != 0) { + printf("ERROR: pthread condition wait failed, error code is %d!\n", rc); + (void)pthread_mutex_unlock(&g_td.mutex); + goto EXIT; + } + + /* 尝试获取mutex锁,正常场景,此处无法获取锁 */ + rc = pthread_mutex_trylock(&g_td.mutex); + if (rc == 0) { + printf("ERROR: mutex gets an abnormal lock!\n"); + goto EXIT; + } + + /* g_wakenNum计数加一,用于统计已经被cond条件变量唤醒的子线程个数 */ + g_wakenNum++; + + /* 释放mutex锁 */ + rc = pthread_mutex_unlock(&g_td.mutex); + if (rc != 0) { + printf("ERROR: mutex release failed, error code is %d!\n", rc); + goto EXIT; + } +EXIT: + return NULL; +} + +static int testcase(void) +{ + int i, rc; + pthread_t thread[THREAD_NUM]; + + /* 初始化mutex锁 */ + rc = pthread_mutex_init(&g_td.mutex, NULL); + if (rc != 0) { + printf("ERROR: mutex init failed, error code is %d!\n", rc); + goto ERROROUT; + } + + /* 初始化cond条件变量 */ + rc = pthread_cond_init(&g_td.cond, NULL); + if (rc != 0) { + printf("ERROR: pthread condition init failed, error code is %d!\n", rc); + goto ERROROUT; + } + + /* 批量创建THREAD_NUM个子线程 */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_create(&thread[i], NULL, ChildThreadFunc, NULL); + if (rc != 0) { + printf("ERROR: pthread create failed, error code is %d!\n", rc); + goto ERROROUT; + } + } + + /* 等待所有子线程都完成mutex锁的获取 */ + while (g_startNum < THREAD_NUM) { + usleep(100); + } + + /* 获取mutex锁,确保所有子线程都阻塞在pthread_cond_wait上 */ + rc = pthread_mutex_lock(&g_td.mutex); + if (rc != 0) { + printf("ERROR: mutex lock failed, error code is %d\n", rc); + goto ERROROUT; + } + + /* 释放mutex锁 */ + rc = pthread_mutex_unlock(&g_td.mutex); + if (rc != 0) { + printf("ERROR: mutex unlock failed, error code is %d!\n", rc); + goto ERROROUT; + } + + for (int j = 0; j < THREAD_NUM; j++) { + /* 在cond条件变量上广播信号 */ + rc = pthread_cond_signal(&g_td.cond); + if (rc != 0) { + printf("ERROR: pthread condition failed, error code is %d!\n", rc); + goto ERROROUT; + } + } + + sleep(1); + + /* 检查是否所有子线程都已被唤醒 */ + if (g_wakenNum != THREAD_NUM) { + printf("ERROR: not all threads awaken, only %d thread(s) awaken!\n", g_wakenNum); + goto ERROROUT; + } + + /* join所有子线程,即等待其结束 */ + for (i = 0; i < THREAD_NUM; i++) { + rc = pthread_join(thread[i], NULL); + if (rc != 0) { + printf("ERROR: pthread join failed, error code is %d!\n", rc); + goto ERROROUT; + } + } + + /* 销毁cond条件变量 */ + rc = pthread_cond_destroy(&g_td.cond); + if (rc != 0) { + printf("ERROR: pthread condition destroy failed, error code is %d!\n", rc); + goto ERROROUT; + } + return 0; +ERROROUT: + return -1; +} + +/* + * 示例代码主函数 + */ +int main(int argc, char *argv[]) +{ + int rc; + + /* 启动测试函数 */ + rc = testcase(); + if (rc != 0) { + printf("ERROR: testcase failed!\n"); + } + + return 0; +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +``` + +## 常见问题 + +无。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-lib.md b/zh-cn/device-dev/kernel/kernel-lite-small-lib.md new file mode 100644 index 0000000000000000000000000000000000000000..849c9823bb4d63fab462824146e779ab635cbd4e --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-lib.md @@ -0,0 +1,7 @@ +# 标准库 + +- **[标准库](kernel-lite-small-lib-standard.md)** + +- **[与Linux标准库的差异](kernel-lite-small-lib-differ.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-memory.md b/zh-cn/device-dev/kernel/kernel-lite-small-memory.md new file mode 100644 index 0000000000000000000000000000000000000000..5f97c5705ac4715be205c81f29469ebf13d750c8 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-memory.md @@ -0,0 +1,353 @@ +# 内存 + +- [基本概念](#section1392116583424) +- [使用场景](#section159581619194319) +- [接口说明](#section114001032104317) + +## 基本概念 + +内存管理是开发过程中必须要关注的重要过程,它包括内存的分配、使用和回收。 + +良好的内存管理对于提高软件性能和可靠性有着十分重要的意义。 + +## 使用场景 + +针对用户态开发,OpenHarmony内核提供了一套内存系统调用接口,支持内存的申请释放、重映射、内存属性的设置等,还有C库的标准内存操作函数。 + +## 接口说明 + +**表 1** 标准C库相关接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口

+

功能

+

strings.h

+

int bcmp(const void *s1, const void *s2, size_t n)

+

比较字节序列。

+

strings.h

+

void bcopy(const void *src, void *dest, size_t n)

+

拷贝字节序列。

+

strings.h

+

void bzero(void *s, size_t n)

+

写入零值字节。

+

string.h

+

void *memccpy(void *dest, const void *src, int c, size_t n)

+

拷贝src 所指的内存内容前n 个字节到dest 所指的地址上。复制时检查参数c 是否出现,若是则返回dest 中值为c 的下一个字节地址。

+

string.h

+

void *memchr(const void *s, int c, size_t n)

+

在s所指内存的前n个字节中查找c。

+

string.h

+

int memcmp(const void *s1, const void *s2, size_t n)

+

内存比较。

+

string.h

+

void *memcpy(void *dest, const void *src, size_t n)

+

内存拷贝。

+

string.h

+

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)

+

找到一个子串。

+

string.h

+

void *memmove(void *dest, const void *src, size_t n)

+

内存移动。

+

string.h

+

void *mempcpy(void *dest, const void *src, size_t n)

+

拷贝内存区域。

+

string.h

+

void *memset(void *s, int c, size_t n)

+

内存初始化。

+

stdlib.h

+

void *malloc(size_t size)

+

申请内存。

+

stdlib.h

+

void *calloc(size_t nmemb, size_t size)

+

申请内存并清零。

+

stdlib.h

+

void *realloc(void *ptr, size_t size)

+

重分配内存。

+

stdlib.h/malloc.h

+

void *valloc(size_t size)

+

分配以页对齐的内存。

+

stdlib.h

+

void free(void *ptr)

+

释放内存。

+

malloc.h

+

size_t malloc_usable_size(void *ptr)

+

获取从堆分配的内存块的大小。

+

unistd.h

+

int getpagesize(void)

+

获取页面大小。

+

unistd.h

+

void *sbrk(intptr_t increment)

+

更改数据段大小。

+
+ +差异接口详细说明: + +- **mmap** + + **函数原型:** + + void \*mmap\(void \*addr, size\_t length, int prot, int flags, int fd, off\_t offset\); + + **函数功能:**申请虚拟内存。 + + **参数说明:** + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

addr

+

用来请求使用某个特定的虚拟内存地址。如果取NULL,结果地址就将自动分配(这是推荐的做法),否则会降低程序的可移植性,因为不同系统的可用地址范围不一样。

+

length

+

内存段的大小。

+

prot

+

用于设置内存段的访问权限,有如下权限:

+
  • PROT_READ:允许读该内存段。
  • PROT_WRITE:允许写该内存段。
  • PROT_EXEC:允许执行该内存段。
  • PROT_NONE:不能访问。
+

flags

+

控制程序对内存段的改变所造成的影响,有如下属性:

+
  • MAP_PRIVATE:内存段私有,对它的修改值仅对本进程有效。
  • MAP_SHARED:把对该内存段的修改保存到磁盘文件中。
+

fd

+

打开的文件描述符。

+

offset

+

用以改变经共享内存段访问的文件中数据的起始偏移值。

+
+ + >![](../public_sys-resources/icon-note.gif) **说明:** + >mmap与Linux实现差异详见[与Linux标准库的差异](kernel-lite-small-lib-differ.md)章节。 + + **返回值:** + + - 成功返回:虚拟内存地址,这地址是页对齐。 + - 失败返回:\(void \*\)-1。 + + +- **munmap接口** + + **函数原型:** + + int munmap\(void \*addr, size\_t length\); + + **函数功能:**释放虚拟内存。 + + **参数说明:** + + + + + + + + + + + + + +

参数

+

描述

+

addr

+

虚拟内存起始位置。

+

length

+

内存段的大小。

+
+ + **返回值:** + + - 成功返回0。 + - 失败返回-1。 + + +- **mprotect接口** + + **函数原型:** + + int mprotect\(void \*addr, size\_t length, int prot\); + + **函数功能:**修改内存段的访问权限。 + + **参数说明:** + + + + + + + + + + + + + + + + +

参数

+

描述

+

addr

+

内存段起始地址,必须页对齐;访问权限异常,内核将直接抛异常并且kill该进程,而不会产生SIGSEGV信号给当前进程。

+

length

+

内存段的大小。

+

prot

+

内存段的访问权限,有如下定义:

+
  • PROT_READ:允许读该内存段。
  • PROT_WRITE:允许写该内存段。
  • PROT_EXEC:允许执行该内存段。
  • PROT_NONE:不能访问。
+
+ + **返回值:** + + - 成功返回0。 + - 失败返回-1。 + + +- **mremap接口** + + **函数原型:** + + void \*mremap\(void \*old\_address, size\_t old\_size, size\_t new\_size, int flags, void new\_address\); + + **函数功能:**重新映射虚拟内存地址。 + + **参数说明:** + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

old_address

+

需要扩大(或缩小)的内存段的原始地址。注意old_address必须是页对齐。

+

old_size

+

内存段的原始大小。

+

new_size

+

新内存段的大小。

+

flags

+

如果没有足够的空间在当前位置展开映射,则返回失败

+
  • MREMAP_MAYMOVE:允许内核将映射重定位到新的虚拟地址。
  • MREMAP_FIXED:mremap()接受第五个参数,void *new_address,该参数指定映射地址必须页对齐;在new_address和new_size指定的地址范围内的所有先前映射都被解除映射。如果指定了MREMAP_FIXED,还必须指定MREMAP_MAYMOVE。
+
+ + **返回值:** + + - 成功返回:重新映射后的虚拟内存地址。 + - 失败返回:\(\(void \*\)-1\)。 + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-net.md b/zh-cn/device-dev/kernel/kernel-lite-small-net.md new file mode 100644 index 0000000000000000000000000000000000000000..8aa33611c312c90c33556691ff5460883c51f3d8 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-net.md @@ -0,0 +1,303 @@ +# 网络 + +- [基本概念](#section9840143083510) +- [使用场景](#section1575885183516) +- [接口说明](#section16351198193614) + +## 基本概念 + +网络模块实现了TCP/IP协议栈基本功能,提供标准的POSIX socket接口。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>当前系统使用**lwIP**提供网络能力。 + +## 使用场景 + +针对用户态开发,OpenHarmony内核提供了一套网络功能系统调用接口,支持socket的创建关闭、数据收发、网络属性的设置等,通过C库提供标准的POSIX socket函数供开发者使用。 + +## 接口说明 + +**表 1** 标准C库相关接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口

+

功能

+

sys/socket.h

+

int accept(int socket, struct sockaddr *address, socklen_t *address_len)

+

接受连接。

+

sys/socket.h

+

int bind(int s, const struct sockaddr *name, socklen_t namelen)

+

socket与IP地址绑定。

+

sys/socket.h

+

int shutdown(int socket, int how)

+

关闭连接。

+

sys/socket.h

+

int getpeername(int s, struct sockaddr *name, socklen_t *namelen)

+

获取对端地址。

+

sys/socket.h

+

int getsockname(int s, struct sockaddr *name, socklen_t *namelen)

+

获取本地地址。

+

sys/socket.h

+

int getsockopt(int s, struct sockaddr *name, socklen_t *namelen)

+

获取socket属性信息。

+

sys/socket.h

+

int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)

+

配置socket属性。

+

unistd.h

+

int close(int s)

+

关闭socket。

+

sys/socket.h

+

int connect(int s, const struct sockaddr *name, socklen_t namelen)

+

连接到指定的目的IP。

+

sys/socket.h

+

int listen(int sockfd, int backlog)

+

聆听连接本socket的请求。

+

sys/socket.h

+

ssize_t recv(int socket, void *buffer, size_t length, int flags)

+

接收socket上收到的数据。

+

sys/socket.h

+

ssize_t recvmsg(int s, struct msghdr *message, int flags)

+

接收socket上收到的数据,可使用更丰富的参数。

+

sys/socket.h

+

ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len)

+

接收socket上收到的数据,可同时获得数据来源IP地址。

+

sys/socket.h

+

ssize_t send(int s, const void *dataptr, size_t size, int flags)

+

通过socket发送数据。

+

sys/socket.h

+

ssize_t sendmsg(int s, const struct msghdr *message, int flags)

+

通过socket发送数据,可使用更丰富的参数。

+

sys/socket.h

+

ssize_t sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)

+

通过socket发送数据,可指定发送的目的IP地址。

+

sys/socket.h

+

int socket(int domain, int type, int protocol)

+

创建socket。

+

sys/select.h

+

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)

+

多路复用。

+

sys/ioctl.h

+

int ioctl(int s, int request, ...)

+

socket属性获取、设置。

+

arpa/inet.h

+

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)

+

网络地址格式转换:将二进制格式IP地址转换为字符串格式。

+

arpa/inet.h

+

int inet_pton(int af, const char *src, void *dst)

+

网络地址格式转换:将字符串格式IP地址转换为二进制格式。

+
+ +与标准接口差异详细说明: + +- **sendmsg** + + **函数原型:** + + ssize\_t sendmsg\(int s, const struct msghdr \*message, int flags\) + + **函数功能:**发送消息。 + + **参数说明:** + + + + + + + + + + + + + + + + +

参数

+

描述

+

s

+

套接字描述符。

+

message

+

待发送的消息,不支持发送ancillary消息。

+

flags

+

用于指定发送消息时行为特性,有如下行为特性:

+
  • MSG_MORE:允许将多次发送的消息进行拼包发送。
  • MSG_DONTWAIT:非阻塞操作。
+
+ + **返回值:** + + - 成功返回:已发送的消息长度(字节数)。 + - 失败返回:-1,并设置errno。 + + +- **recvmsg** + + **函数原型:** + + ssize\_t recvmsg\(int s, struct msghdr \*message, int flags\) + + **函数功能:**接收消息。 + + **参数说明:** + + + + + + + + + + + + + + + + +

参数

+

描述

+

s

+

套接字描述符。

+

message

+

存放接收的消息,不支持接收ancillary消息。

+

flags

+

用于指定接收消息时行为特性,有如下行为特性:

+
  • MSG_PEEK:允许预读消息而不取走。
  • MSG_DONTWAIT:非阻塞操作。
+
+ + **返回值:** + + - 成功返回:已接收的消息长度(字节数)。 + - 失败返回:-1,并设置errno。 + + +- **ioctl** + + **函数原型:** + + int ioctl\(int s, int request, ...\) + + **函数功能:**获取或设置socket属性。 + + **参数说明:** + + + + + + + + + + + + + +

参数

+

描述

+

s

+

套接字描述符。

+

request

+

对socket属性要进行的操作,当前支持如下操作:

+
  • FIONREAD:获取socket当前可读取的数据大小(字节数)。
  • FIONBIO:设置socket是否非阻塞。
+
+ + **返回值:** + + - 成功返回:0。 + - 失败返回:-1,并设置errno。 + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-process.md b/zh-cn/device-dev/kernel/kernel-lite-small-process.md new file mode 100644 index 0000000000000000000000000000000000000000..d6b9ca0377b4a57c3e6663468ddfba4f7a6d930c --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-process.md @@ -0,0 +1,301 @@ +# 进程 + +- [基本概念](#section29197338383) +- [使用场景](#section85513272398) +- [接口说明](#section4517119124015) + +## 基本概念 + +从系统的角度看,进程是资源管理单元。进程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它进程运行。 + +OpenHarmony内核的进程模块可以给用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。这样用户可以将更多的精力投入到业务功能的实现中。 + +OpenHarmony内核中的进程采用抢占式调度机制,支持时间片轮转调度方式。 + +OpenHarmony内核的进程一共有32个优先级\(0-31\),用户进程可配置的优先级有22个\(10-31\),最高优先级为10,最低优先级为31。 + +高优先级的进程可抢占低优先级进程,低优先级进程必须在高优先级进程阻塞或结束后才能得到调度。 + +每一个用户态进程均拥有自己独立的进程空间,相互之间不可见,实现进程间隔离。 + +用户态根进程init由内核态创建,其它用户态进程均由init进程fork而来。 + +**进程状态说明:** + +- 初始化(Init):该进程正在被创建。 + +- 就绪(Ready):该进程在就绪列表中,等待CPU调度。 + +- 运行(Running):该进程正在运行。 + +- 阻塞(Pending):该进程被阻塞挂起。本进程内所有的线程均被阻塞时,进程被阻塞挂起。 + +- 僵尸态(Zombies):该进程运行结束,等待父进程回收其控制块资源。 + + +**图 1** 进程状态迁移示意图 +![](figure/进程状态迁移示意图.png "进程状态迁移示意图") + +**进程状态迁移说明:** + +- Init→Ready: + + 进程创建或fork时,拿到该进程控制块后进入Init状态,处于进程初始化阶段,当进程初始化完成将进程插入调度队列,此时进程进入就绪状态。 + +- Ready→Running: + + 进程创建后进入就绪态,发生进程切换时,就绪列表中最高优先级的进程被执行,从而进入运行态。若此时该进程中已无其它线程处于就绪态,则该进程从就绪列表删除,只处于运行态;若此时该进程中还有其它线程处于就绪态,则该进程依旧在就绪队列,此时进程的就绪态和运行态共存。 + +- Running→Pending: + + 进程内所有的线程均处于阻塞态时,进程在最后一个线程转为阻塞态时,同步进入阻塞态,然后发生进程切换。 + +- Pending→Ready: + + 阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态。 + +- Ready→Pending: + + 进程内的最后一个就绪态线程处于阻塞态时,进程从就绪列表中删除,进程由就绪态转为阻塞态。 + +- Running→Ready: + + 进程由运行态转为就绪态的情况有以下两种: + + 1. 有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。 + 2. 若进程的调度策略为SCHED\_RR,且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。 + +- Running→Zombies: + + 当进程的主线程或所有线程运行结束后,进程由运行态转为僵尸态,等待父进程回收资源。 + + +## 使用场景 + +进程创建后,用户只能操作自己进程空间的资源,无法操作其它进程的资源(共享资源除外)。 用户态允许进程挂起,恢复,延时等操作,同时也可以设置用户态进程调度优先级和调度策略,获取进程调度优先级和调度策略。进程结束的时候,进程会主动释放持有的进程资源,但持有的进程pid资源需要父进程通过wait/waitpid或父进程退出时回收。 + +## 接口说明 + +OpenHarmony内核系统中的进程管理模块为用户提供下面几种功能: + +**表 1** 进程管理模块功能 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

备注

+

进程

+

fork

+

创建一个新进程。

+

-

+

exit

+

终止进程。

+

-

+

atexit

+

注册正常进程终止的回调函数。

+

-

+

abort

+

中止进程执行。

+

-

+

getpid

+

获取进程ID。

+

-

+

getppid

+

获取父进程ID。

+

-

+

getpgrp

+

获取调用进程的进程组ID。

+

-

+

getpgid

+

获取进程的进程组ID。

+

-

+

setpgrp

+

设置调用进程的进程组ID。

+

-

+

setpgid

+

设置进程的进程组ID。

+

-

+

kill

+

给进程发送信号。

+
  • 仅支持1-30号信号的发送。
  • 信号的默认行为不支持STOP及CONTINUE,无COREDUMP功能。
  • 不能屏蔽SIGSTOP、SIGKILL、SIGCONT。
  • 异步信号,发送信号给某进程后,直到该进程被调度后才会执行信号回调(为安全起见,杀死进程的动作是进程自己执行的,内核不能通过信号强制杀死对方)。
  • 进程消亡会发送SIGCHLD给父进程,发送动作无法取消。
  • 无法通过信号唤醒正在睡眠的进程。
+

wait

+

等待任意子进程结束并回收子进程资源。

+

status的值可以由以下宏定义解析:

+
  • WIFEXITED(status):如果子进程正常结束,它就返回真;否则返回假。
  • WEXITSTATUS(status):如果WIFEXITED(status)为真,则可以用该宏取得子进程exit()返回的退出码。
  • WTERMSIG(status) 仅支持以下情况:子进程触发异常结束后通过WTERMSIG获取的进程退出编号始终为SIGUSR2。
  • 不支持的操作: WIFSTOPPED、WSTOPSIG、WCOREDUMP 、WIFCONTINUED。
+

waitpid

+

等待子进程结束并回收子进程资源。

+

options:不支持WUNTRACED,WCONTINUED;

+

status的值可以由以下宏定义解析:

+
  • WIFEXITED(status):如果子进程正常结束,它就返回真;否则返回假。
  • WEXITSTATUS(status):如果WIFEXITED(status)为真,则可以用该宏取得子进程exit()返回的退出码。
  • WTERMSIG(status)仅支持以下情况:子进程触发异常结束后通过WTERMSIG获取的进程退出编号始终为SIGUSR2。
  • 不支持:WIFSTOPPED 、WSTOPSIG、WCOREDUMP 、WIFCONTINUED。
+

调度

+

getpriority

+

获取指定ID的静态优先级。

+
  • 不支持:PRIO_PGRP、PRIO_USER。
+
  • 无动态优先级概念,用于设置静态优先级。
+

setpriority

+

设置指定ID的静态优先级。

+

sched_rr_get_interval

+

获取执行时间限制。

+

-

+

sched_yield

+

系统调用运行进程主动让出执行权。

+

-

+

sched_get_priority_max

+

获取进程静态优先级取值范围的最大值。

+

调度策略只支持:SCHED_RR。

+

sched_get_priority_min

+

获取进程静态优先级取值范围的最小值。

+

sched_getscheduler

+

获取调度策略。

+

sched_setscheduler

+

设置调度策略。

+

sched_getparam

+

获取调度参数。

+

-

+

sched_setparam

+

设置调度参数。

+

-

+

exec

+

execl

+

执行指定的elf格式的用户程序文件。

+

-

+

execle

+

执行指定的elf格式的用户程序文件。

+

-

+

execlp

+

执行指定的elf格式的用户程序文件。

+

-

+

execv

+

执行指定的elf格式的用户程序文件。

+

-

+

execve

+

执行指定的elf格式的用户程序文件。

+

-

+

execvp

+

执行指定的elf格式的用户程序文件。

+

-

+
+ diff --git "a/zh-cn/device-dev/kernel/\347\224\250\346\210\267\346\200\201\345\274\202\345\270\270\344\277\241\346\201\257\350\257\264\346\230\216.md" b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-abn.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/\347\224\250\346\210\267\346\200\201\345\274\202\345\270\270\344\277\241\346\201\257\350\257\264\346\230\216.md" rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-abn.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cat.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cat.md new file mode 100644 index 0000000000000000000000000000000000000000..89f4a35b9f4980a853899a6db9cb91fe205291ed --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cat.md @@ -0,0 +1,53 @@ +# cat + +- [命令功能](#section16710153391315) +- [命令格式](#section1699392313158) +- [参数说明](#section1677217374136) +- [使用指南](#section186772414131) +- [使用实例](#section12158131814561) +- [输出说明](#section183926225561) + +## 命令功能 + +cat用于显示文本文件的内容。 + +## 命令格式 + +cat \[_pathname_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

pathname

+

文件路径。

+

已存在的文件。

+
+ +## 使用指南 + +cat用于显示文本文件的内容。 + +## 使用实例 + +举例:cat hello-harmony.txt + +## 输出说明 + +**图 1** 查看 hello-harmony.txt 文件的信息 +![](figure/查看-hello-harmony-txt-文件的信息.png "查看-hello-harmony-txt-文件的信息") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cd.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cd.md new file mode 100644 index 0000000000000000000000000000000000000000..61247bfba2e28f771398d9a561063eea382984c8 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cd.md @@ -0,0 +1,57 @@ +# cd + +- [命令功能](#section11690184921316) +- [命令格式](#section75695409569) +- [参数说明](#section71961353181311) +- [使用指南](#section3629759111317) +- [使用实例](#section211620301412) +- [输出说明](#section1968117214577) + +## 命令功能 + +cd命令用来改变当前目录。 + +## 命令格式 + +cd \[_path_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

path

+

文件路径。

+

用户必须具有指定目录中的执行(搜索)许可权。

+
+ +## 使用指南 + +- 未指定目录参数时,会跳转至根目录。 +- cd后加路径名时,跳转至该路径。 +- 路径名以 /(斜杠)开头时,表示根目录。 +- .(点)表示当前目录。 +- ..(点点)表示父目录。 + +## 使用实例 + +举例:cd .. + +## 输出说明 + +**图 1** 显示结果如下 +![](figure/显示结果如下.png "显示结果如下") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chgrp.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chgrp.md new file mode 100644 index 0000000000000000000000000000000000000000..efeccc336faaf14bcab8c01256026cd5e437722c --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chgrp.md @@ -0,0 +1,60 @@ +# chgrp + +- [命令功能](#section6103119161418) +- [命令格式](#section186958132141) +- [参数说明](#section81796174141) +- [使用指南](#section14330152417140) +- [使用实例](#section951823119149) +- [输出说明](#section14271133125715) + +## 命令功能 + +chgrp用于修改文件的群组。 + +## 命令格式 + +chgrp \[_group_\] \[_pathname_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

group

+

文件群组。

+

[0,0xFFFFFFFF]

+

pathname

+

文件路径。

+

已存在的文件。

+
+ +## 使用指南 + +在需要修改的文件名前加上文件群组值就可以修改该文件的所属组。 + +## 使用实例 + +举例:chgrp 100 hello-harmony.txt + +## 输出说明 + +**图 1** 修改 hello-harmony.txt 文件的群组为100 +![](figure/修改-hello-harmony-txt-文件的群组为100.png "修改-hello-harmony-txt-文件的群组为100") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chmod.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chmod.md new file mode 100644 index 0000000000000000000000000000000000000000..296ab1e3d3890571360162d88a0b139c6c3d00e4 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chmod.md @@ -0,0 +1,60 @@ +# chmod + +- [命令功能](#section13992936121418) +- [命令格式](#section63342439147) +- [参数说明](#section894414671411) +- [使用指南](#section182415221419) +- [使用实例](#section8518195718147) +- [输出说明](#section127391818158) + +## 命令功能 + +chmod用于修改文件操作权限。 + +## 命令格式 + +chmod \[_mode_\] \[_pathname_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

mode

+

文件或文件夹权限,用8进制表示对应User、Group、及Other(拥有者、群组、其他组)的权限。

+

[0,777]

+

pathname

+

文件路径。

+

已存在的文件。

+
+ +## 使用指南 + +在需要修改的文件名前加上文件权限值就可以修改该文件的权限值。 + +## 使用实例 + +举例:chmod 666 hello-harmony.txt + +## 输出说明 + +**图 1** 修改 hello-harmony.txt 文件的权限为666 +![](figure/修改-hello-harmony-txt-文件的权限为666.png "修改-hello-harmony-txt-文件的权限为666") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chown.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chown.md new file mode 100644 index 0000000000000000000000000000000000000000..4e63051ec9c9aa6e4e6fea52278e0b9905c08f45 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-chown.md @@ -0,0 +1,70 @@ +# chown + +- [命令功能](#section247414691513) +- [命令格式](#section14773151018159) +- [参数说明](#section598731391517) +- [使用指南](#section16524152071510) +- [使用实例](#section17901152561510) +- [输出说明](#section15513163115816) + +## 命令功能 + +chmod用于将指定文件的拥有者改为指定的用户或组。 + +## 命令格式 + +chown \[_owner_\] \[_group_\] \[_pathname_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

owner

+

文件拥有者。

+

[0,0xFFFFFFFF]

+

group

+

文件群组。

+

1、为空。

+

2、[0,0xFFFFFFFF]

+

pathname

+

文件路径。

+

已存在的文件。

+
+ +## 使用指南 + +- 在需要修改的文件名前加上文件拥有者和文件群组就可以分别修改该文件的拥有者和群组。 +- 当owner或group值为-1时则表示对应的owner或group不修改。 +- group参数可以为空。 + +## 使用实例 + +举例:chown 100 200 hello-harmony.txt + +## 输出说明 + +**图 1** 修改 hello-harmony.txt 文件的uid为100,gid为200 +![](figure/修改-hello-harmony-txt-文件的uid为100-gid为200.png "修改-hello-harmony-txt-文件的uid为100-gid为200") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cp.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cp.md new file mode 100644 index 0000000000000000000000000000000000000000..299beb065c72efb62c4d54ae5a675b6e0ae7ec20 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-cp.md @@ -0,0 +1,68 @@ +# cp + +- [命令功能](#section6841203041513) +- [命令格式](#section24286359150) +- [参数说明](#section558617385152) +- [使用指南](#section16128156162) +- [使用实例](#section19354171211618) +- [输出说明](#section16754183195914) + +## 命令功能 + +拷贝文件,创建一份副本。 + +## 命令格式 + +cp \[_SOURCEFILE_\] \[_DESTFILE_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

SOURCEFILE

+

源文件路径。

+

目前只支持文件,不支持目录。

+

DESTFILE

+

目的文件路径。

+

支持目录以及文件。

+
+ +## 使用指南 + +- 同一路径下,源文件与目的文件不能重名。 +- 源文件必须存在,且不为目录。 +- 源文件路径支持“\*”和“?”通配符,“\*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。 +- 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。 +- 目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。 +- 目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。 +- 目的文件不存在时创建新文件,已存在则覆盖。 + +拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。 + +## 使用实例 + +举例:cp hello-harmony.txt ./tmp/ + +## 输出说明 + +**图 1** 显示结果如下 +![](figure/显示结果如下-17.png "显示结果如下-17") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-format.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-format.md new file mode 100644 index 0000000000000000000000000000000000000000..200ddb4fe65b114791341707ba5bea5649f85255 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-format.md @@ -0,0 +1,69 @@ +# format + +- [命令功能](#section1922331919169) +- [命令格式](#section249226169) +- [参数说明](#section985173416177) +- [使用指南](#section1510162714162) +- [使用实例](#section25691431161611) +- [输出说明](#section17368112365920) + +## 命令功能 + +format指令用于格式化磁盘。 + +## 命令格式 + +format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

dev_inodename

+

设备名。

+

sectors

+

分配的单元内存或扇区大小,如果输入0表示参数为空。(取值必须为0或2的幂,fat32下最大值为128,取值0表示自动选择合适的簇大小,不同size的分区,可用的簇大小范围不同,错误的簇大小指定可能导致格式化失败)。

+

option

+
格式化选项,用来选择文件系统的类型,有如下几种参数选择:
  • 0x01:FMT_FAT
  • 0x02:FMT_FAT32
  • 0x07:FMT_ANY
  • 0x08:FMT_ERASE (USB不支持该选项)
+
+

传入其他值皆为非法值,将由系统自动选择格式化方式。若格式化U盘时低格位为 1,会出现错误打印。

+

label

+

该参数为可选参数,输入值应为字符串,用来指定卷标名。当输入字符串"null"时,则把之前设置的卷标名清空。

+
+ +## 使用指南 + +- format指令用于格式化磁盘,设备名可以在dev目录下查找。format时必须安装存储卡。 +- format只能格式化U盘、sd和mmc卡,对Nand flash和Nor flash格式化不起作用。 +- sectors参数必须传入合法值,传入非法参数可能引发异常。 + +## 使用实例 + +举例:输入format /dev/mmcblk0 128 2 + +## 输出说明 + +结果如下 + +![](figure/zh-cn_image_0000001052370307.png) + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-is.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-is.md new file mode 100644 index 0000000000000000000000000000000000000000..0a1823804e0adc769a94d7dbe961d129310da288 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-is.md @@ -0,0 +1,59 @@ +# ls + +- [命令功能](#section6538163771614) +- [命令格式](#section45881743111616) +- [参数说明](#section17528148171617) +- [使用指南](#section041212533166) +- [使用实例](#section986105716167) +- [输出说明](#section2036124918592) + +## 命令功能 + +ls命令用来显示当前目录的内容。 + +## 命令格式 + +ls \[_path_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

path

+

path为空时,显示当前目录的内容。

+

path为无效文件名时,显示失败,提示:

+

ls error: No such directory。

+

path为有效目录路径时,会显示对应目录下的内容。

+

1.为空。

+

2.有效的目录路径。

+
+ +## 使用指南 + +- ls命令显示当前目录的内容。 +- ls可以显示文件的大小。 +- proc下ls无法统计文件大小,显示为0。 + +## 使用实例 + +举例:输入ls + +## 输出说明 + +**图 1** 查看当前系统路径下的目录,显示的内容如下 +![](figure/查看当前系统路径下的目录-显示的内容如下.png "查看当前系统路径下的目录-显示的内容如下") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-isfd.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-isfd.md new file mode 100644 index 0000000000000000000000000000000000000000..e1fb8007c539895e4551e5ef6a8d229beba38e93 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-isfd.md @@ -0,0 +1,29 @@ +# lsfd + +- [命令功能](#section2053406181716) +- [命令格式](#section523771017172) +- [使用指南](#section27241213201719) +- [使用实例](#section442617197173) +- [输出说明](#section42491639151813) + +## 命令功能 + +lsfd命令用来显示当前已经打开的文件描述符及对应的文件名。 + +## 命令格式 + +lsfd + +## 使用指南 + +lsfd命令显示当前已经打开文件的fd号以及文件的名字。 + +## 使用实例 + +举例:输入lsfd + +## 输出说明 + +**图 1** lsfd输出说明 +![](figure/lsfd输出说明.png "lsfd输出说明") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-mkdir.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-mkdir.md new file mode 100644 index 0000000000000000000000000000000000000000..c261ebdca3e37218fb3646c90c3e3a78c854e337 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-mkdir.md @@ -0,0 +1,54 @@ +# mkdir + +- [命令功能](#section1083613274175) +- [命令格式](#section820913118178) +- [参数说明](#section1256834121718) +- [使用指南](#section1294234115172) +- [使用实例](#section1113345211713) +- [输出说明](#section10142201012) + +## 命令功能 + +mkdir命令用来创建一个目录。 + +## 命令格式 + +mkdir \[_directory_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

directory

+

需要创建的目录。

+

N/A

+
+ +## 使用指南 + +- mkdir后加所需要创建的目录名会在当前目录下创建目录。 +- mkdir后加路径,再加上需要创建的目录名,即在指定目录下创建目录。 + +## 使用实例 + +举例:mkdir share + +## 输出说明 + +**图 1** 创建 share 目录 +![](figure/创建-share-目录.png "创建-share-目录") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-mount.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-mount.md new file mode 100644 index 0000000000000000000000000000000000000000..103a5d29c4ed79b4ffc4b5b812e07c3ce414e87d --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-mount.md @@ -0,0 +1,78 @@ +# mount + +- [命令功能](#section11631837182) +- [命令格式](#section1697638111820) +- [参数说明](#section1650151221819) +- [使用指南](#section124541520171912) +- [使用实例](#section7424625171917) +- [输出说明](#section14757018116) + +## 命令功能 + +mount命令用来将设备挂载到指定目录。 + +## 命令格式 + +mount <_device_\> <_path_\> <_name_\> \[_uid gid_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

device

+

要挂载的设备(格式为设备所在路径)。

+

系统拥有的设备。

+

path

+

指定目录。

+

用户必须具有指定目录中的执行(搜索)许可权。

+

N/A

+

name

+

文件系统的种类。

+

vfat, yaffs, jffs, ramfs, nfs,procfs, romfs.

+

uid gid

+

uid是指用户ID。

+

gid是指组ID。

+

可选参数,缺省值uid:0,gid:0。

+

N/A

+
+ +## 使用指南 + +mount后加需要挂载的设备信息、指定目录以及设备文件格式,就能成功挂载文件系统到指定目录。 + +## 使用实例 + +举例:mount /dev/mmcblk0p0 /bin1/vs/sd vfat + +## 输出说明 + +将/dev/mmcblk0p0 挂载到/bin1/vs/sd目录 + +![](figure/zh-cn_image_0000001051690323.png) + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-part.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-part.md new file mode 100644 index 0000000000000000000000000000000000000000..52ba25e101848e6463d1da65c5b0131059584496 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-part.md @@ -0,0 +1,52 @@ +# partinfo + +- [命令功能](#section1777503617199) +- [命令格式](#section185501447132114) +- [参数说明](#section1304151212252) +- [使用指南](#section4566131982520) +- [使用实例](#section4351134942514) +- [输出说明](#section66689331412) + +## 命令功能 + +partinfo命令用于查看系统识别的硬盘,SD卡多分区信息。 + +## 命令格式 + +partinfo <_dev\_inodename_\> + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

dev_inodename

+

要查看的分区名字。

+

合法的分区名。

+
+ +## 使用指南 + +无 + +## 使用实例 + +partinfo /dev/mmcblk0p0 + +## 输出说明 + +![](figure/zh-cn_image_0000001052370303.png) + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-partion.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-partion.md new file mode 100644 index 0000000000000000000000000000000000000000..458f7f05ef470e91f3813b8bcf8a532aa71b0e99 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-partion.md @@ -0,0 +1,62 @@ +# partition + +- [命令功能](#section255095212257) +- [命令格式](#section10258056122515) +- [参数说明](#section177200581256) +- [使用指南](#section17866411262) +- [使用实例](#section1927174202610) +- [输出说明](#section11321011223) + +## 命令功能 + +partition命令用来查看flash分区信息。 + +## 命令格式 + +partition \[_nand / spinor_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

nand

+

显示nand flash分区信息。

+

N/A

+

spinor

+

显示spinor flash分区信息。

+

N/A

+
+ +## 使用指南 + +- partition命令用来查看flash分区信息。 +- 仅当使能yaffs文件系统时才可以查看nand flash分区信息,使能jffs或romfs文件系统时可以查看spinor flash分区信息。 + +## 使用实例 + +举例:partition spinor + +## 输出说明 + +查看spinor flash分区信息 + +![](figure/zh-cn_image_0000001052810300.png) + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-pwd.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-pwd.md new file mode 100644 index 0000000000000000000000000000000000000000..c9d526fc07d50b00ec756a43ebc42a59cd55e531 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-pwd.md @@ -0,0 +1,34 @@ +# pwd + +- [命令功能](#section197737712267) +- [命令格式](#section1544061016267) +- [参数说明](#section599112120262) +- [使用指南](#section66901116152615) +- [使用实例](#section7427181922612) +- [输出说明](#section116313389418) + +## 命令功能 + +pwd命令用来显示当前路径。 + +## 命令格式 + +pwd + +## 参数说明 + +无。 + +## 使用指南 + +pwd 命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 / (斜线)分隔。第一个 / 表示根目录, 最后一个目录是当前目录。 + +## 使用实例 + +举例:输入pwd + +## 输出说明 + +**图 1** 查看当前路径 +![](figure/查看当前路径.png "查看当前路径") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-rm.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-rm.md new file mode 100644 index 0000000000000000000000000000000000000000..b9eb4d90a0a88fc19697f3a7a006b2c957bba948 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-rm.md @@ -0,0 +1,67 @@ +# rm + +- [命令功能](#section181141523142613) +- [命令格式](#section8800926132619) +- [参数说明](#section15476229152617) +- [使用指南](#section10578163215262) +- [使用实例](#section18548133511263) +- [输出说明](#section1565323814265) + +## 命令功能 + +rm命令用来删除文件或文件夹。 + +## 命令格式 + +rm \[_-r_\] \[_dirname / filename_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

-r

+

可选参数,若是删除目录则需要该参数。

+

N/A

+

dirname/filename

+

要删除文件或文件夹的名称,支持输入路径。

+

N/A

+
+ +## 使用指南 + +- rm命令一次只能删除一个文件或文件夹。 +- rm -r命令可以删除非空目录。 + +## 使用实例 + +举例: + +1. 输入rm log1.txt +2. 输入rm -r sd + +## 输出说明 + +**图 1** 用 rm 命令删除文件 log1.txt +![](figure/用-rm-命令删除文件-log1-txt.png "用-rm-命令删除文件-log1-txt") + +**图 2** 用 rm -r 删除目录 sd +![](figure/用-rm--r-删除目录-sd.png "用-rm--r-删除目录-sd") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-rmdir.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-rmdir.md new file mode 100644 index 0000000000000000000000000000000000000000..c37bbea17c0fd6264888cc1272511434198e54a5 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-rmdir.md @@ -0,0 +1,55 @@ +# rmdir + +- [命令功能](#section1839611420266) +- [命令格式](#section329574512266) +- [参数说明](#section15865747102620) +- [使用指南](#section107857508261) +- [使用实例](#section11196165315262) +- [输出说明](#section1073811415613) + +## 命令功能 + +rmdir命令用来删除一个目录。 + +## 命令格式 + +rmdir \[_dir_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

dir

+

需要删除目录的名称,删除目录必须为空,支持输入路径。

+

N/A

+
+ +## 使用指南 + +- rmdir命令只能用来删除目录。 +- rmdir一次只能删除一个目录。 +- rmdir只能删除空目录。 + +## 使用实例 + +举例:输入rmdir dir + +## 输出说明 + +**图 1** 删除一个名为 dir 的目录 +![](figure/删除一个名为-dir-的目录.png "删除一个名为-dir-的目录") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-sta.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-sta.md new file mode 100644 index 0000000000000000000000000000000000000000..2373311252bb249b17dba03132d8c6fdaf234cc2 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-sta.md @@ -0,0 +1,52 @@ +# statfs + +- [命令功能](#section153921657152613) +- [命令格式](#section135391102717) +- [参数说明](#section074312314279) +- [使用指南](#section133816772712) +- [使用实例](#section526149182717) + +## 命令功能 + +statfs命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。 + +## 命令格式 + +statfs \[_directory_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

directory

+

文件系统的路径。

+

必须是存在的文件系统,并且其支持statfs命令,当前支持的文件系统有:JFFS2,FAT,NFS。

+
+ +## 使用指南 + +打印信息因文件系统而异。 + +## 使用实例 + +以nfs文件系统为例: + +statfs /nfs + +**图 1** statfs输出说明 +![](figure/statfs输出说明.png "statfs输出说明") + diff --git a/zh-cn/device-dev/kernel/sync.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-sync.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/sync.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-sync.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-touch.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-touch.md new file mode 100644 index 0000000000000000000000000000000000000000..1ec96315b5f0fcd4ae5b92f8b9dc2951dc729128 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-touch.md @@ -0,0 +1,59 @@ +# touch + +- [命令功能](#section17541924112716) +- [命令格式](#section866182711274) +- [参数说明](#section268912296270) +- [使用指南](#section412093332714) +- [使用实例](#section414434814354) +- [输出说明](#section1028419515711) + +## 命令功能 + +- touch命令用来在指定的目录下创建一个不存在的空文件。 +- touch命令操作已存在的文件会成功,不会更新时间戳。 + +## 命令格式 + +touch \[_filename_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

filename

+

需要创建文件的名称。

+

N/A

+
+ +## 使用指南 + +- touch命令用来创建一个空文件,该文件可读写。 +- 使用touch命令一次只能创建一个文件。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >在系统重要资源路径下使用touch命令创建文件,会对系统造成死机等未知影响,如在/dev路径下执行touch uartdev-0,会产生系统卡死现象。 + + +## 使用实例 + +举例:输入touch file.c 输出说明 + +## 输出说明 + +**图 1** 创建一个名为 file.c 的文件 +![](figure/创建一个名为-file-c-的文件.png "创建一个名为-file-c-的文件") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-umount.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-umount.md new file mode 100644 index 0000000000000000000000000000000000000000..def6e2f84bd6f1c8b214ecbfa88ea3dfc4289c56 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-umount.md @@ -0,0 +1,55 @@ +# umount + +- [命令功能](#section365125133520) +- [命令格式](#section9615254123512) +- [参数说明](#section63446577355) +- [使用指南](#section92931509368) +- [使用实例](#section144311323616) +- [输出说明](#section360525113611) + +## 命令功能 + +umount命令用来卸载指定文件系统。 + +## 命令格式 + +umount \[_dir_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

dir

+

需要卸载文件系统对应的目录。

+

系统已挂载的文件系统的目录。

+
+ +## 使用指南 + +umount后加上需要卸载的指定文件系统的目录,即将指定文件系统卸载。 + +## 使用实例 + +举例:umount /bin1/vs/sd + +## 输出说明 + +将已在/bin1/vs/sd挂载的文件系统卸载 + +**图 1** umount输出示例 +![](figure/umount输出示例.png "umount输出示例") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-write.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-write.md new file mode 100644 index 0000000000000000000000000000000000000000..c94ac15b6a2074c51948a04bfe0e53181359c7a1 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file-write.md @@ -0,0 +1,69 @@ +# writeproc + +- [命令功能](#section366714216619) +- [命令格式](#section8833164614615) +- [参数说明](#section12809111019453) +- [使用指南](#section15935131220717) +- [使用实例](#section79281818476) +- [输出说明](#section12742311179) + +## 命令功能 + +proc fs支持传入字符串参数,需要每个文件实现自己的写方法。 + +## 命令格式 + +writeproc <_data_\> \>\> /proc/<_filename_\> + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

data

+

要输入的字符串,以空格为结束符,如需输入空格,请用""包裹。

+

N/A

+

filename

+

data要传入的proc文件。

+

N/A

+
+ +## 使用指南 + +proc文件实现自身的write函数,调用writeproc命令后会将入参传入write函数。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>procfs不支持多线程访问。 + +## 使用实例 + +举例:writeproc test \>\> /proc/uptime + +## 输出说明 + +OHOS \# writeproc test \>\> /proc/uptime + +\[INFO\]write buf is: test + +test \>\> /proc/uptime + +>![](../public_sys-resources/icon-note.gif) **说明:** +>uptime proc文件临时实现write函数,INFO日志为实现的测试函数打印的日志。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file.md new file mode 100644 index 0000000000000000000000000000000000000000..f2d8302ca40447c34683eec77ec1d78c9275fcc6 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-file.md @@ -0,0 +1,45 @@ +# 文件命令 + +- **[cat](kernel-lite-small-shell-cmd-file-cat.md)** + +- **[cd](kernel-lite-small-shell-cmd-file-cd.md)** + +- **[chgrp](kernel-lite-small-shell-cmd-file-chgrp.md)** + +- **[chmod](kernel-lite-small-shell-cmd-file-chmod.md)** + +- **[chown](kernel-lite-small-shell-cmd-file-chown.md)** + +- **[cp](kernel-lite-small-shell-cmd-file-cp.md)** + +- **[format](kernel-lite-small-shell-cmd-file-format.md)** + +- **[ls](kernel-lite-small-shell-cmd-file-is.md)** + +- **[lsfd](kernel-lite-small-shell-cmd-file-isfd.md)** + +- **[mkdir](kernel-lite-small-shell-cmd-file-mkdir.md)** + +- **[mount](kernel-lite-small-shell-cmd-file-mount.md)** + +- **[partinfo](kernel-lite-small-shell-cmd-file-part.md)** + +- **[partition](kernel-lite-small-shell-cmd-file-partion.md)** + +- **[pwd](kernel-lite-small-shell-cmd-file-pwd.md)** + +- **[rm](kernel-lite-small-shell-cmd-file-rm.md)** + +- **[rmdir](kernel-lite-small-shell-cmd-file-rmdir.md)** + +- **[statfs](kernel-lite-small-shell-cmd-file-sta.md)** + +- **[sync](kernel-lite-small-shell-cmd-file-sync.md)** + +- **[touch](kernel-lite-small-shell-cmd-file-touch.md)** + +- **[writeproc](kernel-lite-small-shell-cmd-file-write.md)** + +- **[umount](kernel-lite-small-shell-cmd-file-umount.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-mag.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-mag.md new file mode 100644 index 0000000000000000000000000000000000000000..bc083f86ce0e71e81429707cec8f586d39243d92 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-mag.md @@ -0,0 +1,38 @@ +# 魔法键使用方法 + +- [使用场景](#section2350114718546) +- [使用方法](#section3305151511559) + +## 使用场景 + +在系统运行出现无响应等情况时,可以通过魔法键功能确定系统是否被锁中断(魔法键也无响应)或者查看系统任务运行状态等信息。 + +在中断有响应的情况下,可以通过魔法键查看task信息中 cpup(CPU占用率)看是哪个任务长时间占用CPU导致系统其他任务无响应(一般为比较高优先级任务一直抢占CPU,导致低优先级任务无响应)。 + +## 使用方法 + +1. 配置宏LOSCFG\_ENABLE\_MAGICKEY。 + +魔法键依赖于宏LOSCFG\_ENABLE\_MAGICKEY,使用时通过menuconfig在配置项中开启“Enable MAGIC KEY”: + +Debug ---\> Enable MAGIC KEY;若关闭该选项,则魔法键失效。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>1. 可以在menuconfig中,将光标移动到LOSCFG\_ENABLE\_MAGICKEY上,输入“?”,查看帮助信息。 + +2. 输入“ctrl + r”键,打开魔法键检测功能。 + +在连接UART或者USB转虚拟串口的情况下,输入“ctrl + r” 键,打开魔法键检测功能,输出 “Magic key on”;再输入一次后,则关闭魔法键检测功能,输出“Magic key off”。魔法键功能如下: + +- ctrl + z:帮助键,输出相关魔法键简单介绍; + +- ctrl + t:输出任务相关信息; + +- ctrl + p:系统主动进入panic,输出panic相关信息后,系统会挂住; + +- ctrl + e:系统进行简单完整性内存池检查,检查出错会输出相关错误信息,检查正常会输出“system memcheck over, all passed!”。 + + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>魔法键检测功能打开情况下,如果需要通过UART或者USB转虚拟串口输入特殊字符需避免与魔法键值重复,否则魔法键会被误触发,而原有设计功能可能出现错误。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-arp.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-arp.md new file mode 100644 index 0000000000000000000000000000000000000000..7ff926b41044eafc1ce54354c4c1dabefd753468 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-arp.md @@ -0,0 +1,114 @@ +# arp + +- [命令功能](#section201149459368) +- [命令格式](#section579813484364) +- [参数说明](#section168065311366) +- [使用指南](#section19190125723612) +- [使用实例](#section10383416372) + +## 命令功能 + +在以太网中,主机之间的通信是直接使用MAC地址(非IP地址)来通信的,所以,对于使用IP通信的协议,必须能够将IP地址转换成MAC地址,才能在局域网(以太网)内通信。解决这个问题的方法就是主机存储一张IP和MAC地址对应的表,即ARP缓存,主机要往一个局域网内的目的IP地址发送IP包时,就可以从ARP缓存表中查询到目的MAC地址。ARP缓存是由TCP/IP协议栈维护的,用户可通过ARP命令查看和修改ARP表。 + +## 命令格式 + +arp + +arp \[_-i IF_\] -s _IPADDR HWADDR_ + +arp \[_-i IF_\] -d _IPADDR_ + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

+

打印整个ARP缓存的内容。

+

N/A

+

-i IF

+

指定的网络接口(可选参数)。

+

N/A

+

-s IPADDR

+

HWADDR

+

增加一条ARP表项,后面的参数是局域网中另一台主机的IP地址及其对应的MAC地址。

+

N/A

+

-d IPADDR

+

删除一条ARP表项。

+

N/A

+
+ +## 使用指南 + +- arp命令用来查询和修改TCP/IP协议栈的ARP缓存表,增加非同一子网内的IP地址的ARP表项是没有意义的,协议栈会返回失败。 +- 命令需要启动TCP/IP协议栈后才能使用。 + +## 使用实例 + +举例: + +1. 输入arp + + **图 1** 打印整个 ARP 缓存表 + + + ![](figure/Snipaste_2021-01-26_10-38-58.png) + + **表 2** 参数说明 + + + + + + + + + + + + + + + + + + + +

参数

+

说明

+

Address

+

表示网络设备的IPv4地址。

+

HWaddress

+

表示网络设备的MAC地址。

+

Iface

+

表示该ARP表项使用的接口名。

+

Type

+

表示该ARP表项是动态的还是静态的,动态是指ARP表项由协议栈自动创建,静态是指ARP表项是由用户增加的。

+
+ + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-dh.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-dh.md new file mode 100644 index 0000000000000000000000000000000000000000..05d883c72b22b3a4500af3b13cb9cae3bb5a3f47 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-dh.md @@ -0,0 +1,138 @@ +# dhclient + +- [命令功能](#section366714216619) +- [命令格式](#section8833164614615) +- [参数说明](#section12809111019453) +- [使用指南](#section15935131220717) +- [使用实例](#section79281818476) +- [输出说明](#section12742311179) + +## 命令功能 + +设置和查看dhclient的参数。 + +## 命令格式 + +dhclient <_netif name_\> + +dhclient -x <_netif name_\> + +dhclient -gb <_netif name_\> + +dhclient -sv <_vendor_\> + +dhclient -gv + +dhclient -gd <_index_\> + +dhclient -sd <_dns\_ip_\> + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

<netif name>

+

启动对应网卡的dhcp请求。

+

网卡名字,eth0。

+

-x <netif name>

+

关闭对应网卡的dhcp功能。

+

网卡名字,eth0。

+

-gb <netif name>

+

查看对应网卡的dhcp请求是否完成。

+

网卡名字,eth0。

+

-sv <vendor>

+

设置dhcp请求的厂商信息。

+

厂商信息,长度是32个字符。

+

-gv

+

查看dhcp请求的厂商信息。

+

N/A

+

-gd <index>

+

获取第index个dns server的信息。

+

index,0或者1。

+

-sd <dns_ip>

+

设置主dns server的ip。

+

dns的ip地址。

+
+ +## 使用指南 + +dhclient eth0 + +dhclient -x eth0 + +dhclient -gb eth0 + +dhclient -sv MFSI + +dhclient -gv + +dhclient -gd 0 + +dhclient -sd 8.8.8.8 + +## 使用实例 + +![](figure/zh-cn_image_0000001053224218.png) + +## 输出说明 + +**表 2** 输出说明 + + + + + + + + + + + + + +

输出

+

说明

+

dhclient: set vendor info [MFSI] success

+

设置厂商信息MFSI信息成功。

+

dns[0]: 192.168.1.100

+

dns server ip地址为192.168.1.100。

+
+ diff --git a/zh-cn/device-dev/kernel/dns.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-dns.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/dns.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-dns.md diff --git a/zh-cn/device-dev/kernel/ifconfig.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipc.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/ifconfig.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipc.md diff --git a/zh-cn/device-dev/kernel/ipdebug.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipd.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/ipdebug.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ipd.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-net.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-net.md new file mode 100644 index 0000000000000000000000000000000000000000..b35a6494a18a56fe021cab3206b146565794c382 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-net.md @@ -0,0 +1,83 @@ +# netstat + +- [命令功能](#section13469162113816) +- [命令格式](#section795712373812) +- [参数说明](#section17629431193817) +- [使用指南](#section5277153519380) +- [使用实例](#section108141437163820) +- [输出说明](#section1357015107117) + +## 命令功能 + +netstat是控制台命令,是一个监测TCP/IP网络的非常有用的工具,它可以显示实际的网络连接以及每一个网络接口设备的状态信息。netstat用于显示与TCP、UDP协议相关的统计数据,一般用于检验本设备(单板)各端口的网络连接情况。 + +## 命令格式 + +netstat + +## 参数说明 + +无 + +## 使用指南 + +直接输入命令。 + +## 使用实例 + +举例:输入netstat + +**图 1** netstat 打印信息 + + +![](figure/Snipaste_2021-01-26_10-38-58-18.png) + +## 输出说明 + +**表 1** 输出说明 + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

Proto

+

协议类型。

+

Recv-Q

+

未被用户读取的数据量。

+

对于Listen TCP,此值为已完成三次握手,但是未被用户accept的TCP连接的数量。

+

Send-Q

+

对TCP连接,已发送但未确认的数据量。

+

对UDP连接,由于IP地址解析未完成而缓存的数据量。

+

Local Address

+

本地地址和端口。

+

Foreign Address

+

远程地址和端口。

+

State

+

TCP连接状态,UDP此项无意义。

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>形如“========== total sockets 32 ====== unused sockets 22 BootTime 27 s ========== ”,表示一共32个套接字,未使用套接字22个,距系统启动已经过27秒。 + diff --git a/zh-cn/device-dev/kernel/ntpdate.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ntp.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/ntpdate.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ntp.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping.md new file mode 100644 index 0000000000000000000000000000000000000000..e1792bc92dd3871588ca67e12a7b56fdc6434230 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping.md @@ -0,0 +1,99 @@ +# ping + +- [命令功能](#section119672573385) +- [命令格式](#section869419010390) +- [参数说明](#section9877183173918) +- [使用指南](#section1097046193914) +- [使用实例](#section14564129113911) +- [输出说明](#section1621732891215) + +## 命令功能 + +ping命令用于测试网络连接是否正常。 + +## 命令格式 + +ping_ _\[_-n cnt_\] \[_-w interval_\] \[_-l data\_len_\]_ _ + +ping \[_-t_\] \[_-w interval_\] __ + +ping _-k_ + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

IP

+

要测试是否网络连通的IPv4地址。

+

N/A

+

-n cnt

+

执行的次数,不带本参数则默认为4次。

+

1-65535

+

-w interval

+

发送两次ping包的时间间隔,单位毫秒。

+

>0

+

-l data_len

+

ping包,即ICMP echo request报文的数据长

+

度,不包含ICMP包头。

+

0-65500

+

-t

+

表示永久ping,直到使用ping -k杀死ping线

+

程。

+

N/A

+

-k

+

杀死ping线程,停止ping。

+

N/A

+
+ +## 使用指南 + +- ping命令用来测试到目的IP的网络连接是否正常,参数为目的IP地址。 +- 如果目的IP不可达,会显示请求超时。 +- 如果显示发送错误,说明没有到目的IP的路由。 +- 命令需要启动TCP/IP协议栈后才能使用。 + +## 使用实例 + +举例:输入ping 192.168.1.10 + +## 输出说明 + +**图 1** ping tftp 服务器地址 + + +![](figure/Snipaste_2021-01-26_10-38-58-19.png) + diff --git a/zh-cn/device-dev/kernel/ping6.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping6.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/ping6.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-ping6.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-tel.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-tel.md new file mode 100644 index 0000000000000000000000000000000000000000..95e8083c8022da0e67f3e192e8e1fbcb1655c4ce --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-tel.md @@ -0,0 +1,65 @@ +# telnet + +- [命令功能](#section3551830123913) +- [命令格式](#section14897133233918) +- [参数说明](#section977718353392) +- [使用指南](#section134991538183916) +- [使用实例](#section1097414426398) +- [输出说明](#section11846624191310) + +## 命令功能 + +本命令用于启动或关闭telnet server服务。 + +## 命令格式 + +telnet \[_on | off_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

on

+

启动telnet server服务。

+

N/A

+

off

+

关闭telnet server服务。

+

N/A

+
+ +## 使用指南 + +- telnet启动要确保网络驱动及网络协议栈已经初始化完成,且板子的网卡是link up状态。 +- 暂时无法支持多个客户端(telnet + IP)同时连接开发板。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >telnet属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 + + +## 使用实例 + +举例:输入telnet on + +## 输出说明 + +**图 1** 输入 telnet on +![](figure/输入-telnet-on.png "输入-telnet-on") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-tftp.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-tftp.md new file mode 100644 index 0000000000000000000000000000000000000000..d0a864992ff0d8fe6fb95c5b408eaf9e0b17fc4b --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net-tftp.md @@ -0,0 +1,87 @@ +# tftp + +- [命令功能](#section15142134573911) +- [命令格式](#section20958174917394) +- [参数说明](#section576613532395) +- [使用指南](#section149795134408) +- [使用实例](#section148921918114015) +- [输出说明](#section7872155631313) + +## 命令功能 + +TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供简单、低开销的文件传输服务。端口号为69。 + +tftp命令可以从TFTP服务器上下载文件。 + +## 命令格式 + +./bin/tftp _<-g/-p\>_ _-l_ _\[FullPathLocalFile\] -r \[RemoteFile\] \[Host\]_ + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

-g/-p

+

文件传输方向:

+
  • -g 从TFTP服务器获取文件。
  • -p 上传文件到TFTP服务器。
+

N/A

+

-l FullPathLocalFile

+

本地文件完整路径。

+

N/A

+

-r RemoteFile

+

服务端文件名。

+

N/A

+

Host

+

服务端IP。

+

N/A

+
+ +## 使用指南 + +1. 在服务器端搭建TFTP服务器,并进行正确配置。 +2. OpenHarmony单板使用tftp命令上传、下载文件。 +3. 传输的文件大小是有限制的不能大于32M。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >tftp属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 + + +## 使用实例 + +举例:从服务器下载out文件。 + +## 输出说明 + +``` +OHOS # ./bin/tftp -g -l /nfs/out -r out 192.168.1.2 +TFTP transfer finish +``` + +tftp命令执行后,传输正常完成会显示TFTP transfer finish, 失败的话会显示其他的打印信息帮助定位问题。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net.md new file mode 100644 index 0000000000000000000000000000000000000000..6695d35058d5c51b722eeb73330d33d312861002 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-net.md @@ -0,0 +1,25 @@ +# 网络命令 + +- **[arp](kernel-lite-small-shell-cmd-net-arp.md)** + +- **[dhclient](kernel-lite-small-shell-cmd-net-dh.md)** + +- **[dns](kernel-lite-small-shell-cmd-net-dns.md)** + +- **[ifconfig](kernel-lite-small-shell-cmd-net-ipc.md)** + +- **[ipdebug](kernel-lite-small-shell-cmd-net-ipd.md)** + +- **[netstat](kernel-lite-small-shell-cmd-net-net.md)** + +- **[ntpdate](kernel-lite-small-shell-cmd-net-ntp.md)** + +- **[ping](kernel-lite-small-shell-cmd-net-ping.md)** + +- **[ping6](kernel-lite-small-shell-cmd-net-ping6.md)** + +- **[telnet](kernel-lite-small-shell-cmd-net-tel.md)** + +- **[tftp](kernel-lite-small-shell-cmd-net-tftp.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-cpup.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-cpup.md new file mode 100644 index 0000000000000000000000000000000000000000..5d9bf1de8a7e21bf2e07681ba275a02ff007c638 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-cpup.md @@ -0,0 +1,65 @@ +# cpup + +- [命令功能](#section1842161614217) +- [命令格式](#section5629527427) +- [参数说明](#section133651361023) +- [使用指南](#section156611948521) +- [使用实例](#section68501605319) +- [输出说明](#section19871522144219) + +## 命令功能 + +cpup命令用于查询系统CPU的占用率。 + +## 命令格式 + +cpup \[_mode_\] \[_taskID_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

mode

+

● 缺省:显示系统最近10s内的CPU占用率。

+

● 0:显示系统最近10s内的CPU占用率。

+

● 1:显示系统最近1s内的CPU占用率。

+

● 其他数字:显示系统启动至今总的CPU 占用率。

+

[0,0xFFFFFFFF]

+

taskID

+

任务ID号

+

[0,0xFFFFFFFF]

+
+ +## 使用指南 + +- 参数缺省时,显示系统10s前的CPU占用率。 +- 只有一个参数时,该参数为mode,显示系统相应时间前的CPU占用率。 +- 输入两个参数时,第一个参数为mode,第二个参数为taskID,显示对应ID号任务的相应时间前的CPU占用率。 + +## 使用实例 + +举例:输入cpup 1 5 + +## 输出说明 + +**图 1** 指令输出结果 +![](figure/指令输出结果.png "指令输出结果") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-date.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-date.md new file mode 100644 index 0000000000000000000000000000000000000000..0ee6698e2fc9e1960b5a7a45474570e80633eb9d --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-date.md @@ -0,0 +1,94 @@ +# date + +- [命令功能](#section56472016338) +- [命令格式](#section16635112512316) +- [参数说明](#section15896030039) +- [使用指南](#section116361036636) +- [使用实例](#section021711411237) +- [输出说明](#section17950184414312) + +## 命令功能 + +date命令用于查询及设置系统日期和时间。 + +## 命令格式 + +date + +date --help + +date +\[_Format_\] + +date -s_ _\[_YY/MM/DD_\] + +date_ _-s_ _\[_hh:mm:ss_\]__ + +date -r \[_Filename_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

--help

+

使用帮助。

+

N/A

+

+Format

+

根据Format格式打印日期和时间。

+

--help中列出的占位符。

+

-s YY/MM/DD

+

设置系统时间,用“/”分割的年月日。

+

>= 1970/01/01

+

-s hh:mm:ss

+

设置系统时间,用“:”分割的时分秒。

+

N/A

+

-r Filename

+

查询Filename文件的修改时间。

+

N/A

+
+ +## 使用指南 + +- date参数缺省时,默认显示当前系统日期和时间。 +- --help、+Format、-s、-r不能混合使用。 + +## 使用实例 + +举例: + +输入date +%Y--%m--%d。 + +## 输出说明 + +**图 1** 按指定格式打印系统日期 +![](figure/按指定格式打印系统日期.png "按指定格式打印系统日期") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-demsg.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-demsg.md new file mode 100644 index 0000000000000000000000000000000000000000..b4e1bbd9eea0c4955f75c2d309474e0ee5a9accf --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-demsg.md @@ -0,0 +1,113 @@ +# dmesg + +- [命令功能](#section4643204919313) +- [命令格式](#section6553153635) +- [参数说明](#section208971157532) +- [使用指南](#section213115219413) +- [使用实例](#section13736564418) +- [输出说明](#section194005101413) + +## 命令功能 + +dmesg命令用于控制内核dmesg缓存区。 + +## 命令格式 + +dmesg + +dmesg \[_-c/-C/-D/-E/-L/-U_\] + +dmesg -s \[_size_\] + +dmesg -l \[_level_\] + +dmesg \> \[_fileA_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

-c

+

打印缓存区内容并清空缓存区。

+

N/A

+

-C

+

清空缓存区。

+

N/A

+

-D/-E

+

关闭/开启控制台打印。

+

N/A

+

-L/-U

+

关闭/开启串口打印。

+

N/A

+

-s size

+

设置缓存区大小 size是要设置的大小。

+

N/A

+

-l level

+

设置缓存等级。

+

0 - 5

+

> fileA

+

将缓存区内容写入文件。

+

N/A

+
+ +## 使用指南 + +- 该命令依赖于LOSCFG\_SHELL\_DMESG,使用时通过menuconfig在配置项中开启"Enable Shell dmesg": + + Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell dmesg + +- dmesg参数缺省时,默认打印缓存区内容。 +- 各“ - ”选项不能混合使用。 + 1. 写入文件需确保已挂载文件系统。 + 2. 关闭串口打印会影响shell使用,建议先连接telnet再尝试关闭串口。 + + +## 使用实例 + +举例: + +输入dmesg \> /usr/dmesg.log。 + +## 输出说明 + +**图 1** dmesg重定向到文件。 +![](figure/dmesg重定向到文件.png "dmesg重定向到文件") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-exec.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-exec.md new file mode 100644 index 0000000000000000000000000000000000000000..c5e437ad7ce79baac800f459b108e50f1c5e9fc2 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-exec.md @@ -0,0 +1,60 @@ +# exec + +- [命令功能](#section4643204919313) +- [命令格式](#section6553153635) +- [参数说明](#section208971157532) +- [使用指南](#section213115219413) +- [使用实例](#section13736564418) +- [输出说明](#section194005101413) + +## 命令功能 + +exec命令属于shell内置命令,目前实现最基础的执行用户态程序的功能。 + +## 命令格式 + +exec <_executable-file_\> + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

executable-file

+

有效的可执行文件。

+

N/A

+
+ +## 使用指南 + +该命令当前仅支持执行有效的二进制程序,程序成功执行,默认后台运行,但与Shell共用终端,可能会导致程序打印输出与Shell输出交错显示。 + +## 使用实例 + +举例: + +输入exec helloworld。 + +## 输出说明 + +``` +OHOS # exec helloworld +OHOS # hello world! +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>可执行文件执行后,先打印“OHOS \#”提示符原因:目前Shell “exec”命令执行均为后台执行,结果可能导致提示符提前打印。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-free.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-free.md new file mode 100644 index 0000000000000000000000000000000000000000..dcfdc363829fad59170e29da6a16c06a523d86c1 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-free.md @@ -0,0 +1,119 @@ +# free + +- [命令功能](#section175151514841) +- [命令格式](#section8488721749) +- [参数说明](#section27272181949) +- [使用指南](#section148661259410) +- [使用实例](#section68081530242) +- [输出说明](#section171235517543) + +## 命令功能 + +free命令可显示系统内存的使用情况,同时显示系统的text段、data段、rodata段、bss段大小。 + +## 命令格式 + +free \[_-k | -m_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

无参数

+

以Byte为单位显示。

+

N/A

+

-k

+

以KB为单位显示。

+

N/A

+

-m

+

以MB为单位显示。

+

N/A

+
+ +## 使用指南 + +无。 + +## 使用实例 + +举例:分别输入free、free -k、free -m. + +## 输出说明 + +**图 1** 以三种方式显示内存使用情况 +![](figure/以三种方式显示内存使用情况.png "以三种方式显示内存使用情况") + +**表 2** 输出说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

total

+

表示系统动态内存池总量。

+

used

+

表示已使用内存总量。

+

free

+

表示未被分配的内存大小。

+

heap

+

表示已分配堆大小。

+

text

+

表示代码段大小。

+

data

+

表示数据段大小。

+

rodata

+

表示只读数据段大小。

+

bss

+

表示未初始化全局变量占用内存大小。

+
+ diff --git a/zh-cn/device-dev/kernel/help.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-help.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/help.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-help.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-hwi.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-hwi.md new file mode 100644 index 0000000000000000000000000000000000000000..9414e1f74464147595229f46315a108d4b531eb5 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-hwi.md @@ -0,0 +1,94 @@ +# hwi + +- [命令功能](#section445335110416) +- [命令格式](#section1795712553416) +- [参数说明](#section92544592410) +- [使用指南](#section104151141252) +- [使用实例](#section11545171957) +- [输出说明](#section075617368542) + +## 命令功能 + +hwi命令查询当前中断信息 + +## 命令格式 + +hwi + +## 参数说明 + +无。 + +## 使用指南 + +- 输入hwi即显示当前中断号、中断次数及注册中断名称。 +- 若开关LOSCFG\_CPUP\_INCLUDE\_IRQ打开,则还会显示各个中断的处理时间(cycles)、CPU占用率以及中断类型。 + +## 使用实例 + +举例:输入hwi + +## 输出说明 + +1. 显示中断信息(LOSCFG\_CPUP\_INCLUDE\_IRQ关闭) + + ![](figure/zh-cn_image_0000001053826366.png) + +2. 显示中断信息(LOSCFG\_CPUP\_INCLUDE\_IRQ打开) + + ![](figure/zh-cn_image_0000001052810304.png) + + **表 1** 输出说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

InterruptNo

+

中断号。

+

Count

+

中断次数。

+

Name

+

注册中断名称。

+

CYCLECOST

+

中断的处理时间(cycles)。

+

CPUUSE

+

CPU占用率。

+

CPUUSE10s

+

最近10s CPU占用率。

+

CPUUSE1s

+

最近1s CPU占用率。

+

mode

+

中断类型:

+
  • normal: 非共享中断。
  • shared: 共享中断。
+
+ + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-kill.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-kill.md new file mode 100644 index 0000000000000000000000000000000000000000..6f1447fbdaa40653977a87780e2d690f953945b5 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-kill.md @@ -0,0 +1,82 @@ +# kill + +- [命令功能](#section366714216619) +- [命令格式](#section8833164614615) +- [参数说明](#section12809111019453) +- [使用指南](#section15935131220717) +- [使用实例](#section79281818476) +- [输出说明](#section12742311179) + +## 命令功能 + +命令用于发送特定信号给指定进程。 + +## 命令格式 + +kill \[_signo_ | _-signo_\] \[_pid_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

signo

+

信号ID。

+

[1,30]

+

pid

+

进程ID。

+

[1,MAX_INT]

+
+ +>![](../public_sys-resources/icon-notice.gif) **须知:** +>signo有效范围为\[0,64\],建议取值范围为\[1,30\],其余为保留内容。 + +## 使用指南 + +必须指定发送的信号编号及进程号。 + +进程编号取值范围根据系统配置变化,例如系统最大支持pid为256,则取值范围缩小为\[1-256\]。 + +## 使用实例 + +1. 查看当前进程列表,查看需要杀死的进程PID(7)。 + +**图 1** 查看进程PID +![](figure/查看进程PID.png "查看进程PID") + +2. 发送信号14(SIGALRM默认行为为进程终止)给7号进程**helloworld\_d**(用户态进程):**kill 14 7**(kill -14 7效果相同),并查看当前进程列表,7号进程已终止。 + +**图 2** 信号发送结果图 +![](figure/信号发送结果图.png "信号发送结果图") + +## 输出说明 + +发送成功或失败输出结果如下。 + +**图 3** 发送信号给指定进程 +![](figure/发送信号给指定进程.png "发送信号给指定进程") + +信号发送会显示发送记录,未报错表示信号发送成功。 + +**图 4** 信号发送失败 +![](figure/信号发送失败.png "信号发送失败") + +信号发送失败,上图所示原因为信号发送命令参数无效,请排查信号编号及进程编号是否无效。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-log.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-log.md new file mode 100644 index 0000000000000000000000000000000000000000..cdadf9859311d2840f490852045b69d409458ad7 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-log.md @@ -0,0 +1,74 @@ +# log + +- [命令功能](#section128219131856) +- [命令格式](#section3894181710519) +- [参数说明](#section7693122310515) +- [使用指南](#section1982111281512) +- [使用实例](#section176301333259) +- [输出说明](#section14354765415) + +## 命令功能 + +log命令用于修改&查询日志配置。 + +## 命令格式 + +log level \[_levelNum_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

levelNum

+

配置日志打印等级。

+

[0x0,0x5]

+
+ +## 使用指南 + +- 该命令依赖于LOSCFG\_SHELL\_LK,使用时通过menuconfig在配置项中开启"Enable Shell lk": + + Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell lK。 + +- log level命令用于配置日志的打印等级,包括6个等级 + + TRACE\_EMG = 0, + + TRACE\_COMMON = 1, + + TRACE\_ERROR = 2, + + TRACE\_WARN = 3, + + TRACE\_INFO = 4, + + TRACE\_DEBUG = 5 + + 若level不在有效范围内,会打印提示信息。 + +- 若log level命令不加\[levelNum\]参数,则默认查看当前打印等级,并且提示使用方法。 + +## 使用实例 + +举例: + +输入log level 4 + +## 输出说明 + +![](figure/zh-cn_image_0000001052530298.png) + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-mem.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-mem.md new file mode 100644 index 0000000000000000000000000000000000000000..8ff0289bcde30ca0918de0c07ef25194ec5db461 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-mem.md @@ -0,0 +1,38 @@ +# memcheck + +- [命令功能](#section191633812516) +- [命令格式](#section428816435510) +- [参数说明](#section1939943304411) +- [使用指南](#section228914491951) +- [使用实例](#section17373205314515) +- [输出说明](#section13406205385413) + +## 命令功能 + +检查动态申请的内存块是否完整,是否存在内存越界造成节点损坏。 + +## 命令格式 + +memcheck + +## 参数说明 + +无。 + +## 使用指南 + +- 当内存池所有节点完整时,输出"system memcheck over, all passed!"。 +- 当内存池存在节点不完整时,输出被损坏节点的内存块信息。 + +## 使用实例 + +举例:输入memcheck + +## 输出说明 + +**图 1** 当前没有内存越界 +![](figure/当前没有内存越界.png "当前没有内存越界") + +**图 2** 出现内存越界 +![](figure/出现内存越界.png "出现内存越界") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-oom.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-oom.md new file mode 100644 index 0000000000000000000000000000000000000000..e21772b94ea31d1251aa05fcf421ae668bcd6643 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-oom.md @@ -0,0 +1,120 @@ +# oom + +- [命令功能](#section366714216619) +- [命令格式](#section8833164614615) +- [参数说明](#section12809111019453) +- [使用指南](#section15935131220717) +- [使用实例](#section79281818476) +- [输出说明](#section12742311179) + +## 命令功能 + +查看和设置低内存阈值以及pagecache内存回收阈值。 + +## 命令格式 + +oom + +oom -i \[_interval_\] + +oom -m \[_mem byte_\] + +oom -r \[_mem byte_\] + +oom -h | --help + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

-i [interval]

+

设置oom线程任务检查的时间间隔。

+

100ms ~ 10000ms

+

-m [mem byte]

+

设置低内存阈值。

+

0MB ~ 1MB,0MB表示不做低内存阈值检查。

+

-r [mem byte]

+

设置pagecache内存回收阈值。

+

低内存阈值 ~ 系统可用最大内存。

+

-h | --help

+

使用帮助。

+

N/A

+
+ +## 使用指南 + +- 参数缺省时,显示oom功能当前配置信息。 + +## 使用实例 + +当系统内存不足时,会打印出内存不足的提示信息。 + +## 输出说明 + +![](figure/zh-cn_image_0000001053710680.png) + +**表 2** 输出说明 + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

[oom] OS is in low memory state

+

total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte)

+

操作系统处于低内存状态。

+

整个系统可用物理内存为0x1bcf000 byte,已经使用了 0x1b50000 byte, 还剩0x7f000 byte,当前设置的低内存阈值为0x80000 byte。

+

[oom] candidate victim process init pid: 1, actual phy mem byte: 82602

+

打印当前各个进程的内存使用情况,init进程实际使用82602byte,其中共享内存按照比例算的。

+

[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558

+

UserProcess12进程实际使用25951558byte内存。

+

[oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558

+

当前使用内存最多的进程是UserProcess12。

+

excFrom: User!

+

当系统处于低内存的情况下,UserProcess12进程再去申请内存时失败退出。

+
+ diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-pmm.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-pmm.md new file mode 100644 index 0000000000000000000000000000000000000000..067433a0b8361351014f52bbe6cb02c523cc1489 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-pmm.md @@ -0,0 +1,91 @@ +# pmm + +- [命令功能](#section445335110416) +- [命令格式](#section1795712553416) +- [参数说明](#section92544592410) +- [使用指南](#section104151141252) +- [使用实例](#section11545171957) +- [输出说明](#section075617368542) + +## 命令功能 + +查看系统内存物理页及pagecache物理页使用情况。 + +## 命令格式 + +pmm + +## 参数说明 + +无 + +## 使用指南 + +Debug版本才具备的命令。 + +## 使用实例 + +输入pmm + +## 输出说明 + +**图 1** 查看物理页使用情况 +![](figure/查看物理页使用情况.png "查看物理页使用情况") + +**表 1** 输出说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

phys_seg

+

物理页控制块地址信息

+

base

+

第一个物理页地址,即物理页内存起始地址

+

size

+

物理页内存大小

+

free_pages

+

空闲物理页数量

+

active anon

+

pagecache中,活跃的匿名页数量

+

inactive anon

+

pagecache中,不活跃的匿名页数量

+

active file

+

pagecache中,活跃的文件页数量

+

inactive file

+

pagecache中,不活跃的文件页数量

+

pmm pages

+

total:总的物理页数,used:已使用的物理页数,free:空闲的物理页数

+
+ diff --git a/zh-cn/device-dev/kernel/reset.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-reset.md old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/kernel/reset.md rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-reset.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sem.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sem.md new file mode 100644 index 0000000000000000000000000000000000000000..4a27c8d10ba557d0821195e56b5d1c930fe1c627 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sem.md @@ -0,0 +1,91 @@ +# sem + +- [命令功能](#section366714216619) +- [命令格式](#section8833164614615) +- [参数说明](#section12809111019453) +- [使用指南](#section15935131220717) +- [使用实例](#section79281818476) +- [输出说明](#section1975118519456) + +## 命令功能 + +sem命令用于查询系统内核信号量相关信息。 + +## 命令格式 + +sem \[_ID__ / fulldata_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

ID

+

信号ID号。

+

[0, 0xFFFFFFFF]

+

fulldata

+

查询所有在用的信号量信息,打印信息包括如下:SemID, Count, Original Count, Creater TaskEntry, Last Access Time。

+

N/A

+
+ +## 使用指南 + +- 参数缺省时,显示所有的信号量的使用数及信号量总数。 +- sem后加ID,显示对应ID信号量的使用数。 +- 参数fulldata依赖于LOSCFG\_DEBUG\_SEMAPHORE,使用时通过menuconfig在配置项中开启"Enable Semaphore Debugging": + + Debug ---\> Enable a Debug Version ---\> Enable Debug LiteOS Kernel Resource ---\> Enable Semaphore Debugging + + +## 使用实例 + +举例1:输入 sem fulldata + +## 输出说明 + +**图 1** 查询所有在用的信号量信息 +![](figure/查询所有在用的信号量信息.png "查询所有在用的信号量信息") + +**表 2** 输出说明 + + + + + + + + + + + + + +

输出

+

说明

+

SemID

+

信号量ID。

+

Count

+

信号量使用数。

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>● sem命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 +>● sem命令的ID参数在\[0, 1023\]范围内时,返回对应ID的信号量的状态(如果对应ID的信号量未被使用则进行提示);其他取值时返回参数错误的提示。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-stack.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-stack.md new file mode 100644 index 0000000000000000000000000000000000000000..8f2904a4b88d28fed4d39423b8ed85de468fb5be --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-stack.md @@ -0,0 +1,73 @@ +# stack + +- [命令功能](#section445335110416) +- [命令格式](#section1795712553416) +- [参数说明](#section92544592410) +- [使用指南](#section104151141252) +- [使用实例](#section11545171957) +- [输出说明](#section075617368542) + +## 命令功能 + +查看系统各堆栈使用情况。 + +## 命令格式 + +stack + +## 参数说明 + +无。 + +## 使用指南 + +无。 + +## 使用实例 + +输入:stack + +## 输出说明 + +**图 1** 系统堆栈使用情况 + + +![](figure/zh-cn_image_0000001054624363.png) + +**表 1** 输出说明 + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

stack name

+

系统堆栈名

+

cpu id

+

cpu 号

+

stack addr

+

栈地址

+

total size

+

堆栈大小

+

used size

+

堆栈实际使用大小

+
+ diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-su.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-su.md new file mode 100644 index 0000000000000000000000000000000000000000..a8536a0e4d713453a9cb71b85ad1adb692bfd0b2 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-su.md @@ -0,0 +1,62 @@ +# su + +- [命令功能](#section297810431676) +- [命令格式](#section157131147876) +- [参数说明](#section04145521671) +- [使用指南](#section14615155610719) +- [使用实例](#section13338150985) +- [输出说明](#section125021924194613) + +## 命令功能 + +su用于变更为其他使用者的身份。 + +## 命令格式 + +su \[_uid_\] \[_gid_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

uid

+

目标用户的用户id值。

+
  • 为空。
  • [0,60000]
+

gid

+

目标用户的群组id值。

+
  • 为空。
  • [0,60000]
+
+ +## 使用指南 + +- su命令缺省切换到root用户,uid默认为0,gid为0。 +- 在su命令后的输入参数uid和gid就可以切换到该uid和gid的用户。 +- 输入参数超出范围时,会打印提醒输入正确范围参数。 + +## 使用实例 + +举例:su 1000 1000 + +## 输出说明 + +**图 1** **切换到**为uid为1000,gid为1000的用户 +![](figure/切换到为uid为1000-gid为1000的用户.png "切换到为uid为1000-gid为1000的用户") + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-swymr.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-swymr.md new file mode 100644 index 0000000000000000000000000000000000000000..07b2b1b04293f87baa0cb9d47448d2913b594b12 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-swymr.md @@ -0,0 +1,110 @@ +# swtmr + +- [命令功能](#section166171064814) +- [命令格式](#section424011111682) +- [参数说明](#section1268410459465) +- [使用指南](#section169806213815) +- [使用实例](#section16676026389) +- [输出说明](#section1541991614710) + +## 命令功能 + +swtmr命令用于查询系统软件定时器相关信息。 + +## 命令格式 + +swtmr \[_ID_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

ID

+

软件定时器ID号。

+

[0,0xFFFFFFFF]

+
+ +## 使用指南 + +- 参数缺省时,默认显示所有软件定时器的相关信息。 +- swtmr后加ID号时,显示ID对应的软件定时器相关信息。 + +## 使用实例 + +举例:输入swtmr和swtmr 1 + +## 输出说明 + +**图 1** 查询所有软件定时器相关信息 +![](figure/查询所有软件定时器相关信息.png "查询所有软件定时器相关信息") + +**图 2** 查询对应 ID 的软件定时器信息 +![](figure/查询对应-ID-的软件定时器信息.png "查询对应-ID-的软件定时器信息") + +**表 2** 输出说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

SwTmrID

+

软件定时器ID。

+

State

+

软件定时器状态。

+

状态可能为:"UnUsed", "Created", "Ticking"。

+

Mode

+

软件定时器模式。

+

模式可能为:"Once", "Period", "NSD(单次定时器,定时结束后不会自动删除)"。

+

Interval

+

软件定时器使用的Tick数。

+

Count

+

软件定时器已经工作的次数。

+

Arg

+

传入的参数。

+

handlerAddr

+

回调函数的地址。

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>- swtmr命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 +>- swtmr命令的ID参数在\[0, 当前软件定时器个数 - 1\]范围内时,返回对应ID的软件定时器的状态;其他取值时返回错误提示。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sys.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sys.md new file mode 100644 index 0000000000000000000000000000000000000000..8b59757af0093680a9f16f986e0f3bd864aa6fba --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-sys.md @@ -0,0 +1,91 @@ +# systeminfo + +- [命令功能](#section863016434820) +- [命令格式](#section139791817795) +- [参数说明](#section19472339164813) +- [使用指南](#section285522592) +- [使用实例](#section9471171015105) +- [输出说明](#section1657011114915) + +## 命令功能 + +systeminfo命令用于显示当前操作系统内资源使用情况,包括任务、信号量、互斥量、队列、定时器等。 + +## 命令格式 + +systeminfo + +## 参数说明 + +无。 + +## 使用指南 + +无。 + +## 使用实例 + +举例:输入systeminfo + +## 输出说明 + +**图 1** 查看系统资源使用情况 +![](figure/查看系统资源使用情况.png "查看系统资源使用情况") + +**表 1** 输出说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

Module

+

模块名称。

+

Used

+

当前使用量。

+

Total

+

最大可用量。

+

Enabled

+

模块是否开启。

+

Task

+

任务。

+

Sem

+

信号量。

+

Mutex

+

互斥量。

+

Queue

+

队列。

+

SwTmr

+

定时器。

+
+ diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-task.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-task.md new file mode 100644 index 0000000000000000000000000000000000000000..4fb2b3e3f8fcd34a9f102e4a2c75b00ff018445b --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-task.md @@ -0,0 +1,125 @@ +# task + +- [命令功能](#section0533181714106) +- [命令格式](#section1014412308101) +- [参数说明](#section116057158506) +- [使用指南](#section2053502951112) +- [使用实例](#section12629113381116) +- [输出说明](#section19299103465015) + +## 命令功能 + +task命令用于查询进程及线程信息。 + +## 命令格式 + +task/task -a + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

-a

+

查看更多信息。

+

N/A

+
+ +## 使用指南 + +- 参数缺省时默认打印部分任务信息。 + +## 使用实例 + +举例:输入task + +## 输出说明 + +**图 1** 查询任务部分信息 +![](figure/查询任务部分信息.png "查询任务部分信息") + +**表 2** 输出说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

PID

+

进程ID。

+

PPID

+

父进程ID。

+

PGID

+

进程组ID。

+

UID

+

用户ID。

+

Status

+

任务当前的状态。

+

CPUUSE10s

+

10秒内CPU使用率。

+

PName

+

进程名。

+

TID

+

任务ID。

+

StackSize

+

任务堆栈的大小。

+

WaterLine

+

栈使用的峰值。

+

MEMUSE

+

内存使用量。

+

TaskName

+

任务名。

+
+ diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-uname.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-uname.md new file mode 100644 index 0000000000000000000000000000000000000000..ff2c1b7a3db2ee050c384be9216102e3d8d30eeb --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-uname.md @@ -0,0 +1,72 @@ +# uname + +- [命令功能](#section107697383115) +- [命令格式](#section162824341116) +- [使用指南](#section2652124861114) +- [使用实例](#section0107995132) +- [输出说明](#section1215113245511) + +## 命令功能 + +uname命令用于显示当前操作系统的名称,版本创建时间,系统名称,版本信息等。 + +## 命令格式 + +uname \[_-a | -s | -t | -v | --help_\] + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

无参数

+

默认显示操作系统名称。

+

-a

+

显示全部信息。

+

-t

+

显示版本创建的时间。

+

-s

+

显示操作系统名称。

+

-v

+

显示版本信息。

+

--help

+

显示uname指令格式提示。

+
+ +## 使用指南 + +uname用于显示当前操作系统名称。语法uname -a | -t| -s| -v 描述uname 命令将正在使用的操作系统名写到标准输出中,这几个参数不能混合使用。 + +## 使用实例 + +举例:输入uname -a + +## 输出说明 + +查看系统信息 + +![](figure/zh-cn_image_0000001052370305.png) + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-vmm.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-vmm.md new file mode 100644 index 0000000000000000000000000000000000000000..35f4ada41e1f7043ea60d584065662facf59f88a --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-vmm.md @@ -0,0 +1,158 @@ +# vmm + +- [命令功能](#section445335110416) +- [命令格式](#section1795712553416) +- [参数说明](#section92544592410) +- [使用指南](#section104151141252) +- [使用实例](#section11545171957) +- [输出说明](#section075617368542) + +## 命令功能 + +查看进程的虚拟内存使用情况。 + +## 命令格式 + +vmm \[_-a / -h / --help_\] + +vmm \[_pid_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

取值范围

+

-a

+

输出所有进程的虚拟内存使用情况

+

N/A

+

-h | --help

+

命令格式说明

+

N/A

+

pid

+

进程ID,说明指定进程的虚拟内存使用情况

+

[0,63]

+
+ +## 使用指南 + +命令缺省输出所有进程的虚拟内存使用情况。 + +## 使用实例 + +输入vmm 3 + +## 输出说明 + +**图 1** PID为3的进程虚拟内存使用信息 +![](figure/PID为3的进程虚拟内存使用信息.png "PID为3的进程虚拟内存使用信息") + +**表 2** 进程基本信息 + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

PID

+

进程ID

+

aspace

+

进程虚拟内存控制块地址信息

+

name

+

进程名

+

base

+

虚拟内存起始地址

+

size

+

虚拟内存大小

+

pages

+

已使用的物理页数量

+
+ +**表 3** 虚拟内存区间信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

输出

+

说明

+

region

+

虚拟区间控制块地址信息

+

name

+

虚拟区间类型

+

base

+

虚拟区间起始地址

+

size

+

虚拟区间大小

+

mmu_flags

+

虚拟区间mmu映射属性

+

pages

+

已使用的物理页数量(包括共享内存部分)

+

pg/ref

+

已使用的物理页数量

+
+ diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-watch.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-watch.md new file mode 100644 index 0000000000000000000000000000000000000000..c3adf787bbca3f7deb8165ed2c1d8e15204dd168 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys-watch.md @@ -0,0 +1,100 @@ +# watch + +- [命令功能](#section20643141481314) +- [命令格式](#section1075441721316) +- [参数说明](#section1472810220135) +- [使用指南](#section186772414131) +- [使用实例](#section4764192791314) +- [输出说明](#section5791253155517) + +## 命令功能 + +watch命令用于周期性的监视一个命令的运行结果。 + +## 命令格式 + +watch + +watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] + +## 参数说明 + +**表 1** 参数说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

缺省值

+

取值范围

+

-c / --count

+

命令执行的总次数。

+

0xFFFFFF

+

(0,0xFFFFFF]

+

-n / --interval

+

命令周期性执行的时间间隔(s)。

+

1s

+

(0,0xFFFFFF]

+

-t / -no-title

+

关闭顶端的时间显示。

+

N/A

+

N/A

+

command

+

需要监测的命令。

+

N/A

+

N/A

+

--over

+

关闭当前监测指令。

+

N/A

+

N/A

+
+ +## 使用指南 + +watch运行过程中可以执行**watch --over**结束本次watch命令。 + +## 使用实例 + +输入举例: + +watch -n 2 -c 6 task + +## 输出说明 + +**图 1** watch task 结果 +![](figure/watch-task-结果.png "watch-task-结果") + +>![](../public_sys-resources/icon-note.gif) **说明:** +>示例中,总共有6次task命令打印,每次间隔2秒,截图为最后一次打印详情。 + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys.md new file mode 100644 index 0000000000000000000000000000000000000000..8bccc06e167edac3be5d99cf37d1aeb81427c730 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd-sys.md @@ -0,0 +1,47 @@ +# 系统命令 + +- **[cpup](kernel-lite-small-shell-cmd-sys-cpup.md)** + +- **[date](kernel-lite-small-shell-cmd-sys-date.md)** + +- **[dmesg](kernel-lite-small-shell-cmd-sys-demsg.md)** + +- **[exec](kernel-lite-small-shell-cmd-sys-exec.md)** + +- **[free](kernel-lite-small-shell-cmd-sys-free.md)** + +- **[help](kernel-lite-small-shell-cmd-sys-help.md)** + +- **[hwi](kernel-lite-small-shell-cmd-sys-hwi.md)** + +- **[kill](kernel-lite-small-shell-cmd-sys-kill.md)** + +- **[log](kernel-lite-small-shell-cmd-sys-log.md)** + +- **[memcheck](kernel-lite-small-shell-cmd-sys-mem.md)** + +- **[oom](kernel-lite-small-shell-cmd-sys-oom.md)** + +- **[pmm](kernel-lite-small-shell-cmd-sys-pmm.md)** + +- **[reset](kernel-lite-small-shell-cmd-sys-reset.md)** + +- **[sem](kernel-lite-small-shell-cmd-sys-sem.md)** + +- **[stack](kernel-lite-small-shell-cmd-sys-stack.md)** + +- **[su](kernel-lite-small-shell-cmd-sys-su.md)** + +- **[swtmr](kernel-lite-small-shell-cmd-sys-swymr.md)** + +- **[systeminfo](kernel-lite-small-shell-cmd-sys-sys.md)** + +- **[task](kernel-lite-small-shell-cmd-sys-task.md)** + +- **[uname](kernel-lite-small-shell-cmd-sys-uname.md)** + +- **[vmm](kernel-lite-small-shell-cmd-sys-vmm.md)** + +- **[watch](kernel-lite-small-shell-cmd-sys-watch.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd.md new file mode 100644 index 0000000000000000000000000000000000000000..95d4b92cffc8d087d40831a981d3f3f7828399a9 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-cmd.md @@ -0,0 +1,13 @@ +# Shell命令使用详解 + +本章节介绍了系统关键命令的功能、格式、参数范围、使用指南和使用实例。 + +不在本文档范围内的命令,详见[help](kernel-lite-small-shell-cmd-sys-help.md)命令的输出内容,也可以通过命令的“-h | --help”选项,查看该命令的使用帮助。 + +- **[系统命令](kernel-lite-small-shell-cmd-sys.md)** + +- **[文件命令](kernel-lite-small-shell-cmd-file.md)** + +- **[网络命令](kernel-lite-small-shell-cmd-net.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-des.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-des.md new file mode 100644 index 0000000000000000000000000000000000000000..8b7909db2079b4225c6253fee4318d83c3afa16d --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-des.md @@ -0,0 +1,36 @@ +# Shell介绍 + +- [注意事项](#section12298165312328) + +OpenHarmony内核提供的Shell支持调试常用的基本功能,包含系统、文件、网络和动态加载相关命令。同时OpenHarmony内核的Shell支持添加新的命令,可以根据需求来进行定制。 + +- 系统相关命令:提供查询系统任务、内核信号量、系统软件定时器、CPU占用率、当前中断等相关信息的能力。 + +- 文件相关命令:支持基本的ls、cd等功能。 + +- 网络相关命令:支持查询接到开发板的其他设备的IP、查询本机IP、测试网络连接、设置开发板的AP和station模式等相关功能。 + + 新增命令的详细流程可参见[开发指导](kernel-lite-small-shell-guide.md)和[编程实例](kernel-lite-small-shell-sample.md)。 + + +## 注意事项 + +在使用Shell功能的过程中,需要注意以下几点: + +- Shell功能支持使用exec命令来运行可执行文件。 +- Shell功能支持默认模式下英文输入。如果出现用户在UTF-8格式下输入了中文字符的情况,只能通过回退三次来删除。 + +- Shell功能支持shell命令、文件名及目录名的Tab键联想补全。若有多个匹配项,则根据共同字符, 打印多个匹配项。对于过多的匹配项(打印多于24行),将会进行打印询问(Display all num possibilities?(y/n)),用户可输入y选择全部打印,或输入n退出打印,选择全部打印并打印超过24行后,会进行--More--提示,此时按回车键继续打印,按q键退出(支持Ctrl+c退出\)。 + +- Shell端工作目录与系统工作目录是分开的,即通过Shell端cd pwd等命令是对Shell端工作目录进行操作,通过chdir getcwd等命令是对系统工作目录进行操作,两个工作目录相互之间没有联系。当文件系统操作命令入参是相对路径时要格外注意。 + +- 在使用网络Shell指令前,需要先调用tcpip\_init函数完成网络初始化并完成telnet连接后才能起作用,内核默认不初始化tcpip\_init。 + +- 不建议使用Shell命令对/dev目录下的设备文件进行操作,这可能会引起不可预知的结果。 + +- Shell功能不符合POSIX标准,仅供调试使用。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >Shell功能仅供调试使用,在Debug版本中开启(使用时通过menuconfig在配置项中开启"LOSCFG\_DEBUG\_VERSION"编译开关进行相关控制),商用产品中禁止包含该功能。 + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell-guide.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..7f7327f6b2899440de2152975b099e6127d3d134 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell-guide.md @@ -0,0 +1,167 @@ +# Shell命令开发指导 + +- [开发指导](#section22071515161018) + +## 开发指导 + +新增Shell命令的典型开发流程如下: + +1. 包含如下头文件: + + ``` + #include "shell.h" + #include "shcmd.h" + ``` + +2. 注册命令。用户可以选择静态注册命令方式和系统运行时动态注册命令方式,静态注册命令方式一般用在系统常用命令注册,动态注册命令方式一般用在用户命令注册。 + + 1. 静态注册命令方式: + + 1. 通过宏的方式注册。 + + 这个宏的原型为: + + ``` + SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) + ``` + + **表 1** SHELLCMD\_ENTRY参数详解 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

l

+

静态注册全局变量名(注意:不与系统中其他symbol重名)。

+

cmdType

+

命令类型:

+
  • CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。

    +
  • CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。

    +
+

cmdKey

+

命令关键字,函数在Shell中访问的名称。

+

paraNum

+

调用的执行函数的入参最大个数,暂不支持。

+

cmdHook

+

命令执行函数地址,即命令实际执行函数。

+
+ + 如: + + ``` + SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) + ``` + + 2. 在build/mk/liteos\_tables\_ldflags.mk中添加相应选项: + + 如:上述“ls”命令注册时,需在build/mk/liteos\_tables\_ldflags.mk中添加“-uls\_shellcmd”。其中-u后面跟SHELLCMD\_ENTRY的第一个参数。 + + + 2. 动态注册命令方式: + + 注册函数原型: + + ``` + UINT32 osCmdReg(CmdT ype cmdType, CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) + ``` + + **表 2** UINT32 osCmdReg参数详解 + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

cmdType

+

命令类型:

+
  • CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。

    +
  • CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。

    +
+

cmdKey

+

命令关键字,函数在Shell中访问的名称。

+

paraNum

+

调用的执行函数的入参最大个数,暂不支持该参数;当前为默认值XARGS(0xFFFFFFFF)。

+

cmdHook

+

命令执行函数地址,即命令实际执行函数。

+
+ + 如: + + ``` + osCmdReg(CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) + ``` + + + >![](../public_sys-resources/icon-note.gif) **说明:** + >命令关键字必须是唯一的,也即两个不同的命令项不能拥有相同的命令关键字,否则只会执行其中一个。 + >Shell在执行用户命令时,如果存在多个命令关键字相同的命令,只会执行其中在"help"命令中排序在最前面的一个。 + +3. 添加内置命令函数原型。 + + ``` + UINT32 osShellCmdLs(UINT32 argc, CHAR **argv) + ``` + + **表 3** osShellCmdLs参数说明 + + + + + + + + + + + + + +

参数

+

参数描述

+

argc

+

Shell命令中,参数个数。

+

argv

+

为指针数组,每个元素指向一个字符串,可以根据选择命令类型,决定是否要把命令关键字传入给注册函数。

+
+ +4. 输入Shell命令,有两种输入方式: + - 在串口工具中直接输入Shell命令。 + + - 在telnet工具中输入Shell命令(telnet使用方式详见[telnet](kernel-lite-small-shell-cmd-net-tel.md))。 + + + diff --git "a/zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\347\274\226\347\250\213\345\256\236\344\276\213.md" b/zh-cn/device-dev/kernel/kernel-lite-small-shell-sample.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/Shell\345\221\275\344\273\244\347\274\226\347\250\213\345\256\236\344\276\213.md" rename to zh-cn/device-dev/kernel/kernel-lite-small-shell-sample.md diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-shell.md b/zh-cn/device-dev/kernel/kernel-lite-small-shell.md new file mode 100644 index 0000000000000000000000000000000000000000..edc56c8c73e6e879e3dac5813fc5e4d502b940e6 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-shell.md @@ -0,0 +1,15 @@ +# 调测 + +- **[Shell介绍](kernel-lite-small-shell-des.md)** + +- **[Shell命令开发指导](kernel-lite-small-shell-guide.md)** + +- **[Shell命令编程实例](kernel-lite-small-shell-sample.md)** + +- **[Shell命令使用详解](kernel-lite-small-shell-cmd.md)** + +- **[魔法键使用方法](kernel-lite-small-shell-cmd-mag.md)** + +- **[用户态异常信息说明](kernel-lite-small-shell-cmd-abn.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite-small-thread.md b/zh-cn/device-dev/kernel/kernel-lite-small-thread.md new file mode 100644 index 0000000000000000000000000000000000000000..b758c77877f7f426c10d031f9c68d6b3c310cb8f --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small-thread.md @@ -0,0 +1,702 @@ +# 线程 + +- [基本概念](#section1179311337405) +- [使用场景](#section44877547404) +- [接口说明](#section2069477134115) + +## 基本概念 + +从系统的角度看,线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它线程运行。 + +OpenHarmony内核每个进程内的线程独立运行、独立调度,当前进程内线程的调度不受其它进程内线程的影响。 + +OpenHarmony内核中的线程采用抢占式调度机制,同时支持时间片轮转调度和FIFO调度方式。 + +OpenHarmony内核的线程一共有32个优先级\(0-31\),最高优先级为0,最低优先级为31。 + +当前进程内高优先级的线程可抢占当前进程内低优先级线程,当前进程内低优先级线程必须在当前进程内高优先级线程阻塞或结束后才能得到调度。 + +**线程状态说明:** + +- 初始化(Init):该线程正在被创建。 + +- 就绪(Ready):该线程在就绪列表中,等待CPU调度。 + +- 运行(Running):该线程正在运行。 + +- 阻塞(Blocked):该线程被阻塞挂起。Blocked状态包括:pending\(因为锁、事件、信号量等阻塞\)、suspended(主动pend)、delay\(延时阻塞\)、pendtime\(因为锁、事件、信号量时间等超时等待\)。 + +- 退出(Exit):该线程运行结束,等待父线程回收其控制块资源。 + + +**图 1** 线程状态迁移示意图 +![](figure/线程状态迁移示意图.png "线程状态迁移示意图") + +**线程状态迁移说明:** + +- Init→Ready: + + 线程创建拿到控制块后为Init状态,处于线程初始化阶段,当线程初始化完成将线程插入调度队列,此时线程进入就绪状态。 + +- Ready→Running: + + 线程创建后进入就绪态,发生线程切换时,就绪列表中最高优先级的线程被执行,从而进入运行态,但此刻该线程会从就绪列表中删除。 + +- Running→Blocked: + + 正在运行的线程发生阻塞(挂起、延时、读信号量等)时,线程状态由运行态变成阻塞态,然后发生线程切换,运行就绪列表中剩余最高优先级线程。 + +- Blocked→Ready : + + 阻塞的线程被恢复后(线程恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的线程会被加入就绪列表,从而由阻塞态变成就绪态。 + +- Ready→Blocked: + + 线程也有可能在就绪态时被阻塞(挂起),此时线程状态会由就绪态转变为阻塞态,该线程从就绪列表中删除,不会参与线程调度,直到该线程被恢复。 + +- Running→Ready: + + 有更高优先级线程创建或者恢复后,会发生线程调度,此刻就绪列表中最高优先级线程变为运行态,那么原先运行的线程由运行态变为就绪态,并加入就绪列表中。 + +- Running→Exit: + + 运行中的线程运行结束,线程状态由运行态变为退出态。若未设置分离属性(PTHREAD\_CREATE\_DETACHED)的线程,运行结束后对外呈现的是Exit状态,即退出态。 + + +## 使用场景 + +线程创建后,用户态可以执行线程调度、挂起、恢复、延时等操作,同时也可以设置线程优先级和调度策略,获取线程优先级和调度策略。 + +## 接口说明 + +OpenHarmony内核系统中的线程管理模块,线程间通信为用户提供下面几种功能: + +**表 1** 线程管理模块功能 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

名称

+

说明

+

备注

+

pthread.h

+

pthread_attr_destroy

+

销毁线程属性对象。

+

-

+

pthread.h

+

pthread_attr_getinheritsched

+

获取线程属性对象的调度属性。

+

-

+

pthread.h

+

pthread_attr_getschedparam

+

获取线程属性对象的调度参数属性。

+

-

+

pthread.h

+

pthread_attr_getschedpolicy

+

获取线程属性对象的调度策略属性。

+

OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。

+

pthread.h

+

pthread_attr_getstacksize

+

获取线程属性对象的堆栈大小。

+

-

+

pthread.h

+

pthread_attr_init

+

初始化线程属性对象。

+

-

+

pthread.h

+

pthread_attr_setdetachstate

+

设置线程属性对象的分离状态。

+

-

+

pthread.h

+

pthread_attr_setinheritsched

+

设置线程属性对象的继承调度属性。

+

-

+

pthread.h

+

pthread_attr_setschedparam

+

设置线程属性对象的调度参数属性。

+

OpenHarmony:设置线程优先级的参数值越小,线程在系统中的优先级越高;设置参数值越大,优先级越低。

+

注意:需要将pthread_attr_t线程属性的inheritsched字段设置为PTHREAD_EXPLICIT_SCHED,否则设置的线程调度优先级将不会生效,系统默认设置为PTHREAD_INHERIT_SCHED。

+

pthread.h

+

pthread_attr_setschedpolicy

+

设置线程属性对象的调度策略属性。

+

OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。

+

pthread.h

+

pthread_attr_setstacksize

+

设置线程属性对象的堆栈大小。

+

-

+

pthread.h

+

pthread_getattr_np

+

获取已创建线程的属性。

+

-

+

pthread.h

+

pthread_cancel

+

向线程发送取消请求。

+

-

+

pthread.h

+

pthread_testcancel

+

请求交付任何未决的取请求。

+

-

+

pthread.h

+

pthread_setcanceltype

+

设置线程可取消类型。

+

-

+

pthread.h

+

pthread_setcancelstate

+

设置线程可取消状态。

+

-

+

pthread.h

+

pthread_create

+

创建一个新的线程。

+

-

+

pthread.h

+

pthread_detach

+

分离一个线程。

+

-

+

pthread.h

+

pthread_equal

+

比较两个线程ID是否相等。

+

-

+

pthread.h

+

pthread_exit

+

终止正在调用的线程。

+

-

+

pthread.h

+

pthread_getschedparam

+

获取线程的调度策略和参数。

+

OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。

+

pthread.h

+

pthread_join

+

等待指定的线程结束。

+

-

+

pthread.h

+

pthread_self

+

获取当前线程的ID。

+

-

+

pthread.h

+

pthread_setschedprio

+

设置线程的调度静态优先级。

+

-

+

pthread.h

+

pthread_kill

+

向线程发送信号。

+

-

+

pthread.h

+

pthread_once

+

使函数调用只能执行一次。

+

-

+

pthread.h

+

pthread_atfork

+

注册fork的处理程序。

+

-

+

pthread.h

+

pthread_cleanup_pop

+

删除位于清理处理程序堆栈顶部的例程。

+

-

+

pthread.h

+

pthread_cleanup_push

+

将例程推送到清理处理程序堆栈的顶部。

+

-

+

pthread.h

+

pthread_barrier_destroy

+

销毁屏障对象(高级实时线程)

+

-

+

pthread.h

+

pthread_barrier_init

+

初始化屏障对象(高级实时线程)

+

-

+

pthread.h

+

pthread_barrier_wait

+

屏障同步(高级实时线程)

+

-

+

pthread.h

+

pthread_barrierattr_destroy

+

销毁屏障属性对象。

+

-

+

pthread.h

+

pthread_barrierattr_init

+

初始化屏障属性对象。

+

-

+

pthread.h

+

pthread_mutex_destroy

+

销毁互斥锁。

+

-

+

pthread.h

+

pthread_mutex_init

+

初始化互斥锁。

+

-

+

pthread.h

+

pthread_mutex_lock

+

互斥锁加锁操作。

+

-

+

pthread.h

+

pthread_mutex_trylock

+

互斥锁尝试加锁操作。

+

-

+

pthread.h

+

pthread_mutex_unlock

+

互斥锁解锁操作。

+

-

+

pthread.h

+

pthread_mutexattr_destroy

+

销毁互斥锁属性对象。

+

-

+

pthread.h

+

pthread_mutexattr_gettype

+

获取互斥锁类型属性。

+

-

+

pthread.h

+

pthread_mutexattr_init

+

初始化互斥锁属性对象。

+

-

+

pthread.h

+

pthread_mutexattr_settype

+

设置互斥锁类型属性。

+

-

+

pthread.h

+

pthread_mutex_timedlock

+

使用超时锁定互斥锁。

+

-

+

pthread.h

+

pthread_rwlock_destroy

+

销毁读写锁。

+

-

+

pthread.h

+

pthread_rwlock_init

+

初始化读写锁。

+

-

+

pthread.h

+

pthread_rwlock_rdlock

+

获取读写锁读锁操作。

+

-

+

pthread.h

+

pthread_rwlock_timedrdlock

+

使用超时锁定读写锁读锁。

+

-

+

pthread.h

+

pthread_rwlock_timedwrlock

+

使用超时锁定读写锁写锁。

+

-

+

pthread.h

+

pthread_rwlock_tryrdlock

+

尝试获取读写锁读锁操作。

+

-

+

pthread.h

+

pthread_rwlock_trywrlock

+

尝试获取读写锁写锁操作。

+

-

+

pthread.h

+

pthread_rwlock_unlock

+

读写锁解锁操作。

+

-

+

pthread.h

+

pthread_rwlock_wrlock

+

获取读写锁写锁操作。

+

-

+

pthread.h

+

pthread_rwlockattr_destroy

+

销毁读写锁属性对象。

+

-

+

pthread.h

+

pthread_rwlockattr_init

+

初始化读写锁属性对象。

+

-

+

pthread.h

+

pthread_cond_broadcast

+

解除若干已被等待条件阻塞的线程。

+

-

+

pthread.h

+

pthread_cond_destroy

+

销毁条件变量。

+

-

+

pthread.h

+

pthread_cond_init

+

初始化条件变量。

+

-

+

pthread.h

+

pthread_cond_signal

+

解除被阻塞的线程。

+

-

+

pthread.h

+

pthread_cond_timedwait

+

定时等待条件。

+

-

+

pthread.h

+

pthread_cond_wait

+

等待条件。

+

-

+

semaphore.h

+

sem_destroy

+

销毁指定的无名信号量。

+

-

+

semaphore.h

+

sem_getvalue

+

获得指定信号量计数值。

+

-

+

semaphore.h

+

sem_init

+

创建并初始化一个无名信号量。

+

-

+

semaphore.h

+

sem_post

+

增加信号量计数。

+

-

+

semaphore.h

+

sem_timedwait

+

获取信号量,且有超时返回功能。

+

-

+

semaphore.h

+

sem_trywait

+

尝试获取信号量。

+

-

+

semaphore.h

+

sem_wait

+

获取信号量。

+

-

+
+ diff --git a/zh-cn/device-dev/kernel/kernel-lite-small.md b/zh-cn/device-dev/kernel/kernel-lite-small.md new file mode 100644 index 0000000000000000000000000000000000000000..a435da97d4b79e35ab0c7e8526a5df706569f215 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite-small.md @@ -0,0 +1,11 @@ +# 小型系统内核 + +- **[基础内核](kernel-lite-small-basic.md)** + +- **[文件系统](kernel-lite-small-file.md)** + +- **[标准库](kernel-lite-small-lib.md)** + +- **[调测](kernel-lite-small-shell.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-lite.md b/zh-cn/device-dev/kernel/kernel-lite.md new file mode 100644 index 0000000000000000000000000000000000000000..f6fcf22c8ec9b834dde5bf84d5b6a13b26c477be --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-lite.md @@ -0,0 +1,7 @@ +# 轻量和小型系统内核 + +- **[轻量系统内核](kernel-lite-mini.md)** + +- **[小型系统内核](kernel-lite-small.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel-standard-build.md b/zh-cn/device-dev/kernel/kernel-standard-build.md new file mode 100644 index 0000000000000000000000000000000000000000..1b52ac7b1f6ef75cb9c1e29e611e54ab24831d79 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-standard-build.md @@ -0,0 +1,47 @@ +# Linux内核编译与构建指导 + +- [开发示例1](#section19369206113115) + - [场景1:版本级编译原生方式](#section1025111193220) + - [场景2:单独编译修改后的内核](#section17446652173211) + + +## 开发示例1 + +以hi3516dv300开源开发板+ubuntu x86主机开发环境为例。 + +### 场景1:版本级编译原生方式 + +使用工程的全量编译命令,编译生成uImage内核镜像 + +``` +./build.sh --product-name Hi3516DV300 # 编译hi3516dv300的uImage内核镜像 +``` + +### 场景2:单独编译修改后的内核 + +1. 准备工作 + + 1. 按[开发板Patch使用指导](kernel-standard-patch.md)打入所需补丁。 + 2. 准备编译环境,可以使用开源arm clang/gcc编译器。 + + 进入工程主目录配置环境变量: + + ``` + export PATH=`pwd`/prebuilts/clang/host/linux-x86/clang-r353983c/bin:`pwd`/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/:$PATH # 配置编译环境 + MAKE_OPTIONES="ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CC=clang HOSTCC=clang" # 使用工程项目自带的clang环境 + ``` + +2. 修改内核代码或内核config (OpenHarmony提供对应平台的defconfig供参考)。 +3. 创建编译目录及生成内核.config。 + + ``` + make ${MAKE_OPTIONES} hi3516dv300_emmc_smp_hos_l2_defconfig # 使用自带的默认config 构建内核 + ``` + +4. 编译生成对应的内核Image。 + + ``` + make ${MAKE_OPTIONES} -j32 uImage # 编译uImage内核镜像 + ``` + + diff --git "a/zh-cn/device-dev/kernel/Linux\345\206\205\346\240\270\346\246\202\350\277\260.md" b/zh-cn/device-dev/kernel/kernel-standard-des.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/Linux\345\206\205\346\240\270\346\246\202\350\277\260.md" rename to zh-cn/device-dev/kernel/kernel-standard-des.md diff --git a/zh-cn/device-dev/kernel/kernel-standard-patch.md b/zh-cn/device-dev/kernel/kernel-standard-patch.md new file mode 100644 index 0000000000000000000000000000000000000000..87b3fea376cbb44d0f082ffdc2bc87c59fbda1d3 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-standard-patch.md @@ -0,0 +1,17 @@ +# OpenHarmony开发板Patch使用指导 + +Patch文件位于工程项目源码路径:kernel/linux/patches/linux-4.19,存放特定芯片架构驱动补丁。 + +如需使用特定芯片平台驱动的Patch,需要在内核仓代码完成对芯片平台驱动补丁合入。 + +合入芯片平台驱动补丁,针对不同芯片平台合入对应的patch: + +以Hi3516dv300为例: + +``` +patch -p1 < device/hisilicon/hi3516dv300/sdk_linux/open_source/linux/hisi_linux-4.19_hos_l2.patch +``` + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>由于OpenHarmony的编译构建流程中会拷贝kernel/linux-4.19的代码环境后进行打补丁动作,在使用OpenHarmony的版本级编译命令前,需要kernel/linux-4.19保持原代码环境。 + diff --git a/zh-cn/device-dev/kernel/kernel-standard.md b/zh-cn/device-dev/kernel/kernel-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..67af7b81d0828a100373e0ab9de0d5b4dee9cd92 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-standard.md @@ -0,0 +1,9 @@ +# 标准系统内核 + +- **[Linux内核概述](kernel-standard-des.md)** + +- **[OpenHarmony开发板Patch使用指导](kernel-standard-patch.md)** + +- **[Linux内核编译与构建指导](kernel-standard-build.md)** + + diff --git a/zh-cn/device-dev/kernel/kernel.md b/zh-cn/device-dev/kernel/kernel.md new file mode 100644 index 0000000000000000000000000000000000000000..05e683e74b37a2999709a58946b4377b4175feb4 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel.md @@ -0,0 +1,7 @@ +# 内核 + +- **[轻量和小型系统内核](kernel-lite.md)** + +- **[标准系统内核](kernel-standard.md)** + + diff --git a/zh-cn/device-dev/kernel/kill.md b/zh-cn/device-dev/kernel/kill.md deleted file mode 100755 index c88e6abc63e0eba88eaa6881366b88de3ab290f6..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/kill.md +++ /dev/null @@ -1,82 +0,0 @@ -# kill - -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section12742311179) - -## 命令功能 - -命令用于发送特定信号给指定进程。 - -## 命令格式 - -kill \[_signo_ | _-signo_\] \[_pid_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

signo

-

信号ID。

-

[1,30]

-

pid

-

进程ID。

-

[1,MAX_INT]

-
- ->![](public_sys-resources/icon-notice.gif) **须知:** ->signo有效范围为\[0,64\],建议取值范围为\[1,30\],其余为保留内容。 - -## 使用指南 - -必须指定发送的信号编号及进程号。 - -进程编号取值范围根据系统配置变化,例如系统最大支持pid为256,则取值范围缩小为\[1-256\]。 - -## 使用实例 - -1. 查看当前进程列表,查看需要杀死的进程PID(7)。 - -**图 1** 查看进程PID -![](figures/查看进程PID.png "查看进程PID") - -2. 发送信号14(SIGALRM默认行为为进程终止)给7号进程**helloworld\_d**(用户态进程):**kill 14 7**(kill -14 7效果相同),并查看当前进程列表,7号进程已终止。 - -**图 2** 信号发送结果图 -![](figures/信号发送结果图.png "信号发送结果图") - -## 输出说明 - -发送成功或失败输出结果如下。 - -**图 3** 发送信号给指定进程 -![](figures/发送信号给指定进程.png "发送信号给指定进程") - -信号发送会显示发送记录,未报错表示信号发送成功。 - -**图 4** 信号发送失败 -![](figures/信号发送失败.png "信号发送失败") - -信号发送失败,上图所示原因为信号发送命令参数无效,请排查信号编号及进程编号是否无效。 - diff --git a/zh-cn/device-dev/kernel/log.md b/zh-cn/device-dev/kernel/log.md deleted file mode 100755 index d6972d55512d7cddf07d2791e586fbe4b00494a8..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/log.md +++ /dev/null @@ -1,74 +0,0 @@ -# log - -- [命令功能](#section128219131856) -- [命令格式](#section3894181710519) -- [参数说明](#section7693122310515) -- [使用指南](#section1982111281512) -- [使用实例](#section176301333259) -- [输出说明](#section14354765415) - -## 命令功能 - -log命令用于修改&查询日志配置。 - -## 命令格式 - -log level \[_levelNum_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

levelNum

-

配置日志打印等级。

-

[0x0,0x5]

-
- -## 使用指南 - -- 该命令依赖于LOSCFG\_SHELL\_LK,使用时通过menuconfig在配置项中开启"Enable Shell lk": - - Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell lK。 - -- log level命令用于配置日志的打印等级,包括6个等级 - - TRACE\_EMG = 0, - - TRACE\_COMMON = 1, - - TRACE\_ERROR = 2, - - TRACE\_WARN = 3, - - TRACE\_INFO = 4, - - TRACE\_DEBUG = 5 - - 若level不在有效范围内,会打印提示信息。 - -- 若log level命令不加\[levelNum\]参数,则默认查看当前打印等级,并且提示使用方法。 - -## 使用实例 - -举例: - -输入log level 4 - -## 输出说明 - -![](figures/zh-cn_image_0000001052530298.png) - diff --git a/zh-cn/device-dev/kernel/ls.md b/zh-cn/device-dev/kernel/ls.md deleted file mode 100755 index fa17ee74660b045d3f3c0d4da8f78a21d517e2f1..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/ls.md +++ /dev/null @@ -1,59 +0,0 @@ -# ls - -- [命令功能](#section6538163771614) -- [命令格式](#section45881743111616) -- [参数说明](#section17528148171617) -- [使用指南](#section041212533166) -- [使用实例](#section986105716167) -- [输出说明](#section2036124918592) - -## 命令功能 - -ls命令用来显示当前目录的内容。 - -## 命令格式 - -ls \[_path_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

path

-

path为空时,显示当前目录的内容。

-

path为无效文件名时,显示失败,提示:

-

ls error: No such directory。

-

path为有效目录路径时,会显示对应目录下的内容。

-

1.为空。

-

2.有效的目录路径。

-
- -## 使用指南 - -- ls命令显示当前目录的内容。 -- ls可以显示文件的大小。 -- proc下ls无法统计文件大小,显示为0。 - -## 使用实例 - -举例:输入ls - -## 输出说明 - -**图 1** 查看当前系统路径下的目录,显示的内容如下 -![](figures/查看当前系统路径下的目录-显示的内容如下.png "查看当前系统路径下的目录-显示的内容如下") - diff --git a/zh-cn/device-dev/kernel/lsfd.md b/zh-cn/device-dev/kernel/lsfd.md deleted file mode 100755 index fe0ac75118286010d5496421fa463d2afc845794..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/lsfd.md +++ /dev/null @@ -1,29 +0,0 @@ -# lsfd - -- [命令功能](#section2053406181716) -- [命令格式](#section523771017172) -- [使用指南](#section27241213201719) -- [使用实例](#section442617197173) -- [输出说明](#section42491639151813) - -## 命令功能 - -lsfd命令用来显示当前已经打开的文件描述符及对应的文件名。 - -## 命令格式 - -lsfd - -## 使用指南 - -lsfd命令显示当前已经打开文件的fd号以及文件的名字。 - -## 使用实例 - -举例:输入lsfd - -## 输出说明 - -**图 1** lsfd输出说明 -![](figures/lsfd输出说明.png "lsfd输出说明") - diff --git a/zh-cn/device-dev/kernel/memcheck.md b/zh-cn/device-dev/kernel/memcheck.md deleted file mode 100755 index 5e6058dcf6025e9f6adaa0a2e04938763ba2eb1c..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/memcheck.md +++ /dev/null @@ -1,38 +0,0 @@ -# memcheck - -- [命令功能](#section191633812516) -- [命令格式](#section428816435510) -- [参数说明](#section1939943304411) -- [使用指南](#section228914491951) -- [使用实例](#section17373205314515) -- [输出说明](#section13406205385413) - -## 命令功能 - -检查动态申请的内存块是否完整,是否存在内存越界造成节点损坏。 - -## 命令格式 - -memcheck - -## 参数说明 - -无。 - -## 使用指南 - -- 当内存池所有节点完整时,输出"system memcheck over, all passed!"。 -- 当内存池存在节点不完整时,输出被损坏节点的内存块信息。 - -## 使用实例 - -举例:输入memcheck - -## 输出说明 - -**图 1** 当前没有内存越界 -![](figures/当前没有内存越界.png "当前没有内存越界") - -**图 2** 出现内存越界 -![](figures/出现内存越界.png "出现内存越界") - diff --git a/zh-cn/device-dev/kernel/mkdir.md b/zh-cn/device-dev/kernel/mkdir.md deleted file mode 100755 index 444d6a246b92fbc3b82dac6f190ad87ad883af46..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/mkdir.md +++ /dev/null @@ -1,54 +0,0 @@ -# mkdir - -- [命令功能](#section1083613274175) -- [命令格式](#section820913118178) -- [参数说明](#section1256834121718) -- [使用指南](#section1294234115172) -- [使用实例](#section1113345211713) -- [输出说明](#section10142201012) - -## 命令功能 - -mkdir命令用来创建一个目录。 - -## 命令格式 - -mkdir \[_directory_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

directory

-

需要创建的目录。

-

N/A

-
- -## 使用指南 - -- mkdir后加所需要创建的目录名会在当前目录下创建目录。 -- mkdir后加路径,再加上需要创建的目录名,即在指定目录下创建目录。 - -## 使用实例 - -举例:mkdir share - -## 输出说明 - -**图 1** 创建 share 目录 -![](figures/创建-share-目录.png "创建-share-目录") - diff --git a/zh-cn/device-dev/kernel/mount.md b/zh-cn/device-dev/kernel/mount.md deleted file mode 100755 index 5924e0ca5acaa6dc2d1379d3bfa9651175eff320..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/mount.md +++ /dev/null @@ -1,78 +0,0 @@ -# mount - -- [命令功能](#section11631837182) -- [命令格式](#section1697638111820) -- [参数说明](#section1650151221819) -- [使用指南](#section124541520171912) -- [使用实例](#section7424625171917) -- [输出说明](#section14757018116) - -## 命令功能 - -mount命令用来将设备挂载到指定目录。 - -## 命令格式 - -mount <_device_\> <_path_\> <_name_\> \[_uid gid_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

device

-

要挂载的设备(格式为设备所在路径)。

-

系统拥有的设备。

-

path

-

指定目录。

-

用户必须具有指定目录中的执行(搜索)许可权。

-

N/A

-

name

-

文件系统的种类。

-

vfat, yaffs, jffs, ramfs, nfs,procfs, romfs.

-

uid gid

-

uid是指用户ID。

-

gid是指组ID。

-

可选参数,缺省值uid:0,gid:0。

-

N/A

-
- -## 使用指南 - -mount后加需要挂载的设备信息、指定目录以及设备文件格式,就能成功挂载文件系统到指定目录。 - -## 使用实例 - -举例:mount /dev/mmcblk0p0 /bin1/vs/sd vfat - -## 输出说明 - -将/dev/mmcblk0p0 挂载到/bin1/vs/sd目录 - -![](figures/zh-cn_image_0000001051690323.png) - diff --git a/zh-cn/device-dev/kernel/netstat.md b/zh-cn/device-dev/kernel/netstat.md deleted file mode 100755 index cca0b0dc9ae8fd60e21db1f7901804d5d33d330a..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/netstat.md +++ /dev/null @@ -1,83 +0,0 @@ -# netstat - -- [命令功能](#section13469162113816) -- [命令格式](#section795712373812) -- [参数说明](#section17629431193817) -- [使用指南](#section5277153519380) -- [使用实例](#section108141437163820) -- [输出说明](#section1357015107117) - -## 命令功能 - -netstat是控制台命令,是一个监测TCP/IP网络的非常有用的工具,它可以显示实际的网络连接以及每一个网络接口设备的状态信息。netstat用于显示与TCP、UDP协议相关的统计数据,一般用于检验本设备(单板)各端口的网络连接情况。 - -## 命令格式 - -netstat - -## 参数说明 - -无 - -## 使用指南 - -直接输入命令。 - -## 使用实例 - -举例:输入netstat - -**图 1** netstat 打印信息 - - -![](figures/Snipaste_2021-01-26_10-38-58-1.png) - -## 输出说明 - -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

Proto

-

协议类型。

-

Recv-Q

-

未被用户读取的数据量。

-

对于Listen TCP,此值为已完成三次握手,但是未被用户accept的TCP连接的数量。

-

Send-Q

-

对TCP连接,已发送但未确认的数据量。

-

对UDP连接,由于IP地址解析未完成而缓存的数据量。

-

Local Address

-

本地地址和端口。

-

Foreign Address

-

远程地址和端口。

-

State

-

TCP连接状态,UDP此项无意义。

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->形如“========== total sockets 32 ====== unused sockets 22 BootTime 27 s ========== ”,表示一共32个套接字,未使用套接字22个,距系统启动已经过27秒。 - diff --git a/zh-cn/device-dev/kernel/oom.md b/zh-cn/device-dev/kernel/oom.md deleted file mode 100755 index 4590f61fedd7ff85e6596ca1bd5d711509d1bd6e..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/oom.md +++ /dev/null @@ -1,120 +0,0 @@ -# oom - -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section12742311179) - -## 命令功能 - -查看和设置低内存阈值以及pagecache内存回收阈值。 - -## 命令格式 - -oom - -oom -i \[_interval_\] - -oom -m \[_mem byte_\] - -oom -r \[_mem byte_\] - -oom -h | --help - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-i [interval]

-

设置oom线程任务检查的时间间隔。

-

100ms ~ 10000ms

-

-m [mem byte]

-

设置低内存阈值。

-

0MB ~ 1MB,0MB表示不做低内存阈值检查。

-

-r [mem byte]

-

设置pagecache内存回收阈值。

-

低内存阈值 ~ 系统可用最大内存。

-

-h | --help

-

使用帮助。

-

N/A

-
- -## 使用指南 - -- 参数缺省时,显示oom功能当前配置信息。 - -## 使用实例 - -当系统内存不足时,会打印出内存不足的提示信息。 - -## 输出说明 - -![](figures/zh-cn_image_0000001053710680.png) - -**表 2** 输出说明 - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

[oom] OS is in low memory state

-

total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte)

-

操作系统处于低内存状态。

-

整个系统可用物理内存为0x1bcf000 byte,已经使用了 0x1b50000 byte, 还剩0x7f000 byte,当前设置的低内存阈值为0x80000 byte。

-

[oom] candidate victim process init pid: 1, actual phy mem byte: 82602

-

打印当前各个进程的内存使用情况,init进程实际使用82602byte,其中共享内存按照比例算的。

-

[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558

-

UserProcess12进程实际使用25951558byte内存。

-

[oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558

-

当前使用内存最多的进程是UserProcess12。

-

excFrom: User!

-

当系统处于低内存的情况下,UserProcess12进程再去申请内存时失败退出。

-
- diff --git a/zh-cn/device-dev/kernel/partinfo.md b/zh-cn/device-dev/kernel/partinfo.md deleted file mode 100755 index b8dc652e97d0bbf411bd53345e0c2aaf5bba72ab..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/partinfo.md +++ /dev/null @@ -1,52 +0,0 @@ -# partinfo - -- [命令功能](#section1777503617199) -- [命令格式](#section185501447132114) -- [参数说明](#section1304151212252) -- [使用指南](#section4566131982520) -- [使用实例](#section4351134942514) -- [输出说明](#section66689331412) - -## 命令功能 - -partinfo命令用于查看系统识别的硬盘,SD卡多分区信息。 - -## 命令格式 - -partinfo <_dev\_inodename_\> - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

dev_inodename

-

要查看的分区名字。

-

合法的分区名。

-
- -## 使用指南 - -无 - -## 使用实例 - -partinfo /dev/mmcblk0p0 - -## 输出说明 - -![](figures/zh-cn_image_0000001052370303.png) - diff --git a/zh-cn/device-dev/kernel/partition.md b/zh-cn/device-dev/kernel/partition.md deleted file mode 100755 index 9a4b15684996b320979efc79eb34924b19cb8440..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/partition.md +++ /dev/null @@ -1,62 +0,0 @@ -# partition - -- [命令功能](#section255095212257) -- [命令格式](#section10258056122515) -- [参数说明](#section177200581256) -- [使用指南](#section17866411262) -- [使用实例](#section1927174202610) -- [输出说明](#section11321011223) - -## 命令功能 - -partition命令用来查看flash分区信息。 - -## 命令格式 - -partition \[_nand / spinor_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

nand

-

显示nand flash分区信息。

-

N/A

-

spinor

-

显示spinor flash分区信息。

-

N/A

-
- -## 使用指南 - -- partition命令用来查看flash分区信息。 -- 仅当使能yaffs文件系统时才可以查看nand flash分区信息,使能jffs或romfs文件系统时可以查看spinor flash分区信息。 - -## 使用实例 - -举例:partition spinor - -## 输出说明 - -查看spinor flash分区信息 - -![](figures/zh-cn_image_0000001052810300.png) - diff --git a/zh-cn/device-dev/kernel/ping.md b/zh-cn/device-dev/kernel/ping.md deleted file mode 100755 index c995f3c5ebd497b1876bb079e4c93b824dcd5ca4..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/ping.md +++ /dev/null @@ -1,99 +0,0 @@ -# ping - -- [命令功能](#section119672573385) -- [命令格式](#section869419010390) -- [参数说明](#section9877183173918) -- [使用指南](#section1097046193914) -- [使用实例](#section14564129113911) -- [输出说明](#section1621732891215) - -## 命令功能 - -ping命令用于测试网络连接是否正常。 - -## 命令格式 - -ping_ _\[_-n cnt_\] \[_-w interval_\] \[_-l data\_len_\]_ _ - -ping \[_-t_\] \[_-w interval_\] __ - -ping _-k_ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

IP

-

要测试是否网络连通的IPv4地址。

-

N/A

-

-n cnt

-

执行的次数,不带本参数则默认为4次。

-

1-65535

-

-w interval

-

发送两次ping包的时间间隔,单位毫秒。

-

>0

-

-l data_len

-

ping包,即ICMP echo request报文的数据长

-

度,不包含ICMP包头。

-

0-65500

-

-t

-

表示永久ping,直到使用ping -k杀死ping线

-

程。

-

N/A

-

-k

-

杀死ping线程,停止ping。

-

N/A

-
- -## 使用指南 - -- ping命令用来测试到目的IP的网络连接是否正常,参数为目的IP地址。 -- 如果目的IP不可达,会显示请求超时。 -- 如果显示发送错误,说明没有到目的IP的路由。 -- 命令需要启动TCP/IP协议栈后才能使用。 - -## 使用实例 - -举例:输入ping 192.168.1.10 - -## 输出说明 - -**图 1** ping tftp 服务器地址 - - -![](figures/Snipaste_2021-01-26_10-38-58-2.png) - diff --git a/zh-cn/device-dev/kernel/pmm.md b/zh-cn/device-dev/kernel/pmm.md deleted file mode 100755 index 9ed393dfdd95811a140333837905c65263a65bd2..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/pmm.md +++ /dev/null @@ -1,91 +0,0 @@ -# pmm - -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) - -## 命令功能 - -查看系统内存物理页及pagecache物理页使用情况。 - -## 命令格式 - -pmm - -## 参数说明 - -无 - -## 使用指南 - -Debug版本才具备的命令。 - -## 使用实例 - -输入pmm - -## 输出说明 - -**图 1** 查看物理页使用情况 -![](figures/查看物理页使用情况.png "查看物理页使用情况") - -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

phys_seg

-

物理页控制块地址信息

-

base

-

第一个物理页地址,即物理页内存起始地址

-

size

-

物理页内存大小

-

free_pages

-

空闲物理页数量

-

active anon

-

pagecache中,活跃的匿名页数量

-

inactive anon

-

pagecache中,不活跃的匿名页数量

-

active file

-

pagecache中,活跃的文件页数量

-

inactive file

-

pagecache中,不活跃的文件页数量

-

pmm pages

-

total:总的物理页数,used:已使用的物理页数,free:空闲的物理页数

-
- diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/kernel/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/kernel/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-note.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/kernel/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/kernel/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/kernel/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/kernel/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/zh-cn/device-dev/kernel/pwd.md b/zh-cn/device-dev/kernel/pwd.md deleted file mode 100755 index bff68160cecb23771496dd419583ba4c084c241e..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/pwd.md +++ /dev/null @@ -1,34 +0,0 @@ -# pwd - -- [命令功能](#section197737712267) -- [命令格式](#section1544061016267) -- [参数说明](#section599112120262) -- [使用指南](#section66901116152615) -- [使用实例](#section7427181922612) -- [输出说明](#section116313389418) - -## 命令功能 - -pwd命令用来显示当前路径。 - -## 命令格式 - -pwd - -## 参数说明 - -无。 - -## 使用指南 - -pwd 命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 / (斜线)分隔。第一个 / 表示根目录, 最后一个目录是当前目录。 - -## 使用实例 - -举例:输入pwd - -## 输出说明 - -**图 1** 查看当前路径 -![](figures/查看当前路径.png "查看当前路径") - diff --git a/zh-cn/device-dev/kernel/rm.md b/zh-cn/device-dev/kernel/rm.md deleted file mode 100755 index 2815b287a1d8bc385b9879727254d4726b8d266b..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/rm.md +++ /dev/null @@ -1,67 +0,0 @@ -# rm - -- [命令功能](#section181141523142613) -- [命令格式](#section8800926132619) -- [参数说明](#section15476229152617) -- [使用指南](#section10578163215262) -- [使用实例](#section18548133511263) -- [输出说明](#section1565323814265) - -## 命令功能 - -rm命令用来删除文件或文件夹。 - -## 命令格式 - -rm \[_-r_\] \[_dirname / filename_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-r

-

可选参数,若是删除目录则需要该参数。

-

N/A

-

dirname/filename

-

要删除文件或文件夹的名称,支持输入路径。

-

N/A

-
- -## 使用指南 - -- rm命令一次只能删除一个文件或文件夹。 -- rm -r命令可以删除非空目录。 - -## 使用实例 - -举例: - -1. 输入rm log1.txt -2. 输入rm -r sd - -## 输出说明 - -**图 1** 用 rm 命令删除文件 log1.txt -![](figures/用-rm-命令删除文件-log1-txt.png "用-rm-命令删除文件-log1-txt") - -**图 2** 用 rm -r 删除目录 sd -![](figures/用-rm--r-删除目录-sd.png "用-rm--r-删除目录-sd") - diff --git a/zh-cn/device-dev/kernel/rmdir.md b/zh-cn/device-dev/kernel/rmdir.md deleted file mode 100755 index 6a1e52eee3b2f6b21f802a4a144ee5fad3d554ab..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/rmdir.md +++ /dev/null @@ -1,55 +0,0 @@ -# rmdir - -- [命令功能](#section1839611420266) -- [命令格式](#section329574512266) -- [参数说明](#section15865747102620) -- [使用指南](#section107857508261) -- [使用实例](#section11196165315262) -- [输出说明](#section1073811415613) - -## 命令功能 - -rmdir命令用来删除一个目录。 - -## 命令格式 - -rmdir \[_dir_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

dir

-

需要删除目录的名称,删除目录必须为空,支持输入路径。

-

N/A

-
- -## 使用指南 - -- rmdir命令只能用来删除目录。 -- rmdir一次只能删除一个目录。 -- rmdir只能删除空目录。 - -## 使用实例 - -举例:输入rmdir dir - -## 输出说明 - -**图 1** 删除一个名为 dir 的目录 -![](figures/删除一个名为-dir-的目录.png "删除一个名为-dir-的目录") - diff --git a/zh-cn/device-dev/kernel/sem.md b/zh-cn/device-dev/kernel/sem.md deleted file mode 100755 index 14342e7531992cd0965a2b33eed6d840eaa0738c..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/sem.md +++ /dev/null @@ -1,91 +0,0 @@ -# sem - -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section1975118519456) - -## 命令功能 - -sem命令用于查询系统内核信号量相关信息。 - -## 命令格式 - -sem \[_ID__ / fulldata_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

ID

-

信号ID号。

-

[0, 0xFFFFFFFF]

-

fulldata

-

查询所有在用的信号量信息,打印信息包括如下:SemID, Count, Original Count, Creater TaskEntry, Last Access Time。

-

N/A

-
- -## 使用指南 - -- 参数缺省时,显示所有的信号量的使用数及信号量总数。 -- sem后加ID,显示对应ID信号量的使用数。 -- 参数fulldata依赖于LOSCFG\_DEBUG\_SEMAPHORE,使用时通过menuconfig在配置项中开启"Enable Semaphore Debugging": - - Debug ---\> Enable a Debug Version ---\> Enable Debug LiteOS Kernel Resource ---\> Enable Semaphore Debugging - - -## 使用实例 - -举例1:输入 sem fulldata - -## 输出说明 - -**图 1** 查询所有在用的信号量信息 -![](figures/查询所有在用的信号量信息.png "查询所有在用的信号量信息") - -**表 2** 输出说明 - - - - - - - - - - - - - -

输出

-

说明

-

SemID

-

信号量ID。

-

Count

-

信号量使用数。

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->● sem命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 ->● sem命令的ID参数在\[0, 1023\]范围内时,返回对应ID的信号量的状态(如果对应ID的信号量未被使用则进行提示);其他取值时返回参数错误的提示。 - diff --git a/zh-cn/device-dev/kernel/stack.md b/zh-cn/device-dev/kernel/stack.md deleted file mode 100755 index 526ed83f4d872388224244d27aee8011f345f766..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/stack.md +++ /dev/null @@ -1,73 +0,0 @@ -# stack - -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) - -## 命令功能 - -查看系统各堆栈使用情况。 - -## 命令格式 - -stack - -## 参数说明 - -无。 - -## 使用指南 - -无。 - -## 使用实例 - -输入:stack - -## 输出说明 - -**图 1** 系统堆栈使用情况 - - -![](figures/zh-cn_image_0000001054624363.png) - -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

stack name

-

系统堆栈名

-

cpu id

-

cpu 号

-

stack addr

-

栈地址

-

total size

-

堆栈大小

-

used size

-

堆栈实际使用大小

-
- diff --git a/zh-cn/device-dev/kernel/statfs.md b/zh-cn/device-dev/kernel/statfs.md deleted file mode 100755 index bc428c78b253e7c7dff60543c2f942db43756b0f..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/statfs.md +++ /dev/null @@ -1,52 +0,0 @@ -# statfs - -- [命令功能](#section153921657152613) -- [命令格式](#section135391102717) -- [参数说明](#section074312314279) -- [使用指南](#section133816772712) -- [使用实例](#section526149182717) - -## 命令功能 - -statfs命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。 - -## 命令格式 - -statfs \[_directory_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

directory

-

文件系统的路径。

-

必须是存在的文件系统,并且其支持statfs命令,当前支持的文件系统有:JFFS2,FAT,NFS。

-
- -## 使用指南 - -打印信息因文件系统而异。 - -## 使用实例 - -以nfs文件系统为例: - -statfs /nfs - -**图 1** statfs输出说明 -![](figures/statfs输出说明.png "statfs输出说明") - diff --git a/zh-cn/device-dev/kernel/su.md b/zh-cn/device-dev/kernel/su.md deleted file mode 100755 index a23b14445d1eabb3fc71242ebff588b937fe2c02..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/su.md +++ /dev/null @@ -1,62 +0,0 @@ -# su - -- [命令功能](#section297810431676) -- [命令格式](#section157131147876) -- [参数说明](#section04145521671) -- [使用指南](#section14615155610719) -- [使用实例](#section13338150985) -- [输出说明](#section125021924194613) - -## 命令功能 - -su用于变更为其他使用者的身份。 - -## 命令格式 - -su \[_uid_\] \[_gid_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

uid

-

目标用户的用户id值。

-
  • 为空。
  • [0,60000]
-

gid

-

目标用户的群组id值。

-
  • 为空。
  • [0,60000]
-
- -## 使用指南 - -- su命令缺省切换到root用户,uid默认为0,gid为0。 -- 在su命令后的输入参数uid和gid就可以切换到该uid和gid的用户。 -- 输入参数超出范围时,会打印提醒输入正确范围参数。 - -## 使用实例 - -举例:su 1000 1000 - -## 输出说明 - -**图 1** **切换到**为uid为1000,gid为1000的用户 -![](figures/切换到为uid为1000-gid为1000的用户.png "切换到为uid为1000-gid为1000的用户") - diff --git a/zh-cn/device-dev/kernel/swtmr.md b/zh-cn/device-dev/kernel/swtmr.md deleted file mode 100755 index 7ab65604883876668fbc61ea7efc4c7fc6f1ed89..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/swtmr.md +++ /dev/null @@ -1,110 +0,0 @@ -# swtmr - -- [命令功能](#section166171064814) -- [命令格式](#section424011111682) -- [参数说明](#section1268410459465) -- [使用指南](#section169806213815) -- [使用实例](#section16676026389) -- [输出说明](#section1541991614710) - -## 命令功能 - -swtmr命令用于查询系统软件定时器相关信息。 - -## 命令格式 - -swtmr \[_ID_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

ID

-

软件定时器ID号。

-

[0,0xFFFFFFFF]

-
- -## 使用指南 - -- 参数缺省时,默认显示所有软件定时器的相关信息。 -- swtmr后加ID号时,显示ID对应的软件定时器相关信息。 - -## 使用实例 - -举例:输入swtmr和swtmr 1 - -## 输出说明 - -**图 1** 查询所有软件定时器相关信息 -![](figures/查询所有软件定时器相关信息.png "查询所有软件定时器相关信息") - -**图 2** 查询对应 ID 的软件定时器信息 -![](figures/查询对应-ID-的软件定时器信息.png "查询对应-ID-的软件定时器信息") - -**表 2** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

SwTmrID

-

软件定时器ID。

-

State

-

软件定时器状态。

-

状态可能为:"UnUsed", "Created", "Ticking"。

-

Mode

-

软件定时器模式。

-

模式可能为:"Once", "Period", "NSD(单次定时器,定时结束后不会自动删除)"。

-

Interval

-

软件定时器使用的Tick数。

-

Count

-

软件定时器已经工作的次数。

-

Arg

-

传入的参数。

-

handlerAddr

-

回调函数的地址。

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->- swtmr命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 ->- swtmr命令的ID参数在\[0, 当前软件定时器个数 - 1\]范围内时,返回对应ID的软件定时器的状态;其他取值时返回错误提示。 - diff --git a/zh-cn/device-dev/kernel/systeminfo.md b/zh-cn/device-dev/kernel/systeminfo.md deleted file mode 100755 index 16fbd841d383b8513254885c9c2cf19916186e67..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/systeminfo.md +++ /dev/null @@ -1,91 +0,0 @@ -# systeminfo - -- [命令功能](#section863016434820) -- [命令格式](#section139791817795) -- [参数说明](#section19472339164813) -- [使用指南](#section285522592) -- [使用实例](#section9471171015105) -- [输出说明](#section1657011114915) - -## 命令功能 - -systeminfo命令用于显示当前操作系统内资源使用情况,包括任务、信号量、互斥量、队列、定时器等。 - -## 命令格式 - -systeminfo - -## 参数说明 - -无。 - -## 使用指南 - -无。 - -## 使用实例 - -举例:输入systeminfo - -## 输出说明 - -**图 1** 查看系统资源使用情况 -![](figures/查看系统资源使用情况.png "查看系统资源使用情况") - -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

Module

-

模块名称。

-

Used

-

当前使用量。

-

Total

-

最大可用量。

-

Enabled

-

模块是否开启。

-

Task

-

任务。

-

Sem

-

信号量。

-

Mutex

-

互斥量。

-

Queue

-

队列。

-

SwTmr

-

定时器。

-
- diff --git a/zh-cn/device-dev/kernel/task.md b/zh-cn/device-dev/kernel/task.md deleted file mode 100755 index 673ed06ae2a24eaa5140dab866d6a71551d14a85..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/task.md +++ /dev/null @@ -1,125 +0,0 @@ -# task - -- [命令功能](#section0533181714106) -- [命令格式](#section1014412308101) -- [参数说明](#section116057158506) -- [使用指南](#section2053502951112) -- [使用实例](#section12629113381116) -- [输出说明](#section19299103465015) - -## 命令功能 - -task命令用于查询进程及线程信息。 - -## 命令格式 - -task/task -a - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-a

-

查看更多信息。

-

N/A

-
- -## 使用指南 - -- 参数缺省时默认打印部分任务信息。 - -## 使用实例 - -举例:输入task - -## 输出说明 - -**图 1** 查询任务部分信息 -![](figures/查询任务部分信息.png "查询任务部分信息") - -**表 2** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

PID

-

进程ID。

-

PPID

-

父进程ID。

-

PGID

-

进程组ID。

-

UID

-

用户ID。

-

Status

-

任务当前的状态。

-

CPUUSE10s

-

10秒内CPU使用率。

-

PName

-

进程名。

-

TID

-

任务ID。

-

StackSize

-

任务堆栈的大小。

-

WaterLine

-

栈使用的峰值。

-

MEMUSE

-

内存使用量。

-

TaskName

-

任务名。

-
- diff --git a/zh-cn/device-dev/kernel/telnet.md b/zh-cn/device-dev/kernel/telnet.md deleted file mode 100755 index e68f22de468d07eb1f954a87be4a30add268a3e0..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/telnet.md +++ /dev/null @@ -1,65 +0,0 @@ -# telnet - -- [命令功能](#section3551830123913) -- [命令格式](#section14897133233918) -- [参数说明](#section977718353392) -- [使用指南](#section134991538183916) -- [使用实例](#section1097414426398) -- [输出说明](#section11846624191310) - -## 命令功能 - -本命令用于启动或关闭telnet server服务。 - -## 命令格式 - -telnet \[_on | off_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

on

-

启动telnet server服务。

-

N/A

-

off

-

关闭telnet server服务。

-

N/A

-
- -## 使用指南 - -- telnet启动要确保网络驱动及网络协议栈已经初始化完成,且板子的网卡是link up状态。 -- 暂时无法支持多个客户端(telnet + IP)同时连接开发板。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >telnet属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 - - -## 使用实例 - -举例:输入telnet on - -## 输出说明 - -**图 1** 输入 telnet on -![](figures/输入-telnet-on.png "输入-telnet-on") - diff --git a/zh-cn/device-dev/kernel/tftp.md b/zh-cn/device-dev/kernel/tftp.md deleted file mode 100755 index a82fdf93898b2f2825c4ae510477f85ea6e3846e..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/tftp.md +++ /dev/null @@ -1,87 +0,0 @@ -# tftp - -- [命令功能](#section15142134573911) -- [命令格式](#section20958174917394) -- [参数说明](#section576613532395) -- [使用指南](#section149795134408) -- [使用实例](#section148921918114015) -- [输出说明](#section7872155631313) - -## 命令功能 - -TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供简单、低开销的文件传输服务。端口号为69。 - -tftp命令可以从TFTP服务器上下载文件。 - -## 命令格式 - -./bin/tftp _<-g/-p\>_ _-l_ _\[FullPathLocalFile\] -r \[RemoteFile\] \[Host\]_ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-g/-p

-

文件传输方向:

-
  • -g 从TFTP服务器获取文件。
  • -p 上传文件到TFTP服务器。
-

N/A

-

-l FullPathLocalFile

-

本地文件完整路径。

-

N/A

-

-r RemoteFile

-

服务端文件名。

-

N/A

-

Host

-

服务端IP。

-

N/A

-
- -## 使用指南 - -1. 在服务器端搭建TFTP服务器,并进行正确配置。 -2. OpenHarmony单板使用tftp命令上传、下载文件。 -3. 传输的文件大小是有限制的不能大于32M。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >tftp属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 - - -## 使用实例 - -举例:从服务器下载out文件。 - -## 输出说明 - -``` -OHOS # ./bin/tftp -g -l /nfs/out -r out 192.168.1.2 -TFTP transfer finish -``` - -tftp命令执行后,传输正常完成会显示TFTP transfer finish, 失败的话会显示其他的打印信息帮助定位问题。 - diff --git a/zh-cn/device-dev/kernel/touch.md b/zh-cn/device-dev/kernel/touch.md deleted file mode 100755 index dc40b522af4032be79f096f674800feba6292a2f..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/touch.md +++ /dev/null @@ -1,59 +0,0 @@ -# touch - -- [命令功能](#section17541924112716) -- [命令格式](#section866182711274) -- [参数说明](#section268912296270) -- [使用指南](#section412093332714) -- [使用实例](#section414434814354) -- [输出说明](#section1028419515711) - -## 命令功能 - -- touch命令用来在指定的目录下创建一个不存在的空文件。 -- touch命令操作已存在的文件会成功,不会更新时间戳。 - -## 命令格式 - -touch \[_filename_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

filename

-

需要创建文件的名称。

-

N/A

-
- -## 使用指南 - -- touch命令用来创建一个空文件,该文件可读写。 -- 使用touch命令一次只能创建一个文件。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >在系统重要资源路径下使用touch命令创建文件,会对系统造成死机等未知影响,如在/dev路径下执行touch uartdev-0,会产生系统卡死现象。 - - -## 使用实例 - -举例:输入touch file.c 输出说明 - -## 输出说明 - -**图 1** 创建一个名为 file.c 的文件 -![](figures/创建一个名为-file-c-的文件.png "创建一个名为-file-c-的文件") - diff --git a/zh-cn/device-dev/kernel/umount.md b/zh-cn/device-dev/kernel/umount.md deleted file mode 100755 index 7cb41d53ef02df0549885092610bb7c5eb156eee..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/umount.md +++ /dev/null @@ -1,55 +0,0 @@ -# umount - -- [命令功能](#section365125133520) -- [命令格式](#section9615254123512) -- [参数说明](#section63446577355) -- [使用指南](#section92931509368) -- [使用实例](#section144311323616) -- [输出说明](#section360525113611) - -## 命令功能 - -umount命令用来卸载指定文件系统。 - -## 命令格式 - -umount \[_dir_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

dir

-

需要卸载文件系统对应的目录。

-

系统已挂载的文件系统的目录。

-
- -## 使用指南 - -umount后加上需要卸载的指定文件系统的目录,即将指定文件系统卸载。 - -## 使用实例 - -举例:umount /bin1/vs/sd - -## 输出说明 - -将已在/bin1/vs/sd挂载的文件系统卸载 - -**图 1** umount输出示例 -![](figures/umount输出示例.png "umount输出示例") - diff --git a/zh-cn/device-dev/kernel/uname.md b/zh-cn/device-dev/kernel/uname.md deleted file mode 100755 index 71a06837cc26f1ae62bc2eb0a240c47f3422f6b7..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/uname.md +++ /dev/null @@ -1,72 +0,0 @@ -# uname - -- [命令功能](#section107697383115) -- [命令格式](#section162824341116) -- [使用指南](#section2652124861114) -- [使用实例](#section0107995132) -- [输出说明](#section1215113245511) - -## 命令功能 - -uname命令用于显示当前操作系统的名称,版本创建时间,系统名称,版本信息等。 - -## 命令格式 - -uname \[_-a | -s | -t | -v | --help_\] - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

无参数

-

默认显示操作系统名称。

-

-a

-

显示全部信息。

-

-t

-

显示版本创建的时间。

-

-s

-

显示操作系统名称。

-

-v

-

显示版本信息。

-

--help

-

显示uname指令格式提示。

-
- -## 使用指南 - -uname用于显示当前操作系统名称。语法uname -a | -t| -s| -v 描述uname 命令将正在使用的操作系统名写到标准输出中,这几个参数不能混合使用。 - -## 使用实例 - -举例:输入uname -a - -## 输出说明 - -查看系统信息 - -![](figures/zh-cn_image_0000001052370305.png) - diff --git a/zh-cn/device-dev/kernel/vmm.md b/zh-cn/device-dev/kernel/vmm.md deleted file mode 100755 index 0d38eadc7e36fabed43abe813d992640bad42206..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/vmm.md +++ /dev/null @@ -1,158 +0,0 @@ -# vmm - -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) - -## 命令功能 - -查看进程的虚拟内存使用情况。 - -## 命令格式 - -vmm \[_-a / -h / --help_\] - -vmm \[_pid_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-a

-

输出所有进程的虚拟内存使用情况

-

N/A

-

-h | --help

-

命令格式说明

-

N/A

-

pid

-

进程ID,说明指定进程的虚拟内存使用情况

-

[0,63]

-
- -## 使用指南 - -命令缺省输出所有进程的虚拟内存使用情况。 - -## 使用实例 - -输入vmm 3 - -## 输出说明 - -**图 1** PID为3的进程虚拟内存使用信息 -![](figures/PID为3的进程虚拟内存使用信息.png "PID为3的进程虚拟内存使用信息") - -**表 2** 进程基本信息 - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

PID

-

进程ID

-

aspace

-

进程虚拟内存控制块地址信息

-

name

-

进程名

-

base

-

虚拟内存起始地址

-

size

-

虚拟内存大小

-

pages

-

已使用的物理页数量

-
- -**表 3** 虚拟内存区间信息 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

region

-

虚拟区间控制块地址信息

-

name

-

虚拟区间类型

-

base

-

虚拟区间起始地址

-

size

-

虚拟区间大小

-

mmu_flags

-

虚拟区间mmu映射属性

-

pages

-

已使用的物理页数量(包括共享内存部分)

-

pg/ref

-

已使用的物理页数量

-
- diff --git a/zh-cn/device-dev/kernel/watch.md b/zh-cn/device-dev/kernel/watch.md deleted file mode 100755 index 0586d287df85decf88bc96708c892b19ab23dc4c..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/watch.md +++ /dev/null @@ -1,100 +0,0 @@ -# watch - -- [命令功能](#section20643141481314) -- [命令格式](#section1075441721316) -- [参数说明](#section1472810220135) -- [使用指南](#section186772414131) -- [使用实例](#section4764192791314) -- [输出说明](#section5791253155517) - -## 命令功能 - -watch命令用于周期性的监视一个命令的运行结果。 - -## 命令格式 - -watch - -watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

缺省值

-

取值范围

-

-c / --count

-

命令执行的总次数。

-

0xFFFFFF

-

(0,0xFFFFFF]

-

-n / --interval

-

命令周期性执行的时间间隔(s)。

-

1s

-

(0,0xFFFFFF]

-

-t / -no-title

-

关闭顶端的时间显示。

-

N/A

-

N/A

-

command

-

需要监测的命令。

-

N/A

-

N/A

-

--over

-

关闭当前监测指令。

-

N/A

-

N/A

-
- -## 使用指南 - -watch运行过程中可以执行**watch --over**结束本次watch命令。 - -## 使用实例 - -输入举例: - -watch -n 2 -c 6 task - -## 输出说明 - -**图 1** watch task 结果 -![](figures/watch-task-结果.png "watch-task-结果") - ->![](public_sys-resources/icon-note.gif) **说明:** ->示例中,总共有6次task命令打印,每次间隔2秒,截图为最后一次打印详情。 - diff --git a/zh-cn/device-dev/kernel/writeproc.md b/zh-cn/device-dev/kernel/writeproc.md deleted file mode 100755 index 7e0306ff60c5def1793041f59306a7d17118594b..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/kernel/writeproc.md +++ /dev/null @@ -1,69 +0,0 @@ -# writeproc - -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section12742311179) - -## 命令功能 - -proc fs支持传入字符串参数,需要每个文件实现自己的写方法。 - -## 命令格式 - -writeproc <_data_\> \>\> /proc/<_filename_\> - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

data

-

要输入的字符串,以空格为结束符,如需输入空格,请用""包裹。

-

N/A

-

filename

-

data要传入的proc文件。

-

N/A

-
- -## 使用指南 - -proc文件实现自身的write函数,调用writeproc命令后会将入参传入write函数。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->procfs不支持多线程访问。 - -## 使用实例 - -举例:writeproc test \>\> /proc/uptime - -## 输出说明 - -OHOS \# writeproc test \>\> /proc/uptime - -\[INFO\]write buf is: test - -test \>\> /proc/uptime - ->![](public_sys-resources/icon-note.gif) **说明:** ->uptime proc文件临时实现write函数,INFO日志为实现的测试函数打印的日志。 - diff --git "a/zh-cn/device-dev/kernel/\344\270\255\346\226\255\347\256\241\347\220\206.md" "b/zh-cn/device-dev/kernel/\344\270\255\346\226\255\347\256\241\347\220\206.md" deleted file mode 100644 index 29edaf0e1e6affff1fd4c5ff00687023434c6651..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\344\270\255\346\226\255\347\256\241\347\220\206.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 中断管理 - -- **[基本概念](基本概念.md)** - -- **[开发指导](开发指导.md)** - - diff --git "a/zh-cn/device-dev/kernel/\344\272\213\344\273\266.md" "b/zh-cn/device-dev/kernel/\344\272\213\344\273\266.md" deleted file mode 100644 index e998fce8eb5759370f6a3e6b053cd26baed727f2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\344\272\213\344\273\266.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 事件 - -- **[基本概念](基本概念-5.md)** - -- **[开发指导](开发指导-6.md)** - - diff --git "a/zh-cn/device-dev/kernel/\344\272\222\346\226\245\351\224\201.md" "b/zh-cn/device-dev/kernel/\344\272\222\346\226\245\351\224\201.md" deleted file mode 100644 index ce0ea2949c4c1e9fa1973457e88e40a411b2069d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\344\272\222\346\226\245\351\224\201.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 互斥锁 - -- **[基本概念](基本概念-7.md)** - -- **[开发指导](开发指导-8.md)** - - diff --git "a/zh-cn/device-dev/kernel/\344\273\273\345\212\241\347\256\241\347\220\206.md" "b/zh-cn/device-dev/kernel/\344\273\273\345\212\241\347\256\241\347\220\206.md" deleted file mode 100644 index 22165d0c36e05cd78b42f6c18f233ccef9eb2269..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\344\273\273\345\212\241\347\256\241\347\220\206.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 任务管理 - -- **[基本概念](基本概念-2.md)** - -- **[开发指导](开发指导-3.md)** - - diff --git "a/zh-cn/device-dev/kernel/\344\277\241\345\217\267\351\207\217.md" "b/zh-cn/device-dev/kernel/\344\277\241\345\217\267\351\207\217.md" deleted file mode 100644 index 6eb88eb04b6e7a3335c5c84f9932d018134cbeb3..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\344\277\241\345\217\267\351\207\217.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 信号量 - -- **[基本概念](基本概念-11.md)** - -- **[开发指导](开发指导-12.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230.md" "b/zh-cn/device-dev/kernel/\345\206\205\345\255\230.md" deleted file mode 100755 index 871a1c5ac807e07ef3a6d220cefd6bef3044e91b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230.md" +++ /dev/null @@ -1,353 +0,0 @@ -# 内存 - -- [基本概念](#section1392116583424) -- [使用场景](#section159581619194319) -- [接口说明](#section114001032104317) - -## 基本概念 - -内存管理是开发过程中必须要关注的重要过程,它包括内存的分配、使用和回收。 - -良好的内存管理对于提高软件性能和可靠性有着十分重要的意义。 - -## 使用场景 - -针对用户态开发,OpenHarmony内核提供了一套内存系统调用接口,支持内存的申请释放、重映射、内存属性的设置等,还有C库的标准内存操作函数。 - -## 接口说明 - -**表 1** 标准C库相关接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口

-

功能

-

strings.h

-

int bcmp(const void *s1, const void *s2, size_t n)

-

比较字节序列。

-

strings.h

-

void bcopy(const void *src, void *dest, size_t n)

-

拷贝字节序列。

-

strings.h

-

void bzero(void *s, size_t n)

-

写入零值字节。

-

string.h

-

void *memccpy(void *dest, const void *src, int c, size_t n)

-

拷贝src 所指的内存内容前n 个字节到dest 所指的地址上。复制时检查参数c 是否出现,若是则返回dest 中值为c 的下一个字节地址。

-

string.h

-

void *memchr(const void *s, int c, size_t n)

-

在s所指内存的前n个字节中查找c。

-

string.h

-

int memcmp(const void *s1, const void *s2, size_t n)

-

内存比较。

-

string.h

-

void *memcpy(void *dest, const void *src, size_t n)

-

内存拷贝。

-

string.h

-

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)

-

找到一个子串。

-

string.h

-

void *memmove(void *dest, const void *src, size_t n)

-

内存移动。

-

string.h

-

void *mempcpy(void *dest, const void *src, size_t n)

-

拷贝内存区域。

-

string.h

-

void *memset(void *s, int c, size_t n)

-

内存初始化。

-

stdlib.h

-

void *malloc(size_t size)

-

申请内存。

-

stdlib.h

-

void *calloc(size_t nmemb, size_t size)

-

申请内存并清零。

-

stdlib.h

-

void *realloc(void *ptr, size_t size)

-

重分配内存。

-

stdlib.h/malloc.h

-

void *valloc(size_t size)

-

分配以页对齐的内存。

-

stdlib.h

-

void free(void *ptr)

-

释放内存。

-

malloc.h

-

size_t malloc_usable_size(void *ptr)

-

获取从堆分配的内存块的大小。

-

unistd.h

-

int getpagesize(void)

-

获取页面大小。

-

unistd.h

-

void *sbrk(intptr_t increment)

-

更改数据段大小。

-
- -差异接口详细说明: - -- **mmap** - - **函数原型:** - - void \*mmap\(void \*addr, size\_t length, int prot, int flags, int fd, off\_t offset\); - - **函数功能:**申请虚拟内存。 - - **参数说明:** - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

描述

-

addr

-

用来请求使用某个特定的虚拟内存地址。如果取NULL,结果地址就将自动分配(这是推荐的做法),否则会降低程序的可移植性,因为不同系统的可用地址范围不一样。

-

length

-

内存段的大小。

-

prot

-

用于设置内存段的访问权限,有如下权限:

-
  • PROT_READ:允许读该内存段。
  • PROT_WRITE:允许写该内存段。
  • PROT_EXEC:允许执行该内存段。
  • PROT_NONE:不能访问。
-

flags

-

控制程序对内存段的改变所造成的影响,有如下属性:

-
  • MAP_PRIVATE:内存段私有,对它的修改值仅对本进程有效。
  • MAP_SHARED:把对该内存段的修改保存到磁盘文件中。
-

fd

-

打开的文件描述符。

-

offset

-

用以改变经共享内存段访问的文件中数据的起始偏移值。

-
- - >![](public_sys-resources/icon-note.gif) **说明:** - >mmap与Linux实现差异详见[与Linux标准库的差异](与Linux标准库的差异.md)章节。 - - **返回值:** - - - 成功返回:虚拟内存地址,这地址是页对齐。 - - 失败返回:\(void \*\)-1。 - - -- **munmap接口** - - **函数原型:** - - int munmap\(void \*addr, size\_t length\); - - **函数功能:**释放虚拟内存。 - - **参数说明:** - - - - - - - - - - - - - -

参数

-

描述

-

addr

-

虚拟内存起始位置。

-

length

-

内存段的大小。

-
- - **返回值:** - - - 成功返回0。 - - 失败返回-1。 - - -- **mprotect接口** - - **函数原型:** - - int mprotect\(void \*addr, size\_t length, int prot\); - - **函数功能:**修改内存段的访问权限。 - - **参数说明:** - - - - - - - - - - - - - - - - -

参数

-

描述

-

addr

-

内存段起始地址,必须页对齐;访问权限异常,内核将直接抛异常并且kill该进程,而不会产生SIGSEGV信号给当前进程。

-

length

-

内存段的大小。

-

prot

-

内存段的访问权限,有如下定义:

-
  • PROT_READ:允许读该内存段。
  • PROT_WRITE:允许写该内存段。
  • PROT_EXEC:允许执行该内存段。
  • PROT_NONE:不能访问。
-
- - **返回值:** - - - 成功返回0。 - - 失败返回-1。 - - -- **mremap接口** - - **函数原型:** - - void \*mremap\(void \*old\_address, size\_t old\_size, size\_t new\_size, int flags, void new\_address\); - - **函数功能:**重新映射虚拟内存地址。 - - **参数说明:** - - - - - - - - - - - - - - - - - - - -

参数

-

描述

-

old_address

-

需要扩大(或缩小)的内存段的原始地址。注意old_address必须是页对齐。

-

old_size

-

内存段的原始大小。

-

new_size

-

新内存段的大小。

-

flags

-

如果没有足够的空间在当前位置展开映射,则返回失败

-
  • MREMAP_MAYMOVE:允许内核将映射重定位到新的虚拟地址。
  • MREMAP_FIXED:mremap()接受第五个参数,void *new_address,该参数指定映射地址必须页对齐;在new_address和new_size指定的地址范围内的所有先前映射都被解除映射。如果指定了MREMAP_FIXED,还必须指定MREMAP_MAYMOVE。
-
- - **返回值:** - - - 成功返回:重新映射后的虚拟内存地址。 - - 失败返回:\(\(void \*\)-1\)。 - - diff --git "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\344\277\241\346\201\257\347\273\237\350\256\241.md" "b/zh-cn/device-dev/kernel/\345\206\205\345\255\230\344\277\241\346\201\257\347\273\237\350\256\241.md" deleted file mode 100644 index f0dce32252a444dc8b0d715477e2aeb2e0740bda..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\344\277\241\346\201\257\347\273\237\350\256\241.md" +++ /dev/null @@ -1,107 +0,0 @@ -# 内存信息统计 - -- [基础概念](#section52691565235) -- [功能配置](#section470611682411) -- [开发指导](#section9368374243) - - [开发流程](#section679912407257) - - [编程实例](#section1025453412611) - - [示例代码](#section165277971315) - - [结果验证](#section3460102414271) - - -## 基础概念 - -内存信息包括内存池大小、内存使用量、剩余内存大小、最大空闲内存、内存水线、内存节点数统计、碎片率等。 - -- 内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小; - -- 碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-最大空闲内存块大小/剩余内存大小)来度量; - -- 其他参数:通过调用接口(详见[内存管理](内存管理.md)章节接口说明),扫描内存池的节点信息,统计出相关信息。 - -## 功能配置 - -LOSCFG\_MEM\_WATERLINE:开关宏,默认打开;若关闭这个功能,在target\_config.h中将这个宏定义为0。如需获取内存水线,需要打开该配置。 - -## 开发指导 - -### 开发流程 - -关键结构体介绍: - -``` -typedef struct { - UINT32 totalUsedSize; // 内存池的内存使用量 - UINT32 totalFreeSize; // 内存池的剩余内存大小 - UINT32 maxFreeNodeSize; // 内存池的最大空闲内存块大小 - UINT32 usedNodeNum; // 内存池的非空闲内存块个数 - UINT32 freeNodeNum; // 内存池的空闲内存块个数 -#if (LOSCFG_MEM_WATERLINE == 1) // 默认打开,如需关闭,在target_config.h中将该宏设置为0 - UINT32 usageWaterLine; // 内存池的水线值 -#endif -} LOS_MEM_POOL_STATUS; -``` - -- 内存水线获取:调用LOS\_MemInfoGet接口,第1个参数是内存池首地址,第2个参数是LOS\_MEM\_POOL\_STATUS类型的句柄,其中字段usageWaterLine即水线值。 - -- 内存碎片率计算:同样调用LOS\_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 - -### 编程实例 - -本实例实现如下功能: - -1.创建一个监控线程,用于获取内存池的信息; - -2.调用LOS\_MemInfoGet接口,获取内存池的基础信息; - -3.利用公式算出使用率及碎片率。 - -### 示例代码 - -代码实现如下: - -``` -#include -#include -#include "los_task.h" -#include "los_memory.h" -#include "los_config.h" - -void MemInfoTaskFunc(void) -{ - LOS_MEM_POOL_STATUS poolStatus = {0}; - LOS_MemInfoGet(pool, &poolStatus); - /* 算出内存池当前的碎片率百分比 */ - unsigned char fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize; - /* 算出内存池当前的使用率百分比 */ - unsigned char usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool); - printf("usage = %d, fragment = %d, maxFreeSize = %d, totalFreeSize = %d, waterLine = %d\n", usage, fragment, poolStatus.maxFreeNodeSize, - poolStatus.totalFreeSize, poolStatus.usageWaterLine); -} - -int MemTest(void) -{ - unsigned int ret; - unsigned int taskID; - TSK_INIT_PARAM_S taskStatus = {0}; - taskStatus.pfnTaskEntry = (TSK_ENTRY_FUNC)MemInfoTaskFunc; - taskStatus.uwStackSize = 0x1000; - taskStatus.pcName = "memInfo"; - taskStatus.usTaskPrio = 10; - ret = LOS_TaskCreate(&taskID, &taskStatus); - if (ret != LOS_OK) { - printf("task create failed\n"); - return -1; - } - return 0; -} -``` - -### 结果验证 - -编译运行输出的结果如下: - -``` -usage = 22, fragment = 3, maxFreeSize = 49056, totalFreeSize = 50132, waterLine = 1414 -``` - diff --git "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\346\263\204\346\274\217\346\243\200\346\265\213.md" "b/zh-cn/device-dev/kernel/\345\206\205\345\255\230\346\263\204\346\274\217\346\243\200\346\265\213.md" deleted file mode 100644 index 5c57178e5077c4aff25a482ad5b6c4a5ed9f6cb5..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\346\263\204\346\274\217\346\243\200\346\265\213.md" +++ /dev/null @@ -1,128 +0,0 @@ -# 内存泄漏检测 - -- [基础概念](#section1026719436293) -- [功能配置](#section13991354162914) -- [开发指导](#section95828159308) - - [开发流程](#section369844416304) - - [编程实例](#section460801313313) - - [示例代码](#section96539275311) - - [结果验证](#section20527343183119) - - -## 基础概念 - -内存泄漏检测机制作为内核的可选功能,用于辅助定位动态内存泄漏问题。开启该功能,动态内存机制会自动记录申请内存时的函数调用关系(下文简称LR)。如果出现泄漏,就可以利用这些记录的信息,找到内存申请的地方,方便进一步确认。 - -## 功能配置 - -1. LOSCFG\_MEM\_LEAKCHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。 -2. LOSCFG\_MEM\_RECORD\_LR\_CNT:记录的LR层数,默认3层;每层LR消耗sizeof\(void \*\)字节数的内存。 -3. LOSCFG\_MEM\_OMIT\_LR\_CNT:忽略的LR层数,默认4层,即从调用LOS\_MemAlloc的函数开始记录,可根据实际情况调整。为啥需要这个配置?有3点原因如下: - - LOS\_MemAlloc接口内部也有函数调用; - - 外部可能对LOS\_MemAlloc接口有封装; - - LOSCFG\_MEM\_RECORD\_LR\_CNT 配置的LR层数有限; - - -正确配置这个宏,将无效的LR层数忽略,就可以记录有效的LR层数,节省内存消耗。 - -## 开发指导 - -### 开发流程 - -该调测功能可以分析关键的代码逻辑中是否存在内存泄漏。开启这个功能,每次申请内存时,会记录LR信息。在需要检测的代码段前后,调用LOS\_MemUsedNodeShow接口,每次都会打印指定内存池已使用的全部节点信息,对比前后两次的节点信息,新增的节点信息就是疑似泄漏的内存节点。通过LR,可以找到具体申请的代码位置,进一步确认是否泄漏。 - -调用LOS\_MemUsedNodeShow接口输出的节点信息格式如下:每1行为一个节点信息;第1列为节点地址,可以根据这个地址,使用GDB等手段查看节点完整信息;第2列为节点的大小,等于节点头大小+数据域大小;第3\~5列为函数调用关系LR地址,可以根据这个值,结合汇编文件,查看该节点具体申请的位置。 - -``` -node size LR[0] LR[1] LR[2] -0x10017320: 0x528 0x9b004eba 0x9b004f60 0x9b005002 -0x10017848: 0xe0 0x9b02c24e 0x9b02c246 0x9b008ef0 -0x10017928: 0x50 0x9b008ed0 0x9b068902 0x9b0687c4 -0x10017978: 0x24 0x9b008ed0 0x9b068924 0x9b0687c4 -0x1001799c: 0x30 0x9b02c24e 0x9b02c246 0x9b008ef0 -0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 -``` - ->![](public_sys-resources/icon-caution.gif) **注意:** ->开启内存检测会影响内存申请的性能,且每个内存节点都会记录LR地址,内存开销也加大。 - -### 编程实例 - -本实例实现如下功能:构建内存泄漏代码段。 - -1. 调用LOS\_MemUsedNodeShow接口,输出全部节点信息打印; -2. 申请内存,但没有释放,模拟内存泄漏; -3. 再次调用LOS\_MemUsedNodeShow接口,输出全部节点信息打印; -4. 将两次log进行对比,得出泄漏的节点信息; -5. 通过LR地址,找出泄漏的代码位置; - -### 示例代码 - -代码实现如下: - -``` -#include -#include -#include "los_memory.h" -#include "los_config.h" - -void MemLeakTest(void) -{ - LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR); - void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); - void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); - LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR); -} -``` - -### 结果验证 - -编译运行输出log如下: - -``` -node size LR[0] LR[1] LR[2] -0x20001b04: 0x24 0x08001a10 0x080035ce 0x080028fc -0x20002058: 0x40 0x08002fe8 0x08003626 0x080028fc -0x200022ac: 0x40 0x08000e0c 0x08000e56 0x0800359e -0x20002594: 0x120 0x08000e0c 0x08000e56 0x08000c8a -0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220 - -node size LR[0] LR[1] LR[2] -0x20001b04: 0x24 0x08001a10 0x080035ce 0x080028fc -0x20002058: 0x40 0x08002fe8 0x08003626 0x080028fc -0x200022ac: 0x40 0x08000e0c 0x08000e56 0x0800359e -0x20002594: 0x120 0x08000e0c 0x08000e56 0x08000c8a -0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220 -0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 -0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 -``` - -对比两次log,差异如下,这些内存节点就是疑似泄漏的内存块: - -``` -0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 -0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 -``` - -部分汇编文件如下: - -``` - MemLeakTest: - 0x80041d4: 0xb510 PUSH {R4, LR} - 0x80041d6: 0x4ca8 LDR.N R4, [PC, #0x2a0] ; g_memStart - 0x80041d8: 0x0020 MOVS R0, R4 - 0x80041da: 0xf7fd 0xf93e BL LOS_MemUsedNodeShow ; 0x800145a - 0x80041de: 0x2108 MOVS R1, #8 - 0x80041e0: 0x0020 MOVS R0, R4 - 0x80041e2: 0xf7fd 0xfbd9 BL LOS_MemAlloc ; 0x8001998 - 0x80041e6: 0x2108 MOVS R1, #8 - 0x80041e8: 0x0020 MOVS R0, R4 - 0x80041ea: 0xf7fd 0xfbd5 BL LOS_MemAlloc ; 0x8001998 - 0x80041ee: 0x0020 MOVS R0, R4 - 0x80041f0: 0xf7fd 0xf933 BL LOS_MemUsedNodeShow ; 0x800145a - 0x80041f4: 0xbd10 POP {R4, PC} - 0x80041f6: 0x0000 MOVS R0, R0 -``` - -其中,通过查找0x080041ee,就可以发现该内存节点是在MemLeakTest接口里申请的且是没有释放的。 - diff --git "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\347\256\241\347\220\206.md" "b/zh-cn/device-dev/kernel/\345\206\205\345\255\230\347\256\241\347\220\206.md" deleted file mode 100644 index fb44d9bd13bde98aa1ac6c90c8b45856b63b8ed2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\347\256\241\347\220\206.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 内存管理 - -- **[基本概念](基本概念-4.md)** - -- **[静态内存](静态内存.md)** - -- **[动态内存](动态内存.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\350\260\203\346\265\213.md" "b/zh-cn/device-dev/kernel/\345\206\205\345\255\230\350\260\203\346\265\213.md" deleted file mode 100644 index 82555bc86205532b29ab368edfe3adc72ba10287..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\206\205\345\255\230\350\260\203\346\265\213.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 内存调测 - -内存调测方法旨在辅助定位动态内存相关问题,提供了基础的动态内存池信息统计手段,向用户呈现内存池水线、碎片率等信息;提供了内存泄漏检测手段,方便用户准确定位存在内存泄漏的代码行,也可以辅助分析系统各个模块内存的使用情况;提供了踩内存检测手段,可以辅助定位越界踩内存的场景。 - -- **[内存信息统计](内存信息统计.md)** - -- **[内存泄漏检测](内存泄漏检测.md)** - -- **[踩内存检测](踩内存检测.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\206\205\346\240\270\350\260\203\346\265\213.md" "b/zh-cn/device-dev/kernel/\345\206\205\346\240\270\350\260\203\346\265\213.md" deleted file mode 100644 index 6b7080f2bcbb60138e4f258cf3a20b1f35be9618..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\206\205\346\240\270\350\260\203\346\265\213.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 内核调测 - -- **[内存调测](内存调测.md)** - -- **[异常调测](异常调测.md)** - -- **[Trace调测](Trace调测.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\212\250\346\200\201\345\206\205\345\255\230.md" "b/zh-cn/device-dev/kernel/\345\212\250\346\200\201\345\206\205\345\255\230.md" deleted file mode 100644 index 05922df9f795ac26bfa94d71858bab47dda9a8de..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\212\250\346\200\201\345\206\205\345\255\230.md" +++ /dev/null @@ -1,227 +0,0 @@ -# 动态内存 - -- [运行机制](#section328282013571) -- [开发指导](#section7921151015814) - - [使用场景](#section326917198583) - - [接口说明](#section1032331584) - - [开发流程](#section07271773592) - - [编程实例](#section84931234145913) - - [结果验证](#section165233233917) - - -## 运行机制 - -动态内存管理,即在内存资源充足的情况下,根据用户需求,从系统配置的一块比较大的连续内存(内存池,也是堆内存)中分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。与静态内存相比,动态内存管理的优点是按需分配,缺点是内存池中容易出现碎片。 - -OpenHarmony LiteOS-M动态内存在TLSF算法的基础上,对区间的划分进行了优化,获得更优的性能,降低了碎片率。动态内存核心算法框图如下: - -**图 1** 动态内存核心算法 -![](figures/动态内存核心算法.png "动态内存核心算法") - -根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:\[4, 127\]和\[27, 231\],如上图size class所示: - -1. 对\[4,127\]区间的内存进行等分,如上图绿色部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。\[4,127\]区间的31个小区间内存对应31个比特位进行标记链表是否为空。 -2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,见上图蓝色的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。总共24\*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。 - -例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间\[40,43\],第10个空闲链表,位图标记的第10比特位。把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间\[2^9,2^9+2^6\],第31+2\*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。 - -内存管理结构如下图所示: - -**图 2** 动态内存管理结构图 -![](figures/动态内存管理结构图.png "动态内存管理结构图") - -- 内存池池头部分 - - 内存池池头部分包含内存池信息、位图标记数组和空闲链表数组。内存池信息包含内存池起始地址及堆区域总大小,内存池属性。位图标记数组有7个32位无符号整数组成,每个比特位标记对应的空闲链表是否挂载空闲内存块节点。空闲内存链表包含223个空闲内存头节点信息,每个空闲内存头节点信息维护内存节点头和空闲链表中的前驱、后继空闲内存节点。 - -- 内存池节点部分 - - 包含3种类型节点:未使用空闲内存节点,已使用内存节点和尾节点。每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。空闲内存节点和已使用内存节点后面的内存区域是数据域,尾节点没有数据域。 - - -## 开发指导 - -### 使用场景 - -动态内存管理的主要工作是动态分配并管理用户申请到的内存区间。动态内存管理主要用于用户需要使用大小不等的内存块的场景,当用户需要使用内存时,可以通过操作系统的动态内存申请函数索取指定大小的内存块,一旦使用完毕,通过动态内存释放函数归还所占用内存,使之可以重复使用。 - -### 接口说明 - -OpenHarmony LiteOS-M的动态内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 - -**表 1** 动态内存模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

初始化和删除内存池

-

LOS_MemInit

-

初始化一块指定的动态内存池,大小为size。

-

LOS_MemDeInit

-

删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效。

-

申请、释放动态内存

-

LOS_MemAlloc

-

从指定动态内存池中申请size长度的内存。

-

LOS_MemFree

-

释放从指定动态内存中申请的内存。

-

LOS_MemRealloc

-

按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块。

-

LOS_MemAllocAlign

-

从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存。

-

获取内存池信息

-

LOS_MemPoolSizeGet

-

获取指定动态内存池的总大小。

-

LOS_MemTotalUsedGet

-

获取指定动态内存池的总使用量大小。

-

LOS_MemInfoGet

-

获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小。

-

LOS_MemPoolList

-

打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。仅打开LOSCFG_MEM_MUL_POOL时有效。

-

获取内存块信息

-

LOS_MemFreeNodeShow

-

打印指定内存池的空闲内存块的大小及数量。

-

LOS_MemUsedNodeShow

-

打印指定内存池的已使用内存块的大小及数量。

-

检查指定内存池的完整性

-

LOS_MemIntegrityCheck

-

对指定内存池做完整性检查,仅打开LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK时有效。

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->- 由于动态内存管理需要管理控制块数据结构来管理内存,这些数据结构会额外消耗内存,故实际用户可使用内存总量小于配置项OS\_SYS\_MEM\_SIZE的大小。 ->- 对齐分配内存接口LOS\_MemAllocAlign/LOS\_MemMallocAlign因为要进行地址对齐,可能会额外消耗部分内存,故存在一些遗失内存,当系统释放该对齐内存时,同时回收由于对齐导致的遗失内存。 - -### 开发流程 - -本节介绍使用动态内存的典型场景开发流程。 - -1. 初始化LOS\_MemInit。 - - 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。注:EndNode作为内存池末尾的节点,size为0。 - - -1. 申请任意大小的动态内存LOS\_MemAlloc。 - - 判断动态内存池中是否存在大于申请量大小的空闲内存块空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。如果空闲内存块大于申请量,需要对内存块进行分割,剩余的部分作为空闲内存块挂载到空闲内存链表上。 - - -1. 释放动态内存LOS\_MemFree。 - - 回收内存块,供下一次使用。调用LOS\_MemFree释放内存块,则会回收内存块,并且将其标记为FreeNode。在回收内存块时,相邻的FreeNode会自动合并。 - - -### 编程实例 - -本实例执行以下步骤: - -1. 初始化一个动态内存池。 -2. 从动态内存池中申请一个内存块。 -3. 在内存块中存放一个数据。 -4. 打印出内存块中的数据。 -5. 释放该内存块。 - -示例代码如下: - -``` -#include "los_memory.h" - -VOID Example_DynMem(VOID) -{ - UINT32 *mem = NULL; - UINT32 ret; - - /*初始化内存池*/ - ret = LOS_MemInit(g_testPool, TEST_POOL_SIZE); - if (LOS_OK == ret) { - printf("Mem init success!\n"); - } else { - printf("Mem init failed!\n"); - return; - } - - /*分配内存*/ - mem = (UINT32 *)LOS_MemAlloc(g_testPool, 4); - if (NULL == mem) { - printf("Mem alloc failed!\n"); - return; - } - printf("Mem alloc success!\n"); - - /*赋值*/ - *mem = 828; - printf("*mem = %d\n", *mem); - - /*释放内存*/ - ret = LOS_MemFree(g_testPool, mem); - if (LOS_OK == ret) { - printf("Mem free success!\n"); - } else { - printf("Mem free failed!\n"); - } - - return; -} -``` - -### 结果验证 - -输出结果如下: - -``` -Mem init success! -Mem alloc success! -*mem = 828 -Mem free success! -``` - diff --git "a/zh-cn/device-dev/kernel/\345\217\214\345\220\221\351\223\276\350\241\250.md" "b/zh-cn/device-dev/kernel/\345\217\214\345\220\221\351\223\276\350\241\250.md" deleted file mode 100644 index 8b9323d6187bdca8b70e5da46a3e718326d6f937..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\217\214\345\220\221\351\223\276\350\241\250.md" +++ /dev/null @@ -1,191 +0,0 @@ -# 双向链表 - -- [基本概念](#section1990715203418) -- [功能说明](#section848334511411) -- [开发流程](#section01781261552) -- [编程实例](#section67569495514) - - [实例描述](#section48761994551) - - [示例代码](#section1280202685519) - - [结果验证](#section5811249105512) - - -## 基本概念 - -双向链表是指含有往前和往后两个方向的链表,即每个结点中除存放下一个节点指针外,还增加一个指向前一个节点的指针。其头指针head是唯一确定的。 - -从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点,这种数据结构形式使得双向链表在查找时更加方便,特别是大量数据的遍历。由于双向链表具有对称性,能方便地完成各种插入、删除等操作,但需要注意前后方向的操作。 - -## 功能说明 - -双向链表模块为用户提供下面几种功能,接口详细信息可以查看API参考。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

初始化链表

-

LOS_ListInit

-

将指定双向链表节点初始化为双向链表

-

LOS_DL_LIST_HEAD

-

定义一个双向链表节点并以该节点初始化为双向链表

-

增加节点

-

LOS_ListAdd

-

将指定节点插入到双向链表头端

-

LOS_ListTailInsert

-

将指定节点插入到双向链表尾端

-

删除节点

-

LOS_ListDelete

-

将指定节点从链表中删除

-

LOS_ListDelInit

-

将指定节点从链表中删除,并使用该节点初始化链表

-

判断双向链表是否为空

-

LOS_ListEmpty

-

判断链表是否为空

-

获取结构体信息

-

LOS_DL_LIST_ENTRY

-

获取包含链表的结构体地址,接口的第一个入参表示的是链表中的某个节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称

-

LOS_OFF_SET_OF

-

获取指定结构体内的成员相对于结构体起始地址的偏移量

-

遍历双向链表

-

LOS_DL_LIST_FOR_EACH

-

遍历双向链表

-

LOS_DL_LIST_FOR_EACH_SAFE

-

遍历双向链表,并存储当前节点的后继节点用于安全校验

-

遍历包含双向链表的结构体

-

LOS_DL_LIST_FOR_EACH_ENTRY

-

遍历指定双向链表,获取包含该链表节点的结构体地址

-

LOS_DL_LIST_FOR_EACH_ENTRY_SAFE

-

遍历指定双向链表,获取包含该链表节点的结构体地址,并存储包含当前节点的后继节点的结构体地址

-
- -## 开发流程 - -双向链表的典型开发流程: - -1. 调用LOS\_ListInit/LOS\_DL\_LIST\_HEAD初始双向链表。 -2. 调用LOS\_ListAdd向链表插入节点。 -3. 调用LOS\_ListTailInsert向链表尾部插入节点。 -4. 调用LOS\_ListDelete删除指定节点。 -5. 调用LOS\_ListEmpty判断链表是否为空。 -6. 调用LOS\_ListDelInit删除指定节点并以此节点初始化链表。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 需要注意节点指针前后方向的操作。 ->- 链表操作接口,为底层接口,不对入参进行判空,需要使用者确保传参合法。 ->- 如果链表节点的内存是动态申请的,删除节点时,要注意释放内存。 - -## 编程实例 - -### 实例描述 - -本实例实现如下功能: - -1. 初始化双向链表。 -2. 增加节点。 -3. 删除节点。 -4. 测试操作是否成功。 - -### 示例代码 - -示例代码如下: - -``` -#include "stdio.h" -#include "los_list.h" - -static UINT32 ListSample(VOID) -{ - LOS_DL_LIST listHead = {NULL,NULL}; - LOS_DL_LIST listNode1 = {NULL,NULL}; - LOS_DL_LIST listNode2 = {NULL,NULL}; - - //首先初始化链表 - printf("Initial head\n"); - LOS_ListInit(&listHead); - - //添加节点1和节点2,并校验他们的相互关系 - LOS_ListAdd(&listHead, &listNode1); - if (listNode1.pstNext == &listHead && listNode1.pstPrev == &listHead) { - printf("Add listNode1 success\n"); - } - - LOS_ListTailInsert(&listHead, &listNode2); - if (listNode2.pstNext == &listHead && listNode2.pstPrev == &listNode1) { - printf("Tail insert listNode2 success\n"); - } - - //删除两个节点 - LOS_ListDelete(&listNode1); - LOS_ListDelete(&listNode2); - - //确认链表为空 - if (LOS_ListEmpty(&listHead)) { - printf("Delete success\n"); - } - - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -Initial head -Add listNode1 success -Tail insert listNode2 success -Delete success -``` - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\225\260\346\215\256\347\273\223\346\236\204.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\225\260\346\215\256\347\273\223\346\236\204.md" deleted file mode 100644 index 5464ca3ceec7232da4ed7051b1c38258e7c4a7c3..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\225\260\346\215\256\347\273\223\346\236\204.md" +++ /dev/null @@ -1,5 +0,0 @@ -# 基本数据结构 - -- **[双向链表](双向链表.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-11.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-11.md" deleted file mode 100644 index dd72ce5e104fdf75ce5dcb71967eae9b0aaf7fab..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-11.md" +++ /dev/null @@ -1,53 +0,0 @@ -# 基本概念 - -- [运行机制](#section1794010261861) - - [信号量控制块](#section11372149164815) - - [信号量运作原理](#section139726510491) - - -信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。 - -一个信号量的数据结构中,通常有一个计数值,用于对有效资源数的计数,表示剩下的可被使用的共享资源数,其值的含义分两种情况: - -- 0,表示该信号量当前不可获取,因此可能存在正在等待该信号量的任务。 -- 正值,表示该信号量当前可被获取。 - -以同步为目的的信号量和以互斥为目的的信号量在使用上有如下不同: - -- 用作互斥时,初始信号量计数值不为0,表示可用的共享资源个数。在需要使用共享资源前,先获取信号量,然后使用一个共享资源,使用完毕后释放信号量。这样在共享资源被取完,即信号量计数减至0时,其他需要获取信号量的任务将被阻塞,从而保证了共享资源的互斥访问。另外,当共享资源数为1时,建议使用二值信号量,一种类似于互斥锁的机制。 -- 用作同步时,初始信号量计数值为0。任务1获取信号量而阻塞,直到任务2或者某中断释放信号量,任务1才得以进入Ready或Running态,从而达到了任务间的同步。 - -## 运行机制 - -### 信号量控制块 - -``` -/** - * 信号量控制块数据结构 - */ -typedef struct { - UINT16 semStat; /* 信号量状态 */ - UINT16 semType; /* 信号量类型 */ - UINT16 semCount; /* 信号量计数 */ - UINT16 semId; /* 信号量索引号 */ - LOS_DL_LIST semList; /* 挂接阻塞于该信号量的任务 */ -} LosSemCB; -``` - -### 信号量运作原理 - -信号量初始化,为配置的N个信号量申请内存(N值可以由用户自行配置,通过LOSCFG\_BASE\_IPC\_SEM\_LIMIT宏实现),并把所有信号量初始化成未使用,加入到未使用链表中供系统使用。 - -信号量创建,从未使用的信号量链表中获取一个信号量,并设定初值。 - -信号量申请,若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其它任务释放该信号量,等待的超时时间可设定。当任务被一个信号量阻塞时,将该任务挂到信号量等待任务队列的队尾。 - -信号量释放,若没有任务等待该信号量,则直接将计数器加1返回。否则唤醒该信号量等待任务队列上的第一个任务。 - -信号量删除,将正在使用的信号量置为未使用信号量,并挂回到未使用链表。 - -信号量允许多个任务在同一时刻访问共享资源,但会限制同一时刻访问此资源的最大任务数目。当访问资源的任务数达到该资源允许的最大数量时,会阻塞其他试图获取该资源的任务,直到有任务释放该信号量。 - -**图 1** 信号量运作示意图 -![](figures/信号量运作示意图.png "信号量运作示意图") - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-2.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-2.md" deleted file mode 100644 index db5ae0ccd5e29fe476b391b83bd3c4ff13199e53..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-2.md" +++ /dev/null @@ -1,96 +0,0 @@ -# 基本概念 - -- [任务相关概念](#section673132352511) -- [任务运行机制](#section176294469251) - -从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。 - -OpenHarmony LiteOS-M的任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。任务模块具有如下特性: - -- 支持多任务。 -- 一个任务表示一个线程。 -- 抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。 -- 相同优先级任务支持时间片轮转调度方式。 -- 共有32个优先级\[0-31\],最高优先级为0,最低优先级为31。 - -## 任务相关概念 - -**任务状态** - -任务有多种运行状态。系统初始化完成后,创建的任务就可以在系统中竞争一定的资源,由内核进行调度。 - -任务状态通常分为以下四种: - -- 就绪(Ready):该任务在就绪队列中,只等待CPU。 -- 运行(Running):该任务正在执行。 -- 阻塞(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、任务正在等待信号量、读写队列或者等待事件等。 -- 退出态(Dead):该任务运行结束,等待系统回收资源。 - -**任务状态迁移** - -**图 1** 任务状态示意图 -![](figures/任务状态示意图.png "任务状态示意图") - -**任务状态迁移说明:** - -- 就绪态→运行态 - - 任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行,从而进入运行态,同时该任务从就绪队列中移出。 - -- 运行态→阻塞态 - - 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,该任务会从就绪队列中删除,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。 - -- 阻塞态→就绪态(阻塞态→运行态) - - 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。 - -- 就绪态→阻塞态 - - 任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务从就绪队列中删除,不会参与任务调度,直到该任务被恢复。 - -- 运行态→就绪态 - - 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。 - -- 运行态→退出态 - - 运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。 - -- 阻塞态→退出态 - - 阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。 - - -**任务ID** - -任务ID,在任务创建时通过参数返回给用户,是任务的重要标识。系统中的ID号是唯一的。用户可以通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。 - -**任务优先级** - -优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,就绪队列中最高优先级的任务将得到执行。 - -**任务入口函数** - -新任务得到调度后将执行的函数。该函数由用户实现,在任务创建时,通过任务创建结构体设置。 - -**任务栈** - -每个任务都拥有一个独立的栈空间,我们称为任务栈。栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。 - -**任务上下文** - -任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当这个任务挂起时,其他任务继续执行,可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。因此在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。 - -**任务控制块TCB** - -每个任务都含有一个任务控制块\(TCB\)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。 - -**任务切换** - -任务切换包含获取就绪队列中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。 - -## 任务运行机制 - -用户创建任务时,系统会初始化任务栈,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。 - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-21.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-21.md" deleted file mode 100644 index 310f6014ea284196a44041b9ae68651d14d58555..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-21.md" +++ /dev/null @@ -1,82 +0,0 @@ -# 基本概念 - -- [运行机制](#section10284121317365) - - [日志方式](#section13804114513361) - - [Cow机制](#section172771130193610) - - [lfs掉电保护](#section42941021173614) - - -LittleFS主要用在微控制器和flash上,是一种嵌入式文件系统,具有如下3个特点: - -1. 掉电恢复 - - 在写入时即使复位或者掉电也可以恢复到上一个正确的状态。 - -2. 擦写均衡 - - 有效延长flash的使用寿命。 - -3. 有限的RAM/ROM - - 节省ROM和RAM空间。 - - -## 运行机制 - -最经典的掉电保护方法有两种,一种是使用日志,一种是通过COW方式。lfs结合了两种方法,并优化了两种方案的缺点,提供了一套掉电保护策略 - -### 日志方式 - -![](figures/zh-cn_image_0000001124310992.png) - -具体步骤为: - -1. 写入数据之前,先在日志区存储开始标志,记录要写入的数据位置和大小; -2. 待写入的数据写入日志区; -3. 待写入的数据写入数据区; -4. 写入完成之后,在日志区记录结束标志。 - -模拟掉电场景: - -1. 步骤1完成,步骤2没有完成;重启之后,保持原来的数据,日志无效; -2. 步骤1,2完成了,步骤3没有完成,尝试把步骤2的数据写入到数据区; -3. 步骤1,2,3完成了,步骤4没有完成,同样尝试把步骤2的数据写入到数据区; - -### Cow机制 - -![](figures/zh-cn_image_0000001170790681.png) - -具体步骤为: - -1. 想更新节点F的数据,先申请一个新的节点,把F的旧数据拷贝过去,然后更新新的数据; -2. 把父节点的指针指向新的节点,去掉旧节点的指针。 - -模拟掉电场景: - -步骤1完成了,步骤2没有完成,则使用旧的数据,新的节点变成孤儿节点。 - -### lfs掉电保护 - -fs结合了日志方式和COW机制两种方式进行掉电保护,并且优化了两种方案。 - -前面谈过文件系统三要素,超级块,inode,以及数据。对应lfs来说,他把超级块以及inode通过日志的方式存储,两种采用统一的存储结构,后文称两者为元数据;普通数据则采用cow的方式存储,采用czt逆序链表的方式。 - -![](figures/zh-cn_image_0000001124307264.png) - -**元数据的存储** - -![](figures/zh-cn_image_0000001124147160.png) - -元数据(对应root,dir)采用双block的方式存储,互为备份,每个block都有一个revision序号,值越大,表示block的数据越新,每个block默认可以存储最多0xff个文件的数据,如果超过这个值,则需要compact(压缩)。 - -Compact是干什么呢? 即当数据的大小大于某个值的时候,把数据整合,剔除同一个id的旧的数据,然后写入到备份block里面。 - -**普通数据的存储** - -Lfs的数据采用链表的方式逆向管理。 - -![](figures/zh-cn_image_0000001124306828.png) - -1. 采用逆向的指针,这样常规的追加数据,不需要额外的开销来重新建立所有的索引; -2. 每个偶数block有多个指针,指向更远的数据,这样可以在检索的时候加快速度。 - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-5.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-5.md" deleted file mode 100644 index a96f943c8d815c0e4274c22744ae6ca33b5d9bb1..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-5.md" +++ /dev/null @@ -1,52 +0,0 @@ -# 基本概念 - -- [运行机制](#section1735611583011) - - [事件控制块](#section1161415384467) - - [事件运作原理](#section187761153144617) - - -事件(Event)是一种任务间的通信机制,可用于任务间的同步操作。事件的特点是: - -- 任务间的事件同步,可以一对多,也可以多对多。一对多表示一个任务可以等待多个事件,多对多表示多个任务可以等待多个事件。但是一次写事件最多触发一个任务从阻塞中醒来。 -- 事件读超时机制。 -- 只做任务间同步,不传输具体数据。 - -提供了事件初始化、事件读写、事件清零、事件销毁等接口。 - -## 运行机制 - -### 事件控制块 - -``` -/** - * 事件控制块数据结构 - */ -typedef struct tagEvent { - UINT32 uwEventID; /* 事件集合,表示已经处理(写入和清零)的事件集合 */ - LOS_DL_LIST stEventList; /* 等待特定事件的任务链表 */ -} EVENT_CB_S, *PEVENT_CB_S; -``` - -### 事件运作原理 - -**事件初始化:**会创建一个事件控制块,该控制块维护一个已处理的事件集合,以及等待特定事件的任务链表。 - -**写事件:**会向事件控制块写入指定的事件,事件控制块更新事件集合,并遍历任务链表,根据任务等待具体条件满足情况决定是否唤醒相关任务。 - -**读事件:**如果读取的事件已存在时,会直接同步返回。其他情况会根据超时时间以及事件触发情况,来决定返回时机:等待的事件条件在超时时间耗尽之前到达,阻塞任务会被直接唤醒,否则超时时间耗尽该任务才会被唤醒。 - -读事件条件满足与否取决于入参eventMask和mode,eventMask即需要关注的事件。mode是具体处理方式,分以下三种情况: - -LOS\_WAITMODE\_AND:表示eventMask中所有事件都发生时,才返回。 - -LOS\_WAITMODE\_OR:表示eventMask中任何事件发生时,就返回。 - -LOS\_WAITMODE\_CLR:事件读取成功后,对应读取到的事件会被清零。需要配合LOS\_WAITMODE\_AND或者LOS\_WAITMODE\_OR来使用。 - -**事件清零:**根据指定掩码,去对事件控制块的事件集合进行清零操作。当掩码为0时,表示将事件集合全部清零。当掩码为0xffff时,表示不清除任何事件,保持事件集合原状。 - -**事件销毁:**销毁指定的事件控制块。 - -**图 1** 事件运作原理图 -![](figures/事件运作原理图.png "事件运作原理图") - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-7.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-7.md" deleted file mode 100644 index 4989a0b93edfc85ad0f1a4b5fb50b7f5eaa89019..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-7.md" +++ /dev/null @@ -1,19 +0,0 @@ -# 基本概念 - -- [运行机制](#section115161649726) - -互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。 - -任意时刻互斥锁的状态只有两种,开锁或闭锁。当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。当该任务释放它时,该互斥锁被开锁,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。 - -多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。另外互斥锁可以解决信号量存在的优先级翻转问题。 - -## 运行机制 - -多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢? - -用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。 - -**图 1** 互斥锁运作示意图 -![](figures/互斥锁运作示意图.png "互斥锁运作示意图") - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-9.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-9.md" deleted file mode 100644 index 90541dda60a684efadf642baf6e01e6c01460b79..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-9.md" +++ /dev/null @@ -1,67 +0,0 @@ -# 基本概念 - -- [运行机制](#section1582619446311) - - [队列控制块](#section1648304614720) - - [队列运作原理](#section15384012164811) - - -队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 - -任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息。任务也能够往队列里写入消息,当队列已经写满消息时,挂起写入任务;当队列中有空闲消息节点时,挂起的写入任务被唤醒并写入消息。 - -可以通过调整读队列和写队列的超时时间来调整读写接口的阻塞模式,如果将读队列和写队列的超时时间设置为0,就不会挂起任务,接口会直接返回,这就是非阻塞模式。反之,如果将都队列和写队列的超时时间设置为大于0的时间,就会以阻塞模式运行。 - -消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用,可以使用队列实现任务异步通信,队列具有如下特性: - -- 消息以先进先出的方式排队,支持异步读写。 -- 读队列和写队列都支持超时机制。 -- 每读取一条消息,就会将该消息节点设置为空闲。 -- 发送消息类型由通信双方约定,可以允许不同长度(不超过队列的消息节点大小)的消息。 -- 一个任务能够从任意一个消息队列接收和发送消息。 -- 多个任务能够从同一个消息队列接收和发送消息。 -- 创建队列时所需的队列空间,接口内系统自行动态申请内存。 - -## 运行机制 - -### 队列控制块 - -``` -/** - * 队列控制块数据结构 - */ -typedef struct -{ - UINT8 *queue; /* 队列消息内存空间的指针 */ - UINT16 queueState; /* 队列状态 */ - UINT16 queueLen; /* 队列中消息节点个数,即队列长度 */ - UINT16 queueSize; /* 消息节点大小 */ - UINT16 queueID; /* 队列ID */ - UINT16 queueHead; /* 消息头节点位置(数组下标)*/ - UINT16 queueTail; /* 消息尾节点位置(数组下标)*/ - UINT16 readWriteableCnt[OS_READWRITE_LEN]; /* 数组下标0的元素表示队列中可读消息数, - 数组下标1的元素表示队列中可写消息数 */ - LOS_DL_LIST readWriteList[OS_READWRITE_LEN]; /* 读取或写入消息的任务等待链表, - 下标0:读取链表,下标1:写入链表 */ - LOS_DL_LIST memList; /* 内存块链表 */ -} LosQueueCB; -``` - -每个队列控制块中都含有队列状态,表示该队列的使用情况: - -- OS\_QUEUE\_UNUSED:队列未被使用。 -- OS\_QUEUE\_INUSED:队列被使用中。 - -### 队列运作原理 - -- 创建队列时,创建队列成功会返回队列ID。 -- 在队列控制块中维护着一个消息头节点位置Head和一个消息尾节点位置Tail,用于表示当前队列中消息的存储情况。Head表示队列中被占用的消息节点的起始位置。Tail表示被占用的消息节点的结束位置,也是空闲消息节点的起始位置。队列刚创建时,Head和Tail均指向队列起始位置。 -- 写队列时,根据readWriteableCnt\[1\]判断队列是否可以写入,不能对已满(readWriteableCnt\[1\]为0)队列进行写操作。写队列支持两种写入方式:向队列尾节点写入,也可以向队列头节点写入。尾节点写入时,根据Tail找到起始空闲消息节点作为数据写入对象,如果Tail已经指向队列尾部则采用回卷方式。头节点写入时,将Head的前一个节点作为数据写入对象,如果Head指向队列起始位置则采用回卷方式。 -- 读队列时,根据readWriteableCnt\[0\]判断队列是否有消息需要读取,对全部空闲(readWriteableCnt\[0\]为0)队列进行读操作会引起任务挂起。如果队列可以读取消息,则根据Head找到最先写入队列的消息节点进行读取。如果Head已经指向队列尾部则采用回卷方式。 -- 删除队列时,根据队列ID找到对应队列,把队列状态置为未使用,把队列控制块置为初始状态,并释放队列所占内存。 - -图 1 队列读写数据操作示意图 - -![](figures/zh-cn_image_0000001124146302.png) - -上图对读写队列做了示意,图中只画了尾节点写入方式,没有画头节点写入,但是两者是类似的。 - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\347\241\200\345\206\205\346\240\270-1.md" "b/zh-cn/device-dev/kernel/\345\237\272\347\241\200\345\206\205\346\240\270-1.md" deleted file mode 100644 index df2416afdc86ecb4952f852342ae640cb0d88d79..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\347\241\200\345\206\205\346\240\270-1.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 基础内核 - -- **[中断管理](中断管理.md)** - -- **[任务管理](任务管理.md)** - -- **[内存管理](内存管理.md)** - -- **[IPC](IPC.md)** - -- **[时间管理](时间管理.md)** - -- **[软件定时器](软件定时器.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\237\272\347\241\200\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\345\237\272\347\241\200\345\206\205\346\240\270.md" deleted file mode 100644 index 94b43451a99a3d3e6b85388a828c0110bd2cc209..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\237\272\347\241\200\345\206\205\346\240\270.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 基础内核 - -- **[进程](进程.md)** - -- **[线程](线程.md)** - -- **[内存](内存.md)** - -- **[网络](网络.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" deleted file mode 100644 index d24843996311d64f63f2873e2f53b784ee55dd73..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 小型系统内核 - -- **[认识LiteOS-M内核](认识LiteOS-M内核.md)** - -- **[快速入门](快速入门.md)** - -- **[基础内核](基础内核-1.md)** - -- **[扩展组件](扩展组件.md)** - -- **[内核调测](内核调测.md)** - -- **[附录](附录.md)** - - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-10.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-10.md" deleted file mode 100644 index c521fd755d1194a135d4a538535a5ec81172ad4f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-10.md" +++ /dev/null @@ -1,199 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section2148236125814) - - [示例代码](#section121451047155716) - - [结果验证](#section2742182082117) - - -## 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建/删除消息队列

-

LOS_QueueCreate

-

创建一个消息队列,由系统动态申请队列空间。

-

LOS_QueueDelete

-

根据队列ID删除一个指定队列。

-

读/写队列(不带拷贝)

-

LOS_QueueRead

-

读取指定队列头节点中的数据(队列节点中的数据实际上是一个地址)。

-

LOS_QueueWrite

-

向指定队列尾节点中写入入参bufferAddr的值(即buffer的地址)。

-

LOS_QueueWriteHead

-

向指定队列头节点中写入入参bufferAddr的值(即buffer的地址)。

-

读/写队列(带拷贝)

-

LOS_QueueReadCopy

-

读取指定队列头节点中的数据。

-

LOS_QueueWriteCopy

-

向指定队列尾节点中写入入参bufferAddr中保存的数据。

-

LOS_QueueWriteHeadCopy

-

向指定队列头节点中写入入参bufferAddr中保存的数据。

-

获取队列信息

-

LOS_QueueInfoGet

-

获取指定队列的信息,包括队列ID、队列长度、消息节点大小、头节点、尾节点、可读节点数量、可写节点数量、等待读操作的任务、等待写操作的任务。

-
- -## 开发流程 - -1. 用LOS\_QueueCreate创建队列。创建成功后,可以得到队列ID。 -2. 通过LOS\_QueueWrite或者LOS\_QueueWriteCopy写队列。 -3. 通过LOS\_QueueRead或者LOS\_QueueReadCopy读队列。 -4. 通过LOS\_QueueInfoGet获取队列信息。 -5. 通过LOS\_QueueDelete删除队列。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 系统支持的最大队列数是指:整个系统的队列资源总个数,而非用户能使用的个数。例如:系统软件定时器多占用一个队列资源,那么用户能使用的队列资源就会减少一个。 ->- 创建队列时传入的队列名和flags暂时未使用,作为以后的预留参数。 ->- 队列接口函数中的入参timeOut是相对时间。 ->- LOS\_QueueReadCopy和LOS\_QueueWriteCopy及LOS\_QueueWriteHeadCopy是一组接口,LOS\_QueueRead和LOS\_QueueWrite及LOS\_QueueWriteHead是一组接口,每组接口需要配套使用。 ->- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,用户必须保证调用LOS\_QueueRead获取到的指针所指向的内存区域在读队列期间没有被异常修改或释放,否则可能导致不可预知的后果。 ->- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,也就意味着实际写和读的消息长度仅仅是一个指针数据,因此用户使用这组接口之前,需确保创建队列时的消息节点大小,为一个指针的长度,避免不必要的浪费和读取失败。 - -## 编程实例 - -### 实例描述 - -创建一个队列,两个任务。任务1调用写队列接口发送消息,任务2通过读队列接口接收消息。 - -1. 通过LOS\_TaskCreate创建任务1和任务2。 -2. 通过LOS\_QueueCreate创建一个消息队列。 -3. 在任务1 SendEntry中发送消息。 -4. 在任务2 RecvEntry中接收消息。 -5. 通过LOS\_QueueDelete删除队列。 - -### 示例代码 - -示例代码如下: - -``` -#include "los_task.h" -#include "los_queue.h" -static UINT32 g_queue; -#define BUFFER_LEN 50 - -VOID SendEntry(VOID) -{ - UINT32 ret = 0; - CHAR abuf[] = "test message"; - UINT32 len = sizeof(abuf); - - ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); - if(ret != LOS_OK) { - printf("send message failure, error: %x\n", ret); - } -} - -VOID RecvEntry(VOID) -{ - UINT32 ret = 0; - CHAR readBuf[BUFFER_LEN] = {0}; - UINT32 readLen = BUFFER_LEN; - - //休眠1s - usleep(1000000); - ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); - if(ret != LOS_OK) { - printf("recv message failure, error: %x\n", ret); - } - - printf("recv message: %s\n", readBuf); - - ret = LOS_QueueDelete(g_queue); - if(ret != LOS_OK) { - printf("delete the queue failure, error: %x\n", ret); - } - - printf("delete the queue success!\n"); -} - -UINT32 ExampleQueue(VOID) -{ - printf("start queue example\n"); - UINT32 ret = 0; - UINT32 task1, task2; - TSK_INIT_PARAM_S initParam = {0}; - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; - initParam.usTaskPrio = 9; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - initParam.pcName = "SendQueue"; - - LOS_TaskLock(); - ret = LOS_TaskCreate(&task1, &initParam); - if(ret != LOS_OK) { - printf("create task1 failed, error: %x\n", ret); - return ret; - } - - initParam.pcName = "RecvQueue"; - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; - ret = LOS_TaskCreate(&task2, &initParam); - if(ret != LOS_OK) { - printf("create task2 failed, error: %x\n", ret); - return ret; - } - - ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); - if(ret != LOS_OK) { - printf("create queue failure, error: %x\n", ret); - } - - printf("create the queue success!\n"); - LOS_TaskUnlock(); - return ret; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -start test example -create the queue success! -recv message: test message -delete the queue success! -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-12.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-12.md" deleted file mode 100644 index 4a483b339176b6f58c5e4059fb13bd28b3eea629..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-12.md" +++ /dev/null @@ -1,206 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section22061718111412) - - [示例代码](#section1775922321416) - - [结果验证](#section160404016213) - - -## 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建/删除信号量

-

LOS_SemCreate

-

创建信号量,返回信号量ID

-

LOS_BinarySemCreate

-

创建二值信号量,其计数值最大为1

-

LOS_SemDelete

-

删除指定的信号量

-

申请/释放信号量

-

LOS_SemPend

-

申请指定的信号量,并设置超时时间

-

LOS_SemPost

-

释放指定的信号量

-
- -## 开发流程 - -1. 创建信号量LOS\_SemCreate,若要创建二值信号量则调用LOS\_BinarySemCreate。 -2. 申请信号量LOS\_SemPend。 -3. 释放信号量LOS\_SemPost。 -4. 删除信号量LOS\_SemDelete。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->由于中断不能被阻塞,因此不能在中断中使用阻塞模式申请信号量。 - -## 编程实例 - -### 实例描述 - -本实例实现如下功能: - -1. 测试任务ExampleSem创建一个信号量,锁任务调度,创建两个任务ExampleSemTask1、ExampleSemTask2, ExampleSemTask2优先级高于ExampleSemTask1,两个任务中申请同一信号量,解锁任务调度后两任务阻塞,测试任务ExampleSem释放信号量。 -2. ExampleSemTask2得到信号量,被调度,然后任务休眠20Tick,ExampleSemTask2延迟,ExampleSemTask1被唤醒。 -3. ExampleSemTask1定时阻塞模式申请信号量,等待时间为10Tick,因信号量仍被ExampleSemTask2持有,ExampleSemTask1挂起,10Tick后仍未得到信号量,ExampleSemTask1被唤醒,试图以永久阻塞模式申请信号量,ExampleSemTask1挂起。 -4. 20Tick后ExampleSemTask2唤醒, 释放信号量后,ExampleSemTask1得到信号量被调度运行,最后释放信号量。 -5. ExampleSemTask1执行完,40Tick后任务ExampleSem被唤醒,执行删除信号量。 - -### 示例代码 - -示例代码如下: - -``` -#include "los_sem.h" -#include "securec.h" - -/* 任务ID */ -static UINT32 g_testTaskId01; -static UINT32 g_testTaskId02; - -/* 测试任务优先级 */ -#define TASK_PRIO_TEST 5 - -/* 信号量结构体id */ -static UINT32 g_semId; - -VOID ExampleSemTask1(VOID) -{ - UINT32 ret; - - printf("ExampleSemTask1 try get sem g_semId, timeout 10 ticks.\n"); - - /* 定时阻塞模式申请信号量,定时时间为10ticks */ - ret = LOS_SemPend(g_semId, 10); - - /* 申请到信号量 */ - if (ret == LOS_OK) { - LOS_SemPost(g_semId); - return; - } - /* 定时时间到,未申请到信号量 */ - if (ret == LOS_ERRNO_SEM_TIMEOUT) { - printf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n"); - - /*永久阻塞模式申请信号量*/ - ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); - printf("ExampleSemTask1 wait_forever and get sem g_semId.\n"); - if (ret == LOS_OK) { - LOS_SemPost(g_semId); - return; - } - } -} - -VOID ExampleSemTask2(VOID) -{ - UINT32 ret; - printf("ExampleSemTask2 try get sem g_semId wait forever.\n"); - - /* 永久阻塞模式申请信号量 */ - ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); - - if (ret == LOS_OK) { - printf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n"); - } - - /* 任务休眠20 ticks */ - LOS_TaskDelay(20); - - printf("ExampleSemTask2 post sem g_semId.\n"); - /* 释放信号量 */ - LOS_SemPost(g_semId); - return; -} - -UINT32 ExampleSem(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - TSK_INIT_PARAM_S task2; - - /* 创建信号量 */ - LOS_SemCreate(0, &g_semId); - - /* 锁任务调度 */ - LOS_TaskLock(); - - /* 创建任务1 */ - (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1; - task1.pcName = "TestTask1"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = TASK_PRIO_TEST; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("task1 create failed .\n"); - return LOS_NOK; - } - - /* 创建任务2 */ - (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2; - task2.pcName = "TestTask2"; - task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task2.usTaskPrio = (TASK_PRIO_TEST - 1); - ret = LOS_TaskCreate(&g_testTaskId02, &task2); - if (ret != LOS_OK) { - printf("task2 create failed.\n"); - return LOS_NOK; - } - - /* 解锁任务调度 */ - LOS_TaskUnlock(); - - ret = LOS_SemPost(g_semId); - - /* 任务休眠400 ticks */ - LOS_TaskDelay(400); - - /* 删除信号量 */ - LOS_SemDelete(g_semId); - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -ExampleSemTask2 try get sem g_semId wait forever. -ExampleSemTask2 get sem g_semId and then delay 20 ticks. -ExampleSemTask1 try get sem g_semId, timeout 10 ticks. - -ExampleSemTask1 timeout and try get sem g_semId wait forever. -ExampleSemTask2 post sem g_semId. -ExampleSemTask1 wait_forever and get sem g_semId. -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-14.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-14.md" deleted file mode 100644 index 46c7d87b7cbbfa961feb34f316b94c73475277b3..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-14.md" +++ /dev/null @@ -1,159 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section127752801718) - - [示例代码](#section321653551711) - - [结果验证](#section4366193318167) - - -用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系时,需要使用到时间管理模块的接口。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的时间管理提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 时间管理接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

时间转换

-

LOS_MS2Tick

-

毫秒转换成Tick

-

LOS_Tick2MS

-

Tick转化为毫秒

-

OsCpuTick2MS

-

Cycle数目转化为毫秒,使用2个

-

UINT32类型的数值分别表示结果数值的高、低32位。

-

OsCpuTick2US

-

Cycle数目转化为微秒,使用2个

-

UINT32类型的数值分别表示结果数值的高、低32位。

-

时间统计

-

LOS_SysClockGet

-

获取系统时钟

-

LOS_TickCountGet

-

获取自系统启动以来的Tick数

-

LOS_CyclePerTickGet

-

每个Tick多少Cycle数

-
- -## 开发流程 - -时间管理的典型开发流程: - -1. 根据实际需求,完成板级配置适配,并配置系统主时钟频率OS\_SYS\_CLOCK(单位Hz)和LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND。OS\_SYS\_CLOCK的默认值基于硬件平台配置。 -2. 调用时钟转换/统计接口。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 时间管理不是单独的功能模块,依赖于OS\_SYS\_CLOCK和LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND两个配置选项。 ->- 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间使用。 ->- 配置选项维护在开发板工程的文件target\_config.h。 - -## 编程实例 - -### 实例描述 - -在下面的例子中,介绍了时间管理的基本方法,包括: - -1. 时间转换:将毫秒数转换为Tick数,或将Tick数转换为毫秒数。 -2. 时间统计:每Tick的Cycle数、自系统启动以来的Tick数和延迟后的Tick数。 - -### 示例代码 - -前提条件: - -- 使用每秒的Tick数LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND的默认值100。 -- 配好OS\_SYS\_CLOCK系统主时钟频率。 - -时间转换: - -``` -VOID Example_TransformTime(VOID) -{ - UINT32 ms; - UINT32 tick; - - tick = LOS_MS2Tick(10000); // 10000ms转换为tick - dprintf("tick = %d \n", tick); - ms = LOS_Tick2MS(100); // 100tick转换为ms - dprintf("ms = %d \n", ms); -} -``` - -时间统计和时间延迟: - -``` -VOID Example_GetTime(VOID) -{ - UINT32 cyclePerTick; - UINT64 tickCount; - - cyclePerTick = LOS_CyclePerTickGet(); - if(0 != cyclePerTick) { - dprintf("LOS_CyclePerTickGet = %d \n", cyclePerTick); - } - - tickCount = LOS_TickCountGet(); - if(0 != tickCount) { - dprintf("LOS_TickCountGet = %d \n", (UINT32)tickCount); - } - - LOS_TaskDelay(200); - tickCount = LOS_TickCountGet(); - if(0 != tickCount) { - dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)tickCount); - } -} -``` - -### 结果验证 - -编译运行得到的结果为: - -时间转换: - -``` -tick = 1000 -ms = 1000 -``` - -时间统计和时间延迟: - -``` -LOS_CyclePerTickGet = 495000 -LOS_TickCountGet = 1 -LOS_TickCountGet after delay = 201 -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-16.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-16.md" deleted file mode 100644 index 37753d3a43aad040cae343376b2a57aa48ff7e20..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-16.md" +++ /dev/null @@ -1,218 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section3741753191918) - - [示例代码](#section20760101182016) - - [结果验证](#section11244112818172) - - -## 接口说明 - -OpenHarmony LiteOS-M内核的软件定时器模块提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 软件定时器接口 - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建、删除定时器

-

LOS_SwtmrCreate

-

创建定时器

-

LOS_SwtmrDelete

-

删除定时器

-

启动、停止定时器

-

LOS_SwtmrStart

-

启动定时器

-

LOS_SwtmrStop

-

停止定时器

-

获得软件定时器剩余Tick数

-

LOS_SwtmrTimeGet

-

获得软件定时器剩余Tick数

-
- -## 开发流程 - -软件定时器的典型开发流程: - -1. 配置软件定时器。 - - 确认配置项LOSCFG\_BASE\_CORE\_SWTMR和LOSCFG\_BASE\_IPC\_QUEUE为1打开状态; - - 配置LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数; - - 配置OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度; - -2. 创建定时器LOS\_SwtmrCreate。 - - 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器; - - 返回函数运行结果,成功或失败; - -3. 启动定时器LOS\_SwtmrStart。 -4. 获得软件定时器剩余Tick数LOS\_SwtmrTimeGet。 -5. 停止定时器LOS\_SwtmrStop。 -6. 删除定时器LOS\_SwtmrDelete。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口或操作。 ->- 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为0,且不允许修改 。 ->- 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数。例如:系统软件定时器多占用一个软件定时器资源数,那么用户能使用的软件定时器资源就会减少一个。 ->- 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源。 ->- 创建单次不自删除属性的定时器,用户需要调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 - -## 编程实例 - -### 实例描述 - -在下面的例子中,演示如下功能: - -1. 软件定时器创建、启动、删除、暂停、重启操作。 -2. 单次软件定时器,周期软件定时器使用方法。 - -### 示例代码 - -前提条件: - -- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMR配置项打开。 -- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMR\_ALIGN配置项关闭,示例代码中演示代码不涉及定时器对齐。 -- 配置好LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数。 -- 配置好OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度。 - -代码实现如下: - -``` -#include "los_swtmr.h" - -/* Timer count */ -UINT32 g_timerCount1 = 0; -UINT32 g_timerCount2 = 0; - -/* 任务ID */ -UINT32 g_testTaskId01; - -void Timer1_Callback(UINT32 arg) // 回调函数1 -{ - UINT32 tick_last1; - g_timerCount1++; - tick_last1=(UINT32)LOS_TickCountGet(); // 获取当前Tick数 - printf("g_timerCount1=%d, tick_last1=%d\n", g_timerCount1, tick_last1); -} - -void Timer2_Callback(UINT32 arg) // 回调函数2 -{ - UINT32 tick_last2; - tick_last2=(UINT32)LOS_TickCountGet(); - g_timerCount2++; - printf("g_timerCount2=%d tick_last2=%d\n", g_timerCount2, tick_last2); -} - -void Timer_example(void) -{ - UINT32 id1; // timer id - UINT32 id2; // timer id - UINT32 uwTick; - - /*创建单次软件定时器,Tick数为1000,启动到1000Tick数时执行回调函数1 */ - LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); - - /*创建周期性软件定时器,每100Tick数执行回调函数2 */ - LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); - printf("create Timer1 success\n"); - - LOS_SwtmrStart (id1); //启动单次软件定时器 - printf("start Timer1 sucess\n"); - - LOS_TaskDelay(200); //延时200Tick数 - LOS_SwtmrTimeGet(id1, &uwTick); // 获得单次软件定时器剩余Tick数 - printf("uwTick =%d\n", uwTick); - - LOS_SwtmrStop(id1); // 停止软件定时器 - printf("stop Timer1 sucess\n"); - - LOS_SwtmrStart(id1); - LOS_TaskDelay(1000); - - LOS_SwtmrDelete(id1); // 删除软件定时器 - printf("delete Timer1 sucess\n"); - - LOS_SwtmrStart(id2); // 启动周期性软件定时器 - printf("start Timer2\n"); - - LOS_TaskDelay(1000); - LOS_SwtmrStop(id2); - LOS_SwtmrDelete(id2); -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - - /* 锁任务调度 */ - LOS_TaskLock(); - - /* 创建任务1 */ - memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Timer_example; - task1.pcName = "TimerTsk"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("TimerTsk create failed.\n"); - return LOS_NOK; - } - - /* 解锁任务调度 */ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### 结果验证 - -编译烧录运行,输出结果如下: - -``` -create Timer1 success -start Timer1 sucess -uwTick =798 -stop Timer1 sucess -g_timerCount1=1, tick_last1=1208 -delete Timer1 sucess -start Timer2 -g_timerCount2=1 tick_last2=1313 -g_timerCount2=2 tick_last2=1413 -g_timerCount2=3 tick_last2=1513 -g_timerCount2=4 tick_last2=1613 -g_timerCount2=5 tick_last2=1713 -g_timerCount2=6 tick_last2=1813 -g_timerCount2=7 tick_last2=1913 -g_timerCount2=8 tick_last2=2013 -g_timerCount2=9 tick_last2=2113 -g_timerCount2=10 tick_last2=2213 -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" deleted file mode 100644 index ee4e2944bc774a1dd9cc59822734b6de9a1c723b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" +++ /dev/null @@ -1,306 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [结果验证](#section189023104457) - - -任务创建后,内核可以执行锁任务调度,解锁任务调度,挂起,恢复,延时等操作,同时也可以设置任务优先级,获取任务优先级。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的任务管理模块提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 任务管理模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建和删除任务

-

LOS_TaskCreateOnly

-

创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态。

-

LOS_TaskCreate

-

创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务。

-

LOS_TaskDelete

-

删除指定的任务。

-

控制任务状态

-

LOS_TaskResume

-

恢复挂起的任务,使该任务进入ready状态。

-

LOS_TaskSuspend

-

挂起指定的任务,然后切换任务

-

LOS_TaskDelay

-

任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态。传入参数为Tick数目。

-

LOS_Msleep

-

传入参数为毫秒数,转换为Tick数目,调用LOS_TaskDelay。

-

LOS_TaskYield

-

当前任务时间片设置为0,释放CPU,触发调度运行就绪任务队列中优先级最高的任务。

-

控制任务调度

-

LOS_TaskLock

-

锁任务调度,但任务仍可被中断打断。

-

LOS_TaskUnlock

-

解锁任务调度。

-

LOS_Schedule

-

触发任务调度。

-

控制任务优先级

-

LOS_CurTaskPriSet

-

设置当前任务的优先级。

-

LOS_TaskPriSet

-

设置指定任务的优先级。

-

LOS_TaskPriGet

-

获取指定任务的优先级。

-

获取任务信息

-

LOS_CurTaskIDGet

-

获取当前任务的ID。

-

LOS_NextTaskIDGet

-

获取任务就绪队列中优先级最高的任务的ID。

-

LOS_NewTaskIDGet

-

等同LOS_NextTaskIDGet。

-

LOS_CurTaskNameGet

-

获取当前任务的名称。

-

LOS_TaskNameGet

-

获取指定任务的名称。

-

LOS_TaskStatusGet

-

获取指定任务的状态。

-

LOS_TaskInfoGet

-

获取指定任务的信息,包括任务状态、优先级、任务栈大小、栈顶指针SP、任务入口函数、已使用的任务栈大小等。

-

LOS_TaskIsRunning

-

获取任务模块是否已经开始调度运行。

-

任务信息维测

-

LOS_TaskSwitchInfoGet

-

获取任务切换信息,需要开启宏LOSCFG_BASE_CORE_EXC_TSK_SWITCH。

-
- -## 开发流程 - -以创建任务为例,讲解开发流程。 - -1. 锁任务调度LOS\_TaskLock,防止高优先级任务调度。 -2. 创建任务LOS\_TaskCreate。 -3. 解锁任务LOS\_TaskUnlock,让任务按照优先级进行调度。 -4. 延时任务LOS\_TaskDelay,任务延时等待。 -5. 挂起指定的任务LOS\_TaskSuspend,任务挂起等待恢复操作。 -6. 恢复挂起的任务LOS\_TaskResume。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 执行Idle任务时,会对待回收链表中的任务控制块和任务栈进行回收。 ->- 任务名是指针,并没有分配空间,在设置任务名时,禁止将局部变量的地址赋值给任务名指针。 ->- 任务栈的大小按8字节大小对齐。确定任务栈大小的原则是,够用就行,多了浪费,少了任务栈溢出。 ->- 挂起当前任务时,如果已经锁任务调度,则无法挂起。 ->- Idle任务及软件定时器任务不能被挂起或者删除。 ->- 在中断处理函数中或者在锁任务的情况下,执行LOS\_TaskDelay会失败。 ->- 锁任务调度,并不关中断,因此任务仍可被中断打断。 ->- 锁任务调度必须和解锁任务调度配合使用。 ->- 设置任务优先级时可能会发生任务调度。 ->- 可配置的系统最大任务数是指:整个系统的任务总个数,而非用户能使用的任务个数。例如:系统软件定时器多占用一个任务资源,那么用户能使用的任务资源就会减少一个。 ->- LOS\_CurTaskPriSet和LOS\_TaskPriSet接口不能在中断中使用,也不能用于修改软件定时器任务的优先级。 ->- LOS\_TaskPriGet接口传入的task ID对应的任务未创建或者超过最大任务数,统一返回-1。 ->- 在删除任务时要保证任务申请的资源(如互斥锁、信号量等)已被释放。 - -## 编程实例 - -本实例介绍基本的任务操作方法,包含2个不同优先级任务的创建、任务延时、任务锁与解锁调度、挂起和恢复等操作,阐述任务优先级调度的机制以及各接口的应用。示例代码如下: - -``` -UINT32 g_taskHiId; -UINT32 g_taskLoId; -#define TSK_PRIOR_HI 4 -#define TSK_PRIOR_LO 5 - -UINT32 Example_TaskHi(VOID) -{ - UINT32 ret; - - printf("Enter TaskHi Handler.\n"); - - /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务(TaskLo任务) */ - ret = LOS_TaskDelay(100); - if (ret != LOS_OK) { - printf("Delay TaskHi Failed.\n"); - return LOS_NOK; - } - - /* 100个Ticks时间到了后,该任务恢复,继续执行 */ - printf("TaskHi LOS_TaskDelay Done.\n"); - - /* 挂起自身任务 */ - ret = LOS_TaskSuspend(g_taskHiId); - if (ret != LOS_OK) { - printf("Suspend TaskHi Failed.\n"); - return LOS_NOK; - } - printf("TaskHi LOS_TaskResume Success.\n"); - return ret; -} - -/* 低优先级任务入口函数 */ -UINT32 Example_TaskLo(VOID) -{ - UINT32 ret; - - printf("Enter TaskLo Handler.\n"); - - /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务 */ - ret = LOS_TaskDelay(100); - if (ret != LOS_OK) { - printf("Delay TaskLo Failed.\n"); - return LOS_NOK; - } - - printf("TaskHi LOS_TaskSuspend Success.\n"); - - /* 恢复被挂起的任务g_taskHiId */ - ret = LOS_TaskResume(g_taskHiId); - if (ret != LOS_OK) { - printf("Resume TaskHi Failed.\n"); - return LOS_NOK; - } - return ret; -} - -/* 任务测试入口函数,创建两个不同优先级的任务 */ -UINT32 Example_TskCaseEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S initParam; - - /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ - LOS_TaskLock(); - - printf("LOS_TaskLock() Success!\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; - initParam.usTaskPrio = TSK_PRIOR_HI; - initParam.pcName = "TaskHi"; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - - /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ - ret = LOS_TaskCreate(&g_taskHiId, &initParam); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - - printf("Example_TaskHi create Failed!\n"); - return LOS_NOK; - } - - printf("Example_TaskHi create Success!\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; - initParam.usTaskPrio = TSK_PRIOR_LO; - initParam.pcName = "TaskLo"; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - - /* 创建低优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ - ret = LOS_TaskCreate(&g_taskLoId, &initParam); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - printf("Example_TaskLo create Failed!\n"); - return LOS_NOK; - } - - printf("Example_TaskLo create Success!\n"); - - /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -LOS_TaskLock() Success! -Example_TaskHi create Success! -Example_TaskLo create Success! -Enter TaskHi Handler. -Enter TaskLo Handler. -TaskHi LOS_TaskDelay Done. -TaskHi LOS_TaskSuspend Success. -TaskHi LOS_TaskResume Success. -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-6.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-6.md" deleted file mode 100644 index 6869a792fd853689071ea77ccce8691aa24b9c8e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-6.md" +++ /dev/null @@ -1,194 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section896412438910) - - [示例代码](#section149077554912) - - [结果验证](#section4461439172017) - - -## 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

事件检测

-

LOS_EventPoll

-

根据eventID,eventMask(事件掩码),mode(事件读取模式),检查用户期待的事件是否发生。

-
须知:

当mode含LOS_WAITMODE_CLR,且用户期待的事件发生时,此时eventID中满足要求的事件会被清零,这种情况下eventID既是入参也是出参。其他情况eventID只作为入参。

-
-

初始化

-

LOS_EventInit

-

事件控制块初始化。

-

事件读

-

LOS_EventRead

-

读事件(等待事件),任务会根据timeOut(单位:tick)进行阻塞等待;

-

未读取到事件时,返回值为0;

-

正常读取到事件时,返回正值(事件发生的集合);

-

其他情况返回特定错误码。

-

事件写

-

LOS_EventWrite

-

写一个特定的事件到事件控制块。

-

事件清除

-

LOS_EventClear

-

根据events掩码,清除事件控制块中的事件。

-

事件销毁

-

LOS_EventDestroy

-

事件控制块销毁。

-
- -## 开发流程 - -事件的典型开发流程: - -1. 初始化事件控制块 -2. 阻塞读事件控制块 -3. 写入相关事件 -4. 阻塞任务被唤醒,读取事件并检查是否满足要求 -5. 处理事件控制块 -6. 事件控制块销毁 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 进行事件读写操作时,事件的第25位为保留位,不可以进行位设置。 ->- 对同一事件反复写入,算作一次写入。 - -## 编程实例 - -### 实例描述 - -示例中,任务Example\_TaskEntry创建一个任务Example\_Event,Example\_Event读事件阻塞,Example\_TaskEntry向该任务写事件。可以通过示例日志中打印的先后顺序理解事件操作时伴随的任务切换。 - -1. 在任务Example\_TaskEntry创建任务Example\_Event,其中任务Example\_Event优先级高于Example\_TaskEntry。 -2. 在任务Example\_Event中读事件0x00000001,阻塞,发生任务切换,执行任务Example\_TaskEntry。 -3. 在任务Example\_TaskEntry向任务Example\_Event写事件0x00000001,发生任务切换,执行任务Example\_Event。 -4. Example\_Event得以执行,直到任务结束。 -5. Example\_TaskEntry得以执行,直到任务结束。 - -### 示例代码 - -示例代码如下: - -``` -#include "los_event.h" -#include "los_task.h" -#include "securec.h" - -/* 任务ID */ -UINT32 g_testTaskId; - -/* 事件控制结构体 */ -EVENT_CB_S g_exampleEvent; - -/* 等待的事件类型 */ -#define EVENT_WAIT 0x00000001 - -/* 用例任务入口函数 */ -VOID Example_Event(VOID) -{ - UINT32 ret; - UINT32 event; - - /* 超时等待方式读事件,超时时间为100 ticks, 若100 ticks后未读取到指定事件,读事件超时,任务直接唤醒 */ - printf("Example_Event wait event 0x%x \n", EVENT_WAIT); - - event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, 100); - if (event == EVENT_WAIT) { - printf("Example_Event,read event :0x%x\n", event); - } else { - printf("Example_Event,read event timeout\n"); - } -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - - /* 事件初始化 */ - ret = LOS_EventInit(&g_exampleEvent); - if (ret != LOS_OK) { - printf("init event failed .\n"); - return -1; - } - - /* 创建任务 */ - (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; - task1.pcName = "EventTsk1"; - task1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId, &task1); - if (ret != LOS_OK) { - printf("task create failed.\n"); - return LOS_NOK; - } - - /* 写g_testTaskId 等待事件 */ - printf("Example_TaskEntry write event.\n"); - - ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); - if (ret != LOS_OK) { - printf("event write failed.\n"); - return LOS_NOK; - } - - /* 清标志位 */ - printf("EventMask:%d\n", g_exampleEvent.uwEventID); - LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); - printf("EventMask:%d\n", g_exampleEvent.uwEventID); - - /* 删除任务 */ - ret = LOS_TaskDelete(g_testTaskId); - if (ret != LOS_OK) { - printf("task delete failed.\n"); - return LOS_NOK; - } - - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -Example_Event wait event 0x1 -Example_TaskEntry write event. -Example_Event,read event :0x1 -EventMask:1 -EventMask:0 -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-8.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-8.md" deleted file mode 100644 index a194bc9e585299c70eae4256ca0e0877f4e226c5..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-8.md" +++ /dev/null @@ -1,205 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section1426719434114) - - [实例描述](#section896412438910) - - [示例代码](#section149077554912) - - [结果验证](#section2059413981311) - - -## 接口说明 - -**表 1** 互斥锁模块接口 - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

互斥锁的创建和删除

-

LOS_MuxCreate

-

创建互斥锁

-

LOS_MuxDelete

-

删除指定的互斥锁

-

互斥锁的申请和释放

-

LOS_MuxPend

-

申请指定的互斥锁

-

LOS_MuxPost

-

释放指定的互斥锁

-
- -## 开发流程 - -互斥锁典型场景的开发流程: - -1. 创建互斥锁LOS\_MuxCreate。 -2. 申请互斥锁LOS\_MuxPend。 - - 申请模式有三种:无阻塞模式、永久阻塞模式、定时阻塞模式。 - - - 无阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有任务持有,或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务,则申请成功。 - - 永久阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该互斥锁,阻塞任务才会重新得以执行。 - - 定时阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该互斥锁,或者用户指定时间超时后,阻塞任务才会重新得以执行。 - -3. 释放互斥锁LOS\_MuxPost。 - - 如果有任务阻塞于指定互斥锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; - - 如果没有任务阻塞于指定互斥锁,则互斥锁释放成功。 - -4. 删除互斥锁LOS\_MuxDelete。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 两个任务不能对同一把互斥锁加锁。如果某任务对已被持有的互斥锁加锁,则该任务会被挂起,直到持有该锁的任务对互斥锁解锁,才能执行对这把互斥锁的加锁操作。 ->- 互斥锁不能在中断服务程序中使用。 ->- LiteOS-M内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。 ->- 持有互斥锁的过程中,不得再调用LOS\_TaskPriSet等接口更改持有互斥锁任务的优先级。 - -## 编程实例 - -### 实例描述 - -本实例实现如下流程。 - -1. 任务Example\_TaskEntry创建一个互斥锁,锁任务调度,创建两个任务Example\_MutexTask1、Example\_MutexTask2。Example\_MutexTask2优先级高于Example\_MutexTask1,解锁任务调度。 -2. Example\_MutexTask2被调度,以永久阻塞模式申请互斥锁,并成功获取到该互斥锁,然后任务休眠100Tick,Example\_MutexTask2挂起,Example\_MutexTask1被唤醒。 -3. Example\_MutexTask1以定时阻塞模式申请互斥锁,等待时间为10Tick,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。10Tick超时时间到达后,Example\_MutexTask1被唤醒,以永久阻塞模式申请互斥锁,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。 -4. 100Tick休眠时间到达后,Example\_MutexTask2被唤醒, 释放互斥锁,唤醒Example\_MutexTask1。Example\_MutexTask1成功获取到互斥锁后,释放,删除互斥锁。 - -### 示例代码 - -示例代码如下: - -``` -#include -#include "los_mux.h" - -/* 互斥锁句柄id */ -UINT32 g_testMux; -/* 任务ID */ -UINT32 g_testTaskId01; -UINT32 g_testTaskId02; - -VOID Example_MutexTask1(VOID) -{ - UINT32 ret; - - printf("task1 try to get mutex, wait 10 ticks.\n"); - /* 申请互斥锁 */ - ret = LOS_MuxPend(g_testMux, 10); - - if (ret == LOS_OK) { - printf("task1 get mutex g_testMux.\n"); - /* 释放互斥锁 */ - LOS_MuxPost(g_testMux); - return; - } - if (ret == LOS_ERRNO_MUX_TIMEOUT ) { - printf("task1 timeout and try to get mutex, wait forever.\n"); - /* 申请互斥锁 */ - ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); - if (ret == LOS_OK) { - printf("task1 wait forever, get mutex g_testMux.\n"); - /* 释放互斥锁 */ - LOS_MuxPost(g_testMux); - /* 删除互斥锁 */ - LOS_MuxDelete(g_testMux); - printf("task1 post and delete mutex g_testMux.\n"); - return; - } - } - return; -} - -VOID Example_MutexTask2(VOID) -{ - printf("task2 try to get mutex, wait forever.\n"); - /* 申请互斥锁 */ - (VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); - - printf("task2 get mutex g_testMux and suspend 100 ticks.\n"); - - /* 任务休眠100Ticks */ - LOS_TaskDelay(100); - - printf("task2 resumed and post the g_testMux\n"); - /* 释放互斥锁 */ - LOS_MuxPost(g_testMux); - return; -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - TSK_INIT_PARAM_S task2; - - /* 创建互斥锁 */ - LOS_MuxCreate(&g_testMux); - - /* 锁任务调度 */ - LOS_TaskLock(); - - /* 创建任务1 */ - memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; - task1.pcName = "MutexTsk1"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("task1 create failed.\n"); - return LOS_NOK; - } - - /* 创建任务2 */ - memset(&task2, 0, sizeof(TSK_INIT_PARAM_S)); - task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; - task2.pcName = "MutexTsk2"; - task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task2.usTaskPrio = 4; - ret = LOS_TaskCreate(&g_testTaskId02, &task2); - if (ret != LOS_OK) { - printf("task2 create failed.\n"); - return LOS_NOK; - } - - /* 解锁任务调度 */ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -task2 try to get mutex, wait forever. -task2 get mutex g_testMux and suspend 100 ticks. -task1 try to get mutex, wait 10 ticks. -task1 timeout and try to get mutex, wait forever. -task2 resumed and post the g_testMux -task1 wait forever, get mutex g_testMux. -task1 post and delete mutex g_testMux. -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100644 index c97dfdd3f24126cbb537d98f53e59a4786fdbc13..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,130 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section11841123033618) -- [编程实例](#section460018317164) - - [结果验证](#section1048572415182) - - -当产生中断请求时,CPU暂停当前的任务,转而去响应外设请求。用户可以根据需要注册对应的中断处理程序,指定CPU响应中断请求时所执行的具体操作。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的中断模块提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 中断模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建、删除中断

-

HalHwiCreate

-

中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,会调用该中断处理程序。

-

HalHwiDelete

-

根据指定的中断号,删除中断。

-

打开、关闭中断

-

LOS_IntUnLock

-

开中断,使能当前处理器所有中断响应。

-

LOS_IntLock

-

关中断,关闭当前处理器所有中断响应。

-

LOS_IntRestore

-

恢复到使用LOS_IntLock、LOS_IntUnLock操作之前的中断状态。

-
- -## 开发流程 - -1. 调用中断创建接口HalHwiCreate创建中断。 -2. 调用TestHwiTrigger接口触发指定中断(该接口在测试套中定义,通过写中断控制器的相关寄存器模拟外部中断,一般的外设设备,不需要执行这一步)。 -3. 调用HalHwiDelete接口删除指定中断,此接口根据实际情况使用,判断是否需要删除中断。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 根据具体硬件,配置支持的最大中断数及可设置的中断优先级个数。 ->- 中断处理程序耗时不能过长,否则会影响CPU对中断的及时响应。 ->- 中断响应过程中不能直接、间接执行引起调度的LOS\_Schedule等函数。 ->- 中断恢复LOS\_IntRestore\(\)的入参必须是与之对应的LOS\_IntLock\(\)的返回值(即关中断之前的CPSR值)。Cortex-M系列处理器中0-15中断为内部使用,因此不建议用户去申请和创建。 - -## 编程实例 - -本实例实现如下功能: - -1. 创建中断。 -2. 触发中断。 -3. 删除中断。 - -代码实现如下,演示如何创建中断和删除中断,当指定的中断号HWI\_NUM\_TEST产生中断时,会调用中断处理函数: - -``` -#include "los_interrupt.h" - -/*创建中断*/ -#define HWI_NUM_TEST 7 - -STATIC VOID HwiUsrIrq(VOID) -{ - printf("in the func HwiUsrIrq \n"); -} - -static UINT32 Example_Interrupt(VOID) -{ - UINT32 ret; - HWI_PRIOR_T hwiPrio = 3; - HWI_MODE_T mode = 0; - HWI_ARG_T arg = 0; - - /*创建中断*/ - ret = HalHwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, arg); - if(ret == LOS_OK){ - printf("Hwi create success!\n"); - } else { - printf("Hwi create failed!\n"); - return LOS_NOK; - } - - /* 延时50个Ticks, 当有硬件中断发生时,会调用函数HwiUsrIrq*/ - LOS_TaskDelay(50); - - /*删除中断*/ - ret = HalHwiDelete(HWI_NUM_TEST); - if(ret == LOS_OK){ - printf("Hwi delete success!\n"); - } else { - printf("Hwi delete failed!\n"); - return LOS_NOK; - } - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -Hwi create success! -Hwi delete success!. -``` - diff --git "a/zh-cn/device-dev/kernel/\345\274\202\345\270\270\350\260\203\346\265\213.md" "b/zh-cn/device-dev/kernel/\345\274\202\345\270\270\350\260\203\346\265\213.md" deleted file mode 100644 index 8e9a050102de2a7721f962338b3d4420498c3d4b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\274\202\345\270\270\350\260\203\346\265\213.md" +++ /dev/null @@ -1,329 +0,0 @@ -# 异常调测 - -- [基本概念](#section2741911123412) -- [运行机制](#section16618124317346) -- [接口说明](#section16111931351) -- [使用指导](#section16317163520350) - - [开发流程](#section13457839133618) - - [定位流程](#section197332323815) - - -## 基本概念 - -OpenHarmony LiteOS-M提供异常接管调测手段,帮助开发者定位分析问题。异常接管是操作系统对运行期间发生的异常情况进行处理的一系列动作,例如打印异常发生时异常类型、发生异常时的系统状态、当前函数的调用栈信息、CPU现场信息、任务调用堆栈等信息。 - -## 运行机制 - -栈帧用于保存函数调用过程中的函数参数、变量、返回值等信息。调用函数时,会创建子函数的栈帧,同时将函数入参、局部变量、寄存器入栈。栈帧从高地址向低地址生长。以ARM32 CPU架构为例,每个栈帧中都会保存PC、LR、SP和FP寄存器的历史值。LR链接寄存器(Link Register)指向函数的返回地址,FP帧指针寄存器(Frame Point)指向当前函数的父函数的栈帧起始地址。利用FP寄存器可以得到父函数的栈帧,从栈帧中获取父函数的FP,就可以得到祖父函数的栈帧,以此类推,可以追溯程序调用栈,得到函数间的调用关系。 - -当系统发生异常时,系统打印异常函数的栈帧中保存的寄存器内容,以及父函数、祖父函数的栈帧中的LR链接寄存器、FP帧指针寄存器内容,用户就可以据此追溯函数间的调用关系,定位异常原因。 - -堆栈分析原理如下图所示,实际堆栈信息根据不同CPU架构有所差异,此处仅做示意。 - -**图 1** 堆栈分析原理示意图 -![](figures/堆栈分析原理示意图.png "堆栈分析原理示意图") - -图中不同颜色的寄存器表示不同的函数。可以看到函数调用过程中,寄存器的保存。通过FP寄存器,栈回溯到异常函数的父函数,继续按照规律对栈进行解析,推出函数调用关系,方便用户定位问题。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的回溯栈模块提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 回溯栈模块接口 - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

回溯栈接口

-

LOS_BackTrace

-

打印调用处的函数调用栈关系。

-

LOS_RecordLR

-

在无法打印的场景,用该接口获取调用处的函数调用栈关系。

-
- -## 使用指导 - -### 开发流程 - -开启异常调测的典型流程如下: - -1. 配置异常接管相关宏。 - - 需要在target\_config.h头文件中修改配置: - - - - - - - - - - - - - - - - -

配置项

-

含义

-

设置值

-

LOSCFG_BACKTRACE_DEPTH

-

函数调用栈深度,默认15层

-

15

-

LOSCFG_BACKTRACE_TYPE

-

回溯栈类型:

-

0:表示关闭该功能;

-

1:表示支持Cortex-m系列硬件的函数调用栈解析;

-

2:表示用于Risc-v系列硬件的函数调用栈解析;

-

根据工具链类型设置1或2

-
- - -1. 使用示例中有问题的代码,编译、运行工程,在串口终端中查看异常信息输出。示例代码模拟异常代码,实际产品开发时使用异常调测机制定位异常问题。 - - 本示例演示异常输出,包含1个任务,该任务入口函数模拟若干函数调用,最终调用一个模拟异常的函数。代码实现如下: - - ``` - #include - #include "los_config.h" - #include "los_interrupt.h" - #include "los_task.h" - - UINT32 g_taskExcId; - #define TSK_PRIOR 4 - - /* 模拟异常函数 */ - - UINT32 Get_Result_Exception_0(UINT16 dividend){ - UINT32 divisor = 0; - UINT32 result = dividend / divisor; - return result; - } - - UINT32 Get_Result_Exception_1(UINT16 dividend){ - return Get_Result_Exception_0(dividend); - } - - UINT32 Get_Result_Exception_2(UINT16 dividend){ - return Get_Result_Exception_1(dividend); - } - - UINT32 Example_Exc(VOID) - { - UINT32 ret; - - printf("Enter Example_Exc Handler.\r\n"); - - /* 模拟函数调用 */ - ret = Get_Result_Exception_2(TSK_PRIOR); - printf("Divided result =%u.\r\n", ret); - - printf("Exit Example_Exc Handler.\r\n"); - return ret; - } - - - /* 任务测试入口函数,创建一个会发生异常的任务 */ - UINT32 Example_Exc_Entry(VOID) - { - UINT32 ret; - TSK_INIT_PARAM_S initParam; - - /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ - LOS_TaskLock(); - - printf("LOS_TaskLock() Success!\r\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Exc; - initParam.usTaskPrio = TSK_PRIOR; - initParam.pcName = "Example_Exc"; - initParam.uwStackSize = LOSCFG_SECURE_STACK_DEFAULT_SIZE; - /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ - ret = LOS_TaskCreate(&g_taskExcId, &initParam); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - - printf("Example_Exc create Failed!\r\n"); - return LOS_NOK; - } - - printf("Example_Exc create Success!\r\n"); - - /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ - LOS_TaskUnlock(); - - return LOS_OK; - } - ``` - - -1. 上述代码串口终端输出异常信息如下: - - ``` - entering kernel init... - LOS_TaskLock() Success! - Example_Exc create Success! - Entering scheduler - Enter Example_Exc Handler. - *************Exception Information************** - Type = 10 - ThrdPid = 4 - Phase = exc in task - FaultAddr = 0xabababab - Current task info: - Task name = Example_Exc - Task ID = 4 - Task SP = 0x200051ac - Task ST = 0x20004ff0 - Task SS = 0x200 - Exception reg dump: - PC = 0x80037da - LR = 0x80037fe - SP = 0x20005190 - R0 = 0x4 - R1 = 0x40 - R2 = 0x4 - R3 = 0x0 - R4 = 0x4040404 - R5 = 0x5050505 - R6 = 0x6060606 - R7 = 0x20005190 - R8 = 0x8080808 - R9 = 0x9090909 - R10 = 0x10101010 - R11 = 0x11111111 - R12 = 0x12121212 - PriMask = 0x0 - xPSR = 0x41000000 - ----- backtrace start ----- - backtrace 0 -- lr = 0x800381a - backtrace 1 -- lr = 0x8003836 - backtrace 2 -- lr = 0x8005a4e - backtrace 3 -- lr = 0x8000494 - backtrace 4 -- lr = 0x8008620 - backtrace 5 -- lr = 0x800282c - backtrace 6 -- lr = 0x80008a0 - backtrace 7 -- lr = 0x80099f8 - backtrace 8 -- lr = 0x800a01a - backtrace 9 -- lr = 0x800282c - backtrace 10 -- lr = 0x80008a0 - backtrace 11 -- lr = 0x80099f8 - backtrace 12 -- lr = 0x8009bf0 - backtrace 13 -- lr = 0x8009c52 - backtrace 14 -- lr = 0x80099aa - ----- backtrace end ----- - - TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID name - --- -------- -------- --------- ---------- ---------- ---------- --------- ----- ---- - 0 0 Pend 0x2d0 0x104 0x200029bc 0x200027f0 0x0 0xffff Swt_Task - 1 31 Ready 0x500 0x44 0x20002f84 0x20002ac8 0x0 0xffff IdleCore000 - 2 6 Ready 0x1000 0x44 0x20003f94 0x20002fd8 0x0 0xffff TaskSampleEntry1 - 3 7 Ready 0x1000 0x44 0x20004f9c 0x20003fe0 0x0 0xffff TaskSampleEntry2 - 4 4 Running 0x200 0xec 0x200051ac 0x20004ff0 0x0 0xffff Example_Exc - - OS exception NVIC dump: - interrupt enable register, base address: 0xe000e100, size: 0x20 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt pending register, base address: 0xe000e200, size: 0x20 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt active register, base address: 0xe000e300, size: 0x20 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt priority register, base address: 0xe000e400, size: 0xf0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt exception register, base address: 0xe000ed18, size: 0xc - 0x0 0x0 0xf0f00000 - interrupt shcsr register, base address: 0xe000ed24, size: 0x4 - 0x70008 - interrupt control register, base address: 0xe000ed04, size: 0x4 - 0x400f806 - - memory pools check: - system heap memcheck over, all passed! - memory pool check end! - ``` - - -### 定位流程 - -异常接管一般的定位步骤如下: - -1. 打开编译后生成的镜像反汇编(asm)文件。如果默认没有生成,可以使用objdump工具生成,命令为: - - ``` - arm-none-eabi-objdump -S -l XXX.elf - ``` - - -1. 搜索PC指针(指向当前正在执行的指令)在asm中的位置,找到发生异常的函数。 - - PC地址指向发生异常时程序正在执行的指令。在当前执行的二进制文件对应的asm文件中,查找PC值0x80037da,找到当前CPU正在执行的指令行,反汇编如下所示: - - ``` - UINT32 Get_Result_Exception_0(UINT16 dividend){ - 80037c8: b480 push {r7} - 80037ca: b085 sub sp, #20 - 80037cc: af00 add r7, sp, #0 - 80037ce: 4603 mov r3, r0 - 80037d0: 80fb strh r3, [r7, #6] - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:10 - UINT32 divisor = 0; - 80037d2: 2300 movs r3, #0 - 80037d4: 60fb str r3, [r7, #12] - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:11 - UINT32 result = dividend / divisor; - 80037d6: 88fa ldrh r2, [r7, #6] - 80037d8: 68fb ldr r3, [r7, #12] - 80037da: fbb2 f3f3 udiv r3, r2, r3 - 80037de: 60bb str r3, [r7, #8] - ``` - - -1. 可以看到: - 1. 异常时CPU正在执行的指令是udiv r3, r2, r3,其中r3取值为0,导致发生除零异常。 - 2. 异常发生在函数Get\_Result\_Exception\_0中。 - -2. 根据LR值查找异常函数的父函数。 - - 包含LR值0x80037fe的反汇编如下所示: - - ``` - 080037ec : - Get_Result_Exception_1(): - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:15 - UINT32 Get_Result_Exception_1(UINT16 dividend){ - 80037ec: b580 push {r7, lr} - 80037ee: b082 sub sp, #8 - 80037f0: af00 add r7, sp, #0 - 80037f2: 4603 mov r3, r0 - 80037f4: 80fb strh r3, [r7, #6] - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:16 - return Get_Result_Exception_0(dividend); - 80037f6: 88fb ldrh r3, [r7, #6] - 80037f8: 4618 mov r0, r3 - 80037fa: f7ff ffe5 bl 80037c8 - 80037fe: 4603 mov r3, r0 - ``` - - -1. LR值80037fe上一行是bl 80037c8 ,此处调用了异常函数,调用异常函数的父函数为Get\_Result\_Exception\_1\(\)。 -2. 重复步骤3,解析异常信息中backtrace start至backtrace end之间的LR值,得到调用产生异常的函数调用栈关系,找到异常原因。 - diff --git "a/zh-cn/device-dev/kernel/\345\277\253\351\200\237\345\205\245\351\227\250.md" "b/zh-cn/device-dev/kernel/\345\277\253\351\200\237\345\205\245\351\227\250.md" deleted file mode 100644 index 53ddc75318ff70d0ffed93acc947c9c1eccd6723..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\345\277\253\351\200\237\345\205\245\351\227\250.md" +++ /dev/null @@ -1,47 +0,0 @@ -# 快速入门 - -- [搭建开发环境](#section157851447151716) -- [获取OpenHarmony源码](#section381985201816) -- [获取示例工程源码](#section204717216181) -- [编译运行](#section9772514181917) - -OpenHarmony LiteOS-M内核的编译构建系统是一个基于gn和ninja的组件化构建系统,支持按组件配置、裁剪和拼装,按需构建出定制化的产品。编译构建系统的详细信息可以参考[编译构建概述](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BA%E6%A6%82%E8%BF%B0.md)。本文主要介绍如何基于gn和ninja编译LiteOS-M工程。 - -## 搭建开发环境 - -在搭建各个开发板环境前,需要完成OpenHarmony系统基础环境搭建。系统基础环境主要是指OpenHarmony的编译环境和开发环境,详细介绍请参考官方站点[搭建系统基础环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/%E6%90%AD%E5%BB%BA%E7%B3%BB%E7%BB%9F%E7%8E%AF%E5%A2%83.md)。开发者需要根据环境搭建文档,完成下述软件的安装:Python3.7+、gn、ninja、hb。对于LiteOS-M内核,还需要安装ARM GCC编译工具链。 - -## 获取OpenHarmony源码 - -开发者需要在Linux服务器上通过Git克隆获取OpenHarmony最新源码,详细的源码获取方式,请见[源码获取](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/%E6%BA%90%E7%A0%81%E8%8E%B7%E5%8F%96.md)。获取OpenHarmony完整仓代码后,假设克隆目录为\~/openHarmony。 - -## 获取示例工程源码 - -以开发板Nucleo-F767Zi为例,演示如何编译运行OpenHarmony LiteOS-M内核工程。在本地目录,执行下述命令克隆示例代码。 - -``` -git clone https://gitee.com/harylee/nucleo_f767zi.git -``` - -假设克隆到的代码目录为\~/nucleo\_f767zi。 执行如下命令把代码目录的device、vendor目录复制到openHarmony工程的相应目录。 - -``` -cp -r ~/nucleo_f767zi/device/st ~/openHarmony/device/st -cp -r ~/nucleo_f767zi/vendor/st ~/openHarmony/vendor/st -``` - -关于示例代码目录的说明,可以参考资料站点[板级目录规范](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E7%A7%BB%E6%A4%8D%E6%A6%82%E8%BF%B0-0.md#section6204129143013)。如果需要自行移植开发板,请参考[板级系统移植](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E6%9D%BF%E7%BA%A7%E7%B3%BB%E7%BB%9F%E7%A7%BB%E6%A4%8D.md)。 - -## 编译运行 - -编译运行前,把交叉编译工具链bin目录配置到PATH环境变量中或者在device/st/nucleo\_f767zi/liteos\_m/config.gni文件中把board\_toolchain\_path配置项设置为交叉编译工具链bin目录。 在OpenHarmony根目录,执行hb set设置产品路径,选择nucleo\_f767zi产品,然后执行hb build开启编译。如下: - -``` -user@dev:~/OpenHarmony$ hb set -[OHOS INFO] Input code path: # 直接按回车,然后选择nucleo_f767zi产品即可 -OHOS Which product do you need? nucleo_f767zi@st -user@dev:~/OpenHarmony$ hb build -``` - -最终的镜像生成在\~/openHarmony/out/nucleo\_f767zi/目录中,通过STM32 ST-LINK Utility软件将镜像文件下载至单板查看运行效果。 - diff --git "a/zh-cn/device-dev/kernel/\346\211\251\345\261\225\347\273\204\344\273\266.md" "b/zh-cn/device-dev/kernel/\346\211\251\345\261\225\347\273\204\344\273\266.md" deleted file mode 100644 index dcfc826616e437211372c13a415dcc6b3657ae63..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\211\251\345\261\225\347\273\204\344\273\266.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 扩展组件 - -- **[C++支持](C++支持.md)** - -- **[CPUP](CPUP.md)** - -- **[文件系统](文件系统-19.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\345\221\275\344\273\244.md" "b/zh-cn/device-dev/kernel/\346\226\207\344\273\266\345\221\275\344\273\244.md" deleted file mode 100755 index c1735a0278573df6d279873637fc764342e644e8..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\345\221\275\344\273\244.md" +++ /dev/null @@ -1,45 +0,0 @@ -# 文件命令 - -- **[cat](cat.md)** - -- **[cd](cd.md)** - -- **[chgrp](chgrp.md)** - -- **[chmod](chmod.md)** - -- **[chown](chown.md)** - -- **[cp](cp.md)** - -- **[format](format.md)** - -- **[ls](ls.md)** - -- **[lsfd](lsfd.md)** - -- **[mkdir](mkdir.md)** - -- **[mount](mount.md)** - -- **[partinfo](partinfo.md)** - -- **[partition](partition.md)** - -- **[pwd](pwd.md)** - -- **[rm](rm.md)** - -- **[rmdir](rmdir.md)** - -- **[statfs](statfs.md)** - -- **[sync](sync.md)** - -- **[touch](touch.md)** - -- **[writeproc](writeproc.md)** - -- **[umount](umount.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-19.md" "b/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-19.md" deleted file mode 100644 index ba10ab39c51ce9917ccc7a664e4b13c3e7842824..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-19.md" +++ /dev/null @@ -1,204 +0,0 @@ -# 文件系统 - -当前支持的文件系统有FATFS与LittleFS,支持的功能如下表所示: - -**表 1** ****功能列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

FATFS

-

LITTELFS

-

文件操作

-

open

-

打开文件

-

支持

-

支持

-

close

-

关闭文件

-

支持

-

支持

-

read

-

读取文件内容

-

支持

-

支持

-

write

-

往文件写入内容

-

支持

-

支持

-

lseek

-

设置文件偏移位置

-

支持

-

支持

-

unlink

-

删除文件

-

支持

-

支持

-

rename

-

重命名文件

-

支持

-

支持

-

fstat

-

通过文件句柄获取文件信息

-

支持

-

支持

-

stat

-

通过文件路径名获取文件信息

-

支持

-

支持

-

fsync

-

文件内容刷入存储设备

-

支持

-

支持

-

目录操作

-

mkdir

-

创建目录

-

支持

-

支持

-

opendir

-

打开目录

-

支持

-

支持

-

readdir

-

读取目录项内容

-

支持

-

支持

-

closedir

-

关闭目录

-

支持

-

支持

-

rmdir

-

删除目录

-

支持

-

支持

-

分区操作

-

mount

-

分区挂载

-

支持

-

支持

-

umount

-

分区卸载

-

支持

-

支持

-

umount2

-

分区卸载,可通过MNT_FORCE参数进行强制卸载

-

支持

-

不支持

-

statfs

-

获取分区信息

-

支持

-

不支持

-
- -- **[FAT](FAT-20.md)** - -- **[LittleFS](LittleFS.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237.md" "b/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237.md" deleted file mode 100644 index b17821e62df9a268e8b4328bafafe90bba795d3b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237.md" +++ /dev/null @@ -1,54 +0,0 @@ -# 文件系统 - -OpenHarmony轻内核支持的文件系统有:VFS(虚拟文件系统)、NFS、RAMFS、FAT、JFFS2。 - -**各个文件系统功能概述:** - -**表 1** 文件系统功能概述 - - - - - - - - - - - - - - - - - - - - - - -

文件系统

-

功能特点概述

-

VFS

-

VFS是Virtual File System(虚拟文件系统)的缩写,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层,为用户提供统一的类Unix文件操作接口。

-

NFS

-

NFS是Network File System(网络文件系统)的缩写。它最大的功能是可以通过网络,让不同的机器、不同的操作系统彼此分享其他用户的文件。

-

RAMFS

-

RAMFS是一种基于RAM的文件系统。RAMFS文件系统把所有的文件都放在RAM中,所以读/写操作发生在RAM中,避免了对存储器的读写损耗,也提高了数据读写速度。RAMFS是基于RAM的动态文件系统的一种存储缓冲机制。

-

FAT

-

FAT文件系统是File Allocation Table(文件配置表)的简称,有FAT12、FAT16、FAT32。在可移动存储介质(U盘、SD卡、移动硬盘等)上多使用FAT文件系统,使设备与Windows、Linux等桌面系统之间保持很好的兼容性。

-

JFFS2

-

JFFS2是Journalling Flash File System Version 2(日志文件系统)的缩写,是MTD设备上的日志型文件系统。主要应用于对NOR_FLASH闪存的文件管理。OpenHarmony内核的JFFS2支持多分区。

-
- -- **[VFS](VFS.md)** - -- **[NFS](NFS.md)** - -- **[RAMFS](RAMFS.md)** - -- **[FAT](FAT.md)** - -- **[JFFS2](JFFS2.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\227\266\351\227\264\347\256\241\347\220\206.md" "b/zh-cn/device-dev/kernel/\346\227\266\351\227\264\347\256\241\347\220\206.md" deleted file mode 100644 index 967a229499e4473b06fadcc91807e5a91cab2e66..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\227\266\351\227\264\347\256\241\347\220\206.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 时间管理 - -- **[基本概念](基本概念-13.md)** - -- **[开发指导](开发指导-14.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223-0.md" "b/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223-0.md" deleted file mode 100755 index a365148450986901a04ff48891283a2ab4b8ded8..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223-0.md" +++ /dev/null @@ -1,197 +0,0 @@ -# 标准库 - -- [框架流程](#section1247343413257) -- [操作实例](#section4807125622614) -- [常见问题](#section1219455217277) - -OpenHarmony内核OpenHarmony使用**musl libc**库,支持标准POSIX接口,开发者可基于POSIX标准接口开发内核之上的组件及应用。 - -## 框架流程 - -**图 1** POSIX接口框架 -![](figures/POSIX接口框架.png "POSIX接口框架") - -**musl libc**库支持POSIX标准,涉及的系统调用相关接口由OpenHarmony内核适配支持 ,以满足接口对外描述的功能要求。 - -标准库支持接口的详细情况请参考C库的API文档,其中也涵盖了与POSIX标准之间的差异说明。 - -## 操作实例 - -在本示例中,主线程创建了THREAD\_NUM个子线程,每个子线程启动后等待被主线程唤醒,主线程成功唤醒所有子线程后,子线程继续执行直至生命周期结束,同时主线程通过pthread\_join方法等待所有线程执行结束。 - -``` -#include -#include -#include - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#define THREAD_NUM 3 -int g_startNum = 0; /* 启动的线程数 */ -int g_wakenNum = 0; /* 唤醒的线程数 */ - -struct testdata { - pthread_mutex_t mutex; - pthread_cond_t cond; -} g_td; - -/* - * 子线程入口函数 - */ -static void *ChildThreadFunc(void *arg) -{ - int rc; - pthread_t self = pthread_self(); - - /* 获取mutex锁 */ - rc = pthread_mutex_lock(&g_td.mutex); - if (rc != 0) { - printf("ERROR:take mutex lock failed, error code is %d!\n", rc); - goto EXIT; - } - - /* g_startNum计数加一,用于统计已经获得mutex锁的子线程个数 */ - g_startNum++; - - /* 等待cond条件变量 */ - rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); - if (rc != 0) { - printf("ERROR: pthread condition wait failed, error code is %d!\n", rc); - (void)pthread_mutex_unlock(&g_td.mutex); - goto EXIT; - } - - /* 尝试获取mutex锁,正常场景,此处无法获取锁 */ - rc = pthread_mutex_trylock(&g_td.mutex); - if (rc == 0) { - printf("ERROR: mutex gets an abnormal lock!\n"); - goto EXIT; - } - - /* g_wakenNum计数加一,用于统计已经被cond条件变量唤醒的子线程个数 */ - g_wakenNum++; - - /* 释放mutex锁 */ - rc = pthread_mutex_unlock(&g_td.mutex); - if (rc != 0) { - printf("ERROR: mutex release failed, error code is %d!\n", rc); - goto EXIT; - } -EXIT: - return NULL; -} - -static int testcase(void) -{ - int i, rc; - pthread_t thread[THREAD_NUM]; - - /* 初始化mutex锁 */ - rc = pthread_mutex_init(&g_td.mutex, NULL); - if (rc != 0) { - printf("ERROR: mutex init failed, error code is %d!\n", rc); - goto ERROROUT; - } - - /* 初始化cond条件变量 */ - rc = pthread_cond_init(&g_td.cond, NULL); - if (rc != 0) { - printf("ERROR: pthread condition init failed, error code is %d!\n", rc); - goto ERROROUT; - } - - /* 批量创建THREAD_NUM个子线程 */ - for (i = 0; i < THREAD_NUM; i++) { - rc = pthread_create(&thread[i], NULL, ChildThreadFunc, NULL); - if (rc != 0) { - printf("ERROR: pthread create failed, error code is %d!\n", rc); - goto ERROROUT; - } - } - - /* 等待所有子线程都完成mutex锁的获取 */ - while (g_startNum < THREAD_NUM) { - usleep(100); - } - - /* 获取mutex锁,确保所有子线程都阻塞在pthread_cond_wait上 */ - rc = pthread_mutex_lock(&g_td.mutex); - if (rc != 0) { - printf("ERROR: mutex lock failed, error code is %d\n", rc); - goto ERROROUT; - } - - /* 释放mutex锁 */ - rc = pthread_mutex_unlock(&g_td.mutex); - if (rc != 0) { - printf("ERROR: mutex unlock failed, error code is %d!\n", rc); - goto ERROROUT; - } - - for (int j = 0; j < THREAD_NUM; j++) { - /* 在cond条件变量上广播信号 */ - rc = pthread_cond_signal(&g_td.cond); - if (rc != 0) { - printf("ERROR: pthread condition failed, error code is %d!\n", rc); - goto ERROROUT; - } - } - - sleep(1); - - /* 检查是否所有子线程都已被唤醒 */ - if (g_wakenNum != THREAD_NUM) { - printf("ERROR: not all threads awaken, only %d thread(s) awaken!\n", g_wakenNum); - goto ERROROUT; - } - - /* join所有子线程,即等待其结束 */ - for (i = 0; i < THREAD_NUM; i++) { - rc = pthread_join(thread[i], NULL); - if (rc != 0) { - printf("ERROR: pthread join failed, error code is %d!\n", rc); - goto ERROROUT; - } - } - - /* 销毁cond条件变量 */ - rc = pthread_cond_destroy(&g_td.cond); - if (rc != 0) { - printf("ERROR: pthread condition destroy failed, error code is %d!\n", rc); - goto ERROROUT; - } - return 0; -ERROROUT: - return -1; -} - -/* - * 示例代码主函数 - */ -int main(int argc, char *argv[]) -{ - int rc; - - /* 启动测试函数 */ - rc = testcase(); - if (rc != 0) { - printf("ERROR: testcase failed!\n"); - } - - return 0; -} -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ -``` - -## 常见问题 - -无。 - diff --git "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223.md" "b/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223.md" deleted file mode 100755 index 56f2c7aa1b5ffa7d292a929f310373364a55d09c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 标准库 - -- **[标准库](标准库-0.md)** - -- **[与Linux标准库的差异](与Linux标准库的差异.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223\346\224\257\346\214\201.md" "b/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223\346\224\257\346\214\201.md" deleted file mode 100644 index 7522c305c5e44955578700d055f5320dd744d90c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\345\272\223\346\224\257\346\214\201.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 标准库支持 - -- **[CMSIS支持](CMSIS支持.md)** - -- **[POSIX支持](POSIX支持.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\347\263\273\347\273\237\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\346\240\207\345\207\206\347\263\273\347\273\237\345\206\205\346\240\270.md" deleted file mode 100644 index 5911c5e037af1c64615d90c915a8d4a5defe1761..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\240\207\345\207\206\347\263\273\347\273\237\345\206\205\346\240\270.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 标准系统内核 - -- **[Linux内核概述](Linux内核概述.md)** - -- **[OpenHarmony开发板Patch使用指导](OpenHarmony开发板Patch使用指导.md)** - -- **[Linux内核编译与构建指导](Linux内核编译与构建指导.md)** - - diff --git "a/zh-cn/device-dev/kernel/\346\266\210\346\201\257\351\230\237\345\210\227.md" "b/zh-cn/device-dev/kernel/\346\266\210\346\201\257\351\230\237\345\210\227.md" deleted file mode 100644 index 3a5640015631e761cd32d7ed3b6564cbb056e5a4..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\346\266\210\346\201\257\351\230\237\345\210\227.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 消息队列 - -- **[基本概念](基本概念-9.md)** - -- **[开发指导](开发指导-10.md)** - - diff --git "a/zh-cn/device-dev/kernel/\347\263\273\347\273\237\345\221\275\344\273\244.md" "b/zh-cn/device-dev/kernel/\347\263\273\347\273\237\345\221\275\344\273\244.md" deleted file mode 100755 index 6d10fdb0221d7d2aaf211f32ca45b1c37b1bb884..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\347\263\273\347\273\237\345\221\275\344\273\244.md" +++ /dev/null @@ -1,47 +0,0 @@ -# 系统命令 - -- **[cpup](cpup.md)** - -- **[date](date.md)** - -- **[dmesg](dmesg.md)** - -- **[exec](exec.md)** - -- **[free](free.md)** - -- **[help](help.md)** - -- **[hwi](hwi.md)** - -- **[kill](kill.md)** - -- **[log](log.md)** - -- **[memcheck](memcheck.md)** - -- **[oom](oom.md)** - -- **[pmm](pmm.md)** - -- **[reset](reset.md)** - -- **[sem](sem.md)** - -- **[stack](stack.md)** - -- **[su](su.md)** - -- **[swtmr](swtmr.md)** - -- **[systeminfo](systeminfo.md)** - -- **[task](task.md)** - -- **[uname](uname.md)** - -- **[vmm](vmm.md)** - -- **[watch](watch.md)** - - diff --git "a/zh-cn/device-dev/kernel/\347\272\277\347\250\213.md" "b/zh-cn/device-dev/kernel/\347\272\277\347\250\213.md" deleted file mode 100755 index 7add0e4dc775da92317ccd9a6bb4edb6f6dff2e9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\347\272\277\347\250\213.md" +++ /dev/null @@ -1,702 +0,0 @@ -# 线程 - -- [基本概念](#section1179311337405) -- [使用场景](#section44877547404) -- [接口说明](#section2069477134115) - -## 基本概念 - -从系统的角度看,线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它线程运行。 - -OpenHarmony内核每个进程内的线程独立运行、独立调度,当前进程内线程的调度不受其它进程内线程的影响。 - -OpenHarmony内核中的线程采用抢占式调度机制,同时支持时间片轮转调度和FIFO调度方式。 - -OpenHarmony内核的线程一共有32个优先级\(0-31\),最高优先级为0,最低优先级为31。 - -当前进程内高优先级的线程可抢占当前进程内低优先级线程,当前进程内低优先级线程必须在当前进程内高优先级线程阻塞或结束后才能得到调度。 - -**线程状态说明:** - -- 初始化(Init):该线程正在被创建。 - -- 就绪(Ready):该线程在就绪列表中,等待CPU调度。 - -- 运行(Running):该线程正在运行。 - -- 阻塞(Blocked):该线程被阻塞挂起。Blocked状态包括:pending\(因为锁、事件、信号量等阻塞\)、suspended(主动pend)、delay\(延时阻塞\)、pendtime\(因为锁、事件、信号量时间等超时等待\)。 - -- 退出(Exit):该线程运行结束,等待父线程回收其控制块资源。 - - -**图 1** 线程状态迁移示意图 -![](figures/线程状态迁移示意图.png "线程状态迁移示意图") - -**线程状态迁移说明:** - -- Init→Ready: - - 线程创建拿到控制块后为Init状态,处于线程初始化阶段,当线程初始化完成将线程插入调度队列,此时线程进入就绪状态。 - -- Ready→Running: - - 线程创建后进入就绪态,发生线程切换时,就绪列表中最高优先级的线程被执行,从而进入运行态,但此刻该线程会从就绪列表中删除。 - -- Running→Blocked: - - 正在运行的线程发生阻塞(挂起、延时、读信号量等)时,线程状态由运行态变成阻塞态,然后发生线程切换,运行就绪列表中剩余最高优先级线程。 - -- Blocked→Ready : - - 阻塞的线程被恢复后(线程恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的线程会被加入就绪列表,从而由阻塞态变成就绪态。 - -- Ready→Blocked: - - 线程也有可能在就绪态时被阻塞(挂起),此时线程状态会由就绪态转变为阻塞态,该线程从就绪列表中删除,不会参与线程调度,直到该线程被恢复。 - -- Running→Ready: - - 有更高优先级线程创建或者恢复后,会发生线程调度,此刻就绪列表中最高优先级线程变为运行态,那么原先运行的线程由运行态变为就绪态,并加入就绪列表中。 - -- Running→Exit: - - 运行中的线程运行结束,线程状态由运行态变为退出态。若未设置分离属性(PTHREAD\_CREATE\_DETACHED)的线程,运行结束后对外呈现的是Exit状态,即退出态。 - - -## 使用场景 - -线程创建后,用户态可以执行线程调度、挂起、恢复、延时等操作,同时也可以设置线程优先级和调度策略,获取线程优先级和调度策略。 - -## 接口说明 - -OpenHarmony内核系统中的线程管理模块,线程间通信为用户提供下面几种功能: - -**表 1** 线程管理模块功能 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

名称

-

说明

-

备注

-

pthread.h

-

pthread_attr_destroy

-

销毁线程属性对象。

-

-

-

pthread.h

-

pthread_attr_getinheritsched

-

获取线程属性对象的调度属性。

-

-

-

pthread.h

-

pthread_attr_getschedparam

-

获取线程属性对象的调度参数属性。

-

-

-

pthread.h

-

pthread_attr_getschedpolicy

-

获取线程属性对象的调度策略属性。

-

OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。

-

pthread.h

-

pthread_attr_getstacksize

-

获取线程属性对象的堆栈大小。

-

-

-

pthread.h

-

pthread_attr_init

-

初始化线程属性对象。

-

-

-

pthread.h

-

pthread_attr_setdetachstate

-

设置线程属性对象的分离状态。

-

-

-

pthread.h

-

pthread_attr_setinheritsched

-

设置线程属性对象的继承调度属性。

-

-

-

pthread.h

-

pthread_attr_setschedparam

-

设置线程属性对象的调度参数属性。

-

OpenHarmony:设置线程优先级的参数值越小,线程在系统中的优先级越高;设置参数值越大,优先级越低。

-

注意:需要将pthread_attr_t线程属性的inheritsched字段设置为PTHREAD_EXPLICIT_SCHED,否则设置的线程调度优先级将不会生效,系统默认设置为PTHREAD_INHERIT_SCHED。

-

pthread.h

-

pthread_attr_setschedpolicy

-

设置线程属性对象的调度策略属性。

-

OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。

-

pthread.h

-

pthread_attr_setstacksize

-

设置线程属性对象的堆栈大小。

-

-

-

pthread.h

-

pthread_getattr_np

-

获取已创建线程的属性。

-

-

-

pthread.h

-

pthread_cancel

-

向线程发送取消请求。

-

-

-

pthread.h

-

pthread_testcancel

-

请求交付任何未决的取请求。

-

-

-

pthread.h

-

pthread_setcanceltype

-

设置线程可取消类型。

-

-

-

pthread.h

-

pthread_setcancelstate

-

设置线程可取消状态。

-

-

-

pthread.h

-

pthread_create

-

创建一个新的线程。

-

-

-

pthread.h

-

pthread_detach

-

分离一个线程。

-

-

-

pthread.h

-

pthread_equal

-

比较两个线程ID是否相等。

-

-

-

pthread.h

-

pthread_exit

-

终止正在调用的线程。

-

-

-

pthread.h

-

pthread_getschedparam

-

获取线程的调度策略和参数。

-

OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。

-

pthread.h

-

pthread_join

-

等待指定的线程结束。

-

-

-

pthread.h

-

pthread_self

-

获取当前线程的ID。

-

-

-

pthread.h

-

pthread_setschedprio

-

设置线程的调度静态优先级。

-

-

-

pthread.h

-

pthread_kill

-

向线程发送信号。

-

-

-

pthread.h

-

pthread_once

-

使函数调用只能执行一次。

-

-

-

pthread.h

-

pthread_atfork

-

注册fork的处理程序。

-

-

-

pthread.h

-

pthread_cleanup_pop

-

删除位于清理处理程序堆栈顶部的例程。

-

-

-

pthread.h

-

pthread_cleanup_push

-

将例程推送到清理处理程序堆栈的顶部。

-

-

-

pthread.h

-

pthread_barrier_destroy

-

销毁屏障对象(高级实时线程)

-

-

-

pthread.h

-

pthread_barrier_init

-

初始化屏障对象(高级实时线程)

-

-

-

pthread.h

-

pthread_barrier_wait

-

屏障同步(高级实时线程)

-

-

-

pthread.h

-

pthread_barrierattr_destroy

-

销毁屏障属性对象。

-

-

-

pthread.h

-

pthread_barrierattr_init

-

初始化屏障属性对象。

-

-

-

pthread.h

-

pthread_mutex_destroy

-

销毁互斥锁。

-

-

-

pthread.h

-

pthread_mutex_init

-

初始化互斥锁。

-

-

-

pthread.h

-

pthread_mutex_lock

-

互斥锁加锁操作。

-

-

-

pthread.h

-

pthread_mutex_trylock

-

互斥锁尝试加锁操作。

-

-

-

pthread.h

-

pthread_mutex_unlock

-

互斥锁解锁操作。

-

-

-

pthread.h

-

pthread_mutexattr_destroy

-

销毁互斥锁属性对象。

-

-

-

pthread.h

-

pthread_mutexattr_gettype

-

获取互斥锁类型属性。

-

-

-

pthread.h

-

pthread_mutexattr_init

-

初始化互斥锁属性对象。

-

-

-

pthread.h

-

pthread_mutexattr_settype

-

设置互斥锁类型属性。

-

-

-

pthread.h

-

pthread_mutex_timedlock

-

使用超时锁定互斥锁。

-

-

-

pthread.h

-

pthread_rwlock_destroy

-

销毁读写锁。

-

-

-

pthread.h

-

pthread_rwlock_init

-

初始化读写锁。

-

-

-

pthread.h

-

pthread_rwlock_rdlock

-

获取读写锁读锁操作。

-

-

-

pthread.h

-

pthread_rwlock_timedrdlock

-

使用超时锁定读写锁读锁。

-

-

-

pthread.h

-

pthread_rwlock_timedwrlock

-

使用超时锁定读写锁写锁。

-

-

-

pthread.h

-

pthread_rwlock_tryrdlock

-

尝试获取读写锁读锁操作。

-

-

-

pthread.h

-

pthread_rwlock_trywrlock

-

尝试获取读写锁写锁操作。

-

-

-

pthread.h

-

pthread_rwlock_unlock

-

读写锁解锁操作。

-

-

-

pthread.h

-

pthread_rwlock_wrlock

-

获取读写锁写锁操作。

-

-

-

pthread.h

-

pthread_rwlockattr_destroy

-

销毁读写锁属性对象。

-

-

-

pthread.h

-

pthread_rwlockattr_init

-

初始化读写锁属性对象。

-

-

-

pthread.h

-

pthread_cond_broadcast

-

解除若干已被等待条件阻塞的线程。

-

-

-

pthread.h

-

pthread_cond_destroy

-

销毁条件变量。

-

-

-

pthread.h

-

pthread_cond_init

-

初始化条件变量。

-

-

-

pthread.h

-

pthread_cond_signal

-

解除被阻塞的线程。

-

-

-

pthread.h

-

pthread_cond_timedwait

-

定时等待条件。

-

-

-

pthread.h

-

pthread_cond_wait

-

等待条件。

-

-

-

semaphore.h

-

sem_destroy

-

销毁指定的无名信号量。

-

-

-

semaphore.h

-

sem_getvalue

-

获得指定信号量计数值。

-

-

-

semaphore.h

-

sem_init

-

创建并初始化一个无名信号量。

-

-

-

semaphore.h

-

sem_post

-

增加信号量计数。

-

-

-

semaphore.h

-

sem_timedwait

-

获取信号量,且有超时返回功能。

-

-

-

semaphore.h

-

sem_trywait

-

尝试获取信号量。

-

-

-

semaphore.h

-

sem_wait

-

获取信号量。

-

-

-
- diff --git "a/zh-cn/device-dev/kernel/\347\275\221\347\273\234.md" "b/zh-cn/device-dev/kernel/\347\275\221\347\273\234.md" deleted file mode 100755 index 17eafd2f164bce1274e6f33838e60f7ef7a255f2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\347\275\221\347\273\234.md" +++ /dev/null @@ -1,303 +0,0 @@ -# 网络 - -- [基本概念](#section9840143083510) -- [使用场景](#section1575885183516) -- [接口说明](#section16351198193614) - -## 基本概念 - -网络模块实现了TCP/IP协议栈基本功能,提供标准的POSIX socket接口。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前系统使用**lwIP**提供网络能力。 - -## 使用场景 - -针对用户态开发,OpenHarmony内核提供了一套网络功能系统调用接口,支持socket的创建关闭、数据收发、网络属性的设置等,通过C库提供标准的POSIX socket函数供开发者使用。 - -## 接口说明 - -**表 1** 标准C库相关接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口

-

功能

-

sys/socket.h

-

int accept(int socket, struct sockaddr *address, socklen_t *address_len)

-

接受连接。

-

sys/socket.h

-

int bind(int s, const struct sockaddr *name, socklen_t namelen)

-

socket与IP地址绑定。

-

sys/socket.h

-

int shutdown(int socket, int how)

-

关闭连接。

-

sys/socket.h

-

int getpeername(int s, struct sockaddr *name, socklen_t *namelen)

-

获取对端地址。

-

sys/socket.h

-

int getsockname(int s, struct sockaddr *name, socklen_t *namelen)

-

获取本地地址。

-

sys/socket.h

-

int getsockopt(int s, struct sockaddr *name, socklen_t *namelen)

-

获取socket属性信息。

-

sys/socket.h

-

int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)

-

配置socket属性。

-

unistd.h

-

int close(int s)

-

关闭socket。

-

sys/socket.h

-

int connect(int s, const struct sockaddr *name, socklen_t namelen)

-

连接到指定的目的IP。

-

sys/socket.h

-

int listen(int sockfd, int backlog)

-

聆听连接本socket的请求。

-

sys/socket.h

-

ssize_t recv(int socket, void *buffer, size_t length, int flags)

-

接收socket上收到的数据。

-

sys/socket.h

-

ssize_t recvmsg(int s, struct msghdr *message, int flags)

-

接收socket上收到的数据,可使用更丰富的参数。

-

sys/socket.h

-

ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len)

-

接收socket上收到的数据,可同时获得数据来源IP地址。

-

sys/socket.h

-

ssize_t send(int s, const void *dataptr, size_t size, int flags)

-

通过socket发送数据。

-

sys/socket.h

-

ssize_t sendmsg(int s, const struct msghdr *message, int flags)

-

通过socket发送数据,可使用更丰富的参数。

-

sys/socket.h

-

ssize_t sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)

-

通过socket发送数据,可指定发送的目的IP地址。

-

sys/socket.h

-

int socket(int domain, int type, int protocol)

-

创建socket。

-

sys/select.h

-

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)

-

多路复用。

-

sys/ioctl.h

-

int ioctl(int s, int request, ...)

-

socket属性获取、设置。

-

arpa/inet.h

-

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)

-

网络地址格式转换:将二进制格式IP地址转换为字符串格式。

-

arpa/inet.h

-

int inet_pton(int af, const char *src, void *dst)

-

网络地址格式转换:将字符串格式IP地址转换为二进制格式。

-
- -与标准接口差异详细说明: - -- **sendmsg** - - **函数原型:** - - ssize\_t sendmsg\(int s, const struct msghdr \*message, int flags\) - - **函数功能:**发送消息。 - - **参数说明:** - - - - - - - - - - - - - - - - -

参数

-

描述

-

s

-

套接字描述符。

-

message

-

待发送的消息,不支持发送ancillary消息。

-

flags

-

用于指定发送消息时行为特性,有如下行为特性:

-
  • MSG_MORE:允许将多次发送的消息进行拼包发送。
  • MSG_DONTWAIT:非阻塞操作。
-
- - **返回值:** - - - 成功返回:已发送的消息长度(字节数)。 - - 失败返回:-1,并设置errno。 - - -- **recvmsg** - - **函数原型:** - - ssize\_t recvmsg\(int s, struct msghdr \*message, int flags\) - - **函数功能:**接收消息。 - - **参数说明:** - - - - - - - - - - - - - - - - -

参数

-

描述

-

s

-

套接字描述符。

-

message

-

存放接收的消息,不支持接收ancillary消息。

-

flags

-

用于指定接收消息时行为特性,有如下行为特性:

-
  • MSG_PEEK:允许预读消息而不取走。
  • MSG_DONTWAIT:非阻塞操作。
-
- - **返回值:** - - - 成功返回:已接收的消息长度(字节数)。 - - 失败返回:-1,并设置errno。 - - -- **ioctl** - - **函数原型:** - - int ioctl\(int s, int request, ...\) - - **函数功能:**获取或设置socket属性。 - - **参数说明:** - - - - - - - - - - - - - -

参数

-

描述

-

s

-

套接字描述符。

-

request

-

对socket属性要进行的操作,当前支持如下操作:

-
  • FIONREAD:获取socket当前可读取的数据大小(字节数)。
  • FIONBIO:设置socket是否非阻塞。
-
- - **返回值:** - - - 成功返回:0。 - - 失败返回:-1,并设置errno。 - - diff --git "a/zh-cn/device-dev/kernel/\347\275\221\347\273\234\345\221\275\344\273\244.md" "b/zh-cn/device-dev/kernel/\347\275\221\347\273\234\345\221\275\344\273\244.md" deleted file mode 100755 index 2a1245c1579a6c54b19f60a348de42461a2cce77..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\347\275\221\347\273\234\345\221\275\344\273\244.md" +++ /dev/null @@ -1,25 +0,0 @@ -# 网络命令 - -- **[arp](arp.md)** - -- **[dhclient](dhclient.md)** - -- **[dns](dns.md)** - -- **[ifconfig](ifconfig.md)** - -- **[ipdebug](ipdebug.md)** - -- **[netstat](netstat.md)** - -- **[ntpdate](ntpdate.md)** - -- **[ping](ping.md)** - -- **[ping6](ping6.md)** - -- **[telnet](telnet.md)** - -- **[tftp](tftp.md)** - - diff --git "a/zh-cn/device-dev/kernel/\350\256\244\350\257\206LiteOS-M\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\350\256\244\350\257\206LiteOS-M\345\206\205\346\240\270.md" deleted file mode 100644 index 7984b0843bb602a8962a0c40915c143803202041..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\350\256\244\350\257\206LiteOS-M\345\206\205\346\240\270.md" +++ /dev/null @@ -1,62 +0,0 @@ -# 认识LiteOS-M内核 - -- [内核简介](#section1429342661510) - - [cpu体系架构支持](#section48891456112819) - - [运行机制](#section4599142312817) - - -## 内核简介 - -OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系统内核,具有小体积、低功耗、高性能的特点。其代码结构简单,主要包括内核最小功能集、内核抽象层、可选组件以及工程目录等。OpenHarmony LiteOS-M内核架构包含硬件相关层以及硬件无关层,如下图所示,其中Kernel Arch模块属于硬件相关层,该模块按不同编译工具链、芯片架构分类,提供统一的HAL(Hardware Abstraction Layer)接口,提升了硬件易适配性,满足AIoT类型丰富的硬件和编译工具链的拓展;Components等其他模块属于硬件无关层,其中Kernel Task等内核模块提供基础能力,Components模块提供网络、文件系统等组件能力,Utils模块提供错误处理、调测等能力,KAL(Kernel Abstraction Layer)模块提供统一的标准接口。 - -**图 1** 内核架构图 -![](figures/内核架构图.png "内核架构图") - -### cpu体系架构支持 - -CPU体系架构分为通用架构定义和特定架构定义两层,通用架构定义层为所有体系架构都需要支持和实现的接口,特定架构定义层为特定体系架构所特有的部分。在新增一个体系架构的时候,必须需要实现通用架构定义层,如果该体系架构还有特有的功能,可以在特定架构定义层来实现。 - -**表 1** CPU体系架构规则 - - - - - - - - - - - - - - - - - - - - -

规则

-

通用体系架构层

-

特定体系架构层

-

头文件位置

-

kernel/arch/include

-

kernel/arch/<arch>/<arch>/<toolchain>/

-

头文件命名

-

los_<function>.h

-

los_arch_<function>.h

-

函数命名

-

Halxxxx

-

Halxxxx

-
- -LiteOS-M已经支持ARM Cortex-M3、ARM Cortex-M4、ARM Cortex-M7、ARM Cortex-M33、RISC-V等主流架构,如果需要扩展CPU体系架构,请参考[芯片架构适配点](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E7%A7%BB%E6%A4%8D%E6%A6%82%E8%BF%B0.md#%E8%8A%AF%E7%89%87%E6%9E%B6%E6%9E%84%E9%80%82%E9%85%8D%E7%82%B9)。 - -### 运行机制 - -在开发板配置文件target\_config.h配置系统时钟、每秒Tick数,可以对任务、内存、IPC、异常处理模块进行裁剪配置。系统启动时,根据配置进行指定模块的初始化。内核启动流程包含外设初始化、系统时钟配置、内核初始化、操作系统启动等,详见内核启动流程图。 - -**图 2** 内核启动流程 -![](figures/内核启动流程.png "内核启动流程") - diff --git "a/zh-cn/device-dev/kernel/\350\260\203\346\265\213.md" "b/zh-cn/device-dev/kernel/\350\260\203\346\265\213.md" deleted file mode 100755 index 2327e141234e6cce885f500c2297d1de5f9061cd..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\350\260\203\346\265\213.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 调测 - -- **[Shell介绍](Shell介绍.md)** - -- **[Shell命令开发指导](Shell命令开发指导.md)** - -- **[Shell命令编程实例](Shell命令编程实例.md)** - -- **[Shell命令使用详解](Shell命令使用详解.md)** - -- **[魔法键使用方法](魔法键使用方法.md)** - -- **[用户态异常信息说明](用户态异常信息说明.md)** - - diff --git "a/zh-cn/device-dev/kernel/\350\270\251\345\206\205\345\255\230\346\243\200\346\265\213.md" "b/zh-cn/device-dev/kernel/\350\270\251\345\206\205\345\255\230\346\243\200\346\265\213.md" deleted file mode 100644 index ab5d4101a001ddd96502f65b446ba27511f254ab..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\350\270\251\345\206\205\345\255\230\346\243\200\346\265\213.md" +++ /dev/null @@ -1,85 +0,0 @@ -# 踩内存检测 - -- [基础概念](#section17368154517335) -- [功能配置](#section4696190123420) -- [开发指导](#section672362973417) - - [开发流程](#section026014863416) - - [编程实例](#section186311302356) - - [示例代码](#section12709533354) - - [结果验证](#section81214126369) - - -## 基础概念 - -踩内存检测机制作为内核的可选功能,用于检测动态内存池的完整性。通过该机制,可以及时发现内存池是否发生了踩内存问题,并给出错误信息,便于及时发现系统问题,提高问题解决效率,降低问题定位成本。 - -## 功能配置 - -LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。 - -1. 开启这个功能,每次申请内存,会实时检测内存池的完整性。 -2. 如果不开启该功能,也可以调用LOS\_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。 - -由于该功能只会检测出哪个内存节点被破坏了,并给出前节点信息(因为内存分布是连续的,当前节点最有可能被前节点破坏)。如果要进一步确认前节点在哪里申请的,需开启内存泄漏检测功能,通过LR记录,辅助定位。 - ->![](public_sys-resources/icon-caution.gif) **注意:** ->开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS\_MemIntegrityCheck接口检测。 - -## 开发指导 - -### 开发流程 - -通过调用LOS\_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。 - -### 编程实例 - -本实例实现如下功能: - -1. 申请两个物理上连续的内存块; -2. 通过memset构造越界访问,踩到下个节点的头4个字节; -3. 调用LOS\_MemIntegrityCheck检测是否发生踩内存。 - -### 示例代码 - -代码实现如下: - -``` -#include -#include -#include "los_memory.h" -#include "los_config.h" - -void MemIntegrityTest(void) -{ - /* 申请两个物理连续的内存块 */ - void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); - void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); - /* 第一个节点内存块大小是8字节,那么12字节的清零,会踩到第二个内存节点的节点头,构造踩内存场景 */ - memset(ptr1, 0, 8 + 4); - LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR); -} -``` - -### 结果验证 - -编译运行输出log如下: - -``` -[ERR][OsMemMagicCheckPrint], 2028, memory check error! -memory used but magic num wrong, magic num = 0x00000000 /* 提示信息,检测到哪个字段被破坏了,用例构造了将下个节点的头4个字节清零,即魔鬼数字字段 */ - - broken node head: 0x20003af0 0x00000000 0x80000020, prev node head: 0x20002ad4 0xabcddcba 0x80000020 -/* 被破坏节点和其前节点关键字段信息,分别为其前节点地址、节点的魔鬼数字、节点的sizeAndFlag;可以看出被破坏节点的魔鬼数字字段被清零,符合用例场景 */ - - broken node head LR info: /* 节点的LR信息需要开启内存检测功能才有有效输出 */ - LR[0]:0x0800414e - LR[1]:0x08000cc2 - LR[2]:0x00000000 - - pre node head LR info: /* 通过LR信息,可以在汇编文件中查找前节点是哪里申请,然后排查其使用的准确性 */ - LR[0]:0x08004144 - LR[1]:0x08000cc2 - LR[2]:0x00000000 -[ERR]Memory interity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* 被破坏节点和其前节点的地址 */ -``` - diff --git "a/zh-cn/device-dev/kernel/\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250.md" "b/zh-cn/device-dev/kernel/\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250.md" deleted file mode 100644 index 903970bdd61bd096a10c842a567cdcfa25d9ba13..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\350\275\257\344\273\266\345\256\232\346\227\266\345\231\250.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 软件定时器 - -- **[基本概念](基本概念-15.md)** - -- **[开发指导](开发指导-16.md)** - - diff --git "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" deleted file mode 100644 index 0ae605881ae93ccbe37bda0971479cb69a6be0e8..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 轻量和小型系统内核 - -- **[轻量系统内核](轻量系统内核.md)** - -- **[小型系统内核](小型系统内核.md)** - - diff --git "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\347\263\273\347\273\237\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\350\275\273\351\207\217\347\263\273\347\273\237\345\206\205\346\240\270.md" deleted file mode 100644 index 290c4915bf94adb34bc2804d40268adcfe38fd87..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\347\263\273\347\273\237\345\206\205\346\240\270.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 轻量系统内核 - -- **[基础内核](基础内核.md)** - -- **[文件系统](文件系统.md)** - -- **[标准库](标准库.md)** - -- **[调测](调测.md)** - - diff --git "a/zh-cn/device-dev/kernel/\350\277\233\347\250\213.md" "b/zh-cn/device-dev/kernel/\350\277\233\347\250\213.md" deleted file mode 100755 index c425b175ae513cd01fbb8a5c4cbf17dca6351e1d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\350\277\233\347\250\213.md" +++ /dev/null @@ -1,301 +0,0 @@ -# 进程 - -- [基本概念](#section29197338383) -- [使用场景](#section85513272398) -- [接口说明](#section4517119124015) - -## 基本概念 - -从系统的角度看,进程是资源管理单元。进程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它进程运行。 - -OpenHarmony内核的进程模块可以给用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。这样用户可以将更多的精力投入到业务功能的实现中。 - -OpenHarmony内核中的进程采用抢占式调度机制,支持时间片轮转调度方式。 - -OpenHarmony内核的进程一共有32个优先级\(0-31\),用户进程可配置的优先级有22个\(10-31\),最高优先级为10,最低优先级为31。 - -高优先级的进程可抢占低优先级进程,低优先级进程必须在高优先级进程阻塞或结束后才能得到调度。 - -每一个用户态进程均拥有自己独立的进程空间,相互之间不可见,实现进程间隔离。 - -用户态根进程init由内核态创建,其它用户态进程均由init进程fork而来。 - -**进程状态说明:** - -- 初始化(Init):该进程正在被创建。 - -- 就绪(Ready):该进程在就绪列表中,等待CPU调度。 - -- 运行(Running):该进程正在运行。 - -- 阻塞(Pending):该进程被阻塞挂起。本进程内所有的线程均被阻塞时,进程被阻塞挂起。 - -- 僵尸态(Zombies):该进程运行结束,等待父进程回收其控制块资源。 - - -**图 1** 进程状态迁移示意图 -![](figures/进程状态迁移示意图.png "进程状态迁移示意图") - -**进程状态迁移说明:** - -- Init→Ready: - - 进程创建或fork时,拿到该进程控制块后进入Init状态,处于进程初始化阶段,当进程初始化完成将进程插入调度队列,此时进程进入就绪状态。 - -- Ready→Running: - - 进程创建后进入就绪态,发生进程切换时,就绪列表中最高优先级的进程被执行,从而进入运行态。若此时该进程中已无其它线程处于就绪态,则该进程从就绪列表删除,只处于运行态;若此时该进程中还有其它线程处于就绪态,则该进程依旧在就绪队列,此时进程的就绪态和运行态共存。 - -- Running→Pending: - - 进程内所有的线程均处于阻塞态时,进程在最后一个线程转为阻塞态时,同步进入阻塞态,然后发生进程切换。 - -- Pending→Ready: - - 阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态。 - -- Ready→Pending: - - 进程内的最后一个就绪态线程处于阻塞态时,进程从就绪列表中删除,进程由就绪态转为阻塞态。 - -- Running→Ready: - - 进程由运行态转为就绪态的情况有以下两种: - - 1. 有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。 - 2. 若进程的调度策略为SCHED\_RR,且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。 - -- Running→Zombies: - - 当进程的主线程或所有线程运行结束后,进程由运行态转为僵尸态,等待父进程回收资源。 - - -## 使用场景 - -进程创建后,用户只能操作自己进程空间的资源,无法操作其它进程的资源(共享资源除外)。 用户态允许进程挂起,恢复,延时等操作,同时也可以设置用户态进程调度优先级和调度策略,获取进程调度优先级和调度策略。进程结束的时候,进程会主动释放持有的进程资源,但持有的进程pid资源需要父进程通过wait/waitpid或父进程退出时回收。 - -## 接口说明 - -OpenHarmony内核系统中的进程管理模块为用户提供下面几种功能: - -**表 1** 进程管理模块功能 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

备注

-

进程

-

fork

-

创建一个新进程。

-

-

-

exit

-

终止进程。

-

-

-

atexit

-

注册正常进程终止的回调函数。

-

-

-

abort

-

中止进程执行。

-

-

-

getpid

-

获取进程ID。

-

-

-

getppid

-

获取父进程ID。

-

-

-

getpgrp

-

获取调用进程的进程组ID。

-

-

-

getpgid

-

获取进程的进程组ID。

-

-

-

setpgrp

-

设置调用进程的进程组ID。

-

-

-

setpgid

-

设置进程的进程组ID。

-

-

-

kill

-

给进程发送信号。

-
  • 仅支持1-30号信号的发送。
  • 信号的默认行为不支持STOP及CONTINUE,无COREDUMP功能。
  • 不能屏蔽SIGSTOP、SIGKILL、SIGCONT。
  • 异步信号,发送信号给某进程后,直到该进程被调度后才会执行信号回调(为安全起见,杀死进程的动作是进程自己执行的,内核不能通过信号强制杀死对方)。
  • 进程消亡会发送SIGCHLD给父进程,发送动作无法取消。
  • 无法通过信号唤醒正在睡眠的进程。
-

wait

-

等待任意子进程结束并回收子进程资源。

-

status的值可以由以下宏定义解析:

-
  • WIFEXITED(status):如果子进程正常结束,它就返回真;否则返回假。
  • WEXITSTATUS(status):如果WIFEXITED(status)为真,则可以用该宏取得子进程exit()返回的退出码。
  • WTERMSIG(status) 仅支持以下情况:子进程触发异常结束后通过WTERMSIG获取的进程退出编号始终为SIGUSR2。
  • 不支持的操作: WIFSTOPPED、WSTOPSIG、WCOREDUMP 、WIFCONTINUED。
-

waitpid

-

等待子进程结束并回收子进程资源。

-

options:不支持WUNTRACED,WCONTINUED;

-

status的值可以由以下宏定义解析:

-
  • WIFEXITED(status):如果子进程正常结束,它就返回真;否则返回假。
  • WEXITSTATUS(status):如果WIFEXITED(status)为真,则可以用该宏取得子进程exit()返回的退出码。
  • WTERMSIG(status)仅支持以下情况:子进程触发异常结束后通过WTERMSIG获取的进程退出编号始终为SIGUSR2。
  • 不支持:WIFSTOPPED 、WSTOPSIG、WCOREDUMP 、WIFCONTINUED。
-

调度

-

getpriority

-

获取指定ID的静态优先级。

-
  • 不支持:PRIO_PGRP、PRIO_USER。
-
  • 无动态优先级概念,用于设置静态优先级。
-

setpriority

-

设置指定ID的静态优先级。

-

sched_rr_get_interval

-

获取执行时间限制。

-

-

-

sched_yield

-

系统调用运行进程主动让出执行权。

-

-

-

sched_get_priority_max

-

获取进程静态优先级取值范围的最大值。

-

调度策略只支持:SCHED_RR。

-

sched_get_priority_min

-

获取进程静态优先级取值范围的最小值。

-

sched_getscheduler

-

获取调度策略。

-

sched_setscheduler

-

设置调度策略。

-

sched_getparam

-

获取调度参数。

-

-

-

sched_setparam

-

设置调度参数。

-

-

-

exec

-

execl

-

执行指定的elf格式的用户程序文件。

-

-

-

execle

-

执行指定的elf格式的用户程序文件。

-

-

-

execlp

-

执行指定的elf格式的用户程序文件。

-

-

-

execv

-

执行指定的elf格式的用户程序文件。

-

-

-

execve

-

执行指定的elf格式的用户程序文件。

-

-

-

execvp

-

执行指定的elf格式的用户程序文件。

-

-

-
- diff --git "a/zh-cn/device-dev/kernel/\351\231\204\345\275\225.md" "b/zh-cn/device-dev/kernel/\351\231\204\345\275\225.md" deleted file mode 100644 index 73adc5ca617dfb9d657241bd0ba43d4afd5c5cbc..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\351\231\204\345\275\225.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 附录 - -- **[内核编码规范](内核编码规范.md)** - -- **[基本数据结构](基本数据结构.md)** - -- **[标准库支持](标准库支持.md)** - - diff --git "a/zh-cn/device-dev/kernel/\351\235\231\346\200\201\345\206\205\345\255\230.md" "b/zh-cn/device-dev/kernel/\351\235\231\346\200\201\345\206\205\345\255\230.md" deleted file mode 100644 index 090cea4a0d0b7ec7188f2836b0014de6b5e0bdab..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\351\235\231\346\200\201\345\206\205\345\255\230.md" +++ /dev/null @@ -1,182 +0,0 @@ -# 静态内存 - -- [运行机制](#section165473517522) -- [开发指导](#section57511620165218) - - [使用场景](#section215474911529) - - [接口说明](#section79231214539) - - [开发流程](#section1388511316548) - - [编程实例](#section17801515105519) - - [结果验证](#section11818154112319) - - -## 运行机制 - -静态内存实质上是一个静态数组,静态内存池内的块大小在初始化时设定,初始化后块大小不可变更。 - -静态内存池由一个控制块LOS\_MEMBOX\_INFO和若干相同大小的内存块LOS\_MEMBOX\_NODE构成。控制块位于内存池头部,用于内存块管理,包含内存块大小uwBlkSize,内存块数量uwBlkNum,已分配使用的内存块数量uwBlkCnt和空闲内存块链表stFreeList。内存块的申请和释放以块大小为粒度,每个内存块包含指向下一个内存块的指针pstNext。 - -**图 1** 静态内存示意图 -![](figures/静态内存示意图.png "静态内存示意图") - -## 开发指导 - -### 使用场景 - -当用户需要使用固定长度的内存时,可以通过静态内存分配的方式获取内存,一旦使用完毕,通过静态内存释放函数归还所占用内存,使之可以重复使用。 - -### 接口说明 - -OpenHarmony LiteOS-M的静态内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 - -**表 1** 静态内存模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

初始化静态内存池

-

LOS_MemboxInit

-

初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小。

-

清除静态内存块内容

-

LOS_MemboxClr

-

清零从静态内存池中申请的静态内存块的内容。

-

申请、释放静态内存

-

LOS_MemboxAlloc

-

从指定的静态内存池中申请一块静态内存块。

-

LOS_MemboxFree

-

释放从静态内存池中申请的一块静态内存块。

-

获取、打印静态内存池信息

-

LOS_MemboxStatisticsGet

-

获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小。

-

LOS_ShowBox

-

打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址。

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->初始化后的内存池的内存块数量,不等于总大小除于内存块大小,因为内存池的控制块和每个内存块的控制头,都存在内存开销,设置总大小时,需要将这些因素考虑进去。 - -### 开发流程 - -本节介绍使用静态内存的典型场景开发流程。 - -1. 规划一片内存区域作为静态内存池。 -2. 调用LOS\_MemboxInit初始化静态内存池。 - - 初始化会将入参指定的内存区域分割为N块(N值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。 - -3. 调用LOS\_MemboxAlloc接口分配静态内存。 - - 系统将会从空闲链表中获取第一个空闲块,并返回该内存块的起始地址。 - -4. 调用LOS\_MemboxClr接口。 - - 将入参地址对应的内存块清零。 - -5. 调用LOS\_MemboxFree接口。 - - 将该内存块加入空闲链表。 - - -### 编程实例 - -本实例执行以下步骤: - -1. 初始化一个静态内存池。 -2. 从静态内存池中申请一块静态内存。 -3. 在内存块存放一个数据。 -4. 打印出内存块中的数据。 -5. 清除内存块中的数据。 -6. 释放该内存块。 - - 示例代码如下: - - -``` -#include "los_membox.h" - -VOID Example_StaticMem(VOID) -{ - UINT32 *mem = NULL; - UINT32 blkSize = 10; - UINT32 boxSize = 100; - UINT32 boxMem[1000]; - UINT32 ret; - - /*内存池初始化*/ - ret = LOS_MemboxInit(&boxMem[0], boxSize, blkSize); - if(ret != LOS_OK) { - printf("Membox init failed!\n"); - return; - } else { - printf("Membox init success!\n"); - } - - /*申请内存块*/ - mem = (UINT32 *)LOS_MemboxAlloc(boxMem); - if (NULL == mem) { - printf("Mem alloc failed!\n"); - return; - } - printf("Mem alloc success!\n"); - - /*赋值*/ - *mem = 828; - printf("*mem = %d\n", *mem); - - /*清除内存内容*/ - LOS_MemboxClr(boxMem, mem); - printf("Mem clear success \n *mem = %d\n", *mem); - - /*释放内存*/ - ret = LOS_MemboxFree(boxMem, mem); - if (LOS_OK == ret) { - printf("Mem free success!\n"); - } else { - printf("Mem free failed!\n"); - } - - return; -} -``` - -### 结果验证 - -输出结果如下: - -``` -Membox init success! -Mem alloc success! -*mem = 828 -Mem clear success -*mem = 0 -Mem free success! -``` - diff --git "a/zh-cn/device-dev/kernel/\351\255\224\346\263\225\351\224\256\344\275\277\347\224\250\346\226\271\346\263\225.md" "b/zh-cn/device-dev/kernel/\351\255\224\346\263\225\351\224\256\344\275\277\347\224\250\346\226\271\346\263\225.md" deleted file mode 100755 index 9bd18a8340d5f63817550f51f09b9cbae5dc6caf..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/kernel/\351\255\224\346\263\225\351\224\256\344\275\277\347\224\250\346\226\271\346\263\225.md" +++ /dev/null @@ -1,38 +0,0 @@ -# 魔法键使用方法 - -- [使用场景](#section2350114718546) -- [使用方法](#section3305151511559) - -## 使用场景 - -在系统运行出现无响应等情况时,可以通过魔法键功能确定系统是否被锁中断(魔法键也无响应)或者查看系统任务运行状态等信息。 - -在中断有响应的情况下,可以通过魔法键查看task信息中 cpup(CPU占用率)看是哪个任务长时间占用CPU导致系统其他任务无响应(一般为比较高优先级任务一直抢占CPU,导致低优先级任务无响应)。 - -## 使用方法 - -1. 配置宏LOSCFG\_ENABLE\_MAGICKEY。 - -魔法键依赖于宏LOSCFG\_ENABLE\_MAGICKEY,使用时通过menuconfig在配置项中开启“Enable MAGIC KEY”: - -Debug ---\> Enable MAGIC KEY;若关闭该选项,则魔法键失效。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->1. 可以在menuconfig中,将光标移动到LOSCFG\_ENABLE\_MAGICKEY上,输入“?”,查看帮助信息。 - -2. 输入“ctrl + r”键,打开魔法键检测功能。 - -在连接UART或者USB转虚拟串口的情况下,输入“ctrl + r” 键,打开魔法键检测功能,输出 “Magic key on”;再输入一次后,则关闭魔法键检测功能,输出“Magic key off”。魔法键功能如下: - -- ctrl + z:帮助键,输出相关魔法键简单介绍; - -- ctrl + t:输出任务相关信息; - -- ctrl + p:系统主动进入panic,输出panic相关信息后,系统会挂住; - -- ctrl + e:系统进行简单完整性内存池检查,检查出错会输出相关错误信息,检查正常会输出“system memcheck over, all passed!”。 - - ->![](public_sys-resources/icon-notice.gif) **须知:** ->魔法键检测功能打开情况下,如果需要通过UART或者USB转虚拟串口输入特殊字符需避免与魔法键值重复,否则魔法键会被误触发,而原有设计功能可能出现错误。 - diff --git "a/zh-cn/device-dev/porting/CMake\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" "b/zh-cn/device-dev/porting/CMake\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" deleted file mode 100755 index bb7404eca3e670115c48f40f4f219347162c5064..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/CMake\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" +++ /dev/null @@ -1,435 +0,0 @@ -# CMake方式组织编译的库移植 - -- [源码获取](#section1771132116245) -- [移植思路](#section9737174410328) -- [交叉编译](#section38205577332) - - [编译参考](#section1088111263418) - - [设置执行交叉编译](#section8168182883515) - -- [测试](#section6686144293611) -- [将该库编译添加到OpenHarmony工程中](#section1651053153715) - -以double-conversion库为例,其移植过程如下文所示 - -## 源码获取 - -从仓库[获取double-conversion源码](https://github.com/google/double-conversion),其目录结构如下表: - -**表 1** 源码目录结构 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

double-conversion/cmake/

-

CMake组织编译使用到的模板

-

double-conversion/double-conversion/

-

源文件目录

-

double-conversion/msvc/

-

-

-

double-conversion/test/

-

测试用例源文件

-

double-conversion/.gitignore

-

-

-

double-conversion/AUTHORS

-

-

-

double-conversion/BUILD

-

-

-

double-conversion/CMakeLists.txt

-

CMake方式顶层编译组织文件

-

double-conversion/COPYING

-

-

-

double-conversion/Changelog

-

-

-

double-conversion/LICENSE

-

-

-

double-conversion/Makefile

-

-

-

double-conversion/README.md

-

-

-

double-conversion/SConstruct

-

-

-

double-conversion/WORKSPACE

-

-

-
- -## 移植思路 - -移植思路:通过修改工具链,交叉编译该三方库,生成OpenHarmony平台的可执行文件,最后再通过GN调用CMake的方式添加到OpenHarmony工程中。 - -## 交叉编译 - -### 编译参考 - -代码仓库的[README.md](https://github.com/google/double-conversion/blob/master/README.md)中详细介绍了使用CMake编译double-conversion库的步骤,以及测试方法。本文参考该指导设置该库的编译配置,并完成测试。若开发人员在移植过程中对该库的编译选项配置有疑惑的地方,可参考该指导。对于其他使用CMake可独立编译的三方库,在移植时可以参考其自带的编译指导。 - -### 设置执行交叉编译 - -CMake方式可通过指定工具链进行交叉编译,修改并编译该库,生成OpenHarmony平台的可执行文件,步骤如下: - -1. 设置工具链 - - 将下列clang工具链配置添加到该工程的顶层CMakeLists.txt(即[表1中的该文件](#table824211132418))中即可。 - - ``` - set(CMAKE_CROSSCOMPILING TRUE) - set(CMAKE_SYSTEM_NAME Generic) - set(CMAKE_CXX_COMPILER_ID Clang) - set(CMAKE_TOOLCHAIN_PREFIX llvm-) - #指定c编译工具(确保工具链所在路径已经添加到了PATH环境变量中)和编译标志,使用clang编译时标志中必须指定--target,否则无法交叉编译。 - set(CMAKE_C_COMPILER clang) - set(CMAKE_C_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") - #指定c++编译工具(确保工具链所在路径已经添加到了PATH环境变量中)和编译标志,必须指定--target,否则无法交叉编译。 - set(CMAKE_CXX_COMPILER clang++) - set(CMAKE_CXX_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") - #指定链接工具和链接标志,必须指定--target和--sysroot,其中OHOS_ROOT_PATH可通过cmake命令后缀参数来指定。 - set(MY_LINK_FLAGS "--target=arm-liteos --sysroot=${OHOS_SYSROOT_PATH}") - set(CMAKE_LINKER clang) - set(CMAKE_CXX_LINKER clang++) - set(CMAKE_C_LINKER clang) - set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINKER} - ${MY_LINK_FLAGS} -o ") - set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINKER} - ${MY_LINK_FLAGS} -o ") - #指定链接库的查找路径。 - set(CMAKE_SYSROOT ${OHOS_SYSROOT_PATH}) - ``` - -2. 执行编译 - - linux命令行中进入double-conversion的源文件目录(即[表1所示目录](#table824211132418)),执行下列命令: - - ``` - mkdir build && cd build - cmake .. -DBUILD_TESTING=ON -DOHOS_SYSROOT_PATH="..." - make -j - ``` - - 其中OHOS\_SYSROOT\_PATH需用绝对路径指定出sysroot目录的位置,以OpenHarmony为例即目录openHarmony/prebuilts/lite/sysroot的绝对路径。 - -3. 查看结果 - - 步骤2操作完成后,build目录下会生成静态库文件和测试用例: - - **表 2** 编译生成文件目录结构 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

double-conversion/build/libdouble-conversion.a

-

生成的静态库文件

-

double-conversion/build/test/

-

目录下存放生成的测试用例和相关CMake缓存文件

-

double-conversion/build/CMakeCache.txt

-

CMake构建过程中的缓存文件

-

double-conversion/build/CMakeFiles/

-

-

-

double-conversion/build/cmake_install.cmake

-

-

-

double-conversion/build/CTestTestfile.cmake

-

-

-

double-conversion/build/DartConfiguration.tcl

-

-

-

double-conversion/build/generated/

-

-

-

double-conversion/build/Makefile

-

-

-

double-conversion/build/Testing/

-

-

-
- - -## 测试 - -1. 搭建OpenHarmony环境 - - 以hi3518ev300为例,编译出OpenHarmony镜像,烧写到开发板,参考[开发Hi3518第一个示例程序](https://device.harmonyos.com/cn/docs/start/introduce/oem_camera_start_example-0000001051610926)。 - - 进入系统如下所示: - - **图 1** OpenHarmony启动成功界面 - ![](figures/OpenHarmony启动成功界面.png "OpenHarmony启动成功界面") - -2. 挂载nfs目录,将[表2](#table1452412391911)中test目录下cctest可执行文件放入nfs目录 -3. 执行用例 - - 该库采用非交叉编译时用例是通过make test执行,CMake会有相关的执行结果统计;交叉编译时无法使用该方法,因此可直接执行生成的测试文件完成测试。 - - - 挂载成功后执行下列命令可列出用例所有条目: - - ``` - cd nfs - ./cctest --list - ``` - - 上述命令执行结果部分展示: - - ``` - test-bignum/Assign< - test-bignum/ShiftLeft< - test-bignum/AddUInt64< - test-bignum/AddBignum< - test-bignum/SubtractBignum< - test-bignum/MultiplyUInt32< - test-bignum/MultiplyUInt64< - test-bignum/MultiplyPowerOfTen< - test-bignum/DivideModuloIntBignum< - test-bignum/Compare< - test-bignum/PlusCompare< - test-bignum/Square< - test-bignum/AssignPowerUInt16< - test-bignum-dtoa/BignumDtoaVariousDoubles< - test-bignum-dtoa/BignumDtoaShortestVariousFloats< - test-bignum-dtoa/BignumDtoaGayShortest< - test-bignum-dtoa/BignumDtoaGayShortestSingle< - test-bignum-dtoa/BignumDtoaGayFixed< - test-bignum-dtoa/BignumDtoaGayPrecision< - test-conversions/DoubleToShortest< - test-conversions/DoubleToShortestSingle< - ... - ``` - - - 以test-bignum条目为例,执行下列命令开始测试: - - ``` - ./cctest test-bignum - ``` - - 测试结果如下则表示通过: - - ``` - Ran 13 tests. - ``` - - -## 将该库编译添加到OpenHarmony工程中 - -1. 复制库到OpenHarmony工程中 - - 拷贝已经能够成功交叉编译的库到OpenHarmony的third\_party目录,为了不修改要移植的三方库目录下的BUILD.gn文件,再添加一层目录放置新增的gn转CMake编译适配文件,新增的文件有BUILD.gn、build\_thirdparty.py、 config.gni,新增后的目录结构如下所示。 - - **表 3** 添加到工程后的目录结构 - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

openHarmony/third_party/double-conversion/BUILD.gn

-

将三方库加入工程的gn适配文件

-

openHarmony/third_party/double-conversion/build_thirdpaty.py

-

GN调用shell命令脚本文件,由上面GN文件将相关命令传入,实现GN转CMake

-

openHarmony/third_party/double-conversion/config.gni

-

三方库编译配置文件,可修改该文件来配置用例是否参与构建等

-

openHarmony/third_party/double-conversion/double-conversion/

-

要移植的三方库目录

-
- -2. 添加gn到CMake适配文件 - - - **新增的BUILD.gn文件实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony平台时只需修改路径即可**。 - - ``` - import("config.gni") - group("double-conversion") { - if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - deps = [":make"] - } - } - if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - action("make") { - script = "//third_party/double-conversion/build_thirdparty.py" - outputs = ["$root_out_dir/log_dc.txt"] - exec_path = rebase_path(rebase_path("./build", ohos_third_party_dir)) - command = "rm * .* -rf && $CMAKE_TOOLS_PATH/cmake .. $CMAKE_FLAG $CMAKE_TOOLCHAIN_FLAG && make -j" - args = [ - "--path=$exec_path", - "--command=${command}" - ] - } - } - ``` - - - **新增的config.gni用于配置该库,实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony时只需修改CMAKE\_FLAG的配置即可。** - - ``` - #CMAKE_FLAG: config compile feature - CMAKE_FLAG = "-DBUILD_TESTING=ON -DCMAKE_CXX_STANDARD=11" - - #toolchain:follow up-layer,depend on $ohos_build_compiler - if (ohos_build_compiler == "clang") { - CMAKE_TOOLCHAIN_FLAG = "-DOHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" - } else { - CMAKE_TOOLCHAIN_FLAG = "" - } - - #CMake tools path,no need setting if this path already joined to $PATH. - CMAKE_TOOLS_PATH = "setting CMake tools path..." - ``` - - - **新增的build\_thirdparty.py实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony时无需修改即可使用。** - - ``` - import os - import sys - from subprocess import Popen - import argparse - import shlex - - def cmd_exec(command): - cmd = shlex.split(command) - proc = Popen(cmd) - proc.wait() - ret_code = proc.returncode - if ret_code != 0: - raise Exception("{} failed, return code is {}".format(cmd, ret_code)) - - def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--path', help='Build path.') - parser.add_argument('--command', help='Build command.') - parser.add_argument('--enable', help='enable python.', nargs='*') - args = parser.parse_args() - - if args.enable: - if args.enable[0] == 'false': - return - - if args.path: - curr_dir = os.getcwd() - os.chdir(args.path) - if args.command: - if '&&' in args.command: - command = args.command.split('&&') - for data in command: - cmd_exec(data) - else: - cmd_exec(args.command) - os.chdir(curr_dir) - - if __name__ == '__main__': - sys.exit(main()) - ``` - - - 在配置文件中添加开关控制该库编译,默认设为关闭 - - 在//build/lite/ohos\_var.gni文件中添加下列配置: - - ``` - declare_args() { - ohos_build_thirdparty_migrated_from_fuchisa = true - } - ``` - -3. 编译构建 - - - 手动单独构建: - - 执行下列命令 - - ``` - hb build -T //third_party/double-conversion:double-conversion - ``` - - 编译成功则[build](#li15717101715249)目录下会生成静态库文件和测试用例 - - diff --git "a/zh-cn/device-dev/porting/Makefile\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" "b/zh-cn/device-dev/porting/Makefile\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" deleted file mode 100755 index a2a6a92ee5a1723f8e5981139bc642a67e7ab9e0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/Makefile\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" +++ /dev/null @@ -1,309 +0,0 @@ -# Makefile方式组织编译的库移植 - -- [源码获取](#section114115321416) -- [设置交叉编译](#section81263255384) -- [测试](#section1830015913391) -- [将该库编译添加到OpenHarmony工程中](#section1898016213406) - -以yxml库为例,其移植过程如下文所示 - -## 源码获取 - -从仓库[获取yxml源码](https://github.com/getdnsapi/yxml),其目录结构如下表: - -**表 1** 源码目录结构 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

yxml/bench/

-

benchmark相关代码

-

yxml/test/

-

测试输入输出文件,及测试脚本

-

yxml/Makefile

-

编译组织文件

-

yxml/.gitattributes

-

-

-

yxml/.gitignore

-

-

-

yxml/COPYING

-

-

-

yxml/yxml.c

-

-

-

yxml/yxml.c.in

-

-

-

yxml/yxml-gen.pl

-

-

-

yxml/yxml.h

-

-

-

yxml/yxml.md

-

-

-

yxml/yxml-states

-

-

-
- -## 设置交叉编译 - -设置Makefile的交叉编译工具链,修改并编译该库,生成OpenHarmony平台的可执行文件,步骤如下: - -1. 设置工具链 - - 将下列clang工具链配置替换掉yxml库根目录的MakeFile(即[表1中的文件](#table16520154171813))中的原有配置。 - - clang工具链配置 - - ``` - #设置交叉编译工具链,确保工具链所在路径已经添加到了PATH环境变量中 - CC:=clang - AR:=llvm-ar - #cflags中必须要添加--target及--sysroot选项 - CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g --target=arm-liteos -march=armv7-a --sysroot=$(OHOS_ROOT_PATH)prebuilts/lite/sysroot - ``` - - 原有配置 - - ``` - CC:=gcc - AR:=ar - CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g - ``` - -2. 执行编译 - - linux命令行中进入yxml的源文件目录(即图1所示目录),执行下列命令: - - ``` - make test OHOS_SYSROOT_PATH=... - ``` - - 其中OHOS\_SYSROOT\_PATH需用绝对路径指定出sysroot所在目录,以OpenHarmony为例即源码根目录prebuilts/lite/sysroot/所在的绝对路径。 - -3. 查看结果 - - 步骤2操作完成后,yxml下会生成out目录,里面有静态库文件和测试用例: - - **表 2** yxml编译生成目录 - - - - - - - - - - - - - -

名称

-

描述

-

openHarmony/third_party/yxml/yxml/out/lib/

-

编译生成的静态库的存放目录

-

openHarmony/third_party/yxml/yxml/out/test/

-

编译生成的测试用例及其输入输出等文件的存放目录

-
- - -## 测试 - -yxml库测试步骤与double-conversion库基本一致,可参考[CMake方式组织编译的库移植](CMake方式组织编译的库移植.md#section6686144293611)的测试过程,以下内容介绍yxml库测试用例的使用方法: - -**表 3** 生成的test目录结构示意 - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

openHarmony/third_party/yxml/yxml/out/test/test.sh

-

自动化测试脚本,由于OpenHarmony不支持脚本运行,因此无法使用,可参考其内容手动测试

-

openHarmony/third_party/yxml/yxml/out/test/test

-

用于测试的可执行文件

-

openHarmony/third_party/yxml/yxml/out/test/*.xml

-

测试输入文件

-

openHarmony/third_party/yxml/yxml/out/test/*.out

-

期望的输出文件

-
- -test.sh内容如下所示: - -``` -#!/bin/sh -for i in *.xml; do - b=`basename $i .xml` - o=${b}.out - t=${b}.test - ./test <$i >$t - if [ -n "`diff -q $o $t`" ]; then - echo "Test failed for $i:" - diff -u $o $t - exit 1 - fi -done -echo "All tests completed successfully." -``` - -由于OpenHarmony的shell中暂不支持输入输出重定向(<和\>),所以测试时需要将输入\*.xml文件内容直接复制进shell后回车,输出内容会直接展示在shell窗口。过程如下: - -下列操作假定已按照2.4节的步骤搭建OpenHarmony,挂载并进入nfs目录: - -1. 执行下列命令 - - ``` - ./test - ``` - -2. 复制\*.xml内容到shell - - 以[test目录](#table115941423164318)下pi01.xml为例,内容如下,输入到shell并回车: - - ``` - - ``` - -3. 比较shell中输出的内容与[test目录](#table115941423164318)中对应的\*.out文件是否一致 - - 输出结果如下: - - ``` - pistart SomePI - picontent abc - piend - elemstart a - elemend - ok - ``` - - 经比较与[test目录](#table115941423164318)下pi01.out内容一致,测试通过。 - - -## 将该库编译添加到OpenHarmony工程中 - -yxml库添加的过程除了适配文件build.gn和config.gni有些许变化外,其他和double-conversion库完全一致,参考[CMake方式组织编译的库移植](CMake方式组织编译的库移植.md#section1651053153715)的配置过程。要修改的适配文件及添加后的目录结构如下: - -- yxml库新增的BUILD.gn实现如下: - -``` -import("config.gni") -group("yxml") { - if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - deps = [":make"] - } -} -if (ohos_build_thirdparty_migrated_from_fuchisa == true) { - action("make") { - script = "//third_party/yxml/build_thirdparty.py" - outputs = ["$target_out_dir/log_yxml.txt"] - exec_path = rebase_path(rebase_path("./yxml", root_build_dir)) - command = "make clean && $MAKE_COMMAND" - args = [ - "--path=$exec_path", - "--command=${command}" - ] - } -} -``` - -- yxml库新增的config.gni配置如下: - -``` -TEST_ENABLE = "YES" - -if (TEST_ENABLE == "YES") { - MAKE_COMMAND = "make test OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" -} else { - MAKE_COMMAND = "make OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" -} -``` - -- 添加完成后目录结构示意: - -**表 4** 添加到工程后的目录结构 - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

openHarmony/third_party/yxml/BUILD.gn

-

将三方库加入工程的gn适配文件

-

openHarmony/third_party/yxml/build_thirdpaty.py

-

GN调用shell命令脚本文件,由上面GN文件将相关命令传入,实现GN转Makefile

-

openHarmony/third_party/yxml/config.gni

-

三方库编译配置文件,可修改该文件来配置用例是否参与构建等

-

openHarmony/third_party/yxml/yxml/

-

要移植的三方库目录

-
- diff --git a/zh-cn/device-dev/porting/Readme-CN.md b/zh-cn/device-dev/porting/Readme-CN.md old mode 100644 new mode 100755 index b6b112121c1d76bdbae69e3171b06900dfcda2e5..3019f69e70b7669d453d47902354e8119d0a805a --- a/zh-cn/device-dev/porting/Readme-CN.md +++ b/zh-cn/device-dev/porting/Readme-CN.md @@ -1,28 +1,28 @@ - -# 开发板移植 -目前OpenHarmony已经成立了SIG组[sig-devboard](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md)。该SIG组以支持更多第三方开发板为目标,提供开发板移植的支撑。 - -在了解开发板移植前,需要先了解一下OpenHarmony对设备的分类。不同设备类型的移植方法会有较大差异。 - -| 设备类型 | 硬件要求 | 支持的内核 | -|---------|-------------|----------------| -| 轻量系统类设备 | 内存>128KB | LiteOS-M | -| 小型系统类设备 | 内存>1MB、有MMU | LiteOS-A、Linux | -| 标准系统类设备 | 内存>128MB | Linux | - -# 1. 代码准备 - -目前OpenHarmony已经为各厂家创建了仓库并在openharmony-sig中进行孵化。参与孵化仓开发,需要使用如下方法初始化和下载代码。 - -```shell -repo init -u https://gitee.com/openharmony-sig/manifest.git -b master -m devboard.xml --no-repo-verify -``` - -其他下载步骤与主线相同。 - -# 2. 开始移植你的开发板 - -- [轻量级系统](lite-system-porting-guide.md) -- 小型系统(待发布) -- [标准系统](standard-system-porting-guide.md) - +# 开发板移植 +目前OpenHarmony已经成立了SIG组[sig-devboard](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md)。该SIG组以支持更多第三方开发板为目标,提供开发板移植的支撑。 + +在了解开发板移植前,需要先了解一下OpenHarmony对设备的分类。不同设备类型的移植方法会有较大差异。 + +| 设备类型 | 硬件要求 | 支持的内核 | +|---------|-------------|----------------| +| 轻量系统类设备 | 内存>128KB | LiteOS-M | +| 小型系统类设备 | 内存>1MB、有MMU | LiteOS-A、Linux | +| 标准系统类设备 | 内存>128MB | Linux | + +# 1. 代码准备 + +目前OpenHarmony已经为各厂家创建了仓库并在openharmony-sig中进行孵化。参与孵化仓开发,需要使用如下方法初始化和下载代码。 + +```shell +repo init -u https://gitee.com/openharmony-sig/manifest.git -b master -m devboard.xml --no-repo-verify +``` + +其他下载步骤与主线相同。 + +# 2. 开始移植你的开发板 + +- [轻量级系统](transplant-minichip.md) +- [小型系统](transplant-smallchip.md) +- [标准系统](standard-system-porting-guide.md) + + diff --git "a/zh-cn/device-dev/porting/XTS\350\256\244\350\257\201.md" "b/zh-cn/device-dev/porting/XTS\350\256\244\350\257\201.md" deleted file mode 100755 index 44b37d014423043bd25028ce5739076d44ac2e72..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/XTS\350\256\244\350\257\201.md" +++ /dev/null @@ -1,65 +0,0 @@ -# XTS认证 - -- [XTS简介](#section6725155811454) - - [将XTS认证子系统加入编译组件中](#section46981118105417) - - [执行联接类模组acts测试用例](#section9489122319819) - - -## XTS简介 - -XTS是OpenHarmony生态认证测试套件的集合,当前包括acts(application compatibility test suite)应用兼容性测试套。test/xts仓当前包括acts与tools软件包: - -- acts,存放acts相关测试用例源码与配置文件,其目的是帮助终端设备厂商尽早发现软件与OpenHarmony的不兼容性,确保软件在整个开发过程中满足OpenHarmony的兼容性要求。 -- tools,存放acts相关测试用例开发框架。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->XTS的启动依赖SAMGR系统服务。 - -适配分为两步,包括: - -1. 将XTS认证子系统加入编译组件中。 -2. 执行联接类模组acts测试用例。 - -### 将XTS认证子系统加入编译组件中 - -举例:将XTS认证子系统加入hispark\_aries产品编译组件中为例。 - -1. 在vendor/hisilicon/hispark\_aries/config.json中加入XTS认证子系统定义: - - ``` - { - "subsystem": "test", - "components": [ - { "component": "xts_acts", "features":[] }, - { "component": "xts_tools", "features":[] } - ] - }, - ``` - -2. Debug版本才会触发XTS认证子系统编译; - -### 执行联接类模组acts测试用例 - -举例:以hispark\_aries产品执行联接类模组acts测试用例为例。 - -1. 获取编译镜像。 - - 请在如下目录获取版本镜像:out/hispark\_pegasus/wifiiot\_hispark\_pegasus/。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >判断当前版本镜像是否集成acts测试套件方法:在map文件中查看对应.a是否被编译即可。 - -2. 版本镜像烧录进开发板。 -3. 测试步骤。 - - (1)使用串口工具登录开发板,并保存串口打印信息。 - - (2)重启设备,查看串口日志。 - -4. 测试结果分析指导。 - - (1)基于串口打印日志进行分析; - - (2)每个测试套件执行以“Start to run test suite”开始,以“xx Tests xx Failures xx Ignored”结束。 - - diff --git a/zh-cn/device-dev/porting/figures/HDF_WIFI.png b/zh-cn/device-dev/porting/figure/HDF_WIFI.png similarity index 100% rename from zh-cn/device-dev/porting/figures/HDF_WIFI.png rename to zh-cn/device-dev/porting/figure/HDF_WIFI.png diff --git "a/zh-cn/device-dev/porting/figures/OpenHarmony\345\220\257\345\212\250\346\210\220\345\212\237\347\225\214\351\235\242.png" "b/zh-cn/device-dev/porting/figure/OpenHarmony\345\220\257\345\212\250\346\210\220\345\212\237\347\225\214\351\235\242.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/figures/OpenHarmony\345\220\257\345\212\250\346\210\220\345\212\237\347\225\214\351\235\242.png" rename to "zh-cn/device-dev/porting/figure/OpenHarmony\345\220\257\345\212\250\346\210\220\345\212\237\347\225\214\351\235\242.png" diff --git a/zh-cn/device-dev/porting/figure/init.jpg b/zh-cn/device-dev/porting/figure/init.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a1e7f8b695bebf395ea6cfa0aed55495c4896118 Binary files /dev/null and b/zh-cn/device-dev/porting/figure/init.jpg differ diff --git a/zh-cn/device-dev/porting/figure/shell.jpg b/zh-cn/device-dev/porting/figure/shell.jpg new file mode 100644 index 0000000000000000000000000000000000000000..efb1e17b00d37b072a3032678144984e2e13b2d6 Binary files /dev/null and b/zh-cn/device-dev/porting/figure/shell.jpg differ diff --git a/zh-cn/device-dev/porting/figures/zh-cn_image_0000001072304191.png b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001072304191.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/porting/figures/zh-cn_image_0000001072304191.png rename to zh-cn/device-dev/porting/figure/zh-cn_image_0000001072304191.png diff --git a/zh-cn/device-dev/porting/figures/zh-cn_image_0000001073943511.png b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001073943511.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/porting/figures/zh-cn_image_0000001073943511.png rename to zh-cn/device-dev/porting/figure/zh-cn_image_0000001073943511.png diff --git a/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126198996.png b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126198996.png new file mode 100644 index 0000000000000000000000000000000000000000..cbc70a899f77382e9e052c30f2a69b61764d2643 Binary files /dev/null and b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126198996.png differ diff --git a/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126354076.png b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126354076.png new file mode 100644 index 0000000000000000000000000000000000000000..b241920b30fea1b2a432f6ba01045bbfbae7fb58 Binary files /dev/null and b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126354076.png differ diff --git a/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126358814.png b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126358814.png new file mode 100644 index 0000000000000000000000000000000000000000..39c6cb96611a7ced5e17bbeee96ac77ba5c1bf58 Binary files /dev/null and b/zh-cn/device-dev/porting/figure/zh-cn_image_0000001126358814.png differ diff --git "a/zh-cn/device-dev/porting/figure/\345\206\205\346\240\270\345\220\257\345\212\250\346\241\206\346\236\266.jpg" "b/zh-cn/device-dev/porting/figure/\345\206\205\346\240\270\345\220\257\345\212\250\346\241\206\346\236\266.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..dd8e1c235633c3e42fcd1360b66b3ce3452db02d Binary files /dev/null and "b/zh-cn/device-dev/porting/figure/\345\206\205\346\240\270\345\220\257\345\212\250\346\241\206\346\236\266.jpg" differ diff --git "a/zh-cn/device-dev/porting/figure/\345\210\206\347\261\273.png" "b/zh-cn/device-dev/porting/figure/\345\210\206\347\261\273.png" new file mode 100644 index 0000000000000000000000000000000000000000..7edac54ec2fcd1fc93330d47acb2d44fceef2710 Binary files /dev/null and "b/zh-cn/device-dev/porting/figure/\345\210\206\347\261\273.png" differ diff --git "a/zh-cn/device-dev/porting/figures/\345\215\225\346\235\277\351\251\261\345\212\250\351\200\202\351\205\215\346\265\201\347\250\213.png" "b/zh-cn/device-dev/porting/figure/\345\215\225\346\235\277\351\251\261\345\212\250\351\200\202\351\205\215\346\265\201\347\250\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/figures/\345\215\225\346\235\277\351\251\261\345\212\250\351\200\202\351\205\215\346\265\201\347\250\213.png" rename to "zh-cn/device-dev/porting/figure/\345\215\225\346\235\277\351\251\261\345\212\250\351\200\202\351\205\215\346\265\201\347\250\213.png" diff --git "a/zh-cn/device-dev/porting/figures/\350\212\257\347\211\207\347\247\273\346\244\215\345\205\263\351\224\256\346\255\245\351\252\244.png" "b/zh-cn/device-dev/porting/figure/\350\212\257\347\211\207\347\247\273\346\244\215\345\205\263\351\224\256\346\255\245\351\252\244.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/figures/\350\212\257\347\211\207\347\247\273\346\244\215\345\205\263\351\224\256\346\255\245\351\252\244.png" rename to "zh-cn/device-dev/porting/figure/\350\212\257\347\211\207\347\247\273\346\244\215\345\205\263\351\224\256\346\255\245\351\252\244.png" diff --git a/zh-cn/device-dev/porting/lite-system-porting-guide.md b/zh-cn/device-dev/porting/lite-system-porting-guide.md deleted file mode 100755 index 0dca00c895f6172ce990465be705745d7b8965db..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/porting/lite-system-porting-guide.md +++ /dev/null @@ -1,27 +0,0 @@ -# 移植指南 - -- [三方库移植指导](三方库移植指导.md) - - [概述](概述.md) - - [CMake方式组织编译的库移植](CMake方式组织编译的库移植.md) - - [Makefile方式组织编译的库移植](Makefile方式组织编译的库移植.md) - -- [三方芯片移植指导](三方芯片移植指导.md) - - [移植准备](移植准备.md) - - [移植须知](移植须知.md) - - [编译构建适配流程](编译构建适配流程.md) - - - [内核移植](内核移植.md) - - [移植概述](移植概述.md) - - [内核基础适配](内核基础适配.md) - - [内核移植验证](内核移植验证.md) - - - [板级系统移植](板级系统移植.md) - - [移植概述](移植概述-0.md) - - [板级驱动适配](板级驱动适配.md) - - [HAL层实现](HAL层实现.md) - - [系统组件调用](系统组件调用.md) - - [三方组件适配](三方组件适配.md) - - [XTS认证](XTS认证.md) - - - [常见问题](常见问题.md) - diff --git a/zh-cn/device-dev/porting/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/porting/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/porting/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/porting/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/porting/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/porting/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/porting/public_sys-resources/icon-note.gif b/zh-cn/device-dev/porting/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/porting/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/porting/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/porting/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/porting/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/porting/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/porting/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/porting/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/porting/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/porting/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/porting/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/zh-cn/device-dev/porting/standard-system-porting-guide.md b/zh-cn/device-dev/porting/standard-system-porting-guide.md index d706df125f8525c8255306bbf8c3261d6bf70e8e..4810ecb0164ec63298b9b7daac678be294b58b6e 100644 --- a/zh-cn/device-dev/porting/standard-system-porting-guide.md +++ b/zh-cn/device-dev/porting/standard-system-porting-guide.md @@ -246,7 +246,7 @@ HDF_INIT(g_touchXXXXChipEntry); Wi-Fi驱动分为两部分,一部分负责管理WLAN设备,另一个部分负责处理WLAN流量。`HDF WLAN`分别为这两部分做了抽象。目前支持SDIO接口的WLAN芯片。 -Wi-Fi结构图 +Wi-Fi结构图 支持一款芯片的主要工作是实现一个ChipDriver驱动。实现HDF_WLAN_CORE和NetDevice提供的接口。主要需要实现的接口有: @@ -375,4 +375,4 @@ obj-$(CONFIG_DRIVERS_WLAN_XXX) += $(HDF_DEVICE_ROOT)/MySoCVendor/peripheral/buil 当在内核中开启`DRIVERS_WLAN_XXX`开关时,会调用`//device/MySoCVendor/peripheral/build/standard/`中的makefile。 -更多详细的开发手册,请参考[WLAN开发](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/WLAN.md)。 +更多详细的开发手册,请参考[WLAN开发](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/WLAN.md)。 \ No newline at end of file diff --git a/zh-cn/device-dev/porting/transplant-chip-board-bundle.md b/zh-cn/device-dev/porting/transplant-chip-board-bundle.md new file mode 100644 index 0000000000000000000000000000000000000000..8e235f7c54dd67da05510aa4f0e80a4e71e2c183 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-board-bundle.md @@ -0,0 +1,57 @@ +# 三方组件适配 + +如果需要使用third\_party目录下与产品相关的三方组件,可能需要对三方组件进行适配,下面以比较常用的mbedtls为例,介绍下适配步骤,注意本小节中仅介绍如何将适配的代码与OpenHarmony的编译框架融合,不会详细介绍mbedtls本身的原理和适配代码的具体逻辑,这些内容请参考mbedtls官方网站上的适配指南。 + +1. 编写适配层代码 + + 根据mbedtls官网的适配指南,编写需要的适配层代码,以适配硬件随机数举例,下面的路径都是相对third\_party/mbedtls的路径: + + 1. 拷贝include/mbedtls/config.h到ports目录下,并修改打开MBEDTLS\_ENTROPY\_HARDWARE\_ALT开关。 + 2. 在ports目录下创建entropy\_poll\_alt.c文件include并实现entropy\_poll.h中的硬件随机数接口 + 3. 在BUILD.gn中的mbedtls\_sources中增加刚才适配的entropy\_poll\_alt.c的路径 + 4. 在BIULD.gn中的lite\_library\("mbedtls\_static"\)中增加一行MBEDTLS\_CONFIG\_FILE指定新配置文件的位置 + + ``` + lite_library("mbedtks_static") { + ... + defines += ["MBEDTLS_CONFIG_FILE=<../port/config.h>"] + ... + } + ``` + + + 注意,上面的修改最好都新建一个config或者新建一个xxx\_alt.c文件来修改,不要直接在原先的代码中修改,侵入式的修改会导致后续版本升级出现大量零散冲突,增加升级维护成本。 + +2. 制作patch + + 由于上面的适配是硬件相关的,上库代码时,不能直接放到通用的third\_party/mbedtls目录中,因此需要将上面的修改制作成patch,在编译之前通过打patch的方式注入到代码中。 + + 1. 首先增加设备的patch配置文件device///patch.yml + 2. 编辑device///patch.yml,增加要打的patch的信息: + + ``` + # 需要打patch的路径,路径均为相对代码根目录的路径 + third_party/mbedtls: + # 该路径下需要打的patch存放路径 + - device///third_party/mbedtls/adapter.patch + third_party/wpa_supplicant: + # 当一个路径下有多个patch的时候会依次执行patch + - device///third_party/wpa_supplicant/xxxxx.patch + - device///third_party/wpa_supplicant/yyyyy.patch + ... + ``` + + 3. 制作上述**步骤1**修改的patch并放到对应的目录即可 + +3. 使用带patch的编译 + + 想要在编译的时候带上patch,其他步骤不变,仅需要在触发编译的时候加上 --patch,例如全编译的命令编程 + + ``` + hb build -f --patch + ``` + + >![](../public_sys-resources/icon-caution.gif) **注意:** + >最后一次打patch的产品信息会被记录,在进行下一次编译操作时,会对上一次的patch进行回退(即执行\`patch -p1 -R < xxx\`),回退patch失败或新增patch失败均会终止编译过程,请解决patch冲突后再次尝试编译。 + + diff --git a/zh-cn/device-dev/porting/transplant-chip-board-component.md b/zh-cn/device-dev/porting/transplant-chip-board-component.md new file mode 100644 index 0000000000000000000000000000000000000000..618fc8acfa8f796b8582551e5756c9b40d1eb934 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-board-component.md @@ -0,0 +1,26 @@ +# 系统组件调用 + +- [SAMGR](#section105874301910) +- [DFX](#section20064420420) + +系统组件为上层应用提供基础能力,包括SAMGR(系统服务框架子系统)、DFX子系统等。在板级系统移植过程中,只需要选择使用即可,不用对其进行适配。 + +## SAMGR + +**基本介绍** + +系统服务框架基于面向服务的架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务共进程、进程间服务调用等开发能力。 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>本组件在板级系统移植中必须要使用,否则其他服务组件无法运行。 + +**SAMGR使用说明,请参考:[SAMGR 使用指导](https://gitee.com/openharmony/distributedschedule_samgr_lite/blob/master/README_zh.md)** + +## DFX + +**基本介绍** + +DFX子系统主要包含DFR(Design for Reliability,可靠性)和DFT(Design for Testability,可测试性)特性,为开发者提供代码维测信息。 + +**DFX子系统使用说明,请参考:[DFX子系统使用指导](../subsystems/subsys-dfx-overview.md)** + diff --git "a/zh-cn/device-dev/porting/\346\235\277\347\272\247\351\251\261\345\212\250\351\200\202\351\205\215.md" b/zh-cn/device-dev/porting/transplant-chip-board-drive.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/\346\235\277\347\272\247\351\251\261\345\212\250\351\200\202\351\205\215.md" rename to zh-cn/device-dev/porting/transplant-chip-board-drive.md diff --git "a/zh-cn/device-dev/porting/HAL\345\261\202\345\256\236\347\216\260.md" b/zh-cn/device-dev/porting/transplant-chip-board-hal.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/HAL\345\261\202\345\256\236\347\216\260.md" rename to zh-cn/device-dev/porting/transplant-chip-board-hal.md diff --git a/zh-cn/device-dev/porting/transplant-chip-board-overview.md b/zh-cn/device-dev/porting/transplant-chip-board-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..732872af5b5e2558bf8b298f918872b2eec030b5 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-board-overview.md @@ -0,0 +1,57 @@ +# 移植概述 + +- [板级移植流程](#section1283115812294) +- [板级目录规范](#section6204129143013) + +## 板级移植流程 + +最小系统移植完成后,下一步进行板级系统移植,板级系统移植包含以下几步操作: + +1. 板级驱动适配。 +2. HAL层实现。 +3. XTS测试套。 +4. 业务功能验证。 + +**图 1** 单板驱动适配流程 +![](figure/单板驱动适配流程.png "单板驱动适配流程") + +## 板级目录规范 + +板级系统编译适配参考[编译系统介绍](transplant-chip-prepare-process.md),板级相关的驱动、SDK、目录、HAL实现存放在device目录,目录结构和具体描述如下: + +``` +. +├── device --- 单板样例 +│ └── xxx --- <单板厂商名> +│ └── xxx --- <单板名>,里面包含liteos-m内核的,并且能够运行的demo +│ ├── BUILD.gn --- 定义单板的编译配置文件 +│ ├── board --- 板子特定的实现(可选,如果本单板直接提供产品级demo,则相关应用层实现放在此目录) +│ ├── liteos_m --- 根据BUILD.gn文件中的kernel_type,使用liteos_m内核 +│ │ └── config.gni --- 编译选项 +│ ├── libraries --- 板级SDK +│ │ └── include --- SDK提供对外头文件 +│ │ └── ... --- binary or source +│ ├── main.c --- main函数入口(如果产品级存在相同定义,则使用产品级配置) +│ ├── target_config.h --- 板级内核配置 +│ ├── project --- 单板级工程配置文件(如果产品级存在相同定义,则使用产品级配置) +│ └── adapter --- 单板适配上层应用组件的适配层接口,根据能力可选 +│ └── hals +│ ├── communication +│ │ └── wifi_lite +│ │ ├── ... +│ └── iot_hardware +│ ├── upgrade +│ ├── utils +│ └── wifiiot_lite +├── vendor --- 提供端到端的OpenHarmony特性产品样例 +│ └── huawei --- 厂商名字 +│ └── wifiiot --- wifiiot表示特性产品 +│ ├── app +│ │ └── main.c --- 产品的main函数入口 +│ ├── project --- 工程配置文件 +│ ├── BUILD.gn --- 工程编译入口 +│ └── config.json --- 定义产品的编译配置文件,配置产品所使用的组件等。 +└── out --- 编译过程中的输出目录 + ├── ... --- 单板/产品编译产生的bin等 +``` + diff --git a/zh-cn/device-dev/porting/transplant-chip-board-xts.md b/zh-cn/device-dev/porting/transplant-chip-board-xts.md new file mode 100644 index 0000000000000000000000000000000000000000..00253685f7583381c9a5d89bd24a57bf2a7d3dcc --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-board-xts.md @@ -0,0 +1,65 @@ +# XTS认证 + +- [XTS简介](#section6725155811454) + - [将XTS认证子系统加入编译组件中](#section46981118105417) + - [执行联接类模组acts测试用例](#section9489122319819) + + +## XTS简介 + +XTS是OpenHarmony生态认证测试套件的集合,当前包括acts(application compatibility test suite)应用兼容性测试套。test/xts仓当前包括acts与tools软件包: + +- acts,存放acts相关测试用例源码与配置文件,其目的是帮助终端设备厂商尽早发现软件与OpenHarmony的不兼容性,确保软件在整个开发过程中满足OpenHarmony的兼容性要求。 +- tools,存放acts相关测试用例开发框架。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>XTS的启动依赖SAMGR系统服务。 + +适配分为两步,包括: + +1. 将XTS认证子系统加入编译组件中。 +2. 执行联接类模组acts测试用例。 + +### 将XTS认证子系统加入编译组件中 + +举例:将XTS认证子系统加入hispark\_aries产品编译组件中为例。 + +1. 在vendor/hisilicon/hispark\_aries/config.json中加入XTS认证子系统定义: + + ``` + { + "subsystem": "test", + "components": [ + { "component": "xts_acts", "features":[] }, + { "component": "xts_tools", "features":[] } + ] + }, + ``` + +2. Debug版本才会触发XTS认证子系统编译; + +### 执行联接类模组acts测试用例 + +举例:以hispark\_aries产品执行联接类模组acts测试用例为例。 + +1. 获取编译镜像。 + + 请在如下目录获取版本镜像:out/hispark\_pegasus/wifiiot\_hispark\_pegasus/。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >判断当前版本镜像是否集成acts测试套件方法:在map文件中查看对应.a是否被编译即可。 + +2. 版本镜像烧录进开发板。 +3. 测试步骤。 + + (1)使用串口工具登录开发板,并保存串口打印信息。 + + (2)重启设备,查看串口日志。 + +4. 测试结果分析指导。 + + (1)基于串口打印日志进行分析; + + (2)每个测试套件执行以“Start to run test suite”开始,以“xx Tests xx Failures xx Ignored”结束。 + + diff --git a/zh-cn/device-dev/porting/transplant-chip-board.md b/zh-cn/device-dev/porting/transplant-chip-board.md new file mode 100644 index 0000000000000000000000000000000000000000..f5d7b754b53786192eec6ce7572833fa12329c8e --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-board.md @@ -0,0 +1,15 @@ +# 板级系统移植 + +- **[移植概述](transplant-chip-board-overview.md)** + +- **[板级驱动适配](transplant-chip-board-drive.md)** + +- **[HAL层实现](transplant-chip-board-hal.md)** + +- **[系统组件调用](transplant-chip-board-component.md)** + +- **[三方组件适配](transplant-chip-board-bundle.md)** + +- **[XTS认证](transplant-chip-board-xts.md)** + + diff --git "a/zh-cn/device-dev/porting/\345\270\270\350\247\201\351\227\256\351\242\230.md" b/zh-cn/device-dev/porting/transplant-chip-faqs.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/\345\270\270\350\247\201\351\227\256\351\242\230.md" rename to zh-cn/device-dev/porting/transplant-chip-faqs.md diff --git a/zh-cn/device-dev/porting/transplant-chip-kernel-adjustment.md b/zh-cn/device-dev/porting/transplant-chip-kernel-adjustment.md new file mode 100644 index 0000000000000000000000000000000000000000..40f82e0cd778cc360d659cba3363f5c94e560745 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-kernel-adjustment.md @@ -0,0 +1,83 @@ +# 内核基础适配 + +- [基础适配](#section14523241594) +- [特性配置项](#section112994366592) + +芯片架构适配完成后,liteos-m提供系统运行所需的系统初始化流程和定制化配置选项。移植过程中,需要关注初始化流程中跟硬件配置相关的函数;了解内核配置选项,才能裁剪出适合单板的最小内核。 + +## 基础适配 + +如下图所示,基础适配主要分为以下两步: + +1. 启动文件startup.S和相应链接配置文件。 +2. main. c中的串口初始化和tick中断注册。 + +**图 1** 启动流程 + + +![](figure/zh-cn_image_0000001073943511.png) + +启动文件startup.S需要确保中断向量表的入口函数(例如reset\_vector)放在RAM的首地址,它由链接配置文件来指定。其中iar、keil和gcc工程的链接配置文件分别为xxx.icf、xxx.sct和xxx.ld,如果startup.S已经完成系统时钟初始化,并且能够引导到main函数,则启动文件不需要进行修改,采用厂商自带的startup.S即可,否则需要实现以上功能。 + +在main.c文件中,需要关注串口初始化UartInit和系统Tick的handler函数注册。 + +- UartInit函数表示单板串口的初始化,具体的函数名根据单板自行定义。这个函数是可选的,用户可以根据硬件单板是否支持串口来自行选择调用该函数。如果硬件单板支持串口,则该函数需要完成使能串口TX和RX通道,设置波特率。 +- HalTickStart设置tick中断的handler函数OsTickHandler。 + +对于中断向量表不可重定向的芯片,需要关闭LOSCFG\_PLATFORM\_HWI宏,并且在startup.S中新增tick中断的handler函数。 + +## 特性配置项 + +liteos\_m的完整配置能力及默认配置在los\_config.h定义,该头文件中的配置项可以根据不同的单板进行裁剪配置。 + +如果针对这些配置项需要进行不同的板级配置,则可将对应的配置项直接定义到对应单板的device/xxxx/target\_config.h文件中,其他未定义的配置项,采用los\_config.h中的默认值。 + +一份典型的配置参数如下: + +**表 1** 内核典型配置项说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

配置项

+

说明

+

LOSCFG_BASE_CORE_SWTMR

+

软件定时器特性开关,1表示打开,0表示关闭

+

LOSCFG_BASE_CORE_SWTMR_ALIGN

+

对齐软件定时器特性开,1表示打开,依赖软件定时器特性打开,0表示关闭

+

LOSCFG_BASE_IPC_MUX

+

mux功能开关,1表示打开,0表示关闭

+

LOSCFG_BASE_IPC_QUEUE

+

队列功能开关,1表示打开,0表示关闭

+

LOSCFG_BASE_IPC_SEM

+

信号量功能开关,1表示打开,0表示关闭

+

LOSCFG_PLATFORM_EXC

+

异常特性开关,1表示打开,0表示关闭

+

LOSCFG_KERNEL_PRINTF

+

打印特性开关,1表示打开,0表示关闭

+
+ diff --git a/zh-cn/device-dev/porting/transplant-chip-kernel-overview.md b/zh-cn/device-dev/porting/transplant-chip-kernel-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..34095a2318d181be7604f6c4ac4ce9bd4d614db2 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-kernel-overview.md @@ -0,0 +1,64 @@ +# 移植概述 + +- [移植场景](#section93781277367) +- [目录规范](#section18127744153119) +- [芯片架构适配点](#section137431650339) + +## 移植场景 + +芯片架构适配是可选过程,如果在liteos\_m/kernel/arch目录下已经支持对应芯片架构,则可以跳过芯片架构适配,进行单板适配过程,否则需要进行芯片架构移植工作。 + +## 目录规范 + +模组芯片使用的内核为liteos-m,liteos-m中主要分为KAL、Components、Kernel和Utils四个模块。 + +- KAL模块作为内核对外的接口依赖Components模块和Kernel模块。 +- Components模块可插拔,它依赖Kernel模块。 + +- 在Kernel模块中,其中硬件相关的代码放在kernel的arch目录中,其余为硬件无关的代码。内核功能集(task、sem等)的实现依赖硬件相关的arch代码,例如任务上下文切换、原子操作等。 +- Utils模块作为基础代码块,被其他模块依赖。 + +**图 1** liteos-m内核模块图 + + +![](figure/zh-cn_image_0000001072304191.png) + +内核的目录结构和说明如下: + +``` +. +├── components --- 移植可选组件,依赖内核,单独对外提供头文件 +├── kal --- 内核抽象层,提供内核对外接口,当前支持cmsis接口和部分posix接口 +├── kernel --- 内核最小功能集代码 +│ ├── arch --- 内核指令架构层代码 +│ │ ├── arm --- arm32架构的代码 +│ │ │ ├── cortex-m3 --- cortex-m3架构的代码 +│ │ │ │ ├── iar --- iar编译工具链实现 +│ │ │ │ ├── keil --- keil编译工具链实现 +│ │ │ │ └── xxx --- xxx编译工具链实现 +│ │ │ └── cortex-m4 --- cortex-m4架构的代码 +│ │ │ ├── iar --- iar编译工具链实现 +│ │ │ ├── keil --- keil编译工具链实现 +│ │ │ └── xxx --- xxx编译工具链实现 +│ │ ├── include --- 所有的arch需要实现的函数定义,内核依赖 +│ │ └── risc-v --- risk-v架构 +│ │ └── gcc --- iar编译工具链实现 +│ ├── include --- 内核最小功能集代码 +│ └── src --- 内核最小功能集代码 +└──utils --- 基础代码,作为依赖的最底层,被系统依赖 +``` + +## 芯片架构适配点 + +如内核的[目录结构](#section18127744153119)所示,arch/include定义通用的芯片架构所需要实现的函数,另外芯片架构相关的代码会有部分的汇编代码,而汇编代码会因编译工具链的不同而不同,因此在具体的芯片架构下,还包含不同工具链(iar、keil、gcc等)的实现。 + +arch/include 目录定义通用的文件以及函数列表,该目录下的所有函数在新增arch组件时都需要适配,详见每一个头文件: + +``` +los_arch.h --- 定义芯片架构初始化所需要的函数 +los_atomic.h --- 定义芯片架构所需要实现的原子操作函数 +los_context.h --- 定义芯片架构所需要实现的任务上下文相关函数 +los_interrupt.h --- 定义芯片架构所需要实现的中断和异常相关的函数 +los_timer.h --- 定义芯片架构所需要实现的系统时钟相关的函数 +``` + diff --git a/zh-cn/device-dev/porting/transplant-chip-kernel-verify.md b/zh-cn/device-dev/porting/transplant-chip-kernel-verify.md new file mode 100644 index 0000000000000000000000000000000000000000..fc16eeb224f18814ed2c114a8fe3f4a07fea59b3 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-kernel-verify.md @@ -0,0 +1,59 @@ +# 内核移植验证 + +在工程device目录下添加编译main.c示例程序文件,此示例程序的主要目的是:LOS\_KernelInit完成之后,创建两个任务,循环调度延时并打印日志信息,通过此方法可以验证系统是否可正常调度以及时钟是否正常。 + +``` +VOID TaskSampleEntry2(VOID) // 任务2的入口函数 +{ + while(1) { + LOS_TaskDelay(10000); + printf("taskSampleEntry2 running...\n"); + } +} + +VOID TaskSampleEntry1(VOID) // 任务1的入口函数 +{ + while(1) { + LOS_TaskDelay(2000); + printf("taskSampleEntry1 running...\n"); + } +} + +UINT32 TaskSample(VOID) +{ + UINT32 uwRet; + UINT32 taskID1,taskID2; + TSK_INIT_PARAM_S stTask1={0}; + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1; + stTask1.uwStackSize = 0X1000; + stTask1.pcName = "taskSampleEntry1"; + stTask1.usTaskPrio = 6; //stTask1的任务优先级设定,不同于stTask2 + uwRet = LOS_TaskCreate(&taskID1, &stTask1); + + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2; + stTask1.uwStackSize = 0X1000; + stTask1.pcName = "taskSampleEntry2"; + stTask1.usTaskPrio = 7; + uwRet = LOS_TaskCreate(&taskID2, &stTask1); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT int main(void) +{ + UINT32 ret; + UartInit(); // 硬件串口配置,通过串口输出调试日志,实际函数名根据单板实现不一样而不一样。 + printf("\n\rhello world!!\n\r"); + ret = LOS_KernelInit(); + TaskSample(); + if (ret == LOS_OK) { + LOS_Start(); // 开始系统调度,循环执行stTask1/stTask2任务,串口输出任务日志 + } + while (1) { + __asm volatile("wfi"); + } +} +``` + +第一个任务运行正常后,说明最小系统的核心流程基本OK;由于xts用例框架对外依赖较多,主要是utils、bootstrap的链接脚本和编译框架,暂时无法支撑内核单独跑xts;此处略过内核测试套的测试,可以通过[XTS测试套](transplant-chip-board-xts.md)来覆盖最小系统是否完整移植成功。 + diff --git a/zh-cn/device-dev/porting/transplant-chip-kernel.md b/zh-cn/device-dev/porting/transplant-chip-kernel.md new file mode 100644 index 0000000000000000000000000000000000000000..e27fea3d596d06af478a4b24eb46ddc8a6b81187 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-kernel.md @@ -0,0 +1,9 @@ +# 内核移植 + +- **[移植概述](transplant-chip-kernel-overview.md)** + +- **[内核基础适配](transplant-chip-kernel-adjustment.md)** + +- **[内核移植验证](transplant-chip-kernel-verify.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-chip-prepare-knows.md b/zh-cn/device-dev/porting/transplant-chip-prepare-knows.md new file mode 100644 index 0000000000000000000000000000000000000000..6c0282c492baf353133e15ad5fb6c24da7a2e8d9 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-prepare-knows.md @@ -0,0 +1,84 @@ +# 移植须知 + +- [移植目录](#section284217487490) +- [移植流程](#section639315306506) +- [移植规范](#section187870185219) + +本文为OpenHarmony平台系统开发人员和芯片(或模组)制造商提供基础的开发移植指导,典型的芯片架构例如cortex-m系列、risc-v系列等都可以按照本文进行移植,暂时不支持蓝牙服务。OpenHarmony是个持续演进的复杂项目,随着版本和API的改变,本文将会不断更新。 + +本文要求读者具有一定的嵌入式系统开发经验,因此它的重点未放在基本的OS基础介绍,而更多地描述OpenHarmony平台移植过程中主要操作和所需要关注的方面。 + +## 移植目录 + +OpenHarmony整体工程较为复杂,目录及实现为系统本身功能,如果不涉及复杂的特性增强,不需要关注每一层实现,移植过程中重点关注如下目录即可: + +**表 1** 移植过程中的重点目录 + + + + + + + + + + + + + + + + + + + +

目录名称

+

描述

+

/build/lite

+

OpenHarmony基础编译构建框架

+

/kernel/liteos_m

+

基础内核,其中芯片架构相关实现在arch目录下

+

/device

+

板级相关实现,各个三方厂商按照OpenHarmony规范适配实现,device下具体目录结构及移植过程参见板级系统移植

+

/vendor

+

产品级相关实现,主要由华为或者产品厂商贡献

+
+ +device目录规则:device/\{芯片解决方案厂商\}/\{开发板\}。以hisilicon的hispark\_taurus为例: + +``` +device +└── hisilicon # 芯片解决方案厂商名 + ├── common # 芯片解决方案开发板公共部分 + └── hispark_taurus # 开发板名称 + ├── BUILD.gn # 开发板编译入口 + ├── hals # 芯片解决方案厂商OS硬件适配 + ├── linux # linux版本 + │ └── config.gni # linux版本编译工具链和编译选项配置 + └── liteos_a # liteos-a版本 + └── config.gni # liteos_a版本编译工具链和编译选项配置 +``` + +vendor目录规则:vendor/\{产品解决方案厂商\}/\{产品名称\}。以华为的wifiiot产品为例: + +``` +vendor # 产品解决方案厂商 +└── huawei # 产品解决方案厂商名称 + └── wifiiot # 产品名称 + ├── hals # 产品解决方案厂商OS适配 + ├── BUILD.gn # 产品编译脚本 + └── config.json # 产品配置文件 +``` + +## 移植流程 + +OpenHarmony的device目录是基础芯片的适配目录,如果在三方芯片应用过程中发现此目录下已经有完整的芯片适配,则不需要再额外移植,直接跳过移植过程进行系统应用开发即可,如果该目录下无对应的芯片移植实现,则根据本文完成移植过程。OpenHarmony三方芯片移植主要过程如下: + +**图 1** 芯片移植关键步骤 +![](figure/芯片移植关键步骤.png "芯片移植关键步骤") + +## 移植规范 + +- 满足OpenHarmony[开源贡献基本规范和准则](https://gitee.com/openharmony/docs/blob/master/zh-cn/contribute/%E5%8F%82%E4%B8%8E%E8%B4%A1%E7%8C%AE.md)。 +- 三方芯片适配所需要贡献的代码主要在device、vendor和arch三个目录,参照[内核目录规范](transplant-chip-kernel-overview.md)和[板级目录规范](transplant-chip-board-overview.md#section6204129143013)满足基本目录命名和使用规范。 + diff --git "a/zh-cn/device-dev/porting/\347\274\226\350\257\221\346\236\204\345\273\272\351\200\202\351\205\215\346\265\201\347\250\213.md" b/zh-cn/device-dev/porting/transplant-chip-prepare-process.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/\347\274\226\350\257\221\346\236\204\345\273\272\351\200\202\351\205\215\346\265\201\347\250\213.md" rename to zh-cn/device-dev/porting/transplant-chip-prepare-process.md diff --git a/zh-cn/device-dev/porting/transplant-chip-prepare.md b/zh-cn/device-dev/porting/transplant-chip-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..358da845b74ef9ce278a3bff22ee09be59501cb2 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip-prepare.md @@ -0,0 +1,7 @@ +# 移植准备 + +- **[移植须知](transplant-chip-prepare-knows.md)** + +- **[编译构建适配流程](transplant-chip-prepare-process.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-chip.md b/zh-cn/device-dev/porting/transplant-chip.md new file mode 100644 index 0000000000000000000000000000000000000000..d0fbee119dd00fe8fb475196714a9a253e676f2b --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-chip.md @@ -0,0 +1,11 @@ +# 三方芯片移植指导 + +- **[移植准备](transplant-chip-prepare.md)** + +- **[内核移植](transplant-chip-kernel.md)** + +- **[板级系统移植](transplant-chip-board.md)** + +- **[常见问题](transplant-chip-faqs.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-minichip.md b/zh-cn/device-dev/porting/transplant-minichip.md new file mode 100644 index 0000000000000000000000000000000000000000..58bebe026e881c23d1d2aa1cd173cc6bc86ea777 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-minichip.md @@ -0,0 +1,11 @@ +# 轻量系统芯片移植指导 + +- **[移植准备](transplant-chip-prepare.md)** + +- **[内核移植](transplant-chip-kernel.md)** + +- **[板级系统移植](transplant-chip-board.md)** + +- **[常见问题](transplant-chip-faqs.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-drive-des.md b/zh-cn/device-dev/porting/transplant-smallchip-drive-des.md new file mode 100644 index 0000000000000000000000000000000000000000..bba3736632bc974821981b0e4839f629ab4d1551 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-drive-des.md @@ -0,0 +1,11 @@ +# 移植概述 + +驱动主要包含两部分,平台驱动和器件驱动。平台驱动主要包括通常在SOC内的GPIO、I2C、SPI等;器件驱动则主要包含通常在SOC外的器件,如 LCD、TP、WLAN等。 + +**图 1** OpenHarmony 驱动分类 + + +![](figure/分类.png) + +HDF驱动被设计为可以跨OS使用的驱动程序,HDF驱动框架会为驱动达成这个目标提供有力的支撑。开发HDF驱动中,请尽可能只使用HDF驱动框架提供的接口,否则会导致驱动丧失跨OS使用的特性。在开始驱动开发前,建议先了解[HDF驱动框架](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/HDF%E9%A9%B1%E5%8A%A8%E6%A1%86%E6%9E%B6.md)。 + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-drive-oom.md b/zh-cn/device-dev/porting/transplant-smallchip-drive-oom.md new file mode 100644 index 0000000000000000000000000000000000000000..353aa15d2a8b5b84c66b3192fc30ccc8c6975694 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-drive-oom.md @@ -0,0 +1,390 @@ +# 器件驱动移植 + +- [LCD驱动移植](#section1574513454119) +- [TP驱动移植](#section20284142116422) +- [WLAN驱动移植](#section0969448164217) + +本章节讲解如何移植各类器件驱动。 + +## LCD驱动移植 + +移植LCD驱动的主要工作是编写一个驱动,在驱动中生成模型的实例,并完成注册。 + +这些LCD的驱动被放置在源码目录//drivers/framework/model/display/driver/panel中。 + +1. 创建Panel驱动 + + 创建HDF驱动,在驱动初始化中调用RegisterPanel接口注册模型实例。如: + + ``` + int32_t LCDxxEntryInit(struct HdfDeviceObject *object) + { + struct PanelData *panel = CreateYourPanel(); + // 注册模型实例 + if (RegisterPanel(panel) != HDF_SUCCESS) { + HDF_LOGE("%s: RegisterPanel failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + struct HdfDriverEntry g_xxxxDevEntry = { + .moduleVersion = 1, + .moduleName = "LCD_XXXX", + .Init = LCDxxEntryInit, + }; + + HDF_INIT(g_xxxxDevEntry); + ``` + +2. 配置加载panel驱动 + + 产品的所有设备信息被定义在源码文件//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs中。修改该文件,在display的host中,名为device\_lcd的device中增加配置。 + + >![](../public_sys-resources/icon-caution.gif) **注意:** + >moduleName 要与panel驱动中的moduleName相同。 + + ``` + root { + ... + display :: host { + device_lcd :: device { + deviceN :: deviceNode { + policy = 0; + priority = 100; + preload = 2; + moduleName = "LCD_XXXX"; + } + } + } + } + ``` + + +## TP驱动移植 + +本节描述如何移植触摸屏驱动。触摸屏的器件驱动被放置在源码目录//drivers/framework/model/input/driver/touchscreen中。 移植触摸屏驱动主要工作是向系统注册ChipDevice模型实例。 + +详细的驱动开发指导,请参考 [TOUCHSCREEN开发指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/TOUCHSCREEN.md)。 + +1. 创建触摸屏器件驱动 + + 在上述touchscreen目录中创建名为touch\_ic\_name.c的文件。编写如下内容 + + ``` + #include "hdf_touch.h" + + static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device) + { + ChipDevice *tpImpl = CreateXXXXTpImpl(); + if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) { // 注册ChipDevice模型 + ReleaseXXXXTpImpl(tpImpl); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + struct HdfDriverEntry g_touchXXXXChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_XXXX", // 注意这里的moduleName要与后续的配置完全一致 + .Init = HdfXXXXChipInit, + }; + + HDF_INIT(g_touchXXXXChipEntry); + ``` + + 其中ChipDevice中要实现如下方法: + + + + + + + + + + + + + + + + + + + + + + + + + +

方法

+

实现说明

+

int32_t (*Init)(ChipDevice *device)

+

实现器件初始化

+

int32_t (*Detect)(ChipDevice *device)

+

实现器件探测

+

int32_t (*Suspend)(ChipDevice *device)

+

实现器件休眠

+

int32_t (*Resume)(ChipDevice *device)

+

实现器件唤醒

+

int32_t (*DataHandle)(ChipDevice *device)

+

需要实现从器件读取数据,将触摸点数据填写入device->driver->frameData中

+

int32_t (*UpdateFirmware)(ChipDevice *device)

+

实现固件升级

+
+ +2. 配置产品,加载器件驱动 + + 产品的所有设备信息被定义在源码文件//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs中。修改该文件,在名为input的host中,名为device\_touch\_chip的device中增加配置。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >moduleName 要与触摸屏驱动中的moduleName相同。 + + ``` + deviceN :: deviceNode { + policy = 0; + priority = 130; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH_XXXX"; + deviceMatchAttr = "touch_XXXX_configs"; + } + ``` + + +## WLAN驱动移植 + +WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负责处理WLAN流量。 + +**图 1** OpenHarmony WLAN结构示意图 + + +![](figure/HDF_WIFI.png) + +如图1,左半部分负责管理WLAN设备,右半部分负责WLAN流量。HDF WLAN分别为这两部分做了抽象,驱动的移植过程可以看做分别实现这两部分所需接口。这些接口有: + + + + + + + + + + + + + + + + + + + + +

接口

+

定义头文件

+

接口说明

+

HdfChipDriverFactory

+

drivers\framework\include\wifi\hdf_wlan_chipdriver_manager.h

+

ChipDriver的Factory,用于支持一个芯片多个WLAN端口

+

HdfChipDriver

+

drivers\framework\include\wifi\wifi_module.h

+

每个WLAN端口对应一个HdfChipDriver,用来管理一个特定端口

+

NetDeviceInterFace

+

drivers\framework\include\wifi\net_device.h

+

与协议栈之间的接口,如发送数据、设置网络接口状态等

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>详细的接口开发指导,请参考[WLAN开发](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/WLAN.md)。 + +具体的移植步骤如下: + +1. 创建HDF WLAN 芯片驱动 + + 在目录/device/vendor\_name/peripheral/wifi/chip\_name/ 创建文件 hdf\_wlan\_chip\_name.c。内容模板如下: + + ``` + static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) { + static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); // 需要移植者实现的方法 + struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) { // 注册驱动工厂 + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + struct HdfDriverEntry g_hdfXXXChipEntry = { + .moduleVersion = 1, + .Init = HdfWlanXXXChipDriverInit, + .Release = HdfWlanXXXChipRelease, + .moduleName = "HDF_WIFI_CHIP_XXX" // 注意:这个名字要与配置一致 + }; + + HDF_INIT(g_hdfXXXChipEntry); + ``` + + 在上述代码的CreateChipDriverFactory方法中,需要创建一个HdfChipDriverFactory类型的对象。该对象提供如下方法 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口

+

说明

+

const char *driverName

+

当前driverName

+

int32_t (*InitChip)(struct HdfWlanDevice *device)

+

初始化芯片

+

int32_t (*DeinitChip)(struct HdfWlanDevice *device)

+

去初始化芯片

+

void (*ReleaseFactory)(struct HdfChipDriverFactory *factory)

+

释放HdfChipDriverFactory对象

+

struct HdfChipDriver *(*Build)(struct HdfWlanDevice *device, uint8_t ifIndex)

+

创建一个HdfChipDriver;输入参数中,device是设备信息,ifIndex是当前创建的接口在这个芯片中的序号

+

void (*Release)(struct HdfChipDriver *chipDriver)

+

释放chipDriver

+

uint8_t (*GetMaxIFCount)(struct HdfChipDriverFactory *factory)

+

获取当前芯片支持的最大接口数

+
+ + 其中Build方法负责创建一个管理指定网络接口的对象HdfChipDriver 。该对象需要提供方法: + + + + + + + + + + + + + + + + + + + + + + +

接口

+

说明

+

int32_t (*init)(struct HdfChipDriver *chipDriver, NetDevice *netDev)

+

初始化当前网络接口,这里需要向netDev提供接口NetDeviceInterFace

+

int32_t (*deinit)(struct HdfChipDriver *chipDriver, NetDevice *netDev)

+

去初始化当前网络接口

+

struct HdfMac80211BaseOps *ops

+

WLAN基础能力接口集

+

struct HdfMac80211STAOps *staOps

+

支持STA模式所需的接口集

+

struct HdfMac80211APOps *apOps

+

支持AP模式所需要的接口集

+
+ +2. 编写配置文件描述驱动支持的芯片 + + 在产品配置目录下创建芯片的配置文件,保存至源码路径//vendor/vendor\_name/product\_name/config/wifi/wlan\_chip\_chip\_name.hcs + + 该文件模板如下: + + ``` + root { + wlan_config { + chip_name :& chipList { + chip_name :: chipInst { + match_attr = "hdf_wlan_chips_chip_name"; /* 这是配置匹配属性,用于提供驱动的配置根 */ + driverName = "driverName"; /* 需要与HdfChipDriverFactory中的driverName相同*/ + sdio { + vendorId = 0xXXXX; /* your vendor id */ + deviceId = [0xXXXX]; /*your supported devices */ + } + } + } + } + } + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >路径和文件中的vendor\_name、product\_name、chip\_name请替换成实际名称 + >vendorId 和 deviceId需要根据实际芯片的识别码进行填写。 + +3. 编写配置文件,加载驱动 + + 产品的所有设备信息被定义在源码文件//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs中。修改该文件,在名为network的host中,名为device\_wlan\_chips的device中增加配置。模板如下: + + ``` + deviceN :: deviceNode { + policy = 0; + preload = 2; + moduleName = "HDF_WLAN_CHIPS"; + deviceMatchAttr = "hdf_wlan_chips_chip_name"; + serviceName = "driverName"; + } + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >moduleName 要与HDF WLAN 芯片驱动中的moduleName相同。 + +4. 修改Kconfig文件,让移植的WLAN模组出现再内核配置中 + + 在device/vendor\_name/drivers/Kconfig中增加配置菜单,模板如下 + + ``` + config DRIVERS_HDF_WIFI_chip_name + bool "Enable chip_name Host driver" + default n + depends on DRIVERS_HDF_WLAN help + Answer Y to enable chip_name Host driver. + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >请替换模板中的chip\_name为实际的芯片名称 + +5. 修改构建脚本,让驱动参与内核构建 + + 在源码文件//device/vendor\_name/drivers/lite.mk末尾追加如下内容 + + ``` + ifeq ($(LOSCFG_DRIVERS_HDF_WIFI_chip_name), y) + # 构建完成要链接一个叫hdf_wlan_chipdriver_chip_name的对象,建议按这个命名,防止冲突 + LITEOS_BASELIB += -lhdf_wlan_chipdriver_chip_name + # 增加构建目录gpio + LIB_SUBDIRS += ../peripheral/wifi/chip_name + endif + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >请替换模板中的chip\_name为实际的芯片名称 + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-drive-plat.md b/zh-cn/device-dev/porting/transplant-smallchip-drive-plat.md new file mode 100644 index 0000000000000000000000000000000000000000..a28bc2faf3fae4cb54a85094e10a185d20b34041 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-drive-plat.md @@ -0,0 +1,165 @@ +# 平台驱动移植 + +在这一步,我们会在源码目录//device/vendor\_name/soc\_name/drivers 目录下创建平台驱动,如果你要移植的SOC的厂商还没有创建仓库的话,请联系[sig-devboard](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md)创建。 + +建议的目录结构: + +``` +device +├── vendor_name +│ ├── drivers +│ │ │ ├── common +│ │ │ ├── Kconfig # 厂商驱动内核菜单入口 +│ │ │ └── lite.mk # 构建的入口 +│ ├── soc_name +│ │ ├── drivers +│ │ │ ├── dmac +│ │ │ ├── gpio +│ │ │ ├── i2c +│ │ │ ├── LICENSE +│ │ │ ├── mipi_dsi +│ │ │ ├── mmc +│ │ │ ├── pwm +│ │ │ ├── README.md # docs 如果需要的话 +│ │ │ ├── README_zh.md +│ │ │ ├── rtc +│ │ │ ├── spi +│ │ │ ├── uart +│ │ │ └── watchdog +│ ├── board_name +``` + +HDF为所有的平台驱动都创建了驱动模型,移植平台驱动的主要工作是向模型注入实例。 这些模型你可以在源码目录//drivers/framework/support/platform/include中找到定义。 + +本节我们会以GPIO为例,讲解如何移植平台驱动,移植过程包含以下步骤: + +1. 创建GPIO驱动 + + 在源码目录//device/vendor\_name/soc\_name/drivers/gpio中创建文件soc\_name\_gpio.c 内容模板如下: + + ``` + #include "gpio_core.h" + + // 定义GPIO结构体,如果需要的话 + struct SocNameGpioCntlr { + struct GpioCntlr cntlr; // 这是HDF GPIO驱动框架需要的结构体 + int myData; // 以下是当前驱动自身需要的 + }; + + // Bind 方法在HDF驱动中主要用户对外发布服务,这里我们不需要,直接返回成功即可 + static int32_t GpioBind(struct HdfDeviceObject *device) + { + (void)device; + return HDF_SUCCESS; + } + + // Init方法时驱动初始化的入口,我们需要在Init方法中完成模型实例的注册 + static int32_t GpioInit(struct HdfDeviceObject *device) + { + SocNameGpioCntlr *impl = CreateGpio(); // 你的创建代码 + ret = GpioCntlrAdd(&impl->cntlr); // 注册GPIO模型实例 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: err add controller:%d", __func__, ret); + return ret; + } + return HDF_SUCCESS; + } + + // Release方法会在驱动卸载时被调用,这里主要完成资源回收 + static void GpioRelease(struct HdfDeviceObject *device) + { + // GpioCntlrFromDevice 方法能从抽象的设备对象中获得init方法注册进去的模型实例。 + struct GpioCntlr *cntlr = GpioCntlrFromDevice(device); + //资源释放... + } + + struct HdfDriverEntry g_gpioDriverEntry = { + .moduleVersion = 1, + .Bind = GpioBind, + .Init = GpioInit, + .Release = GpioRelease, + .moduleName = "SOC_NAME_gpio_driver", // 这个名字我们稍后会在配置文件中用到,用来加载驱动。 + }; + HDF_INIT(g_gpioDriverEntry); // 注册一个GPIO的驱动入口 + ``` + +2. 创建厂商驱动构建入口 + + 如前所述device/vendor\_name/drivers/lite.mk是厂商驱动的构建的入口。我们需要从这个入口开始,进行构建 + + ``` + #文件device/vendor_name/drivers/lite.mk + + SOC_VENDOR_NAME := $(subst $/",,$(LOSCFG_DEVICE_COMPANY)) + SOC_NAME := $(subst $/",,$(LOSCFG_PLATFORM)) + BOARD_NAME := $(subst $/",,$(LOSCFG_PRODUCT_NAME)) + + # 指定SOC进行构建 + LIB_SUBDIRS += $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR_NAME)/$(SOC_NAME)/drivers/ + ``` + +3. 创建SOC驱动构建入口 + + ``` + #文件device/vendor_name/soc_name/drivers/lite.mk + + SOC_DRIVER_ROOT := $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR_NAME)/$(SOC_NAME)/drivers/ + + # 判断如果打开了GPIO的内核编译开关 + ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO), y) + # 构建完成要链接一个叫hdf_gpio的对象 + LITEOS_BASELIB += -lhdf_gpio + # 增加构建目录gpio + LIB_SUBDIRS += $(SOC_DRIVER_ROOT)/gpio + endif + + # 后续其他驱动在此基础上追加 + ``` + +4. 创建GPIO构建入口 + + ``` + include $(LITEOSTOPDIR)/config.mk + include $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mk + + # 指定输出对象的名称,注意要与SOC驱动构建入口里的LITEOS_BASELIB 保持一致 + MODULE_NAME := hdf_gpio + + # 增加HDF框架的INCLUDE + LOCAL_CFLAGS += $(HDF_INCLUDE) + + # 要编译的文件 + LOCAL_SRCS += soc_name_gpio.c + + # 编译参数 + LOCAL_CFLAGS += -fstack-protector-strong -Wextra -Wall -Werror -fsigned-char -fno-strict-aliasing -fno-common + + include $(HDF_DRIVER) + ``` + +5. 配置产品加载驱动 + + 产品的所有设备信息被定义在源码文件//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs中。 + + 平台驱动请添加到platform的host中。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >moduleName要与驱动定义中的相同。 + + ``` + root { + ... + platform :: host { + device_gpio :: device { + device0 :: deviceNode { + policy = 0; + priority = 10; + permission = 0644; + moduleName = "SOC_NAME_gpio_driver"; + } + } + } + } + ``` + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-drive.md b/zh-cn/device-dev/porting/transplant-smallchip-drive.md new file mode 100644 index 0000000000000000000000000000000000000000..8d265ae4d089593010d0ddd7ef6bcbc0ab327f99 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-drive.md @@ -0,0 +1,9 @@ +# 驱动移植 + +- **[移植概述](transplant-smallchip-drive-des.md)** + +- **[平台驱动移植](transplant-smallchip-drive-plat.md)** + +- **[器件驱动移植](transplant-smallchip-drive-oom.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-kernel-a.md b/zh-cn/device-dev/porting/transplant-smallchip-kernel-a.md new file mode 100644 index 0000000000000000000000000000000000000000..f4de2f397dbc53de27f711e7bfa1e909a35b222c --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-kernel-a.md @@ -0,0 +1,265 @@ +# LiteOS-A内核 + +- [移植概述](#section14876256185510) + - [移植场景](#section1986014410569) + - [目录规范](#section10916181716564) + +- [基础适配](#section814974018565) + - [编程样例](#section10854481825) + +- [验证](#section646410453212) + +## 移植概述 + +### 移植场景 + +LiteOS-A当前支持ARMv7-a指令集架构,如果三方芯片为ARMv7-a架构,可以进行内核基础适配;否则还需要先根据芯片的架构来新增内核对该芯片架构的支持,这个工作较为复杂,不在这篇文章范围内。 + +### 目录规范 + +LiteOS-A目录规范参考[LiteOS-A 简介](https://gitee.com/openharmony/kernel_liteos_a)。 + +## 基础适配 + +LiteOS-A提供系统运行所需的系统初始化流程和定制化配置选项。移植过程中,需要关注初始化流程中跟硬件配置相关的函数。 + +如下图所示,LiteOS-A的初始化流程主要包含以下五步: + +1. 新增target\_config.h文件,并且编写单板内存相关的配置宏DDR\_MEM\_ADDR和DDR\_MEM\_SIZE,分别表示内存起始地址和内存的长度,预链接脚本board.ld.S会根据这两个宏进行展开生成链接脚本board.ld。 +2. 链接阶段根据链接脚本board.ld生成内核镜像。 +3. 单核CPU镜像运行入口为汇编文件reset\_vector\_up.S,多核CPU的入口为reset\_vector\_mp.S,在汇编文件中进行中断向量表初始化、MMU页表初始化等操作。 +4. reset\_vector.S汇编代码最终会跳转到C语言的main函数,进行硬件时钟、软件定时器、内存和任务等初始化,这个过程会依赖target\_config.h的特性宏配置,最后会创建SystemInit任务,并且开启任务调度OsSchedStart\(\)。 +5. SystemInit任务在单板代码中实现,其中调用DeviceManagerStart函数进行HDF驱动初始化,这个过程会调用单板代码中的驱动配置文件hdf.hcs以及drivers源码实现。 + +整体启动流程如下图所示: + +**图 1** 整体启动流程 + + +![](figure/zh-cn_image_0000001126358814.png) + +从图1中可以看到,内核基础适配需要单板进行适配的代码包含三部分: + +- 新增target\_config.h文件,其中新增单板硬件配置参数和特性开关的配置参数,具体说明如下: + + **表 1** target\_config.h配置项说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

配置项

+

说明

+

OS_SYS_CLOCK

+

系统cycle的频率

+

DDR_MEM_ADDR

+

系统内存的起始地址

+

DDR_MEM_SIZE

+

系统内存的大小

+

PERIPH_PMM_BASE

+

外设寄存器的起始地址

+

PERIPH_PMM_SIZE

+

外设寄存器的长度大小

+

OS_HWI_MIN

+

系统中断最小值

+

OS_HWI_MAX

+

系统中断最大值

+

NUM_HAL_INTERRUPT_UART0

+

UART0中断号

+

UART0_REG_BASE

+

UART0寄存器基址

+

GIC_BASE_ADDR

+

GIC中断寄存器基址

+

GICD_OFFSET

+

GICD相对GIC基址的偏移地址

+

GICC_OFFSET

+

GICC相对GIC基址的偏移地址

+
+ +- SystemInit函数用于单板用户态业务初始化,典型的初始化场景如图2所示: + + **图 1** 业务启动流程 + + + ![](figure/zh-cn_image_0000001126198996.png) + +- main函数用于内核基础初始化和单板内核态业务初始化,流程如下图3所示,整体由内核启动框架主导初始化流程,图中浅蓝色部分为启动框架中可接受外部模块注册启动的阶段。 + + >![](../public_sys-resources/icon-caution.gif) **注意:** + >同一层级内的模块不能有依赖关系。 + + **图 2** 内核启动框架 + ![](figure/内核启动框架.jpg "内核启动框架") + + **表 2** 启动框架层级 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

层级

+

说明

+

LOS_INIT_LEVEL_EARLIEST

+

最早期初始化

+

说明:不依赖架构,单板以及后续模块会对其有依赖的纯软件模块初始化

+

例如:Trace模块

+

LOS_INIT_LEVEL_ARCH_EARLY

+

架构早期初始化

+

说明:架构相关,后续模块会对其有依赖的模块初始化,如启动过程中非必需的功能,建议放到LOS_INIT_LEVEL_ARCH层

+

LOS_INIT_LEVEL_PLATFORM_EARLY

+

平台早期初始化

+

说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化,如启动过程中必需的功能,建议放到LOS_INIT_LEVEL_PLATFORM层

+

例如:uart模块

+

LOS_INIT_LEVEL_KMOD_PREVM

+

内存初始化前的内核模块初始化

+

说明:在内存初始化之前需要使能的模块初始化

+

LOS_INIT_LEVEL_VM_COMPLETE

+

基础内存就绪后的初始化

+

说明:此时内存初始化完毕,需要进行使能且不依赖进程间通讯机制与系统进程的模块初始化

+

例如:共享内存功能

+

LOS_INIT_LEVEL_ARCH

+

架构后期初始化

+

说明:架构拓展功能相关,后续模块会对其有依赖的模块初始化

+

LOS_INIT_LEVEL_PLATFORM

+

平台后期初始化

+

说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化

+

例如:驱动内核抽象层初始化(mmc、mtd)

+

LOS_INIT_LEVEL_KMOD_BASIC

+

内核基础模块初始化

+

说明:内核可拆卸的基础模块初始化

+

例如:VFS初始化

+

LOS_INIT_LEVEL_KMOD_EXTENDED

+

内核扩展模块初始化

+

说明:内核可拆卸的扩展模块初始化

+

例如:系统调用初始化、ProcFS初始化、Futex初始化、HiLog初始化、HiEvent初始化、LiteIPC初始化

+

LOS_INIT_LEVEL_KMOD_TASK

+

内核任务创建

+

说明:进行内核任务的创建(内核线程,软件定时器任务)

+

例如:资源回收系统常驻任务的创建、SystemInit任务创建、CPU占用率统计任务创建

+
+ + 进行单板移植适配,推荐关注LOS\_INIT\_LEVEL\_ARCH至LOS\_INIT\_LEVEL\_KMOD\_TASK之间的层级,且尽可能拆分初始化行为进行细化阶段注册。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >启动框架中同一层级内的注册模块不能有依赖关系,建议新增模块按照上述启动阶段进行模块初始化的拆分,按需注册启动。 + >可通过查看系统编译生成文件OHOS\_Image.map中.rodata.init.kernel.\*段内的符号表来了解当前已注册进内核启动框架中的各个模块初始化入口,以及检查新注册的模块初始化入口是否生效。 + + +### 编程样例 + +在单板SDK文件中 + +``` +/* 内核启动框架头文件 */ +#include "los_init.h" +...... + +/* 新增模块的初始化函数 */ +unsigned int OsSampleModInit(void) +{ + PRINTK("OsSampleModInit SUCCESS!\n"); + ...... +} +...... +/* 在启动框架的目标层级中注册新增模块 */ +LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED); +``` + +## 验证 + +``` +main core booting up... +OsSampleModInit SUCCESS! +releasing 1 secondary cores +cpu 1 entering scheduler +cpu 0 entering scheduler +``` + +根据上述系统启动阶段的打印可知,内核在启动时进行了该注册模块的初始化函数调用,完成该模块的初始化操作。 + +系统启动完毕后进入内核态shell,能够运行task命令能够正常显示即可。 + +``` +OHOS # help +*******************shell commands:************************* + +arp cat cd chgrp chmod chown cp cpup +date dhclient dmesg dns format free help hwi +ifconfig ipdebug kill log ls lsfd memcheck mkdir +mount netstat oom partinfo partition ping ping6 pmm +pwd reset rm rmdir sem shm stack statfs +su swtmr sync systeminfo task telnet touch umount +uname v2p virstatfs vmm watch writeproc + +``` + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-kernel-linux.md b/zh-cn/device-dev/porting/transplant-smallchip-kernel-linux.md new file mode 100644 index 0000000000000000000000000000000000000000..911329dbd1b9971e422b9242171c031102a137b0 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-kernel-linux.md @@ -0,0 +1,125 @@ +# Linux内核 + +- [移植概述](#section6282121355111) + - [基本信息](#section19589322515) + - [Bootloader](#section19062510518) + +- [适配编译和烧录启动](#section11112101695215) +- [验证](#section17318153325311) + +## 移植概述 + +Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后,进行基础的内核编译构建及验证。 + +### 基本信息 + +当前Linux内核基线是基于Linux社区 4.19 LTS版本演进,合入CVE及bugfix补丁。具体信息参考[代码库](https://gitee.com/openharmony/kernel_linux),对应repo工程代码路径为kernel/linux-4.19。 + +### Bootloader + +可以使用芯片厂商自带的Bootloader,或者是开源Uboot等加载内核镜像。比如为支持Hi3516DV300开发板,OpenHarmony引入的开源[Uboot](https://gitee.com/openharmony/device_hisilicon_third_party_uboot)。 + +## 适配编译和烧录启动 + +1. 准备内核config(特别是芯片相关的config)。 + + config文件所在源码目录:kernel/linux/config/ + + 以hi3516dv300芯片为例,可在对应的linux-4.19/arch/arm/configs/目录下新建\_small\_defconfig,如hi3516dv300\_small\_defconfig表示针对hi3516dv300小型系统的defconfig。该config文件可以由基础defconfig文件small\_common\_defconfig与该芯片相关的config组合生成。 + +2. 准备芯片补丁。 + + 补丁文件所在源码目录:kernel/linux/patches/linux-4.19 + + 以hi3516dv300芯片为例,参考已有的patch目录hi3516dv300\_small\_patch目录,新建\_patch目录,放置相关芯片补丁,注意hdf.patch等驱动补丁。 + +3. 编译。 + + 具体内核编译入口脚本位于工程目录kernel/linux/patches/下面,版本级整编命令会通过BUILD.gn进入kernel\_module\_build.sh和kernel.mk,需要在这2个文件中针对性进行patch及defconfig文件路径、编译器、芯片架构、内核Image格式等的适配。 + + 通过编译错误日志调整补丁,典型错误场景: + + (1)补丁合入失败,出现冲突,需要进行上下文适配修改。 + + (2)编译失败,内核版本差异(函数实现调整等)需要针对性进行内核适配。 + + >![](../public_sys-resources/icon-caution.gif) **注意:** + >- 参考kernel.mk,在OpenHarmony工程的编译构建流程中会拷贝kernel/linux-4.19的代码环境后进行打补丁动作,在使用版本级编译命令前,需要kernel/linux-4.19保持原代码环境。 + >- 对应拷贝后的目录位于: out/<\*\*\*\>/kernel/linux-4.19,可以在该目录下进行补丁的修改适配。 + +4. 烧录启动。 + + 由于不同芯片的开发板的烧录方式不一样,此处不表述具体的烧录方式。需要注意烧录的各镜像的大小及启动参数的配置,参考hi3516dv300采用uboot启动参数: + + ``` + setenv bootargs 'mem=128M console=ttyAMA0,115200 root=/dev/mmcblk0p3 ro rootfstype=ext4 rootwait blkdevparts=mmcblk0:1M(boot),9M(kernel),50M(rootfs),50M(userfs)' + ``` + + +## 验证 + +调试init进程、启动shell和运行简单的用户态程序,验证内核移植是否成功。OpenHarmony[小型系统](https://device.harmonyos.com/cn/docs/start/introduce/oem_start_guide-0000001054913231)的OS镜像结构以及linux用户态的启动流程如下图1所示: + +**图 1** 基于linux内核的OS镜像结构和用户态程序启动流程 + + +![](figure/zh-cn_image_0000001126354076.png) + +基于上述流程,推荐按以下步骤完成验证: + +1. 制作根文件系统镜像。 + + 请参考[新建芯片解决方案和产品解决方案](https://device.harmonyos.com/cn/docs/develop/subsystems/oem_subsys_build_guide-0000001060378721)生成根文件系统镜像rootfs.img。从上图可以看到启动过程与产品配置强相关,在制作rootfs.img过程中请完成如下四种配置: + + - 组件配置 + + 产品组件配置文件vendor/\{company\}/\{product\}/config.json需配置启动恢复子系统\(startup\)的init\_lite组件和内核子系统的linux\_4\_1\_9组件。 + + - 系统服务配置 + + 系统服务配置文件vendor/\{company\}/\{product\}/init\_configs/init\_xxx.cfg需要启动shell服务。 + + - 文件系统配置 + + 文件系统配置vendor/\{company\}/\{product\}/fs.yml中需要创建“/bin/sh -\> mksh“和“/lib/ld-musl-arm.so.1 -\> libc.so“软连接,这两个文件分别是shell可执行程序和可执行程序依赖的c库。 + + - 启动配置 + + 启动配置在vendor/\{company\}/\{product\}/init\_configs/etc目录下,包括fstab、rsS和Sxxx文件,请按开发板实际情况配置。 + + + 编译完成后,可通过检查产品编译输出目录下的rootfs内容,确认rootfs.img文件生成是否符合预期。 + +2. 调试init进程和shell。 + + 烧录rootfs.img并调试init进程和shell,不同厂商的开发板的烧录工具和流程可能不同,请按芯片解决方案提供的流程进行烧录。烧录rootfs.img前请确认bootloader和linux内核启动正常。如果rootfs.img被内核正常挂载,接着将运行/bin/init程序,init进程为用户态的第一个应用程序,它的运行意味着用户态的开始。 + + init程序首先会调用/etc/init.d/rcS脚本,rcS脚本执行第一条命令为"/bin/mount -a”,该命令会加载fstab文件,在fstab中的命令执行完后rcS将顺序调用Sxxx脚本完成设备节点创建和扫描、文件权限配置等操作。 + + 最后,init程序会读取init.cfg系统服务配置文件。根据步骤1中的设置,init程序将会启动shell。如果上述流程运行正常,系统则会进入shell。 + + 若串口有如下版本号日志打印,则表示init程序启动正常: + + **图 2** init启动正常日志 + + + ![](figure/init.jpg) + + 正常进入shell后执行ls命令,串口打印信息如下图: + + **图 3** 正常进入shell后输入ls命令串口打印 + + + ![](figure/shell.jpg) + +3. 配置NFS。 + + init进程和shell正常启动后,以服务端IP为192.168.1.22、客户端IP为192.168.1.4为例,可在根目录执行如下命令开启NFS: + + ``` + ifconfig eth0 192.168.1.4 netmask 255.255.255.0 + mkdir -p /storgage/nfs + mount -t nfs -o nolock,addr=192.168.1.22 192.168.1.22:/nfs /storage/nfs + ``` + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-kernel.md b/zh-cn/device-dev/porting/transplant-smallchip-kernel.md new file mode 100644 index 0000000000000000000000000000000000000000..a1adc2dde7e4c576f8fc9137c42217474a15311e --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-kernel.md @@ -0,0 +1,7 @@ +# 移植内核 + +- **[LiteOS-A内核](transplant-smallchip-kernel-a.md)** + +- **[Linux内核](transplant-smallchip-kernel-linux.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-prepare-building.md b/zh-cn/device-dev/porting/transplant-smallchip-prepare-building.md new file mode 100644 index 0000000000000000000000000000000000000000..6ca5022e46a9574c8856578edc48294feffee89c --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-prepare-building.md @@ -0,0 +1,142 @@ +# 编译构建 + +- [编译环境搭建](#section3336103410314) +- [编译构建系统介绍](#section354343816319) +- [新建芯片解决方案](#section18612153175011) + +## 编译环境搭建 + +首先请搭建OpenHarmony基础环境,步骤请参考轻量和小型系统入门[linux环境搭建](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_environment_lin-0000001105407498)。用户态和LiteOS-A的内核态编译均使用llvm编译器编译,安装方法在搭建基础环境中已提供。若选择移植linux内核,请执行如下命令安装gcc-arm-linux-gnueabi交叉编译工具链,用于编译linux内核态镜像: + +``` +sudo apt-get install gcc-arm-linux-gnueabi +``` + +## 编译构建系统介绍 + +编译构建流程、编译脚本编写、目录规则、独立编译单个组件、独立编译芯片解决方案等介绍请见[编译构建子系统介绍](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BA.md)。 + +## 新建芯片解决方案 + +了解编译框架和搭建完编译环境后,请参考如下步骤新建芯片解决方案: + +1. 新建目录 + + 芯片解决方案的目录规则为:device/\{芯片解决方案厂商\}/\{开发板\}。以海思的hispark\_taurus开发板为例,在代码根目录执行如下命令建立目录: + + ``` + mkdir -p device/hisilicon/hispark_taurus + ``` + + 芯片解决方案目录树的规则如下: + + ``` + device + └── company # 芯片解决方案厂商 + └── board # 开发板名称 + ├── BUILD.gn # 编译脚本 + ├── hals # OS南向接口适配 + ├── linux # 可选,linux内核版本 + │ └── config.gni # linux版本编译配置 + └── liteos_a # 可选,liteos内核版本 + └── config.gni # liteos_a版本编译配置 + ``` + + 以hispark\_taurus移植linux内核为例,目录树应该如下: + + ``` + device + └── hisilicon + └── hispark_tautus + ├── BUILD.gn + ├── hals + ├── ...... + └── linux + └── config.gni + ``` + + 目录树建立后开发板相关的源码放到hispark\_taurus目录下。 + +2. 配置开发板编译选项 + + [步骤1](#li20894101862)中的config.gni可配置开发板相关的编译选项,编译构建框架将会遵照该配置文件中的参数编译所有用户态OS组件。其中关键的字段说明如下: + + ``` + kernel_type: 开发板使用的内核类型,例如:“liteos_a”, “liteos_m”, “linux”。 + kernel_version: 开发板使用的内核版本,例如:“4.19”。 + board_cpu: 开发板CPU类型,例如:“cortex-a7”, “riscv32”。 + board_arch: 开发板芯片arch, 例如: “armv7-a”, “rv32imac”。 + board_toolchain: 开发板自定义的编译工具链名称,例如:“gcc-arm-none-eabi”。若为空,则使用默认为ohos-clang。 + board_toolchain_prefix:编译工具链前缀,例如:“gcc-arm-none-eabi”。 + board_toolchain_type: 编译工具链类型,目前支持gcc和clang。例如:“gcc” ,“clang”。 + board_cflags: 开发板配置的c文件编译选项。 + board_cxx_flags: 开发板配置的cpp文件编译选项。 + board_ld_flags: 开发板配置的链接选项。 + ``` + + 还以海思的hispark\_taurus开发板为例,对应的device/hisilicon/hispark\_taurus/config.gni内容如下: + + ``` + # Board CPU type, e.g. "cortex-a7", "riscv32". + board_cpu = "cortex-a7" + + # Toolchain name used for system compiling. + # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. + # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. + board_toolchain = "mips-linux-gnu-gcc" + + # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. + board_toolchain_path = + rebase_path("//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/bin", + root_build_dir) + + # Compiler prefix. + board_toolchain_prefix = "arm-linux-ohoseabi-" + + # Compiler type, "gcc" or "clang". + board_toolchain_type = "gcc" + + # Board related common compile flags. + board_cflags = [ + ] + board_cxx_flags = [ + ] + board_ld_flags = [] + + # Board related headfiles search path. + board_include_dirs = [] + board_include_dirs += [ rebase_path( + "//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/target/usr/include", + root_build_dir) ] + + # Board adapter dir for OHOS components. + board_adapter_dir = "" + + # Sysroot path. + board_configed_sysroot = "" + + # Board storage type, it used for file system generation. + storage_type = "emmc" + ``` + +3. 编写开发板编译脚本 + + 步骤1中的BUILD.gn为新增的开发板的编译入口,主要用于编译开发板相关的代码,主要为设备侧驱动、设备侧接口适配\(媒体,图形等\)和开发板的SDK等等。 + + 海思的hispark\_taurus开发板的device/hisilicon/hispark\_taurus/BUILD.gn可写成: + + ``` + # group名称建议与开发板名称一致 + group("hispark_taurus") { + deps = [ "//kernel/linux/patches:linux_kernel" ] # 拉起内核编译 + deps += [ + ...... # 开发板其他编译单元 + ] + } + ``` + +4. 编译调试 + + 在开发板目录下执行hb set和hb build即可启动芯片解决方案的编译,编译框架会以开发板下的BUILD.gn为入口启动编译。 + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip-prepare-needs.md b/zh-cn/device-dev/porting/transplant-smallchip-prepare-needs.md new file mode 100644 index 0000000000000000000000000000000000000000..afe392369f2eb34c0c5a8dcf5a6204850347dd11 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-prepare-needs.md @@ -0,0 +1,98 @@ +# 移植须知 + +本文详细介绍如何将OpenHarmony[小型系统](https://device.harmonyos.com/cn/docs/start/introduce/oem_start_guide-0000001054913231)的linux和LiteOS-A内核移植到新的开发板上,要求读者具有一定的嵌入式系统开发经验。建议先查看[入门指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/OpenHarmony-Overview_zh.md),以了解OpenHarmony软件架构、目录结构、内核子系统和驱动子系统相关知识。当前小型系统已适配的开发板如下表所示: + +**表 1** OpenHarmony小型系统已适配的开发板 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

开发板

+

内核

+

arch

+

ROM

+

RAM

+

文件系统

+

Flash 类型

+

hispark_taurus

+

LiteOS-A和linux-4.19

+

ARM cortex-a7

+

8G

+

1GB

+

VFAT、EXT4

+

eMMC4.5

+

hispark_aries

+

LiteOS-A

+

ARM cortex-a7

+

16M

+

512M

+

JFFS2

+

SPI NOR

+
+ +表1中的开发板可作为待移植开发板的参考,当前LiteOS-A和linux-4.19支持的arch、ROM占用、支持的文件系统和支持的Flash类型如下表所示: + +**表 2** OpenHarmony小型系统内核移植信息表 + + + + + + + + + + + + + + + + + + + + + + +

内核

+

支持的arch

+

ROM

+

文件系统

+

Flash类型

+

LiteOS-A

+

ARMv7

+

> 2M

+

VFAT、JFFS2、YAFFS2

+

SPI NOR、NAND、EMMC

+

linux-4.19

+

ARM, ARM64、 MIPS、 X86等

+

> 5M

+

VFAT、JFFS2、YAFFS、EXT/2/3/4、NFS等等

+

NOR、NAND、EMMC等

+
+ diff --git a/zh-cn/device-dev/porting/transplant-smallchip-prepare.md b/zh-cn/device-dev/porting/transplant-smallchip-prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..6ec4b45dff790140fe40830288b5c0bb961ceddb --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip-prepare.md @@ -0,0 +1,7 @@ +# 移植准备 + +- **[移植须知](transplant-smallchip-prepare-needs.md)** + +- **[编译构建](transplant-smallchip-prepare-building.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-smallchip.md b/zh-cn/device-dev/porting/transplant-smallchip.md new file mode 100644 index 0000000000000000000000000000000000000000..4ba38ff4484d56d07681a0dce923d1839b80df87 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-smallchip.md @@ -0,0 +1,9 @@ +# 小型系统芯片移植指导 + +- **[移植准备](../porting/transplant-smallchip-prepare.md)** + +- **[移植内核](../porting/transplant-smallchip-kernel.md)** + +- **[驱动移植](../porting/transplant-smallchip-drive.md)** + + diff --git a/zh-cn/device-dev/porting/transplant-thirdparty-cmake.md b/zh-cn/device-dev/porting/transplant-thirdparty-cmake.md new file mode 100644 index 0000000000000000000000000000000000000000..fb23041d28a62d9768390ecdf41c6cc3acd4c4e2 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-thirdparty-cmake.md @@ -0,0 +1,435 @@ +# CMake方式组织编译的库移植 + +- [源码获取](#section1771132116245) +- [移植思路](#section9737174410328) +- [交叉编译](#section38205577332) + - [编译参考](#section1088111263418) + - [设置执行交叉编译](#section8168182883515) + +- [测试](#section6686144293611) +- [将该库编译添加到OpenHarmony工程中](#section1651053153715) + +以double-conversion库为例,其移植过程如下文所示 + +## 源码获取 + +从仓库[获取double-conversion源码](https://github.com/google/double-conversion),其目录结构如下表: + +**表 1** 源码目录结构 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

double-conversion/cmake/

+

CMake组织编译使用到的模板

+

double-conversion/double-conversion/

+

源文件目录

+

double-conversion/msvc/

+

-

+

double-conversion/test/

+

测试用例源文件

+

double-conversion/.gitignore

+

-

+

double-conversion/AUTHORS

+

-

+

double-conversion/BUILD

+

-

+

double-conversion/CMakeLists.txt

+

CMake方式顶层编译组织文件

+

double-conversion/COPYING

+

-

+

double-conversion/Changelog

+

-

+

double-conversion/LICENSE

+

-

+

double-conversion/Makefile

+

-

+

double-conversion/README.md

+

-

+

double-conversion/SConstruct

+

-

+

double-conversion/WORKSPACE

+

-

+
+ +## 移植思路 + +移植思路:通过修改工具链,交叉编译该三方库,生成OpenHarmony平台的可执行文件,最后再通过GN调用CMake的方式添加到OpenHarmony工程中。 + +## 交叉编译 + +### 编译参考 + +代码仓库的[README.md](https://github.com/google/double-conversion/blob/master/README.md)中详细介绍了使用CMake编译double-conversion库的步骤,以及测试方法。本文参考该指导设置该库的编译配置,并完成测试。若开发人员在移植过程中对该库的编译选项配置有疑惑的地方,可参考该指导。对于其他使用CMake可独立编译的三方库,在移植时可以参考其自带的编译指导。 + +### 设置执行交叉编译 + +CMake方式可通过指定工具链进行交叉编译,修改并编译该库,生成OpenHarmony平台的可执行文件,步骤如下: + +1. 设置工具链 + + 将下列clang工具链配置添加到该工程的顶层CMakeLists.txt(即[表1中的该文件](#table824211132418))中即可。 + + ``` + set(CMAKE_CROSSCOMPILING TRUE) + set(CMAKE_SYSTEM_NAME Generic) + set(CMAKE_CXX_COMPILER_ID Clang) + set(CMAKE_TOOLCHAIN_PREFIX llvm-) + #指定c编译工具(确保工具链所在路径已经添加到了PATH环境变量中)和编译标志,使用clang编译时标志中必须指定--target,否则无法交叉编译。 + set(CMAKE_C_COMPILER clang) + set(CMAKE_C_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") + #指定c++编译工具(确保工具链所在路径已经添加到了PATH环境变量中)和编译标志,必须指定--target,否则无法交叉编译。 + set(CMAKE_CXX_COMPILER clang++) + set(CMAKE_CXX_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w") + #指定链接工具和链接标志,必须指定--target和--sysroot,其中OHOS_ROOT_PATH可通过cmake命令后缀参数来指定。 + set(MY_LINK_FLAGS "--target=arm-liteos --sysroot=${OHOS_SYSROOT_PATH}") + set(CMAKE_LINKER clang) + set(CMAKE_CXX_LINKER clang++) + set(CMAKE_C_LINKER clang) + set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINKER} + ${MY_LINK_FLAGS} -o ") + set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINKER} + ${MY_LINK_FLAGS} -o ") + #指定链接库的查找路径。 + set(CMAKE_SYSROOT ${OHOS_SYSROOT_PATH}) + ``` + +2. 执行编译 + + linux命令行中进入double-conversion的源文件目录(即[表1所示目录](#table824211132418)),执行下列命令: + + ``` + mkdir build && cd build + cmake .. -DBUILD_TESTING=ON -DOHOS_SYSROOT_PATH="..." + make -j + ``` + + 其中OHOS\_SYSROOT\_PATH需用绝对路径指定出sysroot目录的位置,以OpenHarmony为例即目录openHarmony/prebuilts/lite/sysroot的绝对路径。 + +3. 查看结果 + + 步骤2操作完成后,build目录下会生成静态库文件和测试用例: + + **表 2** 编译生成文件目录结构 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

double-conversion/build/libdouble-conversion.a

+

生成的静态库文件

+

double-conversion/build/test/

+

目录下存放生成的测试用例和相关CMake缓存文件

+

double-conversion/build/CMakeCache.txt

+

CMake构建过程中的缓存文件

+

double-conversion/build/CMakeFiles/

+

-

+

double-conversion/build/cmake_install.cmake

+

-

+

double-conversion/build/CTestTestfile.cmake

+

-

+

double-conversion/build/DartConfiguration.tcl

+

-

+

double-conversion/build/generated/

+

-

+

double-conversion/build/Makefile

+

-

+

double-conversion/build/Testing/

+

-

+
+ + +## 测试 + +1. 搭建OpenHarmony环境 + + 以hi3518ev300为例,编译出OpenHarmony镜像,烧写到开发板,参考[开发Hi3518第一个示例程序](../quick-start/quickstart-lite-steps-board3518-running.md)。 + + 进入系统如下所示: + + **图 1** OpenHarmony启动成功界面 + ![](figure/OpenHarmony启动成功界面.png "OpenHarmony启动成功界面") + +2. 挂载nfs目录,将[表2](#table1452412391911)中test目录下cctest可执行文件放入nfs目录 +3. 执行用例 + + 该库采用非交叉编译时用例是通过make test执行,CMake会有相关的执行结果统计;交叉编译时无法使用该方法,因此可直接执行生成的测试文件完成测试。 + + - 挂载成功后执行下列命令可列出用例所有条目: + + ``` + cd nfs + ./cctest --list + ``` + + 上述命令执行结果部分展示: + + ``` + test-bignum/Assign< + test-bignum/ShiftLeft< + test-bignum/AddUInt64< + test-bignum/AddBignum< + test-bignum/SubtractBignum< + test-bignum/MultiplyUInt32< + test-bignum/MultiplyUInt64< + test-bignum/MultiplyPowerOfTen< + test-bignum/DivideModuloIntBignum< + test-bignum/Compare< + test-bignum/PlusCompare< + test-bignum/Square< + test-bignum/AssignPowerUInt16< + test-bignum-dtoa/BignumDtoaVariousDoubles< + test-bignum-dtoa/BignumDtoaShortestVariousFloats< + test-bignum-dtoa/BignumDtoaGayShortest< + test-bignum-dtoa/BignumDtoaGayShortestSingle< + test-bignum-dtoa/BignumDtoaGayFixed< + test-bignum-dtoa/BignumDtoaGayPrecision< + test-conversions/DoubleToShortest< + test-conversions/DoubleToShortestSingle< + ... + ``` + + - 以test-bignum条目为例,执行下列命令开始测试: + + ``` + ./cctest test-bignum + ``` + + 测试结果如下则表示通过: + + ``` + Ran 13 tests. + ``` + + +## 将该库编译添加到OpenHarmony工程中 + +1. 复制库到OpenHarmony工程中 + + 拷贝已经能够成功交叉编译的库到OpenHarmony的third\_party目录,为了不修改要移植的三方库目录下的BUILD.gn文件,再添加一层目录放置新增的gn转CMake编译适配文件,新增的文件有BUILD.gn、build\_thirdparty.py、 config.gni,新增后的目录结构如下所示。 + + **表 3** 添加到工程后的目录结构 + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

openHarmony/third_party/double-conversion/BUILD.gn

+

将三方库加入工程的gn适配文件

+

openHarmony/third_party/double-conversion/build_thirdparty.py

+

GN调用shell命令脚本文件,由上面GN文件将相关命令传入,实现GN转CMake

+

openHarmony/third_party/double-conversion/config.gni

+

三方库编译配置文件,可修改该文件来配置用例是否参与构建等

+

openHarmony/third_party/double-conversion/double-conversion/

+

要移植的三方库目录

+
+ +2. 添加gn到CMake适配文件 + + - **新增的BUILD.gn文件实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony平台时只需修改路径即可**。 + + ``` + import("config.gni") + group("double-conversion") { + if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + deps = [":make"] + } + } + if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + action("make") { + script = "//third_party/double-conversion/build_thirdparty.py" + outputs = ["$root_out_dir/log_dc.txt"] + exec_path = rebase_path(rebase_path("./build", ohos_third_party_dir)) + command = "rm * .* -rf && $CMAKE_TOOLS_PATH/cmake .. $CMAKE_FLAG $CMAKE_TOOLCHAIN_FLAG && make -j" + args = [ + "--path=$exec_path", + "--command=${command}" + ] + } + } + ``` + + - **新增的config.gni用于配置该库,实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony时只需修改CMAKE\_FLAG的配置即可。** + + ``` + #CMAKE_FLAG: config compile feature + CMAKE_FLAG = "-DBUILD_TESTING=ON -DCMAKE_CXX_STANDARD=11" + + #toolchain:follow up-layer,depend on $ohos_build_compiler + if (ohos_build_compiler == "clang") { + CMAKE_TOOLCHAIN_FLAG = "-DOHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" + } else { + CMAKE_TOOLCHAIN_FLAG = "" + } + + #CMake tools path,no need setting if this path already joined to $PATH. + CMAKE_TOOLS_PATH = "setting CMake tools path..." + ``` + + - **新增的build\_thirdparty.py实现如下,其他采用CMake方式可独立编译的三方库移植到OpenHarmony时无需修改即可使用。** + + ``` + import os + import sys + from subprocess import Popen + import argparse + import shlex + + def cmd_exec(command): + cmd = shlex.split(command) + proc = Popen(cmd) + proc.wait() + ret_code = proc.returncode + if ret_code != 0: + raise Exception("{} failed, return code is {}".format(cmd, ret_code)) + + def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--path', help='Build path.') + parser.add_argument('--command', help='Build command.') + parser.add_argument('--enable', help='enable python.', nargs='*') + args = parser.parse_args() + + if args.enable: + if args.enable[0] == 'false': + return + + if args.path: + curr_dir = os.getcwd() + os.chdir(args.path) + if args.command: + if '&&' in args.command: + command = args.command.split('&&') + for data in command: + cmd_exec(data) + else: + cmd_exec(args.command) + os.chdir(curr_dir) + + if __name__ == '__main__': + sys.exit(main()) + ``` + + - 在配置文件中添加开关控制该库编译,默认设为关闭 + + 在//build/lite/ohos\_var.gni文件中添加下列配置: + + ``` + declare_args() { + ohos_build_thirdparty_migrated_from_fuchisa = true + } + ``` + +3. 编译构建 + + - 手动单独构建: + + 执行下列命令 + + ``` + hb build -T //third_party/double-conversion:double-conversion + ``` + + 编译成功则[build](#li15717101715249)目录下会生成静态库文件和测试用例 + + diff --git a/zh-cn/device-dev/porting/transplant-thirdparty-makefile.md b/zh-cn/device-dev/porting/transplant-thirdparty-makefile.md new file mode 100644 index 0000000000000000000000000000000000000000..ddabc1ef30ae29930bea14394ced65ec43e227a2 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-thirdparty-makefile.md @@ -0,0 +1,309 @@ +# Makefile方式组织编译的库移植 + +- [源码获取](#section114115321416) +- [设置交叉编译](#section81263255384) +- [测试](#section1830015913391) +- [将该库编译添加到OpenHarmony工程中](#section1898016213406) + +以yxml库为例,其移植过程如下文所示 + +## 源码获取 + +从仓库[获取yxml源码](https://github.com/getdnsapi/yxml),其目录结构如下表: + +**表 1** 源码目录结构 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

yxml/bench/

+

benchmark相关代码

+

yxml/test/

+

测试输入输出文件,及测试脚本

+

yxml/Makefile

+

编译组织文件

+

yxml/.gitattributes

+

-

+

yxml/.gitignore

+

-

+

yxml/COPYING

+

-

+

yxml/yxml.c

+

-

+

yxml/yxml.c.in

+

-

+

yxml/yxml-gen.pl

+

-

+

yxml/yxml.h

+

-

+

yxml/yxml.md

+

-

+

yxml/yxml-states

+

-

+
+ +## 设置交叉编译 + +设置Makefile的交叉编译工具链,修改并编译该库,生成OpenHarmony平台的可执行文件,步骤如下: + +1. 设置工具链 + + 将下列clang工具链配置替换掉yxml库根目录的MakeFile(即[表1中的文件](#table16520154171813))中的原有配置。 + + clang工具链配置 + + ``` + #设置交叉编译工具链,确保工具链所在路径已经添加到了PATH环境变量中 + CC:=clang + AR:=llvm-ar + #cflags中必须要添加--target及--sysroot选项 + CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g --target=arm-liteos -march=armv7-a --sysroot=$(OHOS_ROOT_PATH)prebuilts/lite/sysroot + ``` + + 原有配置 + + ``` + CC:=gcc + AR:=ar + CFLAGS:=-Wall -Wextra -Wno-unused-parameter -O2 -g + ``` + +2. 执行编译 + + linux命令行中进入yxml的源文件目录(即图1所示目录),执行下列命令: + + ``` + make test OHOS_SYSROOT_PATH=... + ``` + + 其中OHOS\_SYSROOT\_PATH需用绝对路径指定出sysroot所在目录,以OpenHarmony为例即源码根目录prebuilts/lite/sysroot/所在的绝对路径。 + +3. 查看结果 + + 步骤2操作完成后,yxml下会生成out目录,里面有静态库文件和测试用例: + + **表 2** yxml编译生成目录 + + + + + + + + + + + + + +

名称

+

描述

+

openHarmony/third_party/yxml/yxml/out/lib/

+

编译生成的静态库的存放目录

+

openHarmony/third_party/yxml/yxml/out/test/

+

编译生成的测试用例及其输入输出等文件的存放目录

+
+ + +## 测试 + +yxml库测试步骤与double-conversion库基本一致,可参考[CMake方式组织编译的库移植](transplant-thirdparty-cmake.md#section6686144293611)的测试过程,以下内容介绍yxml库测试用例的使用方法: + +**表 3** 生成的test目录结构示意 + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

openHarmony/third_party/yxml/yxml/out/test/test.sh

+

自动化测试脚本,由于OpenHarmony不支持脚本运行,因此无法使用,可参考其内容手动测试

+

openHarmony/third_party/yxml/yxml/out/test/test

+

用于测试的可执行文件

+

openHarmony/third_party/yxml/yxml/out/test/*.xml

+

测试输入文件

+

openHarmony/third_party/yxml/yxml/out/test/*.out

+

期望的输出文件

+
+ +test.sh内容如下所示: + +``` +#!/bin/sh +for i in *.xml; do + b=`basename $i .xml` + o=${b}.out + t=${b}.test + ./test <$i >$t + if [ -n "`diff -q $o $t`" ]; then + echo "Test failed for $i:" + diff -u $o $t + exit 1 + fi +done +echo "All tests completed successfully." +``` + +由于OpenHarmony的shell中暂不支持输入输出重定向(<和\>),所以测试时需要将输入\*.xml文件内容直接复制进shell后回车,输出内容会直接展示在shell窗口。过程如下: + +下列操作假定已按照2.4节的步骤搭建OpenHarmony,挂载并进入nfs目录: + +1. 执行下列命令 + + ``` + ./test + ``` + +2. 复制\*.xml内容到shell + + 以[test目录](#table115941423164318)下pi01.xml为例,内容如下,输入到shell并回车: + + ``` + + ``` + +3. 比较shell中输出的内容与[test目录](#table115941423164318)中对应的\*.out文件是否一致 + + 输出结果如下: + + ``` + pistart SomePI + picontent abc + piend + elemstart a + elemend + ok + ``` + + 经比较与[test目录](#table115941423164318)下pi01.out内容一致,测试通过。 + + +## 将该库编译添加到OpenHarmony工程中 + +yxml库添加的过程除了适配文件build.gn和config.gni有些许变化外,其他和double-conversion库完全一致,参考[CMake方式组织编译的库移植](transplant-thirdparty-cmake.md#section1651053153715)的配置过程。要修改的适配文件及添加后的目录结构如下: + +- yxml库新增的BUILD.gn实现如下: + +``` +import("config.gni") +group("yxml") { + if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + deps = [":make"] + } +} +if (ohos_build_thirdparty_migrated_from_fuchisa == true) { + action("make") { + script = "//third_party/yxml/build_thirdparty.py" + outputs = ["$target_out_dir/log_yxml.txt"] + exec_path = rebase_path(rebase_path("./yxml", root_build_dir)) + command = "make clean && $MAKE_COMMAND" + args = [ + "--path=$exec_path", + "--command=${command}" + ] + } +} +``` + +- yxml库新增的config.gni配置如下: + +``` +TEST_ENABLE = "YES" + +if (TEST_ENABLE == "YES") { + MAKE_COMMAND = "make test OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" +} else { + MAKE_COMMAND = "make OHOS_SYSROOT_PATH=${ohos_root_path}prebuilts/lite/sysroot/" +} +``` + +- 添加完成后目录结构示意: + +**表 4** 添加到工程后的目录结构 + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

openHarmony/third_party/yxml/BUILD.gn

+

将三方库加入工程的gn适配文件

+

openHarmony/third_party/yxml/build_thirdparty.py

+

GN调用shell命令脚本文件,由上面GN文件将相关命令传入,实现GN转Makefile

+

openHarmony/third_party/yxml/config.gni

+

三方库编译配置文件,可修改该文件来配置用例是否参与构建等

+

openHarmony/third_party/yxml/yxml/

+

要移植的三方库目录

+
+ diff --git "a/zh-cn/device-dev/porting/\346\246\202\350\277\260.md" b/zh-cn/device-dev/porting/transplant-thirdparty-overview.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/porting/\346\246\202\350\277\260.md" rename to zh-cn/device-dev/porting/transplant-thirdparty-overview.md diff --git a/zh-cn/device-dev/porting/transplant-thirdparty.md b/zh-cn/device-dev/porting/transplant-thirdparty.md new file mode 100644 index 0000000000000000000000000000000000000000..ca27b2d33989ef22f963d59881cc0d317a337b35 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant-thirdparty.md @@ -0,0 +1,9 @@ +# 三方库移植指导 + +- **[概述](transplant-thirdparty-overview.md)** + +- **[CMake方式组织编译的库移植](transplant-thirdparty-cmake.md)** + +- **[Makefile方式组织编译的库移植](transplant-thirdparty-makefile.md)** + + diff --git a/zh-cn/device-dev/porting/transplant.md b/zh-cn/device-dev/porting/transplant.md new file mode 100644 index 0000000000000000000000000000000000000000..bc8d8a3ad12bef77aaf9e3f74738efe311ecb464 --- /dev/null +++ b/zh-cn/device-dev/porting/transplant.md @@ -0,0 +1,9 @@ +# 移植 + +- **[三方库移植指导](transplant-thirdparty.md)** + +- **[轻量系统芯片移植指导](transplant-minichip.md)** + +- **[小型系统芯片移植指导](transplant-smallchip.md)** + + diff --git "a/zh-cn/device-dev/porting/\344\270\211\346\226\271\345\272\223\347\247\273\346\244\215\346\214\207\345\257\274.md" "b/zh-cn/device-dev/porting/\344\270\211\346\226\271\345\272\223\347\247\273\346\244\215\346\214\207\345\257\274.md" deleted file mode 100755 index e54970ed8fef38469f2388b352fa7df719eea4b9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\344\270\211\346\226\271\345\272\223\347\247\273\346\244\215\346\214\207\345\257\274.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 三方库移植指导 - -- **[概述](概述.md)** - -- **[CMake方式组织编译的库移植](CMake方式组织编译的库移植.md)** - -- **[Makefile方式组织编译的库移植](Makefile方式组织编译的库移植.md)** - - diff --git "a/zh-cn/device-dev/porting/\344\270\211\346\226\271\347\273\204\344\273\266\351\200\202\351\205\215.md" "b/zh-cn/device-dev/porting/\344\270\211\346\226\271\347\273\204\344\273\266\351\200\202\351\205\215.md" deleted file mode 100644 index 0999f32a530ac987759134af1fd23344c25eeb86..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\344\270\211\346\226\271\347\273\204\344\273\266\351\200\202\351\205\215.md" +++ /dev/null @@ -1,57 +0,0 @@ -# 三方组件适配 - -如果需要使用third\_party目录下与产品相关的三方组件,可能需要对三方组件进行适配,下面以比较常用的mbedtls为例,介绍下适配步骤,注意本小节中仅介绍如何将适配的代码与OpenHarmony的编译框架融合,不会详细介绍mbedtls本身的原理和适配代码的具体逻辑,这些内容请参考mbedtls官方网站上的适配指南。 - -1. 编写适配层代码 - - 根据mbedtls官网的适配指南,编写需要的适配层代码,以适配硬件随机数举例,下面的路径都是相对third\_party/mbedtls的路径: - - 1. 拷贝include/mbedtls/config.h到ports目录下,并修改打开MBEDTLS\_ENTROPY\_HARDWARE\_ALT开关。 - 2. 在ports目录下创建entropy\_poll\_alt.c文件include并实现entropy\_poll.h中的硬件随机数接口 - 3. 在BUILD.gn中的mbedtls\_sources中增加刚才适配的entropy\_poll\_alt.c的路径 - 4. 在BIULD.gn中的lite\_library\("mbedtls\_static"\)中增加一行MBEDTLS\_CONFIG\_FILE指定新配置文件的位置 - - ``` - lite_library("mbedtks_static") { - ... - defines += ["MBEDTLS_CONFIG_FILE=<../port/config.h>"] - ... - } - ``` - - - 注意,上面的修改最好都新建一个config或者新建一个xxx\_alt.c文件来修改,不要直接在原先的代码中修改,侵入式的修改会导致后续版本升级出现大量零散冲突,增加升级维护成本。 - -2. 制作patch - - 由于上面的适配是硬件相关的,上库代码时,不能直接放到通用的third\_party/mbedtls目录中,因此需要将上面的修改制作成patch,在编译之前通过打patch的方式注入到代码中。 - - 1. 首先增加设备的patch配置文件device///patch.yml - 2. 编辑device///patch.yml,增加要打的patch的信息: - - ``` - # 需要打patch的路径,路径均为相对代码根目录的路径 - third_party/mbedtls: - # 该路径下需要打的patch存放路径 - - device///third_party/mbedtls/adapter.patch - third_party/wpa_supplicant: - # 当一个路径下有多个patch的时候会依次执行patch - - device///third_party/wpa_supplicant/xxxxx.patch - - device///third_party/wpa_supplicant/yyyyy.patch - ... - ``` - - 3. 制作上述**步骤1**修改的patch并放到对应的目录即可 - -3. 使用带patch的编译 - - 想要在编译的时候带上patch,其他步骤不变,仅需要在触发编译的时候加上 --patch,例如全编译的命令编程 - - ``` - hb build -f --patch - ``` - - >![](public_sys-resources/icon-caution.gif) **注意:** - >最后一次打patch的产品信息会被记录,在进行下一次编译操作时,会对上一次的patch进行回退(即执行\`patch -p1 -R < xxx\`),回退patch失败或新增patch失败均会终止编译过程,请解决patch冲突后再次尝试编译。 - - diff --git "a/zh-cn/device-dev/porting/\344\270\211\346\226\271\350\212\257\347\211\207\347\247\273\346\244\215\346\214\207\345\257\274.md" "b/zh-cn/device-dev/porting/\344\270\211\346\226\271\350\212\257\347\211\207\347\247\273\346\244\215\346\214\207\345\257\274.md" deleted file mode 100755 index c6c7b4103e7cd7eb49b8945cebf7f247a0866662..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\344\270\211\346\226\271\350\212\257\347\211\207\347\247\273\346\244\215\346\214\207\345\257\274.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 三方芯片移植指导 - -- **[移植准备](移植准备.md)** - -- **[内核移植](内核移植.md)** - -- **[板级系统移植](板级系统移植.md)** - -- **[常见问题](常见问题.md)** - - diff --git "a/zh-cn/device-dev/porting/\345\206\205\346\240\270\345\237\272\347\241\200\351\200\202\351\205\215.md" "b/zh-cn/device-dev/porting/\345\206\205\346\240\270\345\237\272\347\241\200\351\200\202\351\205\215.md" deleted file mode 100755 index a4eaf54ec519a7bccaedea0c0295abf7029f0dd9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\345\206\205\346\240\270\345\237\272\347\241\200\351\200\202\351\205\215.md" +++ /dev/null @@ -1,83 +0,0 @@ -# 内核基础适配 - -- [基础适配](#section14523241594) -- [特性配置项](#section112994366592) - -芯片架构适配完成后,liteos-m提供系统运行所需的系统初始化流程和定制化配置选项。移植过程中,需要关注初始化流程中跟硬件配置相关的函数;了解内核配置选项,才能裁剪出适合单板的最小内核。 - -## 基础适配 - -如下图所示,基础适配主要分为以下两步: - -1. 启动文件startup.S和相应链接配置文件。 -2. main. c中的串口初始化和tick中断注册。 - -**图 1** 启动流程 - - -![](figures/zh-cn_image_0000001073943511.png) - -启动文件startup.S需要确保中断向量表的入口函数(例如reset\_vector)放在RAM的首地址,它由链接配置文件来指定。其中iar、keil和gcc工程的链接配置文件分别为xxx.icf、xxx.sct和xxx.ld,如果startup.S已经完成系统时钟初始化,并且能够引导到main函数,则启动文件不需要进行修改,采用厂商自带的startup.S即可,否则需要实现以上功能。 - -在main.c文件中,需要关注串口初始化UartInit和系统Tick的handler函数注册。 - -- UartInit函数表示单板串口的初始化,具体的函数名根据单板自行定义。这个函数是可选的,用户可以根据硬件单板是否支持串口来自行选择调用该函数。如果硬件单板支持串口,则该函数需要完成使能串口TX和RX通道,设置波特率。 -- HalTickStart设置tick中断的handler函数OsTickHandler。 - -对于中断向量表不可重定向的芯片,需要关闭LOSCFG\_PLATFORM\_HWI宏,并且在startup.S中新增tick中断的handler函数。 - -## 特性配置项 - -liteos\_m的完整配置能力及默认配置在los\_config.h定义,该头文件中的配置项可以根据不同的单板进行裁剪配置。 - -如果针对这些配置项需要进行不同的板级配置,则可将对应的配置项直接定义到对应单板的device/xxxx/target\_config.h文件中,其他未定义的配置项,采用los\_config.h中的默认值。 - -一份典型的配置参数如下: - -**表 1** 内核典型配置项说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

配置项

-

说明

-

LOSCFG_BASE_CORE_SWTMR

-

软件定时器特性开关,1表示打开,0表示关闭

-

LOSCFG_BASE_CORE_SWTMR_ALIGN

-

对齐软件定时器特性开,1表示打开,依赖软件定时器特性打开,0表示关闭

-

LOSCFG_BASE_IPC_MUX

-

mux功能开关,1表示打开,0表示关闭

-

LOSCFG_BASE_IPC_QUEUE

-

队列功能开关,1表示打开,0表示关闭

-

LOSCFG_BASE_IPC_SEM

-

信号量功能开关,1表示打开,0表示关闭

-

LOSCFG_PLATFORM_EXC

-

异常特性开关,1表示打开,0表示关闭

-

LOSCFG_KERNEL_PRINTF

-

打印特性开关,1表示打开,0表示关闭

-
- diff --git "a/zh-cn/device-dev/porting/\345\206\205\346\240\270\347\247\273\346\244\215.md" "b/zh-cn/device-dev/porting/\345\206\205\346\240\270\347\247\273\346\244\215.md" deleted file mode 100755 index 1dfe36434a1c3eca30a3dc75f0016a61730ef9e0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\345\206\205\346\240\270\347\247\273\346\244\215.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 内核移植 - -- **[移植概述](移植概述.md)** - -- **[内核基础适配](内核基础适配.md)** - -- **[内核移植验证](内核移植验证.md)** - - diff --git "a/zh-cn/device-dev/porting/\345\206\205\346\240\270\347\247\273\346\244\215\351\252\214\350\257\201.md" "b/zh-cn/device-dev/porting/\345\206\205\346\240\270\347\247\273\346\244\215\351\252\214\350\257\201.md" deleted file mode 100755 index 4604f13ad9b270efb67c33f186b469222f343f78..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\345\206\205\346\240\270\347\247\273\346\244\215\351\252\214\350\257\201.md" +++ /dev/null @@ -1,59 +0,0 @@ -# 内核移植验证 - -在工程device目录下添加编译main.c示例程序文件,此示例程序的主要目的是:LOS\_KernelInit完成之后,创建两个任务,循环调度延时并打印日志信息,通过此方法可以验证系统是否可正常调度以及时钟是否正常。 - -``` -VOID TaskSampleEntry2(VOID) // 任务2的入口函数 -{ - while(1) { - LOS_TaskDelay(10000); - printf("taskSampleEntry2 running...\n"); - } -} - -VOID TaskSampleEntry1(VOID) // 任务1的入口函数 -{ - while(1) { - LOS_TaskDelay(2000); - printf("taskSampleEntry1 running...\n"); - } -} - -UINT32 TaskSample(VOID) -{ - UINT32 uwRet; - UINT32 taskID1,taskID2; - TSK_INIT_PARAM_S stTask1={0}; - stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1; - stTask1.uwStackSize = 0X1000; - stTask1.pcName = "taskSampleEntry1"; - stTask1.usTaskPrio = 6; //stTask1的任务优先级设定,不同于stTask2 - uwRet = LOS_TaskCreate(&taskID1, &stTask1); - - stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2; - stTask1.uwStackSize = 0X1000; - stTask1.pcName = "taskSampleEntry2"; - stTask1.usTaskPrio = 7; - uwRet = LOS_TaskCreate(&taskID2, &stTask1); - - return LOS_OK; -} - -LITE_OS_SEC_TEXT_INIT int main(void) -{ - UINT32 ret; - UartInit(); // 硬件串口配置,通过串口输出调试日志,实际函数名根据单板实现不一样而不一样。 - printf("\n\rhello world!!\n\r"); - ret = LOS_KernelInit(); - TaskSample(); - if (ret == LOS_OK) { - LOS_Start(); // 开始系统调度,循环执行stTask1/stTask2任务,串口输出任务日志 - } - while (1) { - __asm volatile("wfi"); - } -} -``` - -第一个任务运行正常后,说明最小系统的核心流程基本OK;由于xts用例框架对外依赖较多,主要是utils、bootstrap的链接脚本和编译框架,暂时无法支撑内核单独跑xts;此处略过内核测试套的测试,可以通过[XTS测试套](XTS认证.md)来覆盖最小系统是否完整移植成功。 - diff --git "a/zh-cn/device-dev/porting/\346\235\277\347\272\247\347\263\273\347\273\237\347\247\273\346\244\215.md" "b/zh-cn/device-dev/porting/\346\235\277\347\272\247\347\263\273\347\273\237\347\247\273\346\244\215.md" deleted file mode 100755 index 3029464912dea8f0226d3636d6d1a3652832dbca..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\346\235\277\347\272\247\347\263\273\347\273\237\347\247\273\346\244\215.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 板级系统移植 - -- **[移植概述](移植概述-0.md)** - -- **[板级驱动适配](板级驱动适配.md)** - -- **[HAL层实现](HAL层实现.md)** - -- **[系统组件调用](系统组件调用.md)** - -- **[三方组件适配](三方组件适配.md)** - -- **[XTS认证](XTS认证.md)** - - diff --git "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\345\207\206\345\244\207.md" "b/zh-cn/device-dev/porting/\347\247\273\346\244\215\345\207\206\345\244\207.md" deleted file mode 100755 index 1637d5d8932e73b08d50f1060df841f64cd11698..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\345\207\206\345\244\207.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 移植准备 - -- **[移植须知](移植须知.md)** - -- **[编译构建适配流程](编译构建适配流程.md)** - - diff --git "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\346\246\202\350\277\260-0.md" "b/zh-cn/device-dev/porting/\347\247\273\346\244\215\346\246\202\350\277\260-0.md" deleted file mode 100755 index a5d18d9bd490592858e9dcd933265965d0d04187..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\346\246\202\350\277\260-0.md" +++ /dev/null @@ -1,57 +0,0 @@ -# 移植概述 - -- [板级移植流程](#section1283115812294) -- [板级目录规范](#section6204129143013) - -## 板级移植流程 - -最小系统移植完成后,下一步进行板级系统移植,板级系统移植包含以下几步操作: - -1. 板级驱动适配。 -2. HAL层实现。 -3. XTS测试套。 -4. 业务功能验证。 - -**图 1** 单板驱动适配流程 -![](figures/单板驱动适配流程.png "单板驱动适配流程") - -## 板级目录规范 - -板级系统编译适配参考[编译系统介绍](编译构建适配流程.md),板级相关的驱动、SDK、目录、HAL实现存放在device目录,目录结构和具体描述如下: - -``` -. -├── device --- 单板样例 -│ └── xxx --- <单板厂商名> -│ └── xxx --- <单板名>,里面包含liteos-m内核的,并且能够运行的demo -│ ├── BUILD.gn --- 定义单板的编译配置文件 -│ ├── board --- 板子特定的实现(可选,如果本单板直接提供产品级demo,则相关应用层实现放在此目录) -│ ├── liteos_m --- 根据BUILD.gn文件中的kernel_type,使用liteos_m内核 -│ │ └── config.gni --- 编译选项 -│ ├── libraries --- 板级SDK -│ │ └── include --- SDK提供对外头文件 -│ │ └── ... --- binary or source -│ ├── main.c --- main函数入口(如果产品级存在相同定义,则使用产品级配置) -│ ├── target_config.h --- 板级内核配置 -│ ├── project --- 单板级工程配置文件(如果产品级存在相同定义,则使用产品级配置) -│ └── adapter --- 单板适配上层应用组件的适配层接口,根据能力可选 -│ └── hals -│ ├── communication -│ │ └── wifi_lite -│ │ ├── ... -│ └── iot_hardware -│ ├── upgrade -│ ├── utils -│ └── wifiiot_lite -├── vendor --- 提供端到端的OpenHarmony特性产品样例 -│ └── huawei --- 厂商名字 -│ └── wifiiot --- wifiiot表示特性产品 -│ ├── app -│ │ └── main.c --- 产品的main函数入口 -│ ├── project --- 工程配置文件 -│ ├── BUILD.gn --- 工程编译入口 -│ └── config.json --- 定义产品的编译配置文件,配置产品所使用的组件等。 -└── out --- 编译过程中的输出目录 - ├── ... --- 单板/产品编译产生的bin等 -``` - diff --git "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\346\246\202\350\277\260.md" "b/zh-cn/device-dev/porting/\347\247\273\346\244\215\346\246\202\350\277\260.md" deleted file mode 100755 index 6f6b421748893228a5a296f4219d21a61380666c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\346\246\202\350\277\260.md" +++ /dev/null @@ -1,64 +0,0 @@ -# 移植概述 - -- [移植场景](#section93781277367) -- [目录规范](#section18127744153119) -- [芯片架构适配点](#section137431650339) - -## 移植场景 - -芯片架构适配是可选过程,如果在liteos\_m/kernel/arch目录下已经支持对应芯片架构,则可以跳过芯片架构适配,进行单板适配过程,否则需要进行芯片架构移植工作。 - -## 目录规范 - -模组芯片使用的内核为liteos-m,liteos-m中主要分为KAL、Components、Kernel和Utils四个模块。 - -- KAL模块作为内核对外的接口依赖Components模块和Kernel模块。 -- Components模块可插拔,它依赖Kernel模块。 - -- 在Kernel模块中,其中硬件相关的代码放在kernel的arch目录中,其余为硬件无关的代码。内核功能集(task、sem等)的实现依赖硬件相关的arch代码,例如任务上下文切换、原子操作等。 -- Utils模块作为基础代码块,被其他模块依赖。 - -**图 1** liteos-m内核模块图 - - -![](figures/zh-cn_image_0000001072304191.png) - -内核的目录结构和说明如下: - -``` -. -├── components --- 移植可选组件,依赖内核,单独对外提供头文件 -├── kal --- 内核抽象层,提供内核对外接口,当前支持cmsis接口和部分posix接口 -├── kernel --- 内核最小功能集代码 -│ ├── arch --- 内核指令架构层代码 -│ │ ├── arm --- arm32架构的代码 -│ │ │ ├── cortex-m3 --- cortex-m3架构的代码 -│ │ │ │ ├── iar --- iar编译工具链实现 -│ │ │ │ ├── keil --- keil编译工具链实现 -│ │ │ │ └── xxx --- xxx编译工具链实现 -│ │ │ └── cortex-m4 --- cortex-m4架构的代码 -│ │ │ ├── iar --- iar编译工具链实现 -│ │ │ ├── keil --- keil编译工具链实现 -│ │ │ └── xxx --- xxx编译工具链实现 -│ │ ├── include --- 所有的arch需要实现的函数定义,内核依赖 -│ │ └── risc-v --- risk-v架构 -│ │ └── gcc --- iar编译工具链实现 -│ ├── include --- 内核最小功能集代码 -│ └── src --- 内核最小功能集代码 -└──utils --- 基础代码,作为依赖的最底层,被系统依赖 -``` - -## 芯片架构适配点 - -如内核的[目录结构](#section18127744153119)所示,arch/include定义通用的芯片架构所需要实现的函数,另外芯片架构相关的代码会有部分的汇编代码,而汇编代码会因编译工具链的不同而不同,因此在具体的芯片架构下,还包含不同工具链(iar、keil、gcc等)的实现。 - -arch/include 目录定义通用的文件以及函数列表,该目录下的所有函数在新增arch组件时都需要适配,详见每一个头文件: - -``` -los_arch.h --- 定义芯片架构初始化所需要的函数 -los_atomic.h --- 定义芯片架构所需要实现的原子操作函数 -los_context.h --- 定义芯片架构所需要实现的任务上下文相关函数 -los_interrupt.h --- 定义芯片架构所需要实现的中断和异常相关的函数 -los_timer.h --- 定义芯片架构所需要实现的系统时钟相关的函数 -``` - diff --git "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\351\241\273\347\237\245.md" "b/zh-cn/device-dev/porting/\347\247\273\346\244\215\351\241\273\347\237\245.md" deleted file mode 100755 index b28e2b5d0ff4686dcb9b31e033dc9ce1b390475b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\347\247\273\346\244\215\351\241\273\347\237\245.md" +++ /dev/null @@ -1,84 +0,0 @@ -# 移植须知 - -- [移植目录](#section284217487490) -- [移植流程](#section639315306506) -- [移植规范](#section187870185219) - -本文为OpenHarmony平台系统开发人员和芯片(或模组)制造商提供基础的开发移植指导,典型的芯片架构例如cortex-m系列、risc-v系列等都可以按照本文进行移植,暂时不支持蓝牙服务。OpenHarmony是个持续演进的复杂项目,随着版本和API的改变,本文将会不断更新。 - -本文要求读者具有一定的嵌入式系统开发经验,因此它的重点未放在基本的OS基础介绍,而更多地描述OpenHarmony平台移植过程中主要操作和所需要关注的方面。 - -## 移植目录 - -OpenHarmony整体工程较为复杂,目录及实现为系统本身功能,如果不涉及复杂的特性增强,不需要关注每一层实现,移植过程中重点关注如下目录即可: - -**表 1** 移植过程中的重点目录 - - - - - - - - - - - - - - - - - - - -

目录名称

-

描述

-

/build/lite

-

OpenHarmony基础编译构建框架

-

/kernel/liteos_m

-

基础内核,其中芯片架构相关实现在arch目录下

-

/device

-

板级相关实现,各个三方厂商按照OpenHarmony规范适配实现,device下具体目录结构及移植过程参见板级系统移植

-

/vendor

-

产品级相关实现,主要由华为或者产品厂商贡献

-
- -device目录规则:device/\{芯片解决方案厂商\}/\{开发板\}。以hisilicon的hispark\_taurus为例: - -``` -device -└── hisilicon # 芯片解决方案厂商名 - ├── common # 芯片解决方案开发板公共部分 - └── hispark_taurus # 开发板名称 - ├── BUILD.gn # 开发板编译入口 - ├── hals # 芯片解决方案厂商OS硬件适配 - ├── linux # linux版本 - │ └── config.gni # linux版本编译工具链和编译选项配置 - └── liteos_a # liteos-a版本 - └── config.gni # liteos_a版本编译工具链和编译选项配置 -``` - -vendor目录规则:vendor/\{产品解决方案厂商\}/\{产品名称\}。以华为的wifiiot产品为例: - -``` -vendor # 产品解决方案厂商 -└── huawei # 产品解决方案厂商名称 - └── wifiiot # 产品名称 - ├── hals # 产品解决方案厂商OS适配 - ├── BUILD.gn # 产品编译脚本 - └── config.json # 产品配置文件 -``` - -## 移植流程 - -OpenHarmony的device目录是基础芯片的适配目录,如果在三方芯片应用过程中发现此目录下已经有完整的芯片适配,则不需要再额外移植,直接跳过移植过程进行系统应用开发即可,如果该目录下无对应的芯片移植实现,则根据本文完成移植过程。OpenHarmony三方芯片移植主要过程如下: - -**图 1** 芯片移植关键步骤 -![](figures/芯片移植关键步骤.png "芯片移植关键步骤") - -## 移植规范 - -- 满足OpenHarmony[开源贡献基本规范和准则](https://gitee.com/openharmony/docs/blob/master/zh-cn/contribute/%E5%8F%82%E4%B8%8E%E8%B4%A1%E7%8C%AE.md)。 -- 三方芯片适配所需要贡献的代码主要在device、vendor和arch三个目录,参照[内核目录规范](移植概述.md)和[板级目录规范](移植概述-0.md#section6204129143013)满足基本目录命名和使用规范。 - diff --git "a/zh-cn/device-dev/porting/\347\263\273\347\273\237\347\273\204\344\273\266\350\260\203\347\224\250.md" "b/zh-cn/device-dev/porting/\347\263\273\347\273\237\347\273\204\344\273\266\350\260\203\347\224\250.md" deleted file mode 100755 index 5f2a6f6f6a37ddcbaa7da689cef786fe45346751..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/porting/\347\263\273\347\273\237\347\273\204\344\273\266\350\260\203\347\224\250.md" +++ /dev/null @@ -1,26 +0,0 @@ -# 系统组件调用 - -- [SAMGR](#section105874301910) -- [DFX](#section20064420420) - -系统组件为上层应用提供基础能力,包括SAMGR(系统服务框架子系统)、DFX子系统等。在板级系统移植过程中,只需要选择使用即可,不用对其进行适配。 - -## SAMGR - -**基本介绍** - -系统服务框架基于面向服务的架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务共进程、进程间服务调用等开发能力。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本组件在板级系统移植中必须要使用,否则其他服务组件无法运行。 - -**SAMGR使用说明,请参考:[SAMGR 使用指导](https://gitee.com/openharmony/distributedschedule_samgr_lite/blob/master/README_zh.md)** - -## DFX - -**基本介绍** - -DFX子系统主要包含DFR(Design for Reliability,可靠性)和DFT(Design for Testability,可测试性)特性,为开发者提供代码维测信息。 - -**DFX子系统使用说明,请参考:[DFX子系统使用指导](../subsystems/DFX.md)** - diff --git a/en/device-dev/driver/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/public_sys-resources/icon-caution.gif similarity index 100% rename from en/device-dev/driver/public_sys-resources/icon-caution.gif rename to zh-cn/device-dev/public_sys-resources/icon-caution.gif diff --git a/en/device-dev/driver/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/public_sys-resources/icon-danger.gif similarity index 100% rename from en/device-dev/driver/public_sys-resources/icon-danger.gif rename to zh-cn/device-dev/public_sys-resources/icon-danger.gif diff --git a/en/device-dev/driver/public_sys-resources/icon-note.gif b/zh-cn/device-dev/public_sys-resources/icon-note.gif similarity index 100% rename from en/device-dev/driver/public_sys-resources/icon-note.gif rename to zh-cn/device-dev/public_sys-resources/icon-note.gif diff --git a/en/device-dev/driver/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/public_sys-resources/icon-notice.gif similarity index 100% rename from en/device-dev/driver/public_sys-resources/icon-notice.gif rename to zh-cn/device-dev/public_sys-resources/icon-notice.gif diff --git a/en/device-dev/driver/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/public_sys-resources/icon-tip.gif similarity index 100% rename from en/device-dev/driver/public_sys-resources/icon-tip.gif rename to zh-cn/device-dev/public_sys-resources/icon-tip.gif diff --git a/en/device-dev/driver/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/public_sys-resources/icon-warning.gif similarity index 100% rename from en/device-dev/driver/public_sys-resources/icon-warning.gif rename to zh-cn/device-dev/public_sys-resources/icon-warning.gif diff --git "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277.md" deleted file mode 100755 index 1a6f14d262b1474576a3974dff7c57b205f48aaf..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277.md" +++ /dev/null @@ -1,11 +0,0 @@ -# Hi3516开发板 - -- **[安装开发板环境](安装开发板环境-2.md)** - -- **[运行Hello OHOS](运行Hello-OHOS.md)** - -- **[驱动开发示例](驱动开发示例.md)** - -- **[常见问题](常见问题-3.md)** - - diff --git "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" deleted file mode 100755 index 3e24c43eb01be574c4a48c1d9a6e10d82beeca4e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" +++ /dev/null @@ -1,42 +0,0 @@ -# Hi3516开发板介绍 - -- [简介](#section26131214194212) -- [开发板规格](#section15192203316533) - -## 简介 - -Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。 - -**图 1** Hi3516单板正面外观图 - - -![](figures/3516正面.png) - -## 开发板规格 - -**表 1** Hi3516开发板规格清单 - - - - - - - - - - - - - -

规格类型

-

规格清单

-

处理器及内部存储

-
  • Hi3516DV300芯片
  • DDR3 1GB
  • eMMC4.5,8GB容量
-

外部器件

-
  • 以太网口
  • 音频视频
    • 1路语音输入
    • 1路单声道(AC_L)输出,接3W功放(LM4871)
    • MicroHDMI(1路HDMI 1.4)
    -
  • 摄像头
    • 传感器IMX335
    • 镜头M12,焦距4mm,光圈1.8
    -
  • 显示屏
    • LCD连接器(2.35寸)
    • LCD连接器(5.5寸)
    -
  • 外部器件及接口
    • SD卡接口
    • JTAG/I2S 接口
    • ADC接口
    • 舵机接口
    • Grove连接器
    • USB2.0(Type C)
    • 功能按键3个,2个用户自定义按键,1个升级按键
    • LED指示灯,绿灯,红灯
    -
-
- diff --git "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277.md" deleted file mode 100755 index 61807ea64d579d2364ff6c327864f20d8d6aaa6a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277.md" +++ /dev/null @@ -1,9 +0,0 @@ -# Hi3518开发板 - -- **[安装开发板环境](安装开发板环境-4.md)** - -- **[运行Hello OHOS](运行Hello-OHOS-5.md)** - -- **[常见问题](常见问题-6.md)** - - diff --git "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" deleted file mode 100755 index 1f77aeac075607531fb98955ef218dfd00e3c6ae..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" +++ /dev/null @@ -1,57 +0,0 @@ -# Hi3518开发板介绍 - -- [简介](#section14815247616) -- [开发板规格](#section765112478446) - -## 简介 - -Hi3518EV300作为新一代智慧视觉处理SOC,集成新一代ISP\(Image Signal Processor\)以及H.265视频压缩编码器,同时采用先进低功耗工艺和低功耗架构设计,使其在低码率、高画质、低功耗等方面引领行业水平。 - -**图 1** Hi3518EV300单板正面外观图 -![](figures/Hi3518EV300单板正面外观图.png "Hi3518EV300单板正面外观图") - -**图 2** Hi3518EV300单板背面外观图 - - -![](figures/Hi3518正背面.png) - -## 开发板规格 - -**表 1** Hi3518开发板规格清单 - - - - - - - - - - - - - - - - - - - - - - -

规格类型

-

规格清单

-

处理器内核

-
  • 海思3518EV300
-

成像器件

-
  • 1/2.9 F23
-

外部接口

-
  • 外置麦克风MIC
  • 外置8Ω/1.5W扬声器
-

外部存储器接口

-
  • TF卡

    最大支持128GB(通用FAT32格式)

    -
-

WLAN协议

-
  • 支持 802.11 b/g/n
-
- diff --git "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277.md" deleted file mode 100755 index f6c5f5833f16ede72614678ebc0483389d9120f8..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277.md" +++ /dev/null @@ -1,11 +0,0 @@ -# Hi3861开发板 - -- **[安装开发板环境](安装开发板环境.md)** - -- **[WLAN联网](WLAN联网.md)** - -- **[运行Hello World](运行Hello-World.md)** - -- **[常见问题](常见问题-1.md)** - - diff --git "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" deleted file mode 100755 index ac6a21df22f9865ab77ad461ab1805404c595d0b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" +++ /dev/null @@ -1,157 +0,0 @@ -# Hi3861开发板介绍 - -- [简介](#section19352114194115) -- [资源和约束](#section82610215014) -- [开发板规格](#section169054431017) -- [OpenHarmony关键特性](#section1317173016507) - -## 简介 - -Hi3861 WLAN模组是一片大约2cm\*5cm大小的开发板,是一款高度集成的2.4GHz WLAN SoC芯片,集成IEEE 802.11b/g/n基带和RF(Radio Frequency)电路。支持OpenHarmony,并配套提供开放、易用的开发和调试运行环境。 - -**图 1** Hi3861 WLAN模组外观图 - - -![](figures/3861正面.png) - -另外,Hi3861 WLAN模组还可以通过与Hi3861底板连接,扩充自身的外设能力,底板如下图所示。 - -**图 2** Hi3861底板外观图 - - -![](figures/zh-cn_image_0000001174350615.png) - -- RF电路包括功率放大器PA(Power Amplifier)、低噪声放大器LNA(Low Noise Amplifier)、RF Balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s物理层速率。 -- Hi3861 WLAN基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支持IEEE 802.11 b/g/n协议的各种数据速率。 -- Hi3861芯片集成高性能32bit微处理器、硬件安全引擎以及丰富的外设接口,外设接口包括SPI(Synchronous Peripheral Interface)、UART(Universal Asynchronous Receiver & Transmitter)、I2C(The Inter Integrated Circuit)、PWM(Pulse Width Modulation)、GPIO(General Purpose Input/Output)和多路ADC(Analog to Digital Converter),同时支持高速SDIO2.0(Secure Digital Input/Output)接口,最高时钟可达50MHz;芯片内置SRAM(Static Random Access Memory)和Flash,可独立运行,并支持在Flash上运行程序。 -- Hi3861芯片适用于智能家电等物联网智能终端领域。 - - **图 3** Hi3861功能框图 - - - ![](figures/zh-cn_image_0000001128311066.png) - - -## 资源和约束 - -Hi3861 WLAN模组资源十分有限,整板共2MB FLASH,352KB RAM。在编写业务代码时,需注意资源使用效率。 - -## 开发板规格 - -**表 1** Hi3861 WLAN模组规格清单 - - - - - - - - - - - - - - - - - - - - - - - - - -

规格类型

-

规格清单

-

通用规格

-
  • 1×1 2.4GHz频段(ch1~ch14)
  • PHY支持IEEE 802.11b/g/n
  • MAC支持IEEE802.11 d/e/h/i/k/v/w
-
  • 内置PA和LNA,集成TX/RX Switch、Balun等
  • 支持STA和AP形态,作为AP时最大支持6 个STA接入
  • 支持WFA WPA/WPA2 personal、WPS2.0
  • 支持与BT/BLE芯片共存的2/3/4 线PTA方案
  • 电源电压输入范围:2.3V~3.6V
-
  • IO电源电压支持1.8V和3.3V
-
  • 支持RF自校准方案
  • 低功耗:
    • Ultra Deep Sleep模式:5μA@3.3V
    • DTIM1:1.5mA@3.3V
    • DTIM3:0.8mA@3.3V
    -
-

PHY特性

-
  • 支持IEEE802.11b/g/n单天线所有的数据速率
  • 支持最大速率:72.2Mbps@HT20 MCS7
  • 支持标准20MHz带宽和5M/10M窄带宽
  • 支持STBC
  • 支持Short-GI
-

MAC特性

-
  • 支持A-MPDU,A-MSDU
  • 支持Blk-ACK
  • 支持QoS,满足不同业务服务质量需求
-

CPU子系统

-
  • 高性能 32bit微处理器,最大工作频率160MHz
  • 内嵌SRAM 352KB、ROM 288KB
  • 内嵌 2MB Flash
-

外围接口

-
  • 1个SDIO接口、2个SPI接口、2个I2C接口、3个UART接口、15个GPIO接口、7路ADC输入、6路PWM、1个I2S接口(注:上述接口通过复用实现)
  • 外部主晶体频率40M或24M
-

其他信息

-
  • 封装:QFN-32,5mm×5mm
  • 工作温度:-40℃ ~ +85℃
-
- -## OpenHarmony关键特性 - -OpenHarmony基于Hi3861平台提供了多种开放能力,提供的关键组件如下表所示。 - -**表 2** OpenHarmony关键组件列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

组件名

-

能力介绍

-

WLAN服务

-

提供WLAN服务能力。包括:station和hotspot模式的连接、断开、状态查询等。

-

模组外设控制

-

提供操作外设的能力。包括:I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。

-

分布式软总线

-

OpenHarmony分布式网络中,提供设备被发现、数据传输的能力。

-

设备安全绑定

-

提供在设备互联场景中,数据在设备之间的安全流转的能力。

-

基础加解密

-

提供密钥管理、加解密等能力。

-

系统服务管理

-

系统服务管理基于面向服务的架构,提供了OpenHarmony统一化的系统服务开发框架。

-

启动引导

-

提供系统服务的启动入口标识。在系统服务管理启动时,调用boostrap标识的入口函数,并启动系统服务。

-

系统属性

-

提供获取与设置系统属性的能力。

-

基础库

-

提供公共基础库能力。包括:文件操作、KV存储管理等。

-

DFX

-

提供DFX能力。包括:流水日志、时间打点等。

-

XTS

-

提供OpenHarmony生态认证测试套件的集合能力。

-
- diff --git a/zh-cn/device-dev/quick-start/Readme-CN.md b/zh-cn/device-dev/quick-start/Readme-CN.md index 69991d66becb3cfef2d8980b923dc38cdd43f790..f85dd9b4ea17a9cb1764e9f54b7459e41c40868e 100644 --- a/zh-cn/device-dev/quick-start/Readme-CN.md +++ b/zh-cn/device-dev/quick-start/Readme-CN.md @@ -1,41 +1,41 @@ # 快速入门 -- [轻量和小型系统入门](轻量和小型系统入门.md) - - [概述](概述.md) - - [了解开发板](了解开发板.md) - - [Hi3861开发板介绍](Hi3861开发板介绍.md) - - [Hi3516开发板介绍](Hi3516开发板介绍.md) - - [Hi3518开发板介绍](Hi3518开发板介绍.md) +- [轻量和小型系统入门](quickstart-lite.md) + - [概述](quickstart-lite-overview.md) + - [了解开发板](quickstart-lite-introduction.md) + - [Hi3861开发板介绍](quickstart-lite-introduction-hi3861.md) + - [Hi3516开发板介绍](quickstart-lite-introduction-hi3516.md) + - [Hi3518开发板介绍](quickstart-lite-introduction-hi3518.md) - - [搭建系统环境](搭建系统环境.md) - - [概述](概述-0.md) - - [Windows开发环境准备](Windows开发环境准备.md) - - [Ubuntu编译环境准备](Ubuntu编译环境准备.md) - - [常见问题](常见问题.md) + - [搭建系统环境](quickstart-lite-env-setup.md) + - [概述](quickstart-lite-env-setup-des.md) + - [Windows开发环境准备](quickstart-lite-env-setup-win.md) + - [Ubuntu编译环境准备](quickstart-lite-env-setup-lin.md) + - [常见问题](quickstart-lite-env-setup-faqs.md) - - [开发步骤](开发步骤.md) - - [Hi3861开发板](Hi3861开发板.md) - - [安装开发板环境](安装开发板环境.md) - - [WLAN联网](WLAN联网.md) - - [运行Hello World](运行Hello-World.md) - - [常见问题](常见问题-1.md) + - [开发步骤](quickstart-lite-steps.md) + - [Hi3861开发板](quickstart-lite-steps-board3861.md) + - [安装开发板环境](quickstart-lite-steps-board3861-setting.md) + - [WLAN联网](quickstart-lite-steps-board3861-connection.md) + - [运行Hello World](quickstart-lite-steps-board3861-running.md) + - [常见问题](quickstart-lite-steps-board3861-faqs.md) - - [Hi3516开发板](Hi3516开发板.md) - - [安装开发板环境](安装开发板环境-2.md) - - [运行Hello OHOS](运行Hello-OHOS.md) - - [驱动开发示例](驱动开发示例.md) - - [常见问题](常见问题-3.md) + - [Hi3516开发板](quickstart-lite-steps-board3516.md) + - [安装开发板环境](quickstart-lite-steps-board3516-setting.md) + - [运行Hello OHOS](quickstart-lite-steps-board3516-running.md) + - [驱动开发示例](quickstart-lite-steps-board3516-program.md) + - [常见问题](quickstart-lite-steps-board3516-faqs.md) - - [Hi3518开发板](Hi3518开发板.md) - - [安装开发板环境](安装开发板环境-4.md) - - [运行Hello OHOS](运行Hello-OHOS-5.md) - - [常见问题](常见问题-6.md) + - [Hi3518开发板](quickstart-lite-steps-board3518.md) + - [安装开发板环境](quickstart-lite-steps-board3518-setting.md) + - [运行Hello OHOS](quickstart-lite-steps-board3518-running.md) + - [常见问题](quickstart-lite-steps-board3518-faqs.md) -- [标准系统入门](标准系统入门.md) - - [入门介绍](入门介绍.md) - - [Windows开发环境准备](Windows开发环境准备-7.md) - - [搭建Ubuntu环境及编译(Docker方式)](搭建Ubuntu环境及编译(Docker方式).md) - - [搭建Ubuntu环境及编译(安装包方式)](搭建Ubuntu环境及编译(安装包方式).md) - - [镜像烧录](镜像烧录.md) - - [常见问题](常见问题-8.md) +- [标准系统入门](quickstart-standard.md) + - [入门介绍](quickstart-standard-description.md) + - [Windows开发环境准备](quickstart-standard-windows-environment.md) + - [搭建Ubuntu环境及编译(Docker方式)](quickstart-standard-docker-environment.md) + - [搭建Ubuntu环境及编译(安装包方式)](quickstart-standard-package-environment.md) + - [镜像烧录](quickstart-standard-burn.md) + - [常见问题](quickstart-standard-faq.md) diff --git "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207.md" deleted file mode 100755 index 168c6184821b7c892def48d2f4c3ad5b6f055218..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207.md" +++ /dev/null @@ -1,361 +0,0 @@ -# Ubuntu编译环境准备 - -- [获取软件](#section1897711811517) -- [获取源码](#section1545225464016) -- [安装和配置Python](#section1238412211211) -- [安装gn](#section29216201423) -- [安装ninja](#section8762358731) -- [安装LLVM](#section12202192215415) -- [安装hb](#section15794154618411) - - [前提条件](#section1083283711515) - - [安装方法](#section11518484814) - - [卸载方法](#section3512551574) - -- [安装其他工具](#section830511218494) - - [安装方法](#section54409586499) - - -系统要求:Ubuntu16.04及以上64位系统版本。 - -编译环境搭建分为如下几步: - -1. 获取源码 -2. 安装和配置python -3. 安装gn -4. 安装ninja -5. 安装LLVM -6. 安装hb - ->![](public_sys-resources/icon-notice.gif) **须知:** ->- 针对Ubuntu编译环境我们提供了对应的Docker,该Docker封装了相关编译工具,选择使用Docker的开发者可跳过此章节。Docker使用可参考[Docker方式获取编译环境](../get-code/Docker编译环境.md)。 ->- 通常系统默认安装samba、vim等常用软件,需要做适当适配以支持Linux服务器与Windows工作台之间的文件共享。 ->- 想要详细了解OpenHarmony编译构建模块功能的开发者可参考[编译构建使用指南](../subsystems/编译构建.md)。 - -## 获取软件 - -Linux服务器通用环境配置需要的工具及其获取途径如下表所示: - -**表 1** Linux服务器开发工具及获取途径 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

开发工具

-

用途

-

获取途径

-

源码

-

功能开发

-

参考源码获取

-

Python3.7+

-

编译构建工具

-

通过互联网获取

-

gn

-

产生ninja编译脚本

-

https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz

-

ninja

-

执行ninja编译脚本

-

https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar

-

-

LLVM

-

-

-

编译工具链

-

-

Master及OpenHarmony_v2.x分支/标签,请使用以下10.0.1版本:

-

https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz

-

OpenHarmony_v1.x分支/标签,请使用以下9.0.0版本:

-

https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar

-

hb

-

OpenHarmony编译构建命令行工具

-

通过互联网获取

-

其他工具

-

编译构建中依赖的其他工具(如打包、镜像制作等)

-

通过互联网获取

-
- ->![](public_sys-resources/icon-notice.gif) **须知:** ->- 如果后续通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装gn、ninja编译工具。 ->- (推荐)如果后续通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装gn、ninja、LLVM编译工具。安装gn、ninja、LLVM编译工具时,请确保编译工具的环境变量路径唯一。 - -## 获取源码 - -开发者需要在Linux服务器上下载并解压一套源代码,请参见[源码获取](../get-code/源码获取.md)。 - -## 安装和配置Python - -1. 打开Linux编译服务器终端。 -2. 输入如下命令,查看python版本号,需使用python3.7以上版本。 - - ``` - python3 --version - ``` - - 如果低于python3.7版本,不建议直接升级,请按照如下步骤重新安装。以python3.8为例,按照以下步骤安装python。 - - 1. 运行如下命令,查看Ubuntu版本: - - ``` - cat /etc/issue - ``` - - 1. 根据Ubuntu不同版本,安装python。 - - 如果Ubuntu 版本为18+,运行如下命令。 - - ``` - sudo apt-get install python3.8 - ``` - - - 如果Ubuntu版本为16。 - - a. 安装依赖包 - - ``` - sudo apt update && sudo apt install software-properties-common - ``` - - b. 添加deadsnakes PPA 源,然后按回车键确认安装。 - - ``` - sudo add-apt-repository ppa:deadsnakes/ppa - ``` - - c. 安装python3.8 - - ``` - sudo apt upgrade && sudo apt install python3.8 - ``` - - - -3. 设置python和python3软链接为python3.8。 - - ``` - sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1 - sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1 - ``` - -4. 安装并升级Python包管理工具(pip3),任选如下一种方式。 - - **命令行方式:** - - ``` - sudo apt-get install python3-setuptools python3-pip -y - sudo pip3 install --upgrade pip - ``` - - - **安装包方式:** - - ``` - curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py - python get-pip.py - ``` - - - -## 安装gn - -1. 打开Linux编译服务器终端。 -2. [下载gn工具](https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz)。 -3. 在根目录下创建gn文件夹。 - - ``` - mkdir ~/gn - ``` - -4. 解压gn安装包至\~/gn路径下。 - - ``` - tar -xvf gn-linux-x86-1717.tar.gz -C ~/gn - ``` - -5. 设置环境变量。 - - ``` - vim ~/.bashrc - ``` - - 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - - ``` - export PATH=~/gn:$PATH - ``` - -6. 生效环境变量。 - - ``` - source ~/.bashrc - ``` - - -## 安装ninja - -1. 打开Linux编译服务器终端。 -2. [下载ninja工具](https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar)。 -3. 解压ninja安装包至\~/ninja路径下。 - - ``` - tar -xvf ninja.1.9.0.tar -C ~/ - ``` - -4. 设置环境变量。 - - ``` - vim ~/.bashrc - ``` - - 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - - ``` - export PATH=~/ninja:$PATH - ``` - -5. 生效环境变量。 - - ``` - source ~/.bashrc - ``` - - -## 安装LLVM - -1. 打开Linux编译服务器终端。 -2. [下载LLVM工具](https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz)。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >针对OpenHarmony\_v1.x分支/标签,使用此链接[下载LLVM工具](https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar)。 - -3. 解压LLVM安装包至\~/llvm路径下。 - - ``` - tar -zxvf llvm.tar.gz -C ~/ - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >针对OpenHarmony\_v1.x分支/标签,使用如下命令解压: - >``` - >tar -xvf llvm-linux-9.0.0-36191.tar -C ~/ - >``` - -4. 设置环境变量。 - - ``` - vim ~/.bashrc - ``` - - 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - - ``` - export PATH=~/llvm/bin:$PATH - ``` - -5. 生效环境变量。 - - ``` - source ~/.bashrc - ``` - - -## 安装hb - -### 前提条件 - -请先安装Python 3.7.4及以上版本,请见[安装和配置Python](#section1238412211211)。 - -### 安装方法 - -1. 运行如下命令安装hb - - ``` - python3 -m pip install --user ohos-build - ``` - -2. 设置环境变量 - - ``` - vim ~/.bashrc - ``` - - 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - - ``` - export PATH=~/.local/bin:$PATH - ``` - - 执行如下命令更新环境变量。 - - ``` - source ~/.bashrc - ``` - -3. 执行"hb -h",有打印以下信息即表示安装成功: - - ``` - usage: hb - - OHOS build system - - positional arguments: - {build,set,env,clean} - build Build source code - set OHOS build settings - env Show OHOS build env - clean Clean output - - optional arguments: - -h, --help show this help message and exit - ``` - - -### 卸载方法 - -``` -python3 -m pip uninstall ohos-build -``` - ->![](public_sys-resources/icon-notice.gif) **须知:** ->如果安装hb的过程中遇到问题,请参见下文[常见问题](常见问题.md)进行解决。 - -## 安装其他工具 - -### 安装方法 - -1. apt安装全部依赖的工具 - - ``` - sudo apt-get install build-essential gcc g++ make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-boot-tools mtd-utils - ``` - - diff --git "a/zh-cn/device-dev/quick-start/WLAN\350\201\224\347\275\221.md" "b/zh-cn/device-dev/quick-start/WLAN\350\201\224\347\275\221.md" deleted file mode 100755 index ab20f083f914b8a49bf99109750a3f6dd9cb1e0e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/WLAN\350\201\224\347\275\221.md" +++ /dev/null @@ -1,142 +0,0 @@ -# WLAN联网 - -- [源码编译](#section191121332125319) -- [镜像烧录](#section19458165166) -- [WLAN模组联网](#section194671619167) - -本示例将演示如何通过AT命令完成WLAN模组与网关联网。 - -## 源码编译 - -本节描述如何在Linux服务器上进行WLAN模组版本的编译。 - -如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/Docker编译环境.md)的编译操作。如果Linux编译环境通过软件包方式安装,请参考如下步骤。 - -1. 打开DevEco Device Tool工具,点击“View \> Terminal”,进入终端界面。 - - **图 1** IDE终端工具打开方法 - - - ![](figures/1.png) - - 在终端界面使用ssh命令连接linux服务器,如“ssh user@ipaddr”。 - - **图 2** 终端界面示意图 - - - ![](figures/2.png) - -2. 进入代码根路径,并在终端窗口,执行脚本命令“hb set”、“.”,选择需要编译的版本“wifiiot\_hispark\_pegasus”。 - - **图 3** 在终端界面选择目标构建版本示意图 - - - ![](figures/3.png) - -3. 执行“hb build”启动版本构建。 - - **图 4** 在终端界面执行编译命令示意图 - - - ![](figures/4.png) - -4. 编译结束后,如果出现“wifiiot\_hispark\_pegasus build success”字样,则证明构建成功,如下图所示。 - - **图 5** 编译成功示意图 - - - ![](figures/5.png) - -5. 构建成功后,会在./out/wifiiot/路径中生成以下文件,使用如下命令可以查看,至此编译构建流程结束。 - - ``` - ls -l out/hispark_pegasus/wifiiot_hispark_pegasus/ - ``` - - **图 6** 编译文件存放目录示意图 - - - ![](figures/3-0.png) - - -## 镜像烧录 - -Hi3861 WLAN模组的镜像烧录可以通过OpenHarmony IDE工具DevEco完成,工具的基本使用请参考[DevEco Device Tool使用指南](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),烧录过程包含如下步骤。 - -1. 请连接好电脑和待烧录开发板,需要连接USB口,具体可参考[Hi3861开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3861-0000001105041324)。 -2. 打开电脑的设备管理器,查看并记录对应的串口号。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果对应的串口异常,请根据[Hi3861系列开发板串口驱动安装](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3861-drivers-0000001058153433)安装USB转串口的驱动程序。 - - ![](figures/zh-cn_image_0000001128311118.png) - -3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - - ![](figures/zh-cn_image_0000001128311116.png) - -4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3861系列开发板进行适配,无需单独修改。 -5. 在“hi3861”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 - - - upload\_port:选择步骤[2](#zh-cn_topic_0000001056563976_li848662117291)中查询的串口号。 - - upload\_protocol:选择烧录协议,固定选择“burn-serial”。 - - upload\_partitions:选择待烧录的文件,默认选择hi3861\_app。 - - ![](figures/zh-cn_image_0000001128470922.png) - -6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 -7. 打开工程文件,在DevEco Device Tool界面的“PROJECT TASKS”中,点击hi3861下的**Upload**按钮,启动烧录。 - - ![](figures/zh-cn_image_0000001174270749.png) - -8. 启动烧录后,显示如下提示信息时,请按开发板上的RST按钮重启开发板。 - - ![](figures/zh-cn_image_0000001174270751.png) - -9. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 - - ![](figures/zh-cn_image_0000001174350669.png) - - -## WLAN模组联网 - -完成版本构建及烧录后,下面开始介绍如何在串口终端上执行AT命令,使WLAN模组联网。 - -1. 保持Windows工作台和WLAN模组的连接状态,在DevEco工具最下方,点击“DevEco:Serial Monitor”按钮。 - - **图 7** 打开DevEco串口终端示意图 - - - ![](figures/5-1.png) - -2. 复位WLAN模组,终端界面显示“ready to OS start”,则启动成功。 - - **图 8** WLAN复位成功示意图 - - - ![](figures/6.png) - -3. 在DevEco的串口终端中,依次执行如下AT命令,启动STA模式,连接指定AP热点,并开启DHCP功能。 - - ``` - AT+STARTSTA # 启动STA模式 - AT+SCAN # 扫描周边AP - AT+SCANRESULT # 显示扫描结果 - AT+CONN="SSID",,2,"PASSWORD" # 连接指定AP,其中SSID/PASSWORD为待连接的热点名称和密码 - AT+STASTAT # 查看连接结果 - AT+DHCP=wlan0,1 # 通过DHCP向AP请求wlan0的IP地址 - ``` - -4. 查看WLAN模组与网关联通是否正常,如下图所示。 - - ``` - AT+IFCFG # 查看模组接口IP - AT+PING=X.X.X.X # 检查模组与网关的联通性,其中X.X.X.X需替换为实际的网关地址 - ``` - - **图 9** WLAN模组联网成功示意图 - - - ![](figures/截图.png) - - diff --git "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-7.md" "b/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-7.md" deleted file mode 100644 index bb7588a5ce8be87185e5d16a0a815ba8c342c87c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-7.md" +++ /dev/null @@ -1,176 +0,0 @@ -# Windows开发环境准备 - -- [获取软件](#zh-cn_topic_0000001058091994_section1483143015558) -- [安装Visual Studio Code](#zh-cn_topic_0000001058091994_section71401018163318) -- [安装Python](#zh-cn_topic_0000001058091994_section16266553175320) -- [安装Node.js](#zh-cn_topic_0000001058091994_section5353233124511) -- [安装hpm](#zh-cn_topic_0000001058091994_section173054793610) -- [安装DevEco Device Tool插件](#zh-cn_topic_0000001058091994_section4336315185716) - -系统要求:Windows 10 64位系统。 - -DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展,安装分为如下几步: - -1. 安装Visual Studio Code -2. 安装Python -3. 安装Node.js -4. 安装hpm -5. 安装DevEco Device Tool插件 - -## 获取软件 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

工具名称

-

用途说明

-

版本要求

-

获取渠道

-

Visual Studio Code

-

代码编辑工具

-

V1.53及以上 64位版本。

-

https://code.visualstudio.com/Download

-

Python

-

编译构建工具

-

V3.7.4~V3.8.x 64位版本

-

https://www.python.org/downloads/

-

Node.js

-

提供npm环境

-

v12.0.0及以上 64位版本

-

https://nodejs.org/zh-cn/download/

-

hpm

-

包管理工具

-

最新版

-

请参考安装hpm

-

DevEco Device Tool

-

OpenHarmony源码的编译、烧录、调试插件工具

-

v2.2 Beta1

-

https://device.harmonyos.com/cn/ide#download

-

下载前,请使用华为开发者帐号登录,如未注册,请先注册华为开发者帐号

-
- -## 安装Visual Studio Code - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装Visual Studio Code,打开命令行工具,输入**code --version**命令,检查版本号是否为1.53及以上版本;可以正常返回版本号,说明环境变量设置也正确。 - -1. 双击Visual Studio Code软件包进行安装。安装过程中,请勾选“添加到PATH(重启后生效)”。 - - ![](figures/zh-cn_image_0000001057335403.png) - -2. 安装完成后,打开命令行工具,输入**code --version**命令,可以正常显示版本号说明安装成功。 - -## 安装Python - -1. 双击Python安装包进行安装,勾选“**Add Python 3.8 to PATH**”,然后点击**Install Now**开始安装。 - - ![](figures/zh-cn_image_0000001176317561.png) - -2. 等待安装完成后,点击**Close**。 - - ![](figures/zh-cn_image_0000001142794291.png) - -3. 打开命令行工具,输入python --version,检查安装结果。 - - ![](figures/zh-cn_image_0000001130278040.png) - -4. 在命令行工具中,分别执行如下命令设置pip源,用于后续安装DevEco Device Tool过程中下载依赖的组件包。 - - ``` - pip config set global.trusted-host repo.huaweicloud.com - pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple - pip config set global.timeout 120 - ``` - - -## 安装Node.js - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装Node.js,打开命令行工具,输入**node -v**命令,检查版本号是否为12.0.0及以上版本。 - -1. 点击下载后的软件包进行安装,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。 -2. 重新打开命令行工具,输入“node -v“命令,能正常查询Node.js的版本号,说明Node.js安装成功。 - -## 安装hpm - -该方式需先确保**Node.js**安装成功。 - -在安装hpm前,请检查网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问。这种情况下,需要先[设置npm代理](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032),才能安装hpm。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装hpm,可以执行**npm update -g @ohos/hpm-cli**命令升级hpm至最新版本。 - -1. 建议将npm源配置为国内镜像,例如设置为华为云镜像源。 - - ``` - npm config set registry https://repo.huaweicloud.com/repository/npm/ - ``` - -2. 打开命令行工具,执行如下命令安装最新版本hpm。 - - ``` - npm install -g @ohos/hpm-cli - ``` - - ![](figures/zh-cn_image_0000001073840162.png) - -3. 安装完成后,执行如下命令(V为大写字母)检查hpm安装结果。 - - ``` - hpm -V - ``` - - -## 安装DevEco Device Tool插件 - -安装DevEco Device Tool插件,**主机的用户名不能包含中文字符**,否则可能导致运行出现错误。 - -DevEco Device Tool正常运行需要依赖于C/C++和CodeLLDB插件,在安装完DevEco Device Tool后,会自动从Visual Studio Code的插件市场安装C/C++和CodeLLDB插件。因此,在安装DevEco Device Tool前,请检查Visual Studio Code的网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问,请先[Visual Studio Code代理设置](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144)。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->安装DevEco Device Tool时,请先关闭Visual Studio Code。 - -1. 解压DevEco Device Tool插件压缩包,双击安装包程序进行安装。 -2. 安装过程中,会自动安装DevEco Device Tool所需的依赖文件(如C/C++和CodeLLDB插件)和执行程序。 - - ![](figures/zh-cn_image_0000001072468991.png) - -3. 安装完成后,会自动关闭命令行工具窗口。 -4. 启动Visual Studio Code,点击左侧的![](figures/zh-cn_image_0000001072757874.png)按钮,检查INSTALLED中,是否已成功安装C/C++、CodeLLDB和DevEco Device Tool。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果C/C++和CodeLLDB插件安装不成功,则DevEco Device Tool不能正常运行,解决方法,详细请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/ide/user-guides/offline_plugin_install-0000001074376846)。 - - ![](figures/zh-cn_image_0000001142802505.png) - - diff --git "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207.md" deleted file mode 100755 index cffea83cad92e78f19cdb4222117b2c8c75902f0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207.md" +++ /dev/null @@ -1,182 +0,0 @@ -# Windows开发环境准备 - -- [获取软件](#zh-cn_topic_0000001058091994_section1483143015558) -- [安装Visual Studio Code](#zh-cn_topic_0000001058091994_section71401018163318) -- [安装Python](#zh-cn_topic_0000001058091994_section16266553175320) -- [安装Node.js](#zh-cn_topic_0000001058091994_section5353233124511) -- [安装hpm](#zh-cn_topic_0000001058091994_section173054793610) -- [安装DevEco Device Tool插件](#zh-cn_topic_0000001058091994_section4336315185716) - -系统要求:Windows 10 64位系统。 - -DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展,安装分为如下几步: - -1. 安装Visual Studio Code -2. 安装Python -3. 安装Node.js -4. 安装hpm -5. 安装DevEco Device Tool插件 - -## 获取软件 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

工具名称

-

用途说明

-

版本要求

-

获取渠道

-

Visual Studio Code

-

代码编辑工具

-

V1.53及以上 64位版本。

-

https://code.visualstudio.com/Download

-

Python

-

编译构建工具

-

V3.7.4~V3.8.x 64位版本

-

推荐下载:https://www.python.org/downloads/release/python-388/

-

Node.js

-

提供npm环境

-

v12.0.0及以上 64位版本

-

https://nodejs.org/zh-cn/download/

-

hpm

-

包管理工具

-

最新版

-

请参考安装hpm

-

DevEco Device Tool

-

OpenHarmony源码的编译、烧录、调试插件工具

-

v2.2 Beta1

-

https://device.harmonyos.com/cn/ide#download

-

下载前,请使用华为开发者帐号登录,如未注册,请先注册华为开发者帐号

-
- -## 安装Visual Studio Code - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装Visual Studio Code,打开命令行工具,输入**code --version**命令,检查版本号是否为1.53及以上版本;可以正常返回版本号,说明环境变量设置也正确。 - -1. 双击Visual Studio Code软件包进行安装。安装过程中,请勾选“添加到PATH(重启后生效)”。 - - ![](figures/zh-cn_image_0000001174350653.png) - -2. 安装完成后,重启计算机,使Visual Studio Code的环境变量生效。 -3. 打开命令行工具,输入**code --version**命令,可以正常显示版本号说明安装成功。 - -## 安装Python - -1. 双击Python安装包进行安装,勾选“**Add Python 3.8 to PATH**”,然后点击**Install Now**开始安装。 - - ![](figures/zh-cn_image_0000001128470908.png) - -2. 等待安装完成后,点击**Close**。 - - ![](figures/zh-cn_image_0000001128311104.png) - -3. 打开命令行工具,输入python --version,检查安装结果。 - - ![](figures/zh-cn_image_0000001174350655.png) - -4. 在命令行工具中,分别执行如下命令设置pip源,用于后续安装DevEco Device Tool过程中下载依赖的组件包。 - - ``` - pip config set global.trusted-host repo.huaweicloud.com - pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple - pip config set global.timeout 120 - ``` - - -## 安装Node.js - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装Node.js,打开命令行工具,输入**node -v**命令,检查版本号是否为12.0.0及以上版本。 - -1. 点击下载后的软件包进行安装,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。 -2. 重新打开命令行工具,输入“node -v“命令,能正常查询Node.js的版本号,说明Node.js安装成功。 - - ![](figures/zh-cn_image_0000001128311096.png) - - -## 安装hpm - -该方式需先确保**Node.js**安装成功。 - -在安装hpm前,请检查网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问。这种情况下,需要先[设置npm代理](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032),才能安装hpm。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装hpm,可以执行**npm update -g @ohos/hpm-cli**命令升级hpm至最新版本。 - -1. 建议将npm源配置为国内镜像,例如设置为华为云镜像源。 - - ``` - npm config set registry https://repo.huaweicloud.com/repository/npm/ - ``` - -2. 打开命令行工具,执行如下命令安装最新版本hpm。 - - ``` - npm install -g @ohos/hpm-cli - ``` - - ![](figures/zh-cn_image_0000001128311100.png) - -3. 安装完成后,执行如下命令(V为大写字母)检查hpm安装结果。 - - ``` - hpm -V - ``` - - ![](figures/zh-cn_image_0000001174270735.png) - - -## 安装DevEco Device Tool插件 - -安装DevEco Device Tool插件,**主机的用户名不能包含中文字符**,否则可能导致运行出现错误。 - -DevEco Device Tool正常运行需要依赖于C/C++和CodeLLDB插件,在安装完DevEco Device Tool后,会自动从Visual Studio Code的插件市场安装C/C++和CodeLLDB插件。因此,在安装DevEco Device Tool前,请检查Visual Studio Code的网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问,请先[Visual Studio Code代理设置](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144)。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->安装DevEco Device Tool时,请先关闭Visual Studio Code。 - -1. 解压DevEco Device Tool插件压缩包,双击安装包程序进行安装。 -2. 安装过程中,会自动安装DevEco Device Tool所需的依赖文件(如C/C++和CodeLLDB插件)和执行程序。 - - ![](figures/zh-cn_image_0000001128470902.png) - -3. 安装完成后,会自动关闭命令行工具窗口。 -4. 启动Visual Studio Code,点击左侧的![](figures/zh-cn_image_0000001174350651.png)按钮,检查INSTALLED中,是否已成功安装C/C++、CodeLLDB和DevEco Device Tool。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果C/C++和CodeLLDB插件安装不成功,则DevEco Device Tool不能正常运行,解决方法,详细请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/ide/user-guides/offline_plugin_install-0000001074376846)。 - - ![](figures/zh-cn_image_0000001174270727.png) - - diff --git a/zh-cn/device-dev/quick-start/figures/1.png b/zh-cn/device-dev/quick-start/figure/1.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/1.png rename to zh-cn/device-dev/quick-start/figure/1.png diff --git a/zh-cn/device-dev/quick-start/figures/10.png b/zh-cn/device-dev/quick-start/figure/10.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/10.png rename to zh-cn/device-dev/quick-start/figure/10.png diff --git a/zh-cn/device-dev/quick-start/figures/2.png b/zh-cn/device-dev/quick-start/figure/2.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/2.png rename to zh-cn/device-dev/quick-start/figure/2.png diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334-18.png b/zh-cn/device-dev/quick-start/figure/2021-01-27_170334-16.png similarity index 100% rename from en/device-dev/quick-start/figures/2021-01-27_170334-18.png rename to zh-cn/device-dev/quick-start/figure/2021-01-27_170334-16.png diff --git a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-2.png b/zh-cn/device-dev/quick-start/figure/2021-01-27_170334-2.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/2021-01-27_170334-2.png rename to zh-cn/device-dev/quick-start/figure/2021-01-27_170334-2.png diff --git a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-5.png b/zh-cn/device-dev/quick-start/figure/2021-01-27_170334-5.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/2021-01-27_170334-5.png rename to zh-cn/device-dev/quick-start/figure/2021-01-27_170334-5.png diff --git a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334.png b/zh-cn/device-dev/quick-start/figure/2021-01-27_170334.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/2021-01-27_170334.png rename to zh-cn/device-dev/quick-start/figure/2021-01-27_170334.png diff --git a/zh-cn/device-dev/quick-start/figures/3-0.png b/zh-cn/device-dev/quick-start/figure/3-0.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/3-0.png rename to zh-cn/device-dev/quick-start/figure/3-0.png diff --git a/zh-cn/device-dev/quick-start/figures/3.png b/zh-cn/device-dev/quick-start/figure/3.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/3.png rename to zh-cn/device-dev/quick-start/figure/3.png diff --git "a/zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242.png" "b/zh-cn/device-dev/quick-start/figure/3516\346\255\243\351\235\242.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242.png" rename to "zh-cn/device-dev/quick-start/figure/3516\346\255\243\351\235\242.png" diff --git "a/zh-cn/device-dev/quick-start/figures/3861\346\255\243\351\235\242.png" "b/zh-cn/device-dev/quick-start/figure/3861\346\255\243\351\235\242.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/3861\346\255\243\351\235\242.png" rename to "zh-cn/device-dev/quick-start/figure/3861\346\255\243\351\235\242.png" diff --git a/zh-cn/device-dev/quick-start/figures/4.png b/zh-cn/device-dev/quick-start/figure/4.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/4.png rename to zh-cn/device-dev/quick-start/figure/4.png diff --git a/zh-cn/device-dev/quick-start/figures/5-1.png b/zh-cn/device-dev/quick-start/figure/5-1.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/5-1.png rename to zh-cn/device-dev/quick-start/figure/5-1.png diff --git a/zh-cn/device-dev/quick-start/figures/5.png b/zh-cn/device-dev/quick-start/figure/5.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/5.png rename to zh-cn/device-dev/quick-start/figure/5.png diff --git a/zh-cn/device-dev/quick-start/figures/6.png b/zh-cn/device-dev/quick-start/figure/6.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/6.png rename to zh-cn/device-dev/quick-start/figure/6.png diff --git "a/zh-cn/device-dev/quick-start/figures/Hi3518EV300\345\215\225\346\235\277\346\255\243\351\235\242\345\244\226\350\247\202\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/Hi3518EV300\345\215\225\346\235\277\346\255\243\351\235\242\345\244\226\350\247\202\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/Hi3518EV300\345\215\225\346\235\277\346\255\243\351\235\242\345\244\226\350\247\202\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/Hi3518EV300\345\215\225\346\235\277\346\255\243\351\235\242\345\244\226\350\247\202\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/Hi3518\346\255\243\350\203\214\351\235\242.png" "b/zh-cn/device-dev/quick-start/figure/Hi3518\346\255\243\350\203\214\351\235\242.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/Hi3518\346\255\243\350\203\214\351\235\242.png" rename to "zh-cn/device-dev/quick-start/figure/Hi3518\346\255\243\350\203\214\351\235\242.png" diff --git "a/zh-cn/device-dev/quick-start/figures/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212.png" "b/zh-cn/device-dev/quick-start/figure/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212.png" rename to "zh-cn/device-dev/quick-start/figure/SCons\345\256\211\350\243\205\346\210\220\345\212\237\347\225\214\351\235\242-\347\211\210\346\234\254\350\246\201\346\261\2023-0-4\344\273\245\344\270\212.png" diff --git "a/zh-cn/device-dev/quick-start/figures/U-boot\347\203\247\345\206\231\345\256\214\346\210\220\344\270\262\345\217\243\346\230\276\347\244\272\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/U-boot\347\203\247\345\206\231\345\256\214\346\210\220\344\270\262\345\217\243\346\230\276\347\244\272\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/U-boot\347\203\247\345\206\231\345\256\214\346\210\220\344\270\262\345\217\243\346\230\276\347\244\272\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/U-boot\347\203\247\345\206\231\345\256\214\346\210\220\344\270\262\345\217\243\346\230\276\347\244\272\345\233\276.png" diff --git a/zh-cn/device-dev/quick-start/figures/changjian1-10.png b/zh-cn/device-dev/quick-start/figure/changjian1-10.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/changjian1-10.png rename to zh-cn/device-dev/quick-start/figure/changjian1-10.png diff --git a/zh-cn/device-dev/quick-start/figures/changjian1.png b/zh-cn/device-dev/quick-start/figure/changjian1.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/changjian1.png rename to zh-cn/device-dev/quick-start/figure/changjian1.png diff --git a/zh-cn/device-dev/quick-start/figures/chuankou1-6.png b/zh-cn/device-dev/quick-start/figure/chuankou1-6.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/chuankou1-6.png rename to zh-cn/device-dev/quick-start/figure/chuankou1-6.png diff --git a/zh-cn/device-dev/quick-start/figures/chuankou1.png b/zh-cn/device-dev/quick-start/figure/chuankou1.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/chuankou1.png rename to zh-cn/device-dev/quick-start/figure/chuankou1.png diff --git a/zh-cn/device-dev/quick-start/figures/qi1.png b/zh-cn/device-dev/quick-start/figure/qi1.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/qi1.png rename to zh-cn/device-dev/quick-start/figure/qi1.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001057335403.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001057335403.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001057335403.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001057335403.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001072468991.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001072468991.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001072468991.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001072468991.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001072757874.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001072757874.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001072757874.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001072757874.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073840162.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001073840162.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073840162.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001073840162.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001113969542.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001113969542.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001113969542.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001113969542.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001114129428.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001114129428.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001114129428.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001114129428.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001114129432.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001114129432.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001114129432.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001114129432.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117463460.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001117463460.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117463460.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001117463460.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117621400.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001117621400.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117621400.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001117621400.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311066.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311066.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311066.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311066.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311070.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311070.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311070.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311070.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311072.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311072.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311072.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311072.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311090.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311090.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311090.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311090.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311092.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311092.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311092.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311092.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311094.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311094.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311094.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311094.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311096.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311096.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311096.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311096.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311098.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311098.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311098.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311098.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311100.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311100.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311100.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311100.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311104.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311104.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311104.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311104.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311116.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311116.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311116.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311116.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311118.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311118.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311118.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128311118.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470864.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470864.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470864.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470864.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470880.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470880.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470880.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470880.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470900.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470900.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470900.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470900.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470902.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470902.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470902.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470902.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470904.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470904.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470904.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470904.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470906.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470906.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470906.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470906.png diff --git a/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470908.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470908.png new file mode 100644 index 0000000000000000000000000000000000000000..8aa65e82be8db2e7de62fca8980d00ae42215d96 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470908.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470922.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470922.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470922.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001128470922.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001130278040.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001130278040.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001130278040.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001130278040.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001130584312.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001130584312.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001130584312.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001130584312.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001142794291.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001142794291.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001142794291.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001142794291.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001142802505.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001142802505.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001142802505.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001142802505.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270699.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270699.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270699.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270699.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270713.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270713.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270713.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270713.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270715.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270715.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270715.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270715.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270727.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270727.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270727.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270727.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270729.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270729.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270729.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270729.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270731.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270731.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270731.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270731.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270733.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270733.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270733.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270733.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270735.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270735.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270735.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270735.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270737.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270737.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270737.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270737.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270739.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270739.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270739.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270739.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270743.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270743.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270743.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270743.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270749.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270749.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270749.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270749.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270751.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270751.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270751.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174270751.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350615.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350615.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350615.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350615.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350623.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350623.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350623.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350623.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350633.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350633.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350633.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350633.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350641.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350641.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350641.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350641.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350643.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350643.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350643.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350643.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350647.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350647.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350647.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350647.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350649.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350649.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350649.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350649.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350651.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350651.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350651.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350651.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350653.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350653.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350653.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350653.png diff --git a/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350655.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350655.png new file mode 100644 index 0000000000000000000000000000000000000000..2f6e93e40bf4abee3c83aebf0c5f3299e51dc630 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350655.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350659.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350659.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350659.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350659.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350661.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350661.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350661.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350661.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350669.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350669.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350669.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001174350669.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001176317561.png b/zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001176317561.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001176317561.png rename to zh-cn/device-dev/quick-start/figure/zh-cn_image_0000001176317561.png diff --git "a/zh-cn/device-dev/quick-start/figures/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234-15.png" "b/zh-cn/device-dev/quick-start/figure/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234-15.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234-15.png" rename to "zh-cn/device-dev/quick-start/figure/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234-15.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234.png" "b/zh-cn/device-dev/quick-start/figure/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234.png" rename to "zh-cn/device-dev/quick-start/figure/\345\205\201\350\256\270Visual-Studio-Code\345\272\224\347\224\250\350\256\277\351\227\256\347\275\221\347\273\234.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257-9.png" "b/zh-cn/device-dev/quick-start/figure/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257-9.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257-9.png" rename to "zh-cn/device-dev/quick-start/figure/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257-9.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257.png" "b/zh-cn/device-dev/quick-start/figure/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257.png" rename to "zh-cn/device-dev/quick-start/figure/\345\205\263\351\227\255\344\270\262\345\217\243\347\273\210\347\253\257.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\345\220\257\345\212\250\345\271\266\346\210\220\345\212\237\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\345\220\257\345\212\250\345\271\266\346\210\220\345\212\237\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\345\220\257\345\212\250\345\271\266\346\210\220\345\212\237\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\345\220\257\345\212\250\345\271\266\346\210\220\345\212\237\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\345\220\257\345\212\250\346\210\220\345\212\237\345\271\266\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\345\220\257\345\212\250\346\210\220\345\212\237\345\271\266\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\345\220\257\345\212\250\346\210\220\345\212\237\345\271\266\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\345\220\257\345\212\250\346\210\220\345\212\237\345\271\266\346\211\247\350\241\214\345\272\224\347\224\250\347\250\213\345\272\217\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\210\252\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\346\210\252\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\210\252\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\346\210\252\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276-7.png" "b/zh-cn/device-dev/quick-start/figure/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276-7.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276-7.png" rename to "zh-cn/device-dev/quick-start/figure/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276-7.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\346\211\223\345\274\200\344\270\262\345\217\243\345\244\261\350\264\245\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276-14.png" "b/zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276-14.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276-14.png" rename to "zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276-14.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276Visual-Studio-Code\345\272\224\347\224\250\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257-8.png" "b/zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257-8.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257-8.png" rename to "zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257-8.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257.png" "b/zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257.png" rename to "zh-cn/device-dev/quick-start/figure/\346\237\245\346\211\276\346\230\257\345\220\246\345\255\230\345\234\250\345\215\240\347\224\250\344\270\262\345\217\243\347\232\204\347\273\210\347\253\257.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\346\240\207\345\207\206\347\216\257\345\242\203\345\277\253\351\200\237\345\205\245\351\227\250\346\265\201\347\250\213.png" "b/zh-cn/device-dev/quick-start/figure/\346\240\207\345\207\206\347\216\257\345\242\203\345\277\253\351\200\237\345\205\245\351\227\250\346\265\201\347\250\213.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\346\240\207\345\207\206\347\216\257\345\242\203\345\277\253\351\200\237\345\205\245\351\227\250\346\265\201\347\250\213.png" rename to "zh-cn/device-dev/quick-start/figure/\346\240\207\345\207\206\347\216\257\345\242\203\345\277\253\351\200\237\345\205\245\351\227\250\346\265\201\347\250\213.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" "b/zh-cn/device-dev/quick-start/figure/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" rename to "zh-cn/device-dev/quick-start/figure/\347\237\251\345\275\242\345\244\207\344\273\275-292.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276-3.png" "b/zh-cn/device-dev/quick-start/figure/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276-3.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276-3.png" rename to "zh-cn/device-dev/quick-start/figure/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276-3.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\347\241\254\344\273\266\350\277\236\347\272\277\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276-11.png" "b/zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276-11.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276-11.png" rename to "zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276-11.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\344\270\215\351\200\232-\345\215\225\346\235\277\346\227\240\346\263\225\350\216\267\345\217\226\346\226\207\344\273\266\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276-12.png" "b/zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276-12.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276-12.png" rename to "zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276-12.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\347\275\221\347\273\234\351\230\262\347\201\253\345\242\231\350\256\276\347\275\256\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\350\256\276\347\275\256\345\233\276\344\276\213-4.png" "b/zh-cn/device-dev/quick-start/figure/\350\256\276\347\275\256\345\233\276\344\276\213-4.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\350\256\276\347\275\256\345\233\276\344\276\213-4.png" rename to "zh-cn/device-dev/quick-start/figure/\350\256\276\347\275\256\345\233\276\344\276\213-4.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\350\256\276\347\275\256\345\233\276\344\276\213.png" "b/zh-cn/device-dev/quick-start/figure/\350\256\276\347\275\256\345\233\276\344\276\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\350\256\276\347\275\256\345\233\276\344\276\213.png" rename to "zh-cn/device-dev/quick-start/figure/\350\256\276\347\275\256\345\233\276\344\276\213.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276-13.png" "b/zh-cn/device-dev/quick-start/figure/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276-13.png" similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276-13.png" rename to "zh-cn/device-dev/quick-start/figure/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276-13.png" diff --git "a/zh-cn/device-dev/quick-start/figures/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276.png" "b/zh-cn/device-dev/quick-start/figure/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/figures/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276.png" rename to "zh-cn/device-dev/quick-start/figure/\351\230\262\347\201\253\345\242\231\345\222\214\347\275\221\347\273\234\344\277\235\346\212\244\347\225\214\351\235\242\345\233\276.png" diff --git "a/zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242-16.png" "b/zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242-16.png" deleted file mode 100644 index 6975fb5fef92e35dec2de84b7e7035a39794bdf4..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242-16.png" and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/quick-start/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/quick-start/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/public_sys-resources/icon-note.gif b/zh-cn/device-dev/quick-start/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/quick-start/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/quick-start/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/quick-start/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/public_sys-resources/icon-warning.gif and /dev/null differ diff --git "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-0.md" b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-des.md similarity index 100% rename from "zh-cn/device-dev/quick-start/\346\246\202\350\277\260-0.md" rename to zh-cn/device-dev/quick-start/quickstart-lite-env-setup-des.md diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230.md" b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-faqs.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230.md" rename to zh-cn/device-dev/quick-start/quickstart-lite-env-setup-faqs.md diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-lin.md b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-lin.md new file mode 100644 index 0000000000000000000000000000000000000000..ddd8fd5f4fb8249098c4bf7d00ecb4d697e9cbaf --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-lin.md @@ -0,0 +1,361 @@ +# Ubuntu编译环境准备 + +- [获取软件](#section1897711811517) +- [获取源码](#section1545225464016) +- [安装和配置Python](#section1238412211211) +- [安装gn](#section29216201423) +- [安装ninja](#section8762358731) +- [安装LLVM](#section12202192215415) +- [安装hb](#section15794154618411) + - [前提条件](#section1083283711515) + - [安装方法](#section11518484814) + - [卸载方法](#section3512551574) + +- [安装其他工具](#section830511218494) + - [安装方法](#section54409586499) + + +系统要求:Ubuntu16.04及以上64位系统版本。 + +编译环境搭建分为如下几步: + +1. 获取源码 +2. 安装和配置python +3. 安装gn +4. 安装ninja +5. 安装LLVM +6. 安装hb + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>- 针对Ubuntu编译环境我们提供了对应的Docker,该Docker封装了相关编译工具,选择使用Docker的开发者可跳过此章节。Docker使用可参考[Docker方式获取编译环境](../get-code/gettools-acquire.md)。 +>- 通常系统默认安装samba、vim等常用软件,需要做适当适配以支持Linux服务器与Windows工作台之间的文件共享。 +>- 想要详细了解OpenHarmony编译构建模块功能的开发者可参考[编译构建使用指南](../subsystems/subsys-build-mini-lite.md)。 + +## 获取软件 + +Linux服务器通用环境配置需要的工具及其获取途径如下表所示: + +**表 1** Linux服务器开发工具及获取途径 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

开发工具

+

用途

+

获取途径

+

源码

+

功能开发

+

参考源码获取

+

Python3.7+

+

编译构建工具

+

通过互联网获取

+

gn

+

产生ninja编译脚本

+

https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz

+

ninja

+

执行ninja编译脚本

+

https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar

+

+

LLVM

+

+

+

编译工具链

+

+

Master及OpenHarmony_v2.x分支/标签,请使用以下10.0.1版本:

+

https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz

+

OpenHarmony_v1.x分支/标签,请使用以下9.0.0版本:

+

https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar

+

hb

+

OpenHarmony编译构建命令行工具

+

通过互联网获取

+

其他工具

+

编译构建中依赖的其他工具(如打包、镜像制作等)

+

通过互联网获取

+
+ +>![](../public_sys-resources/icon-notice.gif) **须知:** +>- 如果后续通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装gn、ninja编译工具。 +>- (推荐)如果后续通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装gn、ninja、LLVM编译工具。安装gn、ninja、LLVM编译工具时,请确保编译工具的环境变量路径唯一。 + +## 获取源码 + +开发者需要在Linux服务器上下载并解压一套源代码,请参见[源码获取](../get-code/sourcecode-acquire.md)。 + +## 安装和配置Python + +1. 打开Linux编译服务器终端。 +2. 输入如下命令,查看python版本号,需使用python3.7以上版本。 + + ``` + python3 --version + ``` + + 如果低于python3.7版本,不建议直接升级,请按照如下步骤重新安装。以python3.8为例,按照以下步骤安装python。 + + 1. 运行如下命令,查看Ubuntu版本: + + ``` + cat /etc/issue + ``` + + 1. 根据Ubuntu不同版本,安装python。 + - 如果Ubuntu 版本为18+,运行如下命令。 + + ``` + sudo apt-get install python3.8 + ``` + + - 如果Ubuntu版本为16。 + + a. 安装依赖包 + + ``` + sudo apt update && sudo apt install software-properties-common + ``` + + b. 添加deadsnakes PPA 源,然后按回车键确认安装。 + + ``` + sudo add-apt-repository ppa:deadsnakes/ppa + ``` + + c. 安装python3.8 + + ``` + sudo apt upgrade && sudo apt install python3.8 + ``` + + + +3. 设置python和python3软链接为python3.8。 + + ``` + sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1 + sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1 + ``` + +4. 安装并升级Python包管理工具(pip3),任选如下一种方式。 + - **命令行方式:** + + ``` + sudo apt-get install python3-setuptools python3-pip -y + sudo pip3 install --upgrade pip + ``` + + - **安装包方式:** + + ``` + curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py + python get-pip.py + ``` + + + +## 安装gn + +1. 打开Linux编译服务器终端。 +2. [下载gn工具](https://repo.huaweicloud.com/harmonyos/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz)。 +3. 在根目录下创建gn文件夹。 + + ``` + mkdir ~/gn + ``` + +4. 解压gn安装包至\~/gn路径下。 + + ``` + tar -xvf gn-linux-x86-1717.tar.gz -C ~/gn + ``` + +5. 设置环境变量。 + + ``` + vim ~/.bashrc + ``` + + 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 + + ``` + export PATH=~/gn:$PATH + ``` + +6. 生效环境变量。 + + ``` + source ~/.bashrc + ``` + + +## 安装ninja + +1. 打开Linux编译服务器终端。 +2. [下载ninja工具](https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar)。 +3. 解压ninja安装包至\~/ninja路径下。 + + ``` + tar -xvf ninja.1.9.0.tar -C ~/ + ``` + +4. 设置环境变量。 + + ``` + vim ~/.bashrc + ``` + + 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 + + ``` + export PATH=~/ninja:$PATH + ``` + +5. 生效环境变量。 + + ``` + source ~/.bashrc + ``` + + +## 安装LLVM + +1. 打开Linux编译服务器终端。 +2. [下载LLVM工具](https://repo.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz)。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >针对OpenHarmony\_v1.x分支/标签,使用此链接[下载LLVM工具](https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar)。 + +3. 解压LLVM安装包至\~/llvm路径下。 + + ``` + tar -zxvf llvm.tar.gz -C ~/ + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >针对OpenHarmony\_v1.x分支/标签,使用如下命令解压: + >``` + >tar -xvf llvm-linux-9.0.0-36191.tar -C ~/ + >``` + +4. 设置环境变量。 + + ``` + vim ~/.bashrc + ``` + + 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 + + ``` + export PATH=~/llvm/bin:$PATH + ``` + +5. 生效环境变量。 + + ``` + source ~/.bashrc + ``` + + +## 安装hb + +### 前提条件 + +请先安装Python 3.7.4及以上版本,请见[安装和配置Python](#section1238412211211)。 + +### 安装方法 + +1. 运行如下命令安装hb + + ``` + python3 -m pip install --user ohos-build + ``` + +2. 设置环境变量 + + ``` + vim ~/.bashrc + ``` + + 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 + + ``` + export PATH=~/.local/bin:$PATH + ``` + + 执行如下命令更新环境变量。 + + ``` + source ~/.bashrc + ``` + +3. 执行"hb -h",有打印以下信息即表示安装成功: + + ``` + usage: hb + + OHOS build system + + positional arguments: + {build,set,env,clean} + build Build source code + set OHOS build settings + env Show OHOS build env + clean Clean output + + optional arguments: + -h, --help show this help message and exit + ``` + + +### 卸载方法 + +``` +python3 -m pip uninstall ohos-build +``` + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>如果安装hb的过程中遇到问题,请参见下文[常见问题](quickstart-lite-env-setup-faqs.md)进行解决。 + +## 安装其他工具 + +### 安装方法 + +1. apt安装全部依赖的工具 + + ``` + sudo apt-get install build-essential gcc g++ make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-boot-tools mtd-utils gcc-arm-linux-gnueabi + ``` + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-win.md b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-win.md new file mode 100644 index 0000000000000000000000000000000000000000..7f51e21e0b4a80f2d6044c50c05f83b4885fa31f --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-win.md @@ -0,0 +1,182 @@ +# Windows开发环境准备 + +- [获取软件](#zh-cn_topic_0000001058091994_section1483143015558) +- [安装Visual Studio Code](#zh-cn_topic_0000001058091994_section71401018163318) +- [安装Python](#zh-cn_topic_0000001058091994_section16266553175320) +- [安装Node.js](#zh-cn_topic_0000001058091994_section5353233124511) +- [安装hpm](#zh-cn_topic_0000001058091994_section173054793610) +- [安装DevEco Device Tool插件](#zh-cn_topic_0000001058091994_section4336315185716) + +系统要求:Windows 10 64位系统。 + +DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展,安装分为如下几步: + +1. 安装Visual Studio Code +2. 安装Python +3. 安装Node.js +4. 安装hpm +5. 安装DevEco Device Tool插件 + +## 获取软件 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

工具名称

+

用途说明

+

版本要求

+

获取渠道

+

Visual Studio Code

+

代码编辑工具

+

V1.53及以上 64位版本。

+

https://code.visualstudio.com/Download

+

Python

+

编译构建工具

+

V3.7.4~V3.8.x 64位版本

+

推荐下载:https://www.python.org/downloads/release/python-388/

+

Node.js

+

提供npm环境

+

v12.0.0及以上 64位版本

+

https://nodejs.org/zh-cn/download/

+

hpm

+

包管理工具

+

最新版

+

请参考安装hpm

+

DevEco Device Tool

+

OpenHarmony源码的编译、烧录、调试插件工具

+

v2.2 Beta1

+

https://device.harmonyos.com/cn/ide#download

+

下载前,请使用华为开发者帐号登录,如未注册,请先注册华为开发者帐号

+
+ +## 安装Visual Studio Code + +>![](../public_sys-resources/icon-note.gif) **说明:** +>如果已安装Visual Studio Code,打开命令行工具,输入**code --version**命令,检查版本号是否为1.53及以上版本;可以正常返回版本号,说明环境变量设置也正确。 + +1. 双击Visual Studio Code软件包进行安装。安装过程中,请勾选“添加到PATH(重启后生效)”。 + + ![](figure/zh-cn_image_0000001174350653.png) + +2. 安装完成后,重启计算机,使Visual Studio Code的环境变量生效。 +3. 打开命令行工具,输入**code --version**命令,可以正常显示版本号说明安装成功。 + +## 安装Python + +1. 双击Python安装包进行安装,勾选“**Add Python 3.8 to PATH**”,然后点击**Install Now**开始安装。 + + ![](figure/zh-cn_image_0000001128470908.png) + +2. 等待安装完成后,点击**Close**。 + + ![](figure/zh-cn_image_0000001128311104.png) + +3. 打开命令行工具,输入python --version,检查安装结果。 + + ![](figure/zh-cn_image_0000001174350655.png) + +4. 在命令行工具中,分别执行如下命令设置pip源,用于后续安装DevEco Device Tool过程中下载依赖的组件包。 + + ``` + pip config set global.trusted-host repo.huaweicloud.com + pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple + pip config set global.timeout 120 + ``` + + +## 安装Node.js + +>![](../public_sys-resources/icon-note.gif) **说明:** +>如果已安装Node.js,打开命令行工具,输入**node -v**命令,检查版本号是否为12.0.0及以上版本。 + +1. 点击下载后的软件包进行安装,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。 +2. 重新打开命令行工具,输入“node -v“命令,能正常查询Node.js的版本号,说明Node.js安装成功。 + + ![](figure/zh-cn_image_0000001128311096.png) + + +## 安装hpm + +该方式需先确保**Node.js**安装成功。 + +在安装hpm前,请检查网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问。这种情况下,需要先[设置npm代理](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032),才能安装hpm。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>如果已安装hpm,可以执行**npm update -g @ohos/hpm-cli**命令升级hpm至最新版本。 + +1. 建议将npm源配置为国内镜像,例如设置为华为云镜像源。 + + ``` + npm config set registry https://repo.huaweicloud.com/repository/npm/ + ``` + +2. 打开命令行工具,执行如下命令安装最新版本hpm。 + + ``` + npm install -g @ohos/hpm-cli + ``` + + ![](figure/zh-cn_image_0000001128311100.png) + +3. 安装完成后,执行如下命令(V为大写字母)检查hpm安装结果。 + + ``` + hpm -V + ``` + + ![](figure/zh-cn_image_0000001174270735.png) + + +## 安装DevEco Device Tool插件 + +安装DevEco Device Tool插件,**主机的用户名不能包含中文字符**,否则可能导致运行出现错误。 + +DevEco Device Tool正常运行需要依赖于C/C++和CodeLLDB插件,在安装完DevEco Device Tool后,会自动从Visual Studio Code的插件市场安装C/C++和CodeLLDB插件。因此,在安装DevEco Device Tool前,请检查Visual Studio Code的网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问,请先[Visual Studio Code代理设置](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144)。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>安装DevEco Device Tool时,请先关闭Visual Studio Code。 + +1. 解压DevEco Device Tool插件压缩包,双击安装包程序进行安装。 +2. 安装过程中,会自动安装DevEco Device Tool所需的依赖文件(如C/C++和CodeLLDB插件)和执行程序。 + + ![](figure/zh-cn_image_0000001128470902.png) + +3. 安装完成后,会自动关闭命令行工具窗口。 +4. 启动Visual Studio Code,点击左侧的![](figure/zh-cn_image_0000001174350651.png)按钮,检查INSTALLED中,是否已成功安装C/C++、CodeLLDB和DevEco Device Tool。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如果C/C++和CodeLLDB插件安装不成功,则DevEco Device Tool不能正常运行,解决方法,详细请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/ide/user-guides/offline_plugin_install-0000001074376846)。 + + ![](figure/zh-cn_image_0000001174270727.png) + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-env-setup.md b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup.md new file mode 100644 index 0000000000000000000000000000000000000000..f5782f2a9f8bfcd10518821f6e700751928e9491 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-env-setup.md @@ -0,0 +1,11 @@ +# 搭建系统环境 + +- **[概述](quickstart-lite-env-setup-des.md)** + +- **[Windows开发环境准备](quickstart-lite-env-setup-win.md)** + +- **[Ubuntu编译环境准备](quickstart-lite-env-setup-lin.md)** + +- **[常见问题](quickstart-lite-env-setup-faqs.md)** + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3516.md b/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3516.md new file mode 100644 index 0000000000000000000000000000000000000000..1224e4f34641a9e46d69354db9acf0a7d5cf06a3 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3516.md @@ -0,0 +1,42 @@ +# Hi3516开发板介绍 + +- [简介](#section26131214194212) +- [开发板规格](#section15192203316533) + +## 简介 + +Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。 + +**图 1** Hi3516单板正面外观图 + + +![](figure/3516正面.png) + +## 开发板规格 + +**表 1** Hi3516开发板规格清单 + + + + + + + + + + + + + +

规格类型

+

规格清单

+

处理器及内部存储

+
  • Hi3516DV300芯片
  • DDR3 1GB
  • eMMC4.5,8GB容量
+

外部器件

+
  • 以太网口
  • 音频视频
    • 1路语音输入
    • 1路单声道(AC_L)输出,接3W功放(LM4871)
    • MicroHDMI(1路HDMI 1.4)
    +
  • 摄像头
    • 传感器IMX335
    • 镜头M12,焦距4mm,光圈1.8
    +
  • 显示屏
    • LCD连接器(2.35寸)
    • LCD连接器(5.5寸)
    +
  • 外部器件及接口
    • SD卡接口
    • JTAG/I2S 接口
    • ADC接口
    • 舵机接口
    • Grove连接器
    • USB2.0(Type C)
    • 功能按键3个,2个用户自定义按键,1个升级按键
    • LED指示灯,绿灯,红灯
    +
+
+ diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3518.md b/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3518.md new file mode 100644 index 0000000000000000000000000000000000000000..211dffba8a9df92bdec701f63e94a84e98fc1a90 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3518.md @@ -0,0 +1,57 @@ +# Hi3518开发板介绍 + +- [简介](#section14815247616) +- [开发板规格](#section765112478446) + +## 简介 + +Hi3518EV300作为新一代智慧视觉处理SOC,集成新一代ISP\(Image Signal Processor\)以及H.265视频压缩编码器,同时采用先进低功耗工艺和低功耗架构设计,使其在低码率、高画质、低功耗等方面引领行业水平。 + +**图 1** Hi3518EV300单板正面外观图 +![](figure/Hi3518EV300单板正面外观图.png "Hi3518EV300单板正面外观图") + +**图 2** Hi3518EV300单板背面外观图 + + +![](figure/Hi3518正背面.png) + +## 开发板规格 + +**表 1** Hi3518开发板规格清单 + + + + + + + + + + + + + + + + + + + + + + +

规格类型

+

规格清单

+

处理器内核

+
  • 海思3518EV300
+

成像器件

+
  • 1/2.9 F23
+

外部接口

+
  • 外置麦克风MIC
  • 外置8Ω/1.5W扬声器
+

外部存储器接口

+
  • TF卡

    最大支持128GB(通用FAT32格式)

    +
+

WLAN协议

+
  • 支持 802.11 b/g/n
+
+ diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3861.md b/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3861.md new file mode 100644 index 0000000000000000000000000000000000000000..84549ecc121b4df54275fb870af729d55ae2010b --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3861.md @@ -0,0 +1,157 @@ +# Hi3861开发板介绍 + +- [简介](#section19352114194115) +- [资源和约束](#section82610215014) +- [开发板规格](#section169054431017) +- [OpenHarmony关键特性](#section1317173016507) + +## 简介 + +Hi3861 WLAN模组是一片大约2cm\*5cm大小的开发板,是一款高度集成的2.4GHz WLAN SoC芯片,集成IEEE 802.11b/g/n基带和RF(Radio Frequency)电路。支持OpenHarmony,并配套提供开放、易用的开发和调试运行环境。 + +**图 1** Hi3861 WLAN模组外观图 + + +![](figure/3861正面.png) + +另外,Hi3861 WLAN模组还可以通过与Hi3861底板连接,扩充自身的外设能力,底板如下图所示。 + +**图 2** Hi3861底板外观图 + + +![](figure/zh-cn_image_0000001174350615.png) + +- RF电路包括功率放大器PA(Power Amplifier)、低噪声放大器LNA(Low Noise Amplifier)、RF Balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s物理层速率。 +- Hi3861 WLAN基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支持IEEE 802.11 b/g/n协议的各种数据速率。 +- Hi3861芯片集成高性能32bit微处理器、硬件安全引擎以及丰富的外设接口,外设接口包括SPI(Synchronous Peripheral Interface)、UART(Universal Asynchronous Receiver & Transmitter)、I2C(The Inter Integrated Circuit)、PWM(Pulse Width Modulation)、GPIO(General Purpose Input/Output)和多路ADC(Analog to Digital Converter),同时支持高速SDIO2.0(Secure Digital Input/Output)接口,最高时钟可达50MHz;芯片内置SRAM(Static Random Access Memory)和Flash,可独立运行,并支持在Flash上运行程序。 +- Hi3861芯片适用于智能家电等物联网智能终端领域。 + + **图 3** Hi3861功能框图 + + + ![](figure/zh-cn_image_0000001128311066.png) + + +## 资源和约束 + +Hi3861 WLAN模组资源十分有限,整板共2MB FLASH,352KB RAM。在编写业务代码时,需注意资源使用效率。 + +## 开发板规格 + +**表 1** Hi3861 WLAN模组规格清单 + + + + + + + + + + + + + + + + + + + + + + + + + +

规格类型

+

规格清单

+

通用规格

+
  • 1×1 2.4GHz频段(ch1~ch14)
  • PHY支持IEEE 802.11b/g/n
  • MAC支持IEEE802.11 d/e/h/i/k/v/w
+
  • 内置PA和LNA,集成TX/RX Switch、Balun等
  • 支持STA和AP形态,作为AP时最大支持6 个STA接入
  • 支持WFA WPA/WPA2 personal、WPS2.0
  • 支持与BT/BLE芯片共存的2/3/4 线PTA方案
  • 电源电压输入范围:2.3V~3.6V
+
  • IO电源电压支持1.8V和3.3V
+
  • 支持RF自校准方案
  • 低功耗:
    • Ultra Deep Sleep模式:5μA@3.3V
    • DTIM1:1.5mA@3.3V
    • DTIM3:0.8mA@3.3V
    +
+

PHY特性

+
  • 支持IEEE802.11b/g/n单天线所有的数据速率
  • 支持最大速率:72.2Mbps@HT20 MCS7
  • 支持标准20MHz带宽和5M/10M窄带宽
  • 支持STBC
  • 支持Short-GI
+

MAC特性

+
  • 支持A-MPDU,A-MSDU
  • 支持Blk-ACK
  • 支持QoS,满足不同业务服务质量需求
+

CPU子系统

+
  • 高性能 32bit微处理器,最大工作频率160MHz
  • 内嵌SRAM 352KB、ROM 288KB
  • 内嵌 2MB Flash
+

外围接口

+
  • 1个SDIO接口、2个SPI接口、2个I2C接口、3个UART接口、15个GPIO接口、7路ADC输入、6路PWM、1个I2S接口(注:上述接口通过复用实现)
  • 外部主晶体频率40M或24M
+

其他信息

+
  • 封装:QFN-32,5mm×5mm
  • 工作温度:-40℃ ~ +85℃
+
+ +## OpenHarmony关键特性 + +OpenHarmony基于Hi3861平台提供了多种开放能力,提供的关键组件如下表所示。 + +**表 2** OpenHarmony关键组件列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

组件名

+

能力介绍

+

WLAN服务

+

提供WLAN服务能力。包括:station和hotspot模式的连接、断开、状态查询等。

+

模组外设控制

+

提供操作外设的能力。包括:I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。

+

分布式软总线

+

OpenHarmony分布式网络中,提供设备被发现、数据传输的能力。

+

设备安全绑定

+

提供在设备互联场景中,数据在设备之间的安全流转的能力。

+

基础加解密

+

提供密钥管理、加解密等能力。

+

系统服务管理

+

系统服务管理基于面向服务的架构,提供了OpenHarmony统一化的系统服务开发框架。

+

启动引导

+

提供系统服务的启动入口标识。在系统服务管理启动时,调用boostrap标识的入口函数,并启动系统服务。

+

系统属性

+

提供获取与设置系统属性的能力。

+

基础库

+

提供公共基础库能力。包括:文件操作、KV存储管理等。

+

DFX

+

提供DFX能力。包括:流水日志、时间打点等。

+

XTS

+

提供OpenHarmony生态认证测试套件的集合能力。

+
+ diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-introduction.md b/zh-cn/device-dev/quick-start/quickstart-lite-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..65e4fde55ca286b55fb1980a6cd7b67929cb9544 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-introduction.md @@ -0,0 +1,9 @@ +# 了解开发板 + +- **[Hi3861开发板介绍](quickstart-lite-introduction-hi3861.md)** + +- **[Hi3516开发板介绍](quickstart-lite-introduction-hi3516.md)** + +- **[Hi3518开发板介绍](quickstart-lite-introduction-hi3518.md)** + + diff --git "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260.md" b/zh-cn/device-dev/quick-start/quickstart-lite-overview.md similarity index 100% rename from "zh-cn/device-dev/quick-start/\346\246\202\350\277\260.md" rename to zh-cn/device-dev/quick-start/quickstart-lite-overview.md diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-faqs.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..ff748404f05d31f54d19fcd4744fa76fdc7febfe --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-faqs.md @@ -0,0 +1,175 @@ +# 常见问题 + +- [烧写选择串口后提示失败](#section627268185113) +- [Windows电脑与单板网络连接失败](#section195391036568) +- [烧写失败](#section571164016565) +- [编译构建过程中,提示找不到“python”](#section1039835245619) +- [串口无回显](#section14871149155911) + +## 烧写选择串口后提示失败 + +- **现象描述** + + 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied。 + + **图 1** 打开串口失败图 + ![](figure/打开串口失败图.png "打开串口失败图") + +- **可能原因** + + 串口已经被占用。 + +- **解决办法** + +1. 按图依次选择下拉框,查找带有serial-xx的终端 + + **图 2** 查找是否存在占用串口的终端 + ![](figure/查找是否存在占用串口的终端.png "查找是否存在占用串口的终端") + +2. 点击标号中的垃圾桶图标,关闭串口。 + + **图 3** 关闭串口终端 + ![](figure/关闭串口终端.png "关闭串口终端") + +3. 重新点击烧写,选择串口并开始烧写程序 + + **图 4** 重新启动烧写任务 + + + ![](figure/changjian1.png) + + +## Windows电脑与单板网络连接失败 + +- **现象描述** + + 点击烧写并选择串口后,无法获取文件。 + + **图 5** 网络不通,单板无法获取文件图 + ![](figure/网络不通-单板无法获取文件图.png "网络不通-单板无法获取文件图") + +- **可能原因** + + 单板网络与Windows电脑不联通。 + + Windows电脑防火墙未允许Visual Studio Code联网。 + +- **解决方法** + +1. 检查网线是否连接。 +2. 点击Windows防火墙。 + + **图 6** 网络防火墙设置图 + ![](figure/网络防火墙设置图.png "网络防火墙设置图") + +3. 点击“允许应用通过防火墙”。 + + **图 7** 防火墙和网络保护界面图 + ![](figure/防火墙和网络保护界面图.png "防火墙和网络保护界面图") + +4. 查找Visual Studio Code应用。 + + **图 8** 查找Visual Studio Code应用图 + ![](figure/查找Visual-Studio-Code应用图.png "查找Visual-Studio-Code应用图") + +5. 勾选Visual Studio Code的专用和公用网络的访问权限。 + + **图 9** 允许Visual Studio Code应用访问网络 + ![](figure/允许Visual-Studio-Code应用访问网络.png "允许Visual-Studio-Code应用访问网络") + + +## 烧写失败 + +- **现象描述** + + 点击烧写并选择串口后,出现无法烧写的情况。 + +- **可能原因** + + 安装IDE插件DevEco后未重启。 + +- **解决方法** + + 重启IDE。 + + +## 编译构建过程中,提示找不到“python” + +- **现象描述** + + ![](figure/zh-cn_image_0000001174270715.png) + + +- **可能原因1** + + 没有装python。 + +- **解决办法** + + 请按照[安装python](quickstart-lite-env-setup-lin.md)。 + +- **可能原因2** + + ![](figure/zh-cn_image_0000001128470880.png) + +- **解决办法** + + usr/bin目录下没有python软链接,请运行以下命令: + + ``` + # cd /usr/bin/ + # which python3 + # ln -s /usr/local/bin/python3 python + # python --version + ``` + + 例: + + ![](figure/zh-cn_image_0000001174270713.png) + + +## 串口无回显 + +- **现象描述** + + 串口显示已连接,重启单板后,回车无任何回显。 + +- **可能原因1** + + 串口连接错误。 + +- **解决办法** + + 修改串口号。 + + 请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行内[步骤1](#section627268185113)修改串口号。 + + +- **可能原因2** + + 单板U-boot被损坏。 + +- **解决办法** + + 烧写U-boot。 + + 若上述步骤依旧无法连接串口,可能由于单板U-boot损坏,按下述步骤烧写U-boot。 + + +1. 获取引导文件U-boot。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >单板的U-boot文件请在开源包中获取: + >Hi3516DV300:device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin + >Hi3518EV300:device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin + +2. 根据USB烧写步骤烧写U-boot文件。 + + 按照[Hi3516系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Hi3518系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3518_upload-0000001057313128)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。 + +3. 烧写完成后,登录串口如下图所示。 + + **图 10** U-boot烧写完成串口显示图 + ![](figure/U-boot烧写完成串口显示图.png "U-boot烧写完成串口显示图") + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-program.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-program.md new file mode 100644 index 0000000000000000000000000000000000000000..7b43c52c82cf9e8f6c80568f1404af8521106edf --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-program.md @@ -0,0 +1,503 @@ +# 驱动开发示例 + +- [驱动程序介绍](#s8efc1952ebfe4d1ea717182e108c29bb) +- [编译和烧写](#section660016185110) +- [镜像运行](#section333215226219) +- [下一步学习](#section9712145420182) + +本节指导开发者在单板上运行第一个驱动程序,其中包括驱动程序介绍、编译、烧写、运行等步骤。 + +## 驱动程序介绍 + +下面基于HDF框架,提供一个简单的UART(Universal Asynchronous Receiver/Transmitter)平台驱动开发样例,包含配置文件的添加,驱动代码的实现以及用户态程序和驱动交互的流程。驱动程序源码位于vendor/huawei/hdf/sample目录 + +1. 添加配置。 + + 在HDF框架的驱动配置文件(例如device/hisilicon/hi3516dv300/sdk\_liteos/config/uart/uart\_config.hcs)中添加该驱动的配置信息,如下所示: + + ``` + root { + platform { + uart_sample { + num = 5; // UART设备编号 + base = 0x120a0000; // UART 寄存器基地址 + irqNum = 38; + baudrate = 115200; + uartClk = 24000000; + wlen = 0x60; + parity = 0; + stopBit = 0; + match_attr = "sample_uart_5"; + } + } + } + ``` + + 在HDF框架的设备配置文件(例如vendor/hisilicon/ipcamera\_hi3516dv300\_liteos/config/device\_info/device\_info.hcs)中添加该驱动的设备节点信息,如下所示: + + ``` + root { + device_info { + platform :: host { + hostName = "platform_host"; + priority = 50; + device_uart :: device { + device5 :: deviceNode { + policy = 2; + priority = 10; + permission = 0660; + moduleName = "UART_SAMPLE"; + serviceName = "HDF_PLATFORM_UART_5"; + deviceMatchAttr = "sample_uart_5"; + } + } + } + } + } + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >配置文件与UART驱动示例的源码在同一个路径,需要手动添加到Hi3516DV300单板路径下。 + +2. 注册UART驱动入口。 + + 基于HDF框架注册UART驱动的入口HdfDriverEntry,代码如下: + + ``` + // 绑定UART驱动接口到HDF框架 + static int32_t SampleUartDriverBind(struct HdfDeviceObject *device) + { + struct UartHost *uartHost = NULL; + + if (device == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + HDF_LOGI("Enter %s:", __func__); + + uartHost = UartHostCreate(device); + if (uartHost == NULL) { + HDF_LOGE("%s: UartHostCreate failed", __func__); + return HDF_FAILURE; + } + uartHost->service.Dispatch = SampleDispatch; + return HDF_SUCCESS; + } + + // 从UART驱动的HCS中获取配置信息 + static uint32_t GetUartDeviceResource( + struct UartDevice *device, const struct DeviceResourceNode *resourceNode) + { + struct UartResource *resource = &device->resource; + struct DeviceResourceIface *dri = NULL; + dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (dri == NULL || dri->GetUint32 == NULL) { + HDF_LOGE("DeviceResourceIface is invalid"); + return HDF_FAILURE; + } + + if (dri->GetUint32(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read num fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "base", &resource->base, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read base fail"); + return HDF_FAILURE; + } + resource->physBase = (unsigned long)OsalIoRemap(resource->base, 0x48); + if (resource->physBase == 0) { + HDF_LOGE("uart config fail to remap physBase"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "irqNum", &resource->irqNum, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read irqNum fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "baudrate", &resource->baudrate, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read baudrate fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "wlen", &resource->wlen, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read wlen fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "parity", &resource->parity, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read parity fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "stopBit", &resource->stopBit, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read stopBit fail"); + return HDF_FAILURE; + } + if (dri->GetUint32(resourceNode, "uartClk", &resource->uartClk, 0) != HDF_SUCCESS) { + HDF_LOGE("uart config read uartClk fail"); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + // 将UART驱动的配置和接口附加到HDF驱动框架 + static int32_t AttachUartDevice(struct UartHost *host, struct HdfDeviceObject *device) + { + int32_t ret; + struct UartDevice *uartDevice = NULL; + if (device->property == NULL) { + HDF_LOGE("%s: property is NULL", __func__); + return HDF_FAILURE; + } + uartDevice = (struct UartDevice *)OsalMemCalloc(sizeof(struct UartDevice)); + if (uartDevice == NULL) { + HDF_LOGE("%s: OsalMemCalloc uartDevice error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + ret = GetUartDeviceResource(uartDevice, device->property); + if (ret != HDF_SUCCESS) { + (void)OsalMemFree(uartDevice); + return HDF_FAILURE; + } + host->num = uartDevice->resource.num; + host->priv = uartDevice; + AddUartDevice(host); + return InitUartDevice(uartDevice); + } + + // 初始化UART驱动 + static int32_t SampleUartDriverInit(struct HdfDeviceObject *device) + { + int32_t ret; + struct UartHost *host = NULL; + + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_OBJECT; + } + HDF_LOGI("Enter %s:", __func__); + host = UartHostFromDevice(device); + if (host == NULL) { + HDF_LOGE("%s: host is NULL", __func__); + return HDF_FAILURE; + } + ret = AttachUartDevice(host, device); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: attach error", __func__); + return HDF_FAILURE; + } + host->method = &g_sampleUartHostMethod; + return ret; + } + + static void DeinitUartDevice(struct UartDevice *device) + { + struct UartRegisterMap *regMap = (struct UartRegisterMap *)device->resource.physBase; + /* wait for uart enter idle. */ + while (UartPl011IsBusy(regMap)); + UartPl011ResetRegisters(regMap); + uart_clk_cfg(0, false); + OsalIoUnmap((void *)device->resource.physBase); + device->state = UART_DEVICE_UNINITIALIZED; + } + + // 解绑并释放UART驱动 + static void DetachUartDevice(struct UartHost *host) + { + struct UartDevice *uartDevice = NULL; + + if (host->priv == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return; + } + uartDevice = host->priv; + DeinitUartDevice(uartDevice); + (void)OsalMemFree(uartDevice); + host->priv = NULL; + } + + // 释放UART驱动 + static void SampleUartDriverRelease(struct HdfDeviceObject *device) + { + struct UartHost *host = NULL; + HDF_LOGI("Enter %s:", __func__); + + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return; + } + host = UartHostFromDevice(device); + if (host == NULL) { + HDF_LOGE("%s: host is NULL", __func__); + return; + } + if (host->priv != NULL) { + DetachUartDevice(host); + } + UartHostDestroy(host); + } + + struct HdfDriverEntry g_sampleUartDriverEntry = { + .moduleVersion = 1, + .moduleName = "UART_SAMPLE", + .Bind = SampleUartDriverBind, + .Init = SampleUartDriverInit, + .Release = SampleUartDriverRelease, + }; + + HDF_INIT(g_sampleUartDriverEntry); + ``` + +3. 注册UART驱动接口。 + + HDF框架提供了UART驱动接口的模板方法UartHostMethod,实现UART驱动接口的代码如下: + + ``` + static int32_t SampleUartHostInit(struct UartHost *host) + { + HDF_LOGI("%s: Enter", __func__); + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + return HDF_SUCCESS; + } + + static int32_t SampleUartHostDeinit(struct UartHost *host) + { + HDF_LOGI("%s: Enter", __func__); + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + return HDF_SUCCESS; + } + + // 向UART中写入数据 + static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size) + { + HDF_LOGI("%s: Enter", __func__); + uint32_t idx; + struct UartRegisterMap *regMap = NULL; + struct UartDevice *device = NULL; + + if (host == NULL || data == NULL || size == 0) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + device = (struct UartDevice *)host->priv; + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_PARAM; + } + regMap = (struct UartRegisterMap *)device->resource.physBase; + for (idx = 0; idx < size; idx++) { + UartPl011Write(regMap, data[idx]); + } + return HDF_SUCCESS; + } + + // 设置UART的波特率 + static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate) + { + HDF_LOGI("%s: Enter", __func__); + struct UartDevice *device = NULL; + struct UartRegisterMap *regMap = NULL; + UartPl011Error err; + + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + device = (struct UartDevice *)host->priv; + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_PARAM; + } + regMap = (struct UartRegisterMap *)device->resource.physBase; + if (device->state != UART_DEVICE_INITIALIZED) { + return UART_PL011_ERR_NOT_INIT; + } + if (baudRate == 0) { + return UART_PL011_ERR_INVALID_BAUD; + } + err = UartPl011SetBaudrate(regMap, device->uartClk, baudRate); + if (err == UART_PL011_ERR_NONE) { + device->baudrate = baudRate; + } + return err; + } + + // 获取UART的波特率 + static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate) + { + HDF_LOGI("%s: Enter", __func__); + struct UartDevice *device = NULL; + + if (host == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + device = (struct UartDevice *)host->priv; + if (device == NULL) { + HDF_LOGE("%s: device is NULL", __func__); + return HDF_ERR_INVALID_PARAM; + } + *baudRate = device->baudrate; + return HDF_SUCCESS; + } + + // 在HdfUartSampleInit方法中绑定 + struct UartHostMethod g_sampleUartHostMethod = { + .Init = SampleUartHostInit, + .Deinit = SampleUartHostDeinit, + .Read = NULL, + .Write = SampleUartHostWrite, + .SetBaud = SampleUartHostSetBaud, + .GetBaud = SampleUartHostGetBaud, + .SetAttribute = NULL, + .GetAttribute = NULL, + .SetTransMode = NULL, + }; + ``` + + 在device/hisilicon/drivers/lite.mk编译脚本中增加示例UART驱动模块,代码如下: + + ``` + LITEOS_BASELIB += -lhdf_uart_sample + LIB_SUBDIRS += $(LITEOS_SOURCE_ROOT)/vendor/huawei/hdf/sample/platform/uart + ``` + +4. 用户程序和驱动交互代码。 + + UART驱动成功初始化后,会创建/dev/uartdev-5设备节点,通过设备节点与UART驱动交互的代码如下: + + ``` + #include + #include + #include + #include "hdf_log.h" + + #define HDF_LOG_TAG "hello_uart" + #define INFO_SIZE 16 + + int main(void) + { + int ret; + int fd; + const char info[INFO_SIZE] = {" HELLO UART! "}; + + fd = open("/dev/uartdev-5", O_RDWR); + if (fd < 0) { + HDF_LOGE("hello_uart uartdev-5 open failed %d", fd); + return -1; + } + ret = write(fd, info, INFO_SIZE); + if (ret != 0) { + HDF_LOGE("hello_uart write uartdev-5 ret is %d", ret); + } + ret = close(fd); + if (ret != 0) { + HDF_LOGE("hello_uart uartdev-5 close failed %d", fd); + return -1; + } + return ret; + } + ``` + + 在build/lite/components/drivers.json驱动配置中hdf\_hi3516dv300\_liteos\_a组件下的targets中增加hello\_uart\_sample组件,代码如下: + + ``` + { + "components": [ + { + "component": "hdf_hi3516dv300_liteos_a", + ... + "targets": [ + "//vendor/huawei/hdf/sample/platform/uart:hello_uart_sample" + ] + } + ] + } + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如上代码均为示例代码,完整代码可以在vendor/huawei/hdf/sample查看。 + >示例代码默认不参与编译,需要手动添加到编译脚本中。 + + +## 编译和烧写 + +参考《运行Hello OHOS》进行编译和烧写:[编译](quickstart-lite-steps-board3516-running.md#section1077671315253)、[烧录](quickstart-lite-steps-board3516-running.md#section1347011412201) + +## 镜像运行 + +1. 连接串口。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >若无法连接串口,请参考[常见问题](quickstart-lite-steps-board3516-faqs.md)进行排查。 + + **图 1** 连接串口图 + + + ![](figure/chuankou1.png) + + 1. 单击**Monitor**打开串口。 + 2. 连续输入回车直到串口显示"hisilicon"。 + 3. 单板初次启动或修改启动参数,请进入[步骤2](quickstart-lite-steps-board3516-running.md#l5b42e79a33ea4d35982b78a22913b0b1),否则进入[步骤3](quickstart-lite-steps-board3516-running.md#ld26f18828aa44c36bfa36be150e60e49)。 + +2. (单板初次启动必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,若不修改参数只需执行一次。每次复位单板均会自动进入系统。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >U-boot引导程序默认会有2秒的等待时间,用户可使用回车打断等待并显示"hisilicon",通过**reset**命令可再次启动系统。 + + **表 1** U-boot修改命令 + + + + + + + + + + + + + + + + + + + +

执行命令

+

命令解释

+

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

+

读取FLASH起始地址为0x800(单位为512B,即1MB),大小为0x4800(单位为512B,即9MB)的内容到0x80000000的内存地址,该大小(9MB)与IDE中所填写OHOS_Image.bin文件大小必须相同

+

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

+

表示设置启动参数,输出模式为串口输出,波特率为115200,数据位8,rootfs挂载于emmc器件,文件系统类型为vfat,

+

“rootaddr=10M rootsize=20M rw”处对应填入rootfs.img的烧写起始位置与长度,此处与IDE中新增rootfs.img文件时所填大小必须相同

+

saveenv

+

表示保存当前配置。

+

reset

+

表示复位单板。

+
+ + >![](../public_sys-resources/icon-notice.gif) **须知:** + >**“go 0x80000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。 + +3. 输入**“reset”**指令并回车,重启单板,启动成功如下图,输入回车串口显示OHOS字样。 + + **图 2** 系统启动图 + + + ![](figure/qi1.png) + +4. 根目录下,在命令行输入指令“**./bin/hello\_uart**”执行写入的demo程序,显示成功结果如下所示。 + + ``` + OHOS # ./bin/hello_uart + OHOS # HELLO UART! + ``` + + +## 下一步学习 + +恭喜,您已完成Hi3516 快速上手!建议您下一步进入[带屏摄像头产品开发](../guide/device-camera.md)的学习 。 + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-running.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-running.md new file mode 100644 index 0000000000000000000000000000000000000000..336d979c20d2b4413af4c0f562bcb3621e337e6e --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-running.md @@ -0,0 +1,269 @@ +# 运行Hello OHOS + +- [新建应用程序](#section204672145202) +- [编译](#section1077671315253) +- [烧录](#section1347011412201) +- [镜像运行](#section24721014162010) +- [执行应用程序](#section5276734182615) + +本节指导开发者在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello OHOS!”。 + +## 新建应用程序 + +1. 新建目录及源码 + + 新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。 + + ``` + #include + + int main(int argc, char **argv) + { + printf("\n************************************************\n"); + printf("\n\t\tHello OHOS!\n"); + printf("\n************************************************\n\n"); + + return 0; + } + ``` + +2. 新建编译组织文件 + + 新建**applications/sample/camera/apps/BUILD.gn**文件,内容如下所示: + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("hello-OHOS") { + features = [ ":helloworld" ] + } + executable("helloworld") { + output_name = "helloworld" + sources = [ "src/helloworld.c" ] + include_dirs = [] + defines = [] + cflags_c = [] + ldflags = [] + } + ``` + +3. 添加新组件 + + 修改文件**build/lite/components/applications.json**,添加组件hello\_world\_app的配置,如下所示为applications.json文件片段,"\#\#start\#\#"和"\#\#end\#\#"之间为新增配置("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): + + ``` + { + "components": [ + { + "component": "camera_sample_communication", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/communication" + ], + "targets": [ + "//applications/sample/camera/communication:sample" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##start## + { + "component": "hello_world_app", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/apps" + ], + "targets": [ + "//applications/sample/camera/apps:hello-OHOS" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##end## + { + "component": "camera_sample_app", + "description": "Camera related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/launcher", + "applications/sample/camera/cameraApp", + "applications/sample/camera/setting", + "applications/sample/camera/gallery", + "applications/sample/camera/media" + ], + ``` + +4. 修改单板配置文件 + + 修改文件**vendor/hisilicon/hispark\_taurus/config.json**,新增hello\_world\_app组件的条目,如下所示代码片段为applications子系统配置,"\#\#start\#\#"和"\#\#end\#\#"之间为新增条目("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): + + ``` + { + "subsystem": "applications", + "components": [ + { "component": "camera_sample_app", "features":[] }, + { "component": "camera_sample_ai", "features":[] }, + ##start## + { "component": "hello_world_app", "features":[] }, + ##end## + { "component": "camera_screensaver_app", "features":[] } + ] + }, + ``` + + +## 编译 + +如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/gettools-acquire.md)的编译操作。如果Linux编译环境通过软件包方式安装,请进入源码根目录,执行如下命令进行编译: + +``` +hb set(设置编译路径) +.(选择当前路径) +选择ipcamera_hispark_taurus@hisilicon并回车 +hb build -f(执行编译) +``` + +**图 1** 设置图例 +![](figure/设置图例.png "设置图例") + +结果文件生成在out/hispark\_taurus/ipcamera\_hispark\_taurus目录下。 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>Hi3516DV300单板的U-boot文件获取路径:device/hisilicon/hispark\_taurus/sdk\_liteos/uboot/out/boot/u-boot-hi3516dv300.bin + +## 烧录 + +Hi3516开发板的代码烧录支持USB烧录、网口烧录和串口烧录三种方式。此处仅以网口烧录为例进行说明。 + +1. 请连接好电脑和待烧录开发板,以Hi3516DV300为例,需要同时连接串口、网口和电源,具体可参考[Hi3516开发板介绍](quickstart-lite-introduction-hi3516.md)。 +2. 打开电脑的设备管理器,查看并记录对应的串口号。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 + + ![](figure/zh-cn_image_0000001174350647.png) + +3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 + + ![](figure/2021-01-27_170334.png) + +4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3516系列开发板进行适配,无需单独修改。 +5. 在“hi3516dv300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 + + - upload\_port:选择步骤[2](#zh-cn_topic_0000001056443961_li142386399535)中查询的串口号。 + - upload\_protocol:选择烧录协议,固定选择“hiburn-net”。 + - upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。 + + ![](figure/zh-cn_image_0000001128470904.png) + +6. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/ide/user-guides/set_ipaddress-0000001141825075)。 +7. 设置网口烧录的IP地址信息,设置如下选项: + + - upload\_net\_server\_ip:选择[6](#zh-cn_topic_0000001056443961_li1558813168234)中设置的IP地址信息。例如192.168.1.2 + - upload\_net\_client\_mask:设置开发板的子网掩码,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如255.255.255.0 + - upload\_net\_client\_gw:设置开发板的网关,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.1 + - upload\_net\_client\_ip:设置开发板的IP地址,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.3 + + ![](figure/zh-cn_image_0000001174270733.png) + +8. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 +9. 打开工程文件,点击![](figure/2021-01-27_170334-2.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3516dv300下的**Upload**按钮,启动烧录。 + + ![](figure/zh-cn_image_0000001174270729.png) + +10. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。 + + ![](figure/zh-cn_image_0000001128470906.png) + +11. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 + + ![](figure/zh-cn_image_0000001128311098.png) + + +## 镜像运行 + +1. 连接串口。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >若无法连接串口,请参考[常见问题](quickstart-lite-steps-board3516-faqs.md)进行排查。 + + **图 2** 连接串口图 + + + ![](figure/chuankou1.png) + + 1. 单击**Monitor**打开串口。 + 2. 连续输入回车直到串口显示"hisilicon"。 + 3. 单板初次启动或修改启动参数,请进入[步骤2](#l5b42e79a33ea4d35982b78a22913b0b1),否则进入[步骤3](#ld26f18828aa44c36bfa36be150e60e49)。 + +2. (单板初次启动必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,若不修改参数只需执行一次。每次复位单板均会自动进入系统。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >U-boot引导程序默认会有2秒的等待时间,用户可使用回车打断等待并显示"hisilicon",通过**reset**命令可再次启动系统。 + + **表 1** U-boot修改命令 + + + + + + + + + + + + + + + + + + + +

执行命令

+

命令解释

+

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

+

读取FLASH起始地址为0x800(单位为512B,即1MB),大小为0x4800(单位为512B,即9MB)的内容到0x80000000的内存地址,该大小(9MB)与IDE中所填写OHOS_Image.bin文件大小必须相同

+

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

+

表示设置启动参数,输出模式为串口输出,波特率为115200,数据位8,rootfs挂载于emmc器件,文件系统类型为vfat,

+

“rootaddr=10M rootsize=20M rw”处对应填入rootfs.img的烧写起始位置与长度,此处与IDE中新增rootfs.img文件时所填大小必须相同

+

saveenv

+

表示保存当前配置。

+

reset

+

表示复位单板。

+
+ + >![](../public_sys-resources/icon-notice.gif) **须知:** + >**“go 0x80000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。 + +3. 输入**“reset”**指令并回车,重启单板,启动成功如下图,输入回车串口显示OHOS字样。 + + **图 3** 系统启动图 + + + ![](figure/qi1.png) + + +## 执行应用程序 + +根目录下,在命令行输入指令“**./bin/helloworld**”执行写入的demo程序,显示成功结果如下图所示。 + +**图 4** 启动并成功执行应用程序图 +![](figure/启动并成功执行应用程序图.png "启动并成功执行应用程序图") + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-setting.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-setting.md new file mode 100644 index 0000000000000000000000000000000000000000..1b5e88ef8f4b11ec873afdb7c4c3116d5a6fbcb4 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516-setting.md @@ -0,0 +1,122 @@ +# 安装开发板环境 + +- [Hi3516工具要求](#section179175261196) + - [硬件要求](#section5840424125014) + - [软件要求](#section965634210501) + +- [安装Linux服务器工具](#section182916865219) + - [将Linux shell改为bash](#section1715027152617) + - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251) + - [安装文件打包工具及Java虚拟机环境](#section16199102083717) + + +## Hi3516工具要求 + +### 硬件要求 + +- Hi3516DV300 IoT Camera开发板 +- USB转串口线、网线(Windows工作台通过USB转串口线、网线与Hi3516DV300 开发板连接) + +各硬件连接关系如下图所示。 + +**图 1** 硬件连线图 + + +![](figure/矩形备份-292.png) + +### 软件要求 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section182916865219)章节。 + +Hi3516开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 + +**表 1** Linux服务器开发工具及获取途径 + + + + + + + + + + + + + + + + + + + + + + + + +

开发工具

+

用途

+

获取途径

+

bash

+

命令行处理工具

+

系统配置

+

编译基础软件包(仅ubuntu 20+需要)

+

编译依赖的基础软件包

+

通过互联网获取

+

dosfstools、mtools、mtd-utils

+

文件打包工具

+

通过apt-get install安装

+

Java 虚拟机环境

+

编译、调试和运行Java程序

+

通过apt-get install安装

+
+ +## 安装Linux服务器工具 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装LLVM、hc-gen编译工具。 +>- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。 + +### 将Linux shell改为bash + +查看shell是否为bash,在终端运行如下命令 + +``` +ls -l /bin/sh +``` + +如果显示为“/bin/sh -\> bash”则为正常,否则请按以下方式修改: + +**方法一**:在终端运行如下命令,然后选择 no。 + +``` +sudo dpkg-reconfigure dash +``` + +**方法二**:先删除sh,再创建软链接。 + +``` +sudo rm -rf /bin/sh +sudo ln -s /bin/bash /bin/sh +``` + +### 安装编译依赖基础软件(仅Ubuntu 20+需要) + +执行以下命令进行安装: + +``` +sudo apt-get install build-essential gcc g++ make zlib* libffi-dev +``` + +### 安装文件打包工具及Java虚拟机环境 + +1. 打开Linux编译服务器终端 +2. 运行如下命令,安装dosfstools,mtools,mtd-utils,Java运行时环境(JRE)和Java sdk 开发工具包。 + + ``` + sudo apt-get install dosfstools mtools mtd-utils default-jre default-jdk + ``` + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516.md new file mode 100644 index 0000000000000000000000000000000000000000..397255079763931a2d53c5f10f472a2afd7a350b --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3516.md @@ -0,0 +1,11 @@ +# Hi3516开发板 + +- **[安装开发板环境](quickstart-lite-steps-board3516-setting.md)** + +- **[运行Hello OHOS](quickstart-lite-steps-board3516-running.md)** + +- **[驱动开发示例](quickstart-lite-steps-board3516-program.md)** + +- **[常见问题](quickstart-lite-steps-board3516-faqs.md)** + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-faqs.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..dc71a35fb6a0e5fdac8d3f976d58066a474f2a97 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-faqs.md @@ -0,0 +1,174 @@ +# 常见问题 + +- [烧写选择串口后提示失败](#section1498892119619) +- [Windows电脑与单板网络连接失败](#section8512971816) +- [烧写失败](#section1767804111198) +- [编译构建过程中,提示找不到“python”](#zh-cn_topic_0000001053466255_section1039835245619) +- [串口无回显](#zh-cn_topic_0000001053466255_section14871149155911) + +## 烧写选择串口后提示失败 + +- **现象描述** + + 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied。 + + **图 1** 打开串口失败图 + ![](figure/打开串口失败图-7.png "打开串口失败图-7") + +- **可能原因** + + 串口已经被占用。 + +- **解决办法** + +1. 按图依次选择下拉框,查找带有serial-xx的终端 + + **图 2** 查找是否存在占用串口的终端 + ![](figure/查找是否存在占用串口的终端-8.png "查找是否存在占用串口的终端-8") + +2. 点击标号中的垃圾桶图标,关闭串口。 + + **图 3** 关闭串口终端 + ![](figure/关闭串口终端-9.png "关闭串口终端-9") + +3. 重新点击烧写,选择串口并开始烧写程序 + + **图 4** 重新启动烧写任务 + + + ![](figure/changjian1-10.png) + + +## Windows电脑与单板网络连接失败 + +- **现象描述** + + 点击烧写并选择串口后,无法获取文件。 + + **图 5** 网络不通,单板无法获取文件图 + ![](figure/网络不通-单板无法获取文件图-11.png "网络不通-单板无法获取文件图-11") + +- **可能原因** + + 单板网络与Windows电脑不联通。 + + Windows电脑防火墙未允许Visual Studio Code联网。 + +- **解决方法** + +1. 检查网线是否连接。 +2. 点击Windows防火墙。 + + **图 6** 网络防火墙设置图 + ![](figure/网络防火墙设置图-12.png "网络防火墙设置图-12") + +3. 点击“允许应用通过防火墙”。 + + **图 7** 防火墙和网络保护界面图 + ![](figure/防火墙和网络保护界面图-13.png "防火墙和网络保护界面图-13") + +4. 查找Visual Studio Code应用。 + + **图 8** 查找Visual Studio Code应用图 + ![](figure/查找Visual-Studio-Code应用图-14.png "查找Visual-Studio-Code应用图-14") + +5. 勾选Visual Studio Code的专用和公用网络的访问权限。 + + **图 9** 允许Visual Studio Code应用访问网络 + ![](figure/允许Visual-Studio-Code应用访问网络-15.png "允许Visual-Studio-Code应用访问网络-15") + + +## 烧写失败 + +- **现象描述** + + 点击烧写并选择串口后,出现无法烧写的情况。 + +- **可能原因** + + 安装IDE插件DevEco后未重启。 + +- **解决方法** + + 重启IDE。 + + +## 编译构建过程中,提示找不到“python” + +- **现象描述** + + ![](figure/zh-cn_image_0000001174270743.png) + + +- **可能原因1** + + 没有装python。 + +- **解决办法** + + 请按照[安装python](quickstart-lite-env-setup-lin.md)。 + +- **可能原因2** + + ![](figure/zh-cn_image_0000001174270739.png) + +- **解决办法** + + usr/bin目录下没有python软链接,请运行以下命令: + + ``` + # cd /usr/bin/ + # which python3 + # ln -s /usr/local/bin/python3 python + # python --version + ``` + + 例: + + ![](figure/zh-cn_image_0000001174350661.png) + + +## 串口无回显 + +- **现象描述** + + 串口显示已连接,重启单板后,回车无任何回显。 + +- **可能原因1** + + 串口连接错误。 + +- **解决办法** + + 修改串口号。 + + 请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行内[步骤1](quickstart-lite-steps-board3518-running.md)修改串口号。 + + +- **可能原因2** + + 单板U-boot被损坏。 + +- **解决办法** + + 烧写U-boot。 + + 若上述步骤依旧无法连接串口,可能由于单板U-boot损坏,按下述步骤烧写U-boot。 + + +1. 获取引导文件U-boot。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >单板的U-boot文件请在开源包中获取: + >Hi3516DV300:device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin + >Hi3518EV300:device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin + +2. 根据USB烧写步骤烧写U-boot文件。 + + 按照[Hi3516系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Hi3518系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3518_upload-0000001057313128)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。 + +3. 烧写完成后,登录串口如下图所示。 + + ![](figure/zh-cn_image_0000001174350659.png) + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-running.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-running.md new file mode 100644 index 0000000000000000000000000000000000000000..2b5a833cfc380fb2762fda0d333c8a20c8cb4239 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-running.md @@ -0,0 +1,262 @@ +# 运行Hello OHOS + +- [新建应用程序](#section1550972416485) +- [编译](#section234175193114) +- [烧录](#section7609155824819) +- [镜像运行](#section17612105814480) +- [下一步学习](#section9712145420182) + +本节指导开发者在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello OHOS!”。 + +## 新建应用程序 + +1. 新建目录及源码 + + 新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。 + + ``` + #include + + int main(int argc, char **argv) + { + printf("\n************************************************\n"); + printf("\n\t\tHello OHOS!\n"); + printf("\n************************************************\n\n"); + + return 0; + } + ``` + +2. 新建编译组织文件 + + 新建**applications/sample/camera/apps/BUILD.gn**文件,内容如下所示: + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("hello-OHOS") { + features = [ ":helloworld" ] + } + executable("helloworld") { + output_name = "helloworld" + sources = [ "src/helloworld.c" ] + include_dirs = [] + defines = [] + cflags_c = [] + ldflags = [] + } + ``` + +3. 添加新组件 + + 修改文件**build/lite/components/applications.json**,添加组件hello\_world\_app的配置,如下所示为applications.json文件片段,"\#\#start\#\#"和"\#\#end\#\#"之间为新增配置("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): + + ``` + { + "components": [ + { + "component": "camera_sample_communication", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/communication" + ], + "targets": [ + "//applications/sample/camera/communication:sample" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##start## + { + "component": "hello_world_app", + "description": "Communication related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/apps" + ], + "targets": [ + "//applications/sample/camera/apps:hello-OHOS" + ], + "rom": "", + "ram": "", + "output": [], + "adapted_kernel": [ "liteos_a" ], + "features": [], + "deps": { + "components": [], + "third_party": [] + } + }, + ##end## + { + "component": "camera_sample_app", + "description": "Camera related samples.", + "optional": "true", + "dirs": [ + "applications/sample/camera/launcher", + "applications/sample/camera/cameraApp", + "applications/sample/camera/setting", + "applications/sample/camera/gallery", + "applications/sample/camera/media" + ], + ``` + +4. 修改单板配置文件 + + 修改文件**vendor/hisilicon/hispark\_aries/config.json**,新增hello\_world\_app组件的条目,如下所示代码片段为applications子系统配置,"\#\#start\#\#"和"\#\#end\#\#"之间为新增条目("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): + + ``` + { + "subsystem": "applications", + "components": [ + ##start## + { "component": "hello_world_app", "features":[] }, + ##end## + { "component": "camera_sample_app", "features":[] } + + ] + }, + ``` + + +## 编译 + +如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/gettools-acquire.md)的编译操作。如果Linux编译环境通过软件包方式安装,进入源码根目录,执行如下命令进行编译: + +``` +hb set(设置编译路径) +.(选择当前路径) +选择ipcamera_hispark_aries@hisilicon并回车 +hb build -f(执行编译) +``` + +结果文件生成在out/hispark\_aries/ipcamera\_hispark\_aries目录下。 + +**图 1** 设置图例 +![](figure/设置图例-4.png "设置图例-4") + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>Hi3518EV300单板的U-boot文件获取路径:device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin + +## 烧录 + +Hi3518开发板的代码烧录仅支持USB烧录方式。 + +1. 请连接好电脑和待烧录开发板,以Hi3518EV300为例,需要同时连接串口和USB口,具体可参考[Hi3518开发板介绍](quickstart-lite-introduction-hi3518.md)。 +2. 打开电脑的设备管理器,查看并记录对应的串口号。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 + + ![](figure/zh-cn_image_0000001128470900.png) + +3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 + + ![](figure/zh-cn_image_0000001174350649.png) + +4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3518系列开发板进行适配,无需单独修改。 +5. 在“hi3518ev300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 + + - upload\_port:选择步骤[2](#zh-cn_topic_0000001057313128_li46411811196)中查询的串口号。 + - upload\_protocol:选择烧录协议,固定选择“hiburn-usb”。 + - upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。 + + ![](figure/zh-cn_image_0000001128311090.png) + +6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 +7. 打开工程文件,点击![](figure/2021-01-27_170334-5.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3518ev300\_fastboot下的**Erase**按钮,擦除U-Boot。 + + ![](figure/zh-cn_image_0000001174270731.png) + +8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(下电再上电)。 + + ![](figure/zh-cn_image_0000001128311092.png) + +9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。 + + ![](figure/zh-cn_image_0000001128311094.png) + +10. 擦除完成后,点击hi3518ev300下的**Upload**按钮,启动烧录。 + + ![](figure/zh-cn_image_0000001174350641.png) + +11. 启动烧录后,界面提示如下信息时,表示烧录成功。 + + ![](figure/zh-cn_image_0000001174350643.png) + + +## 镜像运行 + +1. 连接串口。 + + >![](../public_sys-resources/icon-notice.gif) **须知:** + >若无法连接串口,请参考[常见问题](quickstart-lite-steps-board3518-faqs.md)进行排查。 + + **图 2** 连接串口图 + + + ![](figure/chuankou1-6.png) + + 1. 单击**Monitor**打开串口。 + 2. 连续输入回车直到串口显示"hisilicon"。 + 3. 单板初次启动或修改启动参数,请进入[步骤2](#li9441185382314),否则进入[步骤3](#li6442853122312)。 + +2. (初次烧写必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,可保存执行结果,但U-boot重新烧入,则需要再次执行下述步骤。 + + **表 1** U-boot修改命令 + + + + + + + + + + + + + + + + + + + + + + +

执行命令

+

命令解释

+

setenv bootcmd "sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000";

+

设置bootcmd内容,选择FLASH器件0,读取FLASH起始地址为0x100000,大小为0x600000字节的内容到0x40000000的内存地址,此处0x600000为6MB,与IDE中填写OHOS_Image.bin的文件大小必须相同

+

setenv bootargs "console=ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7M rootsize=8M";

+

表示设置bootargs参数为串口输出,波特率为115200,数据位8,rootfs挂载于FLASH上,文件系统类型为jffs2 rw,以支持可读写JFFS2文件系统。“rootaddr=7M rootsize=8M”处对应填入实际rootfs.img的烧写起始位置与长度,与IDE内所填大小必须相同

+

saveenv

+

表示保存当前配置。

+

reset

+

表示复位单板。

+

pri

+

表示查看显示参数。

+
+ + >![](../public_sys-resources/icon-notice.gif) **须知:** + >**“go 0x40000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。 + +3. 若启动时显示**"hisilicon \#**字样,请输入**“reset”**指令,等待系统自启动进入系统,系统启动后,显示**“OHOS”**字样,输入**”./bin/helloworld”**并回车,显示成功结果如下图所示。 + + **图 3** 启动成功并执行应用程序图 + ![](figure/启动成功并执行应用程序图.png "启动成功并执行应用程序图") + + +## 下一步学习 + +恭喜您,已完成Hi3518的快速上手!建议您下一步进入[无屏摄像头产品开发](../guide/device-iotcamera.md)的学习 。 + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-setting.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-setting.md new file mode 100644 index 0000000000000000000000000000000000000000..b4a3556e11ce25bd050ca3d4be84ae5897f9142c --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518-setting.md @@ -0,0 +1,114 @@ +# 安装开发板环境 + +- [Hi3518环境搭建](#section1724111409282) + - [硬件要求](#section487353718276) + - [软件要求](#section17315193935817) + +- [安装Linux服务器工具](#section8831868501) + - [将Linux shell改为bash](#section434110241084) + - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section25911132141020) + - [安装文件打包工具](#section390214473129) + + +## Hi3518环境搭建 + +### 硬件要求 + +- Hi3518EV300 IoT Camera开发板 +- USB转串口线、网线(Windows工作台通过USB转串口线、网线与开发板连接) + + 各硬件连接关系如下图所示。 + + +**图 1** 硬件连线图 +![](figure/硬件连线图-3.png "硬件连线图-3") + +### 软件要求 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section8831868501)章节。 + +Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 + +**表 1** Linux服务器开发工具及获取途径 + + + + + + + + + + + + + + + + + + + + +

开发工具

+

用途

+

获取途径

+

bash

+

命令行处理工具

+

系统配置

+

编译基础软件包(仅ubuntu 20+需要)

+

编译依赖的基础软件包

+

通过互联网获取

+

dosfstools、mtools、mtd-utils

+

文件打包工具

+

通过apt-get install安装

+
+ +## 安装Linux服务器工具 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装hc-gen编译工具。 +>- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。 + +### 将Linux shell改为bash + +查看shell是否为bash,在终端运行如下命令 + +``` +ls -l /bin/sh +``` + +如果显示为“/bin/sh -\> bash”则为正常,否则请按以下方式修改: + +**方法一**:在终端运行如下命令,然后选择 no。 + +``` +sudo dpkg-reconfigure dash +``` + +**方法二**:先删除sh,再创建软链接。 + +``` +sudo rm -rf /bin/sh +sudo ln -s /bin/bash /bin/sh +``` + +### 安装编译依赖基础软件(仅Ubuntu 20+需要) + +执行以下命令进行安装: + +``` +sudo apt-get install build-essential gcc g++ make zlib* libffi-dev +``` + +### 安装文件打包工具 + +1. 打开Linux编译服务器终端。 +2. 运行如下命令,安装dosfstools,mtools,mtd-utils。 + + ``` + sudo apt-get install dosfstools mtools mtd-utils + ``` + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518.md new file mode 100644 index 0000000000000000000000000000000000000000..d0f3f9a5873ef8da0b02460a5f6b9acdaa2247a1 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3518.md @@ -0,0 +1,9 @@ +# Hi3518开发板 + +- **[安装开发板环境](quickstart-lite-steps-board3518-setting.md)** + +- **[运行Hello OHOS](quickstart-lite-steps-board3518-running.md)** + +- **[常见问题](quickstart-lite-steps-board3518-faqs.md)** + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-connection.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-connection.md new file mode 100644 index 0000000000000000000000000000000000000000..fe69412c06e34eae1058d50523d5dd37c2956063 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-connection.md @@ -0,0 +1,142 @@ +# WLAN联网 + +- [源码编译](#section191121332125319) +- [镜像烧录](#section19458165166) +- [WLAN模组联网](#section194671619167) + +本示例将演示如何通过AT命令完成WLAN模组与网关联网。 + +## 源码编译 + +本节描述如何在Linux服务器上进行WLAN模组版本的编译。 + +如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/sourcecode-acquire.md)的编译操作。如果Linux编译环境通过软件包方式安装,请参考如下步骤。 + +1. 打开DevEco Device Tool工具,点击“View \> Terminal”,进入终端界面。 + + **图 1** IDE终端工具打开方法 + + + ![](figure/1.png) + + 在终端界面使用ssh命令连接linux服务器,如“ssh user@ipaddr”。 + + **图 2** 终端界面示意图 + + + ![](figure/2.png) + +2. 进入代码根路径,并在终端窗口,执行脚本命令“hb set”、“.”,选择需要编译的版本“wifiiot\_hispark\_pegasus”。 + + **图 3** 在终端界面选择目标构建版本示意图 + + + ![](figure/3.png) + +3. 执行“hb build”启动版本构建。 + + **图 4** 在终端界面执行编译命令示意图 + + + ![](figure/4.png) + +4. 编译结束后,如果出现“wifiiot\_hispark\_pegasus build success”字样,则证明构建成功,如下图所示。 + + **图 5** 编译成功示意图 + + + ![](figure/5.png) + +5. 构建成功后,会在./out/wifiiot/路径中生成以下文件,使用如下命令可以查看,至此编译构建流程结束。 + + ``` + ls -l out/hispark_pegasus/wifiiot_hispark_pegasus/ + ``` + + **图 6** 编译文件存放目录示意图 + + + ![](figure/3-0.png) + + +## 镜像烧录 + +Hi3861 WLAN模组的镜像烧录可以通过OpenHarmony IDE工具DevEco完成,工具的基本使用请参考[DevEco Device Tool使用指南](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),烧录过程包含如下步骤。 + +1. 请连接好电脑和待烧录开发板,需要连接USB口,具体可参考[Hi3861开发板介绍](quickstart-lite-introduction-hi3861.md)。 +2. 打开电脑的设备管理器,查看并记录对应的串口号。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如果对应的串口异常,请根据[Hi3861系列开发板串口驱动安装](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3861-drivers-0000001058153433)安装USB转串口的驱动程序。 + + ![](figure/zh-cn_image_0000001128311118.png) + +3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 + + ![](figure/zh-cn_image_0000001128311116.png) + +4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3861系列开发板进行适配,无需单独修改。 +5. 在“hi3861”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 + + - upload\_port:选择步骤[2](#zh-cn_topic_0000001056563976_li848662117291)中查询的串口号。 + - upload\_protocol:选择烧录协议,固定选择“burn-serial”。 + - upload\_partitions:选择待烧录的文件,默认选择hi3861\_app。 + + ![](figure/zh-cn_image_0000001128470922.png) + +6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 +7. 打开工程文件,在DevEco Device Tool界面的“PROJECT TASKS”中,点击hi3861下的**Upload**按钮,启动烧录。 + + ![](figure/zh-cn_image_0000001174270749.png) + +8. 启动烧录后,显示如下提示信息时,请按开发板上的RST按钮重启开发板。 + + ![](figure/zh-cn_image_0000001174270751.png) + +9. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 + + ![](figure/zh-cn_image_0000001174350669.png) + + +## WLAN模组联网 + +完成版本构建及烧录后,下面开始介绍如何在串口终端上执行AT命令,使WLAN模组联网。 + +1. 保持Windows工作台和WLAN模组的连接状态,在DevEco工具最下方,点击“DevEco:Serial Monitor”按钮。 + + **图 7** 打开DevEco串口终端示意图 + + + ![](figure/5-1.png) + +2. 复位WLAN模组,终端界面显示“ready to OS start”,则启动成功。 + + **图 8** WLAN复位成功示意图 + + + ![](figure/6.png) + +3. 在DevEco的串口终端中,依次执行如下AT命令,启动STA模式,连接指定AP热点,并开启DHCP功能。 + + ``` + AT+STARTSTA # 启动STA模式 + AT+SCAN # 扫描周边AP + AT+SCANRESULT # 显示扫描结果 + AT+CONN="SSID",,2,"PASSWORD" # 连接指定AP,其中SSID/PASSWORD为待连接的热点名称和密码 + AT+STASTAT # 查看连接结果 + AT+DHCP=wlan0,1 # 通过DHCP向AP请求wlan0的IP地址 + ``` + +4. 查看WLAN模组与网关联通是否正常,如下图所示。 + + ``` + AT+IFCFG # 查看模组接口IP + AT+PING=X.X.X.X # 检查模组与网关的联通性,其中X.X.X.X需替换为实际的网关地址 + ``` + + **图 9** WLAN模组联网成功示意图 + + + ![](figure/截图.png) + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-faqs.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..b0dbbae1b366bc12e6e97c8d365476b2168a5217 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-faqs.md @@ -0,0 +1,292 @@ +# 常见问题 + +- [安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”](#section1221016541119) +- [安装python3过程中,提示“-bash: make: command not found”](#section1913477181213) +- [安装python3过程中,提示“zlib not available”](#section108211415131210) +- [安装python3过程中,提示“No module named '\_ctypes'”](#section2062268124) +- [编译构建过程中,提示“No module named 'Crypto'”](#section982315398121) +- [编译构建过程中,提示“No module named 'ecdsa'”](#section102035451216) +- [编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0”](#section4498158162320) +- [编译构建过程中,提示找不到“-lgcc”](#section11181036112615) +- [编译构建过程中,提示找不到“python”](#section1571810194619) +- [安装 kconfiglib时,遇到lsb\_release错误](#section691681635814) + +## 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH” + +- **现象描述** + + 安装python3过程中出现以下错误: + + ``` + configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details + ``` + +- **可能原因** + + 环境中未安装“gcc”。 + +- **解决办法** + + 1、通过命令“apt-get install gcc”在线安装。 + + 2、完成后,重新安装python3。 + + +## 安装python3过程中,提示“-bash: make: command not found” + +- **现象描述** + + 安装python3过程中出现以下错误: + + ``` + -bash: make: command not found + ``` + +- **可能原因** + + 环境中未安装“make”。 + +- **解决办法** + + 1、通过命令“apt-get install make”在线安装。 + + 2、完成后,重新安装python3。 + + +## 安装python3过程中,提示“zlib not available” + +- **现象描述** + + 安装python3过程中出现以下错误: + + ``` + zipimport.ZipImportError: can't decompress data; zlib not avaliable + ``` + +- **可能原因** + + 环境中未安装“zlib”。 + +- **解决办法** + + 方法1:通过命令“apt-get install zlib”在线安装。 + + 方法2:如果软件源中没有该软件,请从“www.zlib.net”下载版本代码,并离线安装。 + + ![](figure/10.png) + + 完成下载后,通过以下命令安装: + + ``` + # tar xvf zlib-1.2.11.tar.gz + # cd zlib-1.2.11 + # ./configure + # make && make install + ``` + + 完成后,重新安装python3。 + + +## 安装python3过程中,提示“No module named '\_ctypes'” + +- **现象描述** + + 安装python3过程中出现以下错误: + + ``` + ModuleNotFoundError:No module named ‘_ctypes’ + ``` + + +- **可能原因** + + 环境中未安装“libffi”和“libffi-devel”。 + + +- **解决办法** + + 1、通过命令“apt-get install libffi\* -y”,在线安装。 + + 2、完成后,重新安装python3。 + + +## 编译构建过程中,提示“No module named 'Crypto'” + +- **现象描述** + + 编译构建过程中出现以下错误: + + ``` + ModuleNotFoundError: No module named 'Crypto' + ``` + + +- **可能原因** + + 环境中未安装“Crypto”。 + + +- **解决办法** + + 方法1:通过命令“pip3 install Crypto”,在线安装。 + + 方法2:离线安装 + + 通过网页[https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files),下载源码。 + + ![](figure/zh-cn_image_0000001128470864.png) + + 将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”。 + + 完成上述安装后,重新构建。 + + +## 编译构建过程中,提示“No module named 'ecdsa'” + +- **现象描述** + + 编译构建过程中出现以下错误: + + ``` + ModuleNotFoundError:No module named 'ecdsa' + ``` + + +- **可能原因** + + 环境中未安装“ecdsa”。 + + +- **解决办法** + + 方法1:通过命令“pip3 install ecdsa”,在线安装。 + + 方法2:离线安装 + + 通过网页[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files),下载安装包。 + + ![](figure/zh-cn_image_0000001128311072.png) + + 将安装包放置Linux服务器中,并安装“pip3 install ecdsa-0.15-py2.py3-none-any.whl”。 + + 完成上述安装后,重新构建。 + + +## 编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0” + +- **现象描述** + + 编译构建过程中出现以下错误: + + ``` + Could not find a version that satisfies the requirement six>=1.9.0 + ``` + + +- **可能原因** + + 环境中未安装合适的“six”。 + + +- **解决办法** + + 方法1:通过命令“pip3 install six”,在线安装。 + + 方法2:离线安装 + + 通过网页[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files),下载安装包。 + + ![](figure/zh-cn_image_0000001174270699.png) + + 将源码放置在Linux服务器中,并安装“pip3 install six-1.14.0-py2.py3-none-any.whl”。 + + 完成上述安装后,重新构建。 + + +## 编译构建过程中,提示找不到“-lgcc” + +- **现象描述** + + 编译构建过程中出现以下错误: + + ``` + riscv32-unknown-elf-ld: cannot find -lgcc + ``` + + +- **可能原因** + + 交叉编译器gcc\_riscv32的PATH添加错误,如下,在"bin"后多添加了一个“/”,应该删除。 + + ``` + ~/gcc_riscv32/bin/:/data/toolchain/ + ``` + + +- **解决办法** + + 重新修改gcc\_riscv32的PATH,将多余的“/”删除。 + + ``` + ~/gcc_riscv32/bin:/data/toolchain/ + ``` + + +## 编译构建过程中,提示找不到“python” + +- **现象描述** + + 编译构建过程中出现以下错误: + + ``` + -bash: /usr/bin/python: No such file or directory + ``` + + +- **可能原因**1 + + 没有装python。 + +- **解决办法** + + 请按照 [安装Python环境](quickstart-lite-env-setup-lin.md) + +- **可能原因2** + + ![](figure/zh-cn_image_0000001128311070.png) + +- **解决办法** + + usr/bin目录下没有python软链接,请运行以下命令添加软链接: + + ``` + # cd /usr/bin/ + # which python3 + # ln -s /usr/local/bin/python3 python + # python --version + ``` + + 例: + + ![](figure/zh-cn_image_0000001174350623.png) + + +## 安装 kconfiglib时,遇到lsb\_release错误 + +- **现象描述** + + 安装kconfiglib过程中遇到如下错误打印: + + ``` + subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1. + ``` + +- **可能原因** + + lsb\_release模块基于的python版本与现有python版本不一致 + +- **解决办法** + + 执行"find / -name lsb\_release",找到lsb\_release位置并删除,如:"sudo rm -rf /usr/bin/lsb\_release" + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-running.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-running.md new file mode 100644 index 0000000000000000000000000000000000000000..547aa5affc7e6d2081e39bc482a1d2168043840d --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-running.md @@ -0,0 +1,158 @@ +# 运行Hello World + +- [修改源码](#section79601457101015) +- [调测验证](#section1621064881419) +- [printf打印](#section1246911301217) +- [根据asm文件进行问题定位](#section199621957141014) +- [运行结果](#section18115713118) +- [下一步学习](#section9712145420182) + +本示例将演示如何编写简单业务,输出“Hello World”,初步了解OpenHarmony 如何运行在开发板上。 + +## 修改源码 + +bugfix和新增业务两种情况,涉及源码修改。下面以新增业务(my\_first\_app)为例,向开发者介绍如何进行源码修改。 + +1. 确定目录结构。 + + 开发者编写业务时,务必先在./applications/sample/wifi-iot/app路径下新建一个目录(或一套目录结构),用于存放业务源码文件。 + + 例如:在app下新增业务my\_first\_app,其中hello\_world.c为业务代码,BUILD.gn为编译脚本,具体规划目录结构如下: + + ``` + . + └── applications + └── sample + └── wifi-iot + └── app + │── my_first_app + │ │── hello_world.c + │ └── BUILD.gn + └── BUILD.gn + ``` + +2. 编写业务代码。 + + 新建./applications/sample/wifi-iot/app/my\_first\_app下的hello\_world.c文件,在hello\_world.c中新建业务入口函数HelloWorld,并实现业务逻辑。并在代码最下方,使用OpenHarmony启动恢复模块接口SYS\_RUN\(\)启动业务。(SYS\_RUN定义在ohos\_init.h文件中) + + ``` + #include + #include "ohos_init.h" + #include "ohos_types.h" + + void HelloWorld(void) + { + printf("[DEMO] Hello world.\n"); + } + SYS_RUN(HelloWorld); + ``` + +3. 编写用于将业务构建成静态库的BUILD.gn文件。 + + 新建./applications/sample/wifi-iot/app/my\_first\_app下的BUILD.gn文件,并完成如下配置。 + + 如[步骤1](#li5479332115116)所述,BUILD.gn文件由三部分内容(目标、源文件、头文件路径)构成,需由开发者完成填写。 + + ``` + static_library("myapp") { + sources = [ + "hello_world.c" + ] + include_dirs = [ + "//utils/native/lite/include" + ] + } + ``` + + - static\_library中指定业务模块的编译结果,为静态库文件libmyapp.a,开发者根据实际情况完成填写。 + - sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。 + - include\_dirs中指定source所需要依赖的.h文件路径。 + +4. 编写模块BUILD.gn文件,指定需参与构建的特性模块。 + + 配置./applications/sample/wifi-iot/app/BUILD.gn文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,以my\_first\_app举例,features字段配置如下。 + + ``` + import("//build/lite/config/component/lite_component.gni") + + lite_component("app") { + features = [ + "my_first_app:myapp", + ] + } + ``` + + - my\_first\_app是相对路径,指向./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn。 + - myapp是目标,指向./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn中的static\_library\("myapp"\)。 + + +## 调测验证 + +目前调试验证的方法有两种,分别为通过printf打印日志、通过asm文件定位panic问题,开发者可以根据具体业务情况选择。 + +由于本示例业务简单,采用printf打印日志的调试方式即可。下面开始介绍这两种调试手段的使用方法。 + +## printf打印 + +代码中增加printf维测,信息会直接打印到串口上。开发者可在业务关键路径或业务异常位置增加日志打印,如下所示。 + +``` +void HelloWorld(void) +{ + printf("[DEMO] Hello world.\n"); +} +``` + +## 根据asm文件进行问题定位 + +系统异常退出时,会在串口上打印异常退出原因调用栈信息,如下文所示。通过解析异常栈信息可以定位异常位置。 + +``` +=======KERNEL PANIC======= +**********************Call Stack********************* +Call Stack 0 -- 4860d8 addr:f784c +Call Stack 1 -- 47b2b2 addr:f788c +Call Stack 2 -- 3e562c addr:f789c +Call Stack 3 -- 4101de addr:f78ac +Call Stack 4 -- 3e5f32 addr:f78cc +Call Stack 5 -- 3f78c0 addr:f78ec +Call Stack 6 -- 3f5e24 addr:f78fc +********************Call Stack end******************* +``` + +为解析上述调用栈信息,需要使用到Hi3861\_wifiiot\_app.asm文件,该文件记录了代码中函数在Flash上的符号地址以及反汇编信息。asm文件会随版本大包一同构建输出,存放在./out/wifiiot/路径下。 + +1. 将调用栈CallStack信息保存到txt文档中,以便于编辑。(可选) +2. 打开asm文件,并搜索CallStack中的地址,列出对应的函数名 信息。通常只需找出前几个栈信息对应的函数,就可明确异常代码方向。 + + ``` + Call Stack 0 -- 4860d8 addr:f784c -- WadRecvCB + Call Stack 1 -- 47b2b2 addr:f788c -- wal_sdp_process_rx_data + Call Stack 2 -- 3e562c addr:f789c + Call Stack 3 -- 4101de addr:f78ac + Call Stack 4 -- 3e5f32 addr:f78cc + Call Stack 5 -- 3f78c0 addr:f78ec + Call Stack 6 -- 3f5e24 addr:f78fc + ``` + +3. 根据以上调用栈信息,可以定位WadRecvCB函数中出现了异常。 + + ![](figure/zh-cn_image_0000001174270737.png) + +4. 完成代码排查及修改。 + +## 运行结果 + +示例代码编译、烧录、运行、调测后,在串口界面会显示如下结果: + +``` +ready to OS start +FileSystem mount ok. +wifi init success! +[DEMO] Hello world. +``` + +## 下一步学习 + +恭喜,您已完成Hi3861 WLAN模组快速上手!建议您下一步进入[WLAN产品开发](../guide/device-wifi.md)的学习 。 + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-setting.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-setting.md new file mode 100644 index 0000000000000000000000000000000000000000..90998c5acf0e5b6ee722fdcb6030a34e8a83b5fb --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861-setting.md @@ -0,0 +1,367 @@ +# 安装开发板环境 + +- [Hi3861工具要求](#section466851916410) + - [硬件要求](#section19202111020215) + - [软件要求](#section727451210318) + +- [安装Linux编译工具](#section497484245614) + - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251) + - [安装Scons](#section7438245172514) + - [安装python模块](#section88701892341) + - [安装gcc\_riscv32(WLAN模组类编译工具链)](#section34435451256) + +- [安装USB转串口驱动](#section1027732411513) + +## Hi3861工具要求 + +### 硬件要求 + +- Linux服务器 +- Windows工作台(主机电脑) +- Hi3861 WLAN模组 +- USB Type-C线(Windows工作台通过USB与Hi3861 WLAN模组连接) + +各硬件连接关系如下图所示。 + +**图 1** 硬件连线图 +![](figure/硬件连线图.png "硬件连线图") + +### 软件要求 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>本节描述采用安装包方式安装相关工具的操作步骤。如果是Docker方式安装,无需安装[表1](#table6299192712513)中的Linux服务器相关工具,只需安装Windows工作台工具即可。 + +Hi3861开发板需要的工具如下表所示。 + +**表 1** Hi3861开发板需要的工具 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

平台类型

+

开发工具

+

用途

+

获取途径

+

Linux服务器

+

编译基础软件包(仅ubuntu 20+需要)

+

编译依赖的基础软件包

+

通过互联网获取

+

Linux服务器

+

SCons3.0.4+

+

编译构建工具

+

通过互联网获取

+

Linux服务器

+

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

+

编译构建工具

+

通过互联网获取

+

Linux服务器

+

gcc riscv32

+

编译构建工具

+

通过互联网获取

+

Windows工作台

+

CH341SER.EXE

+

USB转串口驱动

+

http://www.wch.cn/search?q=ch340g&t=downloads

+
+ +## 安装Linux编译工具 + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装gcc\_riscv32编译工具。 +>- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装gcc\_riscv32编译工具。安装gcc\_riscv32编译工具时,请确保编译工具的环境变量路径唯一。 + +### 安装编译依赖基础软件(仅Ubuntu 20+需要) + +执行以下命令进行安装: + +``` +sudo apt-get install build-essential gcc g++ make zlib* libffi-dev +``` + +### 安装Scons + +1. 打开Linux编译服务器终端。 +2. 运行如下命令,安装SCons安装包。 + + ``` + python3 -m pip install scons + ``` + +3. 运行如下命令,查看是否安装成功。如果安装成功,查询结果下图所示。 + + ``` + scons -v + ``` + + **图 2** SCons安装成功界面,版本要求3.0.4以上 + ![](figure/SCons安装成功界面-版本要求3-0-4以上.png "SCons安装成功界面-版本要求3-0-4以上") + + +### 安装python模块 + +1. 运行如下命令,安装python模块setuptools。 + + ``` + pip3 install setuptools + ``` + +2. 安装GUI menuconfig工具(Kconfiglib),建议安装Kconfiglib 13.2.0+版本,任选如下一种方式。 + - **命令行方式:** + + ``` + sudo pip3 install kconfiglib + ``` + + + - **安装包方式:** + 1. 下载.whl文件(例如:kconfiglib-13.2.0-py2.py3-none-any.whl)。 + + 下载路径:“[https://pypi.org/project/kconfiglib\#files](https://pypi.org/project/kconfiglib#files)” + + + 1. 运行如下命令,安装.whl文件。 + + ``` + sudo pip3 install kconfiglib-13.2.0-py2.py3-none-any.whl + ``` + + + +3. 安装pycryptodome,任选如下一种方式。 + + 安装升级文件签名依赖的Python组件包,包括:pycryptodome、six、ecdsa。安装ecdsa依赖six,请先安装six,再安装ecdsa。 + + - **命令行方式:** + + ``` + sudo pip3 install pycryptodome + ``` + + - **安装包方式:** + 1. 下载.whl文件(例如:pycryptodome-3.9.9-cp38-cp38-manylinux1\_x86\_64.whl)。 + + 下载路径:“[https://pypi.org/project/pycryptodome/\#files](https://pypi.org/project/pycryptodome/#files)”。 + + + 1. 运行如下命令,安装.whl文件。 + + ``` + sudo pip3 install pycryptodome-3.9.9-cp38-cp38-manylinux1_x86_64.whl + ``` + + + +4. 安装six,任选如下一种方式。 + - **命令行方式:** + + ``` + sudo pip3 install six --upgrade --ignore-installed six + ``` + + + - **安装包方式:** + 1. 下载.whl文件(例如:six-1.12.0-py2.py3-none-any.whl)。 + + 下载路径:“[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files)” + + + 1. 运行如下命令,安装.whl文件。 + + ``` + sudo pip3 install six-1.12.0-py2.py3-none-any.whl + ``` + + + +5. 安装ecdsa,任选如下一种方式。 + - **命令行方式:** + + ``` + sudo pip3 install ecdsa + ``` + + - **安装包方式:** + 1. 下载.whl文件(例如:ecdsa-0.14.1-py2.py3-none-any.whl)。 + + 下载路径:“[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files)” + + + 1. 运行如下命令,安装.whl文件。 + + ``` + sudo pip3 install ecdsa-0.14.1-py2.py3-none-any.whl + ``` + + + + +### 安装gcc\_riscv32(WLAN模组类编译工具链) + +>![](../public_sys-resources/icon-notice.gif) **须知:** +>- Hi3861平台仅支持使用libgcc运行时库的静态链接,不建议开发者使用libgcc运行时库的动态链接,会导致商业分发时被GPL V3污染。 +>- 通过下述步骤2-15,我们编译好了gcc\_riscv32 镜像,提供给开发者[直接下载](https://repo.huaweicloud.com/harmonyos/compiler/gcc_riscv32/7.3.0/linux/gcc_riscv32-linux-7.3.0.tar.gz)使用。直接下载 gcc\_riscv32 镜像的开发者可省略下述2-15步。 + +1. 打开Linux编译服务器终端。 +2. 环境准备,请安装"gcc, g++, bison, flex, makeinfo"软件,确保工具链能正确编译。 + + ``` + sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install flex bison && sudo apt-get install texinfo + ``` + +3. 下载riscv-gnu-toolchain交叉编译工具链。 + + ``` + git clone --recursive https://gitee.com/mirrors/riscv-gnu-toolchain.git + ``` + +4. 打开文件夹riscv-gnu-toolchain,先删除空文件夹,以防止下载newlib,binutils,gcc时冲突。 + + ``` + cd riscv-gnu-toolchain && rm -rf riscv-newlib && rm -rf riscv-binutils && rm -rf riscv-gcc + ``` + +5. 下载riscv-newlib-3.0.0。 + + ``` + git clone -b riscv-newlib-3.0.0 https://github.com/riscv/riscv-newlib.git + ``` + +6. 下载riscv-binutils-2.31.1。 + + ``` + git clone -b riscv-binutils-2.31.1 https://github.com/riscv/riscv-binutils-gdb.git + ``` + +7. 下载riscv-gcc-7.3.0。 + + ``` + git clone -b riscv-gcc-7.3.0 https://github.com/riscv/riscv-gcc + ``` + +8. 添加riscv-gcc-7.3.0补丁。 + + 访问gcc官方补丁链接[89411](https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=026216a753ef0a757a9e368a59fa667ea422cf09;hp=2a23a1c39fb33df0277abd4486a3da64ae5e62c2),[86724](https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff;f=gcc/graphite.h;h=be0a22b38942850d88feb159603bb846a8607539;hp=4e0e58c60ab83f1b8acf576e83330466775fac17;hb=b1761565882ed6a171136c2c89e597bc4dd5b6bf;hpb=fbd5f023a03f9f60c6ae36133703af5a711842a3),按照补丁链接中要求的修改,手动将变更添加到对应的.c和.h文件中,注意由于patch版本与下载的gcc版本有所偏差,行数有可能对应不上,请自行查找patch中的关键字定位到对应行。 + +9. 下载[GMP 6.1.2](https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2),并解压安装。 + + ``` + tar -xvf gmp-6.1.2.tar.bz2 && mkdir build_gmp && cd build_gmp && ../gmp-6.1.2/configure --prefix=/usr/local/gmp-6.1.2 --disable-shared --enable-cxx && make && make install + ``` + +10. 下载[mpfr-4.0.2 ](https://www.mpfr.org/mpfr-4.0.2/mpfr-4.0.2.tar.gz),并解压安装。 + + ``` + tar -xvf mpfr-4.0.2.tar.gz && mkdir build_mpfr && cd build_mpfr && ../mpfr-4.0.2/configure --prefix=/usr/local/mpfr-4.0.2 --with-gmp=/usr/local/gmp-6.1.2 --disable-shared && make && make install + ``` + +11. 下载[mpc-1.1.0](https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz) ,并解压安装。 + + ``` + tar -xvf mpc-1.1.0.tar.gz && mkdir build_mpc && cd build_mpc && ../mpc-1.1.0/configure --prefix=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 --disable-shared && make && make install + ``` + +12. 打开文件夹riscv-gnu-toolchain,新建工具链输出目录。 + + ``` + cd /opt && mkdir gcc_riscv32 + ``` + +13. 编译binutils。 + + ``` + mkdir build_binutils && cd build_binutils && ../riscv-binutils-gdb/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32/riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. + ``` + +14. 编译newlib。 + + ``` + mkdir build_newlib && cd build_newlib && ../riscv-newlib/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" \CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. + ``` + +15. 编译gcc。 + + ``` + mkdir build_gcc && cd build_gcc && ../riscv-gcc/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" LDFLAGS="-Wl,-z,relro,-z,now,-z,noexecstack" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --with-headers="/opt/gcc-riscv32/riscv32-unknown-elf/include" --with-mpc=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 && make -j16 && make install + ``` + +16. 设置环境变量。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如果直接采用编译好的riscv32 gcc包,请参照如下步骤设置环境变量: + >1. 将压缩包解压到根目录 + > ``` + > tar -xvf gcc_riscv32-linux-7.3.0.tar.gz -C ~ + > ``` + >2. 设置环境变量。 + > ``` + > vim ~/.bashrc + > ``` + >3. 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 + > ``` + > export PATH=~/gcc_riscv32/bin:$PATH + > ``` + + ``` + vim ~/.bashrc + ``` + + 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 + + ``` + export PATH=~/gcc_riscv32/bin:$PATH + ``` + +17. 生效环境变量。 + + ``` + source ~/.bashrc + ``` + +18. Shell命令行中输入如下命令,如果能正确显示编译器版本号,表明编译器安装成功。 + + ``` + riscv32-unknown-elf-gcc -v + ``` + + +## 安装USB转串口驱动 + +相关步骤在Windows工作台操作。 + +1. 点击链接[下载CH341SER USB转串口](http://www.hihope.org/download/download.aspx?mtt=8)驱动程序。 +2. 点击安装包,安装驱动程序。 +3. 驱动安装完成后,重新插拔USB接口,串口信息显示如下图所示。 + + ![](figure/zh-cn_image_0000001174350633.png) + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861.md new file mode 100644 index 0000000000000000000000000000000000000000..8aca8589071142415783b378a6f932e3213722fa --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-board3861.md @@ -0,0 +1,11 @@ +# Hi3861开发板 + +- **[安装开发板环境](quickstart-lite-steps-board3861-setting.md)** + +- **[WLAN联网](quickstart-lite-steps-board3861-connection.md)** + +- **[运行Hello World](quickstart-lite-steps-board3861-running.md)** + +- **[常见问题](quickstart-lite-steps-board3861-faqs.md)** + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps.md new file mode 100644 index 0000000000000000000000000000000000000000..49545483c62cc3790af97196c58f3e29ce9c00b5 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps.md @@ -0,0 +1,9 @@ +# 开发步骤 + +- **[Hi3861开发板](quickstart-lite-steps-board3861.md)** + +- **[Hi3516开发板](quickstart-lite-steps-board3516.md)** + +- **[Hi3518开发板](quickstart-lite-steps-board3518.md)** + + diff --git a/zh-cn/device-dev/quick-start/quickstart-lite.md b/zh-cn/device-dev/quick-start/quickstart-lite.md new file mode 100644 index 0000000000000000000000000000000000000000..47a4ec111d5d343ef0f1abe4321730c8a201249a --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-lite.md @@ -0,0 +1,11 @@ +# 轻量和小型系统入门 + +- **[概述](quickstart-lite-overview.md)** + +- **[了解开发板](quickstart-lite-introduction.md)** + +- **[搭建系统环境](quickstart-lite-env-setup.md)** + +- **[开发步骤](quickstart-lite-steps.md)** + + diff --git a/zh-cn/device-dev/quick-start/quickstart-standard-burn.md b/zh-cn/device-dev/quick-start/quickstart-standard-burn.md new file mode 100644 index 0000000000000000000000000000000000000000..be86e001d66decb04ed2382d2b8158351437b267 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-standard-burn.md @@ -0,0 +1,201 @@ +# 镜像烧录 + +- [下一步](#section5600113114323) + +标准系统烧录,在V2.2 Beta1及以上版本支持。 + +Hi3516DV300支持烧录标准系统,其烧录方式包括网口烧录和串口烧录三种方式,其中: + +- **Windows系统:支持网口烧录和串口烧录** +- **Linux系统:支持串口烧录和网口烧录。** + +同一种烧录方式(如网口烧录),在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>当前Hi3516DV300开发板支持通过网口、USB、串口三种方式烧录OpenHarmony标准系统。本文以网口方式为例讲解烧录操作,其他两种烧录方式请参照[Hi3516DV300烧录指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)。 + +### 前提条件 + +在DevEco Device Tool中[打开一个工程](https://device.harmonyos.com/cn/docs/ide/user-guides/open_project-0000001071680043),该工程文件夹选择待烧录文件所在文件夹即可。其中开发板类型固定选择Hi3516DV300,Framework选择“Hb”。 + +### 使用网口烧录 + +Hi3516DV300开发板使用网口录方式,支持Windows和Linux系统。 + +1. 请连接好电脑和待烧录开发板,需要同时连接串口、网口和电源,具体可参考[Hi3516DV300开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3516-0000001152041033)。 +2. 打开电脑的设备管理器,查看并记录对应的串口号。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 + + ![](figure/zh-cn_image_0000001114129428.png) + +3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 + + ![](figure/2021-01-27_170334-16.png) + +4. 在**Partition Configuration**页签中,按照下表内容填写烧录文件信息,包括: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Binary

+

Memory

+

System

+

Address

+

Length

+

Board

+

Type

+

fastboot

+

选择“u-boot-hi3516dv300_emmc.bin”

+

emmc

+

none

+

0x000000

+

0x100000

+

固定选择“hi3516dv300”

+

NA

+

boot

+

选择“uImage”

+

emmc

+

none

+

0x100000

+

0xf00000

+

NA

+

updater

+

选择“updater.img”

+

emmc

+

ext3/4

+

0x1000000

+

0x1400000

+

NA

+

misc

+

空白,不用选择

+

emmc

+

none

+

0x2400000

+

0x100000

+

NA

+

system

+

选择“system.img”

+

emmc

+

ext3/4

+

0x2500000

+

0xceb00000

+

NA

+

vendor

+

选择“vendor.img”

+

emmc

+

ext3/4

+

0xd1000000

+

0x10000000

+

NA

+

userdata

+

选择“userdata.img”

+

emmc

+

ext3/4

+

0xe1000000

+

0x5b800000

+

NA

+
+ + ![](figure/zh-cn_image_0000001130584312.png) + +5. 在“hi3516dv300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 + + - upload\_port:选择步骤[2](#zh-cn_topic_0000001056443961_li1050616379507)中查询的串口号。 + - upload\_protocol:选择烧录协议,固定选择“hiburn-net”。 + - upload\_partitions:选择待烧录的文件,包括fastboot、boot、updater、misc、system、vendor和userdata。 + + ![](figure/zh-cn_image_0000001117621400.png) + +6. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516DV300网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/ide/user-guides/set_ipaddress-0000001141825075)。 +7. 设置网口烧录的IP地址信息,设置如下选项: + + - upload\_net\_server\_ip:选择步骤6中设置的IP地址信息。例如192.168.1.2 + - upload\_net\_client\_mask:设置开发板的子网掩码,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如255.255.255.0 + - upload\_net\_client\_gw:设置开发板的网关,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.1 + - upload\_net\_client\_ip:设置开发板的IP地址,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.3 + + ![](figure/zh-cn_image_0000001117463460.png) + +8. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 +9. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。 + + ![](figure/zh-cn_image_0000001114129432.png) + +10. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 + + ![](figure/zh-cn_image_0000001113969542.png) + + +## 下一步 + +恭喜!您已经完成了OpenHarmony标准系统的快速入门,接下来可[开发一个小示例](../guide/device-clock-guide.md),进一步熟悉OpenHarmony的开发。 + diff --git a/zh-cn/device-dev/quick-start/quickstart-standard-description.md b/zh-cn/device-dev/quick-start/quickstart-standard-description.md new file mode 100644 index 0000000000000000000000000000000000000000..20f133bca4fc7cbace60eca8d9a6de8b79e7965a --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-standard-description.md @@ -0,0 +1,54 @@ +# 入门介绍 + +- [快速入门流程](#section7825218111517) +- [开发板简介](#zh-cn_topic_0000001053666242_section047719215429) +- [开发板规格](#zh-cn_topic_0000001053666242_section15192203316533) + +开发者可通过本文快速掌握OpenHarmony标准系统的环境搭建、编译、烧录、启动等操作。标准系统可以使用Windows环境进行开发、烧录,使用Linux环境进行编译。 + +本文将以当前推荐的Hi3516DV300开发板为例对上述操作进行说明。 + +## 快速入门流程 + +标准系统快速入门流程如下图所示,其中“搭建Ubuntu环境及编译”环节可根据实际情况选择docker方式或工具包方式其中一种即可。 + +**图 1** 标准环境快速入门流程 +![](figure/标准环境快速入门流程.png "标准环境快速入门流程") + +## 开发板简介 + +Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。 + +**图 2** Hi3516单板正面外观图 + + +![](figure/3516正面.png) + +## 开发板规格 + +**表 1** Hi3516开发板规格清单 + + + + + + + + + + + + + +

规格类型

+

规格清单

+

处理器及内部存储

+
  • Hi3516DV300芯片
  • DDR3 1GB
  • eMMC4.5,8GB容量
+

外部器件

+
  • 以太网口
  • 音频视频
    • 1路语音输入
    • 1路单声道(AC_L)输出,接3W功放(LM4871)
    • MicroHDMI(1路HDMI 1.4)
    +
  • 摄像头
    • 传感器IMX335
    • 镜头M12,焦距4mm,光圈1.8
    +
  • 显示屏
    • LCD连接器(2.35寸)
    • LCD连接器(5.5寸)
    +
  • 外部器件及接口
    • SD卡接口
    • JTAG/I2S 接口
    • ADC接口
    • 舵机接口
    • Grove连接器
    • USB2.0(Type C)
    • 功能按键3个,2个用户自定义按键,1个升级按键
    • LED指示灯,绿灯,红灯
    +
+
+ diff --git a/zh-cn/device-dev/quick-start/quickstart-standard-docker-environment.md b/zh-cn/device-dev/quick-start/quickstart-standard-docker-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..6f3ed7f03f02d6cb9e59dadbe00d463d7734d319 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-standard-docker-environment.md @@ -0,0 +1,118 @@ +# 搭建Ubuntu环境及编译(Docker方式) + +- [获取标准系统源码](#section8761819202511) + - [前提条件](#section102871547153314) + - [操作步骤](#section429012478331) + +- [获取Docker环境](#section181431248132513) +- [编译](#section92391739152318) + +OpenHarmony标准系统为开发者提供的Docker环境已经将对应的编译工具链进行了封装,开发者可省略对应工具的安装。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>- 在使用Docker前需要先安装Docker,Docker安装请参考[官方指导](https://docs.docker.com/engine/install/ubuntu/)。 +>- Docker方式和安装包方式二选一即可。选择Docker方式的开发者可跳过[安装包方式](quickstart-standard-package-environment.md)的内容。 + +## 获取标准系统源码 + +### 前提条件 + +1. 注册码云gitee账号。 +2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 +3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading))并配置用户信息。 + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. 安装码云repo工具,可以执行如下命令。 + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### 操作步骤 + +方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +方式二:通过repo + https 下载。 + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## 获取Docker环境 + +**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** + +1. 获取Docker镜像。 + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**方式二:通过Dockerfile 构建本地Docker镜像进行构建** + +1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +## 编译 + +1. 在源码的根目录执行预处理脚本。 + + ``` + ../scripts/prepare.sh + ``` + +2. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 + + ``` + ./build.sh --product-name {product_name} + ``` + + \{product\_name\}为当前版本支持的平台,比如:Hi3516DV300 + + 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 + +3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](quickstart-standard-burn.md)。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>退出Docker执行exit命令即可。 + diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-8.md" b/zh-cn/device-dev/quick-start/quickstart-standard-faq.md similarity index 100% rename from "zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-8.md" rename to zh-cn/device-dev/quick-start/quickstart-standard-faq.md diff --git a/zh-cn/device-dev/quick-start/quickstart-standard-package-environment.md b/zh-cn/device-dev/quick-start/quickstart-standard-package-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..d35cc274995107ccc178c03fd48a41641dcc8ea2 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-standard-package-environment.md @@ -0,0 +1,98 @@ +# 搭建Ubuntu环境及编译(安装包方式) + +- [安装依赖工具](#section18431165519244) +- [获取标准系统源码](#section113751052102517) + - [前提条件](#section102871547153314) + - [操作步骤](#section429012478331) + +- [执行prebuilts](#section0495320152619) +- [编译](#section1664835963517) + +## 安装依赖工具 + +安装命令如下: + +``` +sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。 + +## 获取标准系统源码 + +### 前提条件 + +1. 注册码云gitee账号。 +2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 +3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading))并配置用户信息。 + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. 安装码云repo工具,可以执行如下命令。 + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### 操作步骤 + +方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +方式二:通过repo + https 下载。 + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## 执行prebuilts + +在源码根目录下执行脚本,安装编译器及二进制工具。 + +``` +bash build/prebuilts_download.sh +``` + +下载的prebuilts二进制默认存放在与OpenHarmony同目录下的OpenHarmony\_2.0\_canary\_prebuilts下。 + +## 编译 + +在Linux环境进行如下操作: + +1. 进入源码根目录,执行如下命令进行版本编译。 + + ``` + ./build.sh --product-name {product_name} + ``` + + \{product\_name\}为当前版本支持的平台,比如:Hi3516DV300 + +2. 检查编译结果。编译完成后,log中显示如下: + + ``` + build system image successful. + =====build Hi3516DV300 successful. + ``` + + 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >其他模块化编译操作,可参见[编译构建指导](../subsystems/subsys-build-standard-large.md)。 + +3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](quickstart-standard-burn.md)。 + diff --git a/zh-cn/device-dev/quick-start/quickstart-standard-windows-environment.md b/zh-cn/device-dev/quick-start/quickstart-standard-windows-environment.md new file mode 100644 index 0000000000000000000000000000000000000000..bf45ab1684dce5b497d0685d1cc05e3f20e43ac3 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-standard-windows-environment.md @@ -0,0 +1,179 @@ +# Windows开发环境准备 + +- [获取软件](#zh-cn_topic_0000001058091994_section1483143015558) +- [安装Visual Studio Code](#zh-cn_topic_0000001058091994_section71401018163318) +- [安装Python](#zh-cn_topic_0000001058091994_section16266553175320) +- [安装Node.js](#zh-cn_topic_0000001058091994_section5353233124511) +- [安装hpm](#zh-cn_topic_0000001058091994_section173054793610) +- [安装DevEco Device Tool插件](#zh-cn_topic_0000001058091994_section4336315185716) + +系统要求:Windows 10 64位系统。 + +DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展,安装分为如下几步: + +1. 安装Visual Studio Code +2. 安装Python +3. 安装Node.js +4. 安装hpm +5. 安装DevEco Device Tool插件 + +## 获取软件 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

工具名称

+

用途说明

+

版本要求

+

获取渠道

+

Visual Studio Code

+

代码编辑工具

+

V1.53及以上 64位版本。

+

https://code.visualstudio.com/Download

+

Python

+

编译构建工具

+

V3.7.4~V3.8.x 64位版本

+

https://www.python.org/downloads/

+

Node.js

+

提供npm环境

+

v12.0.0及以上 64位版本

+

https://nodejs.org/zh-cn/download/

+

hpm

+

包管理工具

+

最新版

+

请参考安装hpm

+

DevEco Device Tool

+

OpenHarmony源码的编译、烧录、调试插件工具

+

v2.2 Beta1

+

https://device.harmonyos.com/cn/ide#download

+

下载前,请使用华为开发者帐号登录,如未注册,请先注册华为开发者帐号

+
+ +## 安装Visual Studio Code + +>![](../public_sys-resources/icon-note.gif) **说明:** +>如果已安装Visual Studio Code,打开命令行工具,输入**code --version**命令,检查版本号是否为1.53及以上版本;可以正常返回版本号,说明环境变量设置也正确。 + +1. 双击Visual Studio Code软件包进行安装。安装过程中,请勾选“添加到PATH(重启后生效)”。 + + ![](figure/zh-cn_image_0000001057335403.png) + +2. 安装完成后,打开命令行工具,输入**code --version**命令,可以正常显示版本号说明安装成功。 + +## 安装Python + +>![](../public_sys-resources/icon-note.gif) **说明:** +>请注意,Python版本要求为V3.7.4\~V3.8.x 64位版本。 + +1. 双击Python安装包进行安装,勾选“**Add Python 3.8 to PATH**”,然后点击**Install Now**开始安装。 + + ![](figure/zh-cn_image_0000001176317561.png) + +2. 等待安装完成后,点击**Close**。 + + ![](figure/zh-cn_image_0000001142794291.png) + +3. 打开命令行工具,输入python --version,检查安装结果。 + + ![](figure/zh-cn_image_0000001130278040.png) + +4. 在命令行工具中,分别执行如下命令设置pip源,用于后续安装DevEco Device Tool过程中下载依赖的组件包。 + + ``` + pip config set global.trusted-host repo.huaweicloud.com + pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple + pip config set global.timeout 120 + ``` + + +## 安装Node.js + +>![](../public_sys-resources/icon-note.gif) **说明:** +>如果已安装Node.js,打开命令行工具,输入**node -v**命令,检查版本号是否为12.0.0及以上版本。 + +1. 点击下载后的软件包进行安装,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。 +2. 重新打开命令行工具,输入“node -v“命令,能正常查询Node.js的版本号,说明Node.js安装成功。 + +## 安装hpm + +该方式需先确保**Node.js**安装成功。 + +在安装hpm前,请检查网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问。这种情况下,需要先[设置npm代理](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032),才能安装hpm。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>如果已安装hpm,可以执行**npm update -g @ohos/hpm-cli**命令升级hpm至最新版本。 + +1. 建议将npm源配置为国内镜像,例如设置为华为云镜像源。 + + ``` + npm config set registry https://repo.huaweicloud.com/repository/npm/ + ``` + +2. 打开命令行工具,执行如下命令安装最新版本hpm。 + + ``` + npm install -g @ohos/hpm-cli + ``` + + ![](figure/zh-cn_image_0000001073840162.png) + +3. 安装完成后,执行如下命令(V为大写字母)检查hpm安装结果。 + + ``` + hpm -V + ``` + + +## 安装DevEco Device Tool插件 + +安装DevEco Device Tool插件,**主机的用户名不能包含中文字符**,否则可能导致运行出现错误。 + +DevEco Device Tool正常运行需要依赖于C/C++和CodeLLDB插件,在安装完DevEco Device Tool后,会自动从Visual Studio Code的插件市场安装C/C++和CodeLLDB插件。因此,在安装DevEco Device Tool前,请检查Visual Studio Code的网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问,请先[Visual Studio Code代理设置](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144)。 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>安装DevEco Device Tool时,请先关闭Visual Studio Code。 + +1. 解压DevEco Device Tool插件压缩包,双击安装包程序进行安装。 +2. 安装过程中,会自动安装DevEco Device Tool所需的依赖文件(如C/C++和CodeLLDB插件)和执行程序。 + + ![](figure/zh-cn_image_0000001072468991.png) + +3. 安装完成后,会自动关闭命令行工具窗口。 +4. 启动Visual Studio Code,点击左侧的![](figure/zh-cn_image_0000001072757874.png)按钮,检查INSTALLED中,是否已成功安装C/C++、CodeLLDB和DevEco Device Tool。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如果C/C++和CodeLLDB插件安装不成功,则DevEco Device Tool不能正常运行,解决方法,详细请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/ide/user-guides/offline_plugin_install-0000001074376846)。 + + ![](figure/zh-cn_image_0000001142802505.png) + + diff --git a/zh-cn/device-dev/quick-start/quickstart-standard.md b/zh-cn/device-dev/quick-start/quickstart-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..8d2bc8cb313e357a743b62556b44b97c927bb0f2 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart-standard.md @@ -0,0 +1,15 @@ +# 标准系统入门 + +- **[入门介绍](quickstart-standard-description.md)** + +- **[Windows开发环境准备](quickstart-standard-windows-environment.md)** + +- **[搭建Ubuntu环境及编译(Docker方式)](quickstart-standard-docker-environment.md)** + +- **[搭建Ubuntu环境及编译(安装包方式)](quickstart-standard-package-environment.md)** + +- **[镜像烧录](quickstart-standard-burn.md)** + +- **[常见问题](quickstart-standard-faq.md)** + + diff --git a/zh-cn/device-dev/quick-start/quickstart.md b/zh-cn/device-dev/quick-start/quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..5ab9867ff455695acd09b4325c016a46cae44dc8 --- /dev/null +++ b/zh-cn/device-dev/quick-start/quickstart.md @@ -0,0 +1,7 @@ +# 快速入门 + +- **[轻量和小型系统入门](quickstart-lite.md)** + +- **[标准系统入门](quickstart-standard.md)** + + diff --git "a/zh-cn/device-dev/quick-start/\344\272\206\350\247\243\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/\344\272\206\350\247\243\345\274\200\345\217\221\346\235\277.md" deleted file mode 100755 index fae4d8bb46425aee84df037e4e126c480c18bd9d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\344\272\206\350\247\243\345\274\200\345\217\221\346\235\277.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 了解开发板 - -- **[Hi3861开发板介绍](Hi3861开发板介绍.md)** - -- **[Hi3516开发板介绍](Hi3516开发板介绍.md)** - -- **[Hi3518开发板介绍](Hi3518开发板介绍.md)** - - diff --git "a/zh-cn/device-dev/quick-start/\345\205\245\351\227\250\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/\345\205\245\351\227\250\344\273\213\347\273\215.md" deleted file mode 100644 index 3e0807591c3e4ae71f160c45a6da9dc6cbf3dbca..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\205\245\351\227\250\344\273\213\347\273\215.md" +++ /dev/null @@ -1,54 +0,0 @@ -# 入门介绍 - -- [快速入门流程](#section7825218111517) -- [开发板简介](#zh-cn_topic_0000001053666242_section047719215429) -- [开发板规格](#zh-cn_topic_0000001053666242_section15192203316533) - -开发者可通过本文快速掌握OpenHarmony标准系统的环境搭建、编译、烧录、启动等操作。标准系统可以使用Windows环境进行开发、烧录,使用Linux环境进行编译。 - -本文将以当前推荐的Hi3516DV300开发板为例对上述操作进行说明。 - -## 快速入门流程 - -标准系统快速入门流程如下图所示,其中“搭建Ubuntu环境及编译”环节可根据实际情况选择docker方式或工具包方式其中一种即可。 - -**图 1** 标准环境快速入门流程 -![](figures/标准环境快速入门流程.png "标准环境快速入门流程") - -## 开发板简介 - -Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。 - -**图 2** Hi3516单板正面外观图 - - -![](figures/3516正面-16.png) - -## 开发板规格 - -**表 1** Hi3516开发板规格清单 - - - - - - - - - - - - - -

规格类型

-

规格清单

-

处理器及内部存储

-
  • Hi3516DV300芯片
  • DDR3 1GB
  • eMMC4.5,8GB容量
-

外部器件

-
  • 以太网口
  • 音频视频
    • 1路语音输入
    • 1路单声道(AC_L)输出,接3W功放(LM4871)
    • MicroHDMI(1路HDMI 1.4)
    -
  • 摄像头
    • 传感器IMX335
    • 镜头M12,焦距4mm,光圈1.8
    -
  • 显示屏
    • LCD连接器(2.35寸)
    • LCD连接器(5.5寸)
    -
  • 外部器件及接口
    • SD卡接口
    • JTAG/I2S 接口
    • ADC接口
    • 舵机接口
    • Grove连接器
    • USB2.0(Type C)
    • 功能按键3个,2个用户自定义按键,1个升级按键
    • LED指示灯,绿灯,红灯
    -
-
- diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-2.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-2.md" deleted file mode 100644 index 3f827074bfd5e4c7c19251d467dece8dedeb4fe2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-2.md" +++ /dev/null @@ -1,122 +0,0 @@ -# 安装开发板环境 - -- [Hi3516工具要求](#section179175261196) - - [硬件要求](#section5840424125014) - - [软件要求](#section965634210501) - -- [安装Linux服务器工具](#section182916865219) - - [将Linux shell改为bash](#section1715027152617) - - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251) - - [安装文件打包工具及Java虚拟机环境](#section16199102083717) - - -## Hi3516工具要求 - -### 硬件要求 - -- Hi3516DV300 IoT Camera开发板 -- USB转串口线、网线(Windows工作台通过USB转串口线、网线与Hi3516DV300 开发板连接) - -各硬件连接关系如下图所示。 - -**图 1** 硬件连线图 - - -![](figures/矩形备份-292.png) - -### 软件要求 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section182916865219)章节。 - -Hi3516开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 - -**表 1** Linux服务器开发工具及获取途径 - - - - - - - - - - - - - - - - - - - - - - - - -

开发工具

-

用途

-

获取途径

-

bash

-

命令行处理工具

-

系统配置

-

编译基础软件包(仅ubuntu 20+需要)

-

编译依赖的基础软件包

-

通过互联网获取

-

dosfstools、mtools、mtd-utils

-

文件打包工具

-

通过apt-get install安装

-

Java 虚拟机环境

-

编译、调试和运行Java程序

-

通过apt-get install安装

-
- -## 安装Linux服务器工具 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装LLVM、hc-gen编译工具。 ->- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。 - -### 将Linux shell改为bash - -查看shell是否为bash,在终端运行如下命令 - -``` -ls -l /bin/sh -``` - -如果显示为“/bin/sh -\> bash”则为正常,否则请按以下方式修改: - -**方法一**:在终端运行如下命令,然后选择 no。 - -``` -sudo dpkg-reconfigure dash -``` - -**方法二**:先删除sh,再创建软链接。 - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### 安装编译依赖基础软件(仅Ubuntu 20+需要) - -执行以下命令进行安装: - -``` -sudo apt-get install build-essential gcc g++ make zlib* libffi-dev -``` - -### 安装文件打包工具及Java虚拟机环境 - -1. 打开Linux编译服务器终端 -2. 运行如下命令,安装dosfstools,mtools,mtd-utils,Java运行时环境(JRE)和Java sdk 开发工具包。 - - ``` - sudo apt-get install dosfstools mtools mtd-utils default-jre default-jdk - ``` - - diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-4.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-4.md" deleted file mode 100644 index b2bbd778809bfdb9aa3ac3e5104e070cce42eae4..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-4.md" +++ /dev/null @@ -1,114 +0,0 @@ -# 安装开发板环境 - -- [Hi3518环境搭建](#section1724111409282) - - [硬件要求](#section487353718276) - - [软件要求](#section17315193935817) - -- [安装Linux服务器工具](#section8831868501) - - [将Linux shell改为bash](#section434110241084) - - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section25911132141020) - - [安装文件打包工具](#section390214473129) - - -## Hi3518环境搭建 - -### 硬件要求 - -- Hi3518EV300 IoT Camera开发板 -- USB转串口线、网线(Windows工作台通过USB转串口线、网线与开发板连接) - - 各硬件连接关系如下图所示。 - - -**图 1** 硬件连线图 -![](figures/硬件连线图-3.png "硬件连线图-3") - -### 软件要求 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section8831868501)章节。 - -Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 - -**表 1** Linux服务器开发工具及获取途径 - - - - - - - - - - - - - - - - - - - - -

开发工具

-

用途

-

获取途径

-

bash

-

命令行处理工具

-

系统配置

-

编译基础软件包(仅ubuntu 20+需要)

-

编译依赖的基础软件包

-

通过互联网获取

-

dosfstools、mtools、mtd-utils

-

文件打包工具

-

通过apt-get install安装

-
- -## 安装Linux服务器工具 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装hc-gen编译工具。 ->- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。 - -### 将Linux shell改为bash - -查看shell是否为bash,在终端运行如下命令 - -``` -ls -l /bin/sh -``` - -如果显示为“/bin/sh -\> bash”则为正常,否则请按以下方式修改: - -**方法一**:在终端运行如下命令,然后选择 no。 - -``` -sudo dpkg-reconfigure dash -``` - -**方法二**:先删除sh,再创建软链接。 - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### 安装编译依赖基础软件(仅Ubuntu 20+需要) - -执行以下命令进行安装: - -``` -sudo apt-get install build-essential gcc g++ make zlib* libffi-dev -``` - -### 安装文件打包工具 - -1. 打开Linux编译服务器终端。 -2. 运行如下命令,安装dosfstools,mtools,mtd-utils。 - - ``` - sudo apt-get install dosfstools mtools mtd-utils - ``` - - diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203.md" deleted file mode 100644 index 2bf84d7aab300883ba5e0b44f2c0acb5ad043917..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203.md" +++ /dev/null @@ -1,367 +0,0 @@ -# 安装开发板环境 - -- [Hi3861工具要求](#section466851916410) - - [硬件要求](#section19202111020215) - - [软件要求](#section727451210318) - -- [安装Linux编译工具](#section497484245614) - - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251) - - [安装Scons](#section7438245172514) - - [安装python模块](#section88701892341) - - [安装gcc\_riscv32(WLAN模组类编译工具链)](#section34435451256) - -- [安装USB转串口驱动](#section1027732411513) - -## Hi3861工具要求 - -### 硬件要求 - -- Linux服务器 -- Windows工作台(主机电脑) -- Hi3861 WLAN模组 -- USB Type-C线(Windows工作台通过USB与Hi3861 WLAN模组连接) - -各硬件连接关系如下图所示。 - -**图 1** 硬件连线图 -![](figures/硬件连线图.png "硬件连线图") - -### 软件要求 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本节描述采用安装包方式安装相关工具的操作步骤。如果是Docker方式安装,无需安装[表1](#table6299192712513)中的Linux服务器相关工具,只需安装Windows工作台工具即可。 - -Hi3861开发板需要的工具如下表所示。 - -**表 1** Hi3861开发板需要的工具 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

平台类型

-

开发工具

-

用途

-

获取途径

-

Linux服务器

-

编译基础软件包(仅ubuntu 20+需要)

-

编译依赖的基础软件包

-

通过互联网获取

-

Linux服务器

-

SCons3.0.4+

-

编译构建工具

-

通过互联网获取

-

Linux服务器

-

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

-

编译构建工具

-

通过互联网获取

-

Linux服务器

-

gcc riscv32

-

编译构建工具

-

通过互联网获取

-

Windows工作台

-

CH341SER.EXE

-

USB转串口驱动

-

http://www.wch.cn/search?q=ch340g&t=downloads

-
- -## 安装Linux编译工具 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装gcc\_riscv32编译工具。 ->- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装gcc\_riscv32编译工具。安装gcc\_riscv32编译工具时,请确保编译工具的环境变量路径唯一。 - -### 安装编译依赖基础软件(仅Ubuntu 20+需要) - -执行以下命令进行安装: - -``` -sudo apt-get install build-essential gcc g++ make zlib* libffi-dev -``` - -### 安装Scons - -1. 打开Linux编译服务器终端。 -2. 运行如下命令,安装SCons安装包。 - - ``` - python3 -m pip install scons - ``` - -3. 运行如下命令,查看是否安装成功。如果安装成功,查询结果下图所示。 - - ``` - scons -v - ``` - - **图 2** SCons安装成功界面,版本要求3.0.4以上 - ![](figures/SCons安装成功界面-版本要求3-0-4以上.png "SCons安装成功界面-版本要求3-0-4以上") - - -### 安装python模块 - -1. 运行如下命令,安装python模块setuptools。 - - ``` - pip3 install setuptools - ``` - -2. 安装GUI menuconfig工具(Kconfiglib),建议安装Kconfiglib 13.2.0+版本,任选如下一种方式。 - - **命令行方式:** - - ``` - sudo pip3 install kconfiglib - ``` - - - - **安装包方式:** - 1. 下载.whl文件(例如:kconfiglib-13.2.0-py2.py3-none-any.whl)。 - - 下载路径:“[https://pypi.org/project/kconfiglib\#files](https://pypi.org/project/kconfiglib#files)” - - - 1. 运行如下命令,安装.whl文件。 - - ``` - sudo pip3 install kconfiglib-13.2.0-py2.py3-none-any.whl - ``` - - - -3. 安装pycryptodome,任选如下一种方式。 - - 安装升级文件签名依赖的Python组件包,包括:pycryptodome、six、ecdsa。安装ecdsa依赖six,请先安装six,再安装ecdsa。 - - - **命令行方式:** - - ``` - sudo pip3 install pycryptodome - ``` - - - **安装包方式:** - 1. 下载.whl文件(例如:pycryptodome-3.9.9-cp38-cp38-manylinux1\_x86\_64.whl)。 - - 下载路径:“[https://pypi.org/project/pycryptodome/\#files](https://pypi.org/project/pycryptodome/#files)”。 - - - 1. 运行如下命令,安装.whl文件。 - - ``` - sudo pip3 install pycryptodome-3.9.9-cp38-cp38-manylinux1_x86_64.whl - ``` - - - -4. 安装six,任选如下一种方式。 - - **命令行方式:** - - ``` - sudo pip3 install six --upgrade --ignore-installed six - ``` - - - - **安装包方式:** - 1. 下载.whl文件(例如:six-1.12.0-py2.py3-none-any.whl)。 - - 下载路径:“[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files)” - - - 1. 运行如下命令,安装.whl文件。 - - ``` - sudo pip3 install six-1.12.0-py2.py3-none-any.whl - ``` - - - -5. 安装ecdsa,任选如下一种方式。 - - **命令行方式:** - - ``` - sudo pip3 install ecdsa - ``` - - - **安装包方式:** - 1. 下载.whl文件(例如:ecdsa-0.14.1-py2.py3-none-any.whl)。 - - 下载路径:“[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files)” - - - 1. 运行如下命令,安装.whl文件。 - - ``` - sudo pip3 install ecdsa-0.14.1-py2.py3-none-any.whl - ``` - - - - -### 安装gcc\_riscv32(WLAN模组类编译工具链) - ->![](public_sys-resources/icon-notice.gif) **须知:** ->- Hi3861平台仅支持使用libgcc运行时库的静态链接,不建议开发者使用libgcc运行时库的动态链接,会导致商业分发时被GPL V3污染。 ->- 通过下述步骤2-15,我们编译好了gcc\_riscv32 镜像,提供给开发者[直接下载](https://repo.huaweicloud.com/harmonyos/compiler/gcc_riscv32/7.3.0/linux/gcc_riscv32-linux-7.3.0.tar.gz)使用。直接下载 gcc\_riscv32 镜像的开发者可省略下述2-15步。 - -1. 打开Linux编译服务器终端。 -2. 环境准备,请安装"gcc, g++, bison, flex, makeinfo"软件,确保工具链能正确编译。 - - ``` - sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install flex bison && sudo apt-get install texinfo - ``` - -3. 下载riscv-gnu-toolchain交叉编译工具链。 - - ``` - git clone --recursive https://gitee.com/mirrors/riscv-gnu-toolchain.git - ``` - -4. 打开文件夹riscv-gnu-toolchain,先删除空文件夹,以防止下载newlib,binutils,gcc时冲突。 - - ``` - cd riscv-gnu-toolchain && rm -rf riscv-newlib && rm -rf riscv-binutils && rm -rf riscv-gcc - ``` - -5. 下载riscv-newlib-3.0.0。 - - ``` - git clone -b riscv-newlib-3.0.0 https://github.com/riscv/riscv-newlib.git - ``` - -6. 下载riscv-binutils-2.31.1。 - - ``` - git clone -b riscv-binutils-2.31.1 https://github.com/riscv/riscv-binutils-gdb.git - ``` - -7. 下载riscv-gcc-7.3.0。 - - ``` - git clone -b riscv-gcc-7.3.0 https://github.com/riscv/riscv-gcc - ``` - -8. 添加riscv-gcc-7.3.0补丁。 - - 访问gcc官方补丁链接[89411](https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=026216a753ef0a757a9e368a59fa667ea422cf09;hp=2a23a1c39fb33df0277abd4486a3da64ae5e62c2),[86724](https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff;f=gcc/graphite.h;h=be0a22b38942850d88feb159603bb846a8607539;hp=4e0e58c60ab83f1b8acf576e83330466775fac17;hb=b1761565882ed6a171136c2c89e597bc4dd5b6bf;hpb=fbd5f023a03f9f60c6ae36133703af5a711842a3),按照补丁链接中要求的修改,手动将变更添加到对应的.c和.h文件中,注意由于patch版本与下载的gcc版本有所偏差,行数有可能对应不上,请自行查找patch中的关键字定位到对应行。 - -9. 下载[GMP 6.1.2](https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2),并解压安装。 - - ``` - tar -xvf gmp-6.1.2.tar.bz2 && mkdir build_gmp && cd build_gmp && ../gmp-6.1.2/configure --prefix=/usr/local/gmp-6.1.2 --disable-shared --enable-cxx && make && make install - ``` - -10. 下载[mpfr-4.0.2 ](https://www.mpfr.org/mpfr-4.0.2/mpfr-4.0.2.tar.gz),并解压安装。 - - ``` - tar -xvf mpfr-4.0.2.tar.gz && mkdir build_mpfr && cd build_mpfr && ../mpfr-4.0.2/configure --prefix=/usr/local/mpfr-4.0.2 --with-gmp=/usr/local/gmp-6.1.2 --disable-shared && make && make install - ``` - -11. 下载[mpc-1.1.0](https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz) ,并解压安装。 - - ``` - tar -xvf mpc-1.1.0.tar.gz && mkdir build_mpc && cd build_mpc && ../mpc-1.1.0/configure --prefix=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 --disable-shared && make && make install - ``` - -12. 打开文件夹riscv-gnu-toolchain,新建工具链输出目录。 - - ``` - cd /opt && mkdir gcc_riscv32 - ``` - -13. 编译binutils。 - - ``` - mkdir build_binutils && cd build_binutils && ../riscv-binutils-gdb/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32/riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. - ``` - -14. 编译newlib。 - - ``` - mkdir build_newlib && cd build_newlib && ../riscv-newlib/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" \CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd .. - ``` - -15. 编译gcc。 - - ``` - mkdir build_gcc && cd build_gcc && ../riscv-gcc/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" LDFLAGS="-Wl,-z,relro,-z,now,-z,noexecstack" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --with-headers="/opt/gcc-riscv32/riscv32-unknown-elf/include" --with-mpc=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 && make -j16 && make install - ``` - -16. 设置环境变量。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果直接采用编译好的riscv32 gcc包,请参照如下步骤设置环境变量: - >1. 将压缩包解压到根目录 - > ``` - > tar -xvf gcc_riscv32-linux-7.3.0.tar.gz -C ~ - > ``` - >2. 设置环境变量。 - > ``` - > vim ~/.bashrc - > ``` - >3. 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - > ``` - > export PATH=~/gcc_riscv32/bin:$PATH - > ``` - - ``` - vim ~/.bashrc - ``` - - 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - - ``` - export PATH=~/gcc_riscv32/bin:$PATH - ``` - -17. 生效环境变量。 - - ``` - source ~/.bashrc - ``` - -18. Shell命令行中输入如下命令,如果能正确显示编译器版本号,表明编译器安装成功。 - - ``` - riscv32-unknown-elf-gcc -v - ``` - - -## 安装USB转串口驱动 - -相关步骤在Windows工作台操作。 - -1. 点击链接[下载CH341SER USB转串口](http://www.hihope.org/download/download.aspx?mtt=8)驱动程序。 -2. 点击安装包,安装驱动程序。 -3. 驱动安装完成后,重新插拔USB接口,串口信息显示如下图所示。 - - ![](figures/zh-cn_image_0000001174350633.png) - - diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-1.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-1.md" deleted file mode 100644 index f8e0b7384e225685a08fa51e0cf97264bfe3851e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-1.md" +++ /dev/null @@ -1,292 +0,0 @@ -# 常见问题 - -- [安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”](#section1221016541119) -- [安装python3过程中,提示“-bash: make: command not found”](#section1913477181213) -- [安装python3过程中,提示“zlib not available”](#section108211415131210) -- [安装python3过程中,提示“No module named '\_ctypes'”](#section2062268124) -- [编译构建过程中,提示“No module named 'Crypto'”](#section982315398121) -- [编译构建过程中,提示“No module named 'ecdsa'”](#section102035451216) -- [编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0”](#section4498158162320) -- [编译构建过程中,提示找不到“-lgcc”](#section11181036112615) -- [编译构建过程中,提示找不到“python”](#section1571810194619) -- [安装 kconfiglib时,遇到lsb\_release错误](#section691681635814) - -## 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details - ``` - -- **可能原因** - - 环境中未安装“gcc”。 - -- **解决办法** - - 1、通过命令“apt-get install gcc”在线安装。 - - 2、完成后,重新安装python3。 - - -## 安装python3过程中,提示“-bash: make: command not found” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - -bash: make: command not found - ``` - -- **可能原因** - - 环境中未安装“make”。 - -- **解决办法** - - 1、通过命令“apt-get install make”在线安装。 - - 2、完成后,重新安装python3。 - - -## 安装python3过程中,提示“zlib not available” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - zipimport.ZipImportError: can't decompress data; zlib not avaliable - ``` - -- **可能原因** - - 环境中未安装“zlib”。 - -- **解决办法** - - 方法1:通过命令“apt-get install zlib”在线安装。 - - 方法2:如果软件源中没有该软件,请从“www.zlib.net”下载版本代码,并离线安装。 - - ![](figures/10.png) - - 完成下载后,通过以下命令安装: - - ``` - # tar xvf zlib-1.2.11.tar.gz - # cd zlib-1.2.11 - # ./configure - # make && make install - ``` - - 完成后,重新安装python3。 - - -## 安装python3过程中,提示“No module named '\_ctypes'” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - ModuleNotFoundError:No module named ‘_ctypes’ - ``` - - -- **可能原因** - - 环境中未安装“libffi”和“libffi-devel”。 - - -- **解决办法** - - 1、通过命令“apt-get install libffi\* -y”,在线安装。 - - 2、完成后,重新安装python3。 - - -## 编译构建过程中,提示“No module named 'Crypto'” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - ModuleNotFoundError: No module named 'Crypto' - ``` - - -- **可能原因** - - 环境中未安装“Crypto”。 - - -- **解决办法** - - 方法1:通过命令“pip3 install Crypto”,在线安装。 - - 方法2:离线安装 - - 通过网页[https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files),下载源码。 - - ![](figures/zh-cn_image_0000001128470864.png) - - 将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”。 - - 完成上述安装后,重新构建。 - - -## 编译构建过程中,提示“No module named 'ecdsa'” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - ModuleNotFoundError:No module named 'ecdsa' - ``` - - -- **可能原因** - - 环境中未安装“ecdsa”。 - - -- **解决办法** - - 方法1:通过命令“pip3 install ecdsa”,在线安装。 - - 方法2:离线安装 - - 通过网页[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files),下载安装包。 - - ![](figures/zh-cn_image_0000001128311072.png) - - 将安装包放置Linux服务器中,并安装“pip3 install ecdsa-0.15-py2.py3-none-any.whl”。 - - 完成上述安装后,重新构建。 - - -## 编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - Could not find a version that satisfies the requirement six>=1.9.0 - ``` - - -- **可能原因** - - 环境中未安装合适的“six”。 - - -- **解决办法** - - 方法1:通过命令“pip3 install six”,在线安装。 - - 方法2:离线安装 - - 通过网页[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files),下载安装包。 - - ![](figures/zh-cn_image_0000001174270699.png) - - 将源码放置在Linux服务器中,并安装“pip3 install six-1.14.0-py2.py3-none-any.whl”。 - - 完成上述安装后,重新构建。 - - -## 编译构建过程中,提示找不到“-lgcc” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - riscv32-unknown-elf-ld: cannot find -lgcc - ``` - - -- **可能原因** - - 交叉编译器gcc\_riscv32的PATH添加错误,如下,在"bin"后多添加了一个“/”,应该删除。 - - ``` - ~/gcc_riscv32/bin/:/data/toolchain/ - ``` - - -- **解决办法** - - 重新修改gcc\_riscv32的PATH,将多余的“/”删除。 - - ``` - ~/gcc_riscv32/bin:/data/toolchain/ - ``` - - -## 编译构建过程中,提示找不到“python” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - -bash: /usr/bin/python: No such file or directory - ``` - - -- **可能原因**1 - - 没有装python。 - -- **解决办法** - - 请按照 [安装Python环境](../quick-start/Ubuntu编译环境准备.md) - -- **可能原因2** - - ![](figures/zh-cn_image_0000001128311070.png) - -- **解决办法** - - usr/bin目录下没有python软链接,请运行以下命令添加软链接: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - 例: - - ![](figures/zh-cn_image_0000001174350623.png) - - -## 安装 kconfiglib时,遇到lsb\_release错误 - -- **现象描述** - - 安装kconfiglib过程中遇到如下错误打印: - - ``` - subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1. - ``` - -- **可能原因** - - lsb\_release模块基于的python版本与现有python版本不一致 - -- **解决办法** - - 执行"find / -name lsb\_release",找到lsb\_release位置并删除,如:"sudo rm -rf /usr/bin/lsb\_release" - - diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-3.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-3.md" deleted file mode 100644 index ece72f03517ecd60ca587fcba3c3fab1a5974a47..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-3.md" +++ /dev/null @@ -1,175 +0,0 @@ -# 常见问题 - -- [烧写选择串口后提示失败](#section627268185113) -- [Windows电脑与单板网络连接失败](#section195391036568) -- [烧写失败](#section571164016565) -- [编译构建过程中,提示找不到“python”](#section1039835245619) -- [串口无回显](#section14871149155911) - -## 烧写选择串口后提示失败 - -- **现象描述** - - 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied。 - - **图 1** 打开串口失败图 - ![](figures/打开串口失败图.png "打开串口失败图") - -- **可能原因** - - 串口已经被占用。 - -- **解决办法** - -1. 按图依次选择下拉框,查找带有serial-xx的终端 - - **图 2** 查找是否存在占用串口的终端 - ![](figures/查找是否存在占用串口的终端.png "查找是否存在占用串口的终端") - -2. 点击标号中的垃圾桶图标,关闭串口。 - - **图 3** 关闭串口终端 - ![](figures/关闭串口终端.png "关闭串口终端") - -3. 重新点击烧写,选择串口并开始烧写程序 - - **图 4** 重新启动烧写任务 - - - ![](figures/changjian1.png) - - -## Windows电脑与单板网络连接失败 - -- **现象描述** - - 点击烧写并选择串口后,无法获取文件。 - - **图 5** 网络不通,单板无法获取文件图 - ![](figures/网络不通-单板无法获取文件图.png "网络不通-单板无法获取文件图") - -- **可能原因** - - 单板网络与Windows电脑不联通。 - - Windows电脑防火墙未允许Visual Studio Code联网。 - -- **解决方法** - -1. 检查网线是否连接。 -2. 点击Windows防火墙。 - - **图 6** 网络防火墙设置图 - ![](figures/网络防火墙设置图.png "网络防火墙设置图") - -3. 点击“允许应用通过防火墙”。 - - **图 7** 防火墙和网络保护界面图 - ![](figures/防火墙和网络保护界面图.png "防火墙和网络保护界面图") - -4. 查找Visual Studio Code应用。 - - **图 8** 查找Visual Studio Code应用图 - ![](figures/查找Visual-Studio-Code应用图.png "查找Visual-Studio-Code应用图") - -5. 勾选Visual Studio Code的专用和公用网络的访问权限。 - - **图 9** 允许Visual Studio Code应用访问网络 - ![](figures/允许Visual-Studio-Code应用访问网络.png "允许Visual-Studio-Code应用访问网络") - - -## 烧写失败 - -- **现象描述** - - 点击烧写并选择串口后,出现无法烧写的情况。 - -- **可能原因** - - 安装IDE插件DevEco后未重启。 - -- **解决方法** - - 重启IDE。 - - -## 编译构建过程中,提示找不到“python” - -- **现象描述** - - ![](figures/zh-cn_image_0000001174270715.png) - - -- **可能原因1** - - 没有装python。 - -- **解决办法** - - 请按照[安装python](../quick-start/Ubuntu编译环境准备.md)。 - -- **可能原因2** - - ![](figures/zh-cn_image_0000001128470880.png) - -- **解决办法** - - usr/bin目录下没有python软链接,请运行以下命令: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - 例: - - ![](figures/zh-cn_image_0000001174270713.png) - - -## 串口无回显 - -- **现象描述** - - 串口显示已连接,重启单板后,回车无任何回显。 - -- **可能原因1** - - 串口连接错误。 - -- **解决办法** - - 修改串口号。 - - 请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行内[步骤1](../quick-start/运行Hello-OHOS.md)修改串口号。 - - -- **可能原因2** - - 单板U-boot被损坏。 - -- **解决办法** - - 烧写U-boot。 - - 若上述步骤依旧无法连接串口,可能由于单板U-boot损坏,按下述步骤烧写U-boot。 - - -1. 获取引导文件U-boot。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >单板的U-boot文件请在开源包中获取: - >Hi3516DV300:device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin - >Hi3518EV300:device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin - -2. 根据USB烧写步骤烧写U-boot文件。 - - 按照[Hi3516系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Hi3518系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3518_upload-0000001057313128)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。 - -3. 烧写完成后,登录串口如下图所示。 - - **图 10** U-boot烧写完成串口显示图 - ![](figures/U-boot烧写完成串口显示图.png "U-boot烧写完成串口显示图") - - diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-6.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-6.md" deleted file mode 100644 index b2dc3ad51268d608a8767e7eaf9256fbc9adfe11..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-6.md" +++ /dev/null @@ -1,174 +0,0 @@ -# 常见问题 - -- [烧写选择串口后提示失败](#section1498892119619) -- [Windows电脑与单板网络连接失败](#section8512971816) -- [烧写失败](#section1767804111198) -- [编译构建过程中,提示找不到“python”](#zh-cn_topic_0000001053466255_section1039835245619) -- [串口无回显](#zh-cn_topic_0000001053466255_section14871149155911) - -## 烧写选择串口后提示失败 - -- **现象描述** - - 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied。 - - **图 1** 打开串口失败图 - ![](figures/打开串口失败图-7.png "打开串口失败图-7") - -- **可能原因** - - 串口已经被占用。 - -- **解决办法** - -1. 按图依次选择下拉框,查找带有serial-xx的终端 - - **图 2** 查找是否存在占用串口的终端 - ![](figures/查找是否存在占用串口的终端-8.png "查找是否存在占用串口的终端-8") - -2. 点击标号中的垃圾桶图标,关闭串口。 - - **图 3** 关闭串口终端 - ![](figures/关闭串口终端-9.png "关闭串口终端-9") - -3. 重新点击烧写,选择串口并开始烧写程序 - - **图 4** 重新启动烧写任务 - - - ![](figures/changjian1-10.png) - - -## Windows电脑与单板网络连接失败 - -- **现象描述** - - 点击烧写并选择串口后,无法获取文件。 - - **图 5** 网络不通,单板无法获取文件图 - ![](figures/网络不通-单板无法获取文件图-11.png "网络不通-单板无法获取文件图-11") - -- **可能原因** - - 单板网络与Windows电脑不联通。 - - Windows电脑防火墙未允许Visual Studio Code联网。 - -- **解决方法** - -1. 检查网线是否连接。 -2. 点击Windows防火墙。 - - **图 6** 网络防火墙设置图 - ![](figures/网络防火墙设置图-12.png "网络防火墙设置图-12") - -3. 点击“允许应用通过防火墙”。 - - **图 7** 防火墙和网络保护界面图 - ![](figures/防火墙和网络保护界面图-13.png "防火墙和网络保护界面图-13") - -4. 查找Visual Studio Code应用。 - - **图 8** 查找Visual Studio Code应用图 - ![](figures/查找Visual-Studio-Code应用图-14.png "查找Visual-Studio-Code应用图-14") - -5. 勾选Visual Studio Code的专用和公用网络的访问权限。 - - **图 9** 允许Visual Studio Code应用访问网络 - ![](figures/允许Visual-Studio-Code应用访问网络-15.png "允许Visual-Studio-Code应用访问网络-15") - - -## 烧写失败 - -- **现象描述** - - 点击烧写并选择串口后,出现无法烧写的情况。 - -- **可能原因** - - 安装IDE插件DevEco后未重启。 - -- **解决方法** - - 重启IDE。 - - -## 编译构建过程中,提示找不到“python” - -- **现象描述** - - ![](figures/zh-cn_image_0000001174270743.png) - - -- **可能原因1** - - 没有装python。 - -- **解决办法** - - 请按照[安装python](../quick-start/Ubuntu编译环境准备.md)。 - -- **可能原因2** - - ![](figures/zh-cn_image_0000001174270739.png) - -- **解决办法** - - usr/bin目录下没有python软链接,请运行以下命令: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - 例: - - ![](figures/zh-cn_image_0000001174350661.png) - - -## 串口无回显 - -- **现象描述** - - 串口显示已连接,重启单板后,回车无任何回显。 - -- **可能原因1** - - 串口连接错误。 - -- **解决办法** - - 修改串口号。 - - 请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行内[步骤1](../quick-start/运行Hello-OHOS.md)修改串口号。 - - -- **可能原因2** - - 单板U-boot被损坏。 - -- **解决办法** - - 烧写U-boot。 - - 若上述步骤依旧无法连接串口,可能由于单板U-boot损坏,按下述步骤烧写U-boot。 - - -1. 获取引导文件U-boot。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >单板的U-boot文件请在开源包中获取: - >Hi3516DV300:device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin - >Hi3518EV300:device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin - -2. 根据USB烧写步骤烧写U-boot文件。 - - 按照[Hi3516系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Hi3518系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3518_upload-0000001057313128)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。 - -3. 烧写完成后,登录串口如下图所示。 - - ![](figures/zh-cn_image_0000001174350659.png) - - diff --git "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244.md" "b/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244.md" deleted file mode 100644 index 70e795860fbfacc0dc0c4d9c38c453e7a5a99519..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 开发步骤 - -- **[Hi3861开发板](Hi3861开发板.md)** - -- **[Hi3516开发板](Hi3516开发板.md)** - -- **[Hi3518开发板](Hi3518开发板.md)** - - diff --git "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210Docker\346\226\271\345\274\217\357\274\211.md" "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210Docker\346\226\271\345\274\217\357\274\211.md" deleted file mode 100644 index 2f4c97aa4a72f1a42454c7662ccfc17eab7e17d4..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210Docker\346\226\271\345\274\217\357\274\211.md" +++ /dev/null @@ -1,118 +0,0 @@ -# 搭建Ubuntu环境及编译(Docker方式) - -- [获取标准系统源码](#section8761819202511) - - [前提条件](#section102871547153314) - - [操作步骤](#section429012478331) - -- [获取Docker环境](#section181431248132513) -- [编译](#section92391739152318) - -OpenHarmony标准系统为开发者提供的Docker环境已经将对应的编译工具链进行了封装,开发者可省略对应工具的安装。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->- 在使用Docker前需要先安装Docker,Docker安装请参考[官方指导](https://docs.docker.com/engine/install/ubuntu/)。 ->- Docker方式和安装包方式二选一即可。选择Docker方式的开发者可跳过[安装包方式](搭建Ubuntu环境及编译(安装包方式).md)的内容。 - -## 获取标准系统源码 - -### 前提条件 - -1. 注册码云gitee账号。 -2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 -3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading))并配置用户信息。 - - ``` - git config --global user.name "yourname" - git config --global user.email "your-email-address" - git config --global credential.helper store - ``` - -4. 安装码云repo工具,可以执行如下命令。 - - ``` - curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 - chmod a+x /usr/local/bin/repo - pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests - ``` - - -### 操作步骤 - -方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 - -``` -repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -方式二:通过repo + https 下载。 - -``` -repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -## 获取Docker环境 - -**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** - -1. 获取Docker镜像。 - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - -2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - - -**方式二:通过Dockerfile 构建本地Docker镜像进行构建** - -1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 - - ``` - cd docs/docker/standard - ./build.sh - ``` - -3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ``` - docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 - ``` - - -## 编译 - -1. 在源码的根目录执行预处理脚本。 - - ``` - ../scripts/prepare.sh - ``` - -2. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 - - ``` - ./build.sh --product-name {product_name} - ``` - - \{product\_name\}为当前版本支持的平台,比如:Hi3516DV300 - - 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 - -3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](镜像烧录.md)。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->退出Docker执行exit命令即可。 - diff --git "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210\345\256\211\350\243\205\345\214\205\346\226\271\345\274\217\357\274\211.md" "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210\345\256\211\350\243\205\345\214\205\346\226\271\345\274\217\357\274\211.md" deleted file mode 100644 index 92eb461fe7ace1d62022113eabdd655b4d1f6788..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210\345\256\211\350\243\205\345\214\205\346\226\271\345\274\217\357\274\211.md" +++ /dev/null @@ -1,98 +0,0 @@ -# 搭建Ubuntu环境及编译(安装包方式) - -- [安装依赖工具](#section18431165519244) -- [获取标准系统源码](#section113751052102517) - - [前提条件](#section102871547153314) - - [操作步骤](#section429012478331) - -- [执行prebuilts](#section0495320152619) -- [编译](#section1664835963517) - -## 安装依赖工具 - -安装命令如下: - -``` -sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。 - -## 获取标准系统源码 - -### 前提条件 - -1. 注册码云gitee账号。 -2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 -3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading))并配置用户信息。 - - ``` - git config --global user.name "yourname" - git config --global user.email "your-email-address" - git config --global credential.helper store - ``` - -4. 安装码云repo工具,可以执行如下命令。 - - ``` - curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 - chmod a+x /usr/local/bin/repo - pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests - ``` - - -### 操作步骤 - -方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 - -``` -repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -方式二:通过repo + https 下载。 - -``` -repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify -repo sync -c -repo forall -c 'git lfs pull' -``` - -## 执行prebuilts - -在源码根目录下执行脚本,安装编译器及二进制工具。 - -``` -bash build/prebuilts_download.sh -``` - -下载的prebuilts二进制默认存放在与OpenHarmony同目录下的OpenHarmony\_2.0\_canary\_prebuilts下。 - -## 编译 - -在Linux环境进行如下操作: - -1. 进入源码根目录,执行如下命令进行版本编译。 - - ``` - ./build.sh --product-name {product_name} - ``` - - \{product\_name\}为当前版本支持的平台,比如:Hi3516DV300 - -2. 检查编译结果。编译完成后,log中显示如下: - - ``` - build system image successful. - =====build Hi3516DV300 successful. - ``` - - 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >其他模块化编译操作,可参见[编译构建指导](../subsystems/标准系统编译构建指导.md)。 - -3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](镜像烧录.md)。 - diff --git "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272\347\263\273\347\273\237\347\216\257\345\242\203.md" "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272\347\263\273\347\273\237\347\216\257\345\242\203.md" deleted file mode 100755 index 73a9d50f87e5de08c775137b9864e6f02656872e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272\347\263\273\347\273\237\347\216\257\345\242\203.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 搭建系统环境 - -- **[概述](概述-0.md)** - -- **[Windows开发环境准备](Windows开发环境准备.md)** - -- **[Ubuntu编译环境准备](Ubuntu编译环境准备.md)** - -- **[常见问题](常见问题.md)** - - diff --git "a/zh-cn/device-dev/quick-start/\346\240\207\345\207\206\347\263\273\347\273\237\345\205\245\351\227\250.md" "b/zh-cn/device-dev/quick-start/\346\240\207\345\207\206\347\263\273\347\273\237\345\205\245\351\227\250.md" deleted file mode 100755 index 0281a27a47be0f03dcb2595968a0377c5e65f554..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\346\240\207\345\207\206\347\263\273\347\273\237\345\205\245\351\227\250.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 标准系统入门 - -- **[入门介绍](入门介绍.md)** - -- **[Windows开发环境准备](Windows开发环境准备-7.md)** - -- **[搭建Ubuntu环境及编译(Docker方式)](搭建Ubuntu环境及编译(Docker方式).md)** - -- **[搭建Ubuntu环境及编译(安装包方式)](搭建Ubuntu环境及编译(安装包方式).md)** - -- **[镜像烧录](镜像烧录.md)** - -- **[常见问题](常见问题-8.md)** - - diff --git "a/zh-cn/device-dev/quick-start/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\205\245\351\227\250.md" "b/zh-cn/device-dev/quick-start/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\205\245\351\227\250.md" deleted file mode 100644 index a5446960eb35cd7ad18fa426da226ea89ac6d2bf..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\205\245\351\227\250.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 轻量和小型系统入门 - -- **[概述](概述.md)** - -- **[了解开发板](了解开发板.md)** - -- **[搭建系统环境](搭建系统环境.md)** - -- **[开发步骤](开发步骤.md)** - - diff --git "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-5.md" "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-5.md" deleted file mode 100644 index 51873c97ac3662e15356d6350e6da77ed10fc7c0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-5.md" +++ /dev/null @@ -1,262 +0,0 @@ -# 运行Hello OHOS - -- [新建应用程序](#section1550972416485) -- [编译](#section234175193114) -- [烧录](#section7609155824819) -- [镜像运行](#section17612105814480) -- [下一步学习](#section9712145420182) - -本节指导开发者在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello OHOS!”。 - -## 新建应用程序 - -1. 新建目录及源码 - - 新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。 - - ``` - #include - - int main(int argc, char **argv) - { - printf("\n************************************************\n"); - printf("\n\t\tHello OHOS!\n"); - printf("\n************************************************\n\n"); - - return 0; - } - ``` - -2. 新建编译组织文件 - - 新建**applications/sample/camera/apps/BUILD.gn**文件,内容如下所示: - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("hello-OHOS") { - features = [ ":helloworld" ] - } - executable("helloworld") { - output_name = "helloworld" - sources = [ "src/helloworld.c" ] - include_dirs = [] - defines = [] - cflags_c = [] - ldflags = [] - } - ``` - -3. 添加新组件 - - 修改文件**build/lite/components/applications.json**,添加组件hello\_world\_app的配置,如下所示为applications.json文件片段,"\#\#start\#\#"和"\#\#end\#\#"之间为新增配置("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): - - ``` - { - "components": [ - { - "component": "camera_sample_communication", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/communication" - ], - "targets": [ - "//applications/sample/camera/communication:sample" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##start## - { - "component": "hello_world_app", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/apps" - ], - "targets": [ - "//applications/sample/camera/apps:hello-OHOS" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##end## - { - "component": "camera_sample_app", - "description": "Camera related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/launcher", - "applications/sample/camera/cameraApp", - "applications/sample/camera/setting", - "applications/sample/camera/gallery", - "applications/sample/camera/media" - ], - ``` - -4. 修改单板配置文件 - - 修改文件**vendor/hisilicon/hispark\_aries/config.json**,新增hello\_world\_app组件的条目,如下所示代码片段为applications子系统配置,"\#\#start\#\#"和"\#\#end\#\#"之间为新增条目("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): - - ``` - { - "subsystem": "applications", - "components": [ - ##start## - { "component": "hello_world_app", "features":[] }, - ##end## - { "component": "camera_sample_app", "features":[] } - - ] - }, - ``` - - -## 编译 - -如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/Docker编译环境.md)的编译操作。如果Linux编译环境通过软件包方式安装,进入源码根目录,执行如下命令进行编译: - -``` -hb set(设置编译路径) -.(选择当前路径) -选择ipcamera_hispark_aries@hisilicon并回车 -hb build -f(执行编译) -``` - -结果文件生成在out/hispark\_aries/ipcamera\_hispark\_aries目录下。 - -**图 1** 设置图例 -![](figures/设置图例-4.png "设置图例-4") - ->![](public_sys-resources/icon-notice.gif) **须知:** ->Hi3518EV300单板的U-boot文件获取路径:device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin - -## 烧录 - -Hi3518开发板的代码烧录仅支持USB烧录方式。 - -1. 请连接好电脑和待烧录开发板,以Hi3518EV300为例,需要同时连接串口和USB口,具体可参考[Hi3518开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3518-0000001105201138)。 -2. 打开电脑的设备管理器,查看并记录对应的串口号。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - - ![](figures/zh-cn_image_0000001128470900.png) - -3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - - ![](figures/zh-cn_image_0000001174350649.png) - -4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3518系列开发板进行适配,无需单独修改。 -5. 在“hi3518ev300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 - - - upload\_port:选择步骤[2](#zh-cn_topic_0000001057313128_li46411811196)中查询的串口号。 - - upload\_protocol:选择烧录协议,固定选择“hiburn-usb”。 - - upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。 - - ![](figures/zh-cn_image_0000001128311090.png) - -6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 -7. 打开工程文件,点击![](figures/2021-01-27_170334-5.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3518ev300\_fastboot下的**Erase**按钮,擦除U-Boot。 - - ![](figures/zh-cn_image_0000001174270731.png) - -8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(下电再上电)。 - - ![](figures/zh-cn_image_0000001128311092.png) - -9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。 - - ![](figures/zh-cn_image_0000001128311094.png) - -10. 擦除完成后,点击hi3518ev300下的**Upload**按钮,启动烧录。 - - ![](figures/zh-cn_image_0000001174350641.png) - -11. 启动烧录后,界面提示如下信息时,表示烧录成功。 - - ![](figures/zh-cn_image_0000001174350643.png) - - -## 镜像运行 - -1. 连接串口。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >若无法连接串口,请参考[常见问题](../quick-start/常见问题-6.md)进行排查。 - - **图 2** 连接串口图 - - - ![](figures/chuankou1-6.png) - - 1. 单击**Monitor**打开串口。 - 2. 连续输入回车直到串口显示"hisilicon"。 - 3. 单板初次启动或修改启动参数,请进入[步骤2](#li9441185382314),否则进入[步骤3](#li6442853122312)。 - -2. (初次烧写必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,可保存执行结果,但U-boot重新烧入,则需要再次执行下述步骤。 - - **表 1** U-boot修改命令 - - - - - - - - - - - - - - - - - - - - - - -

执行命令

-

命令解释

-

setenv bootcmd "sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000";

-

设置bootcmd内容,选择FLASH器件0,读取FLASH起始地址为0x100000,大小为0x600000字节的内容到0x40000000的内存地址,此处0x600000为6MB,与IDE中填写OHOS_Image.bin的文件大小必须相同

-

setenv bootargs "console=ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7M rootsize=8M";

-

表示设置bootargs参数为串口输出,波特率为115200,数据位8,rootfs挂载于FLASH上,文件系统类型为jffs2 rw,以支持可读写JFFS2文件系统。“rootaddr=7M rootsize=8M”处对应填入实际rootfs.img的烧写起始位置与长度,与IDE内所填大小必须相同

-

saveenv

-

表示保存当前配置。

-

reset

-

表示复位单板。

-

pri

-

表示查看显示参数。

-
- - >![](public_sys-resources/icon-notice.gif) **须知:** - >**“go 0x40000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。 - -3. 若启动时显示**"hisilicon \#**字样,请输入**“reset”**指令,等待系统自启动进入系统,系统启动后,显示**“OHOS”**字样,输入**”./bin/helloworld”**并回车,显示成功结果如下图所示。 - - **图 3** 启动成功并执行应用程序图 - ![](figures/启动成功并执行应用程序图.png "启动成功并执行应用程序图") - - -## 下一步学习 - -恭喜您,已完成Hi3518的快速上手!建议您下一步进入[无屏摄像头产品开发](../guide/摄像头控制.md)的学习 。 - diff --git "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS.md" "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS.md" deleted file mode 100755 index d5f775c64f385feec6cdc67c211ee5978397aca7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS.md" +++ /dev/null @@ -1,269 +0,0 @@ -# 运行Hello OHOS - -- [新建应用程序](#section204672145202) -- [编译](#section1077671315253) -- [烧录](#section1347011412201) -- [镜像运行](#section24721014162010) -- [执行应用程序](#section5276734182615) - -本节指导开发者在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello OHOS!”。 - -## 新建应用程序 - -1. 新建目录及源码 - - 新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。 - - ``` - #include - - int main(int argc, char **argv) - { - printf("\n************************************************\n"); - printf("\n\t\tHello OHOS!\n"); - printf("\n************************************************\n\n"); - - return 0; - } - ``` - -2. 新建编译组织文件 - - 新建**applications/sample/camera/apps/BUILD.gn**文件,内容如下所示: - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("hello-OHOS") { - features = [ ":helloworld" ] - } - executable("helloworld") { - output_name = "helloworld" - sources = [ "src/helloworld.c" ] - include_dirs = [] - defines = [] - cflags_c = [] - ldflags = [] - } - ``` - -3. 添加新组件 - - 修改文件**build/lite/components/applications.json**,添加组件hello\_world\_app的配置,如下所示为applications.json文件片段,"\#\#start\#\#"和"\#\#end\#\#"之间为新增配置("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): - - ``` - { - "components": [ - { - "component": "camera_sample_communication", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/communication" - ], - "targets": [ - "//applications/sample/camera/communication:sample" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##start## - { - "component": "hello_world_app", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/apps" - ], - "targets": [ - "//applications/sample/camera/apps:hello-OHOS" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##end## - { - "component": "camera_sample_app", - "description": "Camera related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/launcher", - "applications/sample/camera/cameraApp", - "applications/sample/camera/setting", - "applications/sample/camera/gallery", - "applications/sample/camera/media" - ], - ``` - -4. 修改单板配置文件 - - 修改文件**vendor/hisilicon/hispark\_taurus/config.json**,新增hello\_world\_app组件的条目,如下所示代码片段为applications子系统配置,"\#\#start\#\#"和"\#\#end\#\#"之间为新增条目("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): - - ``` - { - "subsystem": "applications", - "components": [ - { "component": "camera_sample_app", "features":[] }, - { "component": "camera_sample_ai", "features":[] }, - ##start## - { "component": "hello_world_app", "features":[] }, - ##end## - { "component": "camera_screensaver_app", "features":[] } - ] - }, - ``` - - -## 编译 - -如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/Docker编译环境.md)的编译操作。如果Linux编译环境通过软件包方式安装,请进入源码根目录,执行如下命令进行编译: - -``` -hb set(设置编译路径) -.(选择当前路径) -选择ipcamera_hispark_taurus@hisilicon并回车 -hb build -f(执行编译) -``` - -**图 1** 设置图例 -![](figures/设置图例.png "设置图例") - -结果文件生成在out/hispark\_taurus/ipcamera\_hispark\_taurus目录下。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->Hi3516DV300单板的U-boot文件获取路径:device/hisilicon/hispark\_taurus/sdk\_liteos/uboot/out/boot/u-boot-hi3516dv300.bin - -## 烧录 - -Hi3516开发板的代码烧录支持USB烧录、网口烧录和串口烧录三种方式。此处仅以网口烧录为例进行说明。 - -1. 请连接好电脑和待烧录开发板,以Hi3516DV300为例,需要同时连接串口、网口和电源,具体可参考[Hi3516开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3516-0000001152041033)。 -2. 打开电脑的设备管理器,查看并记录对应的串口号。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - - ![](figures/zh-cn_image_0000001174350647.png) - -3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - - ![](figures/2021-01-27_170334.png) - -4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3516系列开发板进行适配,无需单独修改。 -5. 在“hi3516dv300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 - - - upload\_port:选择步骤[2](#zh-cn_topic_0000001056443961_li142386399535)中查询的串口号。 - - upload\_protocol:选择烧录协议,固定选择“hiburn-net”。 - - upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。 - - ![](figures/zh-cn_image_0000001128470904.png) - -6. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/ide/user-guides/set_ipaddress-0000001141825075)。 -7. 设置网口烧录的IP地址信息,设置如下选项: - - - upload\_net\_server\_ip:选择[6](#zh-cn_topic_0000001056443961_li1558813168234)中设置的IP地址信息。例如192.168.1.2 - - upload\_net\_client\_mask:设置开发板的子网掩码,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如255.255.255.0 - - upload\_net\_client\_gw:设置开发板的网关,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.1 - - upload\_net\_client\_ip:设置开发板的IP地址,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.3 - - ![](figures/zh-cn_image_0000001174270733.png) - -8. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 -9. 打开工程文件,点击![](figures/2021-01-27_170334-2.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3516dv300下的**Upload**按钮,启动烧录。 - - ![](figures/zh-cn_image_0000001174270729.png) - -10. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。 - - ![](figures/zh-cn_image_0000001128470906.png) - -11. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 - - ![](figures/zh-cn_image_0000001128311098.png) - - -## 镜像运行 - -1. 连接串口。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >若无法连接串口,请参考[常见问题](../quick-start/常见问题-3.md)进行排查。 - - **图 2** 连接串口图 - - - ![](figures/chuankou1.png) - - 1. 单击**Monitor**打开串口。 - 2. 连续输入回车直到串口显示"hisilicon"。 - 3. 单板初次启动或修改启动参数,请进入[步骤2](#l5b42e79a33ea4d35982b78a22913b0b1),否则进入[步骤3](#ld26f18828aa44c36bfa36be150e60e49)。 - -2. (单板初次启动必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,若不修改参数只需执行一次。每次复位单板均会自动进入系统。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >U-boot引导程序默认会有2秒的等待时间,用户可使用回车打断等待并显示"hisilicon",通过**reset**命令可再次启动系统。 - - **表 1** U-boot修改命令 - - - - - - - - - - - - - - - - - - - -

执行命令

-

命令解释

-

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

-

读取FLASH起始地址为0x800(单位为512B,即1MB),大小为0x4800(单位为512B,即9MB)的内容到0x80000000的内存地址,该大小(9MB)与IDE中所填写OHOS_Image.bin文件大小必须相同

-

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

-

表示设置启动参数,输出模式为串口输出,波特率为115200,数据位8,rootfs挂载于emmc器件,文件系统类型为vfat,

-

“rootaddr=10M rootsize=20M rw”处对应填入rootfs.img的烧写起始位置与长度,此处与IDE中新增rootfs.img文件时所填大小必须相同

-

saveenv

-

表示保存当前配置。

-

reset

-

表示复位单板。

-
- - >![](public_sys-resources/icon-notice.gif) **须知:** - >**“go 0x80000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。 - -3. 输入**“reset”**指令并回车,重启单板,启动成功如下图,输入回车串口显示OHOS字样。 - - **图 3** 系统启动图 - - - ![](figures/qi1.png) - - -## 执行应用程序 - -根目录下,在命令行输入指令“**./bin/helloworld**”执行写入的demo程序,显示成功结果如下图所示。 - -**图 4** 启动并成功执行应用程序图 -![](figures/启动并成功执行应用程序图.png "启动并成功执行应用程序图") - diff --git "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-World.md" "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-World.md" deleted file mode 100755 index f428ec411ee4fc51d1be00be263867d1f8f8dc74..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-World.md" +++ /dev/null @@ -1,158 +0,0 @@ -# 运行Hello World - -- [修改源码](#section79601457101015) -- [调测验证](#section1621064881419) -- [printf打印](#section1246911301217) -- [根据asm文件进行问题定位](#section199621957141014) -- [运行结果](#section18115713118) -- [下一步学习](#section9712145420182) - -本示例将演示如何编写简单业务,输出“Hello World”,初步了解OpenHarmony 如何运行在开发板上。 - -## 修改源码 - -bugfix和新增业务两种情况,涉及源码修改。下面以新增业务(my\_first\_app)为例,向开发者介绍如何进行源码修改。 - -1. 确定目录结构。 - - 开发者编写业务时,务必先在./applications/sample/wifi-iot/app路径下新建一个目录(或一套目录结构),用于存放业务源码文件。 - - 例如:在app下新增业务my\_first\_app,其中hello\_world.c为业务代码,BUILD.gn为编译脚本,具体规划目录结构如下: - - ``` - . - └── applications - └── sample - └── wifi-iot - └── app - │── my_first_app - │ │── hello_world.c - │ └── BUILD.gn - └── BUILD.gn - ``` - -2. 编写业务代码。 - - 新建./applications/sample/wifi-iot/app/my\_first\_app下的hello\_world.c文件,在hello\_world.c中新建业务入口函数HelloWorld,并实现业务逻辑。并在代码最下方,使用OpenHarmony启动恢复模块接口SYS\_RUN\(\)启动业务。(SYS\_RUN定义在ohos\_init.h文件中) - - ``` - #include - #include "ohos_init.h" - #include "ohos_types.h" - - void HelloWorld(void) - { - printf("[DEMO] Hello world.\n"); - } - SYS_RUN(HelloWorld); - ``` - -3. 编写用于将业务构建成静态库的BUILD.gn文件。 - - 新建./applications/sample/wifi-iot/app/my\_first\_app下的BUILD.gn文件,并完成如下配置。 - - 如[步骤1](#li5479332115116)所述,BUILD.gn文件由三部分内容(目标、源文件、头文件路径)构成,需由开发者完成填写。 - - ``` - static_library("myapp") { - sources = [ - "hello_world.c" - ] - include_dirs = [ - "//utils/native/lite/include" - ] - } - ``` - - - static\_library中指定业务模块的编译结果,为静态库文件libmyapp.a,开发者根据实际情况完成填写。 - - sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。 - - include\_dirs中指定source所需要依赖的.h文件路径。 - -4. 编写模块BUILD.gn文件,指定需参与构建的特性模块。 - - 配置./applications/sample/wifi-iot/app/BUILD.gn文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,以my\_first\_app举例,features字段配置如下。 - - ``` - import("//build/lite/config/component/lite_component.gni") - - lite_component("app") { - features = [ - "my_first_app:myapp", - ] - } - ``` - - - my\_first\_app是相对路径,指向./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn。 - - myapp是目标,指向./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn中的static\_library\("myapp"\)。 - - -## 调测验证 - -目前调试验证的方法有两种,分别为通过printf打印日志、通过asm文件定位panic问题,开发者可以根据具体业务情况选择。 - -由于本示例业务简单,采用printf打印日志的调试方式即可。下面开始介绍这两种调试手段的使用方法。 - -## printf打印 - -代码中增加printf维测,信息会直接打印到串口上。开发者可在业务关键路径或业务异常位置增加日志打印,如下所示。 - -``` -void HelloWorld(void) -{ - printf("[DEMO] Hello world.\n"); -} -``` - -## 根据asm文件进行问题定位 - -系统异常退出时,会在串口上打印异常退出原因调用栈信息,如下文所示。通过解析异常栈信息可以定位异常位置。 - -``` -=======KERNEL PANIC======= -**********************Call Stack********************* -Call Stack 0 -- 4860d8 addr:f784c -Call Stack 1 -- 47b2b2 addr:f788c -Call Stack 2 -- 3e562c addr:f789c -Call Stack 3 -- 4101de addr:f78ac -Call Stack 4 -- 3e5f32 addr:f78cc -Call Stack 5 -- 3f78c0 addr:f78ec -Call Stack 6 -- 3f5e24 addr:f78fc -********************Call Stack end******************* -``` - -为解析上述调用栈信息,需要使用到Hi3861\_wifiiot\_app.asm文件,该文件记录了代码中函数在Flash上的符号地址以及反汇编信息。asm文件会随版本大包一同构建输出,存放在./out/wifiiot/路径下。 - -1. 将调用栈CallStack信息保存到txt文档中,以便于编辑。(可选) -2. 打开asm文件,并搜索CallStack中的地址,列出对应的函数名 信息。通常只需找出前几个栈信息对应的函数,就可明确异常代码方向。 - - ``` - Call Stack 0 -- 4860d8 addr:f784c -- WadRecvCB - Call Stack 1 -- 47b2b2 addr:f788c -- wal_sdp_process_rx_data - Call Stack 2 -- 3e562c addr:f789c - Call Stack 3 -- 4101de addr:f78ac - Call Stack 4 -- 3e5f32 addr:f78cc - Call Stack 5 -- 3f78c0 addr:f78ec - Call Stack 6 -- 3f5e24 addr:f78fc - ``` - -3. 根据以上调用栈信息,可以定位WadRecvCB函数中出现了异常。 - - ![](figures/zh-cn_image_0000001174270737.png) - -4. 完成代码排查及修改。 - -## 运行结果 - -示例代码编译、烧录、运行、调测后,在串口界面会显示如下结果: - -``` -ready to OS start -FileSystem mount ok. -wifi init success! -[DEMO] Hello world. -``` - -## 下一步学习 - -恭喜,您已完成Hi3861 WLAN模组快速上手!建议您下一步进入[WLAN产品开发](../guide/概述.md)的学习 。 - diff --git "a/zh-cn/device-dev/quick-start/\351\225\234\345\203\217\347\203\247\345\275\225.md" "b/zh-cn/device-dev/quick-start/\351\225\234\345\203\217\347\203\247\345\275\225.md" deleted file mode 100644 index 3fca75cfcd0691990f88acac3e1f32ac98528a08..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\351\225\234\345\203\217\347\203\247\345\275\225.md" +++ /dev/null @@ -1,201 +0,0 @@ -# 镜像烧录 - -- [下一步](#section5600113114323) - -标准系统烧录,在V2.2 Beta1及以上版本支持。 - -Hi3516DV300支持烧录标准系统,其烧录方式包括网口烧录和串口烧录三种方式,其中: - -- **Windows系统:支持网口烧录和串口烧录** -- **Linux系统:支持串口烧录和网口烧录。** - -同一种烧录方式(如网口烧录),在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前Hi3516DV300开发板支持通过网口、USB、串口三种方式烧录OpenHarmony标准系统。本文以网口方式为例讲解烧录操作,其他两种烧录方式请参照[Hi3516DV300烧录指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)。 - -### 前提条件 - -在DevEco Device Tool中[打开一个工程](https://device.harmonyos.com/cn/docs/ide/user-guides/open_project-0000001071680043),该工程文件夹选择待烧录文件所在文件夹即可。其中开发板类型固定选择Hi3516DV300,Framework选择“Hb”。 - -### 使用网口烧录 - -Hi3516DV300开发板使用网口录方式,支持Windows和Linux系统。 - -1. 请连接好电脑和待烧录开发板,需要同时连接串口、网口和电源,具体可参考[Hi3516DV300开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3516-0000001152041033)。 -2. 打开电脑的设备管理器,查看并记录对应的串口号。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - - ![](figures/zh-cn_image_0000001114129428.png) - -3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - - ![](figures/2021-01-27_170334-17.png) - -4. 在**Partition Configuration**页签中,按照下表内容填写烧录文件信息,包括: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Binary

-

Memory

-

System

-

Address

-

Length

-

Board

-

Type

-

fastboot

-

选择“u-boot-hi3516dv300_emmc.bin”

-

emmc

-

none

-

0x000000

-

0x100000

-

固定选择“hi3516dv300”

-

NA

-

boot

-

选择“uImage”

-

emmc

-

none

-

0x100000

-

0xf00000

-

NA

-

updater

-

选择“updater.img”

-

emmc

-

ext3/4

-

0x1000000

-

0x1400000

-

NA

-

misc

-

空白,不用选择

-

emmc

-

none

-

0x2400000

-

0x100000

-

NA

-

system

-

选择“system.img”

-

emmc

-

ext3/4

-

0x2500000

-

0xceb00000

-

NA

-

vendor

-

选择“vendor.img”

-

emmc

-

ext3/4

-

0xd1000000

-

0x10000000

-

NA

-

userdata

-

选择“userdata.img”

-

emmc

-

ext3/4

-

0xe1000000

-

0x5b800000

-

NA

-
- - ![](figures/zh-cn_image_0000001130584312.png) - -5. 在“hi3516dv300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 - - - upload\_port:选择步骤[2](#zh-cn_topic_0000001056443961_li1050616379507)中查询的串口号。 - - upload\_protocol:选择烧录协议,固定选择“hiburn-net”。 - - upload\_partitions:选择待烧录的文件,包括fastboot、boot、updater、misc、system、vendor和userdata。 - - ![](figures/zh-cn_image_0000001117621400.png) - -6. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516DV300网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/ide/user-guides/set_ipaddress-0000001141825075)。 -7. 设置网口烧录的IP地址信息,设置如下选项: - - - upload\_net\_server\_ip:选择步骤6中设置的IP地址信息。例如192.168.1.2 - - upload\_net\_client\_mask:设置开发板的子网掩码,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如255.255.255.0 - - upload\_net\_client\_gw:设置开发板的网关,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.1 - - upload\_net\_client\_ip:设置开发板的IP地址,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.3 - - ![](figures/zh-cn_image_0000001117463460.png) - -8. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 -9. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。 - - ![](figures/zh-cn_image_0000001114129432.png) - -10. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 - - ![](figures/zh-cn_image_0000001113969542.png) - - -## 下一步 - -恭喜!您已经完成了OpenHarmony标准系统的快速入门,接下来可[开发一个小示例](../guide/时钟应用开发示例.md),进一步熟悉OpenHarmony的开发。 - diff --git "a/zh-cn/device-dev/quick-start/\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/quick-start/\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100755 index f9eb065a5d8f0b372e670919a8ed6b89681dbb90..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,503 +0,0 @@ -# 驱动开发示例 - -- [驱动程序介绍](#s8efc1952ebfe4d1ea717182e108c29bb) -- [编译和烧写](#section660016185110) -- [镜像运行](#section333215226219) -- [下一步学习](#section9712145420182) - -本节指导开发者在单板上运行第一个驱动程序,其中包括驱动程序介绍、编译、烧写、运行等步骤。 - -## 驱动程序介绍 - -下面基于HDF框架,提供一个简单的UART(Universal Asynchronous Receiver/Transmitter)平台驱动开发样例,包含配置文件的添加,驱动代码的实现以及用户态程序和驱动交互的流程。驱动程序源码位于vendor/huawei/hdf/sample目录 - -1. 添加配置。 - - 在HDF框架的驱动配置文件(例如device/hisilicon/hi3516dv300/sdk\_liteos/config/uart/uart\_config.hcs)中添加该驱动的配置信息,如下所示: - - ``` - root { - platform { - uart_sample { - num = 5; // UART设备编号 - base = 0x120a0000; // UART 寄存器基地址 - irqNum = 38; - baudrate = 115200; - uartClk = 24000000; - wlen = 0x60; - parity = 0; - stopBit = 0; - match_attr = "sample_uart_5"; - } - } - } - ``` - - 在HDF框架的设备配置文件(例如vendor/hisilicon/ipcamera\_hi3516dv300\_liteos/config/device\_info/device\_info.hcs)中添加该驱动的设备节点信息,如下所示: - - ``` - root { - device_info { - platform :: host { - hostName = "platform_host"; - priority = 50; - device_uart :: device { - device5 :: deviceNode { - policy = 2; - priority = 10; - permission = 0660; - moduleName = "UART_SAMPLE"; - serviceName = "HDF_PLATFORM_UART_5"; - deviceMatchAttr = "sample_uart_5"; - } - } - } - } - } - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >配置文件与UART驱动示例的源码在同一个路径,需要手动添加到Hi3516DV300单板路径下。 - -2. 注册UART驱动入口。 - - 基于HDF框架注册UART驱动的入口HdfDriverEntry,代码如下: - - ``` - // 绑定UART驱动接口到HDF框架 - static int32_t SampleUartDriverBind(struct HdfDeviceObject *device) - { - struct UartHost *uartHost = NULL; - - if (device == NULL) { - return HDF_ERR_INVALID_OBJECT; - } - HDF_LOGI("Enter %s:", __func__); - - uartHost = UartHostCreate(device); - if (uartHost == NULL) { - HDF_LOGE("%s: UartHostCreate failed", __func__); - return HDF_FAILURE; - } - uartHost->service.Dispatch = SampleDispatch; - return HDF_SUCCESS; - } - - // 从UART驱动的HCS中获取配置信息 - static uint32_t GetUartDeviceResource( - struct UartDevice *device, const struct DeviceResourceNode *resourceNode) - { - struct UartResource *resource = &device->resource; - struct DeviceResourceIface *dri = NULL; - dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (dri == NULL || dri->GetUint32 == NULL) { - HDF_LOGE("DeviceResourceIface is invalid"); - return HDF_FAILURE; - } - - if (dri->GetUint32(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read num fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "base", &resource->base, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read base fail"); - return HDF_FAILURE; - } - resource->physBase = (unsigned long)OsalIoRemap(resource->base, 0x48); - if (resource->physBase == 0) { - HDF_LOGE("uart config fail to remap physBase"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "irqNum", &resource->irqNum, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read irqNum fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "baudrate", &resource->baudrate, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read baudrate fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "wlen", &resource->wlen, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read wlen fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "parity", &resource->parity, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read parity fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "stopBit", &resource->stopBit, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read stopBit fail"); - return HDF_FAILURE; - } - if (dri->GetUint32(resourceNode, "uartClk", &resource->uartClk, 0) != HDF_SUCCESS) { - HDF_LOGE("uart config read uartClk fail"); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - - // 将UART驱动的配置和接口附加到HDF驱动框架 - static int32_t AttachUartDevice(struct UartHost *host, struct HdfDeviceObject *device) - { - int32_t ret; - struct UartDevice *uartDevice = NULL; - if (device->property == NULL) { - HDF_LOGE("%s: property is NULL", __func__); - return HDF_FAILURE; - } - uartDevice = (struct UartDevice *)OsalMemCalloc(sizeof(struct UartDevice)); - if (uartDevice == NULL) { - HDF_LOGE("%s: OsalMemCalloc uartDevice error", __func__); - return HDF_ERR_MALLOC_FAIL; - } - ret = GetUartDeviceResource(uartDevice, device->property); - if (ret != HDF_SUCCESS) { - (void)OsalMemFree(uartDevice); - return HDF_FAILURE; - } - host->num = uartDevice->resource.num; - host->priv = uartDevice; - AddUartDevice(host); - return InitUartDevice(uartDevice); - } - - // 初始化UART驱动 - static int32_t SampleUartDriverInit(struct HdfDeviceObject *device) - { - int32_t ret; - struct UartHost *host = NULL; - - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_OBJECT; - } - HDF_LOGI("Enter %s:", __func__); - host = UartHostFromDevice(device); - if (host == NULL) { - HDF_LOGE("%s: host is NULL", __func__); - return HDF_FAILURE; - } - ret = AttachUartDevice(host, device); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: attach error", __func__); - return HDF_FAILURE; - } - host->method = &g_sampleUartHostMethod; - return ret; - } - - static void DeinitUartDevice(struct UartDevice *device) - { - struct UartRegisterMap *regMap = (struct UartRegisterMap *)device->resource.physBase; - /* wait for uart enter idle. */ - while (UartPl011IsBusy(regMap)); - UartPl011ResetRegisters(regMap); - uart_clk_cfg(0, false); - OsalIoUnmap((void *)device->resource.physBase); - device->state = UART_DEVICE_UNINITIALIZED; - } - - // 解绑并释放UART驱动 - static void DetachUartDevice(struct UartHost *host) - { - struct UartDevice *uartDevice = NULL; - - if (host->priv == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return; - } - uartDevice = host->priv; - DeinitUartDevice(uartDevice); - (void)OsalMemFree(uartDevice); - host->priv = NULL; - } - - // 释放UART驱动 - static void SampleUartDriverRelease(struct HdfDeviceObject *device) - { - struct UartHost *host = NULL; - HDF_LOGI("Enter %s:", __func__); - - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return; - } - host = UartHostFromDevice(device); - if (host == NULL) { - HDF_LOGE("%s: host is NULL", __func__); - return; - } - if (host->priv != NULL) { - DetachUartDevice(host); - } - UartHostDestroy(host); - } - - struct HdfDriverEntry g_sampleUartDriverEntry = { - .moduleVersion = 1, - .moduleName = "UART_SAMPLE", - .Bind = SampleUartDriverBind, - .Init = SampleUartDriverInit, - .Release = SampleUartDriverRelease, - }; - - HDF_INIT(g_sampleUartDriverEntry); - ``` - -3. 注册UART驱动接口。 - - HDF框架提供了UART驱动接口的模板方法UartHostMethod,实现UART驱动接口的代码如下: - - ``` - static int32_t SampleUartHostInit(struct UartHost *host) - { - HDF_LOGI("%s: Enter", __func__); - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - return HDF_SUCCESS; - } - - static int32_t SampleUartHostDeinit(struct UartHost *host) - { - HDF_LOGI("%s: Enter", __func__); - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - return HDF_SUCCESS; - } - - // 向UART中写入数据 - static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size) - { - HDF_LOGI("%s: Enter", __func__); - uint32_t idx; - struct UartRegisterMap *regMap = NULL; - struct UartDevice *device = NULL; - - if (host == NULL || data == NULL || size == 0) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - device = (struct UartDevice *)host->priv; - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_PARAM; - } - regMap = (struct UartRegisterMap *)device->resource.physBase; - for (idx = 0; idx < size; idx++) { - UartPl011Write(regMap, data[idx]); - } - return HDF_SUCCESS; - } - - // 设置UART的波特率 - static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate) - { - HDF_LOGI("%s: Enter", __func__); - struct UartDevice *device = NULL; - struct UartRegisterMap *regMap = NULL; - UartPl011Error err; - - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - device = (struct UartDevice *)host->priv; - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_PARAM; - } - regMap = (struct UartRegisterMap *)device->resource.physBase; - if (device->state != UART_DEVICE_INITIALIZED) { - return UART_PL011_ERR_NOT_INIT; - } - if (baudRate == 0) { - return UART_PL011_ERR_INVALID_BAUD; - } - err = UartPl011SetBaudrate(regMap, device->uartClk, baudRate); - if (err == UART_PL011_ERR_NONE) { - device->baudrate = baudRate; - } - return err; - } - - // 获取UART的波特率 - static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate) - { - HDF_LOGI("%s: Enter", __func__); - struct UartDevice *device = NULL; - - if (host == NULL) { - HDF_LOGE("%s: invalid parameter", __func__); - return HDF_ERR_INVALID_PARAM; - } - device = (struct UartDevice *)host->priv; - if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); - return HDF_ERR_INVALID_PARAM; - } - *baudRate = device->baudrate; - return HDF_SUCCESS; - } - - // 在HdfUartSampleInit方法中绑定 - struct UartHostMethod g_sampleUartHostMethod = { - .Init = SampleUartHostInit, - .Deinit = SampleUartHostDeinit, - .Read = NULL, - .Write = SampleUartHostWrite, - .SetBaud = SampleUartHostSetBaud, - .GetBaud = SampleUartHostGetBaud, - .SetAttribute = NULL, - .GetAttribute = NULL, - .SetTransMode = NULL, - }; - ``` - - 在device/hisilicon/drivers/lite.mk编译脚本中增加示例UART驱动模块,代码如下: - - ``` - LITEOS_BASELIB += -lhdf_uart_sample - LIB_SUBDIRS += $(LITEOS_SOURCE_ROOT)/vendor/huawei/hdf/sample/platform/uart - ``` - -4. 用户程序和驱动交互代码。 - - UART驱动成功初始化后,会创建/dev/uartdev-5设备节点,通过设备节点与UART驱动交互的代码如下: - - ``` - #include - #include - #include - #include "hdf_log.h" - - #define HDF_LOG_TAG "hello_uart" - #define INFO_SIZE 16 - - int main(void) - { - int ret; - int fd; - const char info[INFO_SIZE] = {" HELLO UART! "}; - - fd = open("/dev/uartdev-5", O_RDWR); - if (fd < 0) { - HDF_LOGE("hello_uart uartdev-5 open failed %d", fd); - return -1; - } - ret = write(fd, info, INFO_SIZE); - if (ret != 0) { - HDF_LOGE("hello_uart write uartdev-5 ret is %d", ret); - } - ret = close(fd); - if (ret != 0) { - HDF_LOGE("hello_uart uartdev-5 close failed %d", fd); - return -1; - } - return ret; - } - ``` - - 在build/lite/components/drivers.json驱动配置中hdf\_hi3516dv300\_liteos\_a组件下的targets中增加hello\_uart\_sample组件,代码如下: - - ``` - { - "components": [ - { - "component": "hdf_hi3516dv300_liteos_a", - ... - "targets": [ - "//vendor/huawei/hdf/sample/platform/uart:hello_uart_sample" - ] - } - ] - } - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >如上代码均为示例代码,完整代码可以在vendor/huawei/hdf/sample查看。 - >示例代码默认不参与编译,需要手动添加到编译脚本中。 - - -## 编译和烧写 - -参考示例1进行编译和烧写:[编译](../quick-start/驱动开发示例.md)、[烧录](../quick-start/驱动开发示例.md) - -## 镜像运行 - -1. 连接串口。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >若无法连接串口,请参考[常见问题](../quick-start/常见问题-3.md)进行排查。 - - **图 1** 连接串口图 - - - ![](figures/chuankou1.png) - - 1. 单击**Monitor**打开串口。 - 2. 连续输入回车直到串口显示"hisilicon"。 - 3. 单板初次启动或修改启动参数,请进入[步骤2](运行Hello-OHOS.md#l5b42e79a33ea4d35982b78a22913b0b1),否则进入[步骤3](运行Hello-OHOS.md#ld26f18828aa44c36bfa36be150e60e49)。 - -2. (单板初次启动必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,若不修改参数只需执行一次。每次复位单板均会自动进入系统。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >U-boot引导程序默认会有2秒的等待时间,用户可使用回车打断等待并显示"hisilicon",通过**reset**命令可再次启动系统。 - - **表 1** U-boot修改命令 - - - - - - - - - - - - - - - - - - - -

执行命令

-

命令解释

-

setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";

-

读取FLASH起始地址为0x800(单位为512B,即1MB),大小为0x4800(单位为512B,即9MB)的内容到0x80000000的内存地址,该大小(9MB)与IDE中所填写OHOS_Image.bin文件大小必须相同

-

setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";

-

表示设置启动参数,输出模式为串口输出,波特率为115200,数据位8,rootfs挂载于emmc器件,文件系统类型为vfat,

-

“rootaddr=10M rootsize=20M rw”处对应填入rootfs.img的烧写起始位置与长度,此处与IDE中新增rootfs.img文件时所填大小必须相同

-

saveenv

-

表示保存当前配置。

-

reset

-

表示复位单板。

-
- - >![](public_sys-resources/icon-notice.gif) **须知:** - >**“go 0x80000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。 - -3. 输入**“reset”**指令并回车,重启单板,启动成功如下图,输入回车串口显示OHOS字样。 - - **图 2** 系统启动图 - - - ![](figures/qi1.png) - -4. 根目录下,在命令行输入指令“**./bin/hello\_uart**”执行写入的demo程序,显示成功结果如下所示。 - - ``` - OHOS # ./bin/hello_uart - OHOS # HELLO UART! - ``` - - -## 下一步学习 - -恭喜,您已完成Hi3516 快速上手!建议您下一步进入[带屏摄像头产品开发](../guide/屏幕和摄像头控制.md)的学习 。 - diff --git a/zh-cn/device-dev/security/Readme-CN.md b/zh-cn/device-dev/security/Readme-CN.md index 3eb2062d716d8d4d3765ae11edcfd8bb3d8bad27..9a8e221f7fe6561d044900efa29dfec7d0d82af0 100755 --- a/zh-cn/device-dev/security/Readme-CN.md +++ b/zh-cn/device-dev/security/Readme-CN.md @@ -1,5 +1,5 @@ # 隐私与安全 -- [隐私保护](隐私保护.md) -- [安全指南](安全指南.md) +- [隐私保护](safety-protection-privacyguide.md) +- [安全指南](safety-safeguide-security.md) diff --git "a/zh-cn/device-dev/security/figures/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" "b/zh-cn/device-dev/security/figure/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" rename to "zh-cn/device-dev/security/figure/1-\346\225\217\346\204\237\346\235\203\351\231\220\345\274\271\347\252\227.png" diff --git "a/zh-cn/device-dev/security/figures/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" "b/zh-cn/device-dev/security/figure/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" rename to "zh-cn/device-dev/security/figure/2-\345\272\224\347\224\250\345\220\257\345\212\250\351\242\204\346\216\210\346\235\203.png" diff --git "a/zh-cn/device-dev/security/figures/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" "b/zh-cn/device-dev/security/figure/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" rename to "zh-cn/device-dev/security/figure/3-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216.png" diff --git "a/zh-cn/device-dev/security/figures/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" "b/zh-cn/device-dev/security/figure/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" rename to "zh-cn/device-dev/security/figure/4-\351\232\220\347\247\201\345\243\260\346\230\216\345\217\230\346\233\264\351\200\232\347\237\245.png" diff --git "a/zh-cn/device-dev/security/figures/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" "b/zh-cn/device-dev/security/figure/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" rename to "zh-cn/device-dev/security/figure/5-\345\272\224\347\224\250\351\232\220\347\247\201\345\243\260\346\230\216\345\205\245\345\217\243.png" diff --git "a/zh-cn/device-dev/security/figures/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" "b/zh-cn/device-dev/security/figure/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" rename to "zh-cn/device-dev/security/figure/6-1-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" diff --git "a/zh-cn/device-dev/security/figures/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" "b/zh-cn/device-dev/security/figure/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" rename to "zh-cn/device-dev/security/figure/6-2-\351\232\220\347\247\201\345\243\260\346\230\216\346\222\244\351\224\200.png" diff --git "a/zh-cn/device-dev/security/figures/DAC\346\265\201\347\250\213\345\233\276.png" "b/zh-cn/device-dev/security/figure/DAC\346\265\201\347\250\213\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/DAC\346\265\201\347\250\213\345\233\276.png" rename to "zh-cn/device-dev/security/figure/DAC\346\265\201\347\250\213\345\233\276.png" diff --git "a/zh-cn/device-dev/security/figures/HUKS\345\212\237\350\203\275\347\273\223\346\236\204\345\233\276.png" "b/zh-cn/device-dev/security/figure/HUKS\345\212\237\350\203\275\347\273\223\346\236\204\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/HUKS\345\212\237\350\203\275\347\273\223\346\236\204\345\233\276.png" rename to "zh-cn/device-dev/security/figure/HUKS\345\212\237\350\203\275\347\273\223\346\236\204\345\233\276.png" diff --git "a/zh-cn/device-dev/security/figures/\345\256\211\345\205\250\344\277\235\351\232\234\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/security/figure/\345\256\211\345\205\250\344\277\235\351\232\234\347\244\272\346\204\217\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/\345\256\211\345\205\250\344\277\235\351\232\234\347\244\272\346\204\217\345\233\276.png" rename to "zh-cn/device-dev/security/figure/\345\256\211\345\205\250\344\277\235\351\232\234\347\244\272\346\204\217\345\233\276.png" diff --git "a/zh-cn/device-dev/security/figures/\350\256\276\345\244\207\351\227\264\345\273\272\347\253\213\345\217\257\344\277\241\345\205\263\347\263\273\346\265\201\347\250\213\345\233\276.png" "b/zh-cn/device-dev/security/figure/\350\256\276\345\244\207\351\227\264\345\273\272\347\253\213\345\217\257\344\277\241\345\205\263\347\263\273\346\265\201\347\250\213\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/security/figures/\350\256\276\345\244\207\351\227\264\345\273\272\347\253\213\345\217\257\344\277\241\345\205\263\347\263\273\346\265\201\347\250\213\345\233\276.png" rename to "zh-cn/device-dev/security/figure/\350\256\276\345\244\207\351\227\264\345\273\272\347\253\213\345\217\257\344\277\241\345\205\263\347\263\273\346\265\201\347\250\213\345\233\276.png" diff --git a/zh-cn/device-dev/security/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/security/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/security/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/security/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/security/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/security/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/security/public_sys-resources/icon-note.gif b/zh-cn/device-dev/security/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/security/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/security/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/security/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/security/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/security/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/security/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/security/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/security/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/security/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/security/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/zh-cn/device-dev/security/safety-protection-privacyguide.md b/zh-cn/device-dev/security/safety-protection-privacyguide.md new file mode 100644 index 0000000000000000000000000000000000000000..95e5eccca8ac113c4ac92f908bb5701109b0e842 --- /dev/null +++ b/zh-cn/device-dev/security/safety-protection-privacyguide.md @@ -0,0 +1,264 @@ +# 隐私保护 + +- [隐私保护概述](#section13200134331414) +- [数据分类分级](#section2371104991511) +- [通用隐私设计规则](#section10354102411162) +- [特殊品类要求](#section118861450201618) + +## 隐私保护概述 + +随着互联网及信息化的发展,个人数据在社会经济和日常生活中发挥着越来越重要的作用。与此同时,个人数据泄露的风险也在增加,消费者产品开发者需要更加有效的保护用户的个人数据,提高用户对产品的信任度。为了提升消费者的隐私体验,产品应默认设置较高级别隐私保护策略,达到保护消费者隐私的目的。 + +**基本概念** + +- **个人数据(Personal Data)** + + 与一个身份已被识别或者身份可被识别的自然人(“数据主体”)相关的任何信息;身份可识别的自然人是指其身份可以通过诸如姓名、身份证号、位置数据等识别码或者通过一个或多个与自然人的身体、生理、精神、经济、文化或者社会身份相关的特定因素来直接或者间接地被识别。个人数据包括:自然人的email地址、电话号码、生物特征(指纹)、位置数据、IP地址、医疗信息、宗教信仰、社保号、婚姻状态等。 + +- **敏感个人数据(Sensitive Personal Data)** + + 敏感个人数据是个人数据的一个重要子集,指的是涉及数据主体的最私密领域的信息或者一旦泄露可能会给数据主体造成重大不利影响的数据。欧盟等国家和地区法律定义的敏感个人数据包括种族、政治观点、宗教和哲学信仰、工会成员资格、基因数据、生物信息、健康和性生活状况、性取向等。 + + 根据业界最佳实践,敏感个人数据还包括可与自然人身份相关联的银行卡号、身份证号、护照号、口令等。敏感个人数据的处理需要更多更严格的保护措施。 + +- **公开个人数据(Public available Personal Data)** + + 数据主体主动公开的个人数据,或公开网页/应用上可访问的个人数据,包括论坛公开的发帖、评论等。 + +- **用户画像(User Profile)** + + 指对个人数据采取的任何自动化处理的方式,包括评估某个自然人特定方面的情况,尤其是为了分析和预测该自然人的工作表现、经济状况、健康、个人喜好、兴趣、可信度、行为举止、所在位置或行迹。 + +- **数据控制者(Data Controller)** + + 单独或者与他人共同确定个人数据处理的目的和手段的自然人、法人、公共机构、政府部门或其他机构。 + +- **数据处理者(Data Processor)** + + 指代表数据控制者处理个人数据的自然人、法人、公共机构、政府部门或其他机构。数据处理者必须按照数据控制者的要求对个人数据进行充分的保护。 + +- **明示同意(Explicit consent)** + + 如下几种情形GDPR法律提到可以通过数据主体明示同意的方式合法地处理数据: + + - 处理敏感个人数据。 + - 自动化决策,包括进行用户画像。 + - 向不具备充分保护水平的国家转移个人数据,并以同意作为合法性基础。 + + 实现明示同意的方式有: + + - 在收集特定数据时,弹出隐私声明告知个人数据处理相关事项,提供勾选框但不默认勾选,让数据主体勾选“我同意以上述方式处理我的个人数据”,或提供“我同意”的按钮让用户主动点击。 + - 以书面的方式明确表达同意,数据主体在书面陈述上签字。 + - 要求数据主体在系统中上传带有其签名的电子表格。 + - 采取双重验证的方式,要求数据主体邮件形式回复同意后,再次点击用于验证的邮件链接或是输入SMS验证码。 + - 用户主动输入的场景,例如用户主动输入身份证和银行卡号绑卡等场景。 + + +## 数据分类分级 + +基于数据保护目标及风险后果,即数据遭到泄露或者遭到破坏带来的法律风险对个人、组织或公众的影响对数据进行定级,分为极高、高、中、低、公开五个数据级别。 + +**表1** 数据分类分级标准 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

数据级别

+

隐私风险

+

隐私属性

+

典型示例

+

极高级

+

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来灾难性负面影响。

+

敏感个人数据

+

DNA、种族、宗教信仰、性取向;生物识别信息;原始通信内容;银行卡密码、磁道数据。

+

高级别

+

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来严重负面影响。

+

敏感个人数据

+

权威社会标识(身份证、护照等);网页浏览记录;轨迹信息;云空间上传的内容数据(图库/音频/视频等)。

+

中级别

+

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来重大负面影响。

+

一般个人数据

+

设备标识(IMEI, SN, OAID )、用户标识(user ID);个人基本信息(姓名,地址);手机号、邮箱等。

+

低级别

+

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来有限负面影响。

+

一般个人数据

+

操作系统设置信息(操作系统版本,国家/地区等);设备硬件信息(设备型号,屏幕尺寸,屏幕分辨率等);网络信息(网络连接状态,接入网络信息);设备状态(登录设备时间/时长)。

+

公开(无风险)

+

对个人或组织无不利影响的可公开数据

+

非个人数据

+

公开发布的产品介绍,公开的会议信息,外部开源的代码等。

+
+ +备注:隐私保护和数据分类分级的相关定义参照GDPR中的相关内容。 + +## 通用隐私设计规则 + +为了指导厂商完成产品的隐私设计工作,我们整理了以下通用的隐私设计要求,作为OpenHarmony设备厂商产品隐私设计的指南和参考。 + +**数据收集及使用公开透明** + +采集个人数据时,应清晰、明确地告知用户,并确保告知用户的个人信息将被如何使用。 + +- 针对不同等级的个人数据需要制定针对性的隐私处理策略。 + - 敏感个人数据的采集需要获取数据主体明示同意。 + - 一般个人数据的采集需要数据主体同意或基于其他合法授权。 + - 非个人数据与中、高或极高级别个人数据关联采集,需要数据主体同意或其他合法授权,并在隐私声明中呈现。 + +- 应制定并遵从适当的隐私政策。在收集、使用留存和第三方分享用户个人数据时需要符合所有适用法律、政策和规定。如在收集个人数据前,需充分告知用户处理个人数据的种类、目的、处理方式、保留期限等,满足数据主体权利相关要求。 + + 根据以上要求,我们设计了正确示例以供参考。隐私通知/声明的参考示例如下: + + **图 1** 隐私通知/声明示例图 + + + ![](figure/2-应用启动预授权.png) ![](figure/3-应用隐私声明.png) + +- 个人数据应当基于具体、明确、合法的目的收集,不应与此目的不相符的方式作进一步处理。对于收集目的变更和用户撤销同意后再次重新使用的场景都需要用户重新同意。隐私声明变更和撤销的示例如下图: + + **图 2** 隐私通知/声明变更示例图 + + + ![](figure/4-隐私声明变更通知.png) + + **图 3** 撤销同意示例图 + + + ![](figure/6-1-隐私声明撤销.png) ![](figure/6-2-隐私声明撤销.png) + +- 需要提供用户查看隐私声明的入口。例如,可以在应用的“关于”界面提供查看隐私声明的入口,如示例图所示: + + **图 4** 隐私声明查看界面示例图 + + + ![](figure/5-应用隐私声明入口.png) + + +**数据收集及使用最小化** + +个人数据收集应与数据处理目的相关,且是适当、必要的。开发者应尽可能对个人数据进行匿名化或假名化处理,降低对数据主体的风险。仅可收集和处理与特定目的相关且必需的个人数据,不能进行与特定目的不相关的进一步处理。 + +- 敏感权限申请的时候要满足权限最小化的要求,在申请权限时,只申请获取必需的信息或资源所需要的权限。如应用不需要相机权限就能够实现其功能时,则不应该向用户申请相机权限。 +- 数据收集最小化:针对数据的收集要满足最小化要求,不收集与产品提供服务无关联的数据。如提供定位服务的产品,不应收集用户的网页浏览记录。 +- 数据使用的功能要求能够使用户受益,收集的数据不能用于一些与用户正常使用无关的功能。数据收集不能有其他与用户正常使用无关的功能存在。如不得将“生物特征”、“健康数据”等敏感个人数据用于服务改进、投放广告或营销等非业务核心功能。 +- 禁止在日志中打印敏感个人数据,如需要打印一般个人数据时,应对个人数据进行匿名化或假名化处理; + + 优先使用可以重置的标识符,如系统提供了NetworkID和DVID作为分布式场景下的设备标识符,广告业务场景下则建议使用[OAID](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/oaid-0000001050783198),基于应用的分析则建议使用[ODID](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/odid-0000001051063255)和[AAID](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/aaid-0000001051142988),其他需要唯一标识符的场景可以使用UUID接口生成;可重置的标识符不能满足业务需求时,才选择序列号和MAC地址等永久性标识符。 + + +**数据处理选择和控制** + +对个人数据处理必须要征得用户的同意或遵守其他适用的法律法规,用户对其个人数据要有充分的控制权。 + +- 获取用户敏感权限的授权:产品弹窗提醒,向用户呈现需要获取的权限和权限使用目的,用户可通过选择决定是否进行授权及指定授权的方式,让用户对产品权限的授予和个人数据使用做到透明、可知、可控。如下图所示: + + **图 5** 敏感权限提示框示例图 + + + ![](figure/1-敏感权限弹窗.png) + +- 用户可以修改、取消授予的权限:当用户不同意某一权限或者数据收集时,应当允许用户使用与这部分权限和数据收集不相关的功能。如智慧屏产品上通信社交应用,用户可以拒绝授予相机权限,不应该影响与相机无关的功能操作,如语音通话。 +- 用户在产品使用过程中,针对录入个人数据的场景,需要给用户提供对个人数据的增加、删除、修改、查看的操作。 +- 需要给出硬件回收或返厂进行安全删除个人数据的机制或方法。 +- 对用户系统软件、应用软件的下载或升级,涉及修改用户隐私空间,用户对于这类行为需要有知情权和控制权,必须给用户提示,并提供给用户同意和取消的选项。 + +**数据安全** + +从技术上保证数据处理活动的安全性,包括个人数据的加密存储、安全传输等安全机制,系统应默认开启或采取安全保护措施。 + +- 对于个人数据的访问需要有保护机制,主要包括身份认证和访问控制。身份认证(如用户名、密码)限定只有经过认证的用户才能访问数据,可应用于多用户场景;访问控制(如[权限控制](safety-safeguide-security.md#li201725506375))可应用于对应用程序的限制。 +- 分布式设备个人数据安全存储要满足密钥管理和存储服务(HUKS:Huawei Universal Keystore)的要求,包括:密钥安全存储、数据安全存储。 +- 个人数据在分布式设备间传输要满足设备间的信任绑定关系和数据传输通道的安全性要求。详细信息可以参考[设备互联安全](safety-safeguide-security.md#section26153183616)。 +- 认证凭证数据(密码、口令、指纹等)须加密存储。 + +**本地化处理** + +用户数据优先在本设备进行处理,对于本设备无法处理的数据应尽可能在超级终端设备本地进行数据的处理,如果超级终端本地处理无法满足业务目的的,在数据离开超级终端设备本地时应尽可能选择匿名化。 + +**未成年人数据保护要求** + +产品专门给未成年人设计的,或者产品收集用户年龄从而可以识别到是在收集未成年人的个人数据,需结合目标市场国家的法律,专门分析未成年人个人数据保护的问题,收集未成年人数据前需要征得监护人的同意。 + +## 特殊品类要求 + +针对消费者硬件产品来说,除了满足以上的通用隐私要求以外,针对特殊品类的产品还有以下的特殊要求,在产品设计过程中参照执行。 + +**表2** 特殊品类隐私要求 + + + + + + + + + + + + + + + + + + + + + + + + + +

产品品类

+

隐私保护特殊要求

+

智能家居

+

安防类产品涉及的指纹、声纹、面部识别、虹膜等个人生物识别信息以及用户密码信息,属于敏感个人数据,应采用技术措施处理后(例如提取个人生物识别信息的摘要)再进行加密保存在产品本地。

+

智能家居

+

安防类产品涉及的音视频和图片,设备厂家作为数据控制者时,必须提供独立的隐私通知、应用界面必须有设备厂家品牌标识;音视频数据的传输和存储必须加密,非用户本人访问安防产品的音视频数据,必须获得用户授权。

+

智能家居/影音娱乐

+

带有摄像头的产品建议提供物理上可关闭功能,通过隐藏、遮盖、转向让消费者感知摄像头处于关闭状态。

+

智能家居/影音娱乐

+

带有麦克风的产品建议提供显性显示录音的状态,如录音开启时状态灯闪烁,录音关闭时状态灯熄灭。

+

移动办公

+

用户数据跨设备显示、传输等场景需要获得消费者的明示同意,给予消费者对其个人数据有充分的控制权。

+

车机

+

1、隐私通知及权限设置

+

避免在驾驶态让用户阅读隐私政策和权限设置。

+

车机应用需要考虑车辆使用时的安全性,应避免让用户在驾驶过程中进行复杂的权限设置或阅读隐私政策,比如HiCar应用应该在手机端完成应用基本权限设置和隐私政策阅读后再进行使用。

+

隐私声明在确认用户身份后告知。

+

车辆的数据会涉及车主、驾驶员和乘客,应保证隐私声明通知到了数据主体本人。建议做法是在确认使用者的身份后进行隐私声明,如需要用户登录的应用,应在账号登录后弹出隐私声明而不是账号登录之前。

+

2、共享应用个人数据保护

+

共享应用在车机重启后应退出,并对当前用户个人数据进行清除或加密,应用还应提供对历史数据进行彻底删除的功能。

+

3、消息提示

+

考虑车机的开放环境,应用在车机上进行消息提醒时,应避免直接将消息内容显示在车机上,正确的做法是仅提示有新的消息需要查看。

+
+ diff --git a/zh-cn/device-dev/security/safety-safeguide-security.md b/zh-cn/device-dev/security/safety-safeguide-security.md new file mode 100644 index 0000000000000000000000000000000000000000..63804f366b4110c67b0b87ced8b24aea03dbf220 --- /dev/null +++ b/zh-cn/device-dev/security/safety-safeguide-security.md @@ -0,0 +1,275 @@ +# 安全指南 + +- [安全概述](#section1521410017353) +- [硬件安全](#section2558121318351) + - [安全机制](#section1399511541896) + - [推荐做法](#section948519243104) + +- [系统安全](#section87802111361) + - [安全机制](#section149107611118) + - [推荐做法](#section1364122019112) + +- [数据安全](#section2468927364) + - [安全机制](#section1378993720111) + - [推荐做法](#section1531735481112) + +- [设备互联安全](#section26153183616) +- [应用安全](#section852593153614) + - [安全机制](#section55012136125) + - [推荐做法](#section6341102610123) + + +## 安全概述 + +OpenHarmony操作系统是一个开放的系统,开发者可以通过OpenHarmony开发灵活的服务和应用,为开发者和使用者带来便利和价值。为了达到这一目的,OpenHarmony提供了一个可以有效保护应用和用户数据的执行环境。 + +在这个执行环境中,芯片的安全能力、系统的安全能力、以及上层的安全服务一起协作,从硬件安全、系统安全、数据安全、设备互联安全、应用安全、安全更新多个维度提供安全保障。 + +**图 1** 安全保障示意图 +![](figure/安全保障示意图.png "安全保障示意图") + +## 硬件安全 + +### 安全机制 + +- 启动可信根 + + OpenHarmony设备采用PKI(Public Key Infrastructure)体系保护软件完整性,确保设备运行来源合法、软件未被篡改。 + + 在设备启动流程中,逐级进行软件签名校验形成安全启动链,任何一个环节的签名校验不通过即终止设备启动;安全启动链中最初执行签名校验的软硬件实体,需确保自身的合法、未被篡改。该实体即为设备的启动可信根。启动可信根可为固化在ROM中的一段代码,这段代码在芯片制造环节固化到芯片中,芯片制造完成后软件不可更改,在设备上电初始化的过程中,最先执行这段ROM中的代码,并由这段ROM代码执行后续的软件签名校验。 + + ROM中的代码在执行签名校验时,需确保用于校验的PKI公钥的合法性,OpenHarmony设备可采用eFuse/OTP等存储介质来存储公钥(如公钥哈希值),来保护公钥自身的合法性。公钥一般在设备制造环节,烧录到设备的eFuse/OTP中。 + +- 硬件隔离可信环境 + + 硬件隔离的可信环境,遵循了可信计算系统的设计理念。可信环境内外形成了两个世界:可信世界与不可信世界,两者之间存在清晰而明确的隔离边界;OpenHarmony设备在可信环境中实现了核心敏感数据的保护机制,可确保即使不可信世界的操作系统存在漏洞且被利用,也依然能确保可信环境中敏感数据的安全。 + + OpenHarmony设备的可信环境,基于硬件的安全隔离机制构建,在不同的OpenHarmony设备上芯片隔离机制略有差异,较为通用的方法是采用ARM的TrustZone技术。在部分Risc-V芯片平台上,也可能采用独立安全核的形式来构建可信环境。 + + 可信环境中,运行特定的、精简的操作系统iTrustee lite,用于管理可信环境的资源和任务调度,给OpenHarmony设备提供安全服务。密钥管理及数据安全,是可信环境中最为常见的安全服务,设备在eFuse/OTP中存有硬件唯一根密钥,可信环境可基于该密钥结合业务上下文衍生出多种密钥,给应用提供密钥管理和数据加解密相关的服务;设备核心密钥生命周期不离开可信环境。可信环境同样可提供身份认证、系统状态监控、数据安全存储等安全服务,提高设备安全性。 + +- 硬件密钥引擎 + + 密码学是信息安全的基础。数据加解密对计算机设备的核心诉求是:高效、安全。硬件加解密技术利用计算机硬件辅助软件,甚至直接取代软件,来处理数据的加解密。相比由软件实现的加解密计算,硬件实现的加解密计算更高效、更安全。 + + 由硬件来实现加解密处理,意味着部分专用的硬件资源会用于处理加解密计算任务,当加解密引擎工作的时候CPU可以并发地继续执行其他计算任务,因此硬件加解密引擎可以带来极大的性能提升,同时降低CPU负载。此外,硬件密钥引擎可以带来更高的安全性,设计良好的硬件密钥引擎,哪怕软件被攻破也依然可保护密钥不泄露,甚至可对抗电磁、辐射等物理侧信道攻击。 + + OpenHarmony设备支持硬件密钥引擎,支撑OpenHarmony系统进行数据加解密、证书验签、哈希计算等计算任务,可支持AES/RSA等主流的密码学算法。 + + +### 推荐做法 + +- 启动可信根可由一段固化在芯片中的代码和设备根密钥组成,前者一般在芯片制造阶段写入,设备生命周期内不可更改,负责在启动阶段校验设备软件证书;后者则是用于设备证书签名的私钥相对应的公钥,证书签名私钥不出PKI签名服务器,而公钥则需写入设备。为防止攻击者篡改公钥从而达到绕过签名认证的目的,写入OpenHarmony设备的公钥须确保不可篡改,可将公钥信息写入如熔丝等介质;考虑到熔丝空间有限,可仅存储公钥的哈希值,并由启动代码校验公钥的合法性。 +- 可信执行环境较为通用的做法是基于ARM TrustZone技术构建,也可根据设备的实际形态选择其他隔离机制,如TrustZone-M、独立安全核等;可信执行环境中须部署TEE OS,用于管理可信执行环境的资源及任务调度。OpenHarmony系统提供iTrustee作为TEE OS的解决方案,开发者及设备商可基于iTrustee开发并部署安全业务。 + + 并非所有OpenHarmony设备都强制要求支持可信执行环境,部分运行低敏感业务的瘦资源设备可不做强制要求;可根据实际业务场景选择是否支持可信执行环境,以及实现怎样的可信执行环境。 + +- 硬件密钥引擎须提供真随机数、公钥、对称密钥、哈希等密钥算法能力,通过在OpenHarmony系统中部署相应的驱动程序,给应用提供统一的密钥管理及密钥算法服务。 + +## 系统安全 + +### 安全机制 + +对于128KB\~128MB内存的设备,推荐使用OpenHarmony轻内核组件,在该内核下: + +- 进程隔离 + + 进程隔离是为了防止A进程读写B进程内存数据的情况发生,进程的隔离技术,一般都采用虚拟地址空间映射方式,通过MMU配置,进程A的虚拟地址和进程B的虚拟地址映射各自不同的实际的物理地址段,这样A进程通过访问虚拟地址访问的实际内存数据在非共享内存的情况下,只属于A进程,B进程无法直接访问。 + + OpenHarmony由于资源有限,对于内核态和用户态的进程采用不同的方式:所有的内核态进程共享同一块VMM空间,即所有的内核态进程之间无隔离,系统启动时内核态创建两个基本进程KProcess和KIdle,KProcess进程为内核态进程的根进程,KIdle进程为KProcess进程的子进程;但是对于每一个用户态进程均拥有自己独立的VMM空间,相互之间不可见,实现进程间隔离。 + +- 自主访问控制 + + 自主访问控制DAC(Discretionary Access Control)的思想是文件权限由文件拥有者来决定其他角色的访问权限。权限管控粒度分为三类:user\(自身\), group\(组员\),other\(其他人\),即UGO。将任意用户分类为UGO中三者之一,并采取相应的管控策略,即完成了DAC权限校验流程。 + + DAC机制依赖于进程的uid、gid等属性,需要以此作为文件创建以及文件访问过程中的特征id。文件创建时,创建者将自身uid写入文件,文件访问时,又以此作为文件归属的分类依据。 + + 每一个应用,对应一个uid。应用在创建文件时,将自身uid信息加入被创建文件的元数据\(metadata\)中,并设置UGO三个组的权限。在文件访问过程中,将以访问者uid作为访问校验主体、以文件元数据中的uid权限信息作为客体,进行权限校验。 + + 下图描述了DAC在文件访问时的鉴权过程,首先匹配进程uid和文件uid属性,其次匹配进程gid和文件gid属性,最后都匹配失败的情况,判断文件other属性是否支持进程的读、写、执行操作。同时支持忽略DAC检测机制(读、写、执行)作为一组系统特权(Capability),支持高权限(如系统服务)对低权限(三方APP)的文件管理。 + + **图 2** DAC流程图 + ![](figure/DAC流程图.png "DAC流程图") + +- Capability机制 + + Capability机制实际上是对root权限的具体细分。在多用户计算机系统中,一般会有一个特殊的角色拥有系统的所有权限,这个角色一般是系统管理员\(root\)。对于OpenHarmony这种需要支持三方应用生态的内核,需要将系统中的特权访问进行管控。系统需要对用户层访问内核的特权级系统调用进行限制。仅允许部分高权限应用进行特权操作。具体实现方式是内核spawn第一个用户程序INIT,其包含全部的特权能力,此后,INIT拉起其他应用框架服务,拉起过程中,对各应用框架进行相应的降权操作,为各应用保留必须的特权能力。 当应用去调用特权接口时,内核态就会通过进程ID查看当前访问者是否有权限访问目标接口。 + +- 安全启动 + + 安全启动是整个系统安全的基础,通过采用数字签名和完整性校验机制,从芯片内部固化的可信启动根开始,逐级校验每一层软件的完整性和合法性,确保最终启动的操作系统软件是厂家提供的正确合法的软件,防止攻击者对系统软件做恶意的篡改和植入,为整个系统提供初始安全的基础运行环境。 + + 在芯片上电后,由于片上ROM代码本身不可更改,因此无需校验;片上ROM基于eFuse中的非对称算法公钥hash对bootloader进行校验。这些过程都基于硬件信任根来进行,是完全可信的。经过此过程校验通过的bootloader模块可以作为后续的信任基础,此过程就是启动信任链的构造过程。Bootloader通常首先对执行环境进行一定的初始化,主要是初始化DDR以及flash读写,为进一步加载后续模块以及执行更为复杂的逻辑进行准备。Bootloader完成初始化动作后,首先完成x509证书的完整性校验,然后利用x509证书的公钥对需要校验的镜像包(kernel.bin、teeOS.bin、rootfs.bin)进行校验。 + + +### 推荐做法 + +- 自主访问控制和Capability机制是控制资源被谁可以访问的机制,建议所有权限设置都采用最小权限原则。 +- 安全启动必须要开启,信任根必须是基于芯片的不可更改的形式存在,并且在有安全升级的情况下,必须考虑安全升级后对于安全启动的影响,也就是安全升级后必须要更新对应镜像文件的签名信息或者hash值。 + +## 数据安全 + +### 安全机制 + +HUKS(Huawei Universal Keystore Service),提供了密钥管理、证书管理服务,当前在OpenHarmony上主要提供密钥管理服务,用于支撑HiChain\(设备身份认证平台\)的基础设备认证。如下是HUKS的功能结构图: + +**图 3** HUKS功能结构图 +![](figure/HUKS功能结构图.png "HUKS功能结构图") + +支持算法包括: + +- 认证加密:AES-128/192/256-GCM +- 签名验签:ED25519 +- 密钥协商:X25519 +- 消息认证:HMAC-SHA256/512 +- 数据摘要:SHA256/512 + +HUKS在使用中有如下约束: + +- 密钥安全存储:密钥要求存储于安全存储区域,数据不可以修改,恢复出厂设置时出厂预置的密钥不能被删除。 +- 密钥访问安全:OpenHarmony通过将不同应用数据保存在不同的位置,来实现应用间数据的隔离。通过参数结构体中包含UID和进程ID,来实现不同应用间的数据隔离。 +- 不支持并发访问:HUKS本身不考虑多个应用同时调用的情况,因为HUKS只是一个lib库,也不考虑资源的互斥。如果有多个应用都会用到HUKS服务,那么应该由每个应用各自链接一份HUKS库,并由业务传入持久化数据存储的路径,以实现应用间的数据存储分开。数据存储在各应用各自存储目录下。 + +### 推荐做法 + +对于设备认证功能,建议使用HiChain来对接HUKS,HUKS可以向HiChain等应用提供密钥的产生、导入、导出、加密/解密、存储、销毁,证书的导入和查询,秘密信息的存储等能力。 + +## 设备互联安全 + +为了实现用户数据在设备互联场景下在各个设备之间的安全流转,需要保证设备之间相互正确可信,即设备和设备之间建立信任关系,并能够在验证信任关系后,搭建安全的连接通道,实现用户数据的安全传输。设备之间的信任关系在本文档中涉及IoT主控设备和IoT设备之间建立的可信关系。设备间可信关系建立的流程如下图所示: + +**图 4** 设备间建立可信关系流程图 +![](figure/设备间建立可信关系流程图.png "设备间建立可信关系流程图") + +- **IoT设备互联安全** + + 设备互联支持基于OpenHarmony的IoT设备(如AI音箱、智能家居、智能穿戴等设备)与IoT主控设备间建立点对点的信任关系,并在具备信任关系的设备间,搭建安全的连接通道,实现用户数据端到端加密传输。 + + +- **IoT主控设备的IoT业务身份标识** + + IoT主控设备为不同的IoT设备管理业务生成不同的身份标识,形成不同IoT管理业务间的隔离,该标识用于IoT主控设备与IoT设备之间的认证以及通信。IoT业务身份标识为椭圆曲线公私钥对(Ed25519公私钥对)。 + + +- **IoT设备身份标识** + + IoT设备会生成各自的设备身份标识,用来与IoT主控设备通信。该身份标识同样为椭圆曲线公私钥对(Ed25519公私钥对);IoT设备私钥不出IoT设备,设备每次恢复出厂设置,会重置这个公私钥对。 + + 上述身份标识可用于IoT主控设备与IoT设备间的安全通信:当IoT主控设备与IoT设备通过信任绑定流程交换业务身份标识或设备标识后,可以进行密钥协商并建立安全通信通道。 + + +- **设备间点对点的信任绑定** + + IoT主控设备和IoT设备建立点对点信任关系的过程,实际上是相互交换IoT设备的身份标识的过程。 + + 在点对点建立信任关系的过程中,用户需要在IoT主控设备上,输入IoT设备上提供的PIN码:对于有屏幕的设备,该PIN码动态生成;对于没有屏幕的设备,该PIN码由设备生产厂家预置;PIN码的展示形式,可以是一个用户可读的数字,也可以是一个二维码。随后,IoT主控设备和IoT设备间使用PAKE协议完成认证和会话密钥协商过程,并在此基础上,通过协商出的会话密钥加密传输通道用于交换双方设备的身份标识公钥。 + + +- **IoT主控设备与IoT设备间的通信安全** + + 当建立过信任关系的IoT主控设备与IoT设备间进行通信时,双方在完成上述信任关系绑定后,基于本地存储的对端身份公钥相互进行认证;在每次通信时基于STS协议完成双向身份认证以及会话密钥协商,之后设备使用此会话密钥加密双方设备间的传输通道。 + + +## 应用安全 + +### 安全机制 + +- 应用签名管控 + + OpenHarmony应用的安装需要首先对包的完整性进行校验,具体策略是在开发阶段完成开发和调试后对安装包进行签名,这个签名需要使用指定的私钥,这个私钥就是跟验签用的公钥是一对的,一般的做法是OEM厂商生成一对公私钥,然后将公钥信息预置到设备中,而私钥就放在一个不联网的本地服务器上,这样可以确保私钥被泄露的风险尽量小,而应用在完成开发后就可以通过外置设备(例如USB)上传安装包到存放私钥的服务器上计算签名并下载签名结果到外置设备上。而安装应用时首先计算包的Hash值,一般采用SHA256算法,然后使用hash值和签名信息以及预置公钥进行验签,只有验签通过的应用才能安装。 + + 除了要证明应用来自云端认证过的,还需要证明来源,即这个应用来自合法开发者开发的,具体做法是,开发者向云端申请开发证书,开发完成后,用开发证书进行自签名,设备端存放这个证书的上一级证书,所以安装过程中,对自签名信息做校验,确保开发者的合法性。 + +- 应用权限控制 + + 由于OpenHarmony系统允许安装三方应用,所以需要对三方应用的敏感权限调用进行管控,具体实现是应用在开发阶段就需要在profile.json中指明此应用在运行过程中可能会调用哪些敏感权限,这些权限包括静态权限和动态权限,静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示获取用户的敏感信息,所以需要在运行时让用户确认才可以调用,授权方式包括系统设置应用手动授权等。除了运行时对应用调用敏感权限进行管控外,还需要利用应用签名管控手段确保应用安装包已经被设备厂商进行了确认。 + + **表 1** **OpenHarmony系统权限列表** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

OpenHarmony系统权限

+

授权方式

+

权限说明

+

ohos.permission.LISTEN_BUNDLE_CHANGE

+

system_grant(静态权限)

+

允许该应用获取应用变化消息。

+

ohos.permission.GET_BUNDLE_INFO

+

system_grant(静态权限)

+

允许该应用获取应用信息。

+

ohos.permission.INSTALL_BUNDLE

+

system_grant(静态权限)

+

允许该应用安装应用。

+

ohos.permission.CAMERA

+

user_grant(动态权限)

+

此应用可随时使用相机拍摄照片和录制视频。

+

ohos.permission.MODIFY_AUDIO_SETTINGS

+

system_grant(静态权限)

+

允许该应用修改全局音频设置,例如音量和用于输出的扬声器。

+

ohos.permission.READ_MEDIA

+

user_grant(动态权限)

+

允许该应用读取您的视频收藏。

+

ohos.permission.MICROPHONE

+

user_grant(动态权限)

+

此应用可随时使用麦克风进行录音。

+

ohos.permission.WRITE_MEDIA

+

user_grant(动态权限)

+

允许该应用写入您的音乐收藏。

+

ohos.permission.DISTRIBUTED_DATASYNC

+

user_grant(动态权限)

+

管控分布式数据传输能力。

+

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

+

user_grant(动态权限)

+

允许应用使用分布式虚拟能力

+
+ + +### 推荐做法 + +开发者在开发过程中需明确后续应用在运行时需要运行哪些权限,并在profile.json中进行注册,然后需要对应用进行签名,确保设备在安装这些应用时能对应用的完整性和来源进行校验。 + diff --git a/zh-cn/device-dev/security/safety.md b/zh-cn/device-dev/security/safety.md new file mode 100644 index 0000000000000000000000000000000000000000..72bbe83ac0cf5052a2b1b53ce27b380ef390b963 --- /dev/null +++ b/zh-cn/device-dev/security/safety.md @@ -0,0 +1,7 @@ +# 隐私与安全 + +- **[隐私保护](safety-protection-privacyguide.md)** + +- **[安全指南](safety-safeguide-security.md)** + + diff --git "a/zh-cn/device-dev/security/\345\256\211\345\205\250\346\214\207\345\215\227.md" "b/zh-cn/device-dev/security/\345\256\211\345\205\250\346\214\207\345\215\227.md" deleted file mode 100755 index c387b9a68e6fd35a272c442f521842e8410c009a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/security/\345\256\211\345\205\250\346\214\207\345\215\227.md" +++ /dev/null @@ -1,271 +0,0 @@ -# 安全指南 - -- [安全概述](#section1521410017353) -- [硬件安全](#section2558121318351) -- [安全机制](#section1312953842210) -- [推荐做法](#section37901319112311) -- [系统安全](#section87802111361) -- [安全机制](#section1654963052914) -- [推荐做法](#section45821048173613) -- [数据安全](#section2468927364) -- [安全机制](#section11192175813293) -- [推荐做法](#section174640713306) -- [设备互联安全](#section26153183616) -- [应用安全](#section852593153614) -- [安全机制](#section12125105014377) -- [推荐做法](#section1641420155381) - -## 安全概述 - -OpenHarmony操作系统是一个开放的系统,开发者可以通过OpenHarmony开发灵活的服务和应用,为开发者和使用者带来便利和价值。为了达到这一目的,OpenHarmony提供了一个可以有效保护应用和用户数据的执行环境。 - -在这个执行环境中,芯片的安全能力、系统的安全能力、以及上层的安全服务一起协作,从硬件安全、系统安全、数据安全、设备互联安全、应用安全、安全更新多个维度提供安全保障。 - -**图 1** 安全保障示意图 -![](figures/安全保障示意图.png "安全保障示意图") - -## 硬件安全 - -## 安全机制 - -- 启动可信根 - - OpenHarmony设备采用PKI(Public Key Infrastructure)体系保护软件完整性,确保设备运行来源合法、软件未被篡改。 - - 在设备启动流程中,逐级进行软件签名校验形成安全启动链,任何一个环节的签名校验不通过即终止设备启动;安全启动链中最初执行签名校验的软硬件实体,需确保自身的合法、未被篡改。该实体即为设备的启动可信根。启动可信根可为固化在ROM中的一段代码,这段代码在芯片制造环节固化到芯片中,芯片制造完成后软件不可更改,在设备上电初始化的过程中,最先执行这段ROM中的代码,并由这段ROM代码执行后续的软件签名校验。 - - ROM中的代码在执行签名校验时,需确保用于校验的PKI公钥的合法性,OpenHarmony设备可采用eFuse/OTP等存储介质来存储公钥(如公钥哈希值),来保护公钥自身的合法性。公钥一般在设备制造环节,烧录到设备的eFuse/OTP中。 - -- 硬件隔离可信环境 - - 硬件隔离的可信环境,遵循了可信计算系统的设计理念。可信环境内外形成了两个世界:可信世界与不可信世界,两者之间存在清晰而明确的隔离边界;OpenHarmony设备在可信环境中实现了核心敏感数据的保护机制,可确保即使不可信世界的操作系统存在漏洞且被利用,也依然能确保可信环境中敏感数据的安全。 - - OpenHarmony设备的可信环境,基于硬件的安全隔离机制构建,在不同的OpenHarmony设备上芯片隔离机制略有差异,较为通用的方法是采用ARM的TrustZone技术。在部分Risc-V芯片平台上,也可能采用独立安全核的形式来构建可信环境。 - - 可信环境中,运行特定的、精简的操作系统iTrustee lite,用于管理可信环境的资源和任务调度,给OpenHarmony设备提供安全服务。密钥管理及数据安全,是可信环境中最为常见的安全服务,设备在eFuse/OTP中存有硬件唯一根密钥,可信环境可基于该密钥结合业务上下文衍生出多种密钥,给应用提供密钥管理和数据加解密相关的服务;设备核心密钥生命周期不离开可信环境。可信环境同样可提供身份认证、系统状态监控、数据安全存储等安全服务,提高设备安全性。 - -- 硬件密钥引擎 - - 密码学是信息安全的基础。数据加解密对计算机设备的核心诉求是:高效、安全。硬件加解密技术利用计算机硬件辅助软件,甚至直接取代软件,来处理数据的加解密。相比由软件实现的加解密计算,硬件实现的加解密计算更高效、更安全。 - - 由硬件来实现加解密处理,意味着部分专用的硬件资源会用于处理加解密计算任务,当加解密引擎工作的时候CPU可以并发地继续执行其他计算任务,因此硬件加解密引擎可以带来极大的性能提升,同时降低CPU负载。此外,硬件密钥引擎可以带来更高的安全性,设计良好的硬件密钥引擎,哪怕软件被攻破也依然可保护密钥不泄露,甚至可对抗电磁、辐射等物理侧信道攻击。 - - OpenHarmony设备支持硬件密钥引擎,支撑OpenHarmony系统进行数据加解密、证书验签、哈希计算等计算任务,可支持AES/RSA等主流的密码学算法。 - - -## 推荐做法 - -- 启动可信根可由一段固化在芯片中的代码和设备根密钥组成,前者一般在芯片制造阶段写入,设备生命周期内不可更改,负责在启动阶段校验设备软件证书;后者则是用于设备证书签名的私钥相对应的公钥,证书签名私钥不出PKI签名服务器,而公钥则需写入设备。为防止攻击者篡改公钥从而达到绕过签名认证的目的,写入OpenHarmony设备的公钥须确保不可篡改,可将公钥信息写入如熔丝等介质;考虑到熔丝空间有限,可仅存储公钥的哈希值,并由启动代码校验公钥的合法性。 -- 可信执行环境较为通用的做法是基于ARM TrustZone技术构建,也可根据设备的实际形态选择其他隔离机制,如TrustZone-M、独立安全核等;可信执行环境中须部署TEE OS,用于管理可信执行环境的资源及任务调度。OpenHarmony系统提供iTrustee作为TEE OS的解决方案,开发者及设备商可基于iTrustee开发并部署安全业务。 - - 并非所有OpenHarmony设备都强制要求支持可信执行环境,部分运行低敏感业务的瘦资源设备可不做强制要求;可根据实际业务场景选择是否支持可信执行环境,以及实现怎样的可信执行环境。 - -- 硬件密钥引擎须提供真随机数、公钥、对称密钥、哈希等密钥算法能力,通过在OpenHarmony系统中部署相应的驱动程序,给应用提供统一的密钥管理及密钥算法服务。 - -## 系统安全 - -## 安全机制 - -对于128KB\~128MB内存的设备,推荐使用OpenHarmony轻内核组件,在该内核下: - -- 进程隔离 - - 进程隔离是为了防止A进程读写B进程内存数据的情况发生,进程的隔离技术,一般都采用虚拟地址空间映射方式,通过MMU配置,进程A的虚拟地址和进程B的虚拟地址映射各自不同的实际的物理地址段,这样A进程通过访问虚拟地址访问的实际内存数据在非共享内存的情况下,只属于A进程,B进程无法直接访问。 - - OpenHarmony由于资源有限,对于内核态和用户态的进程采用不同的方式:所有的内核态进程共享同一块VMM空间,即所有的内核态进程之间无隔离,系统启动时内核态创建两个基本进程KProcess和KIdle,KProcess进程为内核态进程的根进程,KIdle进程为KProcess进程的子进程;但是对于每一个用户态进程均拥有自己独立的VMM空间,相互之间不可见,实现进程间隔离。 - -- 自主访问控制 - - 自主访问控制DAC(Discretionary Access Control)的思想是文件权限由文件拥有者来决定其他角色的访问权限。权限管控粒度分为三类:user\(自身\), group\(组员\),other\(其他人\),即UGO。将任意用户分类为UGO中三者之一,并采取相应的管控策略,即完成了DAC权限校验流程。 - - DAC机制依赖于进程的uid、gid等属性,需要以此作为文件创建以及文件访问过程中的特征id。文件创建时,创建者将自身uid写入文件,文件访问时,又以此作为文件归属的分类依据。 - - 每一个应用,对应一个uid。应用在创建文件时,将自身uid信息加入被创建文件的元数据\(metadata\)中,并设置UGO三个组的权限。在文件访问过程中,将以访问者uid作为访问校验主体、以文件元数据中的uid权限信息作为客体,进行权限校验。 - - 下图描述了DAC在文件访问时的鉴权过程,首先匹配进程uid和文件uid属性,其次匹配进程gid和文件gid属性,最后都匹配失败的情况,判断文件other属性是否支持进程的读、写、执行操作。同时支持忽略DAC检测机制(读、写、执行)作为一组系统特权(Capability),支持高权限(如系统服务)对低权限(三方APP)的文件管理。 - - **图 2** DAC流程图 - ![](figures/DAC流程图.png "DAC流程图") - -- Capability机制 - - Capability机制实际上是对root权限的具体细分。在多用户计算机系统中,一般会有一个特殊的角色拥有系统的所有权限,这个角色一般是系统管理员\(root\)。对于OpenHarmony这种需要支持三方应用生态的内核,需要将系统中的特权访问进行管控。系统需要对用户层访问内核的特权级系统调用进行限制。仅允许部分高权限应用进行特权操作。具体实现方式是内核spawn第一个用户程序INIT,其包含全部的特权能力,此后,INIT拉起其他应用框架服务,拉起过程中,对各应用框架进行相应的降权操作,为各应用保留必须的特权能力。 当应用去调用特权接口时,内核态就会通过进程ID查看当前访问者是否有权限访问目标接口。 - -- 安全启动 - - 安全启动是整个系统安全的基础,通过采用数字签名和完整性校验机制,从芯片内部固化的可信启动根开始,逐级校验每一层软件的完整性和合法性,确保最终启动的操作系统软件是厂家提供的正确合法的软件,防止攻击者对系统软件做恶意的篡改和植入,为整个系统提供初始安全的基础运行环境。 - - 在芯片上电后,由于片上ROM代码本身不可更改,因此无需校验;片上ROM基于eFuse中的非对称算法公钥hash对bootloader进行校验。这些过程都基于硬件信任根来进行,是完全可信的。经过此过程校验通过的bootloader模块可以作为后续的信任基础,此过程就是启动信任链的构造过程。Bootloader通常首先对执行环境进行一定的初始化,主要是初始化DDR以及flash读写,为进一步加载后续模块以及执行更为复杂的逻辑进行准备。Bootloader完成初始化动作后,首先完成x509证书的完整性校验,然后利用x509证书的公钥对需要校验的镜像包(kernel.bin、teeOS.bin、rootfs.bin)进行校验。 - - -## 推荐做法 - -- 自主访问控制和Capability机制是控制资源被谁可以访问的机制,建议所有权限设置都采用最小权限原则。 -- 安全启动必须要开启,信任根必须是基于芯片的不可更改的形式存在,并且在有安全升级的情况下,必须考虑安全升级后对于安全启动的影响,也就是安全升级后必须要更新对应镜像文件的签名信息或者hash值。 - -## 数据安全 - -## 安全机制 - -HUKS(Huawei Universal Keystore Service),提供了密钥管理、证书管理服务,当前在OpenHarmony上主要提供密钥管理服务,用于支撑HiChain\(设备身份认证平台\)的基础设备认证。如下是HUKS的功能结构图: - -**图 3** HUKS功能结构图 -![](figures/HUKS功能结构图.png "HUKS功能结构图") - -支持算法包括: - -- 认证加密:AES-128/192/256-GCM -- 签名验签:ED25519 -- 密钥协商:X25519 -- 消息认证:HMAC-SHA256/512 -- 数据摘要:SHA256/512 - -HUKS在使用中有如下约束: - -- 密钥安全存储:密钥要求存储于安全存储区域,数据不可以修改,恢复出厂设置时出厂预置的密钥不能被删除。 -- 密钥访问安全:OpenHarmony通过将不同应用数据保存在不同的位置,来实现应用间数据的隔离。通过参数结构体中包含UID和进程ID,来实现不同应用间的数据隔离。 -- 不支持并发访问:HUKS本身不考虑多个应用同时调用的情况,因为HUKS只是一个lib库,也不考虑资源的互斥。如果有多个应用都会用到HUKS服务,那么应该由每个应用各自链接一份HUKS库,并由业务传入持久化数据存储的路径,以实现应用间的数据存储分开。数据存储在各应用各自存储目录下。 - -## 推荐做法 - -对于设备认证功能,建议使用HiChain来对接HUKS,HUKS可以向HiChain等应用提供密钥的产生、导入、导出、加密/解密、存储、销毁,证书的导入和查询,秘密信息的存储等能力。 - -## 设备互联安全 - -为了实现用户数据在设备互联场景下在各个设备之间的安全流转,需要保证设备之间相互正确可信,即设备和设备之间建立信任关系,并能够在验证信任关系后,搭建安全的连接通道,实现用户数据的安全传输。设备之间的信任关系在本文档中涉及IoT主控设备和IoT设备之间建立的可信关系。设备间可信关系建立的流程如下图所示: - -**图 4** 设备间建立可信关系流程图 -![](figures/设备间建立可信关系流程图.png "设备间建立可信关系流程图") - -- **IoT设备互联安全** - - 设备互联支持基于OpenHarmony的IoT设备(如AI音箱、智能家居、智能穿戴等设备)与IoT主控设备间建立点对点的信任关系,并在具备信任关系的设备间,搭建安全的连接通道,实现用户数据端到端加密传输。 - - -- **IoT主控设备的IoT业务身份标识** - - IoT主控设备为不同的IoT设备管理业务生成不同的身份标识,形成不同IoT管理业务间的隔离,该标识用于IoT主控设备与IoT设备之间的认证以及通信。IoT业务身份标识为椭圆曲线公私钥对(Ed25519公私钥对)。 - - -- **IoT设备身份标识** - - IoT设备会生成各自的设备身份标识,用来与IoT主控设备通信。该身份标识同样为椭圆曲线公私钥对(Ed25519公私钥对);IoT设备私钥不出IoT设备,设备每次恢复出厂设置,会重置这个公私钥对。 - - 上述身份标识可用于IoT主控设备与IoT设备间的安全通信:当IoT主控设备与IoT设备通过信任绑定流程交换业务身份标识或设备标识后,可以进行密钥协商并建立安全通信通道。 - - -- **设备间点对点的信任绑定** - - IoT主控设备和IoT设备建立点对点信任关系的过程,实际上是相互交换IoT设备的身份标识的过程。 - - 在点对点建立信任关系的过程中,用户需要在IoT主控设备上,输入IoT设备上提供的PIN码:对于有屏幕的设备,该PIN码动态生成;对于没有屏幕的设备,该PIN码由设备生产厂家预置;PIN码的展示形式,可以是一个用户可读的数字,也可以是一个二维码。随后,IoT主控设备和IoT设备间使用PAKE协议完成认证和会话密钥协商过程,并在此基础上,通过协商出的会话密钥加密传输通道用于交换双方设备的身份标识公钥。 - - -- **IoT主控设备与IoT设备间的通信安全** - - 当建立过信任关系的IoT主控设备与IoT设备间进行通信时,双方在完成上述信任关系绑定后,基于本地存储的对端身份公钥相互进行认证;在每次通信时基于STS协议完成双向身份认证以及会话密钥协商,之后设备使用此会话密钥加密双方设备间的传输通道。 - - -## 应用安全 - -## 安全机制 - -- 应用签名管控 - - OpenHarmony应用的安装需要首先对包的完整性进行校验,具体策略是在开发阶段完成开发和调试后对安装包进行签名,这个签名需要使用指定的私钥,这个私钥就是跟验签用的公钥是一对的,一般的做法是OEM厂商生成一对公私钥,然后将公钥信息预置到设备中,而私钥就放在一个不联网的本地服务器上,这样可以确保私钥被泄露的风险尽量小,而应用在完成开发后就可以通过外置设备(例如USB)上传安装包到存放私钥的服务器上计算签名并下载签名结果到外置设备上。而安装应用时首先计算包的Hash值,一般采用SHA256算法,然后使用hash值和签名信息以及预置公钥进行验签,只有验签通过的应用才能安装。 - - 除了要证明应用来自云端认证过的,还需要证明来源,即这个应用来自合法开发者开发的,具体做法是,开发者向云端申请开发证书,开发完成后,用开发证书进行自签名,设备端存放这个证书的上一级证书,所以安装过程中,对自签名信息做校验,确保开发者的合法性。 - -- 应用权限控制 - - 由于OpenHarmony系统允许安装三方应用,所以需要对三方应用的敏感权限调用进行管控,具体实现是应用在开发阶段就需要在profile.json中指明此应用在运行过程中可能会调用哪些敏感权限,这些权限包括静态权限和动态权限,静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示获取用户的敏感信息,所以需要在运行时让用户确认才可以调用,授权方式包括系统设置应用手动授权等。除了运行时对应用调用敏感权限进行管控外,还需要利用应用签名管控手段确保应用安装包已经被设备厂商进行了确认。 - - **表 1** **OpenHarmony系统权限列表** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

OpenHarmony系统权限

-

授权方式

-

权限说明

-

ohos.permission.LISTEN_BUNDLE_CHANGE

-

system_grant(静态权限)

-

允许该应用获取应用变化消息。

-

ohos.permission.GET_BUNDLE_INFO

-

system_grant(静态权限)

-

允许该应用获取应用信息。

-

ohos.permission.INSTALL_BUNDLE

-

system_grant(静态权限)

-

允许该应用安装应用。

-

ohos.permission.CAMERA

-

user_grant(动态权限)

-

此应用可随时使用相机拍摄照片和录制视频。

-

ohos.permission.MODIFY_AUDIO_SETTINGS

-

system_grant(静态权限)

-

允许该应用修改全局音频设置,例如音量和用于输出的扬声器。

-

ohos.permission.READ_MEDIA

-

user_grant(动态权限)

-

允许该应用读取您的视频收藏。

-

ohos.permission.MICROPHONE

-

user_grant(动态权限)

-

此应用可随时使用麦克风进行录音。

-

ohos.permission.WRITE_MEDIA

-

user_grant(动态权限)

-

允许该应用写入您的音乐收藏。

-

ohos.permission.DISTRIBUTED_DATASYNC

-

user_grant(动态权限)

-

管控分布式数据传输能力。

-

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

-

user_grant(动态权限)

-

允许应用使用分布式虚拟能力

-
- - -## 推荐做法 - -开发者在开发过程中需明确后续应用在运行时需要运行哪些权限,并在profile.json中进行注册,然后需要对应用进行签名,确保设备在安装这些应用时能对应用的完整性和来源进行校验。 - diff --git "a/zh-cn/device-dev/security/\351\232\220\347\247\201\344\277\235\346\212\244.md" "b/zh-cn/device-dev/security/\351\232\220\347\247\201\344\277\235\346\212\244.md" deleted file mode 100755 index 3777685f3ff4a8e3cdd3e43aad55008b8d02fa27..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/security/\351\232\220\347\247\201\344\277\235\346\212\244.md" +++ /dev/null @@ -1,264 +0,0 @@ -# 隐私保护 - -- [隐私保护概述](#section13200134331414) -- [数据分类分级](#section2371104991511) -- [通用隐私设计规则](#section10354102411162) -- [特殊品类要求](#section118861450201618) - -## 隐私保护概述 - -随着互联网及信息化的发展,个人数据在社会经济和日常生活中发挥着越来越重要的作用。与此同时,个人数据泄露的风险也在增加,消费者产品开发者需要更加有效的保护用户的个人数据,提高用户对产品的信任度。为了提升消费者的隐私体验,产品应默认设置较高级别隐私保护策略,达到保护消费者隐私的目的。 - -**基本概念** - -- **个人数据(Personal Data)** - - 与一个身份已被识别或者身份可被识别的自然人(“数据主体”)相关的任何信息;身份可识别的自然人是指其身份可以通过诸如姓名、身份证号、位置数据等识别码或者通过一个或多个与自然人的身体、生理、精神、经济、文化或者社会身份相关的特定因素来直接或者间接地被识别。个人数据包括:自然人的email地址、电话号码、生物特征(指纹)、位置数据、IP地址、医疗信息、宗教信仰、社保号、婚姻状态等。 - -- **敏感个人数据(Sensitive Personal Data)** - - 敏感个人数据是个人数据的一个重要子集,指的是涉及数据主体的最私密领域的信息或者一旦泄露可能会给数据主体造成重大不利影响的数据。欧盟等国家和地区法律定义的敏感个人数据包括种族、政治观点、宗教和哲学信仰、工会成员资格、基因数据、生物信息、健康和性生活状况、性取向等。 - - 根据业界最佳实践,敏感个人数据还包括可与自然人身份相关联的银行卡号、身份证号、护照号、口令等。敏感个人数据的处理需要更多更严格的保护措施。 - -- **公开个人数据(Public available Personal Data)** - - 数据主体主动公开的个人数据,或公开网页/应用上可访问的个人数据,包括论坛公开的发帖、评论等。 - -- **用户画像(User Profile)** - - 指对个人数据采取的任何自动化处理的方式,包括评估某个自然人特定方面的情况,尤其是为了分析和预测该自然人的工作表现、经济状况、健康、个人喜好、兴趣、可信度、行为举止、所在位置或行迹。 - -- **数据控制者(Data Controller)** - - 单独或者与他人共同确定个人数据处理的目的和手段的自然人、法人、公共机构、政府部门或其他机构。 - -- **数据处理者(Data Processor)** - - 指代表数据控制者处理个人数据的自然人、法人、公共机构、政府部门或其他机构。数据处理者必须按照数据控制者的要求对个人数据进行充分的保护。 - -- **明示同意(Explicit consent)** - - 如下几种情形GDPR法律提到可以通过数据主体明示同意的方式合法地处理数据: - - - 处理敏感个人数据。 - - 自动化决策,包括进行用户画像。 - - 向不具备充分保护水平的国家转移个人数据,并以同意作为合法性基础。 - - 实现明示同意的方式有: - - - 在收集特定数据时,弹出隐私声明告知个人数据处理相关事项,提供勾选框但不默认勾选,让数据主体勾选“我同意以上述方式处理我的个人数据”,或提供“我同意”的按钮让用户主动点击。 - - 以书面的方式明确表达同意,数据主体在书面陈述上签字。 - - 要求数据主体在系统中上传带有其签名的电子表格。 - - 采取双重验证的方式,要求数据主体邮件形式回复同意后,再次点击用于验证的邮件链接或是输入SMS验证码。 - - 用户主动输入的场景,例如用户主动输入身份证和银行卡号绑卡等场景。 - - -## 数据分类分级 - -基于数据保护目标及风险后果,即数据遭到泄露或者遭到破坏带来的法律风险对个人、组织或公众的影响对数据进行定级,分为极高、高、中、低、公开五个数据级别。 - -**表1** 数据分类分级标准 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

数据级别

-

隐私风险

-

隐私属性

-

典型示例

-

极高级

-

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来灾难性负面影响。

-

敏感个人数据

-

DNA、种族、宗教信仰、性取向;生物识别信息;原始通信内容;银行卡密码、磁道数据。

-

高级别

-

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来严重负面影响。

-

敏感个人数据

-

权威社会标识(身份证、护照等);网页浏览记录;轨迹信息;云空间上传的内容数据(图库/音频/视频等)。

-

中级别

-

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来重大负面影响。

-

一般个人数据

-

设备标识(IMEI, SN, OAID )、用户标识(user ID);个人基本信息(姓名,地址);手机号、邮箱等。

-

低级别

-

数据一旦识别或关联到特定个人或群体,其泄露或不当使用可能会给个人带来有限负面影响。

-

一般个人数据

-

操作系统设置信息(操作系统版本,国家/地区等);设备硬件信息(设备型号,屏幕尺寸,屏幕分辨率等);网络信息(网络连接状态,接入网络信息);设备状态(登录设备时间/时长)。

-

公开(无风险)

-

对个人或组织无不利影响的可公开数据

-

非个人数据

-

公开发布的产品介绍,公开的会议信息,外部开源的代码等。

-
- -备注:隐私保护和数据分类分级的相关定义参照GDPR中的相关内容。 - -## 通用隐私设计规则 - -为了指导厂商完成产品的隐私设计工作,我们整理了以下通用的隐私设计要求,作为OpenHarmony设备厂商产品隐私设计的指南和参考。 - -**数据收集及使用公开透明** - -采集个人数据时,应清晰、明确地告知用户,并确保告知用户的个人信息将被如何使用。 - -- 针对不同等级的个人数据需要制定针对性的隐私处理策略。 - - 敏感个人数据的采集需要获取数据主体明示同意。 - - 一般个人数据的采集需要数据主体同意或基于其他合法授权。 - - 非个人数据与中、高或极高级别个人数据关联采集,需要数据主体同意或其他合法授权,并在隐私声明中呈现。 - -- 应制定并遵从适当的隐私政策。在收集、使用留存和第三方分享用户个人数据时需要符合所有适用法律、政策和规定。如在收集个人数据前,需充分告知用户处理个人数据的种类、目的、处理方式、保留期限等,满足数据主体权利相关要求。 - - 根据以上要求,我们设计了正确示例以供参考。隐私通知/声明的参考示例如下: - - **图 1** 隐私通知/声明示例图 - - - ![](figures/2-应用启动预授权.png) ![](figures/3-应用隐私声明.png) - -- 个人数据应当基于具体、明确、合法的目的收集,不应与此目的不相符的方式作进一步处理。对于收集目的变更和用户撤销同意后再次重新使用的场景都需要用户重新同意。隐私声明变更和撤销的示例如下图: - - **图 2** 隐私通知/声明变更示例图 - - - ![](figures/4-隐私声明变更通知.png) - - **图 3** 撤销同意示例图 - - - ![](figures/6-1-隐私声明撤销.png) ![](figures/6-2-隐私声明撤销.png) - -- 需要提供用户查看隐私声明的入口。例如,可以在应用的“关于”界面提供查看隐私声明的入口,如示例图所示: - - **图 4** 隐私声明查看界面示例图 - - - ![](figures/5-应用隐私声明入口.png) - - -**数据收集及使用最小化** - -个人数据收集应与数据处理目的相关,且是适当、必要的。开发者应尽可能对个人数据进行匿名化或假名化处理,降低对数据主体的风险。仅可收集和处理与特定目的相关且必需的个人数据,不能进行与特定目的不相关的进一步处理。 - -- 敏感权限申请的时候要满足权限最小化的要求,在申请权限时,只申请获取必需的信息或资源所需要的权限。如应用不需要相机权限就能够实现其功能时,则不应该向用户申请相机权限。 -- 数据收集最小化:针对数据的收集要满足最小化要求,不收集与产品提供服务无关联的数据。如提供定位服务的产品,不应收集用户的网页浏览记录。 -- 数据使用的功能要求能够使用户受益,收集的数据不能用于一些与用户正常使用无关的功能。数据收集不能有其他与用户正常使用无关的功能存在。如不得将“生物特征”、“健康数据”等敏感个人数据用于服务改进、投放广告或营销等非业务核心功能。 -- 禁止在日志中打印敏感个人数据,如需要打印一般个人数据时,应对个人数据进行匿名化或假名化处理; - - 优先使用可以重置的标识符,如系统提供了NetworkID和DVID作为分布式场景下的设备标识符,广告业务场景下则建议使用[OAID](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/oaid-0000001050783198),基于应用的分析则建议使用[ODID](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/odid-0000001051063255)和[AAID](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/aaid-0000001051142988),其他需要唯一标识符的场景可以使用UUID接口生成;可重置的标识符不能满足业务需求时,才选择序列号和MAC地址等永久性标识符。 - - -**数据处理选择和控制** - -对个人数据处理必须要征得用户的同意或遵守其他适用的法律法规,用户对其个人数据要有充分的控制权。 - -- 获取用户敏感权限的授权:产品弹窗提醒,向用户呈现需要获取的权限和权限使用目的,用户可通过选择决定是否进行授权及指定授权的方式,让用户对产品权限的授予和个人数据使用做到透明、可知、可控。如下图所示: - - **图 5** 敏感权限提示框示例图 - - - ![](figures/1-敏感权限弹窗.png) - -- 用户可以修改、取消授予的权限:当用户不同意某一权限或者数据收集时,应当允许用户使用与这部分权限和数据收集不相关的功能。如智慧屏产品上通信社交应用,用户可以拒绝授予相机权限,不应该影响与相机无关的功能操作,如语音通话。 -- 用户在产品使用过程中,针对录入个人数据的场景,需要给用户提供对个人数据的增加、删除、修改、查看的操作。 -- 需要给出硬件回收或返厂进行安全删除个人数据的机制或方法。 -- 对用户系统软件、应用软件的下载或升级,涉及修改用户隐私空间,用户对于这类行为需要有知情权和控制权,必须给用户提示,并提供给用户同意和取消的选项。 - -**数据安全** - -从技术上保证数据处理活动的安全性,包括个人数据的加密存储、安全传输等安全机制,系统应默认开启或采取安全保护措施。 - -- 对于个人数据的访问需要有保护机制,主要包括身份认证和访问控制。身份认证(如用户名、密码)限定只有经过认证的用户才能访问数据,可应用于多用户场景;访问控制(如[权限控制](安全指南.md#li201725506375))可应用于对应用程序的限制。 -- 分布式设备个人数据安全存储要满足密钥管理和存储服务(HUKS:Huawei Universal Keystore)的要求,包括:密钥安全存储、数据安全存储。 -- 个人数据在分布式设备间传输要满足设备间的信任绑定关系和数据传输通道的安全性要求。详细信息可以参考[设备互联安全](安全指南.md#section26153183616)。 -- 认证凭证数据(密码、口令、指纹等)须加密存储。 - -**本地化处理** - -用户数据优先在本设备进行处理,对于本设备无法处理的数据应尽可能在超级终端设备本地进行数据的处理,如果超级终端本地处理无法满足业务目的的,在数据离开超级终端设备本地时应尽可能选择匿名化。 - -**未成年人数据保护要求** - -产品专门给未成年人设计的,或者产品收集用户年龄从而可以识别到是在收集未成年人的个人数据,需结合目标市场国家的法律,专门分析未成年人个人数据保护的问题,收集未成年人数据前需要征得监护人的同意。 - -## 特殊品类要求 - -针对消费者硬件产品来说,除了满足以上的通用隐私要求以外,针对特殊品类的产品还有以下的特殊要求,在产品设计过程中参照执行。 - -**表2** 特殊品类隐私要求 - - - - - - - - - - - - - - - - - - - - - - - - - -

产品品类

-

隐私保护特殊要求

-

智能家居

-

安防类产品涉及的指纹、声纹、面部识别、虹膜等个人生物识别信息以及用户密码信息,属于敏感个人数据,应采用技术措施处理后(例如提取个人生物识别信息的摘要)再进行加密保存在产品本地。

-

智能家居

-

安防类产品涉及的音视频和图片,设备厂家作为数据控制者时,必须提供独立的隐私通知、应用界面必须有设备厂家品牌标识;音视频数据的传输和存储必须加密,非用户本人访问安防产品的音视频数据,必须获得用户授权。

-

智能家居/影音娱乐

-

带有摄像头的产品建议提供物理上可关闭功能,通过隐藏、遮盖、转向让消费者感知摄像头处于关闭状态。

-

智能家居/影音娱乐

-

带有麦克风的产品建议提供显性显示录音的状态,如录音开启时状态灯闪烁,录音关闭时状态灯熄灭。

-

移动办公

-

用户数据跨设备显示、传输等场景需要获得消费者的明示同意,给予消费者对其个人数据有充分的控制权。

-

车机

-

1、隐私通知及权限设置

-

避免在驾驶态让用户阅读隐私政策和权限设置。

-

车机应用需要考虑车辆使用时的安全性,应避免让用户在驾驶过程中进行复杂的权限设置或阅读隐私政策,比如HiCar应用应该在手机端完成应用基本权限设置和隐私政策阅读后再进行使用。

-

隐私声明在确认用户身份后告知。

-

车辆的数据会涉及车主、驾驶员和乘客,应保证隐私声明通知到了数据主体本人。建议做法是在确认使用者的身份后进行隐私声明,如需要用户登录的应用,应在账号登录后弹出隐私声明而不是账号登录之前。

-

2、共享应用个人数据保护

-

共享应用在车机重启后应退出,并对当前用户个人数据进行清除或加密,应用还应提供对历史数据进行彻底删除的功能。

-

3、消息提示

-

考虑车机的开放环境,应用在车机上进行消息提醒时,应避免直接将消息内容显示在车机上,正确的做法是仅提示有新的消息需要查看。

-
- diff --git "a/zh-cn/device-dev/subsystems/AI\345\274\225\346\223\216\346\241\206\346\236\266\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/zh-cn/device-dev/subsystems/AI\345\274\225\346\223\216\346\241\206\346\236\266\345\274\200\345\217\221\346\214\207\345\215\227.md" deleted file mode 100755 index b0e0db564441d0635b30ef90c3369a163823e0f3..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/AI\345\274\225\346\223\216\346\241\206\346\236\266\345\274\200\345\217\221\346\214\207\345\215\227.md" +++ /dev/null @@ -1,9 +0,0 @@ -# AI引擎框架开发指南 - -AI业务子系统是OpenHarmony提供原生的分布式AI能力的子系统。AI业务子系统提供了统一的AI引擎框架,实现算法能力快速插件化集成。框架中主要包含插件管理、模块管理和通信管理等模块,完成对AI算法能力的生命周期管理和按需部署。插件管理主要实现插件的生命周期管理及插件的按需部署,快速集成AI能力插件;模块管理主要实现任务的调度及管理客户端的实例;通信管理主要实现客户端和服务端之间的跨进程通信及引擎与插件之间的数据传输。后续,会逐步定义统一的AI能力接口,便于AI能力的分布式调用。同时,提供适配不同推理框架层级的统一推理接口。AI引擎框架如下[图1](#fig143186187187)所示。 - -**图 1** AI引擎框架 - - -![](figures/zh-cn_image_0000001077727032.png) - diff --git "a/zh-cn/device-dev/subsystems/AI\346\241\206\346\236\266.md" "b/zh-cn/device-dev/subsystems/AI\346\241\206\346\236\266.md" deleted file mode 100755 index c4310aa764280d27ea890292596524653beb731e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/AI\346\241\206\346\236\266.md" +++ /dev/null @@ -1,13 +0,0 @@ -# AI框架 - -- **[AI引擎框架开发指南](AI引擎框架开发指南.md)** - -- **[搭建环境](搭建环境.md)** - -- **[技术规范](技术规范.md)** - -- **[开发指导](开发指导.md)** - -- **[开发示例](开发示例.md)** - - diff --git a/zh-cn/device-dev/subsystems/DFX.md b/zh-cn/device-dev/subsystems/DFX.md deleted file mode 100755 index e5f00a7203adb883c359ee2b11eb1b56c60d7173..0000000000000000000000000000000000000000 --- a/zh-cn/device-dev/subsystems/DFX.md +++ /dev/null @@ -1,11 +0,0 @@ -# DFX - -- **[DFX概述](DFX概述.md)** - -- **[HiLog开发指导](HiLog开发指导.md)** - -- **[HiLog\_Lite开发指导](HiLog_Lite开发指导.md)** - -- **[HiSysEvent开发指导](HiSysEvent开发指导.md)** - - diff --git "a/zh-cn/device-dev/subsystems/OTA\345\215\207\347\272\247.md" "b/zh-cn/device-dev/subsystems/OTA\345\215\207\347\272\247.md" deleted file mode 100755 index 0423c0b61223ca02bac79eeb499b659bc03b1b36..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/OTA\345\215\207\347\272\247.md" +++ /dev/null @@ -1,358 +0,0 @@ -# OTA升级 - -- [约束与限制](#section691733275418) -- [生成公私钥对](#section94411533155010) -- [生成升级包](#section632383718539) -- [上传升级包](#section5772112473213) -- [下载升级包](#section251732474917) -- [厂商应用集成OTA能力](#section298217330534) -- [API应用场景-默认场景](#section7685171192916) - - [开发指导](#section0745926153017) - - [示例代码](#section1337111363306) - -- [API应用场景-定制场景](#section1686395317306) - - [开发指导](#section524515314317) - - [示例代码](#section525974743120) - -- [系统升级](#section151997114334) - -OTA(Over the Air)提供对设备远程升级的能力,可以让您的设备(如IP摄像头等),轻松支持远程升级能力。目前仅支持全量包升级,暂不支持差分包升级。全量包升级是将新系统全部内容做成升级包,进行升级;差分包升级是将新老系统的差异内容做成升级包,进行升级。 - -## 约束与限制 - -- 支持基于Hi3861/Hi3518EV300/Hi3516DV300芯片的开源套件。 -- 对Hi3518EV300/Hi3516DV300开源套件,设备需要支持SD卡(VFAT格式)。 - -## 生成公私钥对 - -1. 准备工作:在Windows PC 上,下载安装OpenSSL工具,并配置环境变量。OpenSSL下载路径: - - [http://slproweb.com/products/Win32OpenSSL.html](http://slproweb.com/products/Win32OpenSSL.html) - -2. 在tools\\update\_tools\\update\_pkg\_tools目录下,下载升级包制作工具,保存到Windows本地路径,例如D:\\ota\_tools。 -3. 如图,运行ota\_tools\\key下的Generate\_public\_private\_key.bat ,生成公钥Metis\_PUBLIC.key、私钥private.key和公钥对应的数组public\_arr.txt文件,请妥善保管私钥private.key。 - - **图 1** 生成公私钥对 - - - ![](figures/zh-cn_image_0000001060200050.png) - -4. 用public\_arr.txt里面的全部内容替换OTA模块base\\update\\ota\_lite\\frameworks\\source\\verify\\hota\_verify.c中的g\_pubKeyBuf 。 - - 示例,public\_arr.txt内容 - - ``` - 0x30,0x82,0x1,0xa,0x2,0x82,0x1,0x1,0x0,0xc7,0x8c,0xf3,0x91,0xa1,0x98,0xbf,0xb1,0x8c, - 0xbe,0x22,0xde,0x32,0xb2,0xfa,0xec,0x2c,0x69,0xf6,0x8f,0x43,0xa7,0xb7,0x6f,0x1e,0x4a,0x97, - 0x4b,0x27,0x5d,0x56,0x33,0x9a,0x73,0x4e,0x7c,0xf8,0xfd,0x1a,0xf0,0xe4,0x50,0xda,0x2b,0x8, - 0x74,0xe6,0x28,0xcc,0xc8,0x22,0x1,0xa8,0x14,0x9,0x46,0x46,0x6a,0x10,0xcd,0x39,0xd,0xf3, - 0x4a,0x7f,0x1,0x63,0x21,0x33,0x74,0xc6,0x4a,0xeb,0x68,0x40,0x55,0x3,0x80,0x1d,0xd9,0xbc, - 0xd4,0xb0,0x4a,0x84,0xb7,0xac,0x43,0x1d,0x76,0x3a,0x61,0x40,0x23,0x3,0x88,0xcc,0x80,0xe, - 0x75,0x10,0xe4,0xad,0xac,0xb6,0x4c,0x90,0x8,0x17,0x26,0x21,0xff,0xbe,0x1,0x82,0x16,0x76, - 0x9a,0x1c,0xee,0x8e,0xd9,0xb0,0xea,0xd5,0x50,0x61,0xcc,0x9c,0x2e,0x78,0x15,0x2d,0x1f,0x8b, - 0x94,0x77,0x30,0x39,0x70,0xcf,0x16,0x22,0x82,0x99,0x7c,0xe2,0x55,0x37,0xd4,0x76,0x9e,0x4b, - 0xfe,0x48,0x26,0xc,0xff,0xd9,0x59,0x6f,0x77,0xc6,0x92,0xdd,0xce,0x23,0x68,0x83,0xbd,0xd4, - 0xeb,0x5,0x1b,0x2a,0x7e,0xda,0x9a,0x59,0x93,0x41,0x7b,0x4d,0xef,0x19,0x89,0x4,0x8d,0x5, - 0x7d,0xbc,0x3,0x1f,0x77,0xe6,0x3d,0xa5,0x32,0xf5,0x4,0xb7,0x9c,0xe9,0xfa,0x6e,0xc,0x9f, - 0x4,0x62,0xfe,0x2a,0x5f,0xbf,0xeb,0x9a,0x73,0xa8,0x2a,0x72,0xe3,0xf0,0x57,0x56,0x5c,0x59, - 0x14,0xdd,0x79,0x11,0x42,0x3a,0x48,0xf7,0xe8,0x80,0xb1,0xaf,0x1c,0x40,0xa2,0xc6,0xec,0xf5, - 0x67,0xc1,0x88,0xf6,0x26,0x5c,0xd3,0x11,0x5,0x11,0xed,0xb1,0x45,0x2,0x3,0x1,0x0,0x1, - ``` - - 示例,OTA模块的公钥 - - ``` - #define PUBKEY_LENGTH 270 - - static uint8 g_pubKeyBuf[PUBKEY_LENGTH] = { - 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, - 0x63, 0x07, 0x84, 0xCF, 0x37, 0xF0, 0x45, 0xE8, 0xB9, 0x6E, 0xEF, 0x04, 0x88, 0xD3, 0x43, 0x06, - ``` - -5. 对Hi3518EV300/Hi3516DV300套件,在上一步的基础上,还需用public\_arr.txt里面的全部内容替换uboot模块device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\verify\\update\_public\_key.c中的g\_pub\_key中的全部内容。 - - 示例,uboot模块的公钥 - - ``` - static unsigned char g_pub_key[PUBKEY_LEN] = { - 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, - 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, - ``` - - -## 生成升级包 - -1. 在ota\_tools\\Components目录下,归放需要升级的文件。 - - **图 2** 原始镜像归放位置 - - - ![](figures/zh-cn_image_0000001061889268.png) - - **表 1** 升级包内的文件 - - - - - - - - - - - - - - - - - - - - - - -

包内文件名

-

说明

-

u-boot.bin

-

将编译生成的u-boot-hi351XevX00.bin文件重命名后得到。

-

kernel.bin

-

将编译生成的liteos.bin/kernel文件重命名后得到。

-

rootfs.img

-

将编译生成的rootfs_xxxxx.img文件重命名后得到。

-

config

-

与开发板类型和内核类型相关,参考开源套件的SD卡烧写说明。

-

OTA.tag

-

共32字节,内容为:“package_type:otaA1S2D3F4G5H6J7K8”;其中后16字节为随机数,需要随版本变化。

-
- -2. 修改ota\_tools\\xml下的packet\_harmony.xml文件,配置compAddr分区名,对应ota\_tools\\Components\\的文件,其它项不需修改,作为扩展项预留。 - - 示例,配置组件信息 - - ``` - - - .\Components\rootfs_jffs2.img - .\Components\liteos.bin - .\Components\userfs_jffs2.img - - ``` - -3. 将生成的公私钥路径配置到ota\_tools\\xml路径下的packet\_harmony.xml中。 - - 示例,配置公私钥路径 - - ``` - - .\key\private.key - .\key\Metis_PUBLIC.key - - ``` - -4. 在ota\_tools\\VersionDefine.bat中设置产品名称、软件版本号(用于防回滚校验)。 - - 示例,配置产品名称和版本号 - - ``` - set FILE_PRODUCT_NAME=Hisi - - @rem 设置软件版本号 不要超过16位 - set SOFTWARE_VER=OpenHarmony 1.1 - ``` - -5. 执行ota\_tools下的Make\_Harmony\_PKG.bat,生成升级包Hisi\_OpenHarmony 1.1.bin。升级包通过SHA256+RSA2048方式签名,保证完整性和合法性。 - - **图 3** 升级包制作工具 - - - ![](figures/zh-cn_image_0000001059334449.png) - - -## 上传升级包 - -将升级包Hisi\_OpenHarmony 1.1.bin上传到厂商的OTA服务器。 - -## 下载升级包 - -1. 厂商应用从OTA服务器下载Hisi\_OpenHarmony 1.1.bin。 -2. 对Hi3518EV300/Hi3516DV300开源套件,需要插入SD卡\(容量\>100MBytes\)。 - -## 厂商应用集成OTA能力 - -- 调用OTA模块的动态库libhota.so,对应头文件位于:base\\update\\ota\_lite\\interfaces\\kits\\hota\_partition.h&hota\_updater.h; -- libhota.so对应的源码路径为base\\update\\ota\_lite\\frameworks\\source。 -- API的使用方法,见本文“API应用场景”和API文档的OTA接口章节。 -- 如果需要适配开发板,请参考HAL层头文件:base\\update\\ota\_lite\\hals\\hal\_hota\_board.h。 - -## API应用场景-默认场景 - -升级包是按照上文“生成公私钥对”和“生成升级包”章节制作的。 - -### **开发指导** - -1. 应用侧通过下载,获取当前设备升级包后,调用HotaInit接口初始化OTA模块。 -2. 调用HotaWrite接口传入升级包数据流,接口内部实现校验、解析及写入升级数据流。 -3. 写入完成后,调用HotaRestart接口重启系统。 - - 升级过程中,使用HotaCancel接口可以取消升级。 - - -### **示例代码** - -使用OpenHarmony的“升级包格式和校验方法“进行升级。 - -``` -int main(int argc, char **argv) -{ - printf("this is update print!\r\n"); - if (HotaInit(NULL, NULL) < 0) { - printf("ota update init fail!\r\n"); - return -1; - } - int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) { - printf("file open failed, fd = %d\r\n", fd); - (void)HotaCancel(); - return -1; - } - int offset = 0; - int fileLen = lseek(fd, 0, SEEK_END); - int leftLen = fileLen; - while (leftLen > 0) { - if (lseek(fd, offset, SEEK_SET) < 0) { - close(fd); - printf("lseek fail!\r\n"); - (void)HotaCancel(); - return -1; - } - int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; - (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); - if (read(fd, g_readBuf, tmpLen) < 0) { - close(fd); - printf("read fail!\r\n"); - (void)HotaCancel(); - return -1; - } - if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { - printf("ota write fail!\r\n"); - close(fd); - (void)HotaCancel(); - return -1; - } - offset += READ_BUF_LEN; - leftLen -= tmpLen; - } - close(fd); - printf("ota write finish!\r\n"); - printf("device will reboot in 10s...\r\n"); - sleep(10); - (void)HotaRestart(); - return 0; -} -``` - -## API应用场景-定制场景 - -升级包不是按照上文“生成公私钥对”和“生成升级包”章节制作的,是通过其它方式制作的。 - -### **开发指导** - -1. 应用侧通过下载,获取当前设备升级包后,调用HotaInit接口初始化。 -2. 使用HotaSetPackageType接口设置NOT\_USE\_DEFAULT\_PKG,使用"定制"流程。 -3. 调用HotaWrite接口传入升级包数据流,写入设备。 -4. 写入完成后,调用HotaRead接口读取数据,厂商可以自行校验升级包。 -5. 调用HotaSetBootSettings设置启动标记,在重启后需要进入uboot模式时使用(可选)。 -6. 调用HotaRestart接口,进行重启。 - - 升级过程中,使用HotaCancel接口可以取消升级。 - - -### **示例代码** - -使用非OpenHarmony的“升级包格式和校验方法“进行升级。 - -``` -int main(int argc, char **argv) -{ - printf("this is update print!\r\n"); - if (HotaInit(NULL, NULL) < 0) { - printf("ota update init fail!\r\n"); - (void)HotaCancel(); - return -1; - } - (void)HotaSetPackageType(NOT_USE_DEFAULT_PKG); - int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) { - printf("file open failed, fd = %d\r\n", fd); - (void)HotaCancel(); - return -1; - } - int offset = 0; - int fileLen = lseek(fd, 0, SEEK_END); - int leftLen = fileLen; - while (leftLen > 0) { - if (lseek(fd, offset, SEEK_SET) < 0) { - close(fd); - printf("lseek fail!\r\n"); - (void)HotaCancel(); - return -1; - } - int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; - (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); - if (read(fd, g_readBuf, tmpLen) < 0) { - close(fd); - printf("read fail!\r\n"); - (void)HotaCancel(); - return -1; - } - if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { - printf("ota write fail!\r\n"); - close(fd); - (void)HotaCancel(); - return -1; - } - offset += READ_BUF_LEN; - leftLen -= tmpLen; - } - close(fd); - printf("ota write finish!\r\n"); - leftLen = fileLen; - while (leftLen > 0) { - int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; - (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); - if (HotaRead(offset, READ_BUF_LEN, (unsigned char *)g_readBuf) != 0) {} - printf("ota write fail!\r\n"); - (void)HotaCancel(); - return -1; - } - /* do your verify and parse */ - offset += READ_BUF_LEN; - leftLen -= tmpLen; - } - /* set your boot settings */ - (void)HotaSetBootSettings(); - printf("device will reboot in 10s...\r\n"); - sleep(10); - (void)HotaRestart(); - return 0; -} -``` - -## 系统升级 - -厂商应用调用OTA模块的API,OTA模块执行升级包的签名验证、版本防回滚、烧写落盘功能,升级完成后自动重启系统。 - -对Hi3518EV300/Hi3516DV300开源套件,在需要实现防回滚功能的版本中,需要增加LOCAL\_VERSION的值,如"ohos default 1.0"-\>"ohos default 1.1",LOCAL\_VERSION在device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\ota\_update\\ota\_local\_info.c中。 - -示例,增加版本号 - -``` -const char *get_local_version(void) -{ -#if defined(CONFIG_TARGET_HI3516EV200) || \ - defined(CONFIG_TARGET_HI3516DV300) || \ - defined(CONFIG_TARGET_HI3518EV300) -#define LOCAL_VERSION "ohos default 1.0" /* increase: default release version */ -``` - diff --git a/zh-cn/device-dev/subsystems/Readme-CN.md b/zh-cn/device-dev/subsystems/Readme-CN.md index 3032d57b57d4c11908aae5e450f92382b11bd886..843563ec81e16ad3c87a21e020cc28bca5b3a5fb 100755 --- a/zh-cn/device-dev/subsystems/Readme-CN.md +++ b/zh-cn/device-dev/subsystems/Readme-CN.md @@ -1,96 +1,78 @@ -# 子系统 - -- [编译构建](编译构建.md) - - [轻量和小型系统编译构建指导](轻量和小型系统编译构建指导.md) - - [编译构建概述](编译构建概述.md) - - [编译构建使用指导](编译构建使用指导.md) - - [编译构建常见问题](编译构建常见问题.md) - - - [标准系统编译构建指导](标准系统编译构建指导.md) - - [编译构建概述](编译构建概述-0.md) - - [编译构建使用指导](编译构建使用指导-1.md) - -- [分布式远程启动](分布式远程启动.md) -- [图形图像](图形图像.md) - - [图形图像概述](图形图像概述.md) - - [容器类组件开发指导](容器类组件开发指导.md) - - [布局容器类组件开发指导](布局容器类组件开发指导.md) - - [普通组件开发指导](普通组件开发指导.md) - - [动画开发指导](动画开发指导.md) - -- [媒体](媒体.md) - - [相机](相机.md) - - [相机开发概述](相机开发概述.md) - - [拍照开发指导](拍照开发指导.md) - - [录像开发指导](录像开发指导.md) - - [预览开发指导](预览开发指导.md) - - - [音视频](音视频.md) - - [音视频开发概述](音视频开发概述.md) - - [音视频播放开发指导](音视频播放开发指导.md) - - [音视频录制开发指导](音视频录制开发指导.md) - -- [公共基础](公共基础.md) - - [公共基础库概述](公共基础库概述.md) - - [公共基础库开发指导](公共基础库开发指导.md) - - [公共基础库常见问题](公共基础库常见问题.md) - -- [AI框架](AI框架.md) - - [AI引擎框架开发指南](AI引擎框架开发指南.md) - - [搭建环境](搭建环境.md) - - [技术规范](技术规范.md) - - [代码管理规范](代码管理规范.md) - - [命名规范](命名规范.md) - - [接口开发规范](接口开发规范.md) - - - [开发指导](开发指导.md) - - [SDK开发过程](SDK开发过程.md) - - [插件的开发过程](插件的开发过程.md) - - [配置文件的开发过程](配置文件的开发过程.md) - - - [开发示例](开发示例.md) - - [唤醒词识别SDK的开发示例](唤醒词识别SDK的开发示例.md) - - [唤醒词识别插件的开发示例](唤醒词识别插件的开发示例.md) - - [唤醒词识别配置文件的开发示例](唤醒词识别配置文件的开发示例.md) - -- [Sensor服务](Sensor服务.md) - - [Sensor服务子系概述](Sensor服务子系概述.md) - - [Sensor服务子系使用指导](Sensor服务子系使用指导.md) - - [Sensor服务子系使用实例](Sensor服务子系使用实例.md) - -- [用户程序框架](用户程序框架.md) - - [概述](概述.md) - - [搭建环境](搭建环境-2.md) - - [开发指导](开发指导-3.md) - - [开发实例](开发实例.md) - -- [OTA升级](OTA升级.md) - -- [安全](安全.md) - - [概述](概述-7.md) - - [应用验签开发指导](应用验签开发指导.md) - - [应用权限管理开发指导](应用权限管理开发指导.md) - - [IPC通信鉴权开发指导](IPC通信鉴权开发指导.md) - -- [启动恢复](启动恢复.md) - - [启动恢复子系统概述](启动恢复子系统概述.md) - - [init启动引导组件](init启动引导组件.md) - - [appspawn应用孵化组件](appspawn应用孵化组件.md) - - [bootstrap服务启动组件](bootstrap服务启动组件.md) - - [syspara系统属性组件](syspara系统属性组件.md) - - [常见问题](常见问题.md) - - [参考](参考.md) - -- [测试](测试.md) -- [DFX](DFX.md) - - [DFX概述](DFX概述.md) - - [HiLog开发指导](HiLog开发指导.md) - - [HiLog\_Lite开发指导](HiLog_Lite开发指导.md) - - [HiSysEvent开发指导](HiSysEvent开发指导.md) - -- [研发工具链](研发工具链.md) - - [bytrace使用指导](bytrace使用指导.md) - - [hdc\_std 使用指导](hdc_std-使用指导.md) - -- [XTS认证子系统开发指南](XTS认证子系统开发指南.md) +# 子系统开发指南 + +- [编译构建](subsys-build.md) + - [轻量和小型系统编译构建指导](subsys-build-mini-lite.md) + - [标准系统编译构建指导](subsys-build-standard-large.md) +- [分布式远程启动](subsys-remote-start.md) +- [图形图像](subsys-graphics.md) + - [图形图像概述](subsys-graphics-overview.md) + - [容器类组件开发指导](subsys-graphics-bundle-guide1.md) + - [布局容器类组件开发指导](subsys-graphics-bundle-guide2.md) + - [普通组件开发指导](subsys-graphics-bundle-guide3.md) + - [动画开发指导](subsys-graphics-animation-guide.md) +- [媒体](subsys-multimedia.md) + - [相机](subsys-multimedia-camera.md) + - [相机开发概述](subsys-multimedia-camera-overview.md) + - [拍照开发指导](subsys-multimedia-camera-photo-guide.md) + - [录像开发指导](subsys-multimedia-camera-record-guide.md) + - [预览开发指导](subsys-multimedia-camera-preview-guide.md) + + - [音视频](subsys-multimedia-video.md) + - [音视频开发概述](subsys-multimedia-video-overview.md) + - [音视频播放开发指导](subsys-multimedia-video-play-guide.md) + - [音视频录制开发指导](subsys-multimedia-video-record-guide.md) +- [公共基础](subsys-utils.md) + - [公共基础库概述](subsys-utils-overview.md) + - [公共基础库开发指导](subsys-utils-guide.md) + - [公共基础库常见问题](subsys-utils-faqs.md) +- [AI框架](subsys-aiframework.md) + - [AI引擎框架开发指南](subsys-aiframework-guide.md) + - [搭建环境](subsys-aiframework-envbuild.md) + - [技术规范](subsys-aiframework-tech.md) + - [代码管理规范](subsys-aiframework-tech-codemanage.md) + - [命名规范](subsys-aiframework-tech-name.md) + - [接口开发规范](subsys-aiframework-tech-interface.md) + + - [开发指导](subsys-aiframework-devguide.md) + - [SDK开发过程](subsys-aiframework-devguide-sdk.md) + - [插件的开发过程](subsys-aiframework-devguide-plugin.md) + - [配置文件的开发过程](subsys-aiframework-devguide-conf.md) + + - [开发示例](subsys-aiframework-demo.md) + - [唤醒词识别SDK的开发示例](subsys-aiframework-demo-sdk.md) + - [唤醒词识别插件的开发示例](subsys-aiframework-demo-plugin.md) + - [唤醒词识别配置文件的开发示例](subsys-aiframework-demo-conf.md) +- [Sensor服务](subsys-sensor.md) + - [Sensor服务子系概述](subsys-sensor-overview.md) + - [Sensor服务子系使用指导](subsys-sensor-guide.md) + - [Sensor服务子系使用实例](subsys-sensor-demo.md) +- [用户程序框架](subsys-application-framework.md) + - [概述](subsys-application-framework-overview.md) + - [搭建环境](subsys-application-framework-builden.md) + - [开发指导](subsys-application-framework-guide.md) + - [开发实例](subsys-application-framework-demo.md) +- [OTA升级](subsys-ota-guide.md) +- [安全](subsys-security.md) + - [概述](subsys-security-overview.md) + - [应用验签开发指导](subsys-security-sigverify.md) + - [应用权限管理开发指导](subsys-security-rightmanagement.md) + - [IPC通信鉴权开发指导](subsys-security-communicationverify.md) +- [启动恢复](subsys-boot.md) + - [启动恢复子系统概述](subsys-boot-overview.md) + - [init启动引导组件](subsys-boot-init.md) + - [appspawn应用孵化组件](subsys-boot-appspawn.md) + - [bootstrap服务启动组件](subsys-boot-bootstrap.md) + - [syspara系统属性组件](subsys-boot-syspara.md) + - [常见问题](subsys-boot-faqs.md) + - [参考](subsys-boot-ref.md) +- [测试](subsys-testguide-test.md) +- [DFX](subsys-dfx.md) + - [DFX概述](subsys-dfx-overview.md) + - [HiLog开发指导](subsys-dfx-hilog-rich.md) + - [HiLog\_Lite开发指导](subsys-dfx-hilog-lite.md) + - [HiSysEvent开发指导](subsys-dfx-hisysevent.md) +- [研发工具链](subsys-toolchain.md) + - [bytrace使用指导](subsys-toolchain-bytrace-guide.md) + - [hdc\_std 使用指导](subsys-toolchain-hdc-guide.md) +- [XTS认证子系统开发指南](subsys-xts-guide.md) diff --git "a/zh-cn/device-dev/subsystems/SDK\345\274\200\345\217\221\350\277\207\347\250\213.md" "b/zh-cn/device-dev/subsystems/SDK\345\274\200\345\217\221\350\277\207\347\250\213.md" deleted file mode 100755 index 83d933cdb5df36058c1726de5d289c88a9fb2fbb..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/SDK\345\274\200\345\217\221\350\277\207\347\250\213.md" +++ /dev/null @@ -1,162 +0,0 @@ -# SDK开发过程 - -SDK头文件的功能实现是基于对SDK的调用映射到对client的调用。Client端提供的接口如下[表1](#table203963834718)所示。 - -**表 1** Client端提供的接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

接口说明

-

参数要求

-

int AieClientInit(const ConfigInfo &configInfo, ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, IServiceDeadCb *cb)

-

作用:链接并初始化引擎服务,激活跨进程调用。

-

返回值:0为成功,其他返回值失败。

-

configInfo(NOT NULL):引擎相关初始化配置数据;

-

clientInfo(NOT NULL):引擎客户端信息;

-

algorithmInfo(NOT NULL):调用算法信息;

-

cb(可为NULL):死亡回调 对象;

-

int AieClientPrepare(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo, IClientCb *cb)

-

作用:加载算法插件。

-

返回值: 0为成功,其他返回值失败。

-

clientInfo(NOT NULL):引擎客户端信息;

-

algorithmInfo(NOT NULL):调用算法信息;

-

inputInfo(可为NULL):加载算法插件时输入所需信息;

-

outputInfo(可为NULL):加载算法插件之后如需返回信息则通过此出参返回;

-

cb:异步算法通过此回调返回运算结果,因此异步算法此结构体不能为空;若为同步算法,传入空值即可;

-

int AieClientAsyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

-

作用:执行异步算法。

-

返回值:0为成功,其他返回值失败。

-

clientInfo(NOT NULL):引擎客户端信息;

-

algorithmInfo(NOT NULL):调用算法信息;

-

inputInfo(可为NULL):算法运算入参;

-

int AieClientSyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo)

-

作用:执行同步算法。

-

返回值:0为成功,其他返回值失败。

-

clientInfo(NOT NULL):引擎客户端信息;

-

algorithmInfo(NOT NULL):调用算法信息;

-

inputInfo(可为NULL):算法运算入参;

-

outputInfo(可为NULL):同步算法运算结果出参;

-

int AieClientRelease(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

-

作用:卸载算法插件。

-

返回值:0为成功,其他返回值失败。

-

clientInfo(NOT NULL):引擎客户端信息;

-

algorithmInfo(NOT NULL):卸载算法插件的相关信息;

-

inputInfo(可为NULL):调用卸载接口时的输入信息;

-

int AieClientDestroy(ClientInfo &clientInfo)

-

作用:断开与服务端的链接,释放相关缓存。

-

返回值:0为成功,其他返回值失败。

-

clientInfo(NOT NULL):所要销毁的引擎客户端信息;

-

int AieClientSetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo)

-

作用:设置配置项,可将一些算法的拓展信息通过此接口传入插件。

-

返回值:0为成功,其他返回值失败。

-

clientInfo(NOT NULL):引擎客户端信息;

-

optionType (NOT NULL):算法配置项,算法插件可根据需要利用此状态位;

-

inputInfo(可为NULL):插件可根据需要通过此入参设置算法参数信息;

-

int AieClientGetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo, DataInfo &outputInfo)

-

作用:给定特定的optionType和inputInfo,获取其对应的配置项信息。

-

返回值:0为成功,其他返回值失败。

-

clientInfo(NOT NULL):引擎客户端信息;

-

optionType(NOT NULL):所获取配置项信息的对应算法状态位;

-

inputInfo(可为NULL):所获取配置项信息的对应算法参数信息;

-

outputInfo(可为NULL):所要获取的配置项信息返回结果;

-
- -其中,ConfigInfo,ClientInfo,AlgorithmInfo,DataInfo的数据结构如下[表2](#table22154317482)所示。 - -**表 2** ConfigInfo,ClientInfo,AlgorithmInfo,DataInfo的数据结构 - - - - - - - - - - - - - - - - - - - - - - - - -

结构体名称

-

说明

-

属性

-

ConfigInfo

-

算法配置项信息。

-

const char *description:配置项信息主体;

-

ClientInfo

-

客户端信息。

-

long long clientVersion:客户端设备版本号(当前还未启用);

-

int clientId:客户端ID;

-

int sessionId:会话ID;

-

uid_t serverUid:server端UID;

-

uid_t clientUid:client端UID;

-

int extendLen:拓展信息(extendMsg)长度;

-

unsigned char *extendMsg:拓展信息主体;

-

AlgorithmInfo

-

算法信息。

-

long long clientVersion:客户端设备版本号(当前还未启用);

-

bool isAsync:是否为异步执行;

-

int algorithmType:引擎框架根据插件加载顺序分配的算法类型ID;

-

long long algorithmVersion:算法版本号;

-

bool isCloud:是否上云(当前还未启用);

-

int operateId:执行ID(当前还未启用);

-

int requestId:请求ID,标识每次request,以对应执行结果;

-

int extendLen:拓展信息(extendMsg)长度;

-

unsigned char *extendMsg:拓展信息主体;

-

DataInfo

-

算法数据入参(inputInfo)、接口调用结果出参(outputInfo)。

-

unsigned char *data:数据主体;

-

int length:数据(data)长度;

-
- -具体开发过程可参考唤醒词识别SDK开发示例。 - diff --git "a/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241.md" "b/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241.md" deleted file mode 100755 index 35dd6eab91788b22712d1b005b27b182a8333da0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241.md" +++ /dev/null @@ -1,9 +0,0 @@ -# Sensor服务 - -- **[Sensor服务子系概述](Sensor服务子系概述.md)** - -- **[Sensor服务子系使用指导](Sensor服务子系使用指导.md)** - -- **[Sensor服务子系使用实例](Sensor服务子系使用实例.md)** - - diff --git "a/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 99c79334499f61522bd731bc8f9bf2650480f2fd..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,72 +0,0 @@ -# Sensor服务子系使用指导 - -- [使用步骤](#section18816105182315) - -下面使用步骤以sensorTypeId为0的传感器为例,其他类型的传感器使用方式类似。 - -## 使用步骤 - -1. 导入需要的包 - -``` -#include "sensor_agent.h" -#include "sensor_agent_type.h" -``` - -1. 创建传感器回调函数 - -``` -void SensorDataCallbackImpl(SensorEvent *event) -{ - if(event == NULL){ - return; - } - float *sensorData=(float *)event->data; -} -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->回调函数的格式为RecordSensorCallback类型。 - -1. 获取设备支持sensor列表 - -``` -SensorInfo *sensorInfo = (SensorInfo *)NULL; -int32_t count = 0; -int32_t ret = GetAllSensors(&sensorInfo, &count); -``` - -1. 创建的传感器用户 - -``` -SensorUser sensorUser; -sensorUser.callback = SensorDataCallbackImpl; //成员变量callback指向创建的回调方法 -``` - -1. 使能传感器 - -``` -int32_t ret = ActivateSensor(0, &sensorUser); -``` - -1. 订阅传感器数据 - -``` -int32_t ret = SubscribeSensor(0, &sensorUser); -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->到这步就可以在实现的回调方法中获取到传感器数据。 - -1. 取消传感器数据订阅 - -``` -int32_t ret = UnsubscribeSensor(0, &sensorUser); -``` - -1. 去使能一个传感器 - -``` -int32_t ret = DeactivateSensor(0, &sensorUser); -``` - diff --git "a/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\346\246\202\350\277\260.md" "b/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\346\246\202\350\277\260.md" deleted file mode 100755 index fa1d50d515bbc5e957204aae010019f5629a7767..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\346\246\202\350\277\260.md" +++ /dev/null @@ -1,99 +0,0 @@ -# Sensor服务子系概述 - -- [简介](#section667413271505) -- [接口说明](#section7255104114110) - -## 简介 - -Sensor服务子系统提供了轻量级传感器服务基础框架,您可以使用该框架接口实现传感器列表查询、传感器控制、传感器订阅去订阅等功能。轻量级传感器服务框架如下图所示: - -**图1** Sensor服务框架图 - -![](figures/zh-cn_image_0000001077724150.png) - -- Sensor API:提供传感器的基础API,主要包含查询传感器的列表、订阅/取消传感器数据、执行控制命令等,简化应用开发。 -- Sensor Framework:主要实现传感器的订阅管理、数据通道的创建、销毁等,实现与传感器服务层的通信。 -- Sensor Service:主要实现HDF层数据接收、解析、分发,对设备传感器的管理,数据上报管理以及传感器权限管控等。 - -## 接口说明 - -**表 1** Sensor服务框架API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

接口说明

-

参数要求

-

int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count)

-

作用:获取系统中所有传感器的信息。

-

返回值:0表示成功,其他返回值表示失败。

-

sensorInfo(NOT NULL):输出系统中所有传感器的信息;

-

count(NOT NULL):输出系统中所有传感器的数量。

-

int32_t SubscribeSensor(int32_t sensorTypeId, SensorUser *user)

-

作用:订阅传感器数据,系统会将获取到的传感器数据上报给订阅者。

-

返回值: 0为成功,其他返回值表示失败。

-

sensorTypeId:唯一标识一个传感器类型;

-

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

-

int32_t UnsubscribeSensor(int32_t sensorTypeId, SensorUser *user)

-

作用:去订阅传感器数据,系统将取消传感器数据上报给订阅者。

-

返回值:0为成功,其他返回值表示失败。

-

sensorTypeId:唯一标识一个传感器类型;

-

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

-

int32_t SetBatch(int32_t sensorTypeId, SensorUser *user, int64_t samplingInterval, int64_t reportInterval)

-

作用:设置传感器的数据采样间隔和数据上报间隔

-

返回值:0为成功,其他返回值表示失败。

-

sensorTypeId:唯一标识一个传感器类型;

-

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器;

-

samplingInterval:传感器数据采样间隔,单位纳秒;

-

reportInterval:传感器数据上报间隔,单位纳秒。

-

int32_t ActivateSensor(int32_t sensorTypeId, SensorUser *user)

-

作用:使能一个传感器订阅用户。

-

返回值:0为成功,其他返回值表示失败。

-

sensorTypeId:唯一标识一个传感器类型;

-

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

-

int32_t DeactivateSensor(int32_t sensorTypeId, SensorUser *user)

-

作用:去使能一个传感器订阅用户

-

返回值:0为成功,其他返回值表示失败。

-

sensorTypeId:唯一标识一个传感器类型;

-

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

-

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

-

作用:设置传感器的工作模式

-

返回值:0为成功,其他返回值表示失败。

-

sensorTypeId:唯一标识一个传感器类型;

-

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器;

-

mode:传感器的数据上报模式。

-
- diff --git "a/zh-cn/device-dev/subsystems/XTS\350\256\244\350\257\201\345\255\220\347\263\273\347\273\237\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/zh-cn/device-dev/subsystems/XTS\350\256\244\350\257\201\345\255\220\347\263\273\347\273\237\345\274\200\345\217\221\346\214\207\345\215\227.md" deleted file mode 100755 index b5e511362a0ef107beff73f3fb82f98c8a590487..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/XTS\350\256\244\350\257\201\345\255\220\347\263\273\347\273\237\345\274\200\345\217\221\346\214\207\345\215\227.md" +++ /dev/null @@ -1,648 +0,0 @@ -# XTS认证子系统开发指南 - -- [简介](#section465982318513) -- [系统类型](#section125090457443) -- [目录](#section161941989596) -- [约束](#section119744591305) -- [使用说明](#section137768191623) -- [用例开发指导](#section3695134065513) - - [C语言用例开发编译指导(适用于轻量系统产品用例开发)](#section198193336544) - - [C语言用例执行指导(适用于轻量系统产品用例开发)](#section13820233175418) - - [C++语言用例开发编译指导(适用于小型系统、标准系统用例开发)](#section3822123311540) - - [C++语言用例执行指导(适用于小型系统、标准系统用例开发)](#section128222336544) - - [JS语言用例开发指导(适用于标准系统)](#section159801435165220) - - [JS语言用例编译打包指导(适用于标准系统)](#section445519106559) - - -## 简介 - -XTS子系统是OpenHarmony生态认证测试套件的集合,当前包括acts(application compatibility test suite)应用兼容性测试套件,后续会拓展dcts(device compatibility test suite)设备兼容性测试套件等。 - -XTS子系统当前包括acts与tools软件包: - -- acts,存放acts相关测试用例源码与配置文件,其目的是帮助终端设备厂商尽早发现软件与OpenHarmony的不兼容性,确保软件在整个开发过程中满足OpenHarmony的兼容性要求。 -- tools,存放acts相关测试用例开发框架。 - -## 系统类型 - -OpenHarmony支持如下几种系统类型: - -- 轻量系统(mini system) - - 面向MCU类处理器例如Arm Cortex-M、RISC-V 32位的设备,硬件资源极其有限,支持的设备最小内存为128KiB,可以提供多种轻量级网络协议,轻量级的图形框架,以及丰富的IOT总线读写部件等。可支撑的产品如智能家居领域的连接类模组、传感器设备、穿戴类设备等。 - -- 小型系统(small system) - - 面向应用处理器例如Arm Cortex-A的设备,支持的设备最小内存为1MiB,可以提供更高的安全能力、标准的图形框架、视频编解码的多媒体能力。可支撑的产品如智能家居领域的IP Camera、电子猫眼、路由器以及智慧出行域的行车记录仪等。 - -- 标准系统(standard system) - - 面向应用处理器例如Arm Cortex-A的设备,支持的设备最小内存为128MiB,可以提供增强的交互能力、3D GPU以及硬件合成能力、更多控件以及动效更丰富的图形能力、完整的应用框架。可支撑的产品如高端的冰箱显示屏。 - - -## 目录 - -``` -/test/xts -├── acts # 测试代码存放目录 -│ └── subsystem # 标准系统子系统测试用例源码存放目录 -│ └── subsystem_lite # 轻量系统、小型系统子系统测试用例源码存放目录 -│ └── BUILD.gn # 标准系统测试用例编译配置 -│ └── build_lite # 轻量系统、小型系统测试用例编译配置存放目录 -│ └── BUILD.gn # 轻量系统、小型系统测试用例编译配置 -└── tools # 测试工具代码存放目录 -``` - -## 约束 - -轻量系统用例开发语言是C,小型系统用例开发语言是C++。 - -## 使用说明 - -**表 1** 用例级别说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

级别名称

-

基本定义

-

测试范围

-

Level0

-

冒烟

-

验证关键功能点基本功能/最基本DFX属性在最常见输入下的表现,通过表示功能基本可运行。

-

Level1

-

基本

-

验证各功能点基本功能/基本DFX属性在常见输入下的表现,通过表示功能基本可测试。

-

Level2

-

重要

-

验证各功能点的基本功能/基本DFX属性在常规输入/常见异常情况下的表现,通过表示功能基本正常可用,可开展Beta。

-

Level3

-

一般

-

验证各功能点的全部功能/全部DFX属性在各种常规/非常规输入组合下,或各种正常/异常预置条件组合下的表现。

-

Level4

-

生僻

-

验证关键功能点在极端异常预置条件下、用户难以触及的异常输入组合下的表现。

-
- -**表 2** 用例粒度说明 - - - - - - - - - - - - - - - - - - - - -

用例规模

-

被测试对象

-

测试环境

-

LargeTest

-

业务功能/全场景特性/整机及场景级DFX

-

尽量使用贴近真实的环境设备

-

MediumTest

-

模块/子系统集成至设备后的功能/DFX

-

使用真实的单设备进行验证,可进行消息模拟,尽量不对函数进行MOCK

-

SmallTest

-

模块/类/函数

-

在开发者个人环境进行测试,尽量不依赖其他模块,存在大量的MOCK

-
- -**表 3** 测试类型说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

测试类型名称

-

测试类型定义

-

Function

-

验证被测对象提供给用户的业务功能实现正确性的测试项,这里的“用户”可以是终端用户或开发者,功能包括业务功能及平台功能

-

Performance

-

验证被测对象在特定预置条件/负载模型下的处理能力的测试项,“处理能力”一般以单位时间内可处理的业务量来衡量,如呼叫/秒,帧率/秒,事件处理量/秒等

-

Power

-

验证被测对象在特定预置条件/负载模型下在一定时间内能源消耗量的测试项

-

Reliability

-

验证被测对象在正常/异常输入情况下,或业务量压力和长时间连续运行压力情况下业务表现的测试项,含稳定性、压力、故障注入、Monkey测试项

-

Security

-

验证系统对恶意威胁的防护能力,威胁包括但不限于未授权访问、使用、泄露、破坏、修改、毁灭,以保障信息的机密性、完整性和可用性; 验证系统对用户隐私的保护能力,保障用户的隐私数据被收集、使用、保有、披露和处置符合法律规范,保障用户的隐私权; 验证对各类安全规范的遵从情况,如安全设计规范、安全红线、工信部安全认证规范等,保障安全相关法律法规的合规。

-

Global

-

验证被测对象在是否具有国际化数据支持和本地化能力的测试项,包括语言显示、输入/输出习惯、时间显示、区域特性如货币时间禁忌等等

-

Compatibility

-

当被测对象为应用时,包括被测对象对于自身数据的后向兼容性、对于系统的前后向兼容性、对于不同用户数据(如播放器之音频文件格式/智能短信之用户短信内容)的兼容性测试项; 当被测对象为系统时,包括被测系统对于系统自身数据的后向兼容性、以及对于生态中常用应用的兼容性测试项;当被测对象为软件时,包括被测系统对于相关的硬件的兼容性;

-

User

-

验证被测对象在真实用户场景下的用户体验感受的测试项,注意此种情况下没有客观的“正确”与“失败”,所有的结论及评价都应该来自于用户

-

Standard

-

验证被测对象对于行业及公司内标准/协议/规范的遵从情况的测试项,注意此处的“标准”不包含任何安全标准,针对安全标准的测试项划归为“安全测试”类型

-

Safety

-

验证被测对象的Safety属性,避免产品可能对人身安全、健康以及产品本身带来的危害。

-

Resilience

-

验证被测对象的韧性属性,确保系统受攻击时承受并保持在有定义的运行状态(包括降级)、恢复并适应攻击以保障Mission达成。

-
- -## 用例开发指导 - -根据测试系统选择测试框架和对应测试用例语言。 - -**表 4** 系统和测试框架、开发语言对应关系 - - - - - - - - - - - - - - - - - - - - -

系统

-

测试框架

-

语言

-

轻量系统

-

hctest

-

c

-

小型系统

-

hcpptest

-

c++

-

标准系统

-

HJSUnit、hcpptest

-

js、c++

-
- -### C语言用例开发编译指导(适用于轻量系统产品用例开发) - -**示例:轻量系统测试用例开发** - -当前使用的测试框架是hctest,hctest测试框架支持使用C语言编写测试用例,是在开源测试框架unity的基础上进行增强和适配。 - -1. 用例目录规范:测试用例存储到test/xts/acts仓中 - - ``` - ├── acts - │ └──subsystem_lite - │ │ └── module_hal - │ │ │ └── BUILD.gn - │ │ │ └── src - │ └──build_lite - │ │ └── BUILD.gn - ``` - -2. src目录下用例编写样例。 - - 1.引用测试框架 - - ``` - #include "hctest.h" - ``` - - 2. 使用宏定义LITE\_TEST\_SUIT定义子系统、模块、测试套件名称 - - ``` - /** - * @brief register a test suit named "IntTestSuite" - * @param test subsystem name - * @param example module name - * @param IntTestSuite test suit name - */ - LITE_TEST_SUIT(test, example, IntTestSuite); - ``` - - 3. 定义Setup与TearDown - - 命名方式:测试套件名称+Setup,测试套件名称+TearDown。 - - Setup与TearDown必须存在,可以为空函数。 - - 4. 使用宏定义LITE\_TEST\_CASE写测试用例 - - 包括三个参数:测试套件名称,测试用例名称,用例属性(测试类型、用例粒度、用例级别)。 - - ``` - LITE_TEST_CASE(IntTestSuite, TestCase001, Function | MediumTest | Level1) - { - //do something - }; - ``` - - 5. 使用宏定义 RUN\_TEST\_SUITE注册测试套件 - - ``` - RUN_TEST_SUITE(IntTestSuite); - ``` - -3. 测试模块的配置文件(BUILD.gn)样例: - - 在每个测试模块目录下新建BUILD.gn编译文件,用于指定编译后静态库的名称、依赖的头文件、依赖的库等;具体写法如下: - - ``` - import("//test/xts/tools/lite/build/suite_lite.gni") - hctest_suite("ActsDemoTest") { - suite_name = "acts" - sources = [ - "src/test_demo.c", - ] - include_dirs = [ ] - cflags = [ "-Wno-error" ] - } - ``` - -4. acts下BUILD.gn增加编译选项。 - - 需要将测试模块加入到acts目录下的编译脚本中,编译脚本路径:test/xts/acts/build\_lite/BUILD.gn。 - - ``` - lite_component("acts") { - ... - if(board_name == "liteos_m") { - features += [ - ... - "//xts/acts/subsystem_lite/module_hal:ActsDemoTest" - ] - } - } - ``` - -5. 测试套件编译命令。 - - 随版本编译,debug版本编译时会同步编译acts测试套件 - - >![](public_sys-resources/icon-note.gif) **说明:** - >acts测试套件编译中间件为静态库,最终链接到版本镜像中 。 - - -### C语言用例执行指导(适用于轻量系统产品用例开发) - -**示例:轻量系统测试用例执行** - -将版本镜像烧录进开发板。 - -**测试步骤** - -1. 使用串口工具登录开发板,并保存串口打印信息。 -2. 重启设备,查看串口日志。 - -**测试结果分析指导** - -基于串口打印日志进行分析; - -每个测试套件执行以Start to run test suite开始,以xx Tests xx Failures xx Ignored结束。 - -### C++语言用例开发编译指导(适用于小型系统、标准系统用例开发) - -**示例:小型系统测试用例开发**(标准参考具体样例目录:global/i18n\_standard) - -当前使用的测试框架是hcpptest,hcpptest测试框架是在开源的googletest测试框架的基础上进行的增强和适配。 - -1. 规范用例目录:测试用例存储到test/xts/acts仓中。 - - ``` - ├── acts - │ └──subsystem_lite - │ │ └── module_posix - │ │ │ └── BUILD.gn - │ │ │ └── src - │ └──build_lite - │ │ └── BUILD.gn - ``` - -2. 测试模块src下用例编写样例: - - 1. 引用测试框架: - - 需要引用gtest.h 如:\#include "gtest/gtest.h" - - ``` - #include "gtest/gtest.h" - ``` - - 2. 定义Setup与TearDown - - ``` - using namespace std; - using namespace testing::ext; - class TestSuite: public testing::Test { - protected: - // Preset action of the test suite, which is executed before the first test case - static void SetUpTestCase(void){ - } - // Test suite cleanup action, which is executed after the last test case - static void TearDownTestCase(void){ - } - // Preset action of the test case - virtual void SetUp() - { - } - // Cleanup action of the test case - virtual void TearDown() - { - } - }; - ``` - - 3. 使用宏定义HWTEST或HWTEST\_F写测试用例 - - 普通测试用例的定义:HWTEST(测试套名称, 测试用例名称, 用例标注)。 - - 包含SetUp和TearDown的测试用例的定义 :HWTEST\_F(测试套名称, 测试用例名称,用例标注)。 - - 宏定义包括三个参数:测试套件名称,测试用例名称,用例属性(测试类型、用例粒度、用例级别)。 - - ``` - HWTEST_F(TestSuite, TestCase_0001, Function | MediumTest | Level1) { - // do something - } - ``` - -3. 测试模块下用例配置文件(BUILD.gn)样例: - - 每个测试模块目录下新建BUILD.gn编译文件,用于指定编译后可执行文件的名称、依赖的头文件、依赖的库等;具体写法如下。每个测试模块将独立编译成.bin可执行文件, 该文件可直接push到单板上进行测试。 - - 举例: - - ``` - import("//test/xts/tools/lite/build/suite_lite.gni") - hcpptest_suite("ActsDemoTest") { - suite_name = "acts" - sources = [ - "src/TestDemo.cpp" - ] - - include_dirs = [ - "src", - ... - ] - deps = [ - ... - ] - cflags = [ "-Wno-error" ] - } - - ``` - -4. acts目录下增加编译选项(BUILD.gn)样例: - - 将测试模块加入到acts目录下的编译脚本中,编译脚本为:test/xts/acts/build\_lite/BUILD.gn。 - - ``` - lite_component("acts") { - ... - else if(board_name == "liteos_a") { - features += [ - ... - "//xts/acts/subsystem_lite/module_posix:ActsDemoTest" - ] - } - } - ``` - -5. 测试套件编译命令。 - - 随版本编译,debug版本编译时会同步编译acts测试套件 - - >![](public_sys-resources/icon-note.gif) **说明:** - >小型系统acts独立编译成可执行文件(bin格式), 在编译产物的suites\\acts目录下归档。 - - -### C++语言用例执行指导(适用于小型系统、标准系统用例开发) - -**示例:小型系统测试用例执行** - -目前的用例执行采用nfs共享的方式,mount到单板去执行。 - -**环境搭建** - -1. 使用有限网线或无线将开发板与PC进行连接。 -2. 开发板配置IP、子网掩码、网关,确保开发板与PC处于同一个网段。 -3. PC安装nfs服务器并完成注册,启动nfs服务。 -4. 开发板配置mount命令,确保开发板可以访问PC端的nfs共享文件。 - - 格式:mount \[nfs服务器IP\]:\[/nfs共享目录\] \[/开发板目录\] nfs - - 举例: - - ``` - mount 192.168.1.10:/nfs /nfs nfs - ``` - - -**用例执行** - -测试套件执行 ActsDemoTest.bin 触发用例执行,基于串口打印日志进行分析。 - -### JS语言用例开发指导(适用于标准系统) - -当前使用的测试框架是HJSUnit,用于支撑OpenHarmony application测试(特指基于JS应用框架使用 Javascript 语言开发的 APP)进行自动化测试。 - -**用例编写基础语法** - -测试用例为 js 语言,必须满足 JavaScript 语言编程规范: - -**表 5** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

用例语法

-

描述

-

要求

-

beforeAll

-

测试套级别的预置条件,在所有测试用例开始前执行且仅执行一次,支持一个参数:预置动作函数

-

可选

-

afterAll

-

测试套级别的清理条件,在所有测试用例结束后执行且仅执行一次,支持一个参数:清理动作函数

-

可选

-

beforeEach

-

测试用例级别的预置条件,在每条测试用例开始前执行,执行次数与 it 定义的测试用例数一致,支持一个参数:预置动作函数

-

可选

-

afterEach

-

测试用例级别的清理条件,在每条测试用例结束后执行,执行次数与 it 定义的测试用例数一致,支持一个参数:清理动作函数

-

可选

-

describe

-

定义一个测试套,支持两个参数:测试套名称和测试套函数; describe 支持嵌套,每个 describe 内均可以定义 beforeAll 、beforeEach 、afterEach 和 afterAll

-

必选

-

it

-

定义一条测试用例,支持三个参数:用例名称,过滤参数和用例函数

-

备注:

-

过滤参数:过滤参数为一个 32 位的 Int 类型参数,0 位 置1表示不筛选、默认执行;0-10 位 置1表示测试用例类型;16-18 位 置1表示测试用例规模;24-28 位 置1表示测试层级

-

测试用例类型。置位0-10分别表示:FUNCTION 方法类测试、PERFORMANCE 性能类测试、POWER 功耗类测试、RELIABILITY 可靠性测试、SECURITY 安全合规测试、GLOBAL 整体性测试、COMPATIBILITY 兼容性测试、USER 用户测试、STANDARD 标准测试、SAFETY 安全特性测试,RESILIENCE 压力测试。

-

测试用例规模。置位16-18分别表示:SMALL 小型测试、MEDIUM 中型测试、LARGE 大型测试。

-

测试层级。置位24-28分别表示:LEVEL0-0 级测试、LEVEL1-1 级测试、LEVEL2-2 级测试、LEVEL3-3 级测试、LEVEL4-4 级测试。

-

必选

-
- -用例编写语法采用 jasmine 的标准语法,格式支持ES6格式。 - -1. 规范用例目录:测试用例存储到entry/src/main/js/test目录。 - - ``` - ├── BUILD.gn - │ └──entry - │ │ └──src - │ │ │ └──main - │ │ │ │ └──js - │ │ │ │ │ └──default - │ │ │ │ │ │ └──pages - │ │ │ │ │ │ │ └──index - │ │ │ │ │ │ │ │ └──index.js # 入口文件 - │ │ │ │ │ └──test # 测试代码存放目录 - │ │ │ └── resources # hap资源存放目录 - │ │ │ └── config.json # hap配置文件 - ``` - -2. index.js示例 - - ``` - // 拉起js测试框架,加载测试用例 - import {Core, ExpectExtend} from 'deccjsunit/index' - - export default { - data: { - title: "" - }, - onInit() { - this.title = this.$t('strings.world'); - }, - onShow() { - console.info('onShow finish') - const core = Core.getInstance() - const expectExtend = new ExpectExtend({ - 'id': 'extend' - }) - core.addService('expect', expectExtend) - core.init() - const configService = core.getDefaultService('config') - configService.setConfig(this) - require('../../../test/List.test') - core.execute() - }, - onReady() { - }, - } - ``` - -3. 单元测试用例示例 - - ``` - // Example1: 使用HJSUnit进行单元测试 - describe('appInfoTest', function () { - it('app_info_test_001', 0, function () { - var info = app.getInfo() - expect(info.versionName).assertEqual('1.0') - expect(info.versionCode).assertEqual('3') - }) - }) - ``` - - -### JS语言用例编译打包指导(适用于标准系统) - -hap包编译请参考[标准系统js应用开发指导](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201)。 - diff --git "a/zh-cn/device-dev/subsystems/bytrace\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/bytrace\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100644 index 3933aebf5e5206f7b3c2aaa1f1a8e3d587e43d33..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/bytrace\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,119 +0,0 @@ -# bytrace使用指导 - -- [简介](#section11388623181619) -- [命令行开发指导](#section1595564317164) - - [bytrace命令](#section2344125731617) - - [bytrace命令使用举例](#section5402591174) - - -## 简介 - -bytrace是开发人员用于追踪进程轨迹、分析性能的一种工具,主要对内核ftrace进行了封装和扩展,来支持用户态的打点。通过该工具可以打开想要查看的用户态和内核label(通过下面命令行bytrace -l,查看支持的所有label),然后通过命令行进行抓取trace信息到指定文件中。 - -## 命令行开发指导 - -### bytrace命令 - -bytrace当前支持以下命令: - -**表 1** 命令行列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Option

-

Description

-

-h,--help

-

查看option帮助

-

-b n,--buffer_size n

-

指定n(KB)内存大小用于存取trace日志,默认2048KB

-

-t n,--time n

-

用来指定trace运行的时间(单位:s),取决于需要分析过程的时间

-

--trace_clock clock

-

trace输出的时钟类型,一般设备支持boot、global、mono、uptime、perf等,默认为boot

-

--trace_begin

-

启动抓trace

-

--trace_dump

-

将数据输出到指定位置(默认控制台)

-

--trace_finish

-

停止抓trace,并将数据输出到指定位置(默认控制台)

-

-l,--list_categories

-

输出手机能支持的trace模块

-

--overwrite

-

当缓冲区满的时候,将丢弃最新的信息。(默认丢弃最老的日志)

-

-o filename,--output filename

-

指定输出的目标文件名称

-

-z

-

抓取trace后进行压缩

-
- -### bytrace命令使用举例 - -以下是常用bytrace命令示例,供开发者参考: - -- 查询支持的label。 - -``` -bytrace -l -``` - -或者 - -``` -bytrace --list_categories -``` - -- 设置4M缓存,抓取10秒,抓取label为ability的trace信息。 - -``` -bytrace -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace -``` - -- 设置trace的输出时钟为mono。 - -``` -bytrace --trace_clock mono -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace -``` - -- 抓取trace后进行压缩。 - -``` -bytrace -z -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace -``` - diff --git a/zh-cn/device-dev/subsystems/figures/20200721-223604(eSpace).gif b/zh-cn/device-dev/subsystems/figure/20200721-223604(eSpace).gif old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/20200721-223604(eSpace).gif rename to zh-cn/device-dev/subsystems/figure/20200721-223604(eSpace).gif diff --git "a/zh-cn/device-dev/subsystems/figures/Ability\344\270\216AbilitySlice\347\232\204\345\205\263\347\263\273\345\233\276.png" "b/zh-cn/device-dev/subsystems/figure/Ability\344\270\216AbilitySlice\347\232\204\345\205\263\347\263\273\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/Ability\344\270\216AbilitySlice\347\232\204\345\205\263\347\263\273\345\233\276.png" rename to "zh-cn/device-dev/subsystems/figure/Ability\344\270\216AbilitySlice\347\232\204\345\205\263\347\263\273\345\233\276.png" diff --git "a/zh-cn/device-dev/subsystems/figures/Ability\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" "b/zh-cn/device-dev/subsystems/figure/Ability\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/Ability\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" rename to "zh-cn/device-dev/subsystems/figure/Ability\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" diff --git "a/zh-cn/device-dev/subsystems/figures/Ability\347\256\241\347\220\206\346\234\215\345\212\241\345\222\214\345\214\205\347\256\241\347\220\206\346\234\215\345\212\241\345\220\257\345\212\250.png" "b/zh-cn/device-dev/subsystems/figure/Ability\347\256\241\347\220\206\346\234\215\345\212\241\345\222\214\345\214\205\347\256\241\347\220\206\346\234\215\345\212\241\345\220\257\345\212\250.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/Ability\347\256\241\347\220\206\346\234\215\345\212\241\345\222\214\345\214\205\347\256\241\347\220\206\346\234\215\345\212\241\345\220\257\345\212\250.png" rename to "zh-cn/device-dev/subsystems/figure/Ability\347\256\241\347\220\206\346\234\215\345\212\241\345\222\214\345\214\205\347\256\241\347\220\206\346\234\215\345\212\241\345\220\257\345\212\250.png" diff --git "a/zh-cn/device-dev/subsystems/figures/LiteOS-A\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" "b/zh-cn/device-dev/subsystems/figure/LiteOS-A\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/LiteOS-A\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" rename to "zh-cn/device-dev/subsystems/figure/LiteOS-A\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" diff --git "a/zh-cn/device-dev/subsystems/figures/LiteOS-M\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" "b/zh-cn/device-dev/subsystems/figure/LiteOS-M\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/LiteOS-M\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" rename to "zh-cn/device-dev/subsystems/figure/LiteOS-M\345\271\263\345\217\260dump\347\263\273\347\273\237\345\261\236\346\200\247\350\276\223\345\207\272.png" diff --git "a/zh-cn/device-dev/subsystems/figures/UIButton\347\202\271\345\207\273\346\225\210\346\236\234.gif" "b/zh-cn/device-dev/subsystems/figure/UIButton\347\202\271\345\207\273\346\225\210\346\236\234.gif" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/UIButton\347\202\271\345\207\273\346\225\210\346\236\234.gif" rename to "zh-cn/device-dev/subsystems/figure/UIButton\347\202\271\345\207\273\346\225\210\346\236\234.gif" diff --git "a/zh-cn/device-dev/subsystems/figures/ViewGroup\346\267\273\345\212\240view\345\256\236\344\276\213\346\225\210\346\236\234\345\233\276.png" "b/zh-cn/device-dev/subsystems/figure/ViewGroup\346\267\273\345\212\240view\345\256\236\344\276\213\346\225\210\346\236\234\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/ViewGroup\346\267\273\345\212\240view\345\256\236\344\276\213\346\225\210\346\236\234\345\233\276.png" rename to "zh-cn/device-dev/subsystems/figure/ViewGroup\346\267\273\345\212\240view\345\256\236\344\276\213\346\225\210\346\236\234\345\233\276.png" diff --git a/zh-cn/device-dev/subsystems/figures/unnaming.png b/zh-cn/device-dev/subsystems/figure/unnaming.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/unnaming.png rename to zh-cn/device-dev/subsystems/figure/unnaming.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001051782526.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001051782526.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001051782526.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001051782526.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052582522.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052582522.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052582522.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052582522.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052662559.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052662559.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052662559.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052662559.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052782555.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052782555.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052782555.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052782555.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052942531.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052942531.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001052942531.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001052942531.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001053207924.gif b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001053207924.gif old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001053207924.gif rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001053207924.gif diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001053247975.gif b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001053247975.gif old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001053247975.gif rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001053247975.gif diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001054101094.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001054101094.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001054101094.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001054101094.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001054421113.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001054421113.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001054421113.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001054421113.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001059334449.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001059334449.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001059334449.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001059334449.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001060200050.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001060200050.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001060200050.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001060200050.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001061889268.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001061889268.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001061889268.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001061889268.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001062334618.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001062334618.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001062334618.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001062334618.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001062476933.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001062476933.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001062476933.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001062476933.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001062942690.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001062942690.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001062942690.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001062942690.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001063839940.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001063839940.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001063839940.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001063839940.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001077724150.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001077724150.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001077724150.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001077724150.png diff --git a/zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001077727032.png b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001077727032.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/subsystems/figures/zh-cn_image_0000001077727032.png rename to zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001077727032.png diff --git a/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001119924146.gif b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001119924146.gif new file mode 100644 index 0000000000000000000000000000000000000000..9cd37267672d3bea422b98d95c413e26df330de8 Binary files /dev/null and b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001119924146.gif differ diff --git a/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001166643927.jpg b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001166643927.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ace4cefd36637675f235df3cd596eca3ed218e6c Binary files /dev/null and b/zh-cn/device-dev/subsystems/figure/zh-cn_image_0000001166643927.jpg differ diff --git "a/zh-cn/device-dev/subsystems/figures/\345\212\250\347\224\273\345\256\236\347\216\260\346\225\210\346\236\234\345\233\276.gif" "b/zh-cn/device-dev/subsystems/figure/\345\212\250\347\224\273\345\256\236\347\216\260\346\225\210\346\236\234\345\233\276.gif" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\345\212\250\347\224\273\345\256\236\347\216\260\346\225\210\346\236\234\345\233\276.gif" rename to "zh-cn/device-dev/subsystems/figure/\345\212\250\347\224\273\345\256\236\347\216\260\346\225\210\346\236\234\345\233\276.gif" diff --git "a/zh-cn/device-dev/subsystems/figures/\345\214\205\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" "b/zh-cn/device-dev/subsystems/figure/\345\214\205\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\345\214\205\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" rename to "zh-cn/device-dev/subsystems/figure/\345\214\205\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\241\206\346\236\266\345\233\276.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\345\233\276\347\211\2071.png" "b/zh-cn/device-dev/subsystems/figure/\345\233\276\347\211\2071.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\345\233\276\347\211\2071.png" rename to "zh-cn/device-dev/subsystems/figure/\345\233\276\347\211\2071.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" "b/zh-cn/device-dev/subsystems/figure/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" rename to "zh-cn/device-dev/subsystems/figure/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\345\271\263\351\223\272\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" "b/zh-cn/device-dev/subsystems/figure/\345\271\263\351\223\272\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\345\271\263\351\223\272\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" rename to "zh-cn/device-dev/subsystems/figure/\345\271\263\351\223\272\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\345\272\224\347\224\250\345\220\257\345\212\250\346\265\201\347\250\213.png" "b/zh-cn/device-dev/subsystems/figure/\345\272\224\347\224\250\345\220\257\345\212\250\346\265\201\347\250\213.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\345\272\224\347\224\250\345\220\257\345\212\250\346\265\201\347\250\213.png" rename to "zh-cn/device-dev/subsystems/figure/\345\272\224\347\224\250\345\220\257\345\212\250\346\265\201\347\250\213.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" "b/zh-cn/device-dev/subsystems/figure/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" rename to "zh-cn/device-dev/subsystems/figure/\346\217\222\344\273\266\344\276\235\350\265\226-(2).jpg" diff --git "a/zh-cn/device-dev/subsystems/figures/\346\231\256\351\200\232\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\347\273\223\346\236\204.png" "b/zh-cn/device-dev/subsystems/figure/\346\231\256\351\200\232\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\347\273\223\346\236\204.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\346\231\256\351\200\232\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\347\273\223\346\236\204.png" rename to "zh-cn/device-dev/subsystems/figure/\346\231\256\351\200\232\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\347\273\223\346\236\204.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\346\231\256\351\200\232\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204.png" "b/zh-cn/device-dev/subsystems/figure/\346\231\256\351\200\232\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\346\231\256\351\200\232\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204.png" rename to "zh-cn/device-dev/subsystems/figure/\346\231\256\351\200\232\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\346\260\264\345\271\263-\345\236\202\347\233\264\346\226\271\345\220\221\345\217\257\346\273\221\345\212\250\346\225\210\346\236\234\345\233\276.gif" "b/zh-cn/device-dev/subsystems/figure/\346\260\264\345\271\263-\345\236\202\347\233\264\346\226\271\345\220\221\345\217\257\346\273\221\345\212\250\346\225\210\346\236\234\345\233\276.gif" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\346\260\264\345\271\263-\345\236\202\347\233\264\346\226\271\345\220\221\345\217\257\346\273\221\345\212\250\346\225\210\346\236\234\345\233\276.gif" rename to "zh-cn/device-dev/subsystems/figure/\346\260\264\345\271\263-\345\236\202\347\233\264\346\226\271\345\220\221\345\217\257\346\273\221\345\212\250\346\225\210\346\236\234\345\233\276.gif" diff --git "a/zh-cn/device-dev/subsystems/figures/\346\265\213\350\257\225\345\271\263\345\217\260\346\236\266\346\236\204.png" "b/zh-cn/device-dev/subsystems/figure/\346\265\213\350\257\225\345\271\263\345\217\260\346\236\266\346\236\204.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\346\265\213\350\257\225\345\271\263\345\217\260\346\236\266\346\236\204.png" rename to "zh-cn/device-dev/subsystems/figure/\346\265\213\350\257\225\345\271\263\345\217\260\346\236\266\346\236\204.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\346\265\213\350\257\225\345\271\263\345\217\260\350\277\220\350\241\214\346\227\266\345\272\217.png" "b/zh-cn/device-dev/subsystems/figure/\346\265\213\350\257\225\345\271\263\345\217\260\350\277\220\350\241\214\346\227\266\345\272\217.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\346\265\213\350\257\225\345\271\263\345\217\260\350\277\220\350\241\214\346\227\266\345\272\217.png" rename to "zh-cn/device-dev/subsystems/figure/\346\265\213\350\257\225\345\271\263\345\217\260\350\277\220\350\241\214\346\227\266\345\272\217.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204\347\244\272\346\204\217\345\233\276.png" "b/zh-cn/device-dev/subsystems/figure/\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204\347\244\272\346\204\217\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204\347\244\272\346\204\217\345\233\276.png" rename to "zh-cn/device-dev/subsystems/figure/\347\273\204\344\273\266\346\240\221\347\273\223\346\236\204\347\244\272\346\204\217\345\233\276.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\347\274\226\350\257\221\346\236\204\345\273\272\346\265\201\347\250\213.jpg" "b/zh-cn/device-dev/subsystems/figure/\347\274\226\350\257\221\346\236\204\345\273\272\346\265\201\347\250\213.jpg" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\347\274\226\350\257\221\346\236\204\345\273\272\346\265\201\347\250\213.jpg" rename to "zh-cn/device-dev/subsystems/figure/\347\274\226\350\257\221\346\236\204\345\273\272\346\265\201\347\250\213.jpg" diff --git "a/zh-cn/device-dev/subsystems/figures/\350\207\252\351\200\202\345\272\224\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" "b/zh-cn/device-dev/subsystems/figure/\350\207\252\351\200\202\345\272\224\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\350\207\252\351\200\202\345\272\224\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" rename to "zh-cn/device-dev/subsystems/figure/\350\207\252\351\200\202\345\272\224\346\250\241\345\274\217\345\233\276\347\211\207\346\225\210\346\236\234\345\233\276.png" diff --git "a/zh-cn/device-dev/subsystems/figures/\350\256\276\347\275\2562-2\347\275\221\346\240\274\345\271\266\346\267\273\345\212\2404\344\270\252button\347\273\204\344\273\266\350\277\233\350\241\214\345\270\203\345\261\200.png" "b/zh-cn/device-dev/subsystems/figure/\350\256\276\347\275\2562-2\347\275\221\346\240\274\345\271\266\346\267\273\345\212\2404\344\270\252button\347\273\204\344\273\266\350\277\233\350\241\214\345\270\203\345\261\200.png" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/figures/\350\256\276\347\275\2562-2\347\275\221\346\240\274\345\271\266\346\267\273\345\212\2404\344\270\252button\347\273\204\344\273\266\350\277\233\350\241\214\345\270\203\345\261\200.png" rename to "zh-cn/device-dev/subsystems/figure/\350\256\276\347\275\2562-2\347\275\221\346\240\274\345\271\266\346\267\273\345\212\2404\344\270\252button\347\273\204\344\273\266\350\277\233\350\241\214\345\270\203\345\261\200.png" diff --git a/zh-cn/device-dev/subsystems/figures/RIL-Adapter.png b/zh-cn/device-dev/subsystems/figures/RIL-Adapter.png deleted file mode 100644 index eb3a5f511cb246a0c250a0dc76150b8816f4394b..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/figures/RIL-Adapter.png and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/figures/\345\216\273\347\224\265.png" "b/zh-cn/device-dev/subsystems/figures/\345\216\273\347\224\265.png" deleted file mode 100755 index 6d8841ed7cd427e5f3d091f8d3261bc38c297bbf..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/subsystems/figures/\345\216\273\347\224\265.png" and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/figures/\346\235\245\347\224\265.png" "b/zh-cn/device-dev/subsystems/figures/\346\235\245\347\224\265.png" deleted file mode 100644 index f666f21d1575a00e928c99afb29a7aca8c26e641..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/subsystems/figures/\346\235\245\347\224\265.png" and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/hdc_std-\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/hdc_std-\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100644 index d4993fb7b51791ca8bbd5af2aff43cf011ade64a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/hdc_std-\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,658 +0,0 @@ -# hdc\_std 使用指导 - -- [环境准备](#section05992022154916) -- [注意事项](#section19543134915210) -- [全局option](#section618522925119) -- [查询设备列表](#section174891132104218) -- [服务进程相关命令](#section680531510497) -- [网络相关的命令](#section71176123212) -- [文件相关的命令](#section173133523013) -- [应用相关的命令](#section2072647133819) -- [调试相关的命令](#section112861250195015) - -hdc\_std(OpenHarmony Device Connector)是OpenHarmony为开发人员提供的用于调试的命令行工具,通过该工具可以在Windows/Linux等系统上与开发机或者模拟器进行交互。 - -下文将介绍hdc\_std的环境准备和常用命令及使用举例。 - -## 环境准备 - -**hdc\_std 工具获取方式:** - -从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 - -**使用举例:** - -下面以windows侧使用方式举例: - -从prebuilt/windows侧获取可执行文件hdc\_std.exe,放到磁盘某个位置即可使用。 - -## 注意事项 - -1、使用hdc\_std,如果出现异常,可以尝试通过hdc\_std kill命令杀掉hdc\_std服务,或者通过hdc\_std start -r命令重启服务进程进行解决。 - -2、如果出现hdc\_std list targets获取不到设备信息,通过任务管理器查看是否有hdc.exe进程存在,如果进程存在,可以通过杀掉该进程进行解决。 - -## 全局option - -全局option涉及以下命令: - -- **-h/help -v/version** - -用于显示hdc相关的帮助、版本信息。 - -**表 1** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-h/help -v/version

-

-

返回值

-

返回值说明

-

返回对应信息

-

帮助或者版本信息

-
- -使用方法: - -hdc\_std -h / hdc\_std help - -hdc\_std -v / hdc\_std version - -- **-t key** - -用于连接指定设备标识为key的设备。 - -**表 2** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

key

-

为tcp:port格式,或者USB序列号

-

返回值

-

返回值说明

-

①error: device '***' not found

-

②Nothing to do...

-

①设备不存在

-

②附加的命令不存在

-
- -使用方法: - -该option需要与具体的操作命令搭配使用,下面以shell命令举例: - -hdc\_std list targets (获取设备信息) - -hdc\_std -t _key_ shell (-t后面添加的_key_ 需要替换为上面查询的设备信息) - ->![](public_sys-resources/icon-note.gif) **说明:** ->一台开发机可支持多个设备连接,每个设备有其唯一的设备标识,如果通过网络与设备连接,其标识为tcp:port格式,如果通过usb连接则标识为设备sn号。该命令需要跟随具体操作命令。 - -## 查询设备列表 - -查询设备列表涉及以下命令: - -**list targets\[-v\]** - -显示所有已经连接的目标设备列表 - -**表 3** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-v

-

添加-v选项,则会打印设备详细信息

-

返回值

-

返回值说明

-

①返回设备信息

-

②[Empty]

-

①已经连接的设备列表信息

-

②没有查询到设备信息

-
- -使用方法: - -hdc\_std list targets - -hdc\_std list targets -v - -## 服务进程相关命令 - -服务进程涉及以下命令: - -- **target mount** - -以读写模式挂载/system等分区。 - -**表 4** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-

-

返回值

-

返回值说明

-

①Mount finish

-

②返回具体信息

-

①成功情况下返回的信息

-

②失败情况下的具体信息

-
- -使用方法: - -hdc\_std target mount - -- **smode \[off\]** - -授予后台服务进程root权限, 使用off参数取消授权。 - -使用方法: - -hdc\_std smode - -hdc\_std smode off - -- **kill \[-r\]** - -终止服务进程。 - -**表 5** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-r

-

触发服务重启

-

返回值

-

返回值说明

-

①Kill server finish

-

②返回具体信息

-

①成功情况下返回的信息

-

②失败情况下的具体信息

-
- -使用方法: - -hdc\_std kill - -- **start \[-r\]** - -启动服务进程。 - -**表 6** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-r

-

如果服务进程已经启动,-r选项会触发服务进程重新启动

-

返回值

-

返回值说明

-

-

-
- -使用方法: - -hdc\_std start - -## 网络相关的命令 - -网络部分涉及以下命令: - -- **tconn _host_\[:_port_\]\[-remove\]** - -通过【ip地址:端口号】来指定连接的设备 - -**表 7** 命令说明 - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

host[:port]

-

为tcp:port格式

-

-remove

-

表示断开与指定设备的连接

-

返回值

-

返回值说明

-

①返回具体信息

-

②无

-

①失败情况下的具体信息

-

②成功情况下无返回值

-
- -使用方法(举例): - -hdc\_std tconn 192.168.0.100:8710 - -- **tmode usb** - -执行后设备端对应daemon进程重启,并首先选用usb连接方式。 - -**表 8** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-

-

返回值

-

返回值说明

-

①返回具体信息

-

②无

-

①失败情况下的具体信息

-

②成功情况下无返回值

-
- -使用方法: - -hdc\_std tmode usb - -- **tmode port _port-number_** - -执行后设备端对应daemon进程重启,并优先使用网络方式连接设备,如果连接设备再选择usb连接。 - -**表 9** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

port-number

-

listen连接的网络端口

-

返回值

-

返回值说明

-

①返回具体信息

-

②无

-

①失败情况下的具体信息

-

②成功情况下无返回值

-
- -使用方法: - -hdc\_std tmode port 8710 - ->![](public_sys-resources/icon-note.gif) **说明:** ->执行完毕后,远端daemon将会退出并重启,默认启用TCP连接,如果不加上listen端口则listen随机端口。 - -## 文件相关的命令 - -文件部分涉及以下命令: - -- **file send _local remote_** - -发送文件至远端设备。 - -**表 10** 命令说明 - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

local

-

本地待发送文件路径

-

remote

-

远程待接收文件路径

-

返回值

-

返回值说明

-

①返回具体信息

-

②返回传输结果

-

①失败情况下的具体信息

-

②成功传输的结果信息

-
- -使用方法(举例): - -hdc\_std file send E:\\a.txt /data/local/tmp/a.txt - -- **file recv \[-a\] _remote local_** - -从远端设备接收文件至本地。 - -**表 11** 命令说明 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-a

-

文件保留时间戳模式

-

local

-

本地待接收文件路径

-

remote

-

远程待发送文件路径

-

返回值

-

返回值说明

-

①返回具体信息

-

②无

-

①失败情况下的具体信息

-

②成功情况下无返回值

-
- -使用方法(举例): - -hdc\_std file recv /data/local/tmp/a.txt ./a.txt - -## 应用相关的命令 - -应用部分涉及以下命令: - -- **install \[-r/-d/-g\] _package_** - -安装OpenHarmony package。 - -**表 12** 命令说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

package

-

OpenHarmony应用安装包

-

-r

-

替换已存在应用

-

-d

-

允许降级安装

-

-g

-

动态授权

-

返回值

-

返回值说明

-

①返回具体信息

-

②无

-

①失败情况下的具体信息

-

②成功情况下无返回值

-
- -使用方法(举例): - -hdc\_std install _hwadmin.hap_ - -- **uninstall \[-k\] _package_** - -卸载OpenHarmony应用。 - -**表 13** 命令说明 - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

package

-

OpenHarmony应用安装包

-

-k

-

保留/data/cache

-

返回值

-

返回值说明

-

①返回具体信息

-

②无

-

①失败情况下的具体信息

-

②成功情况下无返回值

-
- -使用方法(举例): - -hdc\_std uninstall _package_ - -## 调试相关的命令 - -调试涉及以下命令: - -- **hilog** - -支持抓取log信息。 - -**表 14** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

-

-

返回值

-

返回值说明

-

返回具体信息

-

抓取的日志信息

-
- -使用方法: - -hdc\_std hilog - -- **shell \[_command_\]** - -远程执行命令或进入交互命令环境。 - -**表 15** 命令说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

command

-

需要执行的单次命令

-

返回值

-

返回值说明

-

返回具体信息

-

shell后面执行命令的结果信息

-
- -使用方法: - -hdc\_std shell - diff --git "a/zh-cn/device-dev/subsystems/hdc_std\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/zh-cn/device-dev/subsystems/hdc_std\345\270\270\350\247\201\351\227\256\351\242\230.md" deleted file mode 100644 index 3f83fba3e9943bb252fec4fc273a197c3fcd9ec7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/hdc_std\345\270\270\350\247\201\351\227\256\351\242\230.md" +++ /dev/null @@ -1,39 +0,0 @@ -# hdc\_std常见问题 - -- [hdc\_std连接不到设备](#section1221016541119) -- [hdc\_std运行不了](#section219185710311) - -## hdc\_std连接不到设备 - -- **现象描述** - - 执行 "hdc\_std list targets"命令后结果为:\[Empty\] - -- **可能原因和解决方法** - 1. 设备没有被识别: - - 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 - - 2. hdc\_std工作异常: - - 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 - - 如果一直获取不到设备信息,请在任务管理器中查询是否有adb进程,该进程可能会对hdc产生干扰,可以将其杀掉后重复执行上面的步骤。 - - 3. hdc\_std与设备不匹配: - - 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 - - - -## hdc\_std运行不了 - -- **现象描述** - - 点击hdc\_std.exe文件无法运行。 - -- **可能原因和解决方法** - - hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 - - diff --git a/zh-cn/device-dev/subsystems/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/subsystems/public_sys-resources/icon-caution.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/zh-cn/device-dev/subsystems/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/subsystems/public_sys-resources/icon-danger.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/zh-cn/device-dev/subsystems/public_sys-resources/icon-note.gif b/zh-cn/device-dev/subsystems/public_sys-resources/icon-note.gif deleted file mode 100755 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/zh-cn/device-dev/subsystems/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/subsystems/public_sys-resources/icon-notice.gif deleted file mode 100755 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/zh-cn/device-dev/subsystems/public_sys-resources/icon-tip.gif b/zh-cn/device-dev/subsystems/public_sys-resources/icon-tip.gif deleted file mode 100755 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/zh-cn/device-dev/subsystems/public_sys-resources/icon-warning.gif b/zh-cn/device-dev/subsystems/public_sys-resources/icon-warning.gif deleted file mode 100755 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/public_sys-resources/icon-warning.gif and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/\345\224\244\351\206\222\350\257\215\350\257\206\345\210\253\351\205\215\347\275\256\346\226\207\344\273\266\347\232\204\345\274\200\345\217\221\347\244\272\344\276\213.md" b/zh-cn/device-dev/subsystems/subsys-aiframework-demo-conf.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\224\244\351\206\222\350\257\215\350\257\206\345\210\253\351\205\215\347\275\256\346\226\207\344\273\266\347\232\204\345\274\200\345\217\221\347\244\272\344\276\213.md" rename to zh-cn/device-dev/subsystems/subsys-aiframework-demo-conf.md diff --git "a/zh-cn/device-dev/subsystems/\345\224\244\351\206\222\350\257\215\350\257\206\345\210\253\346\217\222\344\273\266\347\232\204\345\274\200\345\217\221\347\244\272\344\276\213.md" b/zh-cn/device-dev/subsystems/subsys-aiframework-demo-plugin.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\224\244\351\206\222\350\257\215\350\257\206\345\210\253\346\217\222\344\273\266\347\232\204\345\274\200\345\217\221\347\244\272\344\276\213.md" rename to zh-cn/device-dev/subsystems/subsys-aiframework-demo-plugin.md diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-demo-sdk.md b/zh-cn/device-dev/subsystems/subsys-aiframework-demo-sdk.md new file mode 100644 index 0000000000000000000000000000000000000000..795599d87226dbe1e7150574143f4b739c042c0f --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-demo-sdk.md @@ -0,0 +1,81 @@ +# 唤醒词识别SDK的开发示例 + +1. 在//foundation/ai/engine /interfaces/kits目录中添加唤醒词识别SDK的API接口定义,该接口可用三方应用的调用。如下代码片段即为唤醒词识别定义的API接口示例,其相关代码参考路径为://foundation/ai/engine /interfaces/kits/asr/keyword\_spotting。 + + ``` + class KWSSdk { + public: + KWSSdk(); + virtual ~KWSSdk(); + + // 定义了创建唤醒词检测工具包的方法 + int32_t Create(); + + // 定义了同步执行唤醒词检测任务的方法 + int32_t SyncExecute(const Array &audioInput); + + // 定义了设置唤醒词检测回调器的方法 + int32_t SetCallback(const std::shared_ptr &callback); + + // 定义了销毁唤醒词工具包的方法,释放与插件的会话信息。 + int32_t Destroy(); + }; + ``` + +2. 在//foundation/ai/engine/services/client/algorithm\_sdk的目录中增加SDK中API接口的具体实现,调用client端提供的接口,实现算法插件能力的使用。如下代码片段即为唤醒词识别的API接口中create方法的具体实现示例,更多详细代码可参考://foundation/ai/engine/services/client/algorithm\_sdk/asr/keyword\_spotting。 + + ``` + int32_t KWSSdk::KWSSdkImpl::Create() + { + if (kwsHandle_ != INVALID_KWS_HANDLE) { + HILOGE("[KWSSdkImpl]The SDK has been created"); + return KWS_RETCODE_FAILURE; + } + if (InitComponents() != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]Fail to init sdk components"); + return KWS_RETCODE_FAILURE; + } + // 调用client端提供的接口AieClientInit,实现初始化引擎服务,激活跨进程调用 + int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr); + if (retCode != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode); + return KWS_RETCODE_FAILURE; + } + if (clientInfo_.clientId == INVALID_CLIENT_ID) { + HILOGE("[KWSSdkImpl]Fail to allocate client id"); + return KWS_RETCODE_FAILURE; + } + DataInfo inputInfo = { + .data = nullptr, + .length = 0, + }; + DataInfo outputInfo = { + .data = nullptr, + .length = 0, + }; + // 调用client端提供的接口AieClientPrepare,实现加载算法插件 + retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr); + if (retCode != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode); + return KWS_RETCODE_FAILURE; + } + if (outputInfo.data == nullptr || outputInfo.length <= 0) { + HILOGE("[KWSSdkImpl]The data or length of output info is invalid"); + return KWS_RETCODE_FAILURE; + } + MallocPointerGuard pointerGuard(outputInfo.data); + retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_); + if (retCode != RETCODE_SUCCESS) { + HILOGE("[KWSSdkImpl]Get handle from inputInfo failed"); + return KWS_RETCODE_FAILURE; + } + return KWS_RETCODE_SUCCESS; + } + ``` + + 上述代码为API接口的具体实现,从上述示例的代码中,SDK中create接口的具体实现即为下述示例代码中create方法,该方法调用了AI引擎框架client端开放接口AieClientInit,AieClientPrepare,从而实现与server端建立连接及加载算法模型的能力。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >SDK调用AI引擎client端接口顺序应遵循AieClientInit-\>AieClientPrepare-\>AieClientSyncProcess/AieClientAsyncProcess-\>AieClientRelease-\>AieClientDestroy,否则调用接口会返回错误码。 + + diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-demo.md b/zh-cn/device-dev/subsystems/subsys-aiframework-demo.md new file mode 100644 index 0000000000000000000000000000000000000000..054336dafd8be39390dfed958dc9d1576a3d297a --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-demo.md @@ -0,0 +1,13 @@ +# 开发示例 + +以开发唤醒词识别为例,开发者可在Hi3516DV300开发板上,基于AI引擎框架开发唤醒词识别的sdk以及唤醒词识别的plugin,通过编译命令编出新的版本镜像并将其烧入版本。同时,开发者开发唤醒词识别的应用,该应用能够接收外部音频,将listen到的音频传入SDK中的接口,若音频中带有关键词,唤醒词识别的应用会识别出相应的词语,并打印在命令行中。 + +本示例中唤醒词识别的场景中唤醒词是固定的,当开发者传入的音频包含”Hi,小问“,启动的应用就会打印"\[Hi, xiaowen\]",当不包含时,会打印'\[UNKNOWN\]"。 + +- **[唤醒词识别SDK的开发示例](subsys-aiframework-demo-sdk.md)** + +- **[唤醒词识别插件的开发示例](subsys-aiframework-demo-plugin.md)** + +- **[唤醒词识别配置文件的开发示例](subsys-aiframework-demo-conf.md)** + + diff --git "a/zh-cn/device-dev/subsystems/\351\205\215\347\275\256\346\226\207\344\273\266\347\232\204\345\274\200\345\217\221\350\277\207\347\250\213.md" b/zh-cn/device-dev/subsystems/subsys-aiframework-devguide-conf.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\351\205\215\347\275\256\346\226\207\344\273\266\347\232\204\345\274\200\345\217\221\350\277\207\347\250\213.md" rename to zh-cn/device-dev/subsystems/subsys-aiframework-devguide-conf.md diff --git "a/zh-cn/device-dev/subsystems/\346\217\222\344\273\266\347\232\204\345\274\200\345\217\221\350\277\207\347\250\213.md" b/zh-cn/device-dev/subsystems/subsys-aiframework-devguide-plugin.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\346\217\222\344\273\266\347\232\204\345\274\200\345\217\221\350\277\207\347\250\213.md" rename to zh-cn/device-dev/subsystems/subsys-aiframework-devguide-plugin.md diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-devguide-sdk.md b/zh-cn/device-dev/subsystems/subsys-aiframework-devguide-sdk.md new file mode 100644 index 0000000000000000000000000000000000000000..ed8f624d68c07f4791327fc7b161a793a07e54a8 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-devguide-sdk.md @@ -0,0 +1,162 @@ +# SDK开发过程 + +SDK头文件的功能实现是基于对SDK的调用映射到对client的调用。Client端提供的接口如下[表1](#table203963834718)所示。 + +**表 1** Client端提供的接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口名

+

接口说明

+

参数要求

+

int AieClientInit(const ConfigInfo &configInfo, ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, IServiceDeadCb *cb)

+

作用:链接并初始化引擎服务,激活跨进程调用。

+

返回值:0为成功,其他返回值失败。

+

configInfo(NOT NULL):引擎相关初始化配置数据;

+

clientInfo(NOT NULL):引擎客户端信息;

+

algorithmInfo(NOT NULL):调用算法信息;

+

cb(可为NULL):死亡回调 对象;

+

int AieClientPrepare(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo, IClientCb *cb)

+

作用:加载算法插件。

+

返回值: 0为成功,其他返回值失败。

+

clientInfo(NOT NULL):引擎客户端信息;

+

algorithmInfo(NOT NULL):调用算法信息;

+

inputInfo(可为NULL):加载算法插件时输入所需信息;

+

outputInfo(可为NULL):加载算法插件之后如需返回信息则通过此出参返回;

+

cb:异步算法通过此回调返回运算结果,因此异步算法此结构体不能为空;若为同步算法,传入空值即可;

+

int AieClientAsyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

+

作用:执行异步算法。

+

返回值:0为成功,其他返回值失败。

+

clientInfo(NOT NULL):引擎客户端信息;

+

algorithmInfo(NOT NULL):调用算法信息;

+

inputInfo(可为NULL):算法运算入参;

+

int AieClientSyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo)

+

作用:执行同步算法。

+

返回值:0为成功,其他返回值失败。

+

clientInfo(NOT NULL):引擎客户端信息;

+

algorithmInfo(NOT NULL):调用算法信息;

+

inputInfo(可为NULL):算法运算入参;

+

outputInfo(可为NULL):同步算法运算结果出参;

+

int AieClientRelease(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)

+

作用:卸载算法插件。

+

返回值:0为成功,其他返回值失败。

+

clientInfo(NOT NULL):引擎客户端信息;

+

algorithmInfo(NOT NULL):卸载算法插件的相关信息;

+

inputInfo(可为NULL):调用卸载接口时的输入信息;

+

int AieClientDestroy(ClientInfo &clientInfo)

+

作用:断开与服务端的链接,释放相关缓存。

+

返回值:0为成功,其他返回值失败。

+

clientInfo(NOT NULL):所要销毁的引擎客户端信息;

+

int AieClientSetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo)

+

作用:设置配置项,可将一些算法的拓展信息通过此接口传入插件。

+

返回值:0为成功,其他返回值失败。

+

clientInfo(NOT NULL):引擎客户端信息;

+

optionType (NOT NULL):算法配置项,算法插件可根据需要利用此状态位;

+

inputInfo(可为NULL):插件可根据需要通过此入参设置算法参数信息;

+

int AieClientGetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo, DataInfo &outputInfo)

+

作用:给定特定的optionType和inputInfo,获取其对应的配置项信息。

+

返回值:0为成功,其他返回值失败。

+

clientInfo(NOT NULL):引擎客户端信息;

+

optionType(NOT NULL):所获取配置项信息的对应算法状态位;

+

inputInfo(可为NULL):所获取配置项信息的对应算法参数信息;

+

outputInfo(可为NULL):所要获取的配置项信息返回结果;

+
+ +其中,ConfigInfo,ClientInfo,AlgorithmInfo,DataInfo的数据结构如下[表2](#table22154317482)所示。 + +**表 2** ConfigInfo,ClientInfo,AlgorithmInfo,DataInfo的数据结构 + + + + + + + + + + + + + + + + + + + + + + + + +

结构体名称

+

说明

+

属性

+

ConfigInfo

+

算法配置项信息。

+

const char *description:配置项信息主体;

+

ClientInfo

+

客户端信息。

+

long long clientVersion:客户端设备版本号(当前还未启用);

+

int clientId:客户端ID;

+

int sessionId:会话ID;

+

uid_t serverUid:server端UID;

+

uid_t clientUid:client端UID;

+

int extendLen:拓展信息(extendMsg)长度;

+

unsigned char *extendMsg:拓展信息主体;

+

AlgorithmInfo

+

算法信息。

+

long long clientVersion:客户端设备版本号(当前还未启用);

+

bool isAsync:是否为异步执行;

+

int algorithmType:引擎框架根据插件加载顺序分配的算法类型ID;

+

long long algorithmVersion:算法版本号;

+

bool isCloud:是否上云(当前还未启用);

+

int operateId:执行ID(当前还未启用);

+

int requestId:请求ID,标识每次request,以对应执行结果;

+

int extendLen:拓展信息(extendMsg)长度;

+

unsigned char *extendMsg:拓展信息主体;

+

DataInfo

+

算法数据入参(inputInfo)、接口调用结果出参(outputInfo)。

+

unsigned char *data:数据主体;

+

int length:数据(data)长度;

+
+ +具体开发过程可参考唤醒词识别SDK开发示例。 + diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-devguide.md b/zh-cn/device-dev/subsystems/subsys-aiframework-devguide.md new file mode 100644 index 0000000000000000000000000000000000000000..5de9fe721cbe94bd784c2b09bd70f3258a6af68e --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-devguide.md @@ -0,0 +1,11 @@ +# 开发指导 + +为实现AI 引擎框架的接入,开发者需开发上述[图1](subsys-aiframework-guide.md#fig143186187187)中的SDK模块和Plugin模块,通过调用sdk提供的接口,基于AI引擎框架实现调用plugin中算法的能力,从而实现AI能力的生命周期管理和按需部署功能。 + +- **[SDK开发过程](subsys-aiframework-devguide-sdk.md)** + +- **[插件的开发过程](subsys-aiframework-devguide-plugin.md)** + +- **[配置文件的开发过程](subsys-aiframework-devguide-conf.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-envbuild.md b/zh-cn/device-dev/subsystems/subsys-aiframework-envbuild.md new file mode 100644 index 0000000000000000000000000000000000000000..50cd9a3f9c3e5bf420863c30218379a631400f26 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-envbuild.md @@ -0,0 +1,5 @@ +# 搭建环境 + +1. 准备开发板:Hi3516DV300,Hi3518EV300 +2. [下载源码](../get-code/sourcecode-acquire.md) + diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-guide.md b/zh-cn/device-dev/subsystems/subsys-aiframework-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..c725c6de1d82b1efa4670cedb9654b8f044d25f3 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-guide.md @@ -0,0 +1,9 @@ +# AI引擎框架开发指南 + +AI业务子系统是OpenHarmony提供原生的分布式AI能力的子系统。AI业务子系统提供了统一的AI引擎框架,实现算法能力快速插件化集成。框架中主要包含插件管理、模块管理和通信管理等模块,完成对AI算法能力的生命周期管理和按需部署。插件管理主要实现插件的生命周期管理及插件的按需部署,快速集成AI能力插件;模块管理主要实现任务的调度及管理客户端的实例;通信管理主要实现客户端和服务端之间的跨进程通信及引擎与插件之间的数据传输。后续,会逐步定义统一的AI能力接口,便于AI能力的分布式调用。同时,提供适配不同推理框架层级的统一推理接口。AI引擎框架如下[图1](#fig143186187187)所示。 + +**图 1** AI引擎框架 + + +![](figure/zh-cn_image_0000001077727032.png) + diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-tech-codemanage.md b/zh-cn/device-dev/subsystems/subsys-aiframework-tech-codemanage.md new file mode 100644 index 0000000000000000000000000000000000000000..f93fcf62bb5cb58aa6873e0191ac86627acd5532 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-tech-codemanage.md @@ -0,0 +1,40 @@ +# 代码管理规范 + +- [建议:插件与北向SDK在AI引擎指定的路径下进行代码开发](#section17176374131) +- [规则:插件提供的全部对外接口,统一存放在AI业务子系统interfaces/kits目录](#section2551029111312) +- [规则:插件编译输出路径必须是在/usr/lib](#section97021558121310) + +AI引擎框架包含client、server和common三个主要模块,其中client提供server端连接管理功能,北向SDK在算法对外接口中需封装调用client提供的公共接口;server提供插件加载以及任务管理等功能,各Plugin实现由server提供的插件接口,完成插件接入;common提供与平台相关的操作方法、引擎协议以及相关工具类,供其他各模块调用。 + +AI引擎框架各模块之间的代码依赖关系如下[图1](#fig171811112818)所示: + +**图 1** ****AI引擎代码依赖关系 + + +![](figure/插件依赖-(2).jpg) + +## 建议:插件与北向SDK在AI引擎指定的路径下进行代码开发 + +在AI引擎框架的整体规划中,北向SDK属于client端的一部分,插件由server端调用,属于server端的一部分,因此AI引擎框架为接入的插件与北向SDK规划的路径: + +- SDK代码路径://foundation/ai/engine/services/client/algorithm\_sdk + + e.g. //foundation/ai/engine/services/client/algorithm\_sdk/cv + + e.g. //foundation/ai/engine/services/client/algorithm\_sdk/nlu + +- 插件代码路径://foundation/ai/engine/services/server/plugin + + e.g. //foundation/ai/engine/services/server/plugin/cv + + e.g. //foundation/ai/engine/services/server/plugin/nlu + + +## 规则:插件提供的全部对外接口,统一存放在AI业务子系统interfaces/kits目录 + +北向SDK对外接口是AI业务子系统提供能力的对外暴露方式,按照OpenHarmony的接口管理要求,需统一存放在各子系统的interfaces/kits目录中。当前AI业务子系统插件对外接口路径为//foundation/ai/engine/interfaces/kits,不同插件可在该路径下添加目录,比如增加cv插件,则在路径//foundation/ai/engine/interfaces/kits/cv下面存放接口文件。 + +## 规则:插件编译输出路径必须是在/usr/lib + +server端加载插件是采用dlopen方式,只支持在/usr/lib路径进行,因此插件在编译so时,需要在编译配置文件中指定输出路径为/usr/lib。 + diff --git "a/zh-cn/device-dev/subsystems/\346\216\245\345\217\243\345\274\200\345\217\221\350\247\204\350\214\203.md" b/zh-cn/device-dev/subsystems/subsys-aiframework-tech-interface.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\346\216\245\345\217\243\345\274\200\345\217\221\350\247\204\350\214\203.md" rename to zh-cn/device-dev/subsystems/subsys-aiframework-tech-interface.md diff --git "a/zh-cn/device-dev/subsystems/\345\221\275\345\220\215\350\247\204\350\214\203.md" b/zh-cn/device-dev/subsystems/subsys-aiframework-tech-name.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\221\275\345\220\215\350\247\204\350\214\203.md" rename to zh-cn/device-dev/subsystems/subsys-aiframework-tech-name.md diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework-tech.md b/zh-cn/device-dev/subsystems/subsys-aiframework-tech.md new file mode 100644 index 0000000000000000000000000000000000000000..486878e0b4123418899c58c037ed24b3227e4ad6 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework-tech.md @@ -0,0 +1,15 @@ +# 技术规范 + +**用词约定:** + +**规则:**必须准守的约定 + +**建议:**需要加以考虑的约定 + +- **[代码管理规范](subsys-aiframework-tech-codemanage.md)** + +- **[命名规范](subsys-aiframework-tech-name.md)** + +- **[接口开发规范](subsys-aiframework-tech-interface.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-aiframework.md b/zh-cn/device-dev/subsystems/subsys-aiframework.md new file mode 100644 index 0000000000000000000000000000000000000000..77fa018ec4592e10ced77cbec30a0a7a9f003481 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-aiframework.md @@ -0,0 +1,13 @@ +# AI框架 + +- **[AI引擎框架开发指南](subsys-aiframework-guide.md)** + +- **[搭建环境](subsys-aiframework-envbuild.md)** + +- **[技术规范](subsys-aiframework-tech.md)** + +- **[开发指导](subsys-aiframework-devguide.md)** + +- **[开发示例](subsys-aiframework-demo.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-application-framework-builden.md b/zh-cn/device-dev/subsystems/subsys-application-framework-builden.md new file mode 100644 index 0000000000000000000000000000000000000000..182aea265b994e46add0b4ab22ad8bab8bbf8153 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-application-framework-builden.md @@ -0,0 +1,7 @@ +# 搭建环境 + +- 开发板:Hi3516DV300 + +- [下载源码](../get-code/sourcecode-acquire.md) +- [编译用户程序框架](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E7%94%A8%E6%88%B7%E7%A8%8B%E5%BA%8F%E6%A1%86%E6%9E%B6%E5%AD%90%E7%B3%BB%E7%BB%9F.md) + diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213.md" b/zh-cn/device-dev/subsystems/subsys-application-framework-demo.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213.md" rename to zh-cn/device-dev/subsystems/subsys-application-framework-demo.md diff --git a/zh-cn/device-dev/subsystems/subsys-application-framework-guide.md b/zh-cn/device-dev/subsystems/subsys-application-framework-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..b132c23b9381bc71ac04a83359bad84395061fc8 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-application-framework-guide.md @@ -0,0 +1,711 @@ +# 开发指导 + +- [场景介绍](#section93012287133) +- [接口说明](#section11821047161319) +- [开发步骤](#section10514141679) + - [创建Service类型的Ability](#section19921154214315) + - [包管理接口使用指导](#section1724016743217) + - [Hap包打包](#section171771212328) + + +## 场景介绍 + +- 带界面的Ability的应用,比如:新闻类的应用、视频类的应用、导航类的应用、支付类的应用等等,目前我们看到的大部分应用都是带有界面的用于人机交互的应用。 + +- 不带界面的Ability应用,比如:音乐播放器能在后台播放音乐、后台提供计算服务、导航服务的各类应用等。 + +- 不管是带界面的Ability应用还是不带界面的Ability应用,都要打包成Hap包,最终发布到应用市场,用户通过应用市场下载安装相应的应用。 + +## 接口说明 + +**表 1** Ability子系统的对外接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口名称

+

接口描述

+

Want *WantParseUri(const char *uri)

+

反序列化接口,由字符串生成Want对象。

+

const char *WantToUri(Want want)

+

序列化,把Want对象生成字符串。

+

void SetWantElement(Want *want, ElementName element);

+

设置ElementName对象。

+

void SetWantData(Want *want, const void *data, uint16_t dataLength)

+

设置数据。

+

bool SetWantSvcIdentity(Want *want, SvcIdentity sid)

+

设置SvcIdentity。

+

void ClearWant(Want *want)

+

清除Want的内部内存数据。

+

void SetMainRoute(const std::string &entry)

+

设置AbilitySlice主路由。

+

void SetUIContent(RootView *rootView)

+

设置布局资源。

+

void OnStart(const Want& intent)

+

Ability生命周期状态回调,Ability启动时被回调。

+

void OnStop()

+

Ability生命周期状态回调,Ability销毁时被回调。

+

void OnActive(const Want& intent)

+

Ability生命周期状态回调,Ability显示时被回调。

+

void OnInactive()

+

Ability生命周期状态回调,Ability隐藏时被回调。

+

void OnBackground()

+

Ability生命周期状态回调,Ability退到后台时被回调。

+

const SvcIdentity *OnConnect(const Want &want)

+

Service类型Ability第一次连接时被回调。

+

void OnDisconnect(const Want &want);

+

Service类型Ability断开连接被回调。

+

void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply);

+

Service类型Ability接收消息处理。

+

void Dump(const std::string &extra)

+

dump Ability信息。

+

void Present(AbilitySlice *abilitySlice, const Want &want)

+

发起AbilitySlice跳转。

+

void Terminate()

+

退出当前AbilitySlice。

+

void SetUIContent(RootView *rootView)

+

设置当前AbilitySlice所在Ability的布局资源。

+

void OnStart(const Want& want)

+

AbilitySlice生命周期状态回调,AbilitySlice启动时被回调。

+

void OnStop()

+

AbilitySlice生命周期状态回调,AbilitySlice销毁时被回调。

+

void OnActive(const Want& want)

+

AbilitySlice生命周期状态回调,AbilitySlice显示时被回调。

+

void OnInactive()

+

AbilitySlice生命周期状态回调,AbilitySlice隐藏时被回调。

+

void OnBackground()

+

AbilitySlice生命周期状态回调,AbilitySlice退到后台时被回调。

+

int StartAbility(const Want &want)

+

启动Ability。

+

int StopAbility(const Want &want)

+

停止Service类型的Ability。

+

int TerminateAbility()

+

销毁当前的Ability。

+

int ConnectAbility(const Want &want, const IAbilityConnection &conn, void *data);

+

绑定Service类型的Ability。

+

int DisconnectAbility(const IAbilityConnection &conn)

+

解绑Service类型的Ability。

+

const char *GetBundleName()

+

获取当前ability的对应应用的包名。

+

const char *GetSrcPath()

+

获取当前ability的对应应用的安装路径。

+

const char *GetDataPath()

+

获取当前ability的对应应用的数据路径。

+

int StartAbility(const Want *want)

+

启动Ability,该接口可以不需要在基于Ability开发的应用中使用。

+

int ConnectAbility(const Want *want, const IAbilityConnection *conn, void *data);

+

绑定Service类型的Ability,该接口可以不需要在基于Ability开发的应用中使用。

+

int DisconnectAbility(const IAbilityConnection *conn);

+

解绑Service类型的Ability,该接口可以不需要在基于Ability开发的应用中使用。

+

int StopAbility(const Want *want)

+

停止Service类型的Ability,该接口可以不需要在基于Ability开发的应用中使用。

+

void (*OnAbilityConnectDone)(ElementName *elementName, SvcIdentity *serviceSid, int resultCode, void *data)

+

绑定Service Ability的回调。

+

void (*OnAbilityDisconnectDone)(ElementName *elementName, int resultCode, void *data)

+

解绑Service Ability的回调。

+

void PostTask(const Task& task)

+

投递任务到异步线程进行处理。

+

void PostQuit()

+

退出当前线程的消息循环。

+

static AbilityEventHandler* GetCurrentHandler()

+

获取当前线程的事件处理器。

+

void Run()

+

执行当前线程的消息循环。

+

#define REGISTER_AA(className)

+

注册开发者的Ability到框架中。

+

#define REGISTER_AS(className)

+

注册开发者的AbilitySlice到框架中。

+
+ +## 开发步骤 + +### 创建Service类型的Ability + +1. 在my\_service\_ability.h中创建Ability的子类MyServiceAbility。 + + ``` + class MyServiceAbility: public Ability { + protected: + void OnStart(const Want& want); + const SvcIdentity *OnConnect(const Want &want) override; + void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) override; + }; + ``` + +2. 调用REGISTER\_AA宏将ServiceAbility注册到应用框架中,以便应用框架实例化开发者的MyServiceAbility。 + + ``` + #include "my_service_ability.h" + + REGISTER_AA(ServiceAbility) + + void MyServiceAbility::OnStart(const Want& want) + { + printf("ServiceAbility::OnStart\n"); + Ability::OnStart(want); + } + + const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) + { + printf("ServiceAbility::OnConnect\n"); + return Ability::OnConnect(want); + } + + void MyServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) + { + printf("ServiceAbility::MsgHandle, funcId is %u\n", funcId); + int result = 0; + if (funcId == 0) { + result = IpcIoPopInt32(request) + IpcIoPopInt32(request); + } + // push data + IpcIoPushInt32(reply, result); + } + ``` + +3. 实现Service相关的生命周期方法。Service也是一种Ability,Ability为服务提供了以下生命周期方法,用户可以重写这些方法来添加自己的处理。用户在重写的方法里,需要调用父类对应的方法。 + - OnStart\(\) + + 该方法在创建Service的时候调用,用于做一些Service初始化且耗时较短的工作,在Service的整个生命周期只会调用一次。 + + ``` + void MyServiceAbility::OnStart(const Want& want) + { + printf("ServiceAbility::OnStart\n"); + Ability::OnStart(want); + } + ``` + + - OnConnect​\(\) + + 在组件和服务连接时调用,该方法返回SvcIdentity,组件可以通过它,与服务交互。 + + ``` + const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) + { + printf("ServiceAbility::OnConnect\n"); + return Ability::OnConnect(want); + } + ``` + + - OnDisconnect​\(\) + + 在组件与绑定的Service断开连接时调用。 + + - OnStop\(\) + + 在Service销毁时调用。Service应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。 + + +4. 重写消息处理方法。 + + MsgHandle是Service用来处理客户端消息的方法。其中funcId是客户端传过来的消息类型,request是客户端传过来的序列化请求参数。如果用户在处理完成之后想要把结果传回去,需要把结果序列化后写入reply中。 + + ``` + void ServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) + { + printf("ServiceAbility::MsgHandle, funcId is %d\n", funcId); + int result = 0; + if (funcId == PLUS) { + result = IpcIoPopInt32(request) + IpcIoPopInt32(request); + } + // push data + IpcIoPushInt32(reply, result); + } + ``` + +5. 注册Service。 + + Service也需要在应用清单文件config.json中进行注册,注册类型type需要设置为service。 + + ``` + "abilities": [{ + "name": "ServiceAbility", + "icon": "res/drawable/phone.png", + "label": "test app 2", + "launchType": "standard", + "type": "service", + "visible": true + } + ] + ``` + +6. 启动Service。 + - Ability为用户提供了StartAbility\(\)方法来启动另外一个Ability,因为Service也是Ability的一种,开发者同样可以通过将Want传递给该方法来启动Service。 + + 开发者可以通过Want的SetWantElement \(\)来设置目标服务信息。ElementName结构体的两个主要参数:第一个参数为包名称;第二个参数为目标Ability。 + + ``` + { + Want want = { nullptr }; + ElementName element = { nullptr }; + SetElementBundleName(&element, "com.company.appname"); + SetElementAbilityName(&element, "ServiceAbility"); + SetWantElement(&want, element); + StartAbility(want); + ClearElement(&element); + ClearWant(&want); + } + ``` + + StartAbility\(\) 方法会立即执行,如果Service尚未运行,则系统首先会调用OnStart\(\)。 + + - 停止Service。 + + Service一旦创建就会一直保持在后台运行,开发者可以通过调用StopAbility\(\)来停止Service。 + + +7. 连接Service。 + - 如果Service需要与Page Ability或其他应用组件中的Service进行交互,则应创建用于连接的Service。Service支持其他Ability通过ConnectAbility\(\)与其进行连接,ConnectAbility\(\)需要传入目标Service的Want,以及IAbilityConnection的实例来处理回调。IAbilityConnection提供了两个方法供用户实现,OnAbilityConnectDone\(\)用来处理连接的回调,OnAbilityDisconnectDone\(\)用来处理断开连接的回调。 + + ``` + { + // ability创建IAbilityConnection对象和定义IAbilityConnection的两个方法实现 + IAbilityConnection abilityConnection = new IAbilityConnection(); + abilityConnection->OnAbilityConnectDone = OnAbilityConnectDone; + abilityConnection->OnAbilityDisconnectDone = OnAbilityDisconnectDone; + + void OnAbilityConnectDone(ElementName *elementName, SvcIdentity *serviceSid, + int resultCode, void *data) + { + if (resultCode != 0) { + return; + } + // push data + IpcIo request; + char dataBuffer[IPC_IO_DATA_MAX]; + IpcIoInit(&request, dataBuffer, IPC_IO_DATA_MAX, 0); + IpcIoPushInt32(&request, 10); + IpcIoPushInt32(&request, 6); + + // send and getReply + IpcIo reply; + uintptr_t ptr = 0; + if (Transact(nullptr, *serviceSid, 0, &request, &reply, + LITEIPC_FLAG_DEFAULT, &ptr) != LITEIPC_OK) { + printf("transact error\n"); + return; + } + int result = IpcIoPopInt32(&reply); + printf("execute add method, result is %d\n", result); + if (ptr != 0) { + FreeBuffer(nullptr, reinterpret_cast(ptr)); + } + } + + void OnAbilityDisconnectDone(ElementName *elementName, + int resultCode, void *data) + { + printf("elementName is %s, %s\n", + elementName->bundleName, elementName->abilityName); + } + } + ``` + + - 发起connect和disconnect。 + + ``` + { + // ability发起connect + Want want = { nullptr }; + ElementName element = { nullptr }; + SetElementBundleName(&element, "com.company.appname"); + SetElementAbilityName(&element, "ServiceAbility"); + SetWantElement(&want, element); + ConnectAbility(want, *abilityConnection, this); + + // ability发起disconnect + DisconnectAbility(*abilityConnection); + } + ``` + + + +### 包管理接口使用指导 + +**安装应用** + +安装接口只能给内置的系统应用使用。根据应用的安装路径,可以在安装应用时进行选择: + +- 将应用安装到系统默认的文件目录/storage/app/。 +- 将应用安装到系统外挂的存储介质中,例如micro sdcard。 + +这两种选择可以在创建InstallParam实例的时候指定,当InstallParam的成员变量installLocation为 INSTALL\_LOCATION\_INTERNAL\_ONLY时,意味着应用将会被安装到/storage/app/目录下;当InstallParam的成员变量installLocation为INSTALL\_LOCATION\_PREFER\_EXTERNAL时,意味着应用将被安装到存储介质,其安装目录是/sdcard/app/。由于安装应用的过程是异步的,所以需要使用类似信号量的机制来确保安装的回调可以被执行。 + +安装应用的步骤如下(示例代码以安装到系统目录为例): + +1. 将经过安全签名的应用放置于指定的目录下。 +2. 创建InstallParam实例和信号量。 + + ``` + InstallParam installParam = { + .installLocation = INSTALL_LOCATION_INTERNAL_ONLY, // 安装到系统目录 + .keepData = false + }; + static sem_t g_sem; + ``` + +3. 定义回调函数。 + + ``` + static void InstallCallback(const uint8_t resultCode, const void *resultMessage) + { + std::string strMessage = reinterpret_cast(resultMessage); + if (!strMessage.empty()) { + printf("install resultMessage is %s, %d\n", strMessage.c_str(),resultCode); + } + sem_post(&g_sem); + } + ``` + +4. 调用Install接口。 + + ``` + const uint32_t WAIT_TIMEOUT = 30; + sem_init(&g_sem, 0, 0); + std::string installPath = “/storage/bundle/demo.hap”; // hap包的存储路径 + bool result = Install(installPath.c_str(), &installParam, InstallCallback); + struct timespec ts = {}; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += WAIT_TIMEOUT; // 超时即释放信号量 + sem_timedwait(&g_sem, &ts); + ``` + + +**卸载应用** + +卸载应用的时候可以选择是否保留应用的数据,开发者可以通过创建的InstallParam实例的成员变量keepData来确定。当keepData为true, 卸载应用之后将保留应用的数据,当keepData为false时,卸载应用之后将不会保留应用的数据。 + +1. 创建InstallParam实例和信号量。 + + ``` + static sem_t g_sem; + InstallParam installParam = { + .installLocation = 1, + .keepData = false // 不保留应用数据 + }; + ``` + +2. 定义回调函数。 + + ``` + static void UninstallCallback(const uint8_t resultCode, const void *resultMessage) + { + std::string strMessage = reinterpret_cast(resultMessage); + if (!strMessage.empty()) { + printf("uninstall resultMessage is %s\n", strMessage.c_str()); + g_resultMessage = strMessage; + } + g_resultCode = resultCode; + sem_post(&g_sem); + } + ``` + +3. 调用Uninstall接口。 + + ``` + sem_init(&g_sem, 0, 0); + const uint32_t WAIT_TIMEOUT = 30; + std::string BUNDLE_NAME = “com.huawei.demo”; // 卸载应用的包名 + Uninstall(BUNDLE_NAME.c_str(), &installParam, UninstallCallback); + struct timespec ts = {}; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += WAIT_TIMEOUT; + sem_timedwait(&g_sem, &ts); + ``` + + +**查询已安装应用的包信息** + +开发者可以利用BundleManager提供的接口GetBundleInfo来查询系统内已安装应用的包信息。 + +1. 创建以及初始化BundleInfo。 + + ``` + BundleInfo bundleInfo; + (void) memset_s(&bundleInfo, sizeof(BundleInfo), 0, sizeof(BundleInfo)); + ``` + +2. 调用GetBundleInfo接口,指定查询应用的包名,同时指定flag来确定获取的BundleInfo中是否含有元能力信息(实例代码以含有元能力信息为例)。 + + ``` + std::string BUNDLE_NAME = "com.huawei.demo"; + uint8_t ret = GetBundleInfo(BUNDLE_NAME.c_str(), 1, &bundleInfo); // flags = 1,获取包信息中含有元能力信息 + ``` + +3. 使用完获取的BundleInfo之后,要及时清理掉其内部所占用的内存空间避免内存泄漏。 + + ``` + ClearBundleInfo(&bundleInfo); + ``` + + +### Hap包打包 + +打包工具一般集成到开发工具或者ide中,开发者一般不涉及直接使用该工具,下面的介绍开发者可以作为了解。打包工具的jar包在开源代码中的位置:developtools/packing\_tool/jar。 + +- 打包命令行参数 + + **表 2** 打包所需要的资源文件描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令参数

+

对应的资源文件

+

说明

+

是否可缺省

+

--mode

+

-

+

为“hap”字段,打包生成hap

+

+

--json-path

+

清单文件config.json

+

-

+

+

--resources-path

+

资源文件resources

+

-

+

+

--assets-path

+

资源文件assets

+

-

+

+

--lib-path

+

依赖库文件

+

-

+

+

--shared-libs-path

+

共享库文件

+

针对系统应用的共享库,特殊情况下使用

+

+

--ability-so-path

+

主功能so文件

+

-

+

+

--index-path

+

资源索引

+

资源索引文件由资源生成工具生成,由资源流水线会集成该工具

+

+

--out-path

+

-

+

生成的hap包输出路径,默认为当前目录

+

+

--force

+

-

+

是否覆盖原有同名文件,默认为false

+

+
+ +- 打包示例 + - 开发视图 + + ![](figure/zh-cn_image_0000001062942690.png) + + - 编译视图 + + ![](figure/zh-cn_image_0000001062334618.png) + + - 使用打包工具执行以下命令打包: + + ![](figure/zh-cn_image_0000001062476933.png) + + ``` + $ java -jar hmos_app_packing_tool.jar --mode hap --json-path ./config.json --assets-path ./assets/ --ability-so-path ./libentry.so --index-path ./resources.index --out-path out/entry.hap --force true + ``` + + + diff --git a/zh-cn/device-dev/subsystems/subsys-application-framework-overview.md b/zh-cn/device-dev/subsystems/subsys-application-framework-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..a0ab8c2d1bbeb2118c32fee4eda946747445c5eb --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-application-framework-overview.md @@ -0,0 +1,141 @@ +# 概述 + +- [基本概念](#section72601941194812) +- [Ability子系统](#section14633111813374) +- [包管理子系统](#section1341146154412) +- [运作机制](#section94302021112717) +- [约束与限制](#section89534912527) + +用户程序框架是OpenHarmony为开发者提供开发OpenHarmony应用的开发框架,包含两个模块:Ability子系统和包管理子系统。 + +## 基本概念 + +开发者在开发前需要先了解以下基本概念,方便开发者更好的理解OpenHarmony用户程序框架。 + +## Ability子系统 + +Ability子系统是管理OpenHarmony应用运行状态的开发框架。 + +**图 1** Ability子系统框架图 +![](figure/Ability子系统框架图.png "Ability子系统框架图") + +- **Ability**:系统调度应用的最小单元,是能够完成一个独立功能的组件,一个应用可以包含一个或多个Ability。Ability分为两种类型:Page类型的Ability和Service类型的Ability。 + - **Page类型的Ability**:带有界面,为用户提供人机交互的能力。 + + - **Service类型的Ability**:不带界面,为用户提供后台任务机制。 + + + +- **AbilitySlice**:单个页面及其控制逻辑的总和,是Page类型Ability特有的组件,一个Page类型的Ability可以包含多个AbilitySlice,此时,这些页面提供的业务能力应当是高度相关的。 + + **图 2** Ability与AbilitySlice的关系图 + ![](figure/Ability与AbilitySlice的关系图.png "Ability与AbilitySlice的关系图") + +- **生命周期**:Ability被调度到启动、激活、隐藏和退出等各个状态的统称。 + + **图 3** Ability生命周期流转 + + + ![](figure/图片1.png) + + - **OnStart\(\)** + + 系统首次创建Page实例时触发该回调。对于一个Page实例,该回调在其生命周期过程中仅触发一次,Page在该逻辑后进入INACTIVE状态。开发者必须重写该方法,并在此配置默认展示的AbilitySlice。 + + - **OnActive\(\)** + + Page会在进入INACTIVE状态后来到前台,然后系统调用此回调。Page在此之后进入ACTIVE状态,该状态是应用与用户交互的状态。Page将保持在此状态,除非某类事件发生导致Page失去焦点,比如用户点击返回键或导航到其他Page。 + + 当此类事件发生时,会触发Page回到INACTIVE状态,系统将调用OnInactive\(\)回调。此后,Page可能重新回到ACTIVE状态,系统将再次调用OnActive\(\)回调。因此,开发者通常需要成对实现OnActive\(\)和OnInactive\(\),并在OnActive\(\)中获取在OnInactive\(\)中被释放的资源。 + + - **OnInactive\(\)** + + 当Page失去焦点时,系统将调用此回调,此后Page进入INACTIVE状态。开发者可以在此回调中实现Page失去焦点时应表现的恰当行为。 + + - **OnBackground\(\)** + + 如果Page不再对用户可见,系统将可能根据资源状况调用此回调,此后Page进入BACKGROUND状态。开发者应该在此回调中释放Page不可见时无用的资源,或在此回调中执行较为耗时的状态保存操作。 + + - **OnForeground\(\)** + + 处于BACKGROUND状态的Page仍然驻留在内存中,当重新回到前台时(比如用户重新导航到此Page),系统将先调用OnForeground\(\)回调使Page回到INACTIVE状态,然后调用OnActive\(\)回调使Page回到ACTIVE状态。开发者应当在此回调中重新申请在OnBackground\(\)中释放的资源。轻量化设备目前不支持该接口。 + + - **OnStop\(\)** + + 此回调表示系统正在销毁Page。销毁Page的可能原因包括: + + - 用户通过系统管理能力显式关闭Page,例如使用任务管理器关闭Page。 + - 用户行为触发Page的TerminateAbility\(\)方法调用,例如使用应用的退出功能。 + - 配置变更导致系统暂时销毁Page并重建。 + - 系统出于资源管理目的,自动触发对处于BACKGROUND状态Page的销毁。 + + +- **AbilityKit**:Ability框架提供给开发者的开发包,开发者基于该开发包可以开发出基于Ability组件的应用。基于Ability组件开发的应用有两种类型:基于Javascript语言开发的Ability(JS Ability)和基于C/C++语言开发的Ability(Native Ability)。JS应用开发框架是开发者开发JS Ability所用到框架,是在AbilityKit基础封装的包含js UI组件的一套方便开发者能够迅速开发Ability应用的框架。 +- **AbilityLoader**:负责注册和加载开发者Ability的模块。开发者开发的Ability先要调用AbilityLoader的注册接口注册到框架中,接着Ability启动时会被实例化。 + +- **AbilityManager:**负责AbilityKit和Ability管理服务进行IPC的通信。 + +- **EventHandler**:AbilityKit提供给开发者的用于在Ability中实现线程间通信的一个模块。 + +- **AbilityManagerService**:元能力运行管理服务。该服务用于协调各Ability运行关系、及生命周期进行调度的系统服务。其中,服务启动模块负责Ability管理服务的启动、注册等。服务接口管理模块负责Ability管理服务对外能力的管理。进程管理模块负责Ability应用所在进程的启动和销毁、及其进程信息维护等功能。Ability栈管理模块负责维护各个Ability之间跳转的先后关系。生命周期调度模块是Ability管理服务根据系统当前的操作调度Ability进入相应的状态的模块。连接管理模块是Ability管理服务对Service类型Ability连接管理的模块 + +- **AppSpawn**:负责创建Ability应用所在进程的系统服务,该服务有较高的权限,为Ability应用设置相应的权限,并预加载一些通用的模块,加速应用的启动。 + + +## 包管理子系统 + +包管理子系统是OpenHarmony为开发者提供的安装包管理框架。 + +**图 4** 包管理子系统框架图 +![](figure/包管理子系统框架图.png "包管理子系统框架图") + +- **BundleKit**:是包管理服务对外提供的接口,有安装/卸载接口、包信息查询接口、包状态变化listen接口。 +- **包扫描器**:用来解析本地预制或者安装的安装包,提取里面的各种信息,供管理子模块进行管理,持久化。 +- **包安装子模块**:安装,卸载,升级一个包;包安装服务是一个单独进程和包管理服务通过IPC进行通信,该服务用于创建、删除安装目录和数据目录等,具有较高的权限。 + +- **包管理子模块**:管理安装包相关的信息,存储持久化包信息。 + +- **包安全管理子模块**:签名检查、权限授予、权限管理。 + + +## 运作机制 + +Ability子系统的核心模块是Ability管理服务、包管理子系统的核心模块是包管理服务,这两个服务是系统级服务,借助系统服务框架Samgr实现服务的注册与发现,并对其他进程提供Ability管理服务和包管理服务。Ability管理服务和包管理服务通过AbilityKit和BundleKit以接口的形式向外提供服务。 + +**图 5** Ability管理服务和包管理服务启动 +![](figure/Ability管理服务和包管理服务启动.png "Ability管理服务和包管理服务启动") + +Ability管理服务和包管理服务启动后,就可以安装OpenHarmony应用和启动运行OpenHarmony应用。 + +**图 6** 应用启动流程 +![](figure/应用启动流程.png "应用启动流程") + +桌面为Ability管理服务启动的第一个OpenHarmony应用。桌面启动后,用户可以在桌面上点击安装的OpenHarmony应用并启动该应用。上图6为从桌面启动一个已安装应用的交互流程。 + +从图中可知,Ability管理服务负责协调Ability之间的显示隐藏,包管理服务负责Ability信息的存储查询。 + +## 约束与限制 + +- 语言版本 + + - C++11版本或以上 + + +- 框架针对不同的芯片平台和底层OS能力,规格有所区别 + + - Cortex-M RAM/ROM: + + - RAM:建议大于20K + + - ROM: \> 300K (包含JS应用开发框架,UIKit及引擎等强相关子系统) + + + - Cortex-A RAM/ROM: + + - RAM:建议大于2M + + - ROM:\> 2M (包含JS应用开发框架,UIKit及引擎等强相关子系统) + + + + diff --git a/zh-cn/device-dev/subsystems/subsys-application-framework.md b/zh-cn/device-dev/subsystems/subsys-application-framework.md new file mode 100644 index 0000000000000000000000000000000000000000..99997047ffcf4648b1b4e7fe5eb8ce2db5c6d66c --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-application-framework.md @@ -0,0 +1,11 @@ +# 用户程序框架 + +- **[概述](subsys-application-framework-overview.md)** + +- **[搭建环境](subsys-application-framework-builden.md)** + +- **[开发指导](subsys-application-framework-guide.md)** + +- **[开发实例](subsys-application-framework-demo.md)** + + diff --git "a/zh-cn/device-dev/subsystems/appspawn\345\272\224\347\224\250\345\255\265\345\214\226\347\273\204\344\273\266.md" b/zh-cn/device-dev/subsystems/subsys-boot-appspawn.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/appspawn\345\272\224\347\224\250\345\255\265\345\214\226\347\273\204\344\273\266.md" rename to zh-cn/device-dev/subsystems/subsys-boot-appspawn.md diff --git "a/zh-cn/device-dev/subsystems/bootstrap\346\234\215\345\212\241\345\220\257\345\212\250\347\273\204\344\273\266.md" b/zh-cn/device-dev/subsystems/subsys-boot-bootstrap.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/bootstrap\346\234\215\345\212\241\345\220\257\345\212\250\347\273\204\344\273\266.md" rename to zh-cn/device-dev/subsystems/subsys-boot-bootstrap.md diff --git a/zh-cn/device-dev/subsystems/subsys-boot-faqs.md b/zh-cn/device-dev/subsystems/subsys-boot-faqs.md new file mode 100644 index 0000000000000000000000000000000000000000..196a586630627ef713e6acedf249952fbe63ae5d --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-boot-faqs.md @@ -0,0 +1,56 @@ +# 常见问题 + +- [系统启动过程中打印“parse failed!”错误后停止启动](#section2041345718513) +- [系统启动过程未结束就自动重启,如此反复持续](#section57381816168) +- [参数正确的情况下调用SetParameter/GetParameter返回失败](#section129991227141512) + +## 系统启动过程中打印“parse failed!”错误后停止启动 + +**现象描述** + +系统启动过程中,打印“\[Init\] InitReadCfg, parse failed! please check file /etc/init.cfg format.”错误,启动过程停止,如下图所示: + +![](figure/zh-cn_image_0000001063839940.png) + +**可能原因** + +修改init.cfg文件时,漏掉或多加了逗号或括号等,导致init.cfg文件的json格式被破坏。 + +**解决办法** + +仔细检查init.cfg文件,确保其格式符合json格式要求。 + +## 系统启动过程未结束就自动重启,如此反复持续 + +**现象描述** + +镜像烧写完成后系统启动,启动过程未完成即自动重新启动,如此反复持续。 + +**可能原因** + +被init启动的服务都有一个叫做“importance”的属性(详见[第2章表3](subsys-boot-init.md#table14737791471)描述)。 + +- 当该属性为0时,表示若当前服务进程退出,init不需要重启单板。 +- 当该属性为1时,表示若当前服务进程退出,init需要重启单板。 + +因此出现上述现象的可能原因:有“importance”属性为1的服务在每次启动的过程中都会退出(可能是进程崩溃或出错自动退出),导致init进程自动重启单板。 + +**解决办法** + +1. 需要通过日志确认崩溃或报错退出的服务,并解决其崩溃/报错的问题,然后重新烧写镜像即可。 +2. 也可以将崩溃/报错退出的服务的“importance”属性改为0,然后重新烧写镜像,这样即使其退出,init也不会重启单板。 + +## 参数正确的情况下调用SetParameter/GetParameter返回失败 + +**现象描述** + +在各参数正确的情况下调用SetParameter/GetParameter返回失败。 + +**可能原因** + +程序对SetParameter/GetParameter这两个接口做了权限校验,在各参数正确的情况下调用SetParameter/GetParameter返回操作失败,很有可能是调用者的uid大于1000,没有调用权限。 + +**解决办法** + +无需处理 + diff --git "a/zh-cn/device-dev/subsystems/init\345\220\257\345\212\250\345\274\225\345\257\274\347\273\204\344\273\266.md" b/zh-cn/device-dev/subsystems/subsys-boot-init.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/init\345\220\257\345\212\250\345\274\225\345\257\274\347\273\204\344\273\266.md" rename to zh-cn/device-dev/subsystems/subsys-boot-init.md diff --git a/zh-cn/device-dev/subsystems/subsys-boot-overview.md b/zh-cn/device-dev/subsystems/subsys-boot-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..ee24488c41a99af1472600ecfabe775a0e18e4c3 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-boot-overview.md @@ -0,0 +1,66 @@ +# 启动恢复子系统概述 + +- [约束与限制](#section2029921310472) + +启动恢复子系统负责从内核启动之后到应用启动之前的系统关键服务进程的启动过程以及设备恢复出厂设置的功能。涉及以下组件: + +- init启动引导组件 + + init启动引导组件对应的进程为init进程,是内核完成初始化后启动的第一个用户态进程。init进程启动之后,读取init.cfg配置文件,根据解析结果,执行相应命令(见[第2章表2](subsys-boot-init.md#table122681439144112)描述)并依次启动各关键系统服务进程,在启动系统服务进程的同时设置其对应权限。 + +- appspawn应用孵化组件 + + 负责接收**用户程序框架**的命令孵化应用进程,设置新进程的权限,并调用应用程序框架的入口函数。 + +- bootstrap服务启动组件 + + 提供了各服务和功能的启动入口标识。在SAMGR启动时,会调用boostrap标识的入口函数,并启动系统服务。 + +- syspara系统属性组件 + + 系统属性组件,根据OpenHarmony产品兼容性规范提供获取设备信息的接口,如:产品名、品牌名、厂家名等,同时提供设置/读取系统属性的接口。 + + +## 约束与限制 + +启动恢复子系统源代码目录和适配平台: + +**表 1** 启动恢复子系统源代码目录和适配平台 + + + + + + + + + + + + + + + + + + + +

名称

+

适配平台

+

base/startup/appspawn_lite

+

小型系统设备(参考内存≥1MB),如Hi3516DV300 、Hi3518EV300

+

base/startup/bootstrap_lite

+

轻量系统设备(参考内存≥128KB),如Hi3861V100

+

base/startup/init_lite

+

小型系统设备(参考内存≥1MB),如Hi3516DV300、Hi3518EV300

+

base/startup/syspara_lite

+
  • 轻量系统设备(参考内存≥128KB),如Hi3861V100
  • 小型系统设备(参考内存≥1MB),如Hi3516DV300、Hi3518EV300
+
+ +- init启动引导组件: + - 配置文件init.cfg烧写到单板之后变成只读模式,修改时必须重新打包和烧写rootfs镜像。 + - 配置文件init.cfg仅支持json格式。 + +- bootstrap服务启动组件:需要在链接脚本中配置zInit代码段。 +- syspara系统属性组件:SetParameter/GetParameter仅支持uid大于1000的应用调用。 + diff --git "a/zh-cn/device-dev/subsystems/\345\217\202\350\200\203.md" b/zh-cn/device-dev/subsystems/subsys-boot-ref.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\217\202\350\200\203.md" rename to zh-cn/device-dev/subsystems/subsys-boot-ref.md diff --git "a/zh-cn/device-dev/subsystems/syspara\347\263\273\347\273\237\345\261\236\346\200\247\347\273\204\344\273\266.md" b/zh-cn/device-dev/subsystems/subsys-boot-syspara.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/syspara\347\263\273\347\273\237\345\261\236\346\200\247\347\273\204\344\273\266.md" rename to zh-cn/device-dev/subsystems/subsys-boot-syspara.md diff --git a/zh-cn/device-dev/subsystems/subsys-boot.md b/zh-cn/device-dev/subsystems/subsys-boot.md new file mode 100644 index 0000000000000000000000000000000000000000..a71c6ab86284f1d1dca602c5e7fffd2aae961f7f --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-boot.md @@ -0,0 +1,17 @@ +# 启动恢复 + +- **[启动恢复子系统概述](subsys-boot-overview.md)** + +- **[init启动引导组件](subsys-boot-init.md)** + +- **[appspawn应用孵化组件](subsys-boot-appspawn.md)** + +- **[bootstrap服务启动组件](subsys-boot-bootstrap.md)** + +- **[syspara系统属性组件](subsys-boot-syspara.md)** + +- **[常见问题](subsys-boot-faqs.md)** + +- **[参考](subsys-boot-ref.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-build-mini-lite.md b/zh-cn/device-dev/subsystems/subsys-build-mini-lite.md new file mode 100644 index 0000000000000000000000000000000000000000..dc07da91d5c8c7967965ba91ae1ed276279eb8f7 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-build-mini-lite.md @@ -0,0 +1,996 @@ +# 轻量和小型系统编译构建指导 + +- [概述](#section10958256161119) + - [基本概念](#section1732301411128) + - [目录结构](#section1588744014121) + - [构建流程](#section15761735134) + +- [配置规则](#section2345183962710) + - [组件](#section142532518308) + - [芯片解决方案](#section121501451143710) + - [产品解决方案](#section134549283435) + +- [使用指导](#section13754457192211) + - [前提条件](#section31651120233) + - [hb工具使用说明](#section1133304172313) + - [新增组件](#section167110415315) + - [新增芯片解决方案](#section1474718565412) + - [新增产品解决方案](#section1097623294220) + +- [常见问题](#section19909721104319) + - [ninja版本问题导致编译失败](#section138233464318) + - [ncurses库缺失导致编译失败](#section151033911442) + - [未安装mcopy导致编译失败](#section19811838104418) + - [权限问题导致编译失败](#section03111118451) + - [未安装Crypto导致编译失败](#section69981127125013) + - [编译环境为shell导致编译失败](#section967617530505) + + +## 概述 + +一个基于gn和ninja的构建系统,以支持OpenHarmony组件化开发为目标,提供以下基本功能: + +- 支持按组件拼装产品并编译。 + +- 独立构建芯片解决方案厂商源码。 +- 独立构建单个组件。 + +### 基本概念 + +在使用编译构建子系统前,应了解如下基本概念: + +- 子系统 + + 子系统是一个逻辑概念,它由一个或多个具体的组件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 \> 子系统 \> 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。 + + +- 组件 + + 系统最小的可复用、可配置、可裁剪的功能单元。组件具备目录独立可并行开发、可独立编译、可独立测试的特征。 + +- gn + + Generate ninja的缩写,用于产生ninja文件。 + +- ninja + + ninja是一个专注于速度的小型构建系统。 + +- hb + + OpenHarmony的命令行工具,用来执行编译命令。 + + +### 目录结构 + +``` +build/lite +├── components # 组件描述文件 +├── figures # readme中的图片 +├── hb # hb pip安装包源码 +├── make_rootfs # 文件系统镜像制作脚本 +├── config # 编译配置项 +│ ├── component # 组件相关的模板定义 +│ ├── kernel # 内核相关的编译配置 +│ └── subsystem # 子系统编译配置 +├── platform # ld脚本 +├── testfwk # 测试编译框架 +└── toolchain # 编译工具链配置,包括:编译器路径、编译选项、链接选项等 +``` + +### 构建流程 + +编译构建流程如[图1 ](#fig9744112715161)所示,主要分设置和编译两步: + +**图 1** 编译构建流程 +![](figure/编译构建流程.jpg "编译构建流程") + +1. hb set: 设置OpenHarmony源码目录和要编译的产品。 +2. hb build: 编译产品、开发板或者组件。编译主要过程如下: + - 读取编译配置:根据产品选择的开发板,读取开发板config.gni文件内容,主要包括编译工具链、编译链接命令和选项等。 + - 调用gn:调用gn gen命令,读取产品配置生成产品解决方案out目录和ninja文件。 + - 调用ninja:调用ninja -C out/board/product启动编译。 + - 系统镜像打包:将组件编译产物打包,设置文件属性和权限,制作文件系统镜像。 + + +## 配置规则 + +为了实现芯片解决方案、产品解决方案与OpenHarmony是解耦的、可插拔的,组件、芯片解决方案和产品解决方案的路径、目录树和配置需遵循一定的规则,具体如下: + +### **组件** + +组件源码路径命名规则为:**\{领域\}/\{子系统\}/\{组件\}**,组件目录树规则如下: + +>![](../public_sys-resources/icon-caution.gif) **注意:** +>组件的名称、源码路径、功能简介、是否必选、编译目标、RAM、ROM、编译输出、已适配的内核、可配置的特性和依赖等属性定义在build/lite/components目录下对应子系统的json文件中,新增组件时需要在对应子系统json文件中添加相应的组件定义。产品所配置的组件必须在某个子系统中被定义过,否则会校验失败。 + +``` +component +├── interfaces +│ ├── innerkits # 系统内接口,组件间使用 +│ └── kits # 应用接口,应用开发者使用 +├── frameworks # framework实现 +├── services # service实现 +└── BUILD.gn # 组件编译脚本 +``` + +以泛sensor子系统的sensor服务组件为例,组件属性定义描述文件字段说明如下: + +``` +{ + "components": [ + { + "component": "sensor_lite", # 组件名称 + "description": "Sensor services", # 组件一句话功能描述 + "optional": "true", # 组件是否为最小系统必选 + "dirs": [ # 组件源码路径 + "base/sensors/sensor_lite" + ], + "targets": [ # 组件编译入口 + "//base/sensors/sensor_lite/services:sensor_service" + ], + "rom": "92KB", # 组件ROM值 + "ram": "~200KB", # 组件RAM估值 + "output": [ "libsensor_frameworks.so" ], # 组件编译输出 + "adapted_kernel": [ "liteos_a" ], # 组件已适配的内核 + "features": [], # 组件可配置的特性 + "deps": { + "components": [ # 组件依赖的其他组件 + "samgr_lite", + "ipc_lite" + + ], + "third_party": [ # 组件依赖的三方开源软件 + "bounds_checking_function" + ] + } + } + ] +} +``` + +组件BUILD.gn的编写建议如下: + +- 编译目标名称与组件一致。 +- 组件对外可配置的特性变量需声明在该组件BUILD.gn中,特性变量命名规则:ohos\_\{subsystem\}\_\{component\}\_\{feature\}。特性在组件描述中也需要同步定义,在产品配置文件config.json中按需配置。 +- 宏定义规则:OHOS\_\{SUBSYSTEM\}\_\{COMPONENT\}\_\{FEATURE\} + + >![](../public_sys-resources/icon-note.gif) **说明:** + >组件的编译脚本语言为gn,gn的基本用法请见[gn快速入门](https://gn.googlesource.com/gn/+/master/docs/quick_start.md)。组件即为gn定义的编译目标,可以为静态库、动态库、可执行文件或group。 + + +以图形的UI组件为例,foundation/graphic/ui/BUILD.gn文件如下: + +``` + # 声明组件可配置的特性 + declare_args() { + enable_ohos_graphic_ui_animator = false # 动效特性开关 + ohos_ohos_graphic_ui_font = "vector" # 可配置的字体类型,vector或者bitmap + } + + # 组件基础功能 + shared_library("base") { + sources = [ + ...... + ] + include_dirs = [ + ...... + ] + } + + # 仅在animator开启时编译 + if(enable_ohos_graphic_ui_animator ) { + shared_library("animator") { + sources = [ + ...... + ] + include_dirs = [ + ...... + ] + deps = [ :base ] + } + } + ...... + # target名称建议与组件名称一致, 组件target类型可以是executable(bin文件),shared_library(动态库.so),static_library(静态库.a),group等等 + executable("ui") { + deps = [ + ":base" + ] + + # animator特性由产品配置 + if(enable_ohos_graphic_ui_animator ) { + deps += [ + "animator" + ] + } + } +``` + +### **芯片解决方案** + +- 芯片解决方案是指基于某款开发板的完整解决方案,包含驱动、设备侧接口适配、开发板sdk等。 +- 芯片解决方案是一个特殊的组件,源码路径规则为:**device/\{芯片解决方案厂商\}/\{开发板\}**。 +- 芯片解决方案组件会随产品选择的开发板默认编译。 + +芯片解决方案目录树规则如下: + +``` +device +└── company # 芯片解决方案厂商 + └── board # 开发板名称 + ├── BUILD.gn # 编译脚本 + ├── hals # OS南向接口适配 + ├── linux # 可选,linux内核版本 + │ └── config.gni # linux版本编译配置 + └── liteos_a # 可选,liteos内核版本 + └── config.gni # liteos_a版本编译配置 +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>config.gni为开发板编译相关的配置,编译时会采用该配置文件中的参数编译所有OS组件,编译阶段系统全局可见。 + +config.gni的关键字段介绍如下: + +``` +kernel_type: 开发板使用的内核类型,例如:“liteos_a”, “liteos_m”, “linux”。 +kernel_version: 开发使用的内核版本,例如:“4.19”。 +board_cpu: 开发板CPU类型,例如:“cortex-a7”, “riscv32”。 +board_arch: 开发芯片arch, 例如: “armv7-a”, “rv32imac”。 +board_toolchain: 开发板自定义的编译工具链名称,例如:“gcc-arm-none-eabi”。若为空,则使用默认为ohos-clang。 +board_toolchain_prefix:编译工具链前缀,例如:“gcc-arm-none-eabi”。 +board_toolchain_type: 编译工具链类型,目前支持gcc和clang。例如:“gcc” ,“clang”。 +board_cflags: 开发板配置的c文件编译选项。 +board_cxx_flags: 开发板配置的cpp文件编译选项。 +board_ld_flags: 开发板配置的链接选项。 +``` + +### **产品解决方案** + +产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、组件拼装配置、启动配置和文件系统配置等。产品解决方案的源码路径规则为:**vendor/\{产品解决方案厂商\}/\{产品名称\}**_。_产品解决方案也是一个特殊的组件。 + +产品解决方案的目录树规则如下: + +``` +vendor +└── company # 产品解决方案厂商 + ├── product # 产品名称 + │ ├── init_configs + │ │ ├── etc # init进程启动配置(可选,仅linux内核需要) + │ │ └── init.cfg # 系统服务启动配置 + │ ├── hals # 产品解决方案OS适配 + │ ├── BUILD.gn # 产品编译脚本 + │ └── config.json # 产品配置文件 + │ └── fs.yml # 文件系统打包配置 + └── ...... +``` + +>![](../public_sys-resources/icon-caution.gif) **注意:** +>**新增产品须按如上的规则创建目录和文件,编译构建系统将按该规则扫描已配置的产品。** + +关键的目录和文件详细介绍如下: + +1. **vendor/company/product/init\_configs/etc** + + 该文件夹中包含rcS脚本,Sxxx脚本和fstab脚本。init进程在启动系统服务之前执行这些脚本。执行的流程为“rcS-\>fstab-\>S00-xxx“。Sxxx脚本中的内容与开发板和产品需要有关,主要包括设备节点的创建、创建目录、扫描设备节点、修改文件权限等等。这些文件在产品编译的BUILD.gn中按需拷贝到产品out目录中,最终打包到rootfs镜像中。 + +2. **vendor/company/product/init\_configs/init.cfg** + + init进程启动服务的配置文件,当前支持解析的命令有: + + - start: 启动某个服务 + - mkdir: 创建文件夹 + - chmod: 修改指定路径/文件的权限 + - chown: 修改指定路径/文件的属组 + - mount: 挂载命令 + + 该文件中的各个字段的解释如下: + + ``` + { + "jobs" : [{ # job数组,一个job对应一个命令集合。job的执行顺序:pre-init -> init -> post-init。 + "name" : "pre-init", + "cmds" : [ + "mkdir /storage/data", # 创建目录 + "chmod 0755 /storage/data", # 修改权限,权限值的格式为0xxx, 如0755 + "mkdir /storage/data/log", + "chmod 0755 /storage/data/log", + "chown 4 4 /storage/data/log", # 修改属组,第一个数字为uid, 第二个数字为gid + ...... + "mount vfat /dev/mmcblock0 /sdcard rw,umask=000" # 挂载,格式为: mount [文件系统类型] [source] [target] [flags] [data] + # 其中flags仅支持:nodev、noexec、nosuid和rdonly + ] + }, { + "name" : "init", + "cmds" : [ # 按cmds数组顺序启动启动服务 + "start shell", # 注意:start与服务名称之间有且只有一个空格 + ...... + "start service1" + ] + }, { + "name" : "post-init", # 最后执行的job, init进程启动完成后的处理(如驱动初始化后再mount设备) + "cmds" : [] + } + ], + "services" : [{ # service数组,一个service对应一个进程 + "name" : "shell", # 服务名称 + "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"], # 可执行文件全路径,path必须为第一个元素 + "uid" : 0, # 进程的uid,须与二进制文件的uid保持一致 + "gid" : 0, # 进程的gid,须与二进制文件的gid保持一致 + "once" : 0, # 是否为一次性进程,1:进程退出后,init不在重新拉起。0:常驻进程,进程若退出,init将重新拉起 + "importance" : 0, # 是否为关键进程,1:是关键进程,若进程退出,init将会重启单板。0:非关键进程,若进程退出,init不会重启单板 + "caps" : [4294967295] + }, + ...... + ] + } + ``` + +3. **vendor/company/product/init\_configs/hals** + + 解决方案厂商对OS的适配,需要实现的接口请见各个组件的readme说明文档。 + +4. **vendor/company/product/config.json** + + config.json为编译构建的主入口,包含了开发板、OS组件和内核等配置信息。 + + 以基于hispark\_taurus开发板的ipcamera产品为例,配置文件如下: + + ``` + { + "product_name": "ipcamera", # 产品名称 + "ohos_version": "OpenHarmony 1.0", # 选择的OS版本 + "device_company": "hisilicon", # 芯片厂商 + "board": "hispark_taurus", # 开发板名称 + "kernel_type": "liteos_a", # 选择的内核类型 + "kernel_version": "3.0.0", # 选择的内核版本 + "subsystems": [ + { + "subsystem": "aafwk", # 选择的子系统 + "components": [ + { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] } # 选择的组件和组件特性配置 + ] + }, + { + ...... + } + ...... + 更多子系统和组件 + } + } + ``` + +5. **vendor/company/product/fs.yml** + + 该文件用于配置文件系统镜像制作过程,将编译产物打包成文件系统镜像,比如用户态根文件系统rootfs.img和可读写的userfs.img。它由多个列表组成,每个列表对应一个文件系统。字段说明如下: + + ``` + fs_dir_name: 必填,声明文件系统文件名, 如rootfs、userfs + fs_dirs: 选填,配置out下文件目录与文件系统文件目录的映射关系,每个文件目录对应一个列表 + source_dir: 选填,out下目标文件目录,若缺失则将根据target_dir在文件系统下创建空目录 + target_dir: 必填,文件系统下对应文件目录 + ignore_files:选填,声明拷贝忽略文件 + dir_mode: 选填,文件目录权限,默认755 + file_mode: 选填,该文件目录下所有文件的权限,默认555 + fs_filemode: 选填,配置需要特殊声明权限的文件,每个文件对应一个列表 + file_dir: 必填,文件系统下具体文件路径 + file_mode: 必填,文件权限声明 + fs_symlink: 选填,配置文件系统软连接 + fs_make_cmd: 必填,配置需要制作文件系统脚本,OS提供的脚本在build/lite/make_rootfs下, 支持linux,liteos内核和ext4、jffs2、vfat格式。也支持芯片解决方案厂商自定义。 + fs_attr: 选填,根据配置项动态调整文件系统 + ``` + + 其中fs\_symlink、fs\_make\_cmd字段支持以下变量: + + - $\{root\_path\} + + 代码根目录,对应gn的$\{ohos\_root\_path\} + + - $\{out\_path\} + + 产品out目录,对应gn的$\{root\_out\_dir\} + + - $\{fs\_dir\} + + 文件系统目录,由以下变量拼接而成 + + - $\{root\_path\} + - $\{fs\_dir\_name\} + + + >![](../public_sys-resources/icon-note.gif) **说明:** + >fs.yml是可选的,对于没有文件系统的设备可不配置。 + +6. **vendor/company/product/BUILD.gn** + + 产品编译的入口,主要用于编译解决方案厂商源码和拷贝启动配置文件。如果某个产品被选择为要编译的产品,那么对应产品目录下的BUILD.gn会默认编译。一个典型的产品编译BUILD.gn应该如下: + + ``` + group("product") { # target名称需与product名称即三级目录名称一致 + deps = [] + # 拷贝init配置 + deps += [ "init_configs" ] + # 其他 + ...... + } + ``` + + +## 使用指导 + +### 前提条件 + +开发环境需安装gn、ninja构建工具、python 3.7.4及以上和hb。安装方法请见[搭建系统基础环境](../quick-start/quickstart-lite-env-setup.md)。 + +### hb工具使用说明 + +hb是OpenHarmony的命令行工具,用来执行编译命令。以下对hb的常用命令进行说明。 + +**hb set** + +``` +hb set -h +usage: hb set [-h] [-root [ROOT_PATH]] [-p] + +optional arguments: + -h, --help show this help message and exit + -root [ROOT_PATH], --root_path [ROOT_PATH] + Set OHOS root path + -p, --product Set OHOS board and kernel +``` + +- hb set 后无参数,进入默认设置流程 +- hb set -root dir可直接设置代码根目录 +- hb set -p设置要编译的产品 + +**hb env** + +查看当前设置信息 + +``` +hb env +[OHOS INFO] root path: xxx +[OHOS INFO] board: hispark_taurus +[OHOS INFO] kernel: liteos +[OHOS INFO] product: ipcamera +[OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera +[OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 +``` + +**hb build** + +``` +hb build -h +usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] + [--dmverity] [--tee] [-p PRODUCT] [-f] [-n] + [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch] + [component [component ...]] + +positional arguments: + component name of the component + +optional arguments: + -h, --help show this help message and exit + -b BUILD_TYPE, --build_type BUILD_TYPE + release or debug version + -c COMPILER, --compiler COMPILER + specify compiler + -t [TEST [TEST ...]], --test [TEST [TEST ...]] + compile test suit + --dmverity Enable dmverity + --tee Enable tee + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: camera@huawei + -f, --full full code compilation + -n, --ndk compile ndk + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target + -v, --verbose show all command lines while building + -shs, --sign_haps_by_server + sign haps by server + --patch apply product patch before compiling + + --dmverity Enable dmverity + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: ipcamera@hisilcon + -f, --full full code compilation + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target +``` + +- hb build后无参数,会按照设置好的代码路径、产品进行编译,编译选项使用与之前保持一致。-f 选项将删除当前产品所有编译产品,等同于hb clean + hb build. +- hb build \{component\_name\}:基于设置好的产品对应的单板、内核,单独编译组件(e.g.:hb build kv\_store\)。 +- hb build -p ipcamera@hisilicon:免set编译产品,该命令可以跳过set步骤,直接编译产品。 +- 在device/device\_company/board下单独执行hb build会进入内核选择界面,选择完成后会根据当前路径的单板、选择的内核编译出仅包含内核、驱动的镜像。 + +**hb clean** + +清除out目录对应产品的编译产物,仅保留args.gn、build.log。清除指定路径可输入路径参数:hb clean out/board/product,默认将清除当前hb set的产品对应out路径。 + +``` +hb clean +usage: hb clean [-h] [out_path] + +positional arguments: + out_path clean a specified path. + +optional arguments: + -h, --help show this help message and exit +``` + +### 新增组件 + +本小节介绍如何新增一个组件,首先确定组件归属的子系统和组件名称,然后按如下步骤新增: + +1. 源码开发完成后,添加组件编译脚本。 + + 以编译组件hello\_world可执行文件为例,applications/sample/hello\_world/BUILD.gn可以写为: + + ``` + executable("hello_world") { + include_dirs = [ + "include", + ] + sources = [ + "src/hello_world.c" + ] + } + ``` + + 如上编译脚本,可编译出一个可在OpenHarmony上运行的名为hello\_world的可执行文件。 + + 单独编译该组件,hb set任意选择一款产品,然后使用-T选项单独编译组件: + + ``` + hb build -f -T //applications/sample/hello_world + ``` + + 组件在开发板上功能验证完成后,可按[步骤2\~4](#li11471037297)将组件配置到产品中。 + +2. 添加组件描述。 + + 组件描述位于build/lite/components下,新增的组件需加入对应子系统的json文件中。一个组件描述必选的字段有: + + - component:组件名称。 + - description:组件的一句话功能描述。 + - optional:组件是否为系统可选。 + - dirs:组件源码路径。 + - targets:组件编译入口。 + + 以将hello\_world组件加入应用子系统为例,在applications.json中添加hello\_world对象: + + ``` + { + "components": [ + { + "component": "hello_world", + "description": "Hello world.", + "optional": "true", + "dirs": [ + "applications/sample/hello_world" + ], + "targets": [ + "//applications/sample/hello_world" + ] + }, + ... + ] + } + ``` + +3. 将组件配置到产品。 + + 产品的配置文件config.json位于位于vendor/company/product/下,产品配置文件需包含产品名称、OpenHarmony版本号、device厂商、开发板、内核类型、内核版本号,以及配置的子系统和组件。以将hello\_world组件加入产品配置文件my\_product.json中为例,加入hello\_wolrd对象: + + ``` + { + "product_name": "hello_world_test", + "ohos_version": "OpenHarmony 1.0", + "device_company": "hisilicon", + "board": "hispark_taurus", + "kernel_type": "liteos_a", + "kernel_version": "1.0.0", + "subsystems": [ + { + "subsystem": "applications", + "components": [ + { "component": "hello_world", "features":[] } + ] + }, + ... + ] + } + ``` + +4. 编译产品。 + + 1. 代码根目录输入hb set选择对应产品。 + + 2. 执行hb build。 + + +### 新增芯片解决方案 + +编译构建支持添加新的芯片解决方案厂商,具体步骤如下: + +1. 创建芯片解决方案目录。 + + 按照[芯片解决方案配置规则](#section1625463413327)创建目录,以芯片厂商realtek的“rtl8720“开发板为例, 在代码根目录执行: + + ``` + mkdir -p device/realtek/rtl8720 + ``` + +2. 创建内核适配目录,并编写开发板编译配置config.gni文件。 + + 以realtek的“rtl8720“开发板的liteos\_m适配为例,device/realtek/rtl8720/liteos\_a/config.gni的内容如下: + + ``` + # Kernel type, e.g. "linux", "liteos_a", "liteos_m". + kernel_type = "liteos_a" + + # Kernel version. + kernel_version = "3.0.0" + + # Board CPU type, e.g. "cortex-a7", "riscv32". + board_cpu = "real-m300" + + # Board arch, e.g. "armv7-a", "rv32imac". + board_arch = "" + + # Toolchain name used for system compiling. + # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. + # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. + board_toolchain = "gcc-arm-none-eabi" + + # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. + board_toolchain_path = + rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", + root_build_dir) + + # Compiler prefix. + board_toolchain_prefix = "gcc-arm-none-eabi-" + + # Compiler type, "gcc" or "clang". + board_toolchain_type = "gcc" + + # Board related common compile flags. + board_cflags = [] + board_cxx_flags = [] + board_ld_flags = [] + ``` + +3. 编写编译脚本。 + + 在开发板目录下创建BUILD.gn,target名称应与开发板名称一致。以realtek的rtl8720开发板为例,device/realtek/rtl8720/BUILD.gn内容可以是: + + ``` + group("rtl8720") { # target类型也可以shared_library, static_library, executable + # 具体内容 + ...... + } + ``` + +4. 编译芯片解决方案。 + + 在开发板目录下执行hb build,即可启动芯片解决方案的编译。 + + +### 新增产品解决方案 + +编译构建支持芯片解决方案和组件的灵活拼装,形成定制化的产品解决方案。具体步骤如下: + +1. 创建产品目录 + + 按照[产品解决方案配置规则](#section1625463413327)创建产品目录,以基于“rtl8720“开发板的wifiiot模组为例,在代码根目录执行: + + ``` + mkdir -p vendor/my_company/wifiiot + ``` + +2. 拼装产品 + + 在新建的产品目录下新建config.json文件,以步骤1中的wifiiot为例,vendor/my\_company/wifiiot/config.json可以是: + + ``` + { + "product_name": "wifiiot", # 产品名称 + "ohos_version": "OpenHarmony 1.0", # 使用的OS版本 + "device_company": "realtek", # 芯片解决方案厂商名称 + "board": "rtl8720", # 开发板名称 + "kernel_type": "liteos_m", # 选择的内核类型 + "kernel_version": "3.0.0", # 选择的内核版本 + "subsystems": [ + { + "subsystem": "kernel", # 选择的子系统 + "components": [ + { "component": "liteos_m", "features":[] } # 选择的组件和组件特性 + ] + }, + ... + { + 更多子系统和组件 + } + ] + } + ``` + + 注意:编译构建系统编译前会对device\_company,board,kernel\_type,kernel\_version、subsystem、component字段进行有效性检查,其中device\_company,board,kernel\_type,kernel\_version应与已知的芯片解决方案匹配,subsystem、component应与build/lite/components下的组件描述匹配。 + +3. 适配OS接口 + + 在产品目录下创建hals目录,并将产品解决方案对OS适配的源码和编译脚本放入该目录下。 + +4. 配置系统服务 + + 在产品目录下创建init\_configs目录,并在init\_configs目录下创建init.cfg文件,按需配置要启动的系统服务。 + +5. 配置init进程(仅linux内核需要) + + 在init\_configs目录下创建etc目录,然后在etc下创建init.d文件夹和fstab文件。最后按产品需求在init.d文件下创建并编辑rcS文件和Sxxx文件。 + +6. 配置文件系统镜像(可选,仅支持文件系统的开发板需要) + + 在产品目录下创建fs.yml文件。fs.yml需按产品实际情况配置,一个典型的fs.yml文件如下: + + ``` + - + fs_dir_name: rootfs # 镜像的名称 + fs_dirs: + - + # 将编译生成的out/my_board/my_product/bin目录下的文件拷贝到rootfs/bin中,并忽略测试bin + source_dir: bin + target_dir: bin + ignore_files: + - Test.bin + - TestSuite.bin + - + # 将编译生成的out/my_board/my_product/libs目录下的文件拷贝到rootfs/lib中,忽略所有.a文件,并设置文件和文件夹的权限为644和755 + source_dir: libs + target_dir: lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: usr/lib + target_dir: usr/lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: config + target_dir: etc + - + source_dir: system + target_dir: system + - + source_dir: sbin + target_dir: sbin + - + source_dir: usr/bin + target_dir: usr/bin + - + source_dir: usr/sbin + target_dir: usr/sbin + - + # 创建一个proc空目录 + target_dir: proc + - + target_dir: mnt + - + target_dir: opt + - + target_dir: tmp + - + target_dir: var + - + target_dir: sys + - + source_dir: etc + target_dir: etc + - + source_dir: vendor + target_dir: vendor + - + target_dir: storage + + fs_filemode: + - + file_dir: lib/ld-uClibc-0.9.33.2.so + file_mode: 555 + - + file_dir: lib/ld-2.24.so + file_mode: 555 + - + file_dir: etc/init.cfg + file_mode: 400 + fs_symlink: + - + # 在rootfs/lib下创建软连接ld-musl-arm.so.1 -> libc.so + source: libc.so + link_name: ${fs_dir}/lib/ld-musl-arm.so.1 + - + source: mksh + link_name: ${fs_dir}/bin/sh + - + source: mksh + link_name: ${fs_dir}/bin/shell + fs_make_cmd: + # 使用脚本将rootfs制作为ext4格式的image + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + - + fs_dir_name: userfs + fs_dirs: + - + source_dir: storage/etc + target_dir: etc + - + source_dir: data + target_dir: data + fs_make_cmd: + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + + ``` + +7. 配置产品Patch(可选,视产品涉及组件是否需要打补丁而定) + + 在产品目录下创建patch.yml文件。patch.yml需按产品实际情况配置,一个典型的patch.yml文件如下: + + ``` + # 需要打patch的路径 + foundation/communication/dsoftbus: + # 该路径下需要打的patch存放路径 + - foundation/communication/dsoftbus/1.patch + - foundation/communication/dsoftbus/2.patch + third_party/wpa_supplicant: + - third_party/wpa_supplicant/1.patch + - third_party/wpa_supplicant/2.patch + - third_party/wpa_supplicant/3.patch + ... + ``` + + 配置完成后,编译时增加--patch参数,即可在产品编译前将配置的Patch文件打到对应目录中,再进行编译: + + ``` + hb build -f --patch + ``` + +8. 编写编译脚本 + + 在产品目录下创建BUILD.gn文件,按产品实际情况编写脚本。以步骤1中的wifiiot为例,BUILD.gn示例如下: + + ``` + group("wifiiot") { # target名称与产品名一致 + deps = [] + # 拷贝init配置 + deps += [ "init_configs" ] + # 将hals加入编译 + deps += [ "hals" ] + # 其他 + ...... + } + ``` + +9. 编译产品。 + + 在代码根目录执行hb set按提示选择新增的产品,然后执行hb build即可启动编译。 + + +## 常见问题 + +### ninja版本问题导致编译失败 + +- **现象描述:** + + 编译失败,提示“usr/sbin/ninja: invalid option -- w”。 + +- **可能原因:** + + 编译环境中ninja版本太低,不支持--w选项。 + +- **解决办法:** + + 卸载环境中ninja和gn,按照HarmonyOS官网[获取工具](../get-code/gettools-ide.md)。 + + +### ncurses库缺失导致编译失败 + +- **现象描述:** + + 编译失败,提示“/usr/bin/ld: cannot find -lncurses”。 + +- **可能原因:** + + 编译环境ncurses库缺失。 + +- **解决办法:** + + ``` + sudo apt-get install lib32ncurses5-dev + ``` + + +### 未安装mcopy导致编译失败 + +- **现象描述:** + + ​编译失败,提示“line 77: mcopy: command not found”。 + +- **可能原因:** + + 编译环境未安装mcopy。 + +- **解决办法:** + + ``` + ​sudo apt-get install dosfstools mtools + ``` + + +### 权限问题导致编译失败 + +- **现象描述:** + + 编译失败,提示“riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory”。 + +- ​**可能原因:** + + 当前用户对riscv编译器路径下的文件访问权限不够。 + +- ​**解决办法:** + + 查询gcc\_riscv32所在目录。 + + ``` + which riscv32-unknown-elf-gcc + ``` + + 使用chmod命令修改目录权限为755。 + + +### 未安装Crypto导致编译失败 + +- **现象描述:** + + 编译失败,提示“No module named 'Crypto'”。 + +- **可能原因:** + + python3未安装Crypto。 + +- **解决办法:** + 1. 查询Python版本号。 + + ``` + python3 --version + ``` + + 2. 需使用python3.7以上版本,然后安装pycryptodome。 + + ``` + sudo pip3 install pycryptodome + ``` + + + +### 编译环境为shell导致编译失败 + +- **现象描述:** + + 编译失败:“xx.sh \[: xx unexpected operator”。 + +- **可能原因:** + + 编译环境shell不是bash。 + +- **解决办法:** + + ``` + sudo rm -rf /bin/sh + sudo ln -s /bin/bash /bin/sh + ``` + + diff --git a/zh-cn/device-dev/subsystems/subsys-build-mini.md b/zh-cn/device-dev/subsystems/subsys-build-mini.md new file mode 100644 index 0000000000000000000000000000000000000000..df6e2e0c54c21c72fbecedb3c1c6dbf7132c87ed --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-build-mini.md @@ -0,0 +1,5 @@ +# 轻量和小型系统编译构建指导 + +- **[编译构建子系统—轻量和小型系统](subsys-build-mini-lite.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-build-standard-large.md b/zh-cn/device-dev/subsystems/subsys-build-standard-large.md new file mode 100644 index 0000000000000000000000000000000000000000..9259a8073d9ae1a35c3fc17d4757bee73d72dab9 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-build-standard-large.md @@ -0,0 +1,235 @@ +# 标准系统编译构建指导 + +- [概述](#section17466112012244) + - [基本概念](#section445513507246) + - [运作机制](#section12541217142510) + - [约束与限制](#section886933762513) + +- [编译构建使用指导](#section16901215262) + - [目录结构](#section109065332264) + - [编译命令](#section123265539266) + - [开发步骤](#section591084422719) + + +## 概述 + +编译构建子系统提供了一个基于gn和ninja的编译构建框架。主要提供以下功能: + +- 构建不同芯片平台的产品。如:Hi3516DV300平台。 + +- 根据产品配置可以按照组件组装打包产品需要的能力。 + +### 基本概念 + +在了解编译构建子系统的能力前,应了解如下基本概念: + +- 平台 + + 开发板和内核的组合,不同平台支持的子系统和组件不同。 + +- 子系统 + + OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 \> 子系统 \> 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。子系统是一个逻辑概念,它具体由对应的组件构成。 + +- 组件 + + 对子系统的进一步拆分,可复用的软件单元,它包含源码、配置文件、资源文件和编译脚本;能独立构建,以二进制方式集成,具备独立验证能力的二进制单元。 + +- gn + + Generate ninja的缩写,用于产生ninja文件。 + +- ninja + + ninja是一个专注于速度的小型构建系统。 + + +### 运作机制 + +OpenHarmony侧的编译构建流程主要包括编译命令行解析,调用gn,执行ninja: + +- 命令行解析:解析待编译的产品名称,加载相关配置。 +- 调用gn: 根据命令行解析的产品名称和编译类型,配置编译工具链和全局的编译选项。 +- 执行ninja:启动编译并生成对应的产品版本。 + +### 约束与限制 + +- 需按照[源码获取](../get-code/sourcecode-acquire.md)指导下载全量源码(采用方式三获取)。 +- 编译环境需要Ubuntu18.04及以上版本。 +- 安装编译所需的程序包。 + + 安装命令: + + ``` + sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 + ``` + + +## 编译构建使用指导 + +### 目录结构 + +``` +/build # 编译构建主目录 +├── config # 编译相关的配置项 +├── core +│ └── gn # 编译入口BUILD.gn配置 +├── loader # 各个组件配置加载、模板生成 +├── ohos # OpenHarmony编译打包流程配置 +│ ├── kits # kits编译打包模板和处理流程 +│ ├── ndk # ndk模板和处理流程 +│ ├── notice # notice模板和处理流程 +│ ├── packages # 版本打包模板和处理流程 +│ ├── sa_profile # sa模板和处理流程 +│ ├── sdk # sdk模板和处理流程,包括sdk中包含的模块配置 +│ └── testfwk # 测试相关的处理 +├── scripts # 编译相关的python脚本 +├── templates # c/c++编译模板定义 +└── toolchain # 编译工具链配置 +``` + +### 编译命令 + +- 代码根目录下执行全量版本的编译命令: + + ``` + ./build.sh --product-name {product_name} + ``` + + \{product\_name\}为当前版本支持的平台。比如:Hi3516DV300等。 + + 编译完成后,结果镜像保存在 out/ohos-arm-release/packages/phone/images/ 目录下。 + +- 编译命令支持选项: + + ``` + --product-name # 必须 编译的产品名称,如:Hi3516DV300 + --build-target # 可选 指定编译目标,可以指定多个 + --gn-args # 可选 gn参数,支持指定多个 + --ccache # 可选 编译使用ccache,需要本地安装ccache + ``` + + +### 开发步骤 + +1. 添加组件。 + + 本节以添加一个自定义的组件为例,描述如何编译组件,编译库、编译可执行文件等。 + + 示例组件partA由feature1、feature2和feature3组成,feature1的编译目标为一个动态库,feature2的目标为一个可执行程序,feature3的目标为一个etc配置文件。 + + 示例组件partA的配置需要添加到一个子系统中,本次示例将添加到subsystem\_examples子系统中(subsystem\_examples子系统定义在test/examples/目录)。 + + 示例组件partA的完整目录结构如下: + + ``` + test/examples/partA + ├── feature1 + │ ├── BUILD.gn + │ ├── include + │ │ └── helloworld1.h + │ └── src + │ └── helloworld1.cpp + ├── feature2 + │ ├── BUILD.gn + │ ├── include + │ │ └── helloworld2.h + │ └── src + │ └── helloworld2.cpp + └── feature3 + ├── BUILD.gn + └── src + └── config.conf + ``` + + 示例1:编写动态库gn脚本test/examples/partA/feature1/BUILD.gn,示例如下: + + ``` + config("helloworld_lib_config") { + include_dirs = [ "include" ] + } + + ohos_shared_library("helloworld_lib") { + sources = [ + "include/helloworld1.h", + "src/helloworld1.cpp", + ] + public_configs = [ ":helloworld_lib_config" ] + part_name = "partA" + } + ``` + + 示例2:编写可执行文件gn脚本test/examples/partA/feature2/BUILD.gn,示例如下: + + ``` + ohos_executable("helloworld_bin") { + sources = [ + "src/helloworld2.cpp" + ] + include_dirs = [ "include" ] + deps = [ # 依赖组件内模块 + "../feature1:helloworld_lib" + ] + external_deps = [ "partB:module1" ] # (可选)如果有跨组件的依赖,格式为“组件名:模块名” + install_enable = true # 可执行程序缺省不安装,需要安装时需要指定 + part_name = "partA" + } + ``` + + 示例3:编写etc模块gn脚本test/examples/partA/feature3/BUILD.gn,示例如下: + + ``` + ohos_prebuilt_etc("feature3_etc") { + source = "src/config.conf" + relative_install_dir = "init" #可选,模块安装相对路径,相对于默认安装路径;默认在/system/etc目录 + part_name = "partA" + } + ``` + + 示例4:在子系统的ohos.build中添加组件配置:test/examples/ohos.build。每个子系统有一个ohos.build配置文件,在子系统的根目录下。示例如下: + + ``` + "partA": { + "module_list": [ + "//test/examples/partA/feature1:helloworld_lib", + "//test/examples/partA/feature2:helloworld_bin", + "//test/examples/partA/feature3:feature3_etc", + ], + "inner_kits": [ + + ], + "system_kits": [ + + ], + "test_list": [ + + ] + } + ``` + + 一个组件包含module\_list、inner\_kits、system\_kits、test\_list四个部分的声明,其中: + + - module\_list:组件所包含的模块列表; + - inner\_kits:组件提供给其它组件调用的接口,其他组件的模块可以在external\_deps中添加依赖的模块; + - system\_kits:组件提供给开发者开发应用的接口; + - test\_list:组件中对应模块的测试用例; + +2. 将组件添加到产品配置中。 + + 在产品的配置中添加组件,产品对应的配置文件:productdefine/common/products/\{product-name\}.json。 + + 在产品配置文件中添加 "subsystem\_examples:partA",表示该产品中会编译并打包partA到版本中。 + +3. 编译。 + + 以编译Hi3516DV300为例,编译命令如下: + + ``` + ./build.sh --product-name Hi3516DV300 --ccache + ``` + +4. 编译输出。 + + 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 + + diff --git a/zh-cn/device-dev/subsystems/subsys-build-standard.md b/zh-cn/device-dev/subsystems/subsys-build-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..d5d5ce6278bf65d44db5da6b8b7734e22463b486 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-build-standard.md @@ -0,0 +1,5 @@ +# 标准系统编译构建指导 + +- **[编译构建子系统—标准系统](subsys-build-standard-large.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-build.md b/zh-cn/device-dev/subsystems/subsys-build.md new file mode 100644 index 0000000000000000000000000000000000000000..487b7bf7b22db66cf401cda724f9236f343e0a8a --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-build.md @@ -0,0 +1,7 @@ +# 编译构建 + +- **[轻量和小型系统编译构建指导](subsys-build-mini-lite.md)** + +- **[标准系统编译构建指导](subsys-build-standard-large.md)** + + diff --git "a/zh-cn/device-dev/subsystems/HiLog_Lite\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-dfx-hilog-lite.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/HiLog_Lite\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-dfx-hilog-lite.md diff --git "a/zh-cn/device-dev/subsystems/HiLog\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-dfx-hilog-rich.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/HiLog\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-dfx-hilog-rich.md diff --git "a/zh-cn/device-dev/subsystems/HiSysEvent\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-dfx-hisysevent.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/HiSysEvent\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-dfx-hisysevent.md diff --git a/zh-cn/device-dev/subsystems/subsys-dfx-hisyseventread.md b/zh-cn/device-dev/subsystems/subsys-dfx-hisyseventread.md new file mode 100644 index 0000000000000000000000000000000000000000..333dd112b45fe83e91673798d6fd125db71747e3 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-dfx-hisyseventread.md @@ -0,0 +1,103 @@ +# HiSysEvent订阅指导 + +- [概述](#section315316685112) +- [接口说明](#section0342191810519) +- [开发实例](#section123181432175110) + +## 概述 + +HiSysEvent提供了跨进程订阅机制,用户可以通过注册订阅接口。 + +## 接口说明 + +**表 1** HiSysEvent订阅接口 + + + + + + + + + + + + + +

接口名

+

描述

+

int ISysEventService::AddListener(in SysEventRule[] rules, in ISysEventCallback callback)

+

接口功能:订阅HiSysEvent事件。

+

输入参数:

+
  • rules:事件订阅规则
  • callback:订阅回调对象
+

返回值:

+
  • 0:订阅成功,重复订阅
  • 1:订阅成功,初次订阅
  • 其他返回值:订阅失败
+

void ISysEventCallback::Handle(in String domain, in String eventName, in int eventType, in String eventDetail)

+

接口功能:订阅事件的回调接口。

+

输入参数:

+
  • domain:事件所属领域
  • eventName:事件的名称
  • eventType:事件类型
  • eventDetail:包含事件相关信息的字符串,以json的形式体现
+

返回值:无。

+
+ +**表 2** SysEventRule订阅规则对象 + + + + + + + + + + + + + + + + +

属性名称

+

描述

+

uint32_t ruleType

+

规则类型(匹配范围包括domain以及eventName):

+
  • 1:全字符匹配
  • 2:前缀匹配
  • 3:正则表达式匹配
  • 其他值:无效的匹配方式
+

std::string domain;

+
  • domain:事件所属领域,如果传入的是空字符串,则默认事件领域字段匹配成功
+

std::string eventName

+
  • eventName:事件的名称,如果传入的是空字符串,则默认事件名称字段匹配成功
+
+ +## 开发实例 + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventRule.aidl、ISysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象: + + ISysEventCallback::Handle\(in String domain, in String eventName, in int eventType, in String eventDetail\) + + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventRule.aidl、ISysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象: + + ISysEventCallback::Handle\(in String domain, in String eventName, in int eventType, in String eventDetail\) + +2. 编译设置: + +在编译子系统里面,需要依赖libbinder模块 + +aosp\_deps = \[ "shared\_library:libbinder", \] + +- **[bytrace使用指导](subsys-toolchain-bytrace-guide.md)** + +- **[hdc\_std 使用指导](subsys-toolchain-hdc-guide.md)** + + diff --git "a/zh-cn/device-dev/subsystems/DFX\346\246\202\350\277\260.md" b/zh-cn/device-dev/subsystems/subsys-dfx-overview.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/DFX\346\246\202\350\277\260.md" rename to zh-cn/device-dev/subsystems/subsys-dfx-overview.md diff --git a/zh-cn/device-dev/subsystems/subsys-dfx.md b/zh-cn/device-dev/subsystems/subsys-dfx.md new file mode 100644 index 0000000000000000000000000000000000000000..e4538aa73f4121b6ffcae48694a247fe2b84ef31 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-dfx.md @@ -0,0 +1,11 @@ +# DFX + +- **[DFX概述](subsys-dfx-overview.md)** + +- **[HiLog开发指导](subsys-dfx-hilog-rich.md)** + +- **[HiLog\_Lite开发指导](subsys-dfx-hilog-lite.md)** + +- **[HiSysEvent开发指导](subsys-dfx-hisysevent.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-graphics-animation-guide.md b/zh-cn/device-dev/subsystems/subsys-graphics-animation-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..8332aa22bd87afd1e6d8e6dff632b189cc0c19ea --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-graphics-animation-guide.md @@ -0,0 +1,190 @@ +# 动画开发指导 + +- [使用场景](#section726685714018) +- [接口说明](#section85794718418) +- [开发步骤](#section14101161317435) + +## 使用场景 + +UI动画通过task处理机制每个tick调用一下用户设置的callback函数来实现,具体实现为AnimatorManager、Animator、AnimatorCallback三个类实现。 + +- AnimatorManager:AnimatorManager为单例,在Init函数执行时将自己注册到系统task回调函数中,系统task机制保证每个tick会调用一下AnimatorManager的callback函数,同时AnimatorManager用来管理Animator实例。 +- Animator:Animator中可以设置动画相关的属性,包括动画的起止时间,动画开始和停止,动画状态的设置和获取等。 +- AnimatorCallback:具体每一个tick动画所要做的内容在AnimatorCallback类中实现,开发者需要自己实现Callback方法,动画执行时在Callback实现相应功能。 + +## 接口说明 + +**表 1** 动画接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

子模块

+

方法

+

功能

+

Animator

+

void Start ()

+

动画开始

+

Animator

+

void Stop ()

+

动画停止

+

Animator

+

void Pause ()

+

动画暂停

+

Animator

+

void Resume ()

+

动画恢复

+

Animator

+

uint8_t GetState () const

+

获取动画当前状态

+

Animator

+

void SetState (uint8_t state)

+

设置动画当前状态

+

Animator

+

uint32_t GetTime () const

+

获取动画总持续时间

+

Animator

+

void SetTime (uint32_t time)

+

设置动画总持续时间

+

Animator

+

uint32_t GetRunTime () const

+

获取动画当前已经持续的时间

+

Animator

+

void SetRunTime (uint32_t runTime)

+

设置动画当前已经持续的时间

+

Animator

+

bool IsRepeat () const

+

获取动画是否循环播放

+

AnimatorCallback

+

virtual void Callback (UIView *view)=0

+

由用户实现,动画回调函数

+

AnimatorCallback

+

virtual void OnStop(UIView& view) {}

+

由用户实现,动画停止后的回调函数

+

AnimatorManager

+

static AnimatorManager* GetInstance()

+

获取AnimatorManager实例

+

AnimatorManager

+

void Add (Animator *animator)

+

添加动画

+

AnimatorManager

+

void Remove(const Animator* animator);

+

删除动画

+
+ +## 开发步骤 + +1. 实现AnimatorCallback的回调函数。 + + ``` + class AnimatorCallbackDemo : public OHOS::AnimatorCallback { + public: + AnimatorCallbackDemo(int16_t startPos, int16_t endPos, uint16_t time) + : start_(startPos), end_(endPos), time_(time), curTime_(0) {} + + virtual void Callback(OHOS::UIView* view) + { + curTime_++; + int16_t pos = EasingEquation::CubicEaseIn(start_, end_, curTime_, time_); + view->Invalidate(); + view->SetPosition(pos, view->GetY()); + view->Invalidate(); + } + protected: + int16_t start_; + int16_t end_; + uint16_t time_; + uint16_t curTime_; + }; + ``` + +2. 将AnimatorCallback添加到Animator中。 + + ``` + UIImageView* image = new UIImageView(); + image->SetSrc("..\\config\\images\\A021_001.bin"); + image->SetPosition(0, 50); + AnimatorCallbackDemo* callback = new AnimatorCallbackDemo(0, 338, 60); + Animator* animator = new Animator(callback, image, 0, true); + ``` + +3. 将Animator添加到AnimatorManager中。 + + ``` + AnimatorManager::GetInstance()->Add(animator); + ``` + +4. 点击下图下方的按钮,检查对应的动画运行效果。 + + **图 1** 动画实现效果图 + ![](figure/动画实现效果图.gif "动画实现效果图") + + diff --git a/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide1.md b/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide1.md new file mode 100644 index 0000000000000000000000000000000000000000..52da564931e3f8ff58c2e0379c98dbcbc993aa58 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide1.md @@ -0,0 +1,244 @@ +# 容器类组件开发指导 + +- [UIViewGroup](#section145471898812) +- [使用场景](#section0916112362216) +- [接口说明](#section12641756192212) +- [开发步骤](#section5412161692311) +- [UIScrollView](#section174961523161315) +- [使用场景](#section8937101902413) +- [接口说明](#section14789133142420) +- [开发步骤](#section1769754422417) + +容器类组件,指能包含其它UI组件的组件,容器类组件继承于UIViewGroup(带Add方法),基于实际组件的使用场景,将需要增加其他子组件的组件,放置到容器类继承结构下。如UIAnalogClock内,通常会Add需要的计步信息,时分秒图标等。 + +**图 1** 普通容器类组件结构 +![](figure/普通容器类组件结构.png "普通容器类组件结构") + +RootView、UIAbstractScroll、UIPicker组件从UIViewGroup继承,UIList、UIScrollView、UISwipeView组件从UIAbstractScroll继承。 + +## UIViewGroup + +## 使用场景 + +UIViewGroup是容器类组件基类,实现增加、删除、插入等操作,通过增加方法可以添加子组件。普通容器类组件子组件需要设置位置信息,位置信息为相对父组件的相对坐标。组件树结构如下图: + +**图 2** 组件树结构示意图 +![](figure/组件树结构示意图.png "组件树结构示意图") + +往根节点rootView里添加ViewGroup1容器组件和View1组件,往ViewGroup1容器组件里再添加View2组件和ViewGroup2容器组件,在View1之后添加View3组件。 + +- 关于渲染:容器类组件在渲染时会遍历所有子组件OnDraw方法,以达到刷新所有组件的目的。 +- 关于坐标:子组件位置信息为相对父组件的相对坐标,系统在渲染时计算绝对坐标并显示。 +- 关于树结构遍历:UIViewGroup提供如下方法实现遍历、查找、管理组件树。 + +## 接口说明 + +**表 1** ViewGroup接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

方法

+

功能

+

virtual void Add(UIView* view)

+

添加子组件

+

virtual void Insert(UIView* prevView, UIView* insertView)

+

插入子组件

+

virtual void Remove(UIView* view)

+

删除子组件

+

virtual void RemoveAll()

+

删除所有子组件

+

virtual void GetTargetView(const Point& point, UIView** last)

+

获取目标视图

+

virtual void MoveChildByOffset(int16_t x, int16_t y)

+

偏移子组件

+

UIView* GetChildrenHead() const

+

获取视图头节点

+

UIView* GetChildrenTail() const

+

获取视图最后那个节点

+

virtual UIView* GetChildById(const char* id) const override

+

通过id获取子视图

+
+ +## 开发步骤 + +1. 构造button实例并设置坐标信息。 + + ``` + UILabelButton* btn1 = new UILabelButton(); + btn1->SetPosition(0, 0, 100, 50); + btn1->SetText("btn1"); + + UILabelButton* btn2 = new UILabelButton(); + btn2->SetPosition(50, 50, 100, 50); + btn2->SetText("btn2"); + + UILabelButton* btn3 = new UILabelButton(); + btn3->SetPosition(100, 100, 100, 50); + btn3->SetText("btn3"); + ``` + +2. 构造UIViewGroup实例,并设置坐标信息。 + + ``` + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, 300, 300); + ``` + +3. 使用Add方法添加Button实例到UIViewGroup。 + + ``` + group->Add(btn1); + group->Add(btn2); + group->Add(btn3); + ``` + +4. 检查ViewGroup效果如下图所示。 + + **图 3** ViewGroup添加view实例效果图 + ![](figure/ViewGroup添加view实例效果图.png "ViewGroup添加view实例效果图") + + +## UIScrollView + +## 使用场景 + +UIScrollView提供可滑动的容器类组件,子组件可在触摸事件驱动下上下、左右滑动,并提供水平和垂直方向的游标显示功能。 + +## 接口说明 + +**表 2** ScrollView接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

方法

+

功能

+

void ScrollBy(int16_t xDistance, int16_t yDistance)

+

移动视图

+

void SetScrollbarWidth(uint8_t width)

+

设置滑动条宽度

+

void SetHorizontalScrollState(bool state)

+

设置水平滑动状态

+

bool GetHorizontalScrollState() const

+

获取水平是否可滑动状态

+

void SetVerticalScrollState(bool state)

+

设置垂直滑动状态

+

bool GetVerticalScrollState() const

+

获取垂直是否可滑动状态

+

void SetXScrollBarVisible(bool state)

+

设置X轴滑动条是否可见

+

void SetYScrollBarVisible(bool state)

+

设置Y轴滑动条是否可见

+

void RegisterScrollListener(OnScrollListener* scrollListener)

+

注册滑动事件回调类

+

void RefreshScrollBar()

+

刷新滑动条

+

virtual void OnScrollStart() {}

+

滚动开始回调函数

+

virtual void OnScrollEnd() {}

+

滚动结束回调函数

+

uint8_t GetScrollState() const

+

获取滚动状态

+

void SetScrollState(uint8_t state)

+

设置滚动状态

+
+ +## 开发步骤 + +添加两个button子组件,并显示水平、垂直方向游标。 + +``` +scrollView* scroll = new UIScrollView(); +scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); +scroll->SetPosition(0,0, 200, 200); +scroll->SetXScrollBarVisible(true); +scroll->SetYScrollBarVisible(true); +UILabelButton* button1 = new UILabelButton(); +button1->SetText("button1"); +button1->SetPosition(0, 0, 300, 300); +UILabelButton* button2 = new UILabelButton(); +button2->SetText("button2"); +button2->SetPosition(0, 300, 300, 300); +scroll->Add(button1); +scroll->Add(button2); +``` + +**图 4** 水平、垂直方向可滑动效果图 +![](figure/水平-垂直方向可滑动效果图.gif "水平-垂直方向可滑动效果图") + diff --git a/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide2.md b/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide2.md new file mode 100644 index 0000000000000000000000000000000000000000..f03df38642b7f5892957eedc54a9648b0168e3be --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide2.md @@ -0,0 +1,216 @@ +# 布局容器类组件开发指导 + +- [UISwipeView](#section13631719181717) +- [使用场景](#section11299120102617) +- [接口说明](#section767434119261) +- [开发步骤(水平滑动,不可循环)](#section111911175287) +- [开发步骤(水平滑动,可循环)](#section1976914915282) +- [GridLayout](#section46819199173) +- [使用场景](#section831618247294) +- [接口说明](#section597214622912) +- [开发步骤](#section1418253410306) + +布局类容器组件由视图基础类组成,通过直接设置视图位置,可以达到嵌套和重叠布局的目的;通过设置布局类型和边距达到规格化布局子组件的目的;通过调用相关接口可实现根据父组件及兄弟节点布局视图的目的。 + +## UISwipeView + +## 使用场景 + +UISwipeView继承UIViewGroup,除提供容器类组件Add、Remove、Insert等方法外还提供按页面滑动功能,滑动结束后当前页面居中对齐显示。该组件分为水平方向和垂直方向,通过Add方法添加的子组件会根据Add的顺序和UISwipeView方向自动水平对齐或则垂直对齐。 + +## 接口说明 + +**表 1** SwipeView接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

方法

+

功能

+

void SetCurrentPage(uint16_t index);

+

设置当前页

+

uint16_t GetCurrentPage()

+

获取当前页

+

UIView* GetCurrentView() const

+

获取当前页组件

+

void SetOnSwipeListener(OnSwipeListener& onSwipeListener)

+

设置滑动回调类

+

void SetAnimatorTime(uint16_t time);

+

设置动画事件

+

void SetLoopState(bool loop)

+

设置是否循环

+

UIView* GetViewByIndex(uint16_t index);

+

通过index获取view

+
+ +## 开发步骤(水平滑动,不可循环) + +1. 创建一个水平滑动的UISwipeView。 + + ``` + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + ``` + +2. 向UISwipeView中添加子组件。 + + ``` + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button2->SetText("button2"); + swipe->Add(button2); + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button3->SetText("button3"); + swipe->Add(button3); + ``` + +3. 检查实现效果,水平滑动,不可循环。 + + **图 1** UISwipeView水平滑动效果图 + + + ![](figure/zh-cn_image_0000001053247975.gif) + + +## 开发步骤(水平滑动,可循环) + +1. 创建一个水平滑动的UISwipeView并添加子组件。 + + ``` + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button2->SetText("button2"); + swipe->Add(button2); + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); + button3->SetText("button3"); + swipe->Add(button3); + ``` + +2. 设置UISwipeView循环滑动。 + + ``` + swipe->SetLoopState(true); + ``` + +3. 检查实现效果,水平循环滑动。 + + **图 2** UISwipeView水平滑动循环效果图 + + + ![](figure/zh-cn_image_0000001053207924.gif) + + +## GridLayout + +## 使用场景 + +提供基础布局能力,可设置网格行数和列数,通过Add方法添加的子组件在调用LayoutChildren\(\)方法后自动进行排列布局。 + +## 接口说明 + +**表 2** GridLayout接口说明 + + + + + + + + + + + + + + + + +

方法

+

功能

+

void SetRows(const uint16_t& rows)

+

设置行数

+

void SetCols(const uint16_t& cols)

+

设置列数

+

void LayoutChildren(bool needInvalidate = false)

+

布局子组件

+
+ +## 开发步骤 + +1. 构造GridLayout并设置位置、大小信息。 + + ``` + GridLayout* layout_ = new GridLayout(); + layout_->SetPosition(0, g_y, HROIZONTAL_RESOLUTION, 200); + layout_->SetLayoutDirection(LAYOUT_HOR); + layout_->SetRows(2); + layout_->SetCols(2); + ``` + +2. 构造子组件button。 + + ``` + UILabelButton* bt1 = new UILabelButton(); + bt1->SetPosition(0,0,100,50); + bt1->SetText("bt1"); + UILabelButton* bt2 = new UILabelButton(); + bt2->SetPosition(0, 0, 100, 50); + bt2->SetText("bt2"); + UILabelButton* bt3 = new UILabelButton(); + bt3->SetPosition(0, 0, 100, 50); + bt3->SetText("bt3"); + UILabelButton* bt4 = new UILabelButton(); + bt4->SetPosition(0, 0, 100, 50); + bt4->SetText("bt4"); + ``` + +3. 添加子组件并调用LayoutChildren\(\)。 + + ``` + layout_->Add(bt1); + layout_->Add(bt2); + layout_->Add(bt3); + layout_->Add(bt4); + layout_->LayoutChildren(); + ``` + +4. 检查button组件布局效果如下图所示。 + + **图 3** 设置2\*2网格并添加4个button组件进行布局 + ![](figure/设置2-2网格并添加4个button组件进行布局.png "设置2-2网格并添加4个button组件进行布局") + + diff --git a/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide3.md b/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide3.md new file mode 100644 index 0000000000000000000000000000000000000000..d9b0d48c87587588b3bbd4b39c83e636001dcbd6 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-graphics-bundle-guide3.md @@ -0,0 +1,555 @@ +# 普通组件开发指导 + +- [UIButton](#section145353310214) +- [使用场景](#section1169616141577) +- [接口说明](#section341211538315) +- [开发步骤](#section22501726193214) +- [UIImageView](#section19523161611259) +- [使用场景](#section1274484210400) +- [接口说明](#section74981992411) +- [开发步骤(自适应)](#section144341333134114) +- [开发步骤(平铺模式)](#section97178160421) +- [UILabel](#section16588132012911) +- [使用场景](#section6870195634218) +- [接口说明](#section2012714510433) +- [开发步骤(默认模式)](#section83221538114410) +- [开发步骤(背景色和透明度)](#section933360204510) +- [开发步骤(字符间距)](#section19447826124518) +- [开发步骤(大小自适应)](#section101711842154617) +- [开发步骤(省略号模式)](#section1249519410471) +- [开发步骤(滚动模式)](#section15643122618478) + +普通组件均继承于基类UIView,不可以添加子组件,常用的普通组件有button、image、label等。 + +**图 1** 普通组件树结构 +![](figure/普通组件树结构.png "普通组件树结构") + +UIView为基础类,UIAbstractProgress、UIArcLabel(旋转字体)、UIButton(按键)、UICanvas(画布)、UILabel(字体)、UIImageView(图片)从UIView继承。UIBoxProgress、UICircleProgress从UIAbstractProgress继承,UILabelButton和UIRepeatButton从UIButton继承,UIImageAnimatorView和UITextureMapper从UIImageView继承。 + +## UIButton + +## 使用场景 + +UIButton组件,提供可点击功能,同时可设置不同状态下样式。 + +## 接口说明 + +**表 1** button接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

方法

+

功能

+

void SetImageSrc (const char *defaultImgSrc, const char *triggeredImgSrc)

+

设置button图片

+

void SetImagePosition (const int16_t x, const int16_t y)

+

设置button图片位置

+

int16_t GetImageX () const

+

获取图片X坐标

+

int16_t GetImageY () const

+

获取图片Y坐标

+

const ImageInfo* GetCurImageSrc() const

+

获取当前状态图片

+

Style& GetStyleForState (ButtonState state)

+

设置button当前状态的style

+

voidSetStyleForState (const Style &style, ButtonState state)

+

设置button指定状态的style

+

void Disable ()

+

去使能button

+

void Enable ()

+

使能button

+
+ +## 开发步骤 + +1. 实现点击事件。 + + ``` + class TestBtnOnClickListener : public OHOS::UIView::OnClickListener { + bool OnClick(UIView& view, const ClickEvent& event) override + { + int16_t width = view.GetWidth() + 10; + int16_t height = view.GetHeight() + 10; + view.Resize(width, height); + view.Invalidate(); + return true; + } + }; + ``` + +2. 创建一个UIButton。 + + ``` + UIButton* button = new UIButton(); + button->SetPosition(50, 50); + button->SetWidth(100); + button->SetHeight(50); + ``` + +3. 给UIButton注册点击事件回调。 + + ``` + button->SetOnClickListener(new TestBtnOnClickListener()); + ``` + +4. 检查Button点击效果如下图所示,Button逐渐变大。 + + **图 2** UIButton点击效果 + ![](figure/UIButton点击效果.gif "UIButton点击效果") + + +## UIImageView + +## 使用场景 + +图片组件,提供图片显示,透明度设置,图片旋转、缩放功能。支持的图片格式为RGB565、RGB888、RGBA8888、PNG、JPG。 + +## 接口说明 + +**表 2** image接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

方法

+

功能

+

void SetSrc (const char *src)

+

设置二进制图片路径

+

void SetSrc (const ImageInfo *src)

+

设置图片指针

+

void SetAutoEnable (bool enable)

+

设置组件大小跟随image大小变化

+

const void* GetSrcType () const

+

获取图片类型

+

bool GetAutoEnable () const

+

获取组件大小是否跟随image大小变化

+

void SetBlurLevel(BlurLevel level)

+

设置模糊等级

+

BlurLevel GetBlurLevel() const

+

获取模糊等级

+

void SetTransformAlgorithm(TransformAlgorithm algorithm)

+

设置旋转算法

+

TransformAlgorithm GetTransformAlgorithm() const

+

获取旋转算法

+
+ +## 开发步骤(自适应) + +1. 创建一个UIImageView。 + + ``` + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(0, 30); + ``` + +2. 设置二进制格式的图片。 + + ``` + imageView->SetSrc("..\\config\\images\\A021_001.bin"); + ``` + +3. 检查UIImageView控件大小与图片相同。 + + **图 3** 自适应模式图片效果图 + ![](figure/自适应模式图片效果图.png "自适应模式图片效果图") + + +## 开发步骤(平铺模式) + +1. 创建一个UIImageView。 + + ``` + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(0, 30); + ``` + +2. 设置图片。 + + ``` + imageView->SetSrc("..\\config\\images\\A021_001.bin"); + ``` + +3. 取消图片自适应,设置图片大小,平铺显示效果。 + + ``` + imageView->SetAutoEnable(false); + imageView->Resize(454, 150); + ``` + +4. 检查UIImageView控件显示为平铺效果。 + + **图 4** 平铺模式图片效果图 + ![](figure/平铺模式图片效果图.png "平铺模式图片效果图") + + +## UILabel + +## 使用场景 + +标签(label)是在一块区域上显示文本字符串的组件,可设置区域背景色、文字的显示样式和长文本的显示效果等。 + +## 接口说明 + +**表 3** label接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

方法

+

功能

+

void SetText(const char* text);

+

设置文字

+

const char* GetText() const;

+

获取text

+

void SetLineBreakMode(const uint8_t lineBreakMode);

+

设置label模式,例如截断,自动扩展等。

+

uint8_t GetLineBreakMode() const

+

获取label模式

+

void SetTextColor(ColorType color)

+

设置文本颜色

+

ColorType GetTextColor() const

+

获取文本颜色

+

void SetAlign(UITextLanguageAlignment horizontalAlign,

+

UITextLanguageAlignment verticalAlign = TEXT_ALIGNMENT_TOP);

+

设置文本对齐方式

+

UITextLanguageAlignment GetHorAlign() const

+

获取文本水平对齐方式

+

UITextLanguageAlignment GetVerAlign() const

+

获取文本竖直对齐方式

+

void SetDirect(UITextLanguageDirect direct)

+

设置文本显示方向

+

UITextLanguageDirect GetDirect() const

+

获取文本显示方向

+

void SetFontId(uint8_t fontId);

+

设置动态字体id

+

uint8_t GetFontId() const

+

获取动态字体id

+

void SetFont(const char *name, uint8_t size);

+

设置字的名字和大小

+

void SetAnimatorSpeed(uint16_t animSpeed);

+

设置字体旋转的速度

+

uint16_t GetTextWidth();

+

获取字体的宽

+

uint16_t GetTextHeight();

+

获取字体的高

+

void SetRollStartPos(int16_t pos)

+

设置旋转的位置

+

int16_t GetRollStartPos() const

+

获取旋转的位置

+

void SetTextRotation(LabelRotateDegree angle)

+

设置文本旋转角度枚举值

+

LabelRotateDegree GetTextRotation() const

+

获取文本旋转角度枚举值

+

uint16_t GetTextRotateDegree() const

+

获取文本旋转角度数值

+
+ +## 开发步骤(默认模式) + +1. 创建label,设置大小和位置信息。 + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. 设置字形信息。 + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. 设置文本数据。 + + ``` + label->SetText("label"); + ``` + +4. 检查label大小和显示效果正常,如下图所示。 + + ![](figure/zh-cn_image_0000001051782526.png) + + +## 开发步骤(背景色和透明度) + +1. 创建label,设置大小和位置信息。 + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. 设置字形信息。 + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. 设置背景颜色及透明度效果。 + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetStyle(STYLE_BACKGROUND_OPA, 127); + label->SetText("Label"); + ``` + +4. 检查label背景色为Gray,如下图所示。 + + ![](figure/zh-cn_image_0000001052582522.png) + + +## 开发步骤(字符间距) + +1. 创建label,设置大小和位置信息。 + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. 设置字形信息。 + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. 设置字体颜色和字间距效果。 + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetStyle(STYLE_LETTER_SPACE, 5); + label->SetText("Label"); + ``` + +4. 检查label字符间距为5,如下图所示。 + + ![](figure/zh-cn_image_0000001052942531.png) + + +## 开发步骤(大小自适应) + +当文本过长时,可根据文本信息自动调整label组件大小,也可以设置文本截断或者文本滚动效果。 + +1. 创建label,设置大小和位置信息。 + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. 设置字形信息。 + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. 设置字体颜色为Gray,组件大小自适应文本内容。 + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + label->SetText("123\n567890"); + ``` + +4. 检查label大小自适应文本内容,如下图所示。 + + ![](figure/zh-cn_image_0000001052782555.png) + + +## 开发步骤(省略号模式) + +省略号模式指文本内容显示不下时,在末尾显示省略号。 + +1. 创建label,设置大小和位置信息。 + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. 设置字形信息。 + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. 设置换行模式为DOT模式 + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + label->SetText("123567890"); + ``` + +4. 检查label DOT模式效果,如下图所示,末尾显示省略号。 + + ![](figure/zh-cn_image_0000001052662559.png) + + +## 开发步骤(滚动模式) + +文本滚动显示。 + +1. 创建label,设置大小和位置信息。 + + ``` + UILabel* label = new UILabel(); + label->SetPosition(x, y); + label->Resize(width, height); + ``` + +2. 设置字形信息。 + + ``` + label->SetFont("SourceHanSansSC-Regular.otf", 30); + ``` + +3. 设置换行模式为滚动模式 + + ``` + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + label->SetStyle(STYLE_BACKGROUND_OPA, 127); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetText("123567890"); + ``` + +4. 检查label滚动模式效果,如下图所示。 + + ![](figure/20200721-223604(eSpace).gif) + + diff --git "a/zh-cn/device-dev/subsystems/\345\233\276\345\275\242\345\233\276\345\203\217\346\246\202\350\277\260.md" b/zh-cn/device-dev/subsystems/subsys-graphics-overview.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\233\276\345\275\242\345\233\276\345\203\217\346\246\202\350\277\260.md" rename to zh-cn/device-dev/subsystems/subsys-graphics-overview.md diff --git a/zh-cn/device-dev/subsystems/subsys-graphics.md b/zh-cn/device-dev/subsystems/subsys-graphics.md new file mode 100644 index 0000000000000000000000000000000000000000..bb255fa159a9823a6ddbfc724ba7b9ba4c5ac9cd --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-graphics.md @@ -0,0 +1,13 @@ +# 图形图像 + +- **[图形图像概述](subsys-graphics-overview.md)** + +- **[容器类组件开发指导](subsys-graphics-bundle-guide1.md)** + +- **[布局容器类组件开发指导](subsys-graphics-bundle-guide2.md)** + +- **[普通组件开发指导](subsys-graphics-bundle-guide3.md)** + +- **[动画开发指导](subsys-graphics-animation-guide.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-multimedia-camera-overview.md b/zh-cn/device-dev/subsystems/subsys-multimedia-camera-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..75b2033e9c72cb5541ed32a6d7a8e098e748a526 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-multimedia-camera-overview.md @@ -0,0 +1,116 @@ +# 相机开发概述 + +- [基本概念](#section175012297491) +- [运作机制](#section193961322175011) + +## 基本概念 + +相机是OpenHarmony多媒体进程提供的服务之一,提供了相机的录像、预览、拍照功能,支持多用户并发取流。 + +在进行应用的开发前,开发者应了解以下基本概念: + +- 视频帧 + + 视频流指的是将一系列图片数据按照固定时间间隔排列形成的数据流,每一张图片数据成为一帧,这样的一帧称为视频帧。 + +- 帧速率\(FPS: Frames Per Second\) + + 视频播放每秒钟刷新图片的速度,或是视频每秒的帧数,帧速率越高,视频的观感越流畅。 + +- 分辨率 + + 每一帧的图片信息都是由像素点组成的,分辨率描述了一张图片中像素点的个数。例如1920\*1080\(1080P\),是指图片宽1920像素,高1080像素。 + + +## 运作机制 + +- 多媒体服务进程 + + 多媒体服务作为系统服务,在系统启动时由Init进程拉起,并初始化和分配媒体硬件资源(内存/显示硬件/图像传感器/编解码器等)。初始化过程解析配置文件,确定了多媒体各个服务的能力和资源上限,通常由OEM厂商通过配置文件进行配置。相机服务在多媒体进程初始化时有以下配置项: + + - 内存池:所有媒体服务依赖于内存池中的内存轮转运行 + - 图像传感器:包括了传感器类型、分辨率、ISP等 + - 图像处理器:分辨率、码率、图像翻转等 + - 图像编码器:编码格式、码率、分辨率等 + + +- 关键类的解释 + + 应用通过持有下面4个类,配置和使用Camera的功能,包括了Camera类和它的三个异步回调类,三类回调分别对应了不同类型的异步处理场景,详见[表1](#table486418149411)。 + + **表 1** 关键类的解释 + + + + + + + + + + + + + + + + + + + + + + + + +

对象

+

用途

+

举例

+

Camera

+

对相机进行静态配置(通过配置类),触发相机基本功能

+

拍照/录像/预览

+

CameraDeviceCallback

+

处理相机硬件状态变化

+

可用/不可用

+

CameraStateCallback

+

处理camera自身状态变化

+

创建/释放

+

FrameStateCallback

+

处理帧状态的变化

+

拍照开始和结束/帧率发生变化

+
+ +- 流的传递 + + Surface是多媒体传递音视频的基本数据结构,Camera一般作为Surface中数据的生产者,在不同的场景下有特定的消费者。 + + 相机的预览和录像输出均为视频流,拍照输出为图像帧,二者均通过Surface类进行传递。Surface类可以屏蔽进程内/跨进程的场景,进行多媒体信息流的传递。 + + 以录像为例,用户首先创建Recorder实例,并从Recorder中获取对应Surface,再将此Surface传递给Camera实例,此时Camera将作为生产者向Surface注入视频流,而Recorder作为消费者从Surface中取出视频流进行保存,用户的行为类似桥接,把二者通过Surface连接起来。 + + 类似的,用户也可以自行创建Surface传递给Camera实例,并实现消费者逻辑(例如通过网络传输视频流,或是将拍照的帧数据保存成图片文件)。 + + 图形图像模块也通过Surface从Camera获取流资源,具体步骤详见[图形图像开发指导](subsys-graphics-overview.md)。 + +- 相机运行流程 + 1. Camera创建流程 + + 本进程通过CameraManager创建Camera实例,并从服务端绑定camera设备,创建成功后异步通知developer。类之间的时序图如下: + + **图 1** Camera创建时序图 + + + ![](figure/zh-cn_image_0000001054101094.png) + + + 1. Camera录像/预览流程 + + 开发者首先通过CameraKit创建Camera,然后FrameConfig类对录像或者预览帧属性进行配置。录像/预览时序如下: + + **图 2** Camera录像/预览时序图 + + + ![](figure/zh-cn_image_0000001054421113.png) + + + diff --git a/zh-cn/device-dev/subsystems/subsys-multimedia-camera-photo-guide.md b/zh-cn/device-dev/subsystems/subsys-multimedia-camera-photo-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..0e1ebbfecfc56b1d4eecf483c07c4c646cb85e0b --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-multimedia-camera-photo-guide.md @@ -0,0 +1,396 @@ +# 拍照开发指导 + +- [使用场景](#section1963312376119) +- [接口说明](#section56549532016) +- [约束与限制](#section1165911177314) +- [开发步骤](#section138543918214) + +## 使用场景 + +使用Camera产生图片帧(拍照)。 + +## 接口说明 + +**表 1** API列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

类名

+

接口名

+

描述

+

CameraKit

+

int32_t GetCameraIds(std::list<string> cameraList)

+

获取cameraId列表

+

CameraKit

+

CameraAbility& GetCameraAbility(string cameraId)

+

获取指定camera的能力

+

CameraKit

+

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

+

注册camera设备状态回调

+

CameraKit

+

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

+

去注册camera设备状态回调

+

CameraKit

+

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

+

创建camera实例

+

Camera

+

string GetCameraId()

+

获取cameraID

+

Camera

+

CameraConfig& GetCameraConfig()

+

获取camera配置信息

+

Camera

+

FrameConfig& GetFrameConfig(int32_t type)

+

获取捕获帧类型

+

Camera

+

void Configure(CameraConfig& config)

+

配置camera

+

Camera

+

void Release()

+

释放camera

+

Camera

+

int TriggerLoopingCapture(FrameConfig& frameConfig)

+

开始循环帧捕获

+

Camera

+

void StopLoopingCapture()

+

停止循环帧捕获

+

Camera

+

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

+

抓图

+

CameraConfig

+

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

+

设置帧状态回调

+

CameraConfig

+

static CameraConfig* CreateCameraConfig()

+

创建camera配置信息实例

+

CameraAbility

+

std::list<Size> GetSupportedSizes(int format)

+

根据类型获取支持输出图像尺寸大小

+

CameraAbility

+

std::list<T> GetParameterRange(uint32_t key)

+

获取支持的参数范围

+

CameraDevice

+

CameraDeviceCallback()

+

camera设备回调类构造函数

+

CameraDevice

+

void OnCameraStatus​(std::string cameraId, int32_t status)

+

camera设备状态变化时的回调

+

CameraStateCallback

+

CameraStateCallback​()

+

camera状态回调类构造函数

+

CameraStateCallback

+

void OnConfigured​(Camera& camera)

+

camera配置成功回调

+

CameraStateCallback

+

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

+

camera配置失败回调

+

CameraStateCallback

+

void OnCreated​(Camera& camera)

+

camera创建成功回调

+

CameraStateCallback

+

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

+

camera创建失败回调

+

CameraStateCallback

+

void OnReleased​(Camera& camera)

+

camera释放回调

+

FrameStateCallback

+

FrameStateCallback​()

+

帧状态回调类构造函数

+

FrameStateCallback

+

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

+

拍照帧完成回调

+

FrameStateCallback

+

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

+

拍照帧异常回调

+

FrameConfig

+

int32_t GetFrameConfigType()

+

获取帧配置类型

+

FrameConfig

+

std::list<OHOS::Surface> GetSurfaces()

+

获取帧配置的surface

+

FrameConfig

+

void AddSurface(OHOS::AGP::UISurface& surface);

+

添加surface

+

FrameConfig

+

void RemoveSurface(OHOS::AGP::UISurface& surface);

+

删除surface

+
+ +## 约束与限制 + +无。 + +## 开发步骤 + +1. 实现设备状态回调的派生类,用户在设备状态发生变更(如新插入相机设备/相机掉线)时,自定义操作。 + + ``` + class SampleCameraDeviceCallback : public CameraDeviceCallback { + void OnCameraStatus(std::string cameraId, int32_t status) override + { + //do something when camera is available/unavailable + } + }; + ``` + +2. 实现帧事件回调的派生类,这里在拿到帧数据以后将其转存为文件。 + + ``` + static void SampleSaveCapture(const char *p, uint32_t size) + { + cout << "Start saving picture" << endl; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm *ltm = localtime(&tv.tv_sec); + if (ltm != nullptr) { + ostringstream ss("Capture_"); + ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; + + ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); + cout << "write " << size << " bytes" << endl; + pic.write(p, size); + cout << "Saving picture end" << endl; + } + } + + class TestFrameStateCallback : public FrameStateCallback { + void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override + { + cout << "Receive frame complete inform." << endl; + if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { + cout << "Capture frame received." << endl; + list surfaceList = fc.GetSurfaces(); + for (Surface *surface : surfaceList) { + SurfaceBuffer *buffer = surface->AcquireBuffer(); + if (buffer != nullptr) { + char *virtAddr = static_cast(buffer->GetVirAddr()); + if (virtAddr != nullptr) { + SampleSaveCapture(virtAddr, buffer->GetSize()); + } + surface->ReleaseBuffer(buffer); + } + delete surface; + } + delete &fc; + } + } + }; + ``` + +3. 实现相机状态回调的派生类,当相机状态发生变化(配置成功/失败,创建成功/失败\)时,自定义操作。 + + ``` + class SampleCameraStateMng : public CameraStateCallback { + public: + SampleCameraStateMng() = delete; + SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} + ~SampleCameraStateMng() + { + if (recordFd_ != -1) { + close(recordFd_); + } + } + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} + void OnReleased(Camera &c) override {} + }; + ``` + +4. 创建CameraKit,用于创建和获取camera信息。 + + ``` + CameraKit *camKit = CameraKit::GetInstance(); + list camList = camKit->GetCameraIds(); + string camId; + for (auto &cam : camList) { + cout << "camera name:" << cam << endl; + const CameraAbility *ability = camKit->GetCameraAbility(cam); + /* find camera which fits user's ability */ + list sizeList = ability->GetSupportedSizes(0); + if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { + camId = cam; + break; + } + } + ``` + +5. 创建Camera实例。 + + ``` + EventHandler eventHdlr; // Create a thread to handle callback events + SampleCameraStateMng CamStateMng(eventHdlr); + + camKit->CreateCamera(camId, CamStateMng, eventHdlr); + ``` + +6. 根据[步骤1](#li378084192111)、[步骤2](#li8716104682913)、[步骤3](#li6671035102514)中的回调设计,camera实例创建成功后会进行配置操作,主流程中app需要设计同步机制。 + + ``` + void OnCreated(Camera &c) override + { + cout << "Sample recv OnCreate camera." << endl; + auto config = CameraConfig::CreateCameraConfig(); + config->SetFrameStateCallback(&fsCb_, &eventHdlr_); + c.Configure(*config); + cam_ = &c; + } + + void Capture() + { + if (cam_ == nullptr) { + cout << "Camera is not ready." << endl; + return; + } + FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); + Surface *surface = Surface::CreateSurface(); + if (surface == nullptr) { + delete fc; + return; + } + surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ + fc->AddSurface(*surface); + cam_->TriggerSingleCapture(*fc); + } + ``` + + diff --git "a/zh-cn/device-dev/subsystems/\351\242\204\350\247\210\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-multimedia-camera-preview-guide.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\351\242\204\350\247\210\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-multimedia-camera-preview-guide.md diff --git "a/zh-cn/device-dev/subsystems/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-multimedia-camera-record-guide.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-multimedia-camera-record-guide.md diff --git a/zh-cn/device-dev/subsystems/subsys-multimedia-camera.md b/zh-cn/device-dev/subsystems/subsys-multimedia-camera.md new file mode 100644 index 0000000000000000000000000000000000000000..ad7796b6926b7f89505b6508cda2e796fd961e64 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-multimedia-camera.md @@ -0,0 +1,11 @@ +# 相机 + +- **[相机开发概述](subsys-multimedia-camera-overview.md)** + +- **[拍照开发指导](subsys-multimedia-camera-photo-guide.md)** + +- **[录像开发指导](subsys-multimedia-camera-record-guide.md)** + +- **[预览开发指导](subsys-multimedia-camera-preview-guide.md)** + + diff --git "a/zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221\345\274\200\345\217\221\346\246\202\350\277\260.md" b/zh-cn/device-dev/subsystems/subsys-multimedia-video-overview.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221\345\274\200\345\217\221\346\246\202\350\277\260.md" rename to zh-cn/device-dev/subsystems/subsys-multimedia-video-overview.md diff --git "a/zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221\346\222\255\346\224\276\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-multimedia-video-play-guide.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221\346\222\255\346\224\276\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-multimedia-video-play-guide.md diff --git "a/zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221\345\275\225\345\210\266\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-multimedia-video-record-guide.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221\345\275\225\345\210\266\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-multimedia-video-record-guide.md diff --git a/zh-cn/device-dev/subsystems/subsys-multimedia-video.md b/zh-cn/device-dev/subsystems/subsys-multimedia-video.md new file mode 100644 index 0000000000000000000000000000000000000000..2a59765280656395693afc362f32fac0bc6c1447 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-multimedia-video.md @@ -0,0 +1,9 @@ +# 音视频 + +- **[音视频开发概述](subsys-multimedia-video-overview.md)** + +- **[音视频播放开发指导](subsys-multimedia-video-play-guide.md)** + +- **[音视频录制开发指导](subsys-multimedia-video-record-guide.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-multimedia.md b/zh-cn/device-dev/subsystems/subsys-multimedia.md new file mode 100644 index 0000000000000000000000000000000000000000..50fb9b91f2f47741ba7aa0efe8fa2935e52fd1de --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-multimedia.md @@ -0,0 +1,7 @@ +# 媒体 + +- **[相机](subsys-multimedia-camera.md)** + +- **[音视频](subsys-multimedia-video.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-ota-guide.md b/zh-cn/device-dev/subsystems/subsys-ota-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..8b7978468325b860b0c8f02a5fdb3d1ce4d6a650 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-ota-guide.md @@ -0,0 +1,358 @@ +# OTA升级 + +- [约束与限制](#section691733275418) +- [生成公私钥对](#section94411533155010) +- [生成升级包](#section632383718539) +- [上传升级包](#section5772112473213) +- [下载升级包](#section251732474917) +- [厂商应用集成OTA能力](#section298217330534) +- [API应用场景-默认场景](#section7685171192916) + - [开发指导](#section0745926153017) + - [示例代码](#section1337111363306) + +- [API应用场景-定制场景](#section1686395317306) + - [开发指导](#section524515314317) + - [示例代码](#section525974743120) + +- [系统升级](#section151997114334) + +OTA(Over the Air)提供对设备远程升级的能力,可以让您的设备(如IP摄像头等),轻松支持远程升级能力。目前仅支持全量包升级,暂不支持差分包升级。全量包升级是将新系统全部内容做成升级包,进行升级;差分包升级是将新老系统的差异内容做成升级包,进行升级。 + +## 约束与限制 + +- 支持基于Hi3861/Hi3518EV300/Hi3516DV300芯片的开源套件。 +- 对Hi3518EV300/Hi3516DV300开源套件,设备需要支持SD卡(VFAT格式)。 + +## 生成公私钥对 + +1. 准备工作:在Windows PC 上,下载安装OpenSSL工具,并配置环境变量。OpenSSL下载路径: + + [http://slproweb.com/products/Win32OpenSSL.html](http://slproweb.com/products/Win32OpenSSL.html) + +2. 在tools\\update\_tools\\update\_pkg\_tools目录下,下载升级包制作工具,保存到Windows本地路径,例如D:\\ota\_tools。 +3. 如图,运行ota\_tools\\key下的Generate\_public\_private\_key.bat ,生成公钥Metis\_PUBLIC.key、私钥private.key和公钥对应的数组public\_arr.txt文件,请妥善保管私钥private.key。 + + **图 1** 生成公私钥对 + + + ![](figure/zh-cn_image_0000001060200050.png) + +4. 用public\_arr.txt里面的全部内容替换OTA模块base\\update\\ota\_lite\\frameworks\\source\\verify\\hota\_verify.c中的g\_pubKeyBuf 。 + + 示例,public\_arr.txt内容 + + ``` + 0x30,0x82,0x1,0xa,0x2,0x82,0x1,0x1,0x0,0xc7,0x8c,0xf3,0x91,0xa1,0x98,0xbf,0xb1,0x8c, + 0xbe,0x22,0xde,0x32,0xb2,0xfa,0xec,0x2c,0x69,0xf6,0x8f,0x43,0xa7,0xb7,0x6f,0x1e,0x4a,0x97, + 0x4b,0x27,0x5d,0x56,0x33,0x9a,0x73,0x4e,0x7c,0xf8,0xfd,0x1a,0xf0,0xe4,0x50,0xda,0x2b,0x8, + 0x74,0xe6,0x28,0xcc,0xc8,0x22,0x1,0xa8,0x14,0x9,0x46,0x46,0x6a,0x10,0xcd,0x39,0xd,0xf3, + 0x4a,0x7f,0x1,0x63,0x21,0x33,0x74,0xc6,0x4a,0xeb,0x68,0x40,0x55,0x3,0x80,0x1d,0xd9,0xbc, + 0xd4,0xb0,0x4a,0x84,0xb7,0xac,0x43,0x1d,0x76,0x3a,0x61,0x40,0x23,0x3,0x88,0xcc,0x80,0xe, + 0x75,0x10,0xe4,0xad,0xac,0xb6,0x4c,0x90,0x8,0x17,0x26,0x21,0xff,0xbe,0x1,0x82,0x16,0x76, + 0x9a,0x1c,0xee,0x8e,0xd9,0xb0,0xea,0xd5,0x50,0x61,0xcc,0x9c,0x2e,0x78,0x15,0x2d,0x1f,0x8b, + 0x94,0x77,0x30,0x39,0x70,0xcf,0x16,0x22,0x82,0x99,0x7c,0xe2,0x55,0x37,0xd4,0x76,0x9e,0x4b, + 0xfe,0x48,0x26,0xc,0xff,0xd9,0x59,0x6f,0x77,0xc6,0x92,0xdd,0xce,0x23,0x68,0x83,0xbd,0xd4, + 0xeb,0x5,0x1b,0x2a,0x7e,0xda,0x9a,0x59,0x93,0x41,0x7b,0x4d,0xef,0x19,0x89,0x4,0x8d,0x5, + 0x7d,0xbc,0x3,0x1f,0x77,0xe6,0x3d,0xa5,0x32,0xf5,0x4,0xb7,0x9c,0xe9,0xfa,0x6e,0xc,0x9f, + 0x4,0x62,0xfe,0x2a,0x5f,0xbf,0xeb,0x9a,0x73,0xa8,0x2a,0x72,0xe3,0xf0,0x57,0x56,0x5c,0x59, + 0x14,0xdd,0x79,0x11,0x42,0x3a,0x48,0xf7,0xe8,0x80,0xb1,0xaf,0x1c,0x40,0xa2,0xc6,0xec,0xf5, + 0x67,0xc1,0x88,0xf6,0x26,0x5c,0xd3,0x11,0x5,0x11,0xed,0xb1,0x45,0x2,0x3,0x1,0x0,0x1, + ``` + + 示例,OTA模块的公钥 + + ``` + #define PUBKEY_LENGTH 270 + + static uint8 g_pubKeyBuf[PUBKEY_LENGTH] = { + 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, + 0x63, 0x07, 0x84, 0xCF, 0x37, 0xF0, 0x45, 0xE8, 0xB9, 0x6E, 0xEF, 0x04, 0x88, 0xD3, 0x43, 0x06, + ``` + +5. 对Hi3518EV300/Hi3516DV300套件,在上一步的基础上,还需用public\_arr.txt里面的全部内容替换uboot模块device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\verify\\update\_public\_key.c中的g\_pub\_key中的全部内容。 + + 示例,uboot模块的公钥 + + ``` + static unsigned char g_pub_key[PUBKEY_LEN] = { + 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E, + ``` + + +## 生成升级包 + +1. 在ota\_tools\\Components目录下,归放需要升级的文件。 + + **图 2** 原始镜像归放位置 + + + ![](figure/zh-cn_image_0000001061889268.png) + + **表 1** 升级包内的文件 + + + + + + + + + + + + + + + + + + + + + + +

包内文件名

+

说明

+

u-boot.bin

+

将编译生成的u-boot-hi351XevX00.bin文件重命名后得到。

+

kernel.bin

+

将编译生成的liteos.bin/kernel文件重命名后得到。

+

rootfs.img

+

将编译生成的rootfs_xxxxx.img文件重命名后得到。

+

config

+

与开发板类型和内核类型相关,参考开源套件的SD卡烧写说明。

+

OTA.tag

+

共32字节,内容为:“package_type:otaA1S2D3F4G5H6J7K8”;其中后16字节为随机数,需要随版本变化。

+
+ +2. 修改ota\_tools\\xml下的packet\_harmony.xml文件,配置compAddr分区名,对应ota\_tools\\Components\\的文件,其它项不需修改,作为扩展项预留。 + + 示例,配置组件信息 + + ``` + + + .\Components\rootfs_jffs2.img + .\Components\liteos.bin + .\Components\userfs_jffs2.img + + ``` + +3. 将生成的公私钥路径配置到ota\_tools\\xml路径下的packet\_harmony.xml中。 + + 示例,配置公私钥路径 + + ``` + + .\key\private.key + .\key\Metis_PUBLIC.key + + ``` + +4. 在ota\_tools\\VersionDefine.bat中设置产品名称、软件版本号(用于防回滚校验)。 + + 示例,配置产品名称和版本号 + + ``` + set FILE_PRODUCT_NAME=Hisi + + @rem 设置软件版本号 不要超过16位 + set SOFTWARE_VER=OpenHarmony 1.1 + ``` + +5. 执行ota\_tools下的Make\_Harmony\_PKG.bat,生成升级包Hisi\_OpenHarmony 1.1.bin。升级包通过SHA256+RSA2048方式签名,保证完整性和合法性。 + + **图 3** 升级包制作工具 + + + ![](figure/zh-cn_image_0000001059334449.png) + + +## 上传升级包 + +将升级包Hisi\_OpenHarmony 1.1.bin上传到厂商的OTA服务器。 + +## 下载升级包 + +1. 厂商应用从OTA服务器下载Hisi\_OpenHarmony 1.1.bin。 +2. 对Hi3518EV300/Hi3516DV300开源套件,需要插入SD卡\(容量\>100MBytes\)。 + +## 厂商应用集成OTA能力 + +- 调用OTA模块的动态库libhota.so,对应头文件位于:base\\update\\ota\_lite\\interfaces\\kits\\hota\_partition.h&hota\_updater.h; +- libhota.so对应的源码路径为base\\update\\ota\_lite\\frameworks\\source。 +- API的使用方法,见本文“API应用场景”和API文档的OTA接口章节。 +- 如果需要适配开发板,请参考HAL层头文件:base\\update\\ota\_lite\\hals\\hal\_hota\_board.h。 + +## API应用场景-默认场景 + +升级包是按照上文“生成公私钥对”和“生成升级包”章节制作的。 + +### **开发指导** + +1. 应用侧通过下载,获取当前设备升级包后,调用HotaInit接口初始化OTA模块。 +2. 调用HotaWrite接口传入升级包数据流,接口内部实现校验、解析及写入升级数据流。 +3. 写入完成后,调用HotaRestart接口重启系统。 + + 升级过程中,使用HotaCancel接口可以取消升级。 + + +### **示例代码** + +使用OpenHarmony的“升级包格式和校验方法“进行升级。 + +``` +int main(int argc, char **argv) +{ + printf("this is update print!\r\n"); + if (HotaInit(NULL, NULL) < 0) { + printf("ota update init fail!\r\n"); + return -1; + } + int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + printf("file open failed, fd = %d\r\n", fd); + (void)HotaCancel(); + return -1; + } + int offset = 0; + int fileLen = lseek(fd, 0, SEEK_END); + int leftLen = fileLen; + while (leftLen > 0) { + if (lseek(fd, offset, SEEK_SET) < 0) { + close(fd); + printf("lseek fail!\r\n"); + (void)HotaCancel(); + return -1; + } + int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; + (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); + if (read(fd, g_readBuf, tmpLen) < 0) { + close(fd); + printf("read fail!\r\n"); + (void)HotaCancel(); + return -1; + } + if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { + printf("ota write fail!\r\n"); + close(fd); + (void)HotaCancel(); + return -1; + } + offset += READ_BUF_LEN; + leftLen -= tmpLen; + } + close(fd); + printf("ota write finish!\r\n"); + printf("device will reboot in 10s...\r\n"); + sleep(10); + (void)HotaRestart(); + return 0; +} +``` + +## API应用场景-定制场景 + +升级包不是按照上文“生成公私钥对”和“生成升级包”章节制作的,是通过其它方式制作的。 + +### **开发指导** + +1. 应用侧通过下载,获取当前设备升级包后,调用HotaInit接口初始化。 +2. 使用HotaSetPackageType接口设置NOT\_USE\_DEFAULT\_PKG,使用"定制"流程。 +3. 调用HotaWrite接口传入升级包数据流,写入设备。 +4. 写入完成后,调用HotaRead接口读取数据,厂商可以自行校验升级包。 +5. 调用HotaSetBootSettings设置启动标记,在重启后需要进入uboot模式时使用(可选)。 +6. 调用HotaRestart接口,进行重启。 + + 升级过程中,使用HotaCancel接口可以取消升级。 + + +### **示例代码** + +使用非OpenHarmony的“升级包格式和校验方法“进行升级。 + +``` +int main(int argc, char **argv) +{ + printf("this is update print!\r\n"); + if (HotaInit(NULL, NULL) < 0) { + printf("ota update init fail!\r\n"); + (void)HotaCancel(); + return -1; + } + (void)HotaSetPackageType(NOT_USE_DEFAULT_PKG); + int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + printf("file open failed, fd = %d\r\n", fd); + (void)HotaCancel(); + return -1; + } + int offset = 0; + int fileLen = lseek(fd, 0, SEEK_END); + int leftLen = fileLen; + while (leftLen > 0) { + if (lseek(fd, offset, SEEK_SET) < 0) { + close(fd); + printf("lseek fail!\r\n"); + (void)HotaCancel(); + return -1; + } + int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; + (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); + if (read(fd, g_readBuf, tmpLen) < 0) { + close(fd); + printf("read fail!\r\n"); + (void)HotaCancel(); + return -1; + } + if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) { + printf("ota write fail!\r\n"); + close(fd); + (void)HotaCancel(); + return -1; + } + offset += READ_BUF_LEN; + leftLen -= tmpLen; + } + close(fd); + printf("ota write finish!\r\n"); + leftLen = fileLen; + while (leftLen > 0) { + int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen; + (void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN); + if (HotaRead(offset, READ_BUF_LEN, (unsigned char *)g_readBuf) != 0) {} + printf("ota write fail!\r\n"); + (void)HotaCancel(); + return -1; + } + /* do your verify and parse */ + offset += READ_BUF_LEN; + leftLen -= tmpLen; + } + /* set your boot settings */ + (void)HotaSetBootSettings(); + printf("device will reboot in 10s...\r\n"); + sleep(10); + (void)HotaRestart(); + return 0; +} +``` + +## 系统升级 + +厂商应用调用OTA模块的API,OTA模块执行升级包的签名验证、版本防回滚、烧写落盘功能,升级完成后自动重启系统。 + +对Hi3518EV300/Hi3516DV300开源套件,在需要实现防回滚功能的版本中,需要增加LOCAL\_VERSION的值,如"ohos default 1.0"-\>"ohos default 1.1",LOCAL\_VERSION在device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\ota\_update\\ota\_local\_info.c中。 + +示例,增加版本号 + +``` +const char *get_local_version(void) +{ +#if defined(CONFIG_TARGET_HI3516EV200) || \ + defined(CONFIG_TARGET_HI3516DV300) || \ + defined(CONFIG_TARGET_HI3518EV300) +#define LOCAL_VERSION "ohos default 1.0" /* increase: default release version */ +``` + diff --git "a/zh-cn/device-dev/subsystems/\345\210\206\345\270\203\345\274\217\350\277\234\347\250\213\345\220\257\345\212\250.md" b/zh-cn/device-dev/subsystems/subsys-remote-start.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\210\206\345\270\203\345\274\217\350\277\234\347\250\213\345\220\257\345\212\250.md" rename to zh-cn/device-dev/subsystems/subsys-remote-start.md diff --git "a/zh-cn/device-dev/subsystems/IPC\351\200\232\344\277\241\351\211\264\346\235\203\345\274\200\345\217\221\346\214\207\345\257\274.md" b/zh-cn/device-dev/subsystems/subsys-security-communicationverify.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/IPC\351\200\232\344\277\241\351\211\264\346\235\203\345\274\200\345\217\221\346\214\207\345\257\274.md" rename to zh-cn/device-dev/subsystems/subsys-security-communicationverify.md diff --git a/zh-cn/device-dev/subsystems/subsys-security-overview.md b/zh-cn/device-dev/subsystems/subsys-security-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..5c47b308081819cc88c581f359cca3b4dc8cdd8f --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-security-overview.md @@ -0,0 +1,76 @@ +# 概述 + +- [基本概念](#section175012297491) +- [约束与限制](#section2029921310472) + +OpenHarmony安全子系统目前提供给开发者的安全能力主要包含应用可信、权限管理、设备可信。涉及以下几个模块: + +- 应用验签 + + 为了确保应用内容的完整性,系统通过应用签名和Profile对应用的来源进行管控,同时对于调试应用,还可通过验签接口验证应用和设备的UDID是否匹配,确保应用安装在了正确的设备上。 + +- 应用权限管理 + + 应用权限是管理应用访问系统资源和使用系统能力的一种通用方式,应用在开发阶段需要在profile.json中指明此应用在运行过程中可能会调用哪些权限,其中静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示涉及到敏感信息,所以需要用户进行动态授权。 + +- IPC通信鉴权 + + 系统服务通过IPC暴露接口给其他进程访问,这些接口需要配置相应的访问策略,当其他进程访问这些接口时,将会触发IPC通信鉴权机制校验访问进程是否拥有权限访问该接口,若无权限,则拒绝访问该接口。 + +- 可信设备群组管理 + + 提供基于群组概念的同华为账号群组、点对点群组(如二维码、碰一碰等)的设备安全可信关系的创建和查询,分布式应用可基于该能力进行设备间的可信认证,然后向分布式软总线请求设备间安全会话。 + + +## 基本概念 + +在进行依赖验签组件的应用开发前,开发者应了解以下基本概念: + +- Samgr + + Samgr\(System Ability Manager\)系统能力管理,在OpenHarmony上作为一个管理系统能力的模块,详见系统服务框架子系统。 + + +- BMS + + BMS\(Bundle Manager Service\)包管理管理,在OpenHarmony上主要负责应用的安装、卸载和数据管理。 + + +- 描述文件 + + 本文中的描述文件,指HarmonyAppProvision,简称profile。HarmonyAppProvision采用json文件格式进行描述。 + + +- 叶子证书 + + 最终用于为整包或profile签名的证书称为叶子证书,位于数字证书链的最末端。 + + +- 调试应用 + + 指开发者从应用市场申请调试证书与调试描述文件,并以此签名的hap包。 + + +- 待上架应用 + + 指开发者从应用市场申请发布证书与发布描述文件,以此签名,未通过应用市场正式发布的hap包。 + + +- 发布应用 + + 指开发者从应用市场申请发布证书与发布描述文件,以此签名的hap包,上传至应用市场,并由应用市场正式发布的hap包。 + + +- OpenHarmony自签名应用 + + 当开发者自行编译OpenHarmony系统应用后,采用原应用描述文件,以及公开的OpenHarmony公私钥对和证书进行自签名产生的hap包。 + + +## 约束与限制 + +- 仅支持以下三类应用的验签:应用市场调试应用、应用市场发布应用、OpenHarmony自签名应用的验签。 +- 若对应用市场调试应用验签,则本机UDID需要在描述文件包含的UDID列表中。 +- 待上架应用无法验签通过。 +- 验签组件提供的接口都位于security\_interfaces\_innerkits\_app\_verify仓[app\_verify\_pub.h](https://gitee.com/fork_ohos_wj/security_interfaces_innerkits_app_verify/blob/master/app_verify_pub.h)中,仅支持系统应用开发者调用。 +- 可信设备群组管理接口,目前只对系统签名权限才可以使用。 + diff --git a/zh-cn/device-dev/subsystems/subsys-security-rightmanagement.md b/zh-cn/device-dev/subsystems/subsys-security-rightmanagement.md new file mode 100644 index 0000000000000000000000000000000000000000..37f3cdbbf7c82ceb3489f67358c7ac0f1b07e2bf --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-security-rightmanagement.md @@ -0,0 +1,228 @@ +# 应用权限管理开发指导 + +- [运作机制](#section193961322175011) +- [场景介绍](#section18502174174019) +- [接口说明](#section1633115419401) +- [开发步骤](#section022611498210) + +## 运作机制 + +由于OpenHarmony允许安装三方应用,所以需要对三方应用的敏感权限调用进行管控,具体实现是应用在开发阶段就需要在profile.json中指明此应用在运行过程中可能会调用哪些敏感权限,这些权限包括静态权限和动态权限,静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示获取用户的敏感信息,所以需要在运行时让用户确认才可以调用,授权方式包括系统设置应用手动授权等。除了运行时对应用调用敏感权限进行管控外,还需要利用应用签名管控手段确保应用安装包已经被设备厂商进行了确认。 + +**表 1** OpenHarmony权限列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

OpenHarmony权限

+

授权方式

+

权限说明

+

ohos.permission.LISTEN_BUNDLE_CHANGE

+

system_grant(静态权限)

+

允许该应用获取应用变化消息。

+

ohos.permission.GET_BUNDLE_INFO

+

system_grant(静态权限)

+

允许该应用获取应用信息。

+

ohos.permission.INSTALL_BUNDLE

+

system_grant(静态权限)

+

允许该应用安装应用。

+

ohos.permission.CAMERA

+

user_grant(动态权限)

+

此应用可随时使用相机拍摄照片和录制视频。

+

ohos.permission.MODIFY_AUDIO_SETTINGS

+

system_grant(静态权限)

+

允许该应用修改全局音频设置,例如音量和用于输出的扬声器。

+

ohos.permission.READ_MEDIA

+

user_grant(动态权限)

+

允许该应用读取您的视频收藏。

+

ohos.permission.MICROPHONE

+

user_grant(动态权限)

+

此应用可随时使用麦克风进行录音。

+

ohos.permission.WRITE_MEDIA

+

user_grant(动态权限)

+

允许该应用写入您的音乐收藏。

+

ohos.permission.DISTRIBUTED_DATASYNC

+

user_grant(动态权限)

+

管控分布式数据传输能力。

+

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

+

user_grant(动态权限)

+

允许应用使用分布式虚拟能力

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>静态权限:应用安装时由系统授予的权限,对应于权限敏感级别的system\_grant +>动态权限:应用在运行过程中需要用户授权的权限,对应于权限敏感级别的user\_grant + +## 场景介绍 + +应用权限是软件用来访问系统资源和使用系统能力的一种通行方式。在涉及用户隐私相关功能和数据的场景,例如:访问个人设备的硬件特性,如摄像头、麦克风,以及读写媒体文件等,OpenHarmony通过应用权限管理组件来保护这些数据以及能力。 + +在系统应用开发过程中,如果应用要使用敏感权限,开发者可以调用应用权限管理组件接口检查待访问权限是否被授权,如果未授权,操作不允许。 + +## 接口说明 + +应用权限管理提供的API接口,当前仅供系统应用和系统服务调用,具体API接口如下。 + +**表 2** 应用权限管理API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口名

+

描述

+

int CheckPermission(int uid, const char *permissionName)

+

检查指定UID的应用进程是否具有访问系统服务API的权限

+

int CheckSelfPermission(const char *permissionName)

+

检查调用者是否具有访问系统服务API的权限

+

int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)

+

查询应用申请的所有权限,并检查权限是否被授予

+

int GrantPermission(const char *identifier, const char *permName)

+

将指定权限授予应用程序

+

int RevokePermission(const char *identifier, const char *permName)

+

收回应用程序的指定权限

+

int GrantRuntimePermission(int uid, const char *permissionName)

+

应用运行时动态授予指定权限

+

int RevokeRuntimePermission(int uid, const char *permissionName)

+

应用运行时动态撤销指定权限

+
+ +## 开发步骤 + +本部分以包管理器的应用权限开发为例进行讲解。开发过程中,首先需要明确涉及的敏感权限,并在config.json中声明该权限,在安装应用程序时,包管理器会调用应用权限管理组件的接口检查该权限是否被授予,若授予,安装流程正常进行,否则安装失败。 + +1. 在开发过程中,包管理器明确需要安装应用的权限(ohos.permission.INSTALL\_BUNDLE),并在config.json中声明该权限; + + ``` + { + ... + "module": { + "package": "com.huawei.kitframework", + "deviceType": [ + "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera", "smartVision" + ], + "reqPermissions": [{ + // 声明需要的权限:安装应用程序的权限名 + "name": "ohos.permission.INSTALL_BUNDLE", + "reason": "install bundle", + "usedScene": { + "ability": [ + "KitFramework" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.LISTEN_BUNDLE_CHANGE", + "reason": "install bundle", + "usedScene": { + "ability": [ + "KitFramework" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.GET_BUNDLE_INFO", + "reason": "install bundle", + "usedScene": { + "ability": [ + "KitFramework" + ], + "when": "always" + } + } + ], + ... + } + ``` + +2. 当包管理器开发应用安装功能接口时,会调用权限管理相关接口检查自身是否具有安装应用程序的权限,例如:以安装应用的权限名"ohos.permission.INSTALL\_BUNDLE"作为入参,调用CheckPermission接口检查包管理器是否具有安装应用的权限,如果有权限,安装流程继续执行,否则返回安装失败; + + ``` + constexpr static char PERMISSION_INSTALL_BUNDLE[] = "ohos.permission.INSTALL_BUNDLE"; + + bool Install(const char *hapPath, const InstallParam *installParam, InstallerCallback installerCallback) + { + if ((hapPath == nullptr) || (installerCallback == nullptr) || (installParam == nullptr)) { + HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to nullptr parameters"); + return false; + } + // 检查ohos.permission.INSTALL_BUNDLE权限是否被授予 + if (CheckPermission(0, static_cast(PERMISSION_INSTALL_BUNDLE)) != GRANTED) { + HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to permission denied"); + return false; // 返回安装失败 + } + // 安装流程 + ... + } + ``` + + diff --git a/zh-cn/device-dev/subsystems/subsys-security-sigverify.md b/zh-cn/device-dev/subsystems/subsys-security-sigverify.md new file mode 100644 index 0000000000000000000000000000000000000000..a7e2f85b64ec50c09ad516a117b157d71907c11f --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-security-sigverify.md @@ -0,0 +1,272 @@ +# 应用验签开发指导 + +- [场景介绍](#section18502174174019) +- [验签流程](#section554632717226) +- [接口说明](#section1633115419401) +- [开发步骤(场景一)](#section4207112818418) + - [验签指导](#section11470123816297) + - [生成OpenHarmony自签名应用](#section167151429133312) + - [开发示例](#section174318361353) + +- [开发步骤(场景二)](#section81272563427) + - [验签指导](#section07028210442) + - [开发示例](#section1930711345445) + +- [调测验证](#section427316292411) + +## 场景介绍 + +当需要验证调试应用、发布应用,OpenHarmony自签名应用的完整性是否被破坏时,可以调用验签组件的接口进行验证。如有需要还可通过验签接口获取部分描述文件信息,如appid。对于调试应用,还可通过验签接口验证应用和设备的UDID是否匹配,确保应用安装在了正确的设备上。 + +## 验签流程 + +未经签名的Hap包的压缩方式是ZIP格式,简单分为文件块,中心目录(Central directory)块,中心目录结尾(EOCD,End of central directory record)块。 + +经过签名的Hap包,在文件块,和中心目录块之间,插入了签名块。签名块由文件签名数据块(data sign block)、描述文件签名数据块(profile sign block)和签名头(sign head)组成,如下图所示。 + +**图 1** 经过签名的Hap包结构 + + +![](figure/安全子系统.png) + +整个验签流程,主要分为三部分:整包验签、描述文件签名块验签,以及描述文件内容校验。 + +**整包验签** + +用设备的预置根证书,通过证书链来证明叶子证书本身是可信的,然后用叶子证书的公钥解密出的摘要证明整包是未篡改的。 + +具体操作步骤如下: + +1. 对文件签名数据块中的证书链进行校验,确定其叶子证书是可信的。 +2. 用叶子证书中的公钥对文件签名块进行验签,证明其未被篡改。 +3. 计算并合并文件块,中心目录块和中心目录结尾块的摘要。然后将计算结果,再与签名块中的描述文件签名块的摘要合并,将最终合并的摘要与文件签名块中包含的摘要对比,如果两者相等,则整包验签通过。 + +**描述文件签名块验签** + +首先判断文件签名的签发单位,如果是应用市场签发的发布应用,则无需对描述文件进行验签,直接信任,否则要对其验签。先取出整个描述文件签名块,然后验证证书链,最后用叶子证书对描述文件数据块验签,证明其未被篡改。 + +**描述文件内容校验** + +取出描述文件,并对其内容进行合法性检查。其中若hap包为调试应用,则会比对本机UDID与描述文件中包含的UDID列表,如果本机UDID在描述文件的UDID列表中包含,则验证通过。比较描述文件中包含的证书(如果是应用市场发布应用或OpenHarmony自签名则无需比较),和整包校验时使用的叶子证书,如果相同,认为整个验签流程完成。 + +## 接口说明 + +验签组件当前提供innerkits接口,仅供系统应用调用,相关接口及功能描述如下: + +**表 1** 验签组件API接口功能介绍 + + + + + + + + + + + + + + + + +

接口名

+

描述

+

int APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)

+

主入口函数,输入文件路径,进行验签,并将从描述文件中获取的数据通过verifyRst返回给调用者

+

int APPVERI_SetDebugMode(bool mode)

+

设置测试模式,设置mode为true,则支持基于测试根密钥的证书链校验,设置mode为false,则关闭基于测试根密钥的证书链校验。

+

注:当前没有基于现有测试根密钥的证书,开发者可根据自身需要,替换测试根密钥并进行相关验证。

+

void APPVERI_FreeVerifyRst(VerifyResult *verifyRst)

+

释放verifyRst中申请的内存

+
+ +## 开发步骤(场景一) + +### 验签指导 + +对应用市场发布应用、基于应用市场调试证书签发的调试应用、OpenHarmony自签名应用的校验。 + +1. 定义出参结构体变量VerifyResult; + + ``` + VerifyResult verifyResult = {0}; + ``` + +2. 以文件路径及VerifyResult为入参,调用APPVERI\_AppVerify进行文件校验; + + ``` + int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); + ``` + +3. 判断返回结果,如果校验通过的话,获取VerifyResult中的数据,进行业务处理; + + ``` + signatureInfo.appId = verifyResult.profile.appid; + signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; + ``` + +4. 调用APPVERI\_FreeVerifyRst,释放VerifyResult中申请的内存。 + + ``` + APPVERI_FreeVerifyRst(&verifyResult); + ``` + + +### 生成OpenHarmony自签名应用 + +如果是OpenHarmony自签名应用的校验,开发者可通过以下方式生成OpenHarmony自签名应用。 + +1. 材料备齐。 + + 生成自签名应用需要的材料有:签名工具、系统应用hap包、系统应用profile文件\(\*.p7b\)、签名证书\(\*.cer\)、签名公私钥对\(\*.jks\)。 + +2. 将所有材料放在同一个目录下,打开shell。 +3. 根据应用、描述文件的实际名称修改指令,并在shell中输入,完成签名。 + + ``` + java -jar hapsigntoolv2.jar sign -mode localjks -privatekey "OpenHarmony Software Signature" -inputFile camera.hap -outputFile signed_camera.hap -signAlg SHA256withECDSA -keystore OpenHarmony.jks -keystorepasswd 123456 -keyaliaspasswd 123456 -profile camera_release.p7b -certpath OpenHarmony.cer -profileSigned 1 + ``` + + 关键字段说明: + + -jar:签名工具,[hapsigntool](https://repo.huaweicloud.com/harmonyos/develop_tools/hapsigntoolv2.jar) + + -mode:本地签名标记位,固定为localjks + + -privatekey:密钥对别名,签名公私钥对的别名为OpenHarmony Software Signature + + -inputFile:待签名应用,通过编译产生 + + -outputFile:签名后应用,最终输出 + + -signAlg:签名算法,当前固定为SHA256withECDSA + + -keystore:公私钥对,使用签名公私钥对,位于开源库security\_services\_app\_verify仓中OpenHarmonyCer目录下,[OpenHarmony.jks](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.jks)。默认密码为123456 ,用户可采用工具\(例如keytool\)更改默认密码 + + -keystorepasswd:公私钥对密码,默认签名公私钥对密码为123456 + + -keyaliaspasswd:公私钥对别名密码,默认签名公私钥对别名密码为123456 + + -profile:描述文件,应用的描述文件位于对应源代码目录中 + + -certpath:使用签名证书,位于开源库security\_services\_app\_verify仓中OpenHarmonyCer目录下,[OpenHarmony.cer](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.cer) + + -profileSigned:签名块中是否包含描述文件\(profile\)。固定为1(包含) + + +### 开发示例 + +以应用管理框架组件在应用安装时进行验签的实际调用为例: + +``` +uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) +{ + bool mode = ManagerService::GetInstance().IsDebugMode(); + HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); + // 定义结果结构体 + VerifyResult verifyResult = {0}; + // 输入待验签文件路径进行验签 + int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); + uint8_t errorCode = SwitchErrorCode(ret); + if (errorCode != ERR_OK) { + return errorCode; + } + // 从结果结构体中获取appid + signatureInfo.appId = verifyResult.profile.appid; + // 从结果结构体中获取描述文件中书写的应用名 + signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; + int32_t restricNum = verifyResult.profile.permission.restricNum; + for (int32_t i = 0; i < restricNum; i++) { + signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); + } + // 释放结果结构体中申请的内存 + APPVERI_FreeVerifyRst(&verifyResult); + return ERR_OK; +} +``` + +## 开发步骤(场景二) + +### 验签指导 + +对采用基于测试根密钥证书签名的应用的校验。 + +1. 调用APPVERI\_SetDebugMode\(true\)开启测试模式; + + ``` + ManagerService::SetDebugMode(true); + ... + uint8_t ManagerService::SetDebugMode(bool enable) + { + int32_t ret = APPVERI_SetDebugMode(enable); + if (ret < 0) { + HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); + return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; + } + isDebugMode_ = enable; + HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); + return ERR_OK; + } + ``` + +2. 同场景一中步骤一至四,定义结构体,校验、释放结构体; +3. 调用APPVERI\_SetDebugMode\(false\)关闭测试模式。 + + ``` + ManagerService::SetDebugMode(false); + ``` + + +### 开发示例 + +完整开发示例如下(在场景一代码示例的基础上进行补充): + +``` +uint8_t ManagerService::SetDebugMode(bool enable) +{ + int32_t ret = APPVERI_SetDebugMode(enable); + if (ret < 0) { + HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); + return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; + } + isDebugMode_ = enable; + HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); + return ERR_OK; +} +uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) +{ + // 开启支持测试服务器签名应用验证 + ManagerService::SetDebugMode(true); + bool mode = ManagerService::GetInstance().IsDebugMode(); + HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); + // 定义结果结构体 + VerifyResult verifyResult = {0}; + // 输入待验签文件路径进行验签 + int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); + uint8_t errorCode = SwitchErrorCode(ret); + if (errorCode != ERR_OK) { + return errorCode; + } + // 从结果结构体中获取appid + signatureInfo.appId = verifyResult.profile.appid; + // 从结果结构体中获取描述文件中书写的应用名 + signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; + int32_t restricNum = verifyResult.profile.permission.restricNum; + for (int32_t i = 0; i < restricNum; i++) { + signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); + } + // 释放结果结构体中申请的内存 + APPVERI_FreeVerifyRst(&verifyResult); + // 关闭支持测试服务器签名应用验证 + ManagerService::SetDebugMode(false); + return ERR_OK; +} +``` + +## 调测验证 + +1. 选取一个在OpenHarmony上能够正常安装的应用A。 +2. 根据开发指导开发。 +3. 对应用A,采用自开发程序进行验签,验签通过,能获取到appid。即为开发成功。 + diff --git a/zh-cn/device-dev/subsystems/subsys-security.md b/zh-cn/device-dev/subsystems/subsys-security.md new file mode 100644 index 0000000000000000000000000000000000000000..1a0b0eb10140d07891972385e3ba30d5018d0f63 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-security.md @@ -0,0 +1,11 @@ +# 安全 + +- **[概述](subsys-security-overview.md)** + +- **[应用验签开发指导](subsys-security-sigverify.md)** + +- **[应用权限管理开发指导](subsys-security-rightmanagement.md)** + +- **[IPC通信鉴权开发指导](subsys-security-communicationverify.md)** + + diff --git "a/zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\344\275\277\347\224\250\345\256\236\344\276\213.md" b/zh-cn/device-dev/subsystems/subsys-sensor-demo.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/Sensor\346\234\215\345\212\241\345\255\220\347\263\273\344\275\277\347\224\250\345\256\236\344\276\213.md" rename to zh-cn/device-dev/subsystems/subsys-sensor-demo.md diff --git a/zh-cn/device-dev/subsystems/subsys-sensor-guide.md b/zh-cn/device-dev/subsystems/subsys-sensor-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..b8d7fa3101e40fe532be50aadfe065bdbd5dca9b --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-sensor-guide.md @@ -0,0 +1,72 @@ +# Sensor服务子系使用指导 + +- [使用步骤](#section18816105182315) + +下面使用步骤以sensorTypeId为0的传感器为例,其他类型的传感器使用方式类似。 + +## 使用步骤 + +1. 导入需要的包 + +``` +#include "sensor_agent.h" +#include "sensor_agent_type.h" +``` + +1. 创建传感器回调函数 + +``` +void SensorDataCallbackImpl(SensorEvent *event) +{ + if(event == NULL){ + return; + } + float *sensorData=(float *)event->data; +} +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>回调函数的格式为RecordSensorCallback类型。 + +1. 获取设备支持sensor列表 + +``` +SensorInfo *sensorInfo = (SensorInfo *)NULL; +int32_t count = 0; +int32_t ret = GetAllSensors(&sensorInfo, &count); +``` + +1. 创建的传感器用户 + +``` +SensorUser sensorUser; +sensorUser.callback = SensorDataCallbackImpl; //成员变量callback指向创建的回调方法 +``` + +1. 使能传感器 + +``` +int32_t ret = ActivateSensor(0, &sensorUser); +``` + +1. 订阅传感器数据 + +``` +int32_t ret = SubscribeSensor(0, &sensorUser); +``` + +>![](../public_sys-resources/icon-note.gif) **说明:** +>到这步就可以在实现的回调方法中获取到传感器数据。 + +1. 取消传感器数据订阅 + +``` +int32_t ret = UnsubscribeSensor(0, &sensorUser); +``` + +1. 去使能一个传感器 + +``` +int32_t ret = DeactivateSensor(0, &sensorUser); +``` + diff --git a/zh-cn/device-dev/subsystems/subsys-sensor-overview.md b/zh-cn/device-dev/subsystems/subsys-sensor-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..caee5f57cad7a17eef842b59aba1eec3de56a1a0 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-sensor-overview.md @@ -0,0 +1,99 @@ +# Sensor服务子系概述 + +- [简介](#section667413271505) +- [接口说明](#section7255104114110) + +## 简介 + +Sensor服务子系统提供了轻量级传感器服务基础框架,您可以使用该框架接口实现传感器列表查询、传感器控制、传感器订阅去订阅等功能。轻量级传感器服务框架如下图所示: + +**图1** Sensor服务框架图 + +![](figure/zh-cn_image_0000001077724150.png) + +- Sensor API:提供传感器的基础API,主要包含查询传感器的列表、订阅/取消传感器数据、执行控制命令等,简化应用开发。 +- Sensor Framework:主要实现传感器的订阅管理、数据通道的创建、销毁等,实现与传感器服务层的通信。 +- Sensor Service:主要实现HDF层数据接收、解析、分发,对设备传感器的管理,数据上报管理以及传感器权限管控等。 + +## 接口说明 + +**表 1** Sensor服务框架API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口名

+

接口说明

+

参数要求

+

int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count)

+

作用:获取系统中所有传感器的信息。

+

返回值:0表示成功,其他返回值表示失败。

+

sensorInfo(NOT NULL):输出系统中所有传感器的信息;

+

count(NOT NULL):输出系统中所有传感器的数量。

+

int32_t SubscribeSensor(int32_t sensorTypeId, SensorUser *user)

+

作用:订阅传感器数据,系统会将获取到的传感器数据上报给订阅者。

+

返回值: 0为成功,其他返回值表示失败。

+

sensorTypeId:唯一标识一个传感器类型;

+

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

+

int32_t UnsubscribeSensor(int32_t sensorTypeId, SensorUser *user)

+

作用:去订阅传感器数据,系统将取消传感器数据上报给订阅者。

+

返回值:0为成功,其他返回值表示失败。

+

sensorTypeId:唯一标识一个传感器类型;

+

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

+

int32_t SetBatch(int32_t sensorTypeId, SensorUser *user, int64_t samplingInterval, int64_t reportInterval)

+

作用:设置传感器的数据采样间隔和数据上报间隔

+

返回值:0为成功,其他返回值表示失败。

+

sensorTypeId:唯一标识一个传感器类型;

+

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器;

+

samplingInterval:传感器数据采样间隔,单位纳秒;

+

reportInterval:传感器数据上报间隔,单位纳秒。

+

int32_t ActivateSensor(int32_t sensorTypeId, SensorUser *user)

+

作用:使能一个传感器订阅用户。

+

返回值:0为成功,其他返回值表示失败。

+

sensorTypeId:唯一标识一个传感器类型;

+

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

+

int32_t DeactivateSensor(int32_t sensorTypeId, SensorUser *user)

+

作用:去使能一个传感器订阅用户

+

返回值:0为成功,其他返回值表示失败。

+

sensorTypeId:唯一标识一个传感器类型;

+

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器。

+

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

+

作用:设置传感器的工作模式

+

返回值:0为成功,其他返回值表示失败。

+

sensorTypeId:唯一标识一个传感器类型;

+

user(NOT NULL):传感器的用户,用于从传感器获取数据,一般一个用户只属于一个传感器;

+

mode:传感器的数据上报模式。

+
+ diff --git a/zh-cn/device-dev/subsystems/subsys-sensor.md b/zh-cn/device-dev/subsystems/subsys-sensor.md new file mode 100644 index 0000000000000000000000000000000000000000..415eec2bde7a96ccb8ee88e7c27d41872654b843 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-sensor.md @@ -0,0 +1,9 @@ +# Sensor服务 + +- **[Sensor服务子系概述](subsys-sensor-overview.md)** + +- **[Sensor服务子系使用指导](subsys-sensor-guide.md)** + +- **[Sensor服务子系使用实例](subsys-sensor-demo.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-testguide-test.md b/zh-cn/device-dev/subsystems/subsys-testguide-test.md new file mode 100644 index 0000000000000000000000000000000000000000..2403929934b2c2860c3e2dd2200e9a9046930e64 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-testguide-test.md @@ -0,0 +1,989 @@ +# 测试 + +- [概述](#section12403172115920) + - [基本概念](#section53632272090) + - [运作机制](#section2394431106) + +- [约束与限制](#section2029921310472) +- [搭建环境](#section175012297491) + - [环境要求](#section935055691014) + - [安装环境](#section6511193210111) + - [检验环境是否搭建成功](#section1899144517117) + +- [开发指导](#section16741101301210) + - [场景介绍](#section93782214124) + - [接口说明](#section54131732101218) + - [开发步骤](#section53541946111218) + +- [开发实例](#section7477121918136) +- [测试平台使用](#section76401945124810) +- [包结构说明](#section1875515364133) + +## 概述 + +### 基本概念 + +测试子系统提供基于python开发的一键式的开发者自测试平台,支持跨平台使用以及三方测试框架拓展,主要包括测试用例编译、测试用例管理、测试用例调度分发、测试用例执行、测试结果收集、测试报告生成、测试用例模板、测试环境管理等模块。 + +在测试子系统开发前,开发者应先了解以下概念: + +- 测试用例编译 + + 支持将测试用例源代码编译成可在被测设备侧执行的二进制文件。 + +- 测试用例调度分发 + + 支持将测试用例通过网口通道或者串口通道分发到不同的被测设备上,并且为每一个测试用例分配特定的测试用例执行器。 + +- 测试用例执行器 + + 负责测试用例的预处理,用例执行,结果记录等执行逻辑。 + +- 测试用例模板 + + 定义了测试用例以及用例编译配置GN文件的统一格式。 + +- 测试平台kit + + 测试平台运行过程中公共方法,如提供测试用例目录向被测设备挂载文件系统,测试用例推送到被测设备,或者从被测设备获取测试结果等操作。 + +- 测试报告生成 + + 定义开发者自测试报告模板,生成web测试报告。 + +- 测试环境管理 + + 支持通过USB、串口等方式管理被测设备,功能包括设备发现,设备状态查询等。 + + +### 运作机制 + +- 测试平台架构图如下: + +**图 1** 测试平台架构 +![](figure/测试平台架构.png "测试平台架构") + +- 测试平台运行时序图如下: + +**图 2** 测试平台运行时序 +![](figure/测试平台运行时序.png "测试平台运行时序") + +- 测试平台运行原理 + +测试平台通过shell脚本启动,以命令行方式支持一系列的测试指令执行,通过命令行输出测试结果。 + +## 约束与限制 + +- 功能使用范围:开发自测试平台仅支持代码级的测试用例开发和验证,如单元测试,模块测试。 +- 规格限制:当前测试框架的适用范围仅支持白盒测试。 +- 操作限制:一台测试设备上仅支持启动单个测试平台。 + +## 搭建环境 + +### 环境要求 + +**表 1** **环境要求** + + + + + + + + + + + + + + + + +

项目

+

测试设备

+

被测设备

+

硬件

+
  • 内存:8G及以上
  • 硬盘:100G及以上
  • 硬件架构:X86或ARM64
+
  • Hi3516 DV300开发板
  • Hi3518 EV300开发板
+

软件

+
  • 操作系统:Windows 10 64位 或 Ubuntu 18.04

    系统组件(Linux): libreadline-dev

    +
  • Python:3.7.5及以上
  • Python插件:pyserial3.3及以上、paramiko2.7.1及以上、setuptools40.8.0及以上,rsa4.0及以上
  • NFS Server:haneWIN NFS Server1.2.50及以上或者 NFSv4及以上
+
  • 系统软件:版本不低于OpenHarmony 1.0
  • 内核类型:LiteOS-A或者Linux
+
+ +### 安装环境 + +1. 如测试环境为Linux,需要安装系统组件readline,命令如下: + + ``` + sudo apt-get install libreadline-dev + ``` + + 安装成功提示如下: + + ``` + Reading package lists... Done + Building dependency tree + Reading state information... Done + libreadline-dev is already the newest version (7.0-3). + 0 upgraded, 0 newly installed, 0 to remove and 11 not upgraded. + ``` + +2. 安装Python扩展组件setuptools、(rsa、paramiko、以及pyserial,设备仅支持串口时安装),命令如下: + + 1、安装setuptools,安装命令如下: + + ``` + pip install setuptools + ``` + + 安装成功提示如下: + + ``` + Requirement already satisfied: setuptools in d:\programs\python37\lib\site-packages (41.2.0) + ``` + + 2、安装rsa,安装命令如下: + + ``` + pip install rsa + ``` + + 安装成功提示如下: + + ``` + Installing collected packages: pyasn1, rsa + Successfully installed pyasn1-0.4.8 rsa-4.7 + ``` + + 3、安装Paramiko,安装命令如下: + + ``` + pip install paramiko + ``` + + 安装成功提示如下: + + ``` + Installing collected packages: pycparser, cffi, pynacl, bcrypt, cryptography, paramiko + Successfully installed bcrypt-3.2.0 cffi-1.14.4 cryptography-3.3.1 paramiko-2.7.2 pycparser-2.20 pynacl-1.4.0 + ``` + + 4、安装pyserial(被测设备仅支持串口时安装),安装命令如下: + + ``` + pip install pyserial + ``` + + 安装成功提示如下: + + ``` + Requirement already satisfied: pyserial in d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg (3.4) + ``` + +3. 安装NFS server(被测设备仅支持串口时安装)。 + + **Windows环境安装** + + 下载并安装haneWIN NFS Server1.2.50,地址:https://www.hanewin.net/nfs-e.htm + + **Linux环境下安装** + + ``` + sudo apt install nfs-kernel-server + ``` + + 所有环境配置安装完成,即可在IDE中进行测试平台代码开发调试,推荐的IDE为 DevEco Studio。 + + +### 检验环境是否搭建成功 + +**表 2** **检验环境** + + + + + + + + + + + + + + + + + + + + +

检查项

+

操作

+

满足条件

+

检查python安装与否,版本是否满足要求。

+

命令行窗口执行命令:python --version。

+

版本不小于3.7.5即可。

+

检查python扩展插件安装与否。

+

打开test/xdevice目录,执行run.bat或run.sh。

+

可进入提示符“>>>”界面即可。

+

检查NFS Server启动状态(被测设备仅支持串口时检测)。

+

通过串口登录开发板,执行mount命令挂载NFS。

+

可正常挂载文件目录即可。

+
+ +## 开发指导 + +### 场景介绍 + +针对对开发的业务代码进行白盒测试验证。 + +### 接口说明 + +测试框架集成了开源的单元测试框架,并对测试用例的宏定义做了扩展,具体框架说明详见开源官方文档。 + +**表 3** 测试框架扩展宏定义说明 + + + + + + + + + + + + + + + + +

宏定义

+

描述

+

HWTEST

+

测试用例执行不依赖Setup&Teardown。HWTEST对TEST增加了“用例级别”参数“TestSize.Level1”,例如HWTEST(CalculatorAddTest, TestPoint_001, TestSize.Level1)。

+

HWTEST_F

+

测试用例(不带参数)执行依赖Setup&Teardown。HWTEST_F对TEST_F增加了“用例级别”参数“ TestSize.Level1”,例如HWTEST_F(CalculatorAddTest, TestPoint_001, TestSize.Level1)。

+

HWTEST_P

+

测试用例(带参数)执行依赖Setup&Teardown。HWTEST_P对TEST_P增加了“用例级别”参数“ TestSize.Level1”,例如HWTEST_P(CalculatorAddTest, TestPoint_001, TestSize.Level1)。

+
+ +### 开发步骤 + +1. 按照开发者测试用例目录规划定义测试套文件,需要继承testing::Test类,命名以被测特性+Test命名,示例代码路径:test/developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp + + ``` + /* + * Copyright (c) 2020 OpenHarmony. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include + + using namespace std; + using namespace testing::ext; + + class CalcSubtractionTest : public testing::Test { + public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + }; + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >测试用例规范 + >- 命名规范 + > 测试用例源文件名称和测试套内容保持一致,测试套与用例之间关系1:N,测试套与测试源文件之间关系1:1,每个源文件全局唯一,格式:\[特性\]\_\[功能\]\_\[子功能1\]\_\[子功能1.1\],子功能支持向下细分。 + > 文件命名采用全小写+下划线方式命名,以test结尾,如demo用例:developertest/examples/lite/cxx\_demo + >- 测试用例编码规范 + > 开发者测试用例原则上与特性代码编码规范保持一致,另外需要添加必要的用例描述信息,详见[•自测试用例模板](#li2069415903917)。 + >- 测试用例编译配置规范 + > 测试用例采用GN方式编译,配置遵循本开源项目的[编译指导](subsys-build-mini-lite.md)。 + >- 测试用例模板 + > 详见测试demo用例:developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp + +2. 实现测试套执行过程需要的预处理操作和后处理操作,即实现SetUp和TearDown方法。 + + ``` + void CalcSubtractionTest::SetUpTestCase(void) + { + // step 1: input testsuite setup step + } + + void CalcSubtractionTest::TearDownTestCase(void) + { + // step 2: input testsuite teardown step + } + + void CalcSubtractionTest::SetUp(void) + { + // step 3: input testcase setup step + } + + void CalcSubtractionTest::TearDown(void) + { + // step 4: input testcase teardown step + } + ``` + +3. 针对被测对象的特性编写测试用例,以使用HWTEST\_F为例说明。 + + ``` + /** + * @tc.name: integer_sub_001 + * @tc.desc: Test Calculator + * @tc.type: FUNC + * @tc.require: AR00000000 SR00000000 + */ + HWTEST_F(CalcSubtractionTest, integer_sub_001, TestSize.Level1) + { + EXPECT_EQ(0, Subtraction(1, 0)); + } + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >- @tc.name:用例名称,对测试目的简要描述。 + >- @tc.desc:描述用例详细描述,包括测试目的、测试步骤、期望结果等。 + >- @tc.type:测试属性分类(FUNC、PERF、SECU、RELI)。 + >- @tc.require:需求编号或者issue编号,用来将修改与用例关联。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

序号

+

测试类型名称

+

缩写

+

测试类型描述

+

1

+

功能测试(functionality)

+

FUNC

+

验证软件各个功能满足功能设计与规格。

+

2

+

性能测试(performance)

+

PERF

+

验证软件是否满足性能设计指标。包含负载测试容量测试,压力测试等。

+

3

+

安全性测试(security)

+

SECU

+

验证软件在生命周期内符合安全需求定义和相关法规。

+

4

+

可靠性测试(reliability)

+

RELI

+

在规定的条件下,在规定的时间内,软件不引起系统失效的概率,这里也包含稳定性。

+
+ +4. 编写用例编译GN文件,其中包括定义用例编译目标,添加编译配置依赖,源文件等,举例说明: + + 示例文件路径:test/developertest/examples/lite/cxx\_demo/test/unittest/common/BUILD.gn)。 + + ``` + import("//build/lite/config/test.gni") + + unittest("CalcSubTest") { + output_extension = "bin" + sources = [ + "calc_subtraction_test.cpp" + ] + include_dirs = [] + deps = [] + } + ``` + +5. 将用例编译目标添加到子系统编译配置中,保证用例随版本一起编译,举例说明: + 1. 支持hdc连接的设备,编译配置示例路径:test/developertest/examples/ohos.build。 + + ``` + { + "subsystem": "subsystem_examples", + "parts": { + "subsystem_examples": { + "module_list": [ + "//test/developertest/examples/detector:detector", + ... ... + ], + "test_list": [ + "//test/developertest/examples/detector/test:unittest", + ... ... + ] + }, + ... ... + } + ``` + + 2. 仅支持串口的设备,编译配置示例路径:test/developertest/examples/lite/BUILD.gn。 + + ``` + import("//build/lite/config/test.gni") + + subsystem_test("test") { + test_components = [] + if(ohos_kernel_type == "liteos_riscv") { + features += [ + ] + }else if(ohos_kernel_type == "liteos_a") { + test_components += [ + "//test/developertest/examples/lite/cxx_demo/test/unittest/common:CalcSubTest" + ] + } + } + ``` + + +6. 编写测试用例资源配置,当测试用例需要使用静态测试资源文件时使用该配置。 + 1. 在部件或者模块的test目录下创建resource目录。 + 2. 在resource目录下创建形态目录,如phone。 + 3. 在设备形态目录下创建一个以模块名命名的文件夹,如testmodule。 + 4. 在模块目录下创建一个ohos\_test.xml文件,文件内容格式如下: + + ``` + + + + + + + + ``` + + 5. 在测试用例的编译配置文件中定义resource\_config\_file,用来指定对应的资源文件ohos\_test.xml。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >如上资源文件功能:将resource目录下的test.txt文件通过hdc push命令推送到被测设备的/data/test/resource目录下。 + + +7. 以上步骤完成即完成测试用例编写,即可执行测试用例。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >- 支持hdc连接的设备,测试用例支持单独编译。 + >- 仅支持串口连接的设备,在代码根路径下执行编译debug版本的命令,即可编译测试用例。 + > 测试用例用例的执行详见[测试平台使用](#section76401945124810)。 + + +## 开发实例 + +测试子系统代码仓提供了完整demo用例,demo用例路径:test/developertest/examples/。以一个减法运算方法编写测试用例举例说明: + +- 被测代码如下: + + ``` + static int Subtraction(int a, int b) + { + return a - b; + } + ``` + +- 测试用例代码如下: + + ``` + /** + * @tc.name: integer_sub_002 + * @tc.desc: Verify the Subtraction function. + * @tc.type: FUNC + * @tc.require: AR00000000 SR00000000 + */ + HWTEST_F(CalcSubtractionTest, integer_sub_002, TestSize.Level1) + { + EXPECT_EQ(1, Subtraction(2, 1)); + } + ``` + + +## 测试平台使用 + +1. (可选)安装xdevice组件。安装xdevice后,xdevice组件可以作为python的扩展包使用。 + + 打开xdevice安装目录:test/xdevice,执行如下命令: + + ``` + python setup.py install + ``` + + 安装成功提示如下: + + ``` + ... ... + Installed d:\programs\python37\lib\site-packages\xdevice-0.0.0-py3.7.egg + Processing dependencies for xdevice==0.0.0 + Searching for pyserial==3.4 + Best match: pyserial 3.4 + Processing pyserial-3.4-py3.7.egg + pyserial 3.4 is already the active version in easy-install.pth + Installing miniterm.py script to D:\Programs\Python37\Scripts + + Using d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg + Finished processing dependencies for xdevice==0.0.0 + ``` + +2. 修改developertest/config/user\_config.xml 文件配置developertest组件。 + 1. 测试框架通用配置。 + + \[build\] \# 配置测试用例的编译参数,例如: + + ``` + + false + false + true + ... ... + + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >测试用例的编译参数说明如下: + >example:是否编译测试用例示例,默认false。 + >version:是否编译测试版本,默认false。 + >testcase:是否编译测试用例,默认true。 + + 2. 支持hdc连接的被测设备。 + + \[device\] \# 配置标签为usb-hdc的环境信息,测试设备的IP地址和hdc映射的端口号,例如: + + ``` + + 192.168.1.1 + 9111 + + + ``` + + 3. 仅支持串口的被测设备。 + + \[board\_info\] \# 开发板配置信息,例如: + + ``` + + hispark + taurus + ipcamera + hb build + + ``` + + >![](../public_sys-resources/icon-note.gif) **说明:** + >开发板配置信息如下: + >board\_series:开发板系列,默认hispark。 + >board\_type:开发板类型,默认taurus。 + >board\_product:目标产品,默认ipcamera。 + >build\_command:测试版本和用例的编译命令,默认hb build。 + + \[device\] \# 配置标签为ipcamera的串口信息,COM口和波特率,例如: + + ``` + + + COM1 + cmd + 115200 + 8 + 1 + 1 + + + ``` + + +3. (可选)修改developertest组件配置。如果测试用例已完成编译,可以直接指定测试用例的编译输出路径,测试平台执行用例时即不会重新编译测试用例。 + + 配置文件:config/user\_config.xml + + 1. \[test\_cases\] \# 指定测试用例的输出路径,编译输出目录,例如: + + ``` + + /home/opencode/out/release/tests + + ``` + + 2. \[NFS\] \# 被测设备仅支持串口时配置,指定NFS的映射路径,host\_dir为PC侧的NFS目录,board\_dir为板侧创建的目录,例如: + + ``` + + D:\nfs + user + + ``` + + +4. (可选)测试环境准备。当被测设备仅支持串口时,需要检查。 + - 系统镜像与文件系统已烧录进开发板,开发板上系统正常运行,在系统模式下,如使用shell登录时,设备提示符是“OHOS\#”。 + - 开发主机和开发板串口连接正常,网口连接正常。 + - 开发主机IP与开发板IP处在同一小网网段,相互可以ping通。 + - 开发主机侧创建空目录用于开发板通过NFS挂载测试用例,并且NFS服务启动正常。 + +5. (必选)启动测试平台,执行测试用例。 + - 启动测试框架,打开test/developertest目录,执行启动脚本。 + 1. Windows环境启动测试框架,执行如下脚本: + + ``` + start.bat + ``` + + 2. Linux环境启动测试框架。 + + ``` + ./start.sh + ``` + + + - 设备形态选择。 + + 根据实际的开发板选择,设备形态配置:developertest/config/framework\_config.xml。 + + - 执行测试指令。 + 1. 查询测试用例支持的子系统,模块,产品形态以及测试类型,使用show命令,示例如下: + + ``` + usage: + show productlist Querying Supported Product Forms + show typelist Querying the Supported Test Type + show subsystemlist Querying Supported Subsystems + show modulelist Querying Supported Modules + ``` + + 2. 执行测试指令,其中-t为必选,-ss和-tm为可选字段,示例如下: + + ``` + run -t ut -ss subsystem_examples -tm calculator + ``` + + 3. 参数说明:指定参数可以执行特定特性、模块对应的测试套。 + + ``` + usage: run [-h] [-p PRODUCTFORM] [-t [TESTTYPE [TESTTYPE ...]]] + [-ss SUBSYSTEM] [-tm TESTMODULE] [-ts TESTSUIT] + [-tc TESTCASE] [-tl TESTLEVEL] + + optional arguments: + -h, --help show this help message and exit + -p PRODUCTFORM, --productform PRODUCTFORM Specified product form + -t [TESTTYPE [TESTTYPE ...]], --testtype [TESTTYPE [TESTTYPE ...]] + Specify test type(UT,MST,ST,PERF,ALL) + -ss SUBSYSTEM, --subsystem SUBSYSTEM Specify test subsystem + -tm TESTMODULE, --testmodule TESTMODULE Specified test module + -ts TESTSUIT, --testsuite TESTSUIT Specify test suite + -tc TESTCASE, --testcase TESTCASE Specify test case + -tl TESTLEVEL, --testlevel TESTLEVEL Specify test level + ``` + + + - 测试框架帮助。 + + 帮助指令,用于查询测试平台支持哪些测试指令,如下: + + ``` + help + ``` + + - 退出自测试平台。 + + 退出自测试平台,使用如下命令退出测试平台,如下: + + ``` + quit + ``` + + +6. (必选)查看测试结果与日志,通过在测试平台中执行测试指令,即可在developertest/reports目录下生成测试日志和测试报告。 + - 测试用例的结果会直接显示在控制台上,执行一次的测试结果根路径如下: + + ``` + reports/xxxx-xx-xx-xx-xx-xx + ``` + + - 测试用例格式化结果目录如下: + + ``` + result/ + ``` + + - 测试用例日志目录如下: + + ``` + log/plan_log_xxxx-xx-xx-xx-xx-xx.log + ``` + + - 测试报告汇总: + + ``` + summary_report.html + ``` + + - 测试报告详情: + + ``` + details_report.html + ``` + + + - 测试平台日志目录如下: + + ``` + reports/platform_log_xxxx-xx-xx-xx-xx-xx.log + ``` + + + +## 包结构说明 + +开发者测试平台xdevice组件包结构说明,代码目录test/xdevice,详见下表所示: + +**表 4** xdevice组件包结构说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

功能描述

+

xdevice

+

测试平台基础组件。

+

xdevice/src/xdevice

+

基础测试框架源码。

+

xdevice/config

+

基础测试框架配置文件定义。

+

xdevice/src/xdevice/__main__.py

+

基础测试框架内部入口。

+

xdevice/src/xdevice/__init__.py

+

包依赖定义,插件依赖。

+

xdevice/src/xdevice/variables.py

+

全局变量定义。

+

xdevice/src/xdevice/_core/command

+

用例输入的命令行处理。

+

xdevice/src/xdevice/_core/config

+

基础测试框架的配置管理。

+

xdevice/src/xdevice/_core/environment

+

基础测试框架的环境管理,包括设备管理。

+

xdevice/src/xdevice/_core/executor

+

基础测试框架用例调度和分发。

+

xdevice/src/xdevice/_core/driver

+

基础测试框架测试执行器。

+

xdevice/src/xdevice/_core/resource

+

基础测试框架资源文件以及测试报告模板。

+

xdevice/src/xdevice/_core/testkit

+

基础测试框架公共操作,包括NFS文件系统挂载等。

+

xdevice/src/xdevice/_core/logger.py

+

基础测试框架日志管理。

+

xdevice/src/xdevice/_core/plugin.py

+

基础测试框架插件管理。

+

xdevice/src/xdevice/_core/interface.py

+

基础测试框架插件接口定义。

+

xdevice/setup.py

+

基础测试框架的安装脚本。

+

xdevice/run.bat

+

基础测试框架启动脚本(Windows)。

+

xdevice/run.sh

+

基础测试框架启动脚本(Linux)。

+
+ +开发者测试平台developertest组件包结构说明,代码目录test/developertest,详见下表所示: + +**表 5** developertest组件包结构说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

developertest

+

开发测试框架。

+

developertest/src

+

测试框架源码。

+

developertest/src/core

+

测试执行器。

+

developertest/src/core/build

+

测试用例编译。

+

developertest/src/core/command

+

对用户输入的命令行处理。

+

developertest/src/core/config

+

测试框架配置管理。

+

developertest/src/core/driver

+

测试框架驱动执行器。

+

developertest/src/core/resource

+

测试框架配置文件。

+

developertest/src/core/testcase

+

测试用例管理。

+

developertest/src/core/common.py

+

测试框架公共操作。

+

developertest/src/core/constants.py

+

测试框架全局常量。

+

developertest/src/core/exception.py

+

测试框架异常定义。

+

developertest/src/core/utils.py

+

测试框架工具方法。

+

developertest/src/main

+

测试框架平台。

+

developertest/src/main/__main__.py

+

测试框架内部入口。

+

developertest/examples

+

测试框架demo用例。

+

developertest/third_party

+

测试框架依赖第三方组件适配。

+

developertest/BUILD.gn

+

测试子系统编译配置。

+

developertest/start.bat

+

开发者测试入口(Windows)。

+

developertest/start.sh

+

开发者测试入口(Linux)。

+
+ diff --git a/zh-cn/device-dev/subsystems/subsys-toolchain-bytrace-guide.md b/zh-cn/device-dev/subsystems/subsys-toolchain-bytrace-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..2c443396aca58e31aa099a8de06db028781c7fdd --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-toolchain-bytrace-guide.md @@ -0,0 +1,115 @@ +# bytrace使用指导 + +- [简介](#section11388623181619) +- [开发指导](#section1595564317164) +- [使用实例](#section667273201818) + +## 简介 + +bytrace是开发人员用于追踪进程轨迹、分析性能的一种工具,主要对内核ftrace进行了封装和扩展,来支持用户态的打点。通过该工具可以打开想要查看的用户态和内核label(通过下面命令行bytrace -l,查看支持的所有label),然后通过命令行进行抓取trace信息到指定文件中。 + +## 开发指导 + +bytrace当前支持以下命令: + +**表 1** 命令行列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Option

+

Description

+

-h,--help

+

查看option帮助

+

-b n,--buffer_size n

+

指定n(KB)内存大小用于存取trace日志,默认2048KB

+

-t n,--time n

+

用来指定trace运行的时间(单位:s),取决于需要分析过程的时间

+

--trace_clock clock

+

trace输出的时钟类型,一般设备支持boot、global、mono、uptime、perf等,默认为boot

+

--trace_begin

+

启动抓trace

+

--trace_dump

+

将数据输出到指定位置(默认控制台)

+

--trace_finish

+

停止抓trace,并将数据输出到指定位置(默认控制台)

+

-l,--list_categories

+

输出手机能支持的trace模块

+

--overwrite

+

当缓冲区满的时候,将丢弃最新的信息。(默认丢弃最老的日志)

+

-o filename,--output filename

+

指定输出的目标文件名称

+

-z

+

抓取trace后进行压缩

+
+ +## 使用实例 + +以下是常用bytrace命令示例,供开发者参考: + +- 查询支持的label。 + +``` +bytrace -l +``` + +或者 + +``` +bytrace --list_categories +``` + +- 设置4M缓存,抓取10秒,抓取label为ability的trace信息。 + +``` +bytrace -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace +``` + +- 设置trace的输出时钟为mono。 + +``` +bytrace --trace_clock mono -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace +``` + +- 抓取trace后进行压缩。 + +``` +bytrace -z -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace +``` + diff --git a/zh-cn/device-dev/subsystems/subsys-toolchain-hdc-guide.md b/zh-cn/device-dev/subsystems/subsys-toolchain-hdc-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..93b765389398c04173ff43ab84aa32cf4eff038c --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-toolchain-hdc-guide.md @@ -0,0 +1,685 @@ +# hdc\_std 使用指导 + +- [环境准备](#section05992022154916) +- [注意事项](#section19543134915210) +- [option相关的命令](#section618522925119) +- [查询设备列表的命令](#section174891132104218) +- [服务进程相关命令](#section680531510497) +- [网络相关的命令](#section71176123212) +- [文件相关的命令](#section173133523013) +- [应用相关的命令](#section2072647133819) +- [调试相关的命令](#section112861250195015) +- [常见问题](#section592920255582) + - [hdc\_std连接不到设备](#section74019384588) + - [hdc\_std运行不了](#section63291491267) + + +hdc\_std(OpenHarmony Device Connector)是OpenHarmony为开发人员提供的用于调试的命令行工具,通过该工具可以在Windows/Linux等系统上与开发机或者模拟器进行交互。 + +下文将介绍hdc\_std的环境准备和常用命令及使用举例。 + +## 环境准备 + +**hdc\_std 工具获取方式:** + +从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 + +**使用举例:** + +下面以windows侧使用方式举例: + +从prebuilt/windows侧获取可执行文件hdc\_std.exe,放到磁盘某个位置即可使用。 + +## 注意事项 + +- 使用hdc\_std,如果出现异常,可以尝试通过hdc\_std kill命令杀掉hdc\_std服务,或者通过hdc\_std start -r命令重启服务进程进行解决。 +- 如果出现hdc\_std list targets获取不到设备信息,通过任务管理器查看是否有hdc.exe进程存在,如果进程存在,可以通过杀掉该进程进行解决。 + +## option相关的命令 + +option涉及以下命令: + +**-h/help -v/version** + +用于显示hdc相关的帮助、版本信息。 + +**表 1** 命令说明 + + + + + + + + + +

返回值

+

返回值说明

+

返回对应信息

+

帮助或者版本信息

+
+ +使用方法: + +hdc\_std -h / hdc\_std help + +hdc\_std -v / hdc\_std version + +**-t key** + +用于连接指定设备标识为key的设备。 + +**表 2** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

key

+

为tcp:port格式,或者USB序列号

+

返回值

+

返回值说明

+

①error: device '***' not found

+

②Nothing to do...

+

①设备不存在

+

②附加的命令不存在

+
+ +使用方法: + +该option需要与具体的操作命令搭配使用,下面以shell命令举例: + +hdc\_std list targets (获取设备信息) + +hdc\_std -t _key_ shell (-t后面添加的_key_ 需要替换为上面查询的设备信息) + +>![](../public_sys-resources/icon-note.gif) **说明:** +>一台开发机可支持多个设备连接,每个设备有其唯一的设备标识,如果通过网络与设备连接,其标识为tcp:port格式,如果通过usb连接则标识为设备sn号。该命令需要跟随具体操作命令。 + +## 查询设备列表的命令 + +查询设备列表涉及以下命令: + +**list targets\[-v\]** + +显示所有已经连接的目标设备列表 + +**表 3** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

-v

+

添加-v选项,则会打印设备详细信息

+

返回值

+

返回值说明

+

①返回设备信息

+

②[Empty]

+

①已经连接的设备列表信息

+

②没有查询到设备信息

+
+ +使用方法: + +hdc\_std list targets + +hdc\_std list targets -v + +## 服务进程相关命令 + +服务进程涉及以下命令: + +**target mount** + +以读写模式挂载/system等分区。 + +**表 4** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

+

+

返回值

+

返回值说明

+

①Mount finish

+

②返回具体信息

+

①成功情况下返回的信息

+

②失败情况下的具体信息

+
+ +使用方法: + +hdc\_std target mount + +**smode \[off\]** + +授予后台服务进程root权限, 使用off参数取消授权。 + +使用方法: + +hdc\_std smode + +hdc\_std smode off + +**kill \[-r\]** + +终止服务进程。 + +**表 5** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

-r

+

触发服务重启

+

返回值

+

返回值说明

+

①Kill server finish

+

②返回具体信息

+

①成功情况下返回的信息

+

②失败情况下的具体信息

+
+ +使用方法: + +hdc\_std kill + +**start \[-r\]** + +启动服务进程。 + +**表 6** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

-r

+

如果服务进程已经启动,-r选项会触发服务进程重新启动

+

返回值

+

返回值说明

+

+

+
+ +使用方法: + +hdc\_std start + +## 网络相关的命令 + +网络部分涉及以下命令: + +**tconn host\[:port\]\[-remove\]** + +通过【ip地址:端口号】来指定连接的设备 + +**表 7** 命令说明 + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

host[:port]

+

为tcp:port格式

+

-remove

+

表示断开与指定设备的连接

+

返回值

+

返回值说明

+

①返回具体信息

+

②无

+

①失败情况下的具体信息

+

②成功情况下无返回值

+
+ +使用方法(举例): + +hdc\_std tconn 192.168.0.100:8710 + +**tmode usb** + +执行后设备端对应daemon进程重启,并首先选用usb连接方式。 + +**表 8** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

+

+

返回值

+

返回值说明

+

①返回具体信息

+

②无

+

①失败情况下的具体信息

+

②成功情况下无返回值

+
+ +使用方法: + +hdc\_std tmode usb + +**tmode port port-number** + +执行后设备端对应daemon进程重启,并优先使用网络方式连接设备,如果连接设备再选择usb连接。 + +**表 9** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

port-number

+

listen连接的网络端口

+

返回值

+

返回值说明

+

①返回具体信息

+

②无

+

①失败情况下的具体信息

+

②成功情况下无返回值

+
+ +使用方法: + +hdc\_std tmode port 8710 + +>![](../public_sys-resources/icon-note.gif) **说明:** +>执行完毕后,远端daemon将会退出并重启,默认启用TCP连接,如果不加上listen端口则listen随机端口。 + +## 文件相关的命令 + +文件部分涉及以下命令: + +**file send local remote** + +发送文件至远端设备。 + +**表 10** 命令说明 + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

local

+

本地待发送文件路径

+

remote

+

远程待接收文件路径

+

返回值

+

返回值说明

+

①返回具体信息

+

②返回传输结果

+

①失败情况下的具体信息

+

②成功传输的结果信息

+
+ +使用方法(举例): + +hdc\_std file send E:\\a.txt /data/local/tmp/a.txt + +**file recv \[-a\] remote local** + +从远端设备接收文件至本地。 + +**表 11** 命令说明 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

-a

+

文件保留时间戳模式

+

local

+

本地待接收文件路径

+

remote

+

远程待发送文件路径

+

返回值

+

返回值说明

+

①返回具体信息

+

②无

+

①失败情况下的具体信息

+

②成功情况下无返回值

+
+ +使用方法(举例): + +hdc\_std file recv /data/local/tmp/a.txt ./a.txt + +## 应用相关的命令 + +应用部分涉及以下命令: + +**install \[-r/-d/-g\] _package_** + +安装OpenHarmony package。 + +**表 12** 命令说明 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

package

+

OpenHarmony应用安装包

+

-r

+

替换已存在应用

+

-d

+

允许降级安装

+

-g

+

动态授权

+

返回值

+

返回值说明

+

①返回具体信息

+

②无

+

①失败情况下的具体信息

+

②成功情况下无返回值

+
+ +使用方法(举例): + +hdc\_std install _hwadmin.hap_ + +**uninstall \[-k\] package** + +卸载OpenHarmony应用。 + +**表 13** 命令说明 + + + + + + + + + + + + + + + + + + +

参数

+

参数说明

+

package

+

OpenHarmony应用安装包

+

-k

+

保留/data/cache

+

返回值

+

返回值说明

+

①返回具体信息

+

②无

+

①失败情况下的具体信息

+

②成功情况下无返回值

+
+ +使用方法(举例): + +hdc\_std uninstall _package_ + +## 调试相关的命令 + +调试涉及以下命令: + +**hilog** + +支持抓取log信息。 + +**表 14** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

+

+

返回值

+

返回值说明

+

返回具体信息

+

抓取的日志信息

+
+ +使用方法: + +hdc\_std hilog + +**shell \[_command_\]** + +远程执行命令或进入交互命令环境。 + +**表 15** 命令说明 + + + + + + + + + + + + + + + +

参数

+

参数说明

+

command

+

需要执行的单次命令

+

返回值

+

返回值说明

+

返回具体信息

+

shell后面执行命令的结果信息

+
+ +使用方法: + +hdc\_std shell + +## 常见问题 + +### hdc\_std连接不到设备 + +- **现象描述** + + 执行 "hdc\_std list targets"命令后结果为:\[Empty\] + +- **解决方法** + 1. 设备没有被识别: + + 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 + + 2. hdc\_std工作异常: + + 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 + + 3. hdc\_std与设备不匹配: + + 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 + + + +### hdc\_std运行不了 + +- **现象描述** + + 点击hdc\_std.exe文件无法运行。 + +- **解决方法** + + hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 + + diff --git a/zh-cn/device-dev/subsystems/subsys-toolchain.md b/zh-cn/device-dev/subsystems/subsys-toolchain.md new file mode 100644 index 0000000000000000000000000000000000000000..fcf4e3ed14c0ce6975b04b70d0e9a0bd9c21f06e --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-toolchain.md @@ -0,0 +1,6 @@ +# 研发工具链 + +- [bytrace使用指导](subsys-toolchain-bytrace-guide.md) +- [hdc\_std 使用指导](subsys-toolchain-hdc-guide.md) + + diff --git "a/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200\345\272\223\345\270\270\350\247\201\351\227\256\351\242\230.md" b/zh-cn/device-dev/subsystems/subsys-utils-faqs.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200\345\272\223\345\270\270\350\247\201\351\227\256\351\242\230.md" rename to zh-cn/device-dev/subsystems/subsys-utils-faqs.md diff --git a/zh-cn/device-dev/subsystems/subsys-utils-guide.md b/zh-cn/device-dev/subsystems/subsys-utils-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..1cabae57341e29c31a2ebf0b47e670e438f27444 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-utils-guide.md @@ -0,0 +1,298 @@ +# 公共基础库开发指导 + +- [接口说明](#section1633115419401) +- [开发步骤](#section17450172710292) + - [LiteOS-A内核\(Hi3516、Hi3518平台\)KV存储的native应用开发步骤:](#section258354119295) + - [Dump系统属性在LiteOS-M内核平台使用指南:](#section9179161863014) + - [Dump系统属性在LiteOS-A内核平台使用指南:](#section3179121853017) + + +## 接口说明 + +**表 1** 文件操作接口说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口名

+

描述

+

int UtilsFileOpen(const char* path, int oflag, int mode)

+

打开或创建文件

+

int UtilsFileClose(int fd)

+

关闭文件

+

int UtilsFileRead(int fd, char *buf, unsigned int len)

+

读取特定长度的文件数据

+

int UtilsFileWrite(int fd, const char *buf, unsigned int len)

+

向文件写入特定大小的数据

+

int UtilsFileDelete(const char *path)

+

删除指定文件

+

int UtilsFileStat(const char *path, unsigned int *fileSize)

+

获取文件大小

+

int UtilsFileSeek(int fd, int offset, unsigned int whence)

+

重新定位文件读/写偏移量

+

int UtilsFileCopy(const char* src, const char* dest)

+

将源文件复制一份并存储到目标文件

+

int UtilsFileMove(const char* src, const char* dest)

+

将源文件移动到指定目标文件

+
+ +文件操作使用示例: + +``` +// open && write +char fileName[] = "testfile"; +static const char def[] = "utils_file_operation implement."; +int fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0); +printf("file handle = %d\n", fd); +int ret = UtilsFileWrite(fd, def, strlen(def)); +printf("write ret = %d\n", ret); + +// seek +ret = UtilsFileSeek(fd, 5, SEEK_SET_FS); +printf("lseek ret = %d\n", ret); + +// read && close +char buf[64] = {0}; +int readLen = UtilsFileRead(fd, buf, 64); +ret = UtilsFileClose(fd); +printf("read len = %d : buf = %s\n", readLen, buf); + +// stat +int fileLen = 0; +ret = UtilsFileStat(fileName, &fileLen); +printf("file size = %d\n", fileLen); + +// delete +ret = UtilsFileDelete(fileName); +printf("delete ret = %d\n", ret); +``` + +**表 2** KV存储接口说明 + + + + + + + + + + + + + + + + +

接口名

+

描述

+

int UtilsGetValue(const char* key, char* value, unsigned int len)

+

提供给上层应用根据key获取对应数据项

+

int UtilsSetValue(const char* key, const char* value)

+

提供给上层应用用于存储/更新key对应数据项

+

int UtilsDeleteValue(const char* key)

+

提供给上层应用删除key对应数据项

+
+ +KV存储使用示例: + +``` +// set +char key[] = "rw.sys.version_100"; +char value[] = "Hello kv operation implement!"; +int ret = UtilsSetValue(key, value); +printf("UtilsSetValue set ret = %d\n", ret); + +// get +char temp[128] = {0}; +ret = UtilsGetValue(key, temp, 128); +printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); + +// delete +ret = UtilsDeleteValue(key); +printf("UtilsDeleteValue delete ret = %d\n", ret); +``` + + + + +
+ +## 开发步骤 + +### LiteOS-A内核\(Hi3516、Hi3518平台\)KV存储的native应用开发步骤: + +1. 基于AbilityKit开发KV存储的native应用。 + - 基于KV存储提供的接口编写用户程序,并编译出so(libLauncher.so)文件。 + + ``` + // set + char key[] = "rw.sys.version_100"; + char value[] = "Hello kv operation implement!"; + int ret = UtilsSetValue(key, value); + printf("UtilsSetValue set ret = %d\n", ret); + + // get + char temp[128] = {0}; + ret = UtilsGetValue(key, temp, 128); + printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); + + // delete + ret = UtilsDeleteValue(key); + printf("UtilsDeleteValue delete ret = %d\n", ret); + ``` + + - 编写config.json文件,内容如下: + + ``` + { + "app": { + "bundleName": "com.huawei.launcher", + "vendor": "huawei", + "version": { + "code": 1, + "name": "1.0" + } + }, + "deviceConfig": { + "default": { + "reqSdk": { + "compatible": "zsdk 1.0.0", + "target": "zsdk 1.0.1" + }, + "keepAlive": false + }, + "smartCamera": { + "reqSdk": { + "compatible": "zsdk 1.0.0", + "target": "zsdk 1.0.1" + }, + "keepAlive": false + } + }, + "module": { + "package": "com.huawei.launcher", + "name": ".MyHarmonyAbilityPackage", + "deviceType": [ + "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "Launcher", + "moduleType": "entry" + }, + "abilities": [{ + "name": "MainAbility", + "icon": "res/drawable/phone.png", + "label": "test app 1", + "launchType": "standard", + "type": "page" + }, + { + "name": "SecondAbility", + "icon": "res/drawable/phone.png", + "label": "test app 2", + "launchType": "standard", + "type": "page" + }, + { + "name": "ServiceAbility", + "icon": "res/drawable/phone.png", + "label": "test app 2", + "launchType": "standard", + "type": "service" + } + ] + } + } + ``` + + + - 生成hap包。 + + - 按照如下目录结构存放文件,res/drawable下面放置资源文件: + + ![](figure/unnaming.png) + + - 将上述文件打包生成zip包,修改后缀为.hap,例如Launcher.hap + + +2. 连接单板,通过串口向单板发送安装KV存储native应用的命令。 + + ``` + ./nfs/dev_tools/bin/bm install -p /nfs/Launcher.hap + ``` + +3. 通过串口向单板发送运行KV存储native应用的命令。 + + ``` + ./nfs/dev_tools/bin/aa start -p com.huawei.launcher -n ServiceAbility + ``` + + +### Dump系统属性在LiteOS-M内核平台使用指南: + +1. 连接单板,通过串口向单板发送AT+SYSPARA命令。 + + ``` + AT+SYSPARA + ``` + + **图 1** LiteOS-M平台dump系统属性输出 + ![](figure/LiteOS-M平台dump系统属性输出.png "LiteOS-M平台dump系统属性输出") + + +### Dump系统属性在LiteOS-A内核平台使用指南: + +1. 连接单板,运行bin路径下的os\_dump加参数--help,查看os\_dump使用指导。 + + ``` + ./bin/os_dump --help + ``` + +2. os\_dump加参数-l,查看当前系统有哪些模块支持获取属性。 + + ``` + ./bin/os_dump -l + ``` + +3. os\_dump加参数syspara,查看当前系统属性 + + ``` + ./bin/os_dump syspara + ``` + + **图 2** LiteOS-A平台dump系统属性输出 + ![](figure/LiteOS-A平台dump系统属性输出.png "LiteOS-A平台dump系统属性输出") + + diff --git "a/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200\345\272\223\346\246\202\350\277\260.md" b/zh-cn/device-dev/subsystems/subsys-utils-overview.md old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200\345\272\223\346\246\202\350\277\260.md" rename to zh-cn/device-dev/subsystems/subsys-utils-overview.md diff --git a/zh-cn/device-dev/subsystems/subsys-utils.md b/zh-cn/device-dev/subsystems/subsys-utils.md new file mode 100644 index 0000000000000000000000000000000000000000..28a5d910c2862796d71aba1463dda945b1a5e64f --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-utils.md @@ -0,0 +1,9 @@ +# 公共基础 + +- **[公共基础库概述](subsys-utils-overview.md)** + +- **[公共基础库开发指导](subsys-utils-guide.md)** + +- **[公共基础库常见问题](subsys-utils-faqs.md)** + + diff --git a/zh-cn/device-dev/subsystems/subsys-xts-guide.md b/zh-cn/device-dev/subsystems/subsys-xts-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..1240c60b9d64b230d4415ddf74c37477f57b27ed --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys-xts-guide.md @@ -0,0 +1,715 @@ +# XTS认证子系统开发指南 + +- [简介](#section465982318513) +- [系统类型](#section125090457443) +- [目录](#section161941989596) +- [约束](#section119744591305) +- [使用说明](#section137768191623) +- [用例开发指导](#section3695134065513) + - [C语言用例开发编译指导(适用于轻量系统产品用例开发)](#section198193336544) + - [C语言用例执行指导(适用于轻量系统产品用例开发)](#section13820233175418) + - [C++语言用例开发编译指导(适用于小型系统、标准系统用例开发)](#section3822123311540) + - [C++语言用例执行指导(适用于小型系统、标准系统用例开发)](#section128222336544) + - [JS语言用例开发指导(适用于标准系统)](#section159801435165220) + - [JS语言用例编译打包指导(适用于标准系统)](#section445519106559) + - [\#ZH-CN\_TOPIC\_0000001126156429/section191521423950](#section191521423950) + +- [全量编译指导(适用于标准系统)](#section1519992743415) +- [全量用例执行指导(适用于小型系统、标准系统)](#section118149111426) + +## 简介 + +XTS子系统是OpenHarmony生态认证测试套件的集合,当前包括acts(application compatibility test suite)应用兼容性测试套件,后续会拓展dcts(device compatibility test suite)设备兼容性测试套件等。 + +XTS子系统当前包括acts与tools软件包: + +- acts,存放acts相关测试用例源码与配置文件,其目的是帮助终端设备厂商尽早发现软件与OpenHarmony的不兼容性,确保软件在整个开发过程中满足OpenHarmony的兼容性要求。 +- tools,存放acts相关测试用例开发框架。 + +## 系统类型 + +OpenHarmony支持如下几种系统类型: + +- 轻量系统(mini system) + + 面向MCU类处理器例如Arm Cortex-M、RISC-V 32位的设备,硬件资源极其有限,支持的设备最小内存为128KiB,可以提供多种轻量级网络协议,轻量级的图形框架,以及丰富的IOT总线读写部件等。可支撑的产品如智能家居领域的连接类模组、传感器设备、穿戴类设备等。 + +- 小型系统(small system) + + 面向应用处理器例如Arm Cortex-A的设备,支持的设备最小内存为1MiB,可以提供更高的安全能力、标准的图形框架、视频编解码的多媒体能力。可支撑的产品如智能家居领域的IP Camera、电子猫眼、路由器以及智慧出行域的行车记录仪等。 + +- 标准系统(standard system) + + 面向应用处理器例如Arm Cortex-A的设备,支持的设备最小内存为128MiB,可以提供增强的交互能力、3D GPU以及硬件合成能力、更多控件以及动效更丰富的图形能力、完整的应用框架。可支撑的产品如高端的冰箱显示屏。 + + +## 目录 + +``` +/test/xts +├── acts # 测试代码存放目录 +│ └── subsystem # 标准系统子系统测试用例源码存放目录 +│ └── subsystem_lite # 轻量系统、小型系统子系统测试用例源码存放目录 +│ └── BUILD.gn # 标准系统测试用例编译配置 +│ └── build_lite # 轻量系统、小型系统测试用例编译配置存放目录 +│ └── BUILD.gn # 轻量系统、小型系统测试用例编译配置 +└── tools # 测试工具代码存放目录 +``` + +## 约束 + +轻量系统用例开发语言是C,小型系统用例开发语言是C++。 + +## 使用说明 + +**表 1** 用例级别说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

级别名称

+

基本定义

+

测试范围

+

Level0

+

冒烟

+

验证关键功能点基本功能/最基本DFX属性在最常见输入下的表现,通过表示功能基本可运行。

+

Level1

+

基本

+

验证各功能点基本功能/基本DFX属性在常见输入下的表现,通过表示功能基本可测试。

+

Level2

+

重要

+

验证各功能点的基本功能/基本DFX属性在常规输入/常见异常情况下的表现,通过表示功能基本正常可用,可开展Beta。

+

Level3

+

一般

+

验证各功能点的全部功能/全部DFX属性在各种常规/非常规输入组合下,或各种正常/异常预置条件组合下的表现。

+

Level4

+

生僻

+

验证关键功能点在极端异常预置条件下、用户难以触及的异常输入组合下的表现。

+
+ +**表 2** 用例粒度说明 + + + + + + + + + + + + + + + + + + + + +

用例规模

+

被测试对象

+

测试环境

+

LargeTest

+

业务功能/全场景特性/整机及场景级DFX

+

尽量使用贴近真实的环境设备

+

MediumTest

+

模块/子系统集成至设备后的功能/DFX

+

使用真实的单设备进行验证,可进行消息模拟,尽量不对函数进行MOCK

+

SmallTest

+

模块/类/函数

+

在开发者个人环境进行测试,尽量不依赖其他模块,存在大量的MOCK

+
+ +**表 3** 测试类型说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

测试类型名称

+

测试类型定义

+

Function

+

验证被测对象提供给用户的业务功能实现正确性的测试项,这里的“用户”可以是终端用户或开发者,功能包括业务功能及平台功能

+

Performance

+

验证被测对象在特定预置条件/负载模型下的处理能力的测试项,“处理能力”一般以单位时间内可处理的业务量来衡量,如呼叫/秒,帧率/秒,事件处理量/秒等

+

Power

+

验证被测对象在特定预置条件/负载模型下在一定时间内能源消耗量的测试项

+

Reliability

+

验证被测对象在正常/异常输入情况下,或业务量压力和长时间连续运行压力情况下业务表现的测试项,含稳定性、压力、故障注入、Monkey测试项

+

Security

+

验证系统对恶意威胁的防护能力,威胁包括但不限于未授权访问、使用、泄露、破坏、修改、毁灭,以保障信息的机密性、完整性和可用性; 验证系统对用户隐私的保护能力,保障用户的隐私数据被收集、使用、保有、披露和处置符合法律规范,保障用户的隐私权; 验证对各类安全规范的遵从情况,如安全设计规范、安全红线、工信部安全认证规范等,保障安全相关法律法规的合规。

+

Global

+

验证被测对象在是否具有国际化数据支持和本地化能力的测试项,包括语言显示、输入/输出习惯、时间显示、区域特性如货币时间禁忌等等

+

Compatibility

+

当被测对象为应用时,包括被测对象对于自身数据的后向兼容性、对于系统的前后向兼容性、对于不同用户数据(如播放器之音频文件格式/智能短信之用户短信内容)的兼容性测试项; 当被测对象为系统时,包括被测系统对于系统自身数据的后向兼容性、以及对于生态中常用应用的兼容性测试项;当被测对象为软件时,包括被测系统对于相关的硬件的兼容性;

+

User

+

验证被测对象在真实用户场景下的用户体验感受的测试项,注意此种情况下没有客观的“正确”与“失败”,所有的结论及评价都应该来自于用户

+

Standard

+

验证被测对象对于行业及公司内标准/协议/规范的遵从情况的测试项,注意此处的“标准”不包含任何安全标准,针对安全标准的测试项划归为“安全测试”类型

+

Safety

+

验证被测对象的Safety属性,避免产品可能对人身安全、健康以及产品本身带来的危害。

+

Resilience

+

验证被测对象的韧性属性,确保系统受攻击时承受并保持在有定义的运行状态(包括降级)、恢复并适应攻击以保障Mission达成。

+
+ +## 用例开发指导 + +根据测试系统选择测试框架和对应测试用例语言。 + +**表 4** 系统和测试框架、开发语言对应关系 + + + + + + + + + + + + + + + + + + + + +

系统

+

测试框架

+

语言

+

轻量系统

+

hctest

+

c

+

小型系统

+

hcpptest

+

c++

+

标准系统

+

HJSUnit、hcpptest

+

js、c++

+
+ +### C语言用例开发编译指导(适用于轻量系统产品用例开发) + +**示例:轻量系统测试用例开发** + +当前使用的测试框架是hctest,hctest测试框架支持使用C语言编写测试用例,是在开源测试框架unity的基础上进行增强和适配。 + +1. 用例目录规范:测试用例存储到test/xts/acts仓中 + + ``` + ├── acts + │ └──subsystem_lite + │ │ └── module_hal + │ │ │ └── BUILD.gn + │ │ │ └── src + │ └──build_lite + │ │ └── BUILD.gn + ``` + +2. src目录下用例编写样例。 + + 1.引用测试框架 + + ``` + #include "hctest.h" + ``` + + 2. 使用宏定义LITE\_TEST\_SUIT定义子系统、模块、测试套件名称 + + ``` + /** + * @brief register a test suit named "IntTestSuite" + * @param test subsystem name + * @param example module name + * @param IntTestSuite test suit name + */ + LITE_TEST_SUIT(test, example, IntTestSuite); + ``` + + 3. 定义Setup与TearDown + + 命名方式:测试套件名称+Setup,测试套件名称+TearDown。 + + Setup与TearDown必须存在,可以为空函数。 + + 4. 使用宏定义LITE\_TEST\_CASE写测试用例 + + 包括三个参数:测试套件名称,测试用例名称,用例属性(测试类型、用例粒度、用例级别)。 + + ``` + LITE_TEST_CASE(IntTestSuite, TestCase001, Function | MediumTest | Level1) + { + //do something + }; + ``` + + 5. 使用宏定义 RUN\_TEST\_SUITE注册测试套件 + + ``` + RUN_TEST_SUITE(IntTestSuite); + ``` + +3. 测试模块的配置文件(BUILD.gn)样例: + + 在每个测试模块目录下新建BUILD.gn编译文件,用于指定编译后静态库的名称、依赖的头文件、依赖的库等;具体写法如下: + + ``` + import("//test/xts/tools/lite/build/suite_lite.gni") + hctest_suite("ActsDemoTest") { + suite_name = "acts" + sources = [ + "src/test_demo.c", + ] + include_dirs = [ ] + cflags = [ "-Wno-error" ] + } + ``` + +4. acts下BUILD.gn增加编译选项。 + + 需要将测试模块加入到acts目录下的编译脚本中,编译脚本路径:test/xts/acts/build\_lite/BUILD.gn。 + + ``` + lite_component("acts") { + ... + if(board_name == "liteos_m") { + features += [ + ... + "//xts/acts/subsystem_lite/module_hal:ActsDemoTest" + ] + } + } + ``` + +5. 测试套件编译命令。 + + 随版本编译,debug版本编译时会同步编译acts测试套件 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >acts测试套件编译中间件为静态库,最终链接到版本镜像中 。 + + +### C语言用例执行指导(适用于轻量系统产品用例开发) + +**示例:轻量系统测试用例执行** + +将版本镜像烧录进开发板。 + +**测试步骤** + +1. 使用串口工具登录开发板,并保存串口打印信息。 +2. 重启设备,查看串口日志。 + +**测试结果分析指导** + +基于串口打印日志进行分析; + +每个测试套件执行以Start to run test suite开始,以xx Tests xx Failures xx Ignored结束。 + +### C++语言用例开发编译指导(适用于小型系统、标准系统用例开发) + +**示例:小型系统测试用例开发**(标准参考具体样例目录:global/i18n\_standard) + +当前使用的测试框架是hcpptest,hcpptest测试框架是在开源的googletest测试框架的基础上进行的增强和适配。 + +1. 规范用例目录:测试用例存储到test/xts/acts仓中。 + + ``` + ├── acts + │ └──subsystem_lite + │ │ └── module_posix + │ │ │ └── BUILD.gn + │ │ │ └── src + │ └──build_lite + │ │ └── BUILD.gn + ``` + +2. 测试模块src下用例编写样例: + + 1. 引用测试框架: + + 需要引用gtest.h 如:\#include "gtest/gtest.h" + + ``` + #include "gtest/gtest.h" + ``` + + 2. 定义Setup与TearDown + + ``` + using namespace std; + using namespace testing::ext; + class TestSuite: public testing::Test { + protected: + // Preset action of the test suite, which is executed before the first test case + static void SetUpTestCase(void){ + } + // Test suite cleanup action, which is executed after the last test case + static void TearDownTestCase(void){ + } + // Preset action of the test case + virtual void SetUp() + { + } + // Cleanup action of the test case + virtual void TearDown() + { + } + }; + ``` + + 3. 使用宏定义HWTEST或HWTEST\_F写测试用例 + + 普通测试用例的定义:HWTEST(测试套名称, 测试用例名称, 用例标注)。 + + 包含SetUp和TearDown的测试用例的定义 :HWTEST\_F(测试套名称, 测试用例名称,用例标注)。 + + 宏定义包括三个参数:测试套件名称,测试用例名称,用例属性(测试类型、用例粒度、用例级别)。 + + ``` + HWTEST_F(TestSuite, TestCase_0001, Function | MediumTest | Level1) { + // do something + } + ``` + +3. 测试模块下用例配置文件(BUILD.gn)样例: + + 每个测试模块目录下新建BUILD.gn编译文件,用于指定编译后可执行文件的名称、依赖的头文件、依赖的库等;具体写法如下。每个测试模块将独立编译成.bin可执行文件, 该文件可直接push到单板上进行测试。 + + 举例: + + ``` + import("//test/xts/tools/lite/build/suite_lite.gni") + hcpptest_suite("ActsDemoTest") { + suite_name = "acts" + sources = [ + "src/TestDemo.cpp" + ] + + include_dirs = [ + "src", + ... + ] + deps = [ + ... + ] + cflags = [ "-Wno-error" ] + } + + ``` + +4. acts目录下增加编译选项(BUILD.gn)样例: + + 将测试模块加入到acts目录下的编译脚本中,编译脚本为:test/xts/acts/build\_lite/BUILD.gn。 + + ``` + lite_component("acts") { + ... + else if(board_name == "liteos_a") { + features += [ + ... + "//xts/acts/subsystem_lite/module_posix:ActsDemoTest" + ] + } + } + ``` + +5. 测试套件编译命令。 + + 随版本编译,debug版本编译时会同步编译acts测试套件 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >小型系统acts独立编译成可执行文件(bin格式), 在编译产物的suites\\acts目录下归档。 + + +### C++语言用例执行指导(适用于小型系统、标准系统用例开发) + +**示例:小型系统测试用例执行** + +目前的用例执行采用nfs共享的方式,mount到单板去执行。 + +**环境搭建** + +1. 使用有限网线或无线将开发板与PC进行连接。 +2. 开发板配置IP、子网掩码、网关,确保开发板与PC处于同一个网段。 +3. PC安装nfs服务器并完成注册,启动nfs服务。 +4. 开发板配置mount命令,确保开发板可以访问PC端的nfs共享文件。 + + 格式:mount \[nfs服务器IP\]:\[/nfs共享目录\] \[/开发板目录\] nfs + + 举例: + + ``` + mount 192.168.1.10:/nfs /nfs nfs + ``` + + +**用例执行** + +测试套件执行 ActsDemoTest.bin 触发用例执行,基于串口打印日志进行分析。 + +### JS语言用例开发指导(适用于标准系统) + +当前使用的测试框架是HJSUnit,用于支撑OpenHarmony application测试(特指基于JS应用框架使用 Javascript 语言开发的 APP)进行自动化测试。 + +**用例编写基础语法** + +测试用例为 js 语言,必须满足 JavaScript 语言编程规范: + +**表 5** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

用例语法

+

描述

+

要求

+

beforeAll

+

测试套级别的预置条件,在所有测试用例开始前执行且仅执行一次,支持一个参数:预置动作函数

+

可选

+

afterAll

+

测试套级别的清理条件,在所有测试用例结束后执行且仅执行一次,支持一个参数:清理动作函数

+

可选

+

beforeEach

+

测试用例级别的预置条件,在每条测试用例开始前执行,执行次数与 it 定义的测试用例数一致,支持一个参数:预置动作函数

+

可选

+

afterEach

+

测试用例级别的清理条件,在每条测试用例结束后执行,执行次数与 it 定义的测试用例数一致,支持一个参数:清理动作函数

+

可选

+

describe

+

定义一个测试套,支持两个参数:测试套名称和测试套函数; describe 支持嵌套,每个 describe 内均可以定义 beforeAll 、beforeEach 、afterEach 和 afterAll

+

必选

+

it

+

定义一条测试用例,支持三个参数:用例名称,过滤参数和用例函数

+

备注:

+

过滤参数:过滤参数为一个 32 位的 Int 类型参数,0 位 置1表示不筛选、默认执行;0-10 位 置1表示测试用例类型;16-18 位 置1表示测试用例规模;24-28 位 置1表示测试层级

+

测试用例类型。置位0-10分别表示:FUNCTION 方法类测试、PERFORMANCE 性能类测试、POWER 功耗类测试、RELIABILITY 可靠性测试、SECURITY 安全合规测试、GLOBAL 整体性测试、COMPATIBILITY 兼容性测试、USER 用户测试、STANDARD 标准测试、SAFETY 安全特性测试,RESILIENCE 压力测试。

+

测试用例规模。置位16-18分别表示:SMALL 小型测试、MEDIUM 中型测试、LARGE 大型测试。

+

测试层级。置位24-28分别表示:LEVEL0-0 级测试、LEVEL1-1 级测试、LEVEL2-2 级测试、LEVEL3-3 级测试、LEVEL4-4 级测试。

+

必选

+
+ +用例编写语法采用 jasmine 的标准语法,格式支持ES6格式。 + +1. 规范用例目录:测试用例存储到entry/src/main/js/test目录。 + + ``` + ├── BUILD.gn + │ └──entry + │ │ └──src + │ │ │ └──main + │ │ │ │ └──js + │ │ │ │ │ └──default + │ │ │ │ │ │ └──pages + │ │ │ │ │ │ │ └──index + │ │ │ │ │ │ │ │ └──index.js # 入口文件 + │ │ │ │ │ └──test # 测试代码存放目录 + │ │ │ └── resources # hap资源存放目录 + │ │ │ └── config.json # hap配置文件 + ``` + +2. index.js示例 + + ``` + // 拉起js测试框架,加载测试用例 + import {Core, ExpectExtend} from 'deccjsunit/index' + + export default { + data: { + title: "" + }, + onInit() { + this.title = this.$t('strings.world'); + }, + onShow() { + console.info('onShow finish') + const core = Core.getInstance() + const expectExtend = new ExpectExtend({ + 'id': 'extend' + }) + core.addService('expect', expectExtend) + core.init() + const configService = core.getDefaultService('config') + configService.setConfig(this) + require('../../../test/List.test') + core.execute() + }, + onReady() { + }, + } + ``` + +3. 单元测试用例示例 + + ``` + // Example1: 使用HJSUnit进行单元测试 + describe('appInfoTest', function () { + it('app_info_test_001', 0, function () { + var info = app.getInfo() + expect(info.versionName).assertEqual('1.0') + expect(info.versionCode).assertEqual('3') + }) + }) + ``` + + +### JS语言用例编译打包指导(适用于标准系统) + +hap包编译请参考[标准系统js应用开发指导](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201)。 + +## 全量编译指导(适用于标准系统) + +1. 全量编译 + + **命令**: + + ``` + ./build.sh suite=acts system_size=standard + ``` + + **测试用例输出目录**:out/release/suites/acts/testcases + + **测试框架&用例整体输出目录:**out/release/suites/acts(编译用例时会同步编译测试套执行框架) + + +## 全量用例执行指导(适用于小型系统、标准系统) + +**搭建测试环境** + +Windows工作台下安装python3.7及以上版本,确保工作台和测试设备正常连接。 + +**测试执行目录**(对应编译生成的out/release/suites/acts目录) + +``` +├── testcase # 测试套文件存放目录 +│ └──xxx.hap # 测试套可执行hap文件 +│ └──xxx.json # 测试套对应执行配置文件 +├── tools # 测试框架工具目录 +├── run.bat # window平台测试套启动执行文件 +├── report # 测试报告生成目录 +``` + +**用例执行** + +1. 在Windows工作台上,找到从Linux服务器上拷贝下来的测试套件用例目录\(对应编译生成的out/release/suites/acts目录\),在Windows命令窗口进入对应目录,直接执行acts\\run.bat。 + +1. 界面启动后,输入用例执行指令。 + + - 全量执行 + + ``` + run acts + ``` + + ![](figure/zh-cn_image_0000001119924146.gif) + + + - 模块执行\(具体模块可以查看\\acts\\testcases\\\) + + ``` + run –l ActsSamgrTest + ``` + + ![](figure/zh-cn_image_0000001166643927.jpg) + + + 等待执行完成。 + + +1. 查看测试报告。 + + 进入acts\\reports\\,获取当前的执行记录,打开“summary\_report.html”可以获取到测试报告。 + + diff --git a/zh-cn/device-dev/subsystems/subsys.md b/zh-cn/device-dev/subsystems/subsys.md new file mode 100644 index 0000000000000000000000000000000000000000..b301414e122da41764db79ca418a5d7a84c838a8 --- /dev/null +++ b/zh-cn/device-dev/subsystems/subsys.md @@ -0,0 +1,33 @@ +# 子系统开发指南 + +- **[编译构建](subsys-build.md)** + +- **[分布式远程启动](subsys-remote-start.md)** + +- **[图形图像](subsys-graphics.md)** + +- **[媒体](subsys-multimedia.md)** + +- **[公共基础](subsys-utils.md)** + +- **[AI框架](subsys-aiframework.md)** + +- **[Sensor服务](subsys-sensor.md)** + +- **[用户程序框架](subsys-application-framework.md)** + +- **[OTA升级](subsys-ota-guide.md)** + +- **[安全](subsys-security.md)** + +- **[启动恢复](subsys-boot.md)** + +- **[测试](subsys-testguide-test.md)** + +- **[DFX](subsys-dfx.md)** + +- **[HiSysEvent订阅指导](subsys-dfx-hisyseventread.md)** + +- **[XTS认证子系统开发指南](subsys-xts-guide.md)** + + diff --git "a/zh-cn/device-dev/subsystems/\344\273\243\347\240\201\347\256\241\347\220\206\350\247\204\350\214\203.md" "b/zh-cn/device-dev/subsystems/\344\273\243\347\240\201\347\256\241\347\220\206\350\247\204\350\214\203.md" deleted file mode 100755 index 25dde0bbc86164b4d7a0e2bec0e5b06b87d175dd..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\344\273\243\347\240\201\347\256\241\347\220\206\350\247\204\350\214\203.md" +++ /dev/null @@ -1,40 +0,0 @@ -# 代码管理规范 - -- [建议:插件与北向SDK在AI引擎指定的路径下进行代码开发](#section17176374131) -- [规则:插件提供的全部对外接口,统一存放在AI业务子系统interfaces/kits目录](#section2551029111312) -- [规则:插件编译输出路径必须是在/usr/lib](#section97021558121310) - -AI引擎框架包含client、server和common三个主要模块,其中client提供server端连接管理功能,北向SDK在算法对外接口中需封装调用client提供的公共接口;server提供插件加载以及任务管理等功能,各Plugin实现由server提供的插件接口,完成插件接入;common提供与平台相关的操作方法、引擎协议以及相关工具类,供其他各模块调用。 - -AI引擎框架各模块之间的代码依赖关系如下[图1](#fig171811112818)所示: - -**图 1** ****AI引擎代码依赖关系 - - -![](figures/插件依赖-(2).jpg) - -## 建议:插件与北向SDK在AI引擎指定的路径下进行代码开发 - -在AI引擎框架的整体规划中,北向SDK属于client端的一部分,插件由server端调用,属于server端的一部分,因此AI引擎框架为接入的插件与北向SDK规划的路径: - -- SDK代码路径://foundation/ai/engine/services/client/algorithm\_sdk - - e.g. //foundation/ai/engine/services/client/algorithm\_sdk/cv - - e.g. //foundation/ai/engine/services/client/algorithm\_sdk/nlu - -- 插件代码路径://foundation/ai/engine/services/server/plugin - - e.g. //foundation/ai/engine/services/server/plugin/cv - - e.g. //foundation/ai/engine/services/server/plugin/nlu - - -## 规则:插件提供的全部对外接口,统一存放在AI业务子系统interfaces/kits目录 - -北向SDK对外接口是AI业务子系统提供能力的对外暴露方式,按照OpenHarmony的接口管理要求,需统一存放在各子系统的interfaces/kits目录中。当前AI业务子系统插件对外接口路径为//foundation/ai/engine/interfaces/kits,不同插件可在该路径下添加目录,比如增加cv插件,则在路径//foundation/ai/engine/interfaces/kits/cv下面存放接口文件。 - -## 规则:插件编译输出路径必须是在/usr/lib - -server端加载插件是采用dlopen方式,只支持在/usr/lib路径进行,因此插件在编译so时,需要在编译配置文件中指定输出路径为/usr/lib。 - diff --git "a/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200.md" "b/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200.md" deleted file mode 100755 index 5a9dc698745f0ec1dc3c6dc9fa361f75740a940d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 公共基础 - -- **[公共基础库概述](公共基础库概述.md)** - -- **[公共基础库开发指导](公共基础库开发指导.md)** - -- **[公共基础库常见问题](公共基础库常见问题.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200\345\272\223\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200\345\272\223\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 38a64bb9ebb5b0e5fc669019b436fd68d03c4fce..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\205\254\345\205\261\345\237\272\347\241\200\345\272\223\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,298 +0,0 @@ -# 公共基础库开发指导 - -- [接口说明](#section1633115419401) -- [开发步骤](#section17450172710292) - - [LiteOS-A内核\(Hi3516、Hi3518平台\)KV存储的native应用开发步骤:](#section258354119295) - - [Dump系统属性在LiteOS-M内核平台使用指南:](#section9179161863014) - - [Dump系统属性在LiteOS-A内核平台使用指南:](#section3179121853017) - - -## 接口说明 - -**表 1** 文件操作接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

int UtilsFileOpen(const char* path, int oflag, int mode)

-

打开或创建文件

-

int UtilsFileClose(int fd)

-

关闭文件

-

int UtilsFileRead(int fd, char *buf, unsigned int len)

-

读取特定长度的文件数据

-

int UtilsFileWrite(int fd, const char *buf, unsigned int len)

-

向文件写入特定大小的数据

-

int UtilsFileDelete(const char *path)

-

删除指定文件

-

int UtilsFileStat(const char *path, unsigned int *fileSize)

-

获取文件大小

-

int UtilsFileSeek(int fd, int offset, unsigned int whence)

-

重新定位文件读/写偏移量

-

int UtilsFileCopy(const char* src, const char* dest)

-

将源文件复制一份并存储到目标文件

-

int UtilsFileMove(const char* src, const char* dest)

-

将源文件移动到指定目标文件

-
- -文件操作使用示例: - -``` -// open && write -char fileName[] = "testfile"; -static const char def[] = "utils_file_operation implement."; -int fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0); -printf("file handle = %d\n", fd); -int ret = UtilsFileWrite(fd, def, strlen(def)); -printf("write ret = %d\n", ret); - -// seek -ret = UtilsFileSeek(fd, 5, SEEK_SET_FS); -printf("lseek ret = %d\n", ret); - -// read && close -char buf[64] = {0}; -int readLen = UtilsFileRead(fd, buf, 64); -ret = UtilsFileClose(fd); -printf("read len = %d : buf = %s\n", readLen, buf); - -// stat -int fileLen = 0; -ret = UtilsFileStat(fileName, &fileLen); -printf("file size = %d\n", fileLen); - -// delete -ret = UtilsFileDelete(fileName); -printf("delete ret = %d\n", ret); -``` - -**表 2** KV存储接口说明 - - - - - - - - - - - - - - - - -

接口名

-

描述

-

int UtilsGetValue(const char* key, char* value, unsigned int len)

-

提供给上层应用根据key获取对应数据项

-

int UtilsSetValue(const char* key, const char* value)

-

提供给上层应用用于存储/更新key对应数据项

-

int UtilsDeleteValue(const char* key)

-

提供给上层应用删除key对应数据项

-
- -KV存储使用示例: - -``` -// set -char key[] = "rw.sys.version_100"; -char value[] = "Hello kv operation implement!"; -int ret = UtilsSetValue(key, value); -printf("UtilsSetValue set ret = %d\n", ret); - -// get -char temp[128] = {0}; -ret = UtilsGetValue(key, temp, 128); -printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); - -// delete -ret = UtilsDeleteValue(key); -printf("UtilsDeleteValue delete ret = %d\n", ret); -``` - - - - -
- -## 开发步骤 - -### LiteOS-A内核\(Hi3516、Hi3518平台\)KV存储的native应用开发步骤: - -1. 基于AbilityKit开发KV存储的native应用。 - - 基于KV存储提供的接口编写用户程序,并编译出so(libLauncher.so)文件。 - - ``` - // set - char key[] = "rw.sys.version_100"; - char value[] = "Hello kv operation implement!"; - int ret = UtilsSetValue(key, value); - printf("UtilsSetValue set ret = %d\n", ret); - - // get - char temp[128] = {0}; - ret = UtilsGetValue(key, temp, 128); - printf("UtilsGetValue get ret = %d, temp = %s\n", ret, temp); - - // delete - ret = UtilsDeleteValue(key); - printf("UtilsDeleteValue delete ret = %d\n", ret); - ``` - - - 编写config.json文件,内容如下: - - ``` - { - "app": { - "bundleName": "com.huawei.launcher", - "vendor": "huawei", - "version": { - "code": 1, - "name": "1.0" - } - }, - "deviceConfig": { - "default": { - "reqSdk": { - "compatible": "zsdk 1.0.0", - "target": "zsdk 1.0.1" - }, - "keepAlive": false - }, - "smartCamera": { - "reqSdk": { - "compatible": "zsdk 1.0.0", - "target": "zsdk 1.0.1" - }, - "keepAlive": false - } - }, - "module": { - "package": "com.huawei.launcher", - "name": ".MyHarmonyAbilityPackage", - "deviceType": [ - "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera" - ], - "distro": { - "deliveryWithInstall": true, - "moduleName": "Launcher", - "moduleType": "entry" - }, - "abilities": [{ - "name": "MainAbility", - "icon": "res/drawable/phone.png", - "label": "test app 1", - "launchType": "standard", - "type": "page" - }, - { - "name": "SecondAbility", - "icon": "res/drawable/phone.png", - "label": "test app 2", - "launchType": "standard", - "type": "page" - }, - { - "name": "ServiceAbility", - "icon": "res/drawable/phone.png", - "label": "test app 2", - "launchType": "standard", - "type": "service" - } - ] - } - } - ``` - - - - 生成hap包。 - - - 按照如下目录结构存放文件,res/drawable下面放置资源文件: - - ![](figures/unnaming.png) - - - 将上述文件打包生成zip包,修改后缀为.hap,例如Launcher.hap - - -2. 连接单板,通过串口向单板发送安装KV存储native应用的命令。 - - ``` - ./nfs/dev_tools/bin/bm install -p /nfs/Launcher.hap - ``` - -3. 通过串口向单板发送运行KV存储native应用的命令。 - - ``` - ./nfs/dev_tools/bin/aa start -p com.huawei.launcher -n ServiceAbility - ``` - - -### Dump系统属性在LiteOS-M内核平台使用指南: - -1. 连接单板,通过串口向单板发送AT+SYSPARA命令。 - - ``` - AT+SYSPARA - ``` - - **图 1** LiteOS-M平台dump系统属性输出 - ![](figures/LiteOS-M平台dump系统属性输出.png "LiteOS-M平台dump系统属性输出") - - -### Dump系统属性在LiteOS-A内核平台使用指南: - -1. 连接单板,运行bin路径下的os\_dump加参数--help,查看os\_dump使用指导。 - - ``` - ./bin/os_dump --help - ``` - -2. os\_dump加参数-l,查看当前系统有哪些模块支持获取属性。 - - ``` - ./bin/os_dump -l - ``` - -3. os\_dump加参数syspara,查看当前系统属性 - - ``` - ./bin/os_dump syspara - ``` - - **图 2** LiteOS-A平台dump系统属性输出 - ![](figures/LiteOS-A平台dump系统属性输出.png "LiteOS-A平台dump系统属性输出") - - diff --git "a/zh-cn/device-dev/subsystems/\345\212\250\347\224\273\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\212\250\347\224\273\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index e58aed68c06c7bda4fa8491a80f6ff68f0b720ce..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\212\250\347\224\273\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,190 +0,0 @@ -# 动画开发指导 - -- [使用场景](#section726685714018) -- [接口说明](#section85794718418) -- [开发步骤](#section14101161317435) - -## 使用场景 - -UI动画通过task处理机制每个tick调用一下用户设置的callback函数来实现,具体实现为AnimatorManager、Animator、AnimatorCallback三个类实现。 - -- AnimatorManager:AnimatorManager为单例,在Init函数执行时将自己注册到系统task回调函数中,系统task机制保证每个tick会调用一下AnimatorManager的callback函数,同时AnimatorManager用来管理Animator实例。 -- Animator:Animator中可以设置动画相关的属性,包括动画的起止时间,动画开始和停止,动画状态的设置和获取等。 -- AnimatorCallback:具体每一个tick动画所要做的内容在AnimatorCallback类中实现,开发者需要自己实现Callback方法,动画执行时在Callback实现相应功能。 - -## 接口说明 - -**表 1** 动画接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

子模块

-

方法

-

功能

-

Animator

-

void Start ()

-

动画开始

-

Animator

-

void Stop ()

-

动画停止

-

Animator

-

void Pause ()

-

动画暂停

-

Animator

-

void Resume ()

-

动画恢复

-

Animator

-

uint8_t GetState () const

-

获取动画当前状态

-

Animator

-

void SetState (uint8_t state)

-

设置动画当前状态

-

Animator

-

uint32_t GetTime () const

-

获取动画总持续时间

-

Animator

-

void SetTime (uint32_t time)

-

设置动画总持续时间

-

Animator

-

uint32_t GetRunTime () const

-

获取动画当前已经持续的时间

-

Animator

-

void SetRunTime (uint32_t runTime)

-

设置动画当前已经持续的时间

-

Animator

-

bool IsRepeat () const

-

获取动画是否循环播放

-

AnimatorCallback

-

virtual void Callback (UIView *view)=0

-

由用户实现,动画回调函数

-

AnimatorCallback

-

virtual void OnStop(UIView& view) {}

-

由用户实现,动画停止后的回调函数

-

AnimatorManager

-

static AnimatorManager* GetInstance()

-

获取AnimatorManager实例

-

AnimatorManager

-

void Add (Animator *animator)

-

添加动画

-

AnimatorManager

-

void Remove(const Animator* animator);

-

删除动画

-
- -## 开发步骤 - -1. 实现AnimatorCallback的回调函数。 - - ``` - class AnimatorCallbackDemo : public OHOS::AnimatorCallback { - public: - AnimatorCallbackDemo(int16_t startPos, int16_t endPos, uint16_t time) - : start_(startPos), end_(endPos), time_(time), curTime_(0) {} - - virtual void Callback(OHOS::UIView* view) - { - curTime_++; - int16_t pos = EasingEquation::CubicEaseIn(start_, end_, curTime_, time_); - view->Invalidate(); - view->SetPosition(pos, view->GetY()); - view->Invalidate(); - } - protected: - int16_t start_; - int16_t end_; - uint16_t time_; - uint16_t curTime_; - }; - ``` - -2. 将AnimatorCallback添加到Animator中。 - - ``` - UIImageView* image = new UIImageView(); - image->SetSrc("..\\config\\images\\A021_001.bin"); - image->SetPosition(0, 50); - AnimatorCallbackDemo* callback = new AnimatorCallbackDemo(0, 338, 60); - Animator* animator = new Animator(callback, image, 0, true); - ``` - -3. 将Animator添加到AnimatorManager中。 - - ``` - AnimatorManager::GetInstance()->Add(animator); - ``` - -4. 点击下图下方的按钮,检查对应的动画运行效果。 - - **图 1** 动画实现效果图 - ![](figures/动画实现效果图.gif "动画实现效果图") - - diff --git "a/zh-cn/device-dev/subsystems/\345\220\257\345\212\250\346\201\242\345\244\215.md" "b/zh-cn/device-dev/subsystems/\345\220\257\345\212\250\346\201\242\345\244\215.md" deleted file mode 100755 index 0514d4bd500c9a0de7dd78af98f690b09fd16cc1..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\220\257\345\212\250\346\201\242\345\244\215.md" +++ /dev/null @@ -1,17 +0,0 @@ -# 启动恢复 - -- **[启动恢复子系统概述](启动恢复子系统概述.md)** - -- **[init启动引导组件](init启动引导组件.md)** - -- **[appspawn应用孵化组件](appspawn应用孵化组件.md)** - -- **[bootstrap服务启动组件](bootstrap服务启动组件.md)** - -- **[syspara系统属性组件](syspara系统属性组件.md)** - -- **[常见问题](常见问题.md)** - -- **[参考](参考.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\345\220\257\345\212\250\346\201\242\345\244\215\345\255\220\347\263\273\347\273\237\346\246\202\350\277\260.md" "b/zh-cn/device-dev/subsystems/\345\220\257\345\212\250\346\201\242\345\244\215\345\255\220\347\263\273\347\273\237\346\246\202\350\277\260.md" deleted file mode 100755 index 1287b4212dbaf8470686796086bdcd06c0faa20b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\220\257\345\212\250\346\201\242\345\244\215\345\255\220\347\263\273\347\273\237\346\246\202\350\277\260.md" +++ /dev/null @@ -1,66 +0,0 @@ -# 启动恢复子系统概述 - -- [约束与限制](#section2029921310472) - -启动恢复子系统负责从内核启动之后到应用启动之前的系统关键服务进程的启动过程以及设备恢复出厂设置的功能。涉及以下组件: - -- init启动引导组件 - - init启动引导组件对应的进程为init进程,是内核完成初始化后启动的第一个用户态进程。init进程启动之后,读取init.cfg配置文件,根据解析结果,执行相应命令(见[第2章表2](init启动引导组件.md#table122681439144112)描述)并依次启动各关键系统服务进程,在启动系统服务进程的同时设置其对应权限。 - -- appspawn应用孵化组件 - - 负责接收**用户程序框架**的命令孵化应用进程,设置新进程的权限,并调用应用程序框架的入口函数。 - -- bootstrap服务启动组件 - - 提供了各服务和功能的启动入口标识。在SAMGR启动时,会调用boostrap标识的入口函数,并启动系统服务。 - -- syspara系统属性组件 - - 系统属性组件,根据OpenHarmony产品兼容性规范提供获取设备信息的接口,如:产品名、品牌名、厂家名等,同时提供设置/读取系统属性的接口。 - - -## 约束与限制 - -启动恢复子系统源代码目录和适配平台: - -**表 1** 启动恢复子系统源代码目录和适配平台 - - - - - - - - - - - - - - - - - - - -

名称

-

适配平台

-

base/startup/appspawn_lite

-

小型系统设备(参考内存≥1MB),如Hi3516DV300 、Hi3518EV300

-

base/startup/bootstrap_lite

-

轻量系统设备(参考内存≥128KB),如Hi3861V100

-

base/startup/init_lite

-

小型系统设备(参考内存≥1MB),如Hi3516DV300、Hi3518EV300

-

base/startup/syspara_lite

-
  • 轻量系统设备(参考内存≥128KB),如Hi3861V100
  • 小型系统设备(参考内存≥1MB),如Hi3516DV300、Hi3518EV300
-
- -- init启动引导组件: - - 配置文件init.cfg烧写到单板之后变成只读模式,修改时必须重新打包和烧写rootfs镜像。 - - 配置文件init.cfg仅支持json格式。 - -- bootstrap服务启动组件:需要在链接脚本中配置zInit代码段。 -- syspara系统属性组件:SetParameter/GetParameter仅支持uid大于1000的应用调用。 - diff --git "a/zh-cn/device-dev/subsystems/\345\224\244\351\206\222\350\257\215\350\257\206\345\210\253SDK\347\232\204\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/subsystems/\345\224\244\351\206\222\350\257\215\350\257\206\345\210\253SDK\347\232\204\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100755 index c8f592b80cfa7aa2254c26bfbe1fcda8a14da699..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\224\244\351\206\222\350\257\215\350\257\206\345\210\253SDK\347\232\204\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,81 +0,0 @@ -# 唤醒词识别SDK的开发示例 - -1. 在//foundation/ai/engine /interfaces/kits目录中添加唤醒词识别SDK的API接口定义,该接口可用三方应用的调用。如下代码片段即为唤醒词识别定义的API接口示例,其相关代码参考路径为://foundation/ai/engine /interfaces/kits/asr/keyword\_spotting。 - - ``` - class KWSSdk { - public: - KWSSdk(); - virtual ~KWSSdk(); - - // 定义了创建唤醒词检测工具包的方法 - int32_t Create(); - - // 定义了同步执行唤醒词检测任务的方法 - int32_t SyncExecute(const Array &audioInput); - - // 定义了设置唤醒词检测回调器的方法 - int32_t SetCallback(const std::shared_ptr &callback); - - // 定义了销毁唤醒词工具包的方法,释放与插件的会话信息。 - int32_t Destroy(); - }; - ``` - -2. 在//foundation/ai/engine/services/client/algorithm\_sdk的目录中增加SDK中API接口的具体实现,调用client端提供的接口,实现算法插件能力的使用。如下代码片段即为唤醒词识别的API接口中create方法的具体实现示例,更多详细代码可参考://foundation/ai/engine/services/client/algorithm\_sdk/asr/keyword\_spotting。 - - ``` - int32_t KWSSdk::KWSSdkImpl::Create() - { - if (kwsHandle_ != INVALID_KWS_HANDLE) { - HILOGE("[KWSSdkImpl]The SDK has been created"); - return KWS_RETCODE_FAILURE; - } - if (InitComponents() != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]Fail to init sdk components"); - return KWS_RETCODE_FAILURE; - } - // 调用client端提供的接口AieClientInit,实现初始化引擎服务,激活跨进程调用 - int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr); - if (retCode != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode); - return KWS_RETCODE_FAILURE; - } - if (clientInfo_.clientId == INVALID_CLIENT_ID) { - HILOGE("[KWSSdkImpl]Fail to allocate client id"); - return KWS_RETCODE_FAILURE; - } - DataInfo inputInfo = { - .data = nullptr, - .length = 0, - }; - DataInfo outputInfo = { - .data = nullptr, - .length = 0, - }; - // 调用client端提供的接口AieClientPrepare,实现加载算法插件 - retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr); - if (retCode != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode); - return KWS_RETCODE_FAILURE; - } - if (outputInfo.data == nullptr || outputInfo.length <= 0) { - HILOGE("[KWSSdkImpl]The data or length of output info is invalid"); - return KWS_RETCODE_FAILURE; - } - MallocPointerGuard pointerGuard(outputInfo.data); - retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_); - if (retCode != RETCODE_SUCCESS) { - HILOGE("[KWSSdkImpl]Get handle from inputInfo failed"); - return KWS_RETCODE_FAILURE; - } - return KWS_RETCODE_SUCCESS; - } - ``` - - 上述代码为API接口的具体实现,从上述示例的代码中,SDK中create接口的具体实现即为下述示例代码中create方法,该方法调用了AI引擎框架client端开放接口AieClientInit,AieClientPrepare,从而实现与server端建立连接及加载算法模型的能力。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >SDK调用AI引擎client端接口顺序应遵循AieClientInit-\>AieClientPrepare-\>AieClientSyncProcess/AieClientAsyncProcess-\>AieClientRelease-\>AieClientDestroy,否则调用接口会返回错误码。 - - diff --git "a/zh-cn/device-dev/subsystems/\345\233\276\345\275\242\345\233\276\345\203\217.md" "b/zh-cn/device-dev/subsystems/\345\233\276\345\275\242\345\233\276\345\203\217.md" deleted file mode 100755 index 08422282d6c645d6451f0f930689f79fc73c4ad9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\233\276\345\275\242\345\233\276\345\203\217.md" +++ /dev/null @@ -1,13 +0,0 @@ -# 图形图像 - -- **[图形图像概述](图形图像概述.md)** - -- **[容器类组件开发指导](容器类组件开发指导.md)** - -- **[布局容器类组件开发指导](布局容器类组件开发指导.md)** - -- **[普通组件开发指导](普通组件开发指导.md)** - -- **[动画开发指导](动画开发指导.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\345\252\222\344\275\223.md" "b/zh-cn/device-dev/subsystems/\345\252\222\344\275\223.md" deleted file mode 100755 index c76c3a1f71afffffd608dd2db0ed33072b8bff54..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\252\222\344\275\223.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 媒体 - -- **[相机](相机.md)** - -- **[音视频](音视频.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\345\256\211\345\205\250.md" "b/zh-cn/device-dev/subsystems/\345\256\211\345\205\250.md" deleted file mode 100755 index 88ce479aa01d95df97297fd45bd3ac17d0d16ff1..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\256\211\345\205\250.md" +++ /dev/null @@ -1,13 +0,0 @@ -# 安全 - -- **[概述](概述-7.md)** - -- **[应用验签开发指导](应用验签开发指导.md)** - -- **[应用权限管理开发指导](应用权限管理开发指导.md)** - -- **[IPC通信鉴权开发指导](IPC通信鉴权开发指导.md)** - -- **[可信设备群组管理开发指导](可信设备群组管理开发指导.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 507ad3b1186829744ad660c5cd49f52eee5b9415..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,244 +0,0 @@ -# 容器类组件开发指导 - -- [UIViewGroup](#section145471898812) -- [使用场景](#section0916112362216) -- [接口说明](#section12641756192212) -- [开发步骤](#section5412161692311) -- [UIScrollView](#section174961523161315) -- [使用场景](#section8937101902413) -- [接口说明](#section14789133142420) -- [开发步骤](#section1769754422417) - -容器类组件,指能包含其它UI组件的组件,容器类组件继承于UIViewGroup(带Add方法),基于实际组件的使用场景,将需要增加其他子组件的组件,放置到容器类继承结构下。如UIAnalogClock内,通常会Add需要的计步信息,时分秒图标等。 - -**图 1** 普通容器类组件结构 -![](figures/普通容器类组件结构.png "普通容器类组件结构") - -RootView、UIAbstractScroll、UIPicker组件从UIViewGroup继承,UIList、UIScrollView、UISwipeView组件从UIAbstractScroll继承。 - -## UIViewGroup - -## 使用场景 - -UIViewGroup是容器类组件基类,实现增加、删除、插入等操作,通过增加方法可以添加子组件。普通容器类组件子组件需要设置位置信息,位置信息为相对父组件的相对坐标。组件树结构如下图: - -**图 2** 组件树结构示意图 -![](figures/组件树结构示意图.png "组件树结构示意图") - -往根节点rootView里添加ViewGroup1容器组件和View1组件,往ViewGroup1容器组件里再添加View2组件和ViewGroup2容器组件,在View1之后添加View3组件。 - -- 关于渲染:容器类组件在渲染时会遍历所有子组件OnDraw方法,以达到刷新所有组件的目的。 -- 关于坐标:子组件位置信息为相对父组件的相对坐标,系统在渲染时计算绝对坐标并显示。 -- 关于树结构遍历:UIViewGroup提供如下方法实现遍历、查找、管理组件树。 - -## 接口说明 - -**表 1** ViewGroup接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

方法

-

功能

-

virtual void Add(UIView* view)

-

添加子组件

-

virtual void Insert(UIView* prevView, UIView* insertView)

-

插入子组件

-

virtual void Remove(UIView* view)

-

删除子组件

-

virtual void RemoveAll()

-

删除所有子组件

-

virtual void GetTargetView(const Point& point, UIView** last)

-

获取目标视图

-

virtual void MoveChildByOffset(int16_t x, int16_t y)

-

偏移子组件

-

UIView* GetChildrenHead() const

-

获取视图头节点

-

UIView* GetChildrenTail() const

-

获取视图最后那个节点

-

virtual UIView* GetChildById(const char* id) const override

-

通过id获取子视图

-
- -## 开发步骤 - -1. 构造button实例并设置坐标信息。 - - ``` - UILabelButton* btn1 = new UILabelButton(); - btn1->SetPosition(0, 0, 100, 50); - btn1->SetText("btn1"); - - UILabelButton* btn2 = new UILabelButton(); - btn2->SetPosition(50, 50, 100, 50); - btn2->SetText("btn2"); - - UILabelButton* btn3 = new UILabelButton(); - btn3->SetPosition(100, 100, 100, 50); - btn3->SetText("btn3"); - ``` - -2. 构造UIViewGroup实例,并设置坐标信息。 - - ``` - UIViewGroup* group = new UIViewGroup(); - group->SetPosition(0, 0, 300, 300); - ``` - -3. 使用Add方法添加Button实例到UIViewGroup。 - - ``` - group->Add(btn1); - group->Add(btn2); - group->Add(btn3); - ``` - -4. 检查ViewGroup效果如下图所示。 - - **图 3** ViewGroup添加view实例效果图 - ![](figures/ViewGroup添加view实例效果图.png "ViewGroup添加view实例效果图") - - -## UIScrollView - -## 使用场景 - -UIScrollView提供可滑动的容器类组件,子组件可在触摸事件驱动下上下、左右滑动,并提供水平和垂直方向的游标显示功能。 - -## 接口说明 - -**表 2** ScrollView接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

方法

-

功能

-

void ScrollBy(int16_t xDistance, int16_t yDistance)

-

移动视图

-

void SetScrollbarWidth(uint8_t width)

-

设置滑动条宽度

-

void SetHorizontalScrollState(bool state)

-

设置水平滑动状态

-

bool GetHorizontalScrollState() const

-

获取水平是否可滑动状态

-

void SetVerticalScrollState(bool state)

-

设置垂直滑动状态

-

bool GetVerticalScrollState() const

-

获取垂直是否可滑动状态

-

void SetXScrollBarVisible(bool state)

-

设置X轴滑动条是否可见

-

void SetYScrollBarVisible(bool state)

-

设置Y轴滑动条是否可见

-

void RegisterScrollListener(OnScrollListener* scrollListener)

-

注册滑动事件回调类

-

void RefreshScrollBar()

-

刷新滑动条

-

virtual void OnScrollStart() {}

-

滚动开始回调函数

-

virtual void OnScrollEnd() {}

-

滚动结束回调函数

-

uint8_t GetScrollState() const

-

获取滚动状态

-

void SetScrollState(uint8_t state)

-

设置滚动状态

-
- -## 开发步骤 - -添加两个button子组件,并显示水平、垂直方向游标。 - -``` -scrollView* scroll = new UIScrollView(); -scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); -scroll->SetPosition(0,0, 200, 200); -scroll->SetXScrollBarVisible(true); -scroll->SetYScrollBarVisible(true); -UILabelButton* button1 = new UILabelButton(); -button1->SetText("button1"); -button1->SetPosition(0, 0, 300, 300); -UILabelButton* button2 = new UILabelButton(); -button2->SetText("button2"); -button2->SetPosition(0, 300, 300, 300); -scroll->Add(button1); -scroll->Add(button2); -``` - -**图 4** 水平、垂直方向可滑动效果图 -![](figures/水平-垂直方向可滑动效果图.gif "水平-垂直方向可滑动效果图") - diff --git "a/zh-cn/device-dev/subsystems/\345\270\203\345\261\200\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\270\203\345\261\200\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 4f8653aad5a60dd337d7ff873ee22d005474cad3..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\270\203\345\261\200\345\256\271\345\231\250\347\261\273\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,216 +0,0 @@ -# 布局容器类组件开发指导 - -- [UISwipeView](#section13631719181717) -- [使用场景](#section11299120102617) -- [接口说明](#section767434119261) -- [开发步骤(水平滑动,不可循环)](#section111911175287) -- [开发步骤(水平滑动,可循环)](#section1976914915282) -- [GridLayout](#section46819199173) -- [使用场景](#section831618247294) -- [接口说明](#section597214622912) -- [开发步骤](#section1418253410306) - -布局类容器组件由视图基础类组成,通过直接设置视图位置,可以达到嵌套和重叠布局的目的;通过设置布局类型和边距达到规格化布局子组件的目的;通过调用相关接口可实现根据父组件及兄弟节点布局视图的目的。 - -## UISwipeView - -## 使用场景 - -UISwipeView继承UIViewGroup,除提供容器类组件Add、Remove、Insert等方法外还提供按页面滑动功能,滑动结束后当前页面居中对齐显示。该组件分为水平方向和垂直方向,通过Add方法添加的子组件会根据Add的顺序和UISwipeView方向自动水平对齐或则垂直对齐。 - -## 接口说明 - -**表 1** SwipeView接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

方法

-

功能

-

void SetCurrentPage(uint16_t index);

-

设置当前页

-

uint16_t GetCurrentPage()

-

获取当前页

-

UIView* GetCurrentView() const

-

获取当前页组件

-

void SetOnSwipeListener(OnSwipeListener& onSwipeListener)

-

设置滑动回调类

-

void SetAnimatorTime(uint16_t time);

-

设置动画事件

-

void SetLoopState(bool loop)

-

设置是否循环

-

UIView* GetViewByIndex(uint16_t index);

-

通过index获取view

-
- -## 开发步骤(水平滑动,不可循环) - -1. 创建一个水平滑动的UISwipeView。 - - ``` - UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); - ``` - -2. 向UISwipeView中添加子组件。 - - ``` - UILabelButton* button1 = new UILabelButton(); - button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button1->SetText("button1"); - swipe->Add(button1); - UILabelButton* button2 = new UILabelButton(); - button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button2->SetText("button2"); - swipe->Add(button2); - UILabelButton* button3 = new UILabelButton(); - button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button3->SetText("button3"); - swipe->Add(button3); - ``` - -3. 检查实现效果,水平滑动,不可循环。 - - **图 1** UISwipeView水平滑动效果图 - - - ![](figures/zh-cn_image_0000001053247975.gif) - - -## 开发步骤(水平滑动,可循环) - -1. 创建一个水平滑动的UISwipeView并添加子组件。 - - ``` - UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); - UILabelButton* button1 = new UILabelButton(); - button1->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button1->SetText("button1"); - swipe->Add(button1); - UILabelButton* button2 = new UILabelButton(); - button2->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button2->SetText("button2"); - swipe->Add(button2); - UILabelButton* button3 = new UILabelButton(); - button3->SetPosition(0, 0, g_ButtonW, g_ButtonH); - button3->SetText("button3"); - swipe->Add(button3); - ``` - -2. 设置UISwipeView循环滑动。 - - ``` - swipe->SetLoopState(true); - ``` - -3. 检查实现效果,水平循环滑动。 - - **图 2** UISwipeView水平滑动循环效果图 - - - ![](figures/zh-cn_image_0000001053207924.gif) - - -## GridLayout - -## 使用场景 - -提供基础布局能力,可设置网格行数和列数,通过Add方法添加的子组件在调用LayoutChildren\(\)方法后自动进行排列布局。 - -## 接口说明 - -**表 2** GridLayout接口说明 - - - - - - - - - - - - - - - - -

方法

-

功能

-

void SetRows(const uint16_t& rows)

-

设置行数

-

void SetCols(const uint16_t& cols)

-

设置列数

-

void LayoutChildren(bool needInvalidate = false)

-

布局子组件

-
- -## 开发步骤 - -1. 构造GridLayout并设置位置、大小信息。 - - ``` - GridLayout* layout_ = new GridLayout(); - layout_->SetPosition(0, g_y, HROIZONTAL_RESOLUTION, 200); - layout_->SetLayoutDirection(LAYOUT_HOR); - layout_->SetRows(2); - layout_->SetCols(2); - ``` - -2. 构造子组件button。 - - ``` - UILabelButton* bt1 = new UILabelButton(); - bt1->SetPosition(0,0,100,50); - bt1->SetText("bt1"); - UILabelButton* bt2 = new UILabelButton(); - bt2->SetPosition(0, 0, 100, 50); - bt2->SetText("bt2"); - UILabelButton* bt3 = new UILabelButton(); - bt3->SetPosition(0, 0, 100, 50); - bt3->SetText("bt3"); - UILabelButton* bt4 = new UILabelButton(); - bt4->SetPosition(0, 0, 100, 50); - bt4->SetText("bt4"); - ``` - -3. 添加子组件并调用LayoutChildren\(\)。 - - ``` - layout_->Add(bt1); - layout_->Add(bt2); - layout_->Add(bt3); - layout_->Add(bt4); - layout_->LayoutChildren(); - ``` - -4. 检查button组件布局效果如下图所示。 - - **图 3** 设置2\*2网格并添加4个button组件进行布局 - ![](figures/设置2-2网格并添加4个button组件进行布局.png "设置2-2网格并添加4个button组件进行布局") - - diff --git "a/zh-cn/device-dev/subsystems/\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/zh-cn/device-dev/subsystems/\345\270\270\350\247\201\351\227\256\351\242\230.md" deleted file mode 100755 index c81824514aa2b6660e73433a089e82faca04fa13..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\270\270\350\247\201\351\227\256\351\242\230.md" +++ /dev/null @@ -1,56 +0,0 @@ -# 常见问题 - -- [系统启动过程中打印“parse failed!”错误后停止启动](#section2041345718513) -- [系统启动过程未结束就自动重启,如此反复持续](#section57381816168) -- [参数正确的情况下调用SetParameter/GetParameter返回失败](#section129991227141512) - -## 系统启动过程中打印“parse failed!”错误后停止启动 - -**现象描述** - -系统启动过程中,打印“\[Init\] InitReadCfg, parse failed! please check file /etc/init.cfg format.”错误,启动过程停止,如下图所示: - -![](figures/zh-cn_image_0000001063839940.png) - -**可能原因** - -修改init.cfg文件时,漏掉或多加了逗号或括号等,导致init.cfg文件的json格式被破坏。 - -**解决办法** - -仔细检查init.cfg文件,确保其格式符合json格式要求。 - -## 系统启动过程未结束就自动重启,如此反复持续 - -**现象描述** - -镜像烧写完成后系统启动,启动过程未完成即自动重新启动,如此反复持续。 - -**可能原因** - -被init启动的服务都有一个叫做“importance”的属性(详见[第2章表3](init启动引导组件.md#table14737791471)描述)。 - -- 当该属性为0时,表示若当前服务进程退出,init不需要重启单板。 -- 当该属性为1时,表示若当前服务进程退出,init需要重启单板。 - -因此出现上述现象的可能原因:有“importance”属性为1的服务在每次启动的过程中都会退出(可能是进程崩溃或出错自动退出),导致init进程自动重启单板。 - -**解决办法** - -1. 需要通过日志确认崩溃或报错退出的服务,并解决其崩溃/报错的问题,然后重新烧写镜像即可。 -2. 也可以将崩溃/报错退出的服务的“importance”属性改为0,然后重新烧写镜像,这样即使其退出,init也不会重启单板。 - -## 参数正确的情况下调用SetParameter/GetParameter返回失败 - -**现象描述** - -在各参数正确的情况下调用SetParameter/GetParameter返回失败。 - -**可能原因** - -程序对SetParameter/GetParameter这两个接口做了权限校验,在各参数正确的情况下调用SetParameter/GetParameter返回操作失败,很有可能是调用者的uid大于1000,没有调用权限。 - -**解决办法** - -无需处理 - diff --git "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\346\235\203\351\231\220\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\346\235\203\351\231\220\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 127a7f175667a950f8cd2f4e43e3bc738d825519..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\346\235\203\351\231\220\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,228 +0,0 @@ -# 应用权限管理开发指导 - -- [运作机制](#section193961322175011) -- [场景介绍](#section18502174174019) -- [接口说明](#section1633115419401) -- [开发步骤](#section022611498210) - -## 运作机制 - -由于OpenHarmony允许安装三方应用,所以需要对三方应用的敏感权限调用进行管控,具体实现是应用在开发阶段就需要在profile.json中指明此应用在运行过程中可能会调用哪些敏感权限,这些权限包括静态权限和动态权限,静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示获取用户的敏感信息,所以需要在运行时让用户确认才可以调用,授权方式包括系统设置应用手动授权等。除了运行时对应用调用敏感权限进行管控外,还需要利用应用签名管控手段确保应用安装包已经被设备厂商进行了确认。 - -**表 1** OpenHarmony权限列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

OpenHarmony权限

-

授权方式

-

权限说明

-

ohos.permission.LISTEN_BUNDLE_CHANGE

-

system_grant(静态权限)

-

允许该应用获取应用变化消息。

-

ohos.permission.GET_BUNDLE_INFO

-

system_grant(静态权限)

-

允许该应用获取应用信息。

-

ohos.permission.INSTALL_BUNDLE

-

system_grant(静态权限)

-

允许该应用安装应用。

-

ohos.permission.CAMERA

-

user_grant(动态权限)

-

此应用可随时使用相机拍摄照片和录制视频。

-

ohos.permission.MODIFY_AUDIO_SETTINGS

-

system_grant(静态权限)

-

允许该应用修改全局音频设置,例如音量和用于输出的扬声器。

-

ohos.permission.READ_MEDIA

-

user_grant(动态权限)

-

允许该应用读取您的视频收藏。

-

ohos.permission.MICROPHONE

-

user_grant(动态权限)

-

此应用可随时使用麦克风进行录音。

-

ohos.permission.WRITE_MEDIA

-

user_grant(动态权限)

-

允许该应用写入您的音乐收藏。

-

ohos.permission.DISTRIBUTED_DATASYNC

-

user_grant(动态权限)

-

管控分布式数据传输能力。

-

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

-

user_grant(动态权限)

-

允许应用使用分布式虚拟能力

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->静态权限:应用安装时由系统授予的权限,对应于权限敏感级别的system\_grant ->动态权限:应用在运行过程中需要用户授权的权限,对应于权限敏感级别的user\_grant - -## 场景介绍 - -应用权限是软件用来访问系统资源和使用系统能力的一种通行方式。在涉及用户隐私相关功能和数据的场景,例如:访问个人设备的硬件特性,如摄像头、麦克风,以及读写媒体文件等,OpenHarmony通过应用权限管理组件来保护这些数据以及能力。 - -在系统应用开发过程中,如果应用要使用敏感权限,开发者可以调用应用权限管理组件接口检查待访问权限是否被授权,如果未授权,操作不允许。 - -## 接口说明 - -应用权限管理提供的API接口,当前仅供系统应用和系统服务调用,具体API接口如下。 - -**表 2** 应用权限管理API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

int CheckPermission(int uid, const char *permissionName)

-

检查指定UID的应用进程是否具有访问系统服务API的权限

-

int CheckSelfPermission(const char *permissionName)

-

检查调用者是否具有访问系统服务API的权限

-

int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)

-

查询应用申请的所有权限,并检查权限是否被授予

-

int GrantPermission(const char *identifier, const char *permName)

-

将指定权限授予应用程序

-

int RevokePermission(const char *identifier, const char *permName)

-

收回应用程序的指定权限

-

int GrantRuntimePermission(int uid, const char *permissionName)

-

应用运行时动态授予指定权限

-

int RevokeRuntimePermission(int uid, const char *permissionName)

-

应用运行时动态撤销指定权限

-
- -## 开发步骤 - -本部分以包管理器的应用权限开发为例进行讲解。开发过程中,首先需要明确涉及的敏感权限,并在config.json中声明该权限,在安装应用程序时,包管理器会调用应用权限管理组件的接口检查该权限是否被授予,若授予,安装流程正常进行,否则安装失败。 - -1. 在开发过程中,包管理器明确需要安装应用的权限(ohos.permission.INSTALL\_BUNDLE),并在config.json中声明该权限; - - ``` - { - ... - "module": { - "package": "com.huawei.kitframework", - "deviceType": [ - "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera", "smartVision" - ], - "reqPermissions": [{ - // 声明需要的权限:安装应用程序的权限名 - "name": "ohos.permission.INSTALL_BUNDLE", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - }, - { - "name": "ohos.permission.LISTEN_BUNDLE_CHANGE", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - }, - { - "name": "ohos.permission.GET_BUNDLE_INFO", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - } - ], - ... - } - ``` - -2. 当包管理器开发应用安装功能接口时,会调用权限管理相关接口检查自身是否具有安装应用程序的权限,例如:以安装应用的权限名"ohos.permission.INSTALL\_BUNDLE"作为入参,调用CheckPermission接口检查包管理器是否具有安装应用的权限,如果有权限,安装流程继续执行,否则返回安装失败; - - ``` - constexpr static char PERMISSION_INSTALL_BUNDLE[] = "ohos.permission.INSTALL_BUNDLE"; - - bool Install(const char *hapPath, const InstallParam *installParam, InstallerCallback installerCallback) - { - if ((hapPath == nullptr) || (installerCallback == nullptr) || (installParam == nullptr)) { - HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to nullptr parameters"); - return false; - } - // 检查ohos.permission.INSTALL_BUNDLE权限是否被授予 - if (CheckPermission(0, static_cast(PERMISSION_INSTALL_BUNDLE)) != GRANTED) { - HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to permission denied"); - return false; // 返回安装失败 - } - // 安装流程 - ... - } - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\351\252\214\347\255\276\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\351\252\214\347\255\276\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 8c5e78070f8c6b457d28fa149bcc528bad8a910b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\351\252\214\347\255\276\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,272 +0,0 @@ -# 应用验签开发指导 - -- [场景介绍](#section18502174174019) -- [验签流程](#section554632717226) -- [接口说明](#section1633115419401) -- [开发步骤(场景一)](#section4207112818418) - - [验签指导](#section11470123816297) - - [生成OpenHarmony自签名应用](#section167151429133312) - - [开发示例](#section174318361353) - -- [开发步骤(场景二)](#section81272563427) - - [验签指导](#section07028210442) - - [开发示例](#section1930711345445) - -- [调测验证](#section427316292411) - -## 场景介绍 - -当需要验证调试应用、发布应用,OpenHarmony自签名应用的完整性是否被破坏时,可以调用验签组件的接口进行验证。如有需要还可通过验签接口获取部分描述文件信息,如appid。对于调试应用,还可通过验签接口验证应用和设备的UDID是否匹配,确保应用安装在了正确的设备上。 - -## 验签流程 - -未经签名的Hap包的压缩方式是ZIP格式,简单分为文件块,中心目录(Central directory)块,中心目录结尾(EOCD,End of central directory record)块。 - -经过签名的Hap包,在文件块,和中心目录块之间,插入了签名块。签名块由文件签名数据块(data sign block)、描述文件签名数据块(profile sign block)和签名头(sign head)组成,如下图所示。 - -**图 1** 经过签名的Hap包结构 - - -![](figures/安全子系统.png) - -整个验签流程,主要分为三部分:整包验签、描述文件签名块验签,以及描述文件内容校验。 - -**整包验签** - -用设备的预置根证书,通过证书链来证明叶子证书本身是可信的,然后用叶子证书的公钥解密出的摘要证明整包是未篡改的。 - -具体操作步骤如下: - -1. 对文件签名数据块中的证书链进行校验,确定其叶子证书是可信的。 -2. 用叶子证书中的公钥对文件签名块进行验签,证明其未被篡改。 -3. 计算并合并文件块,中心目录块和中心目录结尾块的摘要。然后将计算结果,再与签名块中的描述文件签名块的摘要合并,将最终合并的摘要与文件签名块中包含的摘要对比,如果两者相等,则整包验签通过。 - -**描述文件签名块验签** - -首先判断文件签名的签发单位,如果是应用市场签发的发布应用,则无需对描述文件进行验签,直接信任,否则要对其验签。先取出整个描述文件签名块,然后验证证书链,最后用叶子证书对描述文件数据块验签,证明其未被篡改。 - -**描述文件内容校验** - -取出描述文件,并对其内容进行合法性检查。其中若hap包为调试应用,则会比对本机UDID与描述文件中包含的UDID列表,如果本机UDID在描述文件的UDID列表中包含,则验证通过。比较描述文件中包含的证书(如果是应用市场发布应用或OpenHarmony自签名则无需比较),和整包校验时使用的叶子证书,如果相同,认为整个验签流程完成。 - -## 接口说明 - -验签组件当前提供innerkits接口,仅供系统应用调用,相关接口及功能描述如下: - -**表 1** 验签组件API接口功能介绍 - - - - - - - - - - - - - - - - -

接口名

-

描述

-

int APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)

-

主入口函数,输入文件路径,进行验签,并将从描述文件中获取的数据通过verifyRst返回给调用者

-

int APPVERI_SetDebugMode(bool mode)

-

设置测试模式,设置mode为true,则支持基于测试根密钥的证书链校验,设置mode为false,则关闭基于测试根密钥的证书链校验。

-

注:当前没有基于现有测试根密钥的证书,开发者可根据自身需要,替换测试根密钥并进行相关验证。

-

void APPVERI_FreeVerifyRst(VerifyResult *verifyRst)

-

释放verifyRst中申请的内存

-
- -## 开发步骤(场景一) - -### 验签指导 - -对应用市场发布应用、基于应用市场调试证书签发的调试应用、OpenHarmony自签名应用的校验。 - -1. 定义出参结构体变量VerifyResult; - - ``` - VerifyResult verifyResult = {0}; - ``` - -2. 以文件路径及VerifyResult为入参,调用APPVERI\_AppVerify进行文件校验; - - ``` - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - ``` - -3. 判断返回结果,如果校验通过的话,获取VerifyResult中的数据,进行业务处理; - - ``` - signatureInfo.appId = verifyResult.profile.appid; - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - ``` - -4. 调用APPVERI\_FreeVerifyRst,释放VerifyResult中申请的内存。 - - ``` - APPVERI_FreeVerifyRst(&verifyResult); - ``` - - -### 生成OpenHarmony自签名应用 - -如果是OpenHarmony自签名应用的校验,开发者可通过以下方式生成OpenHarmony自签名应用。 - -1. 材料备齐。 - - 生成自签名应用需要的材料有:签名工具、系统应用hap包、系统应用profile文件\(\*.p7b\)、签名证书\(\*.cer\)、签名公私钥对\(\*.jks\)。 - -2. 将所有材料放在同一个目录下,打开shell。 -3. 根据应用、描述文件的实际名称修改指令,并在shell中输入,完成签名。 - - ``` - java -jar hapsigntoolv2.jar sign -mode localjks -privatekey "OpenHarmony Software Signature" -inputFile camera.hap -outputFile signed_camera.hap -signAlg SHA256withECDSA -keystore OpenHarmony.jks -keystorepasswd 123456 -keyaliaspasswd 123456 -profile camera_release.p7b -certpath OpenHarmony.cer -profileSigned 1 - ``` - - 关键字段说明: - - -jar:签名工具,[hapsigntool](https://repo.huaweicloud.com/harmonyos/develop_tools/hapsigntoolv2.jar) - - -mode:本地签名标记位,固定为localjks - - -privatekey:密钥对别名,签名公私钥对的别名为OpenHarmony Software Signature - - -inputFile:待签名应用,通过编译产生 - - -outputFile:签名后应用,最终输出 - - -signAlg:签名算法,当前固定为SHA256withECDSA - - -keystore:公私钥对,使用签名公私钥对,位于开源库security\_services\_app\_verify仓中OpenHarmonyCer目录下,[OpenHarmony.jks](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.jks)。默认密码为123456 ,用户可采用工具\(例如keytool\)更改默认密码 - - -keystorepasswd:公私钥对密码,默认签名公私钥对密码为123456 - - -keyaliaspasswd:公私钥对别名密码,默认签名公私钥对别名密码为123456 - - -profile:描述文件,应用的描述文件位于对应源代码目录中 - - -certpath:使用签名证书,位于开源库security\_services\_app\_verify仓中OpenHarmonyCer目录下,[OpenHarmony.cer](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.cer) - - -profileSigned:签名块中是否包含描述文件\(profile\)。固定为1(包含) - - -### 开发示例 - -以应用管理框架组件在应用安装时进行验签的实际调用为例: - -``` -uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) -{ - bool mode = ManagerService::GetInstance().IsDebugMode(); - HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); - // 定义结果结构体 - VerifyResult verifyResult = {0}; - // 输入待验签文件路径进行验签 - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - uint8_t errorCode = SwitchErrorCode(ret); - if (errorCode != ERR_OK) { - return errorCode; - } - // 从结果结构体中获取appid - signatureInfo.appId = verifyResult.profile.appid; - // 从结果结构体中获取描述文件中书写的应用名 - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - int32_t restricNum = verifyResult.profile.permission.restricNum; - for (int32_t i = 0; i < restricNum; i++) { - signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); - } - // 释放结果结构体中申请的内存 - APPVERI_FreeVerifyRst(&verifyResult); - return ERR_OK; -} -``` - -## 开发步骤(场景二) - -### 验签指导 - -对采用基于测试根密钥证书签名的应用的校验。 - -1. 调用APPVERI\_SetDebugMode\(true\)开启测试模式; - - ``` - ManagerService::SetDebugMode(true); - ... - uint8_t ManagerService::SetDebugMode(bool enable) - { - int32_t ret = APPVERI_SetDebugMode(enable); - if (ret < 0) { - HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); - return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; - } - isDebugMode_ = enable; - HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); - return ERR_OK; - } - ``` - -2. 同场景一中步骤一至四,定义结构体,校验、释放结构体; -3. 调用APPVERI\_SetDebugMode\(false\)关闭测试模式。 - - ``` - ManagerService::SetDebugMode(false); - ``` - - -### 开发示例 - -完整开发示例如下(在场景一代码示例的基础上进行补充): - -``` -uint8_t ManagerService::SetDebugMode(bool enable) -{ - int32_t ret = APPVERI_SetDebugMode(enable); - if (ret < 0) { - HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); - return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; - } - isDebugMode_ = enable; - HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); - return ERR_OK; -} -uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) -{ - // 开启支持测试服务器签名应用验证 - ManagerService::SetDebugMode(true); - bool mode = ManagerService::GetInstance().IsDebugMode(); - HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); - // 定义结果结构体 - VerifyResult verifyResult = {0}; - // 输入待验签文件路径进行验签 - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - uint8_t errorCode = SwitchErrorCode(ret); - if (errorCode != ERR_OK) { - return errorCode; - } - // 从结果结构体中获取appid - signatureInfo.appId = verifyResult.profile.appid; - // 从结果结构体中获取描述文件中书写的应用名 - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - int32_t restricNum = verifyResult.profile.permission.restricNum; - for (int32_t i = 0; i < restricNum; i++) { - signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); - } - // 释放结果结构体中申请的内存 - APPVERI_FreeVerifyRst(&verifyResult); - // 关闭支持测试服务器签名应用验证 - ManagerService::SetDebugMode(false); - return ERR_OK; -} -``` - -## 调测验证 - -1. 选取一个在OpenHarmony上能够正常安装的应用A。 -2. 根据开发指导开发。 -3. 对应用A,采用自开发程序进行验签,验签通过,能获取到appid。即为开发成功。 - diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213-6.md" "b/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213-6.md" deleted file mode 100755 index 39c2377cd403b1b3aaed2c97947c6cea63b4e6dc..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213-6.md" +++ /dev/null @@ -1,112 +0,0 @@ -# 开发实例 - -- [去电开发实例](#section286643718507) -- [来电开发实例](#section3205350105014) - -## 去电开发实例 - -去电的调用流程示例如下图所示: - -**图 1** 去电调用流程图 - - -![](figures/去电.png) - -当应用触发去电动作时,RIL Adapter会接收到拨打电话的请求,OnRequest\(\)会根据拨打电话请求ID调用拨打电话的接口。在该接口里会把电话服务传过来的数据封装为对应的AT指令发送到Modem,Modem执行完拨号命令后通过OnRequestResponse\(\)接口把响应结果上报给RIL Adapter。 - -``` -#include -#include -#include -#include -#include "atchannel.h" -#include "at_tok.h" -#include "hdf_log.h" -#include "ril.h" - -static void OnRequest(int request, void *data, size_t datalen, RIL_Token token) -{ - HDF_LOGI("OnRequest request = %{public}d start \n", request); - switch (request) { - case HREQ_CALL_DIAL: - SendDialRequest(data, datalen, token); - break; - …… - default: - break; - } -} - -// 将去电ID和参数转换成对应的AT命令,通过send_at_request发送给Modem -static void SendDialRequest(void *data, size_t datalen __unused, RIL_Token token) -{ - char *atCmd; - const char *clir; - int ret; - DialInfo *pDial; - pDial = (DialInfo *) data; - - if (!strncmp(pDial->address, "*31#", 4)) { - HDF_LOGI("clir suppression"); - clir = "i"; - num = (char *)&(pDial->address[4]); - } else if (!strncmp(pDial->address, "#31#", 4)) { - HDF_LOGI("clir invocation"); - clir = "I"; - num = (char *)&(pDial->address[4]); - } else { - HDF_LOGI("set clir state to default"); - clir = ""; - num = (char *)pDial->number; - } - - asprintf(&atCmd, "ATD%s%s;", pDial->address, clir); - ret = send_at_request(atCmd, NULL); - free(atCmd); - // 命令执行完成后调用该接口,将Modem执行的结果反馈给RIL Adapter - OnRequestResponse(t, RIL_RESULT_SUCCESS, NULL, 0); -} -``` - -## 来电开发实例 - -来电的调用流程示例如下图所示: - -**图 2** 来电调用流程图 - - -![](figures/来电.png) - -Modem设备节点读取线程s\_tid\_read会循环读取Modem上报的消息,当Modem接收到来电时会主动上报来电相关的信息; - -当该线程通过调用OnNotificationResponse\(\)解析到Modem上报的数据是以"+CRING"、"RING"等字符开头时,表示有来电事件,然后通过OnRadioEventNotify\(HNOTI\_CALL\_STATUS, NULL, 0\)上报给RIL Adapter完成来电事件上报。 - -``` -#include -#include "atchannel.h" -#include "at_tok.h" -#include "hdf_log.h" -#include "ril.h" - -bool IsCallStatusUpdated(const char *s) -{ - return (StrBeginWith(s, "+CRING:") - || StrBeginWith(s, "RING") - || StrBeginWith(s, "NO CARRIER") - || StrBeginWith(s, "+CCWA")); -} - -// 将Modem上报数据解析为对应的Modem事件 -static void OnNotificationResponse(const char *s, const char *sms_pdu) -{ - char *line = NULL, *p; - HDF_LOGI("OnNotificationResponse = %{public}s sState = %{public}d", s, sState); - // 解析到以"+CRING:"等字符开头的数据时,转换为来电事件 - if (IsCallStatusUpdated(s)) { - // 通知RIL Adapter有来电事件 - OnRadioEventNotify(HNOTI_CALL_STATUS, NULL, 0); - } - …… -} -``` - diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" "b/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" deleted file mode 100644 index 6a68dfe23f9f81c975fab1807c63bc9fbe6a15f4..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" +++ /dev/null @@ -1,711 +0,0 @@ -# 开发指导 - -- [场景介绍](#section93012287133) -- [接口说明](#section11821047161319) -- [开发步骤](#section10514141679) - - [创建Service类型的Ability](#section19921154214315) - - [包管理接口使用指导](#section1724016743217) - - [Hap包打包](#section171771212328) - - -## 场景介绍 - -- 带界面的Ability的应用,比如:新闻类的应用、视频类的应用、导航类的应用、支付类的应用等等,目前我们看到的大部分应用都是带有界面的用于人机交互的应用。 - -- 不带界面的Ability应用,比如:音乐播放器能在后台播放音乐、后台提供计算服务、导航服务的各类应用等。 - -- 不管是带界面的Ability应用还是不带界面的Ability应用,都要打包成Hap包,最终发布到应用市场,用户通过应用市场下载安装相应的应用。 - -## 接口说明 - -**表 1** Ability子系统的对外接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名称

-

接口描述

-

Want *WantParseUri(const char *uri)

-

反序列化接口,由字符串生成Want对象。

-

const char *WantToUri(Want want)

-

序列化,把Want对象生成字符串。

-

void SetWantElement(Want *want, ElementName element);

-

设置ElementName对象。

-

void SetWantData(Want *want, const void *data, uint16_t dataLength)

-

设置数据。

-

bool SetWantSvcIdentity(Want *want, SvcIdentity sid)

-

设置SvcIdentity。

-

void ClearWant(Want *want)

-

清除Want的内部内存数据。

-

void SetMainRoute(const std::string &entry)

-

设置AbilitySlice主路由。

-

void SetUIContent(RootView *rootView)

-

设置布局资源。

-

void OnStart(const Want& intent)

-

Ability生命周期状态回调,Ability启动时被回调。

-

void OnStop()

-

Ability生命周期状态回调,Ability销毁时被回调。

-

void OnActive(const Want& intent)

-

Ability生命周期状态回调,Ability显示时被回调。

-

void OnInactive()

-

Ability生命周期状态回调,Ability隐藏时被回调。

-

void OnBackground()

-

Ability生命周期状态回调,Ability退到后台时被回调。

-

const SvcIdentity *OnConnect(const Want &want)

-

Service类型Ability第一次连接时被回调。

-

void OnDisconnect(const Want &want);

-

Service类型Ability断开连接被回调。

-

void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply);

-

Service类型Ability接收消息处理。

-

void Dump(const std::string &extra)

-

dump Ability信息。

-

void Present(AbilitySlice *abilitySlice, const Want &want)

-

发起AbilitySlice跳转。

-

void Terminate()

-

退出当前AbilitySlice。

-

void SetUIContent(RootView *rootView)

-

设置当前AbilitySlice所在Ability的布局资源。

-

void OnStart(const Want& want)

-

AbilitySlice生命周期状态回调,AbilitySlice启动时被回调。

-

void OnStop()

-

AbilitySlice生命周期状态回调,AbilitySlice销毁时被回调。

-

void OnActive(const Want& want)

-

AbilitySlice生命周期状态回调,AbilitySlice显示时被回调。

-

void OnInactive()

-

AbilitySlice生命周期状态回调,AbilitySlice隐藏时被回调。

-

void OnBackground()

-

AbilitySlice生命周期状态回调,AbilitySlice退到后台时被回调。

-

int StartAbility(const Want &want)

-

启动Ability。

-

int StopAbility(const Want &want)

-

停止Service类型的Ability。

-

int TerminateAbility()

-

销毁当前的Ability。

-

int ConnectAbility(const Want &want, const IAbilityConnection &conn, void *data);

-

绑定Service类型的Ability。

-

int DisconnectAbility(const IAbilityConnection &conn)

-

解绑Service类型的Ability。

-

const char *GetBundleName()

-

获取当前ability的对应应用的包名。

-

const char *GetSrcPath()

-

获取当前ability的对应应用的安装路径。

-

const char *GetDataPath()

-

获取当前ability的对应应用的数据路径。

-

int StartAbility(const Want *want)

-

启动Ability,该接口可以不需要在基于Ability开发的应用中使用。

-

int ConnectAbility(const Want *want, const IAbilityConnection *conn, void *data);

-

绑定Service类型的Ability,该接口可以不需要在基于Ability开发的应用中使用。

-

int DisconnectAbility(const IAbilityConnection *conn);

-

解绑Service类型的Ability,该接口可以不需要在基于Ability开发的应用中使用。

-

int StopAbility(const Want *want)

-

停止Service类型的Ability,该接口可以不需要在基于Ability开发的应用中使用。

-

void (*OnAbilityConnectDone)(ElementName *elementName, SvcIdentity *serviceSid, int resultCode, void *data)

-

绑定Service Ability的回调。

-

void (*OnAbilityDisconnectDone)(ElementName *elementName, int resultCode, void *data)

-

解绑Service Ability的回调。

-

void PostTask(const Task& task)

-

投递任务到异步线程进行处理。

-

void PostQuit()

-

退出当前线程的消息循环。

-

static AbilityEventHandler* GetCurrentHandler()

-

获取当前线程的事件处理器。

-

void Run()

-

执行当前线程的消息循环。

-

#define REGISTER_AA(className)

-

注册开发者的Ability到框架中。

-

#define REGISTER_AS(className)

-

注册开发者的AbilitySlice到框架中。

-
- -## 开发步骤 - -### 创建Service类型的Ability - -1. 在my\_service\_ability.h中创建Ability的子类MyServiceAbility。 - - ``` - class MyServiceAbility: public Ability { - protected: - void OnStart(const Want& want); - const SvcIdentity *OnConnect(const Want &want) override; - void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) override; - }; - ``` - -2. 调用REGISTER\_AA宏将ServiceAbility注册到应用框架中,以便应用框架实例化开发者的MyServiceAbility。 - - ``` - #include "my_service_ability.h" - - REGISTER_AA(ServiceAbility) - - void MyServiceAbility::OnStart(const Want& want) - { - printf("ServiceAbility::OnStart\n"); - Ability::OnStart(want); - } - - const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) - { - printf("ServiceAbility::OnConnect\n"); - return Ability::OnConnect(want); - } - - void MyServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) - { - printf("ServiceAbility::MsgHandle, funcId is %u\n", funcId); - int result = 0; - if (funcId == 0) { - result = IpcIoPopInt32(request) + IpcIoPopInt32(request); - } - // push data - IpcIoPushInt32(reply, result); - } - ``` - -3. 实现Service相关的生命周期方法。Service也是一种Ability,Ability为服务提供了以下生命周期方法,用户可以重写这些方法来添加自己的处理。用户在重写的方法里,需要调用父类对应的方法。 - - OnStart\(\) - - 该方法在创建Service的时候调用,用于做一些Service初始化且耗时较短的工作,在Service的整个生命周期只会调用一次。 - - ``` - void MyServiceAbility::OnStart(const Want& want) - { - printf("ServiceAbility::OnStart\n"); - Ability::OnStart(want); - } - ``` - - - OnConnect​\(\) - - 在组件和服务连接时调用,该方法返回SvcIdentity,组件可以通过它,与服务交互。 - - ``` - const SvcIdentity *MyServiceAbility::OnConnect(const Want &want) - { - printf("ServiceAbility::OnConnect\n"); - return Ability::OnConnect(want); - } - ``` - - - OnDisconnect​\(\) - - 在组件与绑定的Service断开连接时调用。 - - - OnStop\(\) - - 在Service销毁时调用。Service应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。 - - -4. 重写消息处理方法。 - - MsgHandle是Service用来处理客户端消息的方法。其中funcId是客户端传过来的消息类型,request是客户端传过来的序列化请求参数。如果用户在处理完成之后想要把结果传回去,需要把结果序列化后写入reply中。 - - ``` - void ServiceAbility::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) - { - printf("ServiceAbility::MsgHandle, funcId is %d\n", funcId); - int result = 0; - if (funcId == PLUS) { - result = IpcIoPopInt32(request) + IpcIoPopInt32(request); - } - // push data - IpcIoPushInt32(reply, result); - } - ``` - -5. 注册Service。 - - Service也需要在应用清单文件config.json中进行注册,注册类型type需要设置为service。 - - ``` - "abilities": [{ - "name": "ServiceAbility", - "icon": "res/drawable/phone.png", - "label": "test app 2", - "launchType": "standard", - "type": "service", - "visible": true - } - ] - ``` - -6. 启动Service。 - - Ability为用户提供了StartAbility\(\)方法来启动另外一个Ability,因为Service也是Ability的一种,开发者同样可以通过将Want传递给该方法来启动Service。 - - 开发者可以通过Want的SetWantElement \(\)来设置目标服务信息。ElementName结构体的两个主要参数:第一个参数为包名称;第二个参数为目标Ability。 - - ``` - { - Want want = { nullptr }; - ElementName element = { nullptr }; - SetElementBundleName(&element, "com.company.appname"); - SetElementAbilityName(&element, "ServiceAbility"); - SetWantElement(&want, element); - StartAbility(want); - ClearElement(&element); - ClearWant(&want); - } - ``` - - StartAbility\(\) 方法会立即执行,如果Service尚未运行,则系统首先会调用OnStart\(\)。 - - - 停止Service。 - - Service一旦创建就会一直保持在后台运行,开发者可以通过调用StopAbility\(\)来停止Service。 - - -7. 连接Service。 - - 如果Service需要与Page Ability或其他应用组件中的Service进行交互,则应创建用于连接的Service。Service支持其他Ability通过ConnectAbility\(\)与其进行连接,ConnectAbility\(\)需要传入目标Service的Want,以及IAbilityConnection的实例来处理回调。IAbilityConnection提供了两个方法供用户实现,OnAbilityConnectDone\(\)用来处理连接的回调,OnAbilityDisconnectDone\(\)用来处理断开连接的回调。 - - ``` - { - // ability创建IAbilityConnection对象和定义IAbilityConnection的两个方法实现 - IAbilityConnection abilityConnection = new IAbilityConnection(); - abilityConnection->OnAbilityConnectDone = OnAbilityConnectDone; - abilityConnection->OnAbilityDisconnectDone = OnAbilityDisconnectDone; - - void OnAbilityConnectDone(ElementName *elementName, SvcIdentity *serviceSid, - int resultCode, void *data) - { - if (resultCode != 0) { - return; - } - // push data - IpcIo request; - char dataBuffer[IPC_IO_DATA_MAX]; - IpcIoInit(&request, dataBuffer, IPC_IO_DATA_MAX, 0); - IpcIoPushInt32(&request, 10); - IpcIoPushInt32(&request, 6); - - // send and getReply - IpcIo reply; - uintptr_t ptr = 0; - if (Transact(nullptr, *serviceSid, 0, &request, &reply, - LITEIPC_FLAG_DEFAULT, &ptr) != LITEIPC_OK) { - printf("transact error\n"); - return; - } - int result = IpcIoPopInt32(&reply); - printf("execute add method, result is %d\n", result); - if (ptr != 0) { - FreeBuffer(nullptr, reinterpret_cast(ptr)); - } - } - - void OnAbilityDisconnectDone(ElementName *elementName, - int resultCode, void *data) - { - printf("elementName is %s, %s\n", - elementName->bundleName, elementName->abilityName); - } - } - ``` - - - 发起connect和disconnect。 - - ``` - { - // ability发起connect - Want want = { nullptr }; - ElementName element = { nullptr }; - SetElementBundleName(&element, "com.company.appname"); - SetElementAbilityName(&element, "ServiceAbility"); - SetWantElement(&want, element); - ConnectAbility(want, *abilityConnection, this); - - // ability发起disconnect - DisconnectAbility(*abilityConnection); - } - ``` - - - -### 包管理接口使用指导 - -**安装应用** - -安装接口只能给内置的系统应用使用。根据应用的安装路径,可以在安装应用时进行选择: - -- 将应用安装到系统默认的文件目录/storage/app/。 -- 将应用安装到系统外挂的存储介质中,例如micro sdcard。 - -这两种选择可以在创建InstallParam实例的时候指定,当InstallParam的成员变量installLocation为 INSTALL\_LOCATION\_INTERNAL\_ONLY时,意味着应用将会被安装到/storage/app/目录下;当InstallParam的成员变量installLocation为INSTALL\_LOCATION\_PREFER\_EXTERNAL时,意味着应用将被安装到存储介质,其安装目录是/sdcard/app/。由于安装应用的过程是异步的,所以需要使用类似信号量的机制来确保安装的回调可以被执行。 - -安装应用的步骤如下(示例代码以安装到系统目录为例): - -1. 将经过安全签名的应用放置于指定的目录下。 -2. 创建InstallParam实例和信号量。 - - ``` - InstallParam installParam = { - .installLocation = INSTALL_LOCATION_INTERNAL_ONLY, // 安装到系统目录 - .keepData = false - }; - static sem_t g_sem; - ``` - -3. 定义回调函数。 - - ``` - static void InstallCallback(const uint8_t resultCode, const void *resultMessage) - { - std::string strMessage = reinterpret_cast(resultMessage); - if (!strMessage.empty()) { - printf("install resultMessage is %s, %d\n", strMessage.c_str(),resultCode); - } - sem_post(&g_sem); - } - ``` - -4. 调用Install接口。 - - ``` - const uint32_t WAIT_TIMEOUT = 30; - sem_init(&g_sem, 0, 0); - std::string installPath = “/storage/bundle/demo.hap”; // hap包的存储路径 - bool result = Install(installPath.c_str(), &installParam, InstallCallback); - struct timespec ts = {}; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += WAIT_TIMEOUT; // 超时即释放信号量 - sem_timedwait(&g_sem, &ts); - ``` - - -**卸载应用** - -卸载应用的时候可以选择是否保留应用的数据,开发者可以通过创建的InstallParam实例的成员变量keepData来确定。当keepData为true, 卸载应用之后将保留应用的数据,当keepData为false时,卸载应用之后将不会保留应用的数据。 - -1. 创建InstallParam实例和信号量。 - - ``` - static sem_t g_sem; - InstallParam installParam = { - .installLocation = 1, - .keepData = false // 不保留应用数据 - }; - ``` - -2. 定义回调函数。 - - ``` - static void UninstallCallback(const uint8_t resultCode, const void *resultMessage) - { - std::string strMessage = reinterpret_cast(resultMessage); - if (!strMessage.empty()) { - printf("uninstall resultMessage is %s\n", strMessage.c_str()); - g_resultMessage = strMessage; - } - g_resultCode = resultCode; - sem_post(&g_sem); - } - ``` - -3. 调用Uninstall接口。 - - ``` - sem_init(&g_sem, 0, 0); - const uint32_t WAIT_TIMEOUT = 30; - std::string BUNDLE_NAME = “com.huawei.demo”; // 卸载应用的包名 - Uninstall(BUNDLE_NAME.c_str(), &installParam, UninstallCallback); - struct timespec ts = {}; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += WAIT_TIMEOUT; - sem_timedwait(&g_sem, &ts); - ``` - - -**查询已安装应用的包信息** - -开发者可以利用BundleManager提供的接口GetBundleInfo来查询系统内已安装应用的包信息。 - -1. 创建以及初始化BundleInfo。 - - ``` - BundleInfo bundleInfo; - (void) memset_s(&bundleInfo, sizeof(BundleInfo), 0, sizeof(BundleInfo)); - ``` - -2. 调用GetBundleInfo接口,指定查询应用的包名,同时指定flag来确定获取的BundleInfo中是否含有元能力信息(实例代码以含有元能力信息为例)。 - - ``` - std::string BUNDLE_NAME = "com.huawei.demo"; - uint8_t ret = GetBundleInfo(BUNDLE_NAME.c_str(), 1, &bundleInfo); // flags = 1,获取包信息中含有元能力信息 - ``` - -3. 使用完获取的BundleInfo之后,要及时清理掉其内部所占用的内存空间避免内存泄漏。 - - ``` - ClearBundleInfo(&bundleInfo); - ``` - - -### Hap包打包 - -打包工具一般集成到开发工具或者ide中,开发者一般不涉及直接使用该工具,下面的介绍开发者可以作为了解。打包工具的jar包在开源代码中的位置:developtools/packing\_tool/jar。 - -- 打包命令行参数 - - **表 2** 打包所需要的资源文件描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

命令参数

-

对应的资源文件

-

说明

-

是否可缺省

-

--mode

-

-

-

为“hap”字段,打包生成hap

-

-

--json-path

-

清单文件config.json

-

-

-

-

--resources-path

-

资源文件resources

-

-

-

-

--assets-path

-

资源文件assets

-

-

-

-

--lib-path

-

依赖库文件

-

-

-

-

--shared-libs-path

-

共享库文件

-

针对系统应用的共享库,特殊情况下使用

-

-

--ability-so-path

-

主功能so文件

-

-

-

-

--index-path

-

资源索引

-

资源索引文件由资源生成工具生成,由资源流水线会集成该工具

-

-

--out-path

-

-

-

生成的hap包输出路径,默认为当前目录

-

-

--force

-

-

-

是否覆盖原有同名文件,默认为false

-

-
- -- 打包示例 - - 开发视图 - - ![](figures/zh-cn_image_0000001062942690.png) - - - 编译视图 - - ![](figures/zh-cn_image_0000001062334618.png) - - - 使用打包工具执行以下命令打包: - - ![](figures/zh-cn_image_0000001062476933.png) - - ``` - $ java -jar hmos_app_packing_tool.jar --mode hap --json-path ./config.json --assets-path ./assets/ --ability-so-path ./libentry.so --index-path ./resources.index --out-path out/entry.hap --force true - ``` - - - diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 4ef866ea112a9d162a86e22d4a5badacfbfb1b0b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 开发指导 - -为实现AI 引擎框架的接入,开发者需开发上述[图1](AI引擎框架开发指南.md#fig143186187187)中的SDK模块和Plugin模块,通过调用sdk提供的接口,基于AI引擎框架实现调用plugin中算法的能力,从而实现AI能力的生命周期管理和按需部署功能。 - -- **[SDK开发过程](SDK开发过程.md)** - -- **[插件的开发过程](插件的开发过程.md)** - -- **[配置文件的开发过程](配置文件的开发过程.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100755 index 346b8a084afbb9645ee0436d39b12456a2b28625..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,13 +0,0 @@ -# 开发示例 - -以开发唤醒词识别为例,开发者可在Hi3516DV300开发板上,基于AI引擎框架开发唤醒词识别的sdk以及唤醒词识别的plugin,通过编译命令编出新的版本镜像并将其烧入版本。同时,开发者开发唤醒词识别的应用,该应用能够接收外部音频,将listen到的音频传入SDK中的接口,若音频中带有关键词,唤醒词识别的应用会识别出相应的词语,并打印在命令行中。 - -本示例中唤醒词识别的场景中唤醒词是固定的,当开发者传入的音频包含”Hi,小问“,启动的应用就会打印"\[Hi, xiaowen\]",当不包含时,会打印'\[UNKNOWN\]"。 - -- **[唤醒词识别SDK的开发示例](唤醒词识别SDK的开发示例.md)** - -- **[唤醒词识别插件的开发示例](唤醒词识别插件的开发示例.md)** - -- **[唤醒词识别配置文件的开发示例](唤醒词识别配置文件的开发示例.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\346\212\200\346\234\257\350\247\204\350\214\203.md" "b/zh-cn/device-dev/subsystems/\346\212\200\346\234\257\350\247\204\350\214\203.md" deleted file mode 100755 index e2497a9e3850d12fc57e61924b8f6b0b2451d7d9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\212\200\346\234\257\350\247\204\350\214\203.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 技术规范 - -**用词约定:** - -**规则:**必须准守的约定 - -**建议:**需要加以考虑的约定 - -- **[代码管理规范](代码管理规范.md)** - -- **[命名规范](命名规范.md)** - -- **[接口开发规范](接口开发规范.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 2b37619913040891523cba68ded948d628a273f5..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,395 +0,0 @@ -# 拍照开发指导 - -- [使用场景](#section1963312376119) -- [接口说明](#section56549532016) -- [约束与限制](#section1165911177314) -- [开发步骤](#section138543918214) - -## 使用场景 - -使用Camera产生图片帧(拍照)。 - -## 接口说明 - -**表 1** API列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

类名

-

接口名

-

描述

-

CameraKit

-

int32_t GetCameraIds(std::list<string> cameraList)

-

获取cameraId列表

-

CameraKit

-

CameraAbility& GetCameraAbility(string cameraId)

-

获取指定camera的能力

-

CameraKit

-

void RegisterCameraDeviceCallback(CameraDeviceCallback* callback, EventHandler* handler)

-

注册camera设备状态回调

-

CameraKit

-

void UnregisterCameraDeviceCallback(CameraDeviceCallback* callback)

-

去注册camera设备状态回调

-

CameraKit

-

void CreateCamera(string cameraId, CameraStateCallback* callback, EventHandler* handler)

-

创建camera实例

-

Camera

-

string GetCameraId()

-

获取cameraID

-

Camera

-

CameraConfig& GetCameraConfig()

-

获取camera配置信息

-

Camera

-

FrameConfig& GetFrameConfig(int32_t type)

-

获取捕获帧类型

-

Camera

-

void Configure(CameraConfig& config)

-

配置camera

-

Camera

-

void Release()

-

释放camera

-

Camera

-

int TriggerLoopingCapture(FrameConfig& frameConfig)

-

开始循环帧捕获

-

Camera

-

void StopLoopingCapture()

-

停止循环帧捕获

-

Camera

-

int32_t TriggerSingleCapture(FrameConfig& frameConfig)

-

抓图

-

CameraConfig

-

void SetFrameStateCallback(FrameStateCallback* callback, EventHandler* handler);

-

设置帧状态回调

-

CameraConfig

-

static CameraConfig* CreateCameraConfig()

-

创建camera配置信息实例

-

CameraAbility

-

std::list<Size> GetSupportedSizes(int format)

-

根据类型获取支持输出图像尺寸大小

-

CameraAbility

-

std::list<T> GetParameterRange(uint32_t key)

-

获取支持的参数范围

-

CameraDevice

-

CameraDeviceCallback()

-

camera设备回调类构造函数

-

CameraDevice

-

void OnCameraStatus​(std::string cameraId, int32_t status)

-

camera设备状态变化时的回调

-

CameraStateCallback

-

CameraStateCallback​()

-

camera状态回调类构造函数

-

CameraStateCallback

-

void OnConfigured​(Camera& camera)

-

camera配置成功回调

-

CameraStateCallback

-

void OnConfigureFailed​(Camera& camera,int32_t errorCode)

-

camera配置失败回调

-

CameraStateCallback

-

void OnCreated​(Camera& camera)

-

camera创建成功回调

-

CameraStateCallback

-

void OnCreateFailed​(std::string cameraId,int32_t errorCode)

-

camera创建失败回调

-

CameraStateCallback

-

void OnReleased​(Camera& camera)

-

camera释放回调

-

FrameStateCallback

-

FrameStateCallback​()

-

帧状态回调类构造函数

-

FrameStateCallback

-

void OnFrameFinished(Camera& camera, FrameConfig& frameConfig, FrameResult& frameResult)

-

拍照帧完成回调

-

FrameStateCallback

-

void OnFrameError​(Camera& camera, FrameConfig& frameConfig, int32_t errorCode, FrameResult& frameResult)

-

拍照帧异常回调

-

FrameConfig

-

int32_t GetFrameConfigType()

-

获取帧配置类型

-

FrameConfig

-

std::list<OHOS::Surface> GetSurfaces()

-

获取帧配置的surface

-

FrameConfig

-

void AddSurface(OHOS::AGP::UISurface& surface);

-

添加surface

-

FrameConfig

-

void RemoveSurface(OHOS::AGP::UISurface& surface);

-

删除surface

-
- -## 约束与限制 - -无。 - -## 开发步骤 - -1. 实现设备状态回调的派生类,用户在设备状态发生变更(如新插入相机设备/相机掉线)时,自定义操作。 - - ``` - class SampleCameraDeviceCallback : public CameraDeviceCallback { - void OnCameraStatus(std::string cameraId, int32_t status) override - { - //do something when camera is available/unavailable - } - }; - ``` - -2. 实现帧事件回调的派生类,这里在拿到帧数据以后将其转存为文件。 - - ``` - static void SampleSaveCapture(const char *p, uint32_t size) - { - cout << "Start saving picture" << endl; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm *ltm = localtime(&tv.tv_sec); - if (ltm != nullptr) { - ostringstream ss("Capture_"); - ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg"; - - ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc); - cout << "write " << size << " bytes" << endl; - pic.write(p, size); - cout << "Saving picture end" << endl; - } - } - - class TestFrameStateCallback : public FrameStateCallback { - void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override - { - cout << "Receive frame complete inform." << endl; - if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) { - cout << "Capture frame received." << endl; - list surfaceList = fc.GetSurfaces(); - for (Surface *surface : surfaceList) { - SurfaceBuffer *buffer = surface->AcquireBuffer(); - if (buffer != nullptr) { - char *virtAddr = static_cast(buffer->GetVirAddr()); - if (virtAddr != nullptr) { - SampleSaveCapture(virtAddr, buffer->GetSize()); - } - surface->ReleaseBuffer(buffer); - } - delete surface; - } - delete &fc; - } - } - }; - ``` - -3. 实现相机状态回调的派生类,当相机状态发生变化(配置成功/失败,创建成功/失败\)时,自定义操作。 - - ``` - class SampleCameraStateMng : public CameraStateCallback { - public: - SampleCameraStateMng() = delete; - SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {} - ~SampleCameraStateMng() - { - if (recordFd_ != -1) { - close(recordFd_); - } - } - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {} - void OnReleased(Camera &c) override {} - }; - ``` - -4. 创建CameraKit,用于创建和获取camera信息。 - - ``` - CameraKit *camKit = CameraKit::GetInstance(); - list camList = camKit->GetCameraIds(); - string camId; - for (auto &cam : camList) { - cout << "camera name:" << cam << endl; - const CameraAbility *ability = camKit->GetCameraAbility(cam); - /* find camera which fits user's ability */ - list sizeList = ability->GetSupportedSizes(0); - if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) { - camId = cam; - break; - } - } - ``` - -5. 创建Camera实例。 - - ``` - EventHandler eventHdlr; // Create a thread to handle callback events - SampleCameraStateMng CamStateMng(eventHdlr); - - camKit->CreateCamera(camId, CamStateMng, eventHdlr); - ``` - -6. 根据[步骤1](#li378084192111)、[步骤2](#li8716104682913)、[步骤3](#li6671035102514)中的回调设计,camera实例创建成功后会进行配置操作,主流程中app需要设计同步机制。 - - ``` - void OnCreated(Camera &c) override - { - cout << "Sample recv OnCreate camera." << endl; - auto config = CameraConfig::CreateCameraConfig(); - config->SetFrameStateCallback(&fsCb_, &eventHdlr_); - c.Configure(*config); - cam_ = &c; - } - - void Capture() - { - if (cam_ == nullptr) { - cout << "Camera is not ready." << endl; - return; - } - FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE); - Surface *surface = Surface::CreateSurface(); - if (surface == nullptr) { - delete fc; - } - surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ - fc->AddSurface(*surface); - cam_->TriggerSingleCapture(*fc); - } - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203-2.md" "b/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203-2.md" deleted file mode 100755 index 272f0279421d4978f9630781b67300a5888ef970..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203-2.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 搭建环境 - -- 开发板:Hi3516DV300 - -- [下载源码](../get-code/源码获取.md) -- [编译用户程序框架](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E7%94%A8%E6%88%B7%E7%A8%8B%E5%BA%8F%E6%A1%86%E6%9E%B6%E5%AD%90%E7%B3%BB%E7%BB%9F.md) - diff --git "a/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203.md" "b/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203.md" deleted file mode 100755 index 47fefd53336be6b712b10a85c4ba32aec3e63d6f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203.md" +++ /dev/null @@ -1,5 +0,0 @@ -# 搭建环境 - -1. 准备开发板:Hi3516DV300,Hi3518EV300 -2. [下载源码](https://device.harmonyos.com/cn/docs/start/get-code/oem_sourcecode_guide-0000001050769927#ZH-CN_TOPIC_0000001050769927__section1186691118430) - diff --git "a/zh-cn/device-dev/subsystems/\346\231\256\351\200\232\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\346\231\256\351\200\232\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 2c417f20a485aa9f6e6bbb303048baacbc30809b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\231\256\351\200\232\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,555 +0,0 @@ -# 普通组件开发指导 - -- [UIButton](#section145353310214) -- [使用场景](#section1169616141577) -- [接口说明](#section341211538315) -- [开发步骤](#section22501726193214) -- [UIImageView](#section19523161611259) -- [使用场景](#section1274484210400) -- [接口说明](#section74981992411) -- [开发步骤(自适应)](#section144341333134114) -- [开发步骤(平铺模式)](#section97178160421) -- [UILabel](#section16588132012911) -- [使用场景](#section6870195634218) -- [接口说明](#section2012714510433) -- [开发步骤(默认模式)](#section83221538114410) -- [开发步骤(背景色和透明度)](#section933360204510) -- [开发步骤(字符间距)](#section19447826124518) -- [开发步骤(大小自适应)](#section101711842154617) -- [开发步骤(省略号模式)](#section1249519410471) -- [开发步骤(滚动模式)](#section15643122618478) - -普通组件均继承于基类UIView,不可以添加子组件,常用的普通组件有button、image、label等。 - -**图 1** 普通组件树结构 -![](figures/普通组件树结构.png "普通组件树结构") - -UIView为基础类,UIAbstractProgress、UIArcLabel(旋转字体)、UIButton(按键)、UICanvas(画布)、UILabel(字体)、UIImageView(图片)从UIView继承。UIBoxProgress、UICircleProgress从UIAbstractProgress继承,UILabelButton和UIRepeatButton从UIButton继承,UIImageAnimatorView和UITextureMapper从UIImageView继承。 - -## UIButton - -## 使用场景 - -UIButton组件,提供可点击功能,同时可设置不同状态下样式。 - -## 接口说明 - -**表 1** button接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

方法

-

功能

-

void SetImageSrc (const char *defaultImgSrc, const char *triggeredImgSrc)

-

设置button图片

-

void SetImagePosition (const int16_t x, const int16_t y)

-

设置button图片位置

-

int16_t GetImageX () const

-

获取图片X坐标

-

int16_t GetImageY () const

-

获取图片Y坐标

-

const ImageInfo* GetCurImageSrc() const

-

获取当前状态图片

-

Style& GetStyleForState (ButtonState state)

-

设置button当前状态的style

-

voidSetStyleForState (const Style &style, ButtonState state)

-

设置button指定状态的style

-

void Disable ()

-

去使能button

-

void Enable ()

-

使能button

-
- -## 开发步骤 - -1. 实现点击事件。 - - ``` - class TestBtnOnClickListener : public OHOS::UIView::OnClickListener { - bool OnClick(UIView& view, const ClickEvent& event) override - { - int16_t width = view.GetWidth() + 10; - int16_t height = view.GetHeight() + 10; - view.Resize(width, height); - view.Invalidate(); - return true; - } - }; - ``` - -2. 创建一个UIButton。 - - ``` - UIButton* button = new UIButton(); - button->SetPosition(50, 50); - button->SetWidth(100); - button->SetHeight(50); - ``` - -3. 给UIButton注册点击事件回调。 - - ``` - button->SetOnClickListener(new TestBtnOnClickListener()); - ``` - -4. 检查Button点击效果如下图所示,Button逐渐变大。 - - **图 2** UIButton点击效果 - ![](figures/UIButton点击效果.gif "UIButton点击效果") - - -## UIImageView - -## 使用场景 - -图片组件,提供图片显示,透明度设置,图片旋转、缩放功能。支持的图片格式为RGB565、RGB888、RGBA8888、PNG、JPG。 - -## 接口说明 - -**表 2** image接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

方法

-

功能

-

void SetSrc (const char *src)

-

设置二进制图片路径

-

void SetSrc (const ImageInfo *src)

-

设置图片指针

-

void SetAutoEnable (bool enable)

-

设置组件大小跟随image大小变化

-

const void* GetSrcType () const

-

获取图片类型

-

bool GetAutoEnable () const

-

获取组件大小是否跟随image大小变化

-

void SetBlurLevel(BlurLevel level)

-

设置模糊等级

-

BlurLevel GetBlurLevel() const

-

获取模糊等级

-

void SetTransformAlgorithm(TransformAlgorithm algorithm)

-

设置旋转算法

-

TransformAlgorithm GetTransformAlgorithm() const

-

获取旋转算法

-
- -## 开发步骤(自适应) - -1. 创建一个UIImageView。 - - ``` - UIImageView* imageView = new UIImageView(); - imageView->SetPosition(0, 30); - ``` - -2. 设置二进制格式的图片。 - - ``` - imageView->SetSrc("..\\config\\images\\A021_001.bin"); - ``` - -3. 检查UIImageView控件大小与图片相同。 - - **图 3** 自适应模式图片效果图 - ![](figures/自适应模式图片效果图.png "自适应模式图片效果图") - - -## 开发步骤(平铺模式) - -1. 创建一个UIImageView。 - - ``` - UIImageView* imageView = new UIImageView(); - imageView->SetPosition(0, 30); - ``` - -2. 设置图片。 - - ``` - imageView->SetSrc("..\\config\\images\\A021_001.bin"); - ``` - -3. 取消图片自适应,设置图片大小,平铺显示效果。 - - ``` - imageView->SetAutoEnable(false); - imageView->Resize(454, 150); - ``` - -4. 检查UIImageView控件显示为平铺效果。 - - **图 4** 平铺模式图片效果图 - ![](figures/平铺模式图片效果图.png "平铺模式图片效果图") - - -## UILabel - -## 使用场景 - -标签(label)是在一块区域上显示文本字符串的组件,可设置区域背景色、文字的显示样式和长文本的显示效果等。 - -## 接口说明 - -**表 3** label接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

方法

-

功能

-

void SetText(const char* text);

-

设置文字

-

const char* GetText() const;

-

获取text

-

void SetLineBreakMode(const uint8_t lineBreakMode);

-

设置label模式,例如截断,自动扩展等。

-

uint8_t GetLineBreakMode() const

-

获取label模式

-

void SetTextColor(ColorType color)

-

设置文本颜色

-

ColorType GetTextColor() const

-

获取文本颜色

-

void SetAlign(UITextLanguageAlignment horizontalAlign,

-

UITextLanguageAlignment verticalAlign = TEXT_ALIGNMENT_TOP);

-

设置文本对齐方式

-

UITextLanguageAlignment GetHorAlign() const

-

获取文本水平对齐方式

-

UITextLanguageAlignment GetVerAlign() const

-

获取文本竖直对齐方式

-

void SetDirect(UITextLanguageDirect direct)

-

设置文本显示方向

-

UITextLanguageDirect GetDirect() const

-

获取文本显示方向

-

void SetFontId(uint8_t fontId);

-

设置动态字体id

-

uint8_t GetFontId() const

-

获取动态字体id

-

void SetFont(const char *name, uint8_t size);

-

设置字的名字和大小

-

void SetAnimatorSpeed(uint16_t animSpeed);

-

设置字体旋转的速度

-

uint16_t GetTextWidth();

-

获取字体的宽

-

uint16_t GetTextHeight();

-

获取字体的高

-

void SetRollStartPos(int16_t pos)

-

设置旋转的位置

-

int16_t GetRollStartPos() const

-

获取旋转的位置

-

void SetTextRotation(LabelRotateDegree angle)

-

设置文本旋转角度枚举值

-

LabelRotateDegree GetTextRotation() const

-

获取文本旋转角度枚举值

-

uint16_t GetTextRotateDegree() const

-

获取文本旋转角度数值

-
- -## 开发步骤(默认模式) - -1. 创建label,设置大小和位置信息。 - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. 设置字形信息。 - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. 设置文本数据。 - - ``` - label->SetText("label"); - ``` - -4. 检查label大小和显示效果正常,如下图所示。 - - ![](figures/zh-cn_image_0000001051782526.png) - - -## 开发步骤(背景色和透明度) - -1. 创建label,设置大小和位置信息。 - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. 设置字形信息。 - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. 设置背景颜色及透明度效果。 - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetStyle(STYLE_BACKGROUND_OPA, 127); - label->SetText("Label"); - ``` - -4. 检查label背景色为Gray,如下图所示。 - - ![](figures/zh-cn_image_0000001052582522.png) - - -## 开发步骤(字符间距) - -1. 创建label,设置大小和位置信息。 - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. 设置字形信息。 - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. 设置字体颜色和字间距效果。 - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetStyle(STYLE_LETTER_SPACE, 5); - label->SetText("Label"); - ``` - -4. 检查label字符间距为5,如下图所示。 - - ![](figures/zh-cn_image_0000001052942531.png) - - -## 开发步骤(大小自适应) - -当文本过长时,可根据文本信息自动调整label组件大小,也可以设置文本截断或者文本滚动效果。 - -1. 创建label,设置大小和位置信息。 - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. 设置字形信息。 - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. 设置字体颜色为Gray,组件大小自适应文本内容。 - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); - label->SetText("123\n567890"); - ``` - -4. 检查label大小自适应文本内容,如下图所示。 - - ![](figures/zh-cn_image_0000001052782555.png) - - -## 开发步骤(省略号模式) - -省略号模式指文本内容显示不下时,在末尾显示省略号。 - -1. 创建label,设置大小和位置信息。 - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. 设置字形信息。 - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. 设置换行模式为DOT模式 - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); - label->SetText("123567890"); - ``` - -4. 检查label DOT模式效果,如下图所示,末尾显示省略号。 - - ![](figures/zh-cn_image_0000001052662559.png) - - -## 开发步骤(滚动模式) - -文本滚动显示。 - -1. 创建label,设置大小和位置信息。 - - ``` - UILabel* label = new UILabel(); - label->SetPosition(x, y); - label->Resize(width, height); - ``` - -2. 设置字形信息。 - - ``` - label->SetFont("SourceHanSansSC-Regular.otf", 30); - ``` - -3. 设置换行模式为滚动模式 - - ``` - label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); - label->SetStyle(STYLE_BACKGROUND_OPA, 127); - label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); - label->SetText("123567890"); - ``` - -4. 检查label滚动模式效果,如下图所示。 - - ![](figures/20200721-223604(eSpace).gif) - - diff --git "a/zh-cn/device-dev/subsystems/\346\240\207\345\207\206\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\346\240\207\345\207\206\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" deleted file mode 100644 index 6c6cf033328d93b995af036b0607bb9c31bb37ef..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\240\207\345\207\206\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 标准系统编译构建指导 - -- **[编译构建概述](编译构建概述-0.md)** - -- **[编译构建使用指导](编译构建使用指导-1.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260-7.md" "b/zh-cn/device-dev/subsystems/\346\246\202\350\277\260-7.md" deleted file mode 100644 index 45d0d3267613ee990ad09557a99fb18a311c5efe..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260-7.md" +++ /dev/null @@ -1,76 +0,0 @@ -# 概述 - -- [基本概念](#section175012297491) -- [约束与限制](#section2029921310472) - -OpenHarmony安全子系统目前提供给开发者的安全能力主要包含应用可信、权限管理、设备可信。涉及以下几个模块: - -- 应用验签 - - 为了确保应用内容的完整性,系统通过应用签名和Profile对应用的来源进行管控,同时对于调试应用,还可通过验签接口验证应用和设备的UDID是否匹配,确保应用安装在了正确的设备上。 - -- 应用权限管理 - - 应用权限是管理应用访问系统资源和使用系统能力的一种通用方式,应用在开发阶段需要在profile.json中指明此应用在运行过程中可能会调用哪些权限,其中静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示涉及到敏感信息,所以需要用户进行动态授权。 - -- IPC通信鉴权 - - 系统服务通过IPC暴露接口给其他进程访问,这些接口需要配置相应的访问策略,当其他进程访问这些接口时,将会触发IPC通信鉴权机制校验访问进程是否拥有权限访问该接口,若无权限,则拒绝访问该接口。 - -- 可信设备群组管理 - - 提供基于群组概念的同华为账号群组、点对点群组(如二维码、碰一碰等)的设备安全可信关系的创建和查询,分布式应用可基于该能力进行设备间的可信认证,然后向分布式软总线请求设备间安全会话。 - - -## 基本概念 - -在进行依赖验签组件的应用开发前,开发者应了解以下基本概念: - -- Samgr - - Samgr\(System Ability M2anager\)系统能力管理,在OpenHarmony上作为一个管理系统能力的模块,详见系统服务框架子系统。 - - -- BMS - - BMS\(Bundle Manager Service\)包管理管理,在OpenHarmony上主要负责应用的安装、卸载和数据管理。 - - -- 描述文件 - - 本文中的描述文件,指HarmonyAppProvision,简称profile。HarmonyAppProvision采用json文件格式进行描述。 - - -- 叶子证书 - - 最终用于为整包或profile签名的证书称为叶子证书,位于数字证书链的最末端。 - - -- 调试应用 - - 指开发者从应用市场申请调试证书与调试描述文件,并以此签名的hap包。 - - -- 待上架应用 - - 指开发者从应用市场申请发布证书与发布描述文件,以此签名,未通过应用市场正式发布的hap包。 - - -- 发布应用 - - 指开发者从应用市场申请发布证书与发布描述文件,以此签名的hap包,上传至应用市场,并由应用市场正式发布的hap包。 - - -- OpenHarmony自签名应用 - - 当开发者自行编译OpenHarmony系统应用后,采用原应用描述文件,以及公开的OpenHarmony公私钥对和证书进行自签名产生的hap包。 - - -## 约束与限制 - -- 仅支持以下三类应用的验签:应用市场调试应用、应用市场发布应用、OpenHarmony自签名应用的验签。 -- 若对应用市场调试应用验签,则本机UDID需要在描述文件包含的UDID列表中。 -- 待上架应用无法验签通过。 -- 验签组件提供的接口都位于security\_interfaces\_innerkits\_app\_verify仓[app\_verify\_pub.h](https://gitee.com/fork_ohos_wj/security_interfaces_innerkits_app_verify/blob/master/app_verify_pub.h)中,仅支持系统应用开发者调用。 -- 可信设备群组管理接口,目前只对系统签名权限才可以使用。 - diff --git "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260.md" "b/zh-cn/device-dev/subsystems/\346\246\202\350\277\260.md" deleted file mode 100755 index 63ee16f94ce7de540c47dae8ab52a5aef504889b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260.md" +++ /dev/null @@ -1,141 +0,0 @@ -# 概述 - -- [基本概念](#section72601941194812) -- [Ability子系统](#section14633111813374) -- [包管理子系统](#section1341146154412) -- [运作机制](#section94302021112717) -- [约束与限制](#section89534912527) - -用户程序框架是OpenHarmony为开发者提供开发OpenHarmony应用的开发框架,包含两个模块:Ability子系统和包管理子系统。 - -## 基本概念 - -开发者在开发前需要先了解以下基本概念,方便开发者更好的理解OpenHarmony用户程序框架。 - -## Ability子系统 - -Ability子系统是管理OpenHarmony应用运行状态的开发框架。 - -**图 1** Ability子系统框架图 -![](figures/Ability子系统框架图.png "Ability子系统框架图") - -- **Ability**:系统调度应用的最小单元,是能够完成一个独立功能的组件,一个应用可以包含一个或多个Ability。Ability分为两种类型:Page类型的Ability和Service类型的Ability。 - - **Page类型的Ability**:带有界面,为用户提供人机交互的能力。 - - - **Service类型的Ability**:不带界面,为用户提供后台任务机制。 - - - -- **AbilitySlice**:单个页面及其控制逻辑的总和,是Page类型Ability特有的组件,一个Page类型的Ability可以包含多个AbilitySlice,此时,这些页面提供的业务能力应当是高度相关的。 - - **图 2** Ability与AbilitySlice的关系图 - ![](figures/Ability与AbilitySlice的关系图.png "Ability与AbilitySlice的关系图") - -- **生命周期**:Ability被调度到启动、激活、隐藏和退出等各个状态的统称。 - - **图 3** Ability生命周期流转 - - - ![](figures/图片1.png) - - - **OnStart\(\)** - - 系统首次创建Page实例时触发该回调。对于一个Page实例,该回调在其生命周期过程中仅触发一次,Page在该逻辑后进入INACTIVE状态。开发者必须重写该方法,并在此配置默认展示的AbilitySlice。 - - - **OnActive\(\)** - - Page会在进入INACTIVE状态后来到前台,然后系统调用此回调。Page在此之后进入ACTIVE状态,该状态是应用与用户交互的状态。Page将保持在此状态,除非某类事件发生导致Page失去焦点,比如用户点击返回键或导航到其他Page。 - - 当此类事件发生时,会触发Page回到INACTIVE状态,系统将调用OnInactive\(\)回调。此后,Page可能重新回到ACTIVE状态,系统将再次调用OnActive\(\)回调。因此,开发者通常需要成对实现OnActive\(\)和OnInactive\(\),并在OnActive\(\)中获取在OnInactive\(\)中被释放的资源。 - - - **OnInactive\(\)** - - 当Page失去焦点时,系统将调用此回调,此后Page进入INACTIVE状态。开发者可以在此回调中实现Page失去焦点时应表现的恰当行为。 - - - **OnBackground\(\)** - - 如果Page不再对用户可见,系统将可能根据资源状况调用此回调,此后Page进入BACKGROUND状态。开发者应该在此回调中释放Page不可见时无用的资源,或在此回调中执行较为耗时的状态保存操作。 - - - **OnForeground\(\)** - - 处于BACKGROUND状态的Page仍然驻留在内存中,当重新回到前台时(比如用户重新导航到此Page),系统将先调用OnForeground\(\)回调使Page回到INACTIVE状态,然后调用OnActive\(\)回调使Page回到ACTIVE状态。开发者应当在此回调中重新申请在OnBackground\(\)中释放的资源。轻量化设备目前不支持该接口。 - - - **OnStop\(\)** - - 此回调表示系统正在销毁Page。销毁Page的可能原因包括: - - - 用户通过系统管理能力显式关闭Page,例如使用任务管理器关闭Page。 - - 用户行为触发Page的TerminateAbility\(\)方法调用,例如使用应用的退出功能。 - - 配置变更导致系统暂时销毁Page并重建。 - - 系统出于资源管理目的,自动触发对处于BACKGROUND状态Page的销毁。 - - -- **AbilityKit**:Ability框架提供给开发者的开发包,开发者基于该开发包可以开发出基于Ability组件的应用。基于Ability组件开发的应用有两种类型:基于Javascript语言开发的Ability(JS Ability)和基于C/C++语言开发的Ability(Native Ability)。JS应用开发框架是开发者开发JS Ability所用到框架,是在AbilityKit基础封装的包含js UI组件的一套方便开发者能够迅速开发Ability应用的框架。 -- **AbilityLoader**:负责注册和加载开发者Ability的模块。开发者开发的Ability先要调用AbilityLoader的注册接口注册到框架中,接着Ability启动时会被实例化。 - -- **AbilityManager**:负责AbilityKit和Ability管理服务进行IPC的通信。 - -- **EventHandler**:AbilityKit提供给开发者的用于在Ability中实现线程间通信的一个模块。 - -- **AbilityManagerService**:元能力运行管理服务。该服务用于协调各Ability运行关系、及生命周期进行调度的系统服务。其中,服务启动模块负责Ability管理服务的启动、注册等。服务接口管理模块负责Ability管理服务对外能力的管理。进程管理模块负责Ability应用所在进程的启动和销毁、及其进程信息维护等功能。Ability栈管理模块负责维护各个Ability之间跳转的先后关系。生命周期调度模块是Ability管理服务根据系统当前的操作调度Ability进入相应的状态的模块。连接管理模块是Ability管理服务对Service类型Ability连接管理的模块 - -- **AppSpawn**:负责创建Ability应用所在进程的系统服务,该服务有较高的权限,为Ability应用设置相应的权限,并预加载一些通用的模块,加速应用的启动。 - - -## 包管理子系统 - -包管理子系统是OpenHarmony为开发者提供的安装包管理框架。 - -**图 4** 包管理子系统框架图 -![](figures/包管理子系统框架图.png "包管理子系统框架图") - -- **BundleKit**:是包管理服务对外提供的接口,有安装/卸载接口、包信息查询接口、包状态变化listen接口。 -- **包扫描器**:用来解析本地预制或者安装的安装包,提取里面的各种信息,供管理子模块进行管理,持久化。 -- **包安装子模块**:安装,卸载,升级一个包;包安装服务是一个单独进程和包管理服务通过IPC进行通信,该服务用于创建、删除安装目录和数据目录等,具有较高的权限。 - -- **包管理子模块**:管理安装包相关的信息,存储持久化包信息。 - -- **包安全管理子模块**:签名检查、权限授予、权限管理。 - - -## 运作机制 - -Ability子系统的核心模块是Ability管理服务、包管理子系统的核心模块是包管理服务,这两个服务是系统级服务,借助系统服务框架Samgr实现服务的注册与发现,并对其他进程提供Ability管理服务和包管理服务。Ability管理服务和包管理服务通过AbilityKit和BundleKit以接口的形式向外提供服务。 - -**图 5** Ability管理服务和包管理服务启动 -![](figures/Ability管理服务和包管理服务启动.png "Ability管理服务和包管理服务启动") - -Ability管理服务和包管理服务启动后,就可以安装OpenHarmony应用和启动运行OpenHarmony应用。 - -**图 6** 应用启动流程 -![](figures/应用启动流程.png "应用启动流程") - -桌面为Ability管理服务启动的第一个OpenHarmony应用。桌面启动后,用户可以在桌面上点击安装的OpenHarmony应用并启动该应用。上图6为从桌面启动一个已安装应用的交互流程。 - -从图中可知,Ability管理服务负责协调Ability之间的显示隐藏,包管理服务负责Ability信息的存储查询。 - -## 约束与限制 - -- 语言版本 - - - C++11版本或以上 - - -- 框架针对不同的芯片平台和底层OS能力,规格有所区别 - - - Cortex-M RAM/ROM: - - - RAM:建议大于20K - - - ROM: \> 300K (包含JS应用开发框架,UIKit及引擎等强相关子系统) - - - - Cortex-A RAM/ROM: - - - RAM:建议大于2M - - - ROM:\> 2M (包含JS应用开发框架,UIKit及引擎等强相关子系统) - - - - diff --git "a/zh-cn/device-dev/subsystems/\346\265\213\350\257\225.md" "b/zh-cn/device-dev/subsystems/\346\265\213\350\257\225.md" deleted file mode 100755 index ee62074e9be367efea0a74fa180c801d6381ef42..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\265\213\350\257\225.md" +++ /dev/null @@ -1,989 +0,0 @@ -# 测试 - -- [概述](#section12403172115920) - - [基本概念](#section53632272090) - - [运作机制](#section2394431106) - -- [约束与限制](#section2029921310472) -- [搭建环境](#section175012297491) - - [环境要求](#section935055691014) - - [安装环境](#section6511193210111) - - [检验环境是否搭建成功](#section1899144517117) - -- [开发指导](#section16741101301210) - - [场景介绍](#section93782214124) - - [接口说明](#section54131732101218) - - [开发步骤](#section53541946111218) - -- [开发实例](#section7477121918136) -- [测试平台使用](#section76401945124810) -- [包结构说明](#section1875515364133) - -## 概述 - -### 基本概念 - -测试子系统提供基于python开发的一键式的开发者自测试平台,支持跨平台使用以及三方测试框架拓展,主要包括测试用例编译、测试用例管理、测试用例调度分发、测试用例执行、测试结果收集、测试报告生成、测试用例模板、测试环境管理等模块。 - -在测试子系统开发前,开发者应先了解以下概念: - -- 测试用例编译 - - 支持将测试用例源代码编译成可在被测设备侧执行的二进制文件。 - -- 测试用例调度分发 - - 支持将测试用例通过网口通道或者串口通道分发到不同的被测设备上,并且为每一个测试用例分配特定的测试用例执行器。 - -- 测试用例执行器 - - 负责测试用例的预处理,用例执行,结果记录等执行逻辑。 - -- 测试用例模板 - - 定义了测试用例以及用例编译配置GN文件的统一格式。 - -- 测试平台kit - - 测试平台运行过程中公共方法,如提供测试用例目录向被测设备挂载文件系统,测试用例推送到被测设备,或者从被测设备获取测试结果等操作。 - -- 测试报告生成 - - 定义开发者自测试报告模板,生成web测试报告。 - -- 测试环境管理 - - 支持通过USB、串口等方式管理被测设备,功能包括设备发现,设备状态查询等。 - - -### 运作机制 - -- 测试平台架构图如下: - -**图 1** 测试平台架构 -![](figures/测试平台架构.png "测试平台架构") - -- 测试平台运行时序图如下: - -**图 2** 测试平台运行时序 -![](figures/测试平台运行时序.png "测试平台运行时序") - -- 测试平台运行原理 - -测试平台通过shell脚本启动,以命令行方式支持一系列的测试指令执行,通过命令行输出测试结果。 - -## 约束与限制 - -- 功能使用范围:开发自测试平台仅支持代码级的测试用例开发和验证,如单元测试,模块测试。 -- 规格限制:当前测试框架的适用范围仅支持白盒测试。 -- 操作限制:一台测试设备上仅支持启动单个测试平台。 - -## 搭建环境 - -### 环境要求 - -**表 1** **环境要求** - - - - - - - - - - - - - - - - -

项目

-

测试设备

-

被测设备

-

硬件

-
  • 内存:8G及以上
  • 硬盘:100G及以上
  • 硬件架构:X86或ARM64
-
  • Hi3516 DV300开发板
  • Hi3518 EV300开发板
-

软件

-
  • 操作系统:Windows 10 64位 或 Ubuntu 18.04

    系统组件(Linux): libreadline-dev

    -
  • Python:3.7.5及以上
  • Python插件:pyserial3.3及以上、paramiko2.7.1及以上、setuptools40.8.0及以上,rsa4.0及以上
  • NFS Server:haneWIN NFS Server1.2.50及以上或者 NFSv4及以上
-
  • 系统软件:版本不低于OpenHarmony 1.0
  • 内核类型:LiteOS-A或者Linux
-
- -### 安装环境 - -1. 如测试环境为Linux,需要安装系统组件readline,命令如下: - - ``` - sudo apt-get install libreadline-dev - ``` - - 安装成功提示如下: - - ``` - Reading package lists... Done - Building dependency tree - Reading state information... Done - libreadline-dev is already the newest version (7.0-3). - 0 upgraded, 0 newly installed, 0 to remove and 11 not upgraded. - ``` - -2. 安装Python扩展组件setuptools、(rsa、paramiko、以及pyserial,设备仅支持串口时安装),命令如下: - - 1、安装setuptools,安装命令如下: - - ``` - pip install setuptools - ``` - - 安装成功提示如下: - - ``` - Requirement already satisfied: setuptools in d:\programs\python37\lib\site-packages (41.2.0) - ``` - - 2、安装rsa,安装命令如下: - - ``` - pip install rsa - ``` - - 安装成功提示如下: - - ``` - Installing collected packages: pyasn1, rsa - Successfully installed pyasn1-0.4.8 rsa-4.7 - ``` - - 3、安装Paramiko,安装命令如下: - - ``` - pip install paramiko - ``` - - 安装成功提示如下: - - ``` - Installing collected packages: pycparser, cffi, pynacl, bcrypt, cryptography, paramiko - Successfully installed bcrypt-3.2.0 cffi-1.14.4 cryptography-3.3.1 paramiko-2.7.2 pycparser-2.20 pynacl-1.4.0 - ``` - - 4、安装pyserial(被测设备仅支持串口时安装),安装命令如下: - - ``` - pip install pyserial - ``` - - 安装成功提示如下: - - ``` - Requirement already satisfied: pyserial in d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg (3.4) - ``` - -3. 安装NFS server(被测设备仅支持串口时安装)。 - - **Windows环境安装** - - 下载并安装haneWIN NFS Server1.2.50,地址:https://www.hanewin.net/nfs-e.htm - - **Linux环境下安装** - - ``` - sudo apt install nfs-kernel-server - ``` - - 所有环境配置安装完成,即可在IDE中进行测试平台代码开发调试,推荐的IDE为 DevEco Studio。 - - -### 检验环境是否搭建成功 - -**表 2** **检验环境** - - - - - - - - - - - - - - - - - - - - -

检查项

-

操作

-

满足条件

-

检查python安装与否,版本是否满足要求。

-

命令行窗口执行命令:python --version。

-

版本不小于3.7.5即可。

-

检查python扩展插件安装与否。

-

打开test/xdevice目录,执行run.bat或run.sh。

-

可进入提示符“>>>”界面即可。

-

检查NFS Server启动状态(被测设备仅支持串口时检测)。

-

通过串口登录开发板,执行mount命令挂载NFS。

-

可正常挂载文件目录即可。

-
- -## 开发指导 - -### 场景介绍 - -针对对开发的业务代码进行白盒测试验证。 - -### 接口说明 - -测试框架集成了开源的单元测试框架,并对测试用例的宏定义做了扩展,具体框架说明详见开源官方文档。 - -**表 3** 测试框架扩展宏定义说明 - - - - - - - - - - - - - - - - -

宏定义

-

描述

-

HWTEST

-

测试用例执行不依赖Setup&Teardown。HWTEST对TEST增加了“用例级别”参数“TestSize.Level1”,例如HWTEST(CalculatorAddTest, TestPoint_001, TestSize.Level1)。

-

HWTEST_F

-

测试用例(不带参数)执行依赖Setup&Teardown。HWTEST_F对TEST_F增加了“用例级别”参数“ TestSize.Level1”,例如HWTEST_F(CalculatorAddTest, TestPoint_001, TestSize.Level1)。

-

HWTEST_P

-

测试用例(带参数)执行依赖Setup&Teardown。HWTEST_P对TEST_P增加了“用例级别”参数“ TestSize.Level1”,例如HWTEST_P(CalculatorAddTest, TestPoint_001, TestSize.Level1)。

-
- -### 开发步骤 - -1. 按照开发者测试用例目录规划定义测试套文件,需要继承testing::Test类,命名以被测特性+Test命名,示例代码路径:test/developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp - - ``` - /* - * Copyright (c) 2020 OpenHarmony. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include - - using namespace std; - using namespace testing::ext; - - class CalcSubtractionTest : public testing::Test { - public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); - }; - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >测试用例规范 - >- 命名规范 - > 测试用例源文件名称和测试套内容保持一致,测试套与用例之间关系1:N,测试套与测试源文件之间关系1:1,每个源文件全局唯一,格式:\[特性\]\_\[功能\]\_\[子功能1\]\_\[子功能1.1\],子功能支持向下细分。 - > 文件命名采用全小写+下划线方式命名,以test结尾,如demo用例:developertest/examples/lite/cxx\_demo - >- 测试用例编码规范 - > 开发者测试用例原则上与特性代码编码规范保持一致,另外需要添加必要的用例描述信息,详见[•自测试用例模板](#li2069415903917)。 - >- 测试用例编译配置规范 - > 测试用例采用GN方式编译,配置遵循本开源项目的[编译指导](../quick-start/概述.md)。 - >- 测试用例模板 - > 详见测试demo用例:developertest/examples/lite/cxx\_demo/test/unittest/common/calc\_subtraction\_test.cpp - -2. 实现测试套执行过程需要的预处理操作和后处理操作,即实现SetUp和TearDown方法。 - - ``` - void CalcSubtractionTest::SetUpTestCase(void) - { - // step 1: input testsuite setup step - } - - void CalcSubtractionTest::TearDownTestCase(void) - { - // step 2: input testsuite teardown step - } - - void CalcSubtractionTest::SetUp(void) - { - // step 3: input testcase setup step - } - - void CalcSubtractionTest::TearDown(void) - { - // step 4: input testcase teardown step - } - ``` - -3. 针对被测对象的特性编写测试用例,以使用HWTEST\_F为例说明。 - - ``` - /** - * @tc.name: integer_sub_001 - * @tc.desc: Test Calculator - * @tc.type: FUNC - * @tc.require: AR00000000 SR00000000 - */ - HWTEST_F(CalcSubtractionTest, integer_sub_001, TestSize.Level1) - { - EXPECT_EQ(0, Subtraction(1, 0)); - } - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >- @tc.name:用例名称,对测试目的简要描述。 - >- @tc.desc:描述用例详细描述,包括测试目的、测试步骤、期望结果等。 - >- @tc.type:测试属性分类(FUNC、PERF、SECU、RELI)。 - >- @tc.require:需求编号或者issue编号,用来将修改与用例关联。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

序号

-

测试类型名称

-

缩写

-

测试类型描述

-

1

-

功能测试(functionality)

-

FUNC

-

验证软件各个功能满足功能设计与规格。

-

2

-

性能测试(performance)

-

PERF

-

验证软件是否满足性能设计指标。包含负载测试容量测试,压力测试等。

-

3

-

安全性测试(security)

-

SECU

-

验证软件在生命周期内符合安全需求定义和相关法规。

-

4

-

可靠性测试(reliability)

-

RELI

-

在规定的条件下,在规定的时间内,软件不引起系统失效的概率,这里也包含稳定性。

-
- -4. 编写用例编译GN文件,其中包括定义用例编译目标,添加编译配置依赖,源文件等,举例说明: - - 示例文件路径:test/developertest/examples/lite/cxx\_demo/test/unittest/common/BUILD.gn)。 - - ``` - import("//build/lite/config/test.gni") - - unittest("CalcSubTest") { - output_extension = "bin" - sources = [ - "calc_subtraction_test.cpp" - ] - include_dirs = [] - deps = [] - } - ``` - -5. 将用例编译目标添加到子系统编译配置中,保证用例随版本一起编译,举例说明: - 1. 支持hdc连接的设备,编译配置示例路径:test/developertest/examples/ohos.build。 - - ``` - { - "subsystem": "subsystem_examples", - "parts": { - "subsystem_examples": { - "module_list": [ - "//test/developertest/examples/detector:detector", - ... ... - ], - "test_list": [ - "//test/developertest/examples/detector/test:unittest", - ... ... - ] - }, - ... ... - } - ``` - - 2. 仅支持串口的设备,编译配置示例路径:test/developertest/examples/lite/BUILD.gn。 - - ``` - import("//build/lite/config/test.gni") - - subsystem_test("test") { - test_components = [] - if(ohos_kernel_type == "liteos_riscv") { - features += [ - ] - }else if(ohos_kernel_type == "liteos_a") { - test_components += [ - "//test/developertest/examples/lite/cxx_demo/test/unittest/common:CalcSubTest" - ] - } - } - ``` - - -6. 编写测试用例资源配置,当测试用例需要使用静态测试资源文件时使用该配置。 - 1. 在部件或者模块的test目录下创建resource目录。 - 2. 在resource目录下创建形态目录,如phone。 - 3. 在设备形态目录下创建一个以模块名命名的文件夹,如testmodule。 - 4. 在模块目录下创建一个ohos\_test.xml文件,文件内容格式如下: - - ``` - - - - - - - - ``` - - 5. 在测试用例的编译配置文件中定义resource\_config\_file,用来指定对应的资源文件ohos\_test.xml。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如上资源文件功能:将resource目录下的test.txt文件通过hdc push命令推送到被测设备的/data/test/resource目录下。 - - -7. 以上步骤完成即完成测试用例编写,即可执行测试用例。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >- 支持hdc连接的设备,测试用例支持单独编译。 - >- 仅支持串口连接的设备,在代码根路径下执行编译debug版本的命令,即可编译测试用例。 - > 测试用例用例的执行详见[测试平台使用](#section76401945124810)。 - - -## 开发实例 - -测试子系统代码仓提供了完整demo用例,demo用例路径:test/developertest/examples/。以一个减法运算方法编写测试用例举例说明: - -- 被测代码如下: - - ``` - static int Subtraction(int a, int b) - { - return a - b; - } - ``` - -- 测试用例代码如下: - - ``` - /** - * @tc.name: integer_sub_002 - * @tc.desc: Verify the Subtraction function. - * @tc.type: FUNC - * @tc.require: AR00000000 SR00000000 - */ - HWTEST_F(CalcSubtractionTest, integer_sub_002, TestSize.Level1) - { - EXPECT_EQ(1, Subtraction(2, 1)); - } - ``` - - -## 测试平台使用 - -1. (可选)安装xdevice组件。安装xdevice后,xdevice组件可以作为python的扩展包使用。 - - 打开xdevice安装目录:test/xdevice,执行如下命令: - - ``` - python setup.py install - ``` - - 安装成功提示如下: - - ``` - ... ... - Installed d:\programs\python37\lib\site-packages\xdevice-0.0.0-py3.7.egg - Processing dependencies for xdevice==0.0.0 - Searching for pyserial==3.4 - Best match: pyserial 3.4 - Processing pyserial-3.4-py3.7.egg - pyserial 3.4 is already the active version in easy-install.pth - Installing miniterm.py script to D:\Programs\Python37\Scripts - - Using d:\programs\python37\lib\site-packages\pyserial-3.4-py3.7.egg - Finished processing dependencies for xdevice==0.0.0 - ``` - -2. 修改developertest/config/user\_config.xml 文件配置developertest组件。 - 1. 测试框架通用配置。 - - \[build\] \# 配置测试用例的编译参数,例如: - - ``` - - false - false - true - ... ... - - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >测试用例的编译参数说明如下: - >example:是否编译测试用例示例,默认false。 - >version:是否编译测试版本,默认false。 - >testcase:是否编译测试用例,默认true。 - - 2. 支持hdc连接的被测设备。 - - \[device\] \# 配置标签为usb-hdc的环境信息,测试设备的IP地址和hdc映射的端口号,例如: - - ``` - - 192.168.1.1 - 9111 - - - ``` - - 3. 仅支持串口的被测设备。 - - \[board\_info\] \# 开发板配置信息,例如: - - ``` - - hispark - taurus - ipcamera - hb build - - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >开发板配置信息如下: - >board\_series:开发板系列,默认hispark。 - >board\_type:开发板类型,默认taurus。 - >board\_product:目标产品,默认ipcamera。 - >build\_command:测试版本和用例的编译命令,默认hb build。 - - \[device\] \# 配置标签为ipcamera的串口信息,COM口和波特率,例如: - - ``` - - - COM1 - cmd - 115200 - 8 - 1 - 1 - - - ``` - - -3. (可选)修改developertest组件配置。如果测试用例已完成编译,可以直接指定测试用例的编译输出路径,测试平台执行用例时即不会重新编译测试用例。 - - 配置文件:config/user\_config.xml - - 1. \[test\_cases\] \# 指定测试用例的输出路径,编译输出目录,例如: - - ``` - - /home/opencode/out/release/tests - - ``` - - 2. \[NFS\] \# 被测设备仅支持串口时配置,指定NFS的映射路径,host\_dir为PC侧的NFS目录,board\_dir为板侧创建的目录,例如: - - ``` - - D:\nfs - user - - ``` - - -4. (可选)测试环境准备。当被测设备仅支持串口时,需要检查。 - - 系统镜像与文件系统已烧录进开发板,开发板上系统正常运行,在系统模式下,如使用shell登录时,设备提示符是“OHOS\#”。 - - 开发主机和开发板串口连接正常,网口连接正常。 - - 开发主机IP与开发板IP处在同一小网网段,相互可以ping通。 - - 开发主机侧创建空目录用于开发板通过NFS挂载测试用例,并且NFS服务启动正常。 - -5. (必选)启动测试平台,执行测试用例。 - - 启动测试框架,打开test/developertest目录,执行启动脚本。 - 1. Windows环境启动测试框架,执行如下脚本: - - ``` - start.bat - ``` - - 2. Linux环境启动测试框架。 - - ``` - ./start.sh - ``` - - - - 设备形态选择。 - - 根据实际的开发板选择,设备形态配置:developertest/config/framework\_config.xml。 - - - 执行测试指令。 - 1. 查询测试用例支持的子系统,模块,产品形态以及测试类型,使用show命令,示例如下: - - ``` - usage: - show productlist Querying Supported Product Forms - show typelist Querying the Supported Test Type - show subsystemlist Querying Supported Subsystems - show modulelist Querying Supported Modules - ``` - - 2. 执行测试指令,其中-t为必选,-ss和-tm为可选字段,示例如下: - - ``` - run -t ut -ss subsystem_examples -tm calculator - ``` - - 3. 参数说明:指定参数可以执行特定特性、模块对应的测试套。 - - ``` - usage: run [-h] [-p PRODUCTFORM] [-t [TESTTYPE [TESTTYPE ...]]] - [-ss SUBSYSTEM] [-tm TESTMODULE] [-ts TESTSUIT] - [-tc TESTCASE] [-tl TESTLEVEL] - - optional arguments: - -h, --help show this help message and exit - -p PRODUCTFORM, --productform PRODUCTFORM Specified product form - -t [TESTTYPE [TESTTYPE ...]], --testtype [TESTTYPE [TESTTYPE ...]] - Specify test type(UT,MST,ST,PERF,ALL) - -ss SUBSYSTEM, --subsystem SUBSYSTEM Specify test subsystem - -tm TESTMODULE, --testmodule TESTMODULE Specified test module - -ts TESTSUIT, --testsuite TESTSUIT Specify test suite - -tc TESTCASE, --testcase TESTCASE Specify test case - -tl TESTLEVEL, --testlevel TESTLEVEL Specify test level - ``` - - - - 测试框架帮助。 - - 帮助指令,用于查询测试平台支持哪些测试指令,如下: - - ``` - help - ``` - - - 退出自测试平台。 - - 退出自测试平台,使用如下命令退出测试平台,如下: - - ``` - quit - ``` - - -6. (必选)查看测试结果与日志,通过在测试平台中执行测试指令,即可在developertest/reports目录下生成测试日志和测试报告。 - - 测试用例的结果会直接显示在控制台上,执行一次的测试结果根路径如下: - - ``` - reports/xxxx-xx-xx-xx-xx-xx - ``` - - - 测试用例格式化结果目录如下: - - ``` - result/ - ``` - - - 测试用例日志目录如下: - - ``` - log/plan_log_xxxx-xx-xx-xx-xx-xx.log - ``` - - - 测试报告汇总: - - ``` - summary_report.html - ``` - - - 测试报告详情: - - ``` - details_report.html - ``` - - - - 测试平台日志目录如下: - - ``` - reports/platform_log_xxxx-xx-xx-xx-xx-xx.log - ``` - - - -## 包结构说明 - -开发者测试平台xdevice组件包结构说明,代码目录test/xdevice,详见下表所示: - -**表 4** xdevice组件包结构说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

名称

-

功能描述

-

xdevice

-

测试平台基础组件。

-

xdevice/src/xdevice

-

基础测试框架源码。

-

xdevice/config

-

基础测试框架配置文件定义。

-

xdevice/src/xdevice/__main__.py

-

基础测试框架内部入口。

-

xdevice/src/xdevice/__init__.py

-

包依赖定义,插件依赖。

-

xdevice/src/xdevice/variables.py

-

全局变量定义。

-

xdevice/src/xdevice/_core/command

-

用例输入的命令行处理。

-

xdevice/src/xdevice/_core/config

-

基础测试框架的配置管理。

-

xdevice/src/xdevice/_core/environment

-

基础测试框架的环境管理,包括设备管理。

-

xdevice/src/xdevice/_core/executor

-

基础测试框架用例调度和分发。

-

xdevice/src/xdevice/_core/driver

-

基础测试框架测试执行器。

-

xdevice/src/xdevice/_core/resource

-

基础测试框架资源文件以及测试报告模板。

-

xdevice/src/xdevice/_core/testkit

-

基础测试框架公共操作,包括NFS文件系统挂载等。

-

xdevice/src/xdevice/_core/logger.py

-

基础测试框架日志管理。

-

xdevice/src/xdevice/_core/plugin.py

-

基础测试框架插件管理。

-

xdevice/src/xdevice/_core/interface.py

-

基础测试框架插件接口定义。

-

xdevice/setup.py

-

基础测试框架的安装脚本。

-

xdevice/run.bat

-

基础测试框架启动脚本(Windows)。

-

xdevice/run.sh

-

基础测试框架启动脚本(Linux)。

-
- -开发者测试平台developertest组件包结构说明,代码目录test/developertest,详见下表所示: - -**表 5** developertest组件包结构说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

developertest

-

开发测试框架。

-

developertest/src

-

测试框架源码。

-

developertest/src/core

-

测试执行器。

-

developertest/src/core/build

-

测试用例编译。

-

developertest/src/core/command

-

对用户输入的命令行处理。

-

developertest/src/core/config

-

测试框架配置管理。

-

developertest/src/core/driver

-

测试框架驱动执行器。

-

developertest/src/core/resource

-

测试框架配置文件。

-

developertest/src/core/testcase

-

测试用例管理。

-

developertest/src/core/common.py

-

测试框架公共操作。

-

developertest/src/core/constants.py

-

测试框架全局常量。

-

developertest/src/core/exception.py

-

测试框架异常定义。

-

developertest/src/core/utils.py

-

测试框架工具方法。

-

developertest/src/main

-

测试框架平台。

-

developertest/src/main/__main__.py

-

测试框架内部入口。

-

developertest/examples

-

测试框架demo用例。

-

developertest/third_party

-

测试框架依赖第三方组件适配。

-

developertest/BUILD.gn

-

测试子系统编译配置。

-

developertest/start.bat

-

开发者测试入口(Windows)。

-

developertest/start.sh

-

开发者测试入口(Linux)。

-
- diff --git "a/zh-cn/device-dev/subsystems/\347\224\250\346\210\267\347\250\213\345\272\217\346\241\206\346\236\266.md" "b/zh-cn/device-dev/subsystems/\347\224\250\346\210\267\347\250\213\345\272\217\346\241\206\346\236\266.md" deleted file mode 100755 index 14552d89af7b37c90cd9edbbc22f1d2d6c2b0bcb..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\224\250\346\210\267\347\250\213\345\272\217\346\241\206\346\236\266.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 用户程序框架 - -- **[概述](概述.md)** - -- **[搭建环境](搭建环境-2.md)** - -- **[开发指导](开发指导-3.md)** - -- **[开发实例](开发实例.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\347\233\270\346\234\272.md" "b/zh-cn/device-dev/subsystems/\347\233\270\346\234\272.md" deleted file mode 100755 index 3b86f53b9bc45e06e5cd20e684af73db06c88e77..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\233\270\346\234\272.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 相机 - -- **[相机开发概述](相机开发概述.md)** - -- **[拍照开发指导](拍照开发指导.md)** - -- **[录像开发指导](录像开发指导.md)** - -- **[预览开发指导](预览开发指导.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\347\233\270\346\234\272\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/subsystems/\347\233\270\346\234\272\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index 65801b39bcc9ab160e7ad0d0133f46f330a67145..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\233\270\346\234\272\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,116 +0,0 @@ -# 相机开发概述 - -- [基本概念](#section175012297491) -- [运作机制](#section193961322175011) - -## 基本概念 - -相机是OpenHarmony多媒体进程提供的服务之一,提供了相机的录像、预览、拍照功能,支持多用户并发取流。 - -在进行应用的开发前,开发者应了解以下基本概念: - -- 视频帧 - - 视频流指的是将一系列图片数据按照固定时间间隔排列形成的数据流,每一张图片数据成为一帧,这样的一帧称为视频帧。 - -- 帧速率\(FPS: Frames Per Second\) - - 视频播放每秒钟刷新图片的速度,或是视频每秒的帧数,帧速率越高,视频的观感越流畅。 - -- 分辨率 - - 每一帧的图片信息都是由像素点组成的,分辨率描述了一张图片中像素点的个数。例如1920\*1080\(1080P\),是指图片宽1920像素,高1080像素。 - - -## 运作机制 - -- 多媒体服务进程 - - 多媒体服务作为系统服务,在系统启动时由Init进程拉起,并初始化和分配媒体硬件资源(内存/显示硬件/图像传感器/编解码器等)。初始化过程解析配置文件,确定了多媒体各个服务的能力和资源上限,通常由OEM厂商通过配置文件进行配置。相机服务在多媒体进程初始化时有以下配置项: - - - 内存池:所有媒体服务依赖于内存池中的内存轮转运行 - - 图像传感器:包括了传感器类型、分辨率、ISP等 - - 图像处理器:分辨率、码率、图像翻转等 - - 图像编码器:编码格式、码率、分辨率等 - - -- 关键类的解释 - - 应用通过持有下面4个类,配置和使用Camera的功能,包括了Camera类和它的三个异步回调类,三类回调分别对应了不同类型的异步处理场景,详见[表1](#table486418149411)。 - - **表 1** 关键类的解释 - - - - - - - - - - - - - - - - - - - - - - - - -

对象

-

用途

-

举例

-

Camera

-

对相机进行静态配置(通过配置类),触发相机基本功能

-

拍照/录像/预览

-

CameraDeviceCallback

-

处理相机硬件状态变化

-

可用/不可用

-

CameraStateCallback

-

处理camera自身状态变化

-

创建/释放

-

FrameStateCallback

-

处理帧状态的变化

-

拍照开始和结束/帧率发生变化

-
- -- 流的传递 - - Surface是多媒体传递音视频的基本数据结构,Camera一般作为Surface中数据的生产者,在不同的场景下有特定的消费者。 - - 相机的预览和录像输出均为视频流,拍照输出为图像帧,二者均通过Surface类进行传递。Surface类可以屏蔽进程内/跨进程的场景,进行多媒体信息流的传递。 - - 以录像为例,用户首先创建Recorder实例,并从Recorder中获取对应Surface,再将此Surface传递给Camera实例,此时Camera将作为生产者向Surface注入视频流,而Recorder作为消费者从Surface中取出视频流进行保存,用户的行为类似桥接,把二者通过Surface连接起来。 - - 类似的,用户也可以自行创建Surface传递给Camera实例,并实现消费者逻辑(例如通过网络传输视频流,或是将拍照的帧数据保存成图片文件)。 - - 图形图像模块也通过Surface从Camera获取流资源,具体步骤详见[图形图像开发指导](图形图像概述.md)。 - -- 相机运行流程 - 1. Camera创建流程 - - 本进程通过CameraManager创建Camera实例,并从服务端绑定camera设备,创建成功后异步通知developer。类之间的时序图如下: - - **图 1** Camera创建时序图 - - - ![](figures/zh-cn_image_0000001054101094.png) - - - 1. Camera录像/预览流程 - - 开发者首先通过CameraKit创建Camera,然后FrameConfig类对录像或者预览帧属性进行配置。录像/预览时序如下: - - **图 2** Camera录像/预览时序图 - - - ![](figures/zh-cn_image_0000001054421113.png) - - - diff --git "a/zh-cn/device-dev/subsystems/\347\240\224\345\217\221\345\267\245\345\205\267\351\223\276.md" "b/zh-cn/device-dev/subsystems/\347\240\224\345\217\221\345\267\245\345\205\267\351\223\276.md" deleted file mode 100644 index 5c490a8cfbdc0458b160ce6b284ecd2582f2faad..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\240\224\345\217\221\345\267\245\345\205\267\351\223\276.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 研发工具链 - -- **[bytrace使用指导](bytrace使用指导.md)** - -- **[hdc\_std 使用指导](hdc_std-使用指导.md)** - -- **[hdc\_std常见问题](hdc_std常见问题.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272.md" deleted file mode 100755 index b59e4b2a18f9ef3c093e85b47b97126043b59744..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 编译构建 - -- **[轻量和小型系统编译构建指导](轻量和小型系统编译构建指导.md)** - -- **[标准系统编译构建指导](标准系统编译构建指导.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274-1.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274-1.md" deleted file mode 100755 index 661ff10cf6bdcb8d16510560214c53e124813a6d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274-1.md" +++ /dev/null @@ -1,176 +0,0 @@ -# 编译构建使用指导 - -- [目录结构](#section56731811102915) -- [编译](#section1069873833818) - - [编译命令](#section2740182614395) - -- [开发步骤](#section4207112818418) - -## 目录结构 - -``` -/build # 编译构建主目录 -├── config # 编译相关的配置项 -├── core -│ └── gn # 编译入口BUILD.gn配置 -├── loader # 各个组件配置加载、模板生成 -├── ohos # OpenHarmony编译打包流程配置 -│ ├── kits # kits编译打包模板和处理流程 -│ ├── ndk # ndk模板和处理流程 -│ ├── notice # notice模板和处理流程 -│ ├── packages # 版本打包模板和处理流程 -│ ├── sa_profile # sa模板和处理流程 -│ ├── sdk # sdk模板和处理流程,包括sdk中包含的模块配置 -│ └── testfwk # 测试相关的处理 -├── scripts # 编译相关的python脚本 -├── templates # c/c++编译模板定义 -└── toolchain # 编译工具链配置 -``` - -## 编译 - -### 编译命令 - -- 代码根目录下执行全量版本的编译命令: - - ``` - ./build.sh --product-name {product_name} - ``` - - \{product\_name\}为当前版本支持的平台。比如:Hi3516DV300等。 - - 编译完成后,结果镜像保存在 out/ohos-arm-release/packages/phone/images/ 目录下。 - -- 编译命令支持选项: - - ``` - --product-name # 必须 编译的产品名称,如:Hi3516DV300 - --build-target # 可选 指定编译目标,可以指定多个 - --gn-args # 可选 gn参数,支持指定多个 - --ccache # 可选 编译使用ccache,需要本地安装ccache - ``` - - -## 开发步骤 - -1. 添加组件。 - - 本节以添加一个自定义的组件为例,描述如何编译组件,编译库、编译可执行文件等。 - - 示例组件partA由feature1、feature2和feature3组成,feature1的编译目标为一个动态库,feature2的目标为一个可执行程序,feature3的目标为一个etc配置文件。 - - 示例组件partA的配置需要添加到一个子系统中,本次示例将添加到subsystem\_examples子系统中(subsystem\_examples子系统定义在test/examples/目录)。 - - 示例组件partA的完整目录结构如下: - - ``` - test/examples/partA - ├── feature1 - │ ├── BUILD.gn - │ ├── include - │ │ └── helloworld1.h - │ └── src - │ └── helloworld1.cpp - ├── feature2 - │ ├── BUILD.gn - │ ├── include - │ │ └── helloworld2.h - │ └── src - │ └── helloworld2.cpp - └── feature3 - ├── BUILD.gn - └── src - └── config.conf - ``` - - 示例1:编写动态库gn脚本test/examples/partA/feature1/BUILD.gn,示例如下: - - ``` - config("helloworld_lib_config") { - include_dirs = [ "include" ] - } - - ohos_shared_library("helloworld_lib") { - sources = [ - "include/helloworld1.h", - "src/helloworld1.cpp", - ] - public_configs = [ ":helloworld_lib_config" ] - part_name = "partA" - } - ``` - - 示例2:编写可执行文件gn脚本test/examples/partA/feature2/BUILD.gn,示例如下: - - ``` - ohos_executable("helloworld_bin") { - sources = [ - "src/helloworld2.cpp" - ] - include_dirs = [ "include" ] - deps = [ # 依赖组件内模块 - "../feature1:helloworld_lib" - ] - external_deps = [ "partB:module1" ] # (可选)如果有跨组件的依赖,格式为“组件名:模块名” - install_enable = true # 可执行程序缺省不安装,需要安装时需要指定 - part_name = "partA" - } - ``` - - 示例3:编写etc模块gn脚本test/examples/partA/feature3/BUILD.gn,示例如下: - - ``` - ohos_prebuilt_etc("feature3_etc") { - source = "src/config.conf" - relative_install_dir = "init" #可选,模块安装相对路径,相对于默认安装路径;默认在/system/etc目录 - part_name = "partA" - } - ``` - - 示例4:在子系统的ohos.build中添加组件配置:test/examples/ohos.build。每个子系统有一个ohos.build配置文件,在子系统的根目录下。示例如下: - - ``` - "partA": { - "module_list": [ - "//test/examples/partA/feature1:helloworld_lib", - "//test/examples/partA/feature2:helloworld_bin", - "//test/examples/partA/feature3:feature3_etc", - ], - "inner_kits": [ - - ], - "system_kits": [ - - ], - "test_list": [ - - ] - } - ``` - - 一个组件包含module\_list、inner\_kits、system\_kits、test\_list四个部分的声明,其中: - - - module\_list:组件所包含的模块列表; - - inner\_kits:组件提供给其它组件调用的接口,其他组件的模块可以在external\_deps中添加依赖的模块; - - system\_kits:组件提供给开发者开发应用的接口; - - test\_list:组件中对应模块的测试用例; - -2. 将组件添加到产品配置中。 - - 在产品的配置中添加组件,产品对应的配置文件:productdefine/common/products/\{product-name\}.json。 - - 在产品配置文件中添加 "subsystem\_examples:partA",表示该产品中会编译并打包partA到版本中。 - -3. 编译。 - - 以编译Hi3516DV300为例,编译命令如下: - - ``` - ./build.sh --product-name Hi3516DV300 --ccache - ``` - -4. 编译输出。 - - 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 8d5f276817760d9b28e9bee264507fc2e6c6b533..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,431 +0,0 @@ -# 编译构建使用指导 - -- [前提条件](#section13333171022312) -- [hb命令行工具使用](#section477242204612) -- [新增组件](#section4207112818418) -- [新增芯片解决方案](#section2737141421917) -- [新增产品解决方案](#section720881917199) - -## 前提条件 - -开发环境需安装gn、ninja构建工具、python 3.7.4及以上和hb。安装方法请见[搭建系统基础环境](../quick-start/搭建系统环境.md)。 - -## hb命令行工具使用 - -hb是OpenHarmony的命令行工具,用来执行编译命令。以下对hb的常用命令进行说明。 - -1. **hb set** - - ``` - hb set -h - usage: hb set [-h] [-root [ROOT_PATH]] [-p] - - optional arguments: - -h, --help show this help message and exit - -root [ROOT_PATH], --root_path [ROOT_PATH] - Set OHOS root path - -p, --product Set OHOS board and kernel - ``` - - - hb set 后无参数,进入默认设置流程 - - hb set -root dir可直接设置代码根目录 - - hb set -p设置要编译的产品 - -2. **hb env** - - 查看当前设置信息 - - ``` - hb env - [OHOS INFO] root path: xxx - [OHOS INFO] board: hispark_taurus - [OHOS INFO] kernel: liteos - [OHOS INFO] product: ipcamera - [OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera - [OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 - ``` - -3. **hb build** - - ``` - hb build -h - usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] - [--dmverity] [-p PRODUCT] [-f] [-n] - [component [component ...]] - - positional arguments: - component name of the component - - optional arguments: - -h, --help show this help message and exit - -b BUILD_TYPE, --build_type BUILD_TYPE - release or debug version - -t [TEST [TEST ...]], --test [TEST [TEST ...]] - compile test suit - --dmverity Enable dmverity - -p PRODUCT, --product PRODUCT - build a specified product with - {product_name}@{company}, eg: ipcamera@hisilcon - -f, --full full code compilation - -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] - Compile single target - ``` - - - hb build后无参数,会按照设置好的代码路径、产品进行编译,编译选项使用与之前保持一致。-f 选项将删除当前产品所有编译产品,等同于hb clean + hb build. - - hb build \{component\_name\}:基于设置好的产品对应的单板、内核,单独编译组件(e.g.:hb build kv\_store\)。 - - hb build -p ipcamera@hisilicon:免set编译产品,该命令可以跳过set步骤,直接编译产品。 - - 在device/device\_company/board下单独执行hb build会进入内核选择界面,选择完成后会根据当前路径的单板、选择的内核编译出仅包含内核、驱动的镜像。 - -4. **hb clean** - - 清除out目录对应产品的编译产物,仅保留args.gn、build.log。清除指定路径可输入路径参数:hb clean out/board/product,默认将清除当前hb set的产品对应out路径。 - - ``` - hb clean - usage: hb clean [-h] [out_path] - - positional arguments: - out_path clean a specified path. - - optional arguments: - -h, --help show this help message and exit - ``` - - -## 新增组件 - -本小节介绍如何新增一个组件,首先确定组件归属的子系统和组件名称,然后按如下步骤新增: - -1. 源码开发完成后,添加组件编译脚本。 - - 以编译组件hello\_world可执行文件为例,applications/sample/hello\_world/BUILD.gn可以写为: - - ``` - executable("hello_world") { - include_dirs = [ - "include", - ] - sources = [ - "src/hello_world.c" - ] - } - ``` - - 如上编译脚本,可编译出一个可在OpenHarmony上运行的名为hello\_world的可执行文件。 - - 单独编译该组件,hb set任意选择一款产品,然后使用-T选项单独编译组件: - - ``` - hb build -f -T //applications/sample/hello_world - ``` - - 组件在开发板上功能验证完成后,可按步骤2\~5将组件配置到产品中。 - -2. 添加组件描述。 - - 组件描述位于build/lite/components下,新增的组件需加入对应子系统的json文件中。一个组件描述必选的字段有: - - - component:组件名称。 - - description:组件的一句话功能描述。 - - optional:组件是否为系统可选。 - - dirs:组件源码路径。 - - targets:组件编译入口。 - - 以将hello\_world组件加入应用子系统为例,在applications.json中添加hello\_world对象: - - ``` - { - "components": [ - { - "component": "hello_world", - "description": "Hello world.", - "optional": "true", - "dirs": [ - "applications/sample/hello_world" - ], - "targets": [ - "//applications/sample/hello_world" - ] - }, - ... - ] - } - ``` - -3. 将组件配置到产品。 - - 产品的配置文件config.json位于位于vendor/company/product/下,产品配置文件需包含产品名称、OpenHarmony版本号、device厂商、开发板、内核类型、内核版本号,以及配置的子系统和组件。以将hello\_world组件加入产品配置文件my\_product.json中为例,加入hello\_wolrd对象: - - ``` - { - "product_name": "hello_world_test", - "ohos_version": "OpenHarmony 1.0", - "device_company": "hisilicon", - "board": "hispark_taurus", - "kernel_type": "liteos_a", - "kernel_version": "1.0.0", - "subsystems": [ - { - "subsystem": "applications", - "components": [ - { "component": "hello_world", "features":[] } - ] - }, - ... - ] - } - ``` - -4. 编译产品。 - - 1. 代码根目录输入hb set选择对应产品。 - - 2. 执行hb build。 - - -## 新增芯片解决方案 - -编译构建支持添加新的芯片解决方案厂商,具体步骤如下: - -1. 创建芯片解决方案目录。 - - 按照[芯片解决方案配置规则](编译构建概述.md#section1625463413327)创建目录,以芯片厂商realtek的“rtl8720“开发板为例, 在代码根目录执行: - - ``` - mkdir -p device/realtek/rtl8720 - ``` - -2. 创建内核适配目录,并编写开发板编译配置config.gni文件。 - - 以realtek的“rtl8720“开发板的liteos\_m适配为例,device/realtek/rtl8720/liteos\_a/config.gni的内容如下: - - ``` - # Kernel type, e.g. "linux", "liteos_a", "liteos_m". - kernel_type = "liteos_a" - - # Kernel version. - kernel_version = "3.0.0" - - # Board CPU type, e.g. "cortex-a7", "riscv32". - board_cpu = "real-m300" - - # Board arch, e.g. "armv7-a", "rv32imac". - board_arch = "" - - # Toolchain name used for system compiling. - # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. - # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. - board_toolchain = "gcc-arm-none-eabi" - - # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. - board_toolchain_path = - rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", - root_build_dir) - - # Compiler prefix. - board_toolchain_prefix = "gcc-arm-none-eabi-" - - # Compiler type, "gcc" or "clang". - board_toolchain_type = "gcc" - - # Board related common compile flags. - board_cflags = [] - board_cxx_flags = [] - board_ld_flags = [] - ``` - -3. 编写编译脚本。 - - 在开发板目录下创建BUILD.gn,target名称应与开发板名称一致。以realtek的rtl8720开发板为例,device/realtek/rtl8720/BUILD.gn内容可以是: - - ``` - group("rtl8720") { # target类型也可以shared_library, static_library, executable - # 具体内容 - ...... - } - ``` - -4. 编译芯片解决方案。 - - 在开发板目录下执行hb build,即可启动芯片解决方案的编译。 - - -## 新增产品解决方案 - -编译构建支持芯片解决方案和组件的灵活拼装,形成定制化的产品解决方案。具体步骤如下: - -1. 创建产品目录 - - 按照[产品解决方案配置规则](编译构建概述.md#section1625463413327)创建产品目录,以基于“rtl8720“开发板的wifiiot模组为例,在代码根目录执行: - - ``` - mkdir -p vendor/my_company/wifiiot - ``` - -2. 拼装产品 - - 在新建的产品目录下新建config.json文件,以步骤1中的wifiiot为例,vendor/my\_company/wifiiot/config.json可以是: - - ``` - { - "product_name": "wifiiot", # 产品名称 - "ohos_version": "OpenHarmony 1.0", # 使用的OS版本 - "device_company": "realtek", # 芯片解决方案厂商名称 - "board": "rtl8720", # 开发板名称 - "kernel_type": "liteos_m", # 选择的内核类型 - "kernel_version": "3.0.0", # 选择的内核版本 - "subsystems": [ - { - "subsystem": "kernel", # 选择的子系统 - "components": [ - { "component": "liteos_m", "features":[] } # 选择的组件和组件特性 - ] - }, - ... - { - 更多子系统和组件 - } - ] - } - ``` - - 注意:编译构建系统编译前会对device\_company,board,kernel\_type,kernel\_version、subsystem、component字段进行有效性检查,其中device\_company,board,kernel\_type,kernel\_version应与已知的芯片解决方案匹配,subsystem、component应与build/lite/components下的组件描述匹配。 - -3. 适配OS接口 - - 在产品目录下创建hals目录,并将产品解决方案对OS适配的源码和编译脚本放入该目录下。 - -4. 配置系统服务 - - 在产品目录下创建init\_configs目录,并在init\_configs目录下创建init.cfg文件,按需配置要启动的系统服务。 - -5. 配置init进程(仅linux内核需要) - - 在init\_configs目录下创建etc目录,然后在etc下创建init.d文件夹和fstab文件。最后按产品需求在init.d文件下创建并编辑rcS文件和Sxxx文件。 - -6. 配置文件系统镜像(可选,仅支持文件系统的开发板需要) - - 在产品目录下创建fs.yml文件。fs.yml需按产品实际情况配置,一个典型的fs.yml文件如下: - - ``` - - - fs_dir_name: rootfs # 镜像的名称 - fs_dirs: - - - # 将编译生成的out/my_board/my_product/bin目录下的文件拷贝到rootfs/bin中,并忽略测试bin - source_dir: bin - target_dir: bin - ignore_files: - - Test.bin - - TestSuite.bin - - - # 将编译生成的out/my_board/my_product/libs目录下的文件拷贝到rootfs/lib中,忽略所有.a文件,并设置文件和文件夹的权限为644和755 - source_dir: libs - target_dir: lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: usr/lib - target_dir: usr/lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: config - target_dir: etc - - - source_dir: system - target_dir: system - - - source_dir: sbin - target_dir: sbin - - - source_dir: usr/bin - target_dir: usr/bin - - - source_dir: usr/sbin - target_dir: usr/sbin - - - # 创建一个proc空目录 - target_dir: proc - - - target_dir: mnt - - - target_dir: opt - - - target_dir: tmp - - - target_dir: var - - - target_dir: sys - - - source_dir: etc - target_dir: etc - - - source_dir: vendor - target_dir: vendor - - - target_dir: storage - - fs_filemode: - - - file_dir: lib/ld-uClibc-0.9.33.2.so - file_mode: 555 - - - file_dir: lib/ld-2.24.so - file_mode: 555 - - - file_dir: etc/init.cfg - file_mode: 400 - fs_symlink: - - - # 在rootfs/lib下创建软连接ld-musl-arm.so.1 -> libc.so - source: libc.so - link_name: ${fs_dir}/lib/ld-musl-arm.so.1 - - - source: mksh - link_name: ${fs_dir}/bin/sh - - - source: mksh - link_name: ${fs_dir}/bin/shell - fs_make_cmd: - # 使用脚本将rootfs制作为ext4格式的image - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - - - fs_dir_name: userfs - fs_dirs: - - - source_dir: storage/etc - target_dir: etc - - - source_dir: data - target_dir: data - fs_make_cmd: - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - - ``` - -7. 编写编译脚本 - - 在产品目录下创建BUILD.gn文件,按产品实际情况编写脚本。以步骤1中的wifiiot为例,BUILD.gn示例如下: - - ``` - group("wifiiot") { # target名称与产品名一致 - deps = [] - # 拷贝init配置 - deps += [ "init_configs" ] - # 将hals加入编译 - deps += [ "hals" ] - # 其他 - ...... - } - ``` - -8. 编译产品。 - - 在代码根目录执行hb set按提示选择新增的产品,然后执行hb build即可启动编译。 - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\270\270\350\247\201\351\227\256\351\242\230.md" deleted file mode 100755 index ca00b2428542c6024ff6fa79649c5814646cfd28..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\270\270\350\247\201\351\227\256\351\242\230.md" +++ /dev/null @@ -1,121 +0,0 @@ -# 编译构建常见问题 - -- [由于ninja版本问题导致编译失败](#section1019152312222) -- [由于ncurses库缺失导致编译失败](#section21449422618) -- [由于未安装mcopy导致编译失败](#section12477184992615) -- [由于权限问题导致编译失败](#section178451337202716) -- [由于未安装Crypto导致编译失败](#section1241481172819) -- [由于编译环境为shell导致编译失败](#section3691222152919) - -## 由于ninja版本问题导致编译失败 - -- **现象描述:** - - 编译失败,提示“usr/sbin/ninja: invalid option -- w”。 - -- **可能原因:** - - 编译环境中ninja版本太低,不支持--w选项。 - -- **解决办法:** - - 卸载环境中ninja和gn,按照HarmonyOS官网[获取工具](../get-code/获取工具.md)。 - - -## 由于ncurses库缺失导致编译失败 - -- **现象描述:** - - 编译失败,提示“/usr/bin/ld: cannot find -lncurses”。 - -- **可能原因:** - - 编译环境ncurses库缺失。 - -- **解决办法:** - - ``` - sudo apt-get install lib32ncurses5-dev - ``` - - -## 由于未安装mcopy导致编译失败 - -- **现象描述:** - - ​编译失败,提示“line 77: mcopy: command not found”。 - -- **可能原因:** - - 编译环境未安装mcopy。 - -- **解决办法:** - - ``` - ​sudo apt-get install dosfstools mtools - ``` - - -## 由于权限问题导致编译失败 - -- **现象描述:** - - 编译失败,提示“riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory”。 - -- ​**可能原因:** - - 当前用户对riscv编译器路径下的文件访问权限不够。 - -- ​**解决办法:** - 1. 查询gcc\_riscv32所在目录。 - - ``` - which riscv32-unknown-elf-gcc - ``` - - 2. 使用chmod命令修改目录权限为755。 - - -## 由于未安装Crypto导致编译失败 - -- **现象描述:** - - 编译失败,提示“No module named 'Crypto'”。 - -- **可能原因:** - - python3未安装Crypto。 - -- **解决办法:** - 1. 查询Python版本号。 - - ``` - python3 --version - ``` - - 2. 需使用python3.7以上版本,然后安装pycryptodome。 - - ``` - sudo pip3 install pycryptodome - ``` - - - -## 由于编译环境为shell导致编译失败 - -- **现象描述:** - - 编译失败:“xx.sh \[: xx unexpected operator”。 - -- **可能原因:** - - 编译环境shell不是bash。 - -- **解决办法:** - - ``` - sudo rm -rf /bin/sh - sudo ln -s /bin/bash /bin/sh - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260-0.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260-0.md" deleted file mode 100755 index 1bd7dd28d93785765d46a6c7585280e1fe6d390a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260-0.md" +++ /dev/null @@ -1,58 +0,0 @@ -# 编译构建概述 - -- [基本概念](#section175012297491) -- [运作机制](#section193961322175011) -- [约束与限制](#section2029921310472) - -编译构建子系统提供了一个基于gn和ninja的编译构建框架。主要提供以下功能: - -- 构建不同芯片平台的产品。如:Hi3516DV300平台。 - -- 根据产品配置可以按照组件组装打包产品需要的能力。 - -## 基本概念 - -在了解编译构建子系统的能力前,应了解如下基本概念: - -- 平台 - - 开发板和内核的组合,不同平台支持的子系统和组件不同。 - -- 子系统 - - OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 \> 子系统 \> 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。子系统是一个逻辑概念,它具体由对应的组件构成。 - -- 组件 - - 对子系统的进一步拆分,可复用的软件单元,它包含源码、配置文件、资源文件和编译脚本;能独立构建,以二进制方式集成,具备独立验证能力的二进制单元。 - -- gn - - Generate ninja的缩写,用于产生ninja文件。 - -- ninja - - ninja是一个专注于速度的小型构建系统。 - - -## 运作机制 - -OpenHarmony侧的编译构建流程主要包括编译命令行解析,调用gn,执行ninja: - -- 命令行解析:解析待编译的产品名称,加载相关配置。 -- 调用gn: 根据命令行解析的产品名称和编译类型,配置编译工具链和全局的编译选项。 -- 执行ninja:启动编译并生成对应的产品版本。 - -## 约束与限制 - -- 需按照[源码获取](../get-code/源码获取.md)指导下载全量源码(采用方式三获取)。 -- 编译环境需要Ubuntu18.04及以上版本。 -- 安装编译所需的程序包。 - - 安装命令: - - ``` - sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260.md" deleted file mode 100755 index 83423cbe1c9b0d7f4bfd6bae3124b490c43cd6c8..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260.md" +++ /dev/null @@ -1,381 +0,0 @@ -# 编译构建概述 - -- [基本概念](#section175012297491) -- [目录结构](#section3267040205617) -- [构建流程](#section193961322175011) -- [组件、芯片解决方案和产品解决方案配置规则](#section1625463413327) - -一个基于gn和ninja的构建系统,以支持OpenHarmony组件化开发为目标,提供以下基本功能: - -- 支持按组件拼装产品并编译。 - -- 独立构建芯片解决方案厂商源码。 -- 独立构建单个组件。 - -## 基本概念 - -在使用编译构建子系统前,应了解如下基本概念: - -- 子系统 - - 子系统是一个逻辑概念,它由一个或多个具体的组件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 \> 子系统 \> 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。 - - -- 组件 - - 系统最小的可复用、可配置、可裁剪的功能单元。组件具备目录独立可并行开发、可独立编译、可独立测试的特征。 - -- gn - - Generate ninja的缩写,用于产生ninja文件。 - -- ninja - - ninja是一个专注于速度的小型构建系统。 - -- hb - - OpenHarmony的命令行工具,用来执行编译命令。 - - -## 目录结构 - -``` -build/lite -├── components # 组件描述文件 -├── figures # readme中的图片 -├── hb # hb pip安装包源码 -├── make_rootfs # 文件系统镜像制作脚本 -├── config # 编译配置项 -│ ├── component # 组件相关的模板定义 -│ ├── kernel # 内核相关的编译配置 -│ └── subsystem # 子系统编译配置 -├── platform # ld脚本 -├── testfwk # 测试编译框架 -└── toolchain # 编译工具链配置,包括:编译器路径、编译选项、链接选项等 -``` - -## 构建流程 - -编译构建流程如[图1 ](#fig9744112715161)所示,主要分设置和编译两步: - -**图 1** 编译构建流程 -![](figures/编译构建流程.jpg "编译构建流程") - -1. hb set: 设置OpenHarmony源码目录和要编译的产品。 -2. hb build: 编译产品、开发板或者组件。编译主要过程如下: - - 读取编译配置:根据产品选择的开发板,读取开发板config.gni文件内容,主要包括编译工具链、编译链接命令和选项等。 - - 调用gn:调用gn gen命令,读取产品配置生成产品解决方案out目录和ninja文件。 - - 调用ninja:调用ninja -C out/board/product启动编译。 - - 系统镜像打包:将组件编译产物打包,设置文件属性和权限,制作文件系统镜像。 - - -## 组件、芯片解决方案和产品解决方案配置规则 - -为了实现芯片解决方案、产品解决方案与OpenHarmony是解耦的、可插拔的,组件、芯片解决方案和产品解决方案的路径、目录树和配置需遵循一定的规则,具体如下: - -- **组件** - -组件源码路径命名规则为:_\{领域\}/\{子系统\}/\{组件\}_,组件目录树规则如下: - -``` -component -├── interfaces -│ ├── innerkits # 系统内接口,组件间使用 -│ └── kits # 应用接口,应用开发者使用 -├── frameworks # framework实现 -├── services # service实现 -└── BUILD.gn # 组件编译脚本 -``` - -组件的名称、源码路径、功能简介、是否必选、编译目标、RAM、ROM、编译输出、已适配的内核、可配置的特性和依赖等属性定义在build/lite/components目录下对应子系统的json文件中,新增组件时需要在对应子系统json文件中添加相应的组件定义。产品所配置的组件必须在某个子系统中被定义过,否则会校验失败。 - -以泛sensor子系统的sensor服务组件为例,组件属性定义描述文件字段说明如下: - -``` -{ - "components": [ - { - "component": "sensor_lite", # 组件名称 - "description": "Sensor services", # 组件一句话功能描述 - "optional": "true", # 组件是否为最小系统必选 - "dirs": [ # 组件源码路径 - "base/sensors/sensor_lite" - ], - "targets": [ # 组件编译入口 - "//base/sensors/sensor_lite/services:sensor_service" - ], - "rom": "92KB", # 组件ROM值 - "ram": "~200KB", # 组件RAM估值 - "output": [ "libsensor_frameworks.so" ], # 组件编译输出 - "adapted_kernel": [ "liteos_a" ], # 组件已适配的内核 - "features": [], # 组件可配置的特性 - "deps": { - "components": [ # 组件依赖的其他组件 - "samgr_lite", - "ipc_lite" - - ], - "third_party": [ # 组件依赖的三方开源软件 - "bounds_checking_function" - ] - } - } - ] -} -``` - -组件的编译脚本语言为gn,gn的基本用法请见[gn快速入门](https://gn.googlesource.com/gn/+/master/docs/quick_start.md)。组件即为gn定义的编译目标,可以为静态库、动态库、可执行文件或group。组件BUILD.gn的编写建议如下: - -1)编译目标名称与组件一致。 - -2)组件对外可配置的特性变量需声明在该组件BUILD.gn中,特性变量命名规则:ohos\_\{subsystem\}\_\{component\}\_\{feature\}。特性在组件描述中也需要同步定义,在产品配置文件config.json中按需配置。 - -3)宏定义规则:OHOS\_\{SUBSYSTEM\}\_\{COMPONENT\}\_\{FEATURE\} - -以图形的UI组件为例,foundation/graphic/ui/BUILD.gn文件如下: - -``` - # 声明组件可配置的特性 - declare_args() { - enable_ohos_graphic_ui_animator = false # 动效特性开关 - ohos_ohos_graphic_ui_font = "vector" # 可配置的字体类型,vector或者bitmap - } - - # 组件基础功能 - shared_library("base") { - sources = [ - ...... - ] - include_dirs = [ - ...... - ] - } - - # 仅在animator开启时编译 - if(enable_ohos_graphic_ui_animator ) { - shared_library("animator") { - sources = [ - ...... - ] - include_dirs = [ - ...... - ] - deps = [ :base ] - } - } - ...... - # target名称建议与组件名称一致, 组件target类型可以是executable(bin文件),shared_library(动态库.so),static_library(静态库.a),group等等 - executable("ui") { - deps = [ - ":base" - ] - - # animator特性由产品配置 - if(enable_ohos_graphic_ui_animator ) { - deps += [ - "animator" - ] - } - } -``` - -- **芯片解决方案** - -芯片解决方案是指基于某款开发板的完整解决方案,包含驱动、设备侧接口适配、开发板sdk等。芯片解决方案是一个特殊的组件,源码路径规则为:_device/\{芯片解决方案厂商\}/\{开发板\}_。芯片解决方案组件会随产品选择的开发板默认编译。芯片解决方案目录树规则如下: - -``` -device -└── company # 芯片解决方案厂商 - └── board # 开发板名称 - ├── BUILD.gn # 编译脚本 - ├── hals # OS南向接口适配 - ├── linux # 可选,linux内核版本 - │ └── config.gni # linux版本编译配置 - └── liteos_a # 可选,liteos内核版本 - └── config.gni # liteos_a版本编译配置 -``` - -config.gni为开发板编译相关的配置。编译时会采用该配置文件中的参数选择编译相应的OS组件,编译阶段系统全局可见。关键字段介绍如下: - -``` -kernel_type: 开发板使用的内核类型,例如:“liteos_a”, “liteos_m”, “linux”。 -kernel_version: 开发使用的内核版本,例如:“4.19”。 -board_cpu: 开发板CPU类型,例如:“cortex-a7”, “riscv32”。 -board_arch: 开发芯片arch, 例如: “armv7-a”, “rv32imac”。 -board_toolchain: 开发板自定义的编译工具链名称,例如:“gcc-arm-none-eabi”。若为空,则使用默认为ohos-clang。 -board_toolchain_prefix:编译工具链前缀,例如:“gcc-arm-none-eabi”。 -board_toolchain_type: 编译工具链类型,目前支持gcc和clang。例如:“gcc” ,“clang”。 -board_cflags: 开发板配置的c文件编译选项。 -board_cxx_flags: 开发板配置的cpp文件编译选项。 -board_ld_flags: 开发板配置的链接选项。 -``` - -- **产品解决方案** - -产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、组件拼装配置、启动配置和文件系统配置等。源码路径规则为:_vendor/\{产品解决方案厂商\}/\{产品名称\}。_产品解决方案也是一个特殊的组件,目录树规则如下: - -``` -vendor -└── company # 产品解决方案厂商 - ├── product # 产品名称 - │ ├── init_configs - │ │ ├── etc # init进程启动配置(可选,仅linux内核需要) - │ │ └── init.cfg # 系统服务启动配置 - │ ├── hals # 产品解决方案OS适配 - │ ├── BUILD.gn # 产品编译脚本 - │ └── config.json # 产品配置文件 - │ └── fs.yml # 文件系统打包配置 - └── ...... -``` - -新增产品须按如上的规则创建目录和文件,编译构建系统将按该规则扫描已配置的产品。关键的目录和文件详细介绍如下: - -1. vendor/company/product/init\_configs/etc - - 该文件夹中包含rcS脚本,Sxxx脚本和fstab脚本,init进程在启动系统服务之前执行这些脚本。执行的流程为“rcS-\>fstab-\>S00-xxx“,Sxxx脚本中的内容与开发板和产品需要有关,主要包括设备节点的创建、创建目录、扫描设备节点、修改文件权限等等。这些文件在产品编译的BUILD.gn中按需拷贝到产品out目录中,最终打包到rootfs镜像中。 - -2. vendor/company/product/init\_configs/init.cfg - - init进程启动服务的配置文件,当前支持解析的命令有: - - 1\) start: 启动某个服务 - - 2\) mkdir: 创建文件夹 - - 3)chmod: 修改指定路径/文件的权限 - - 4\) chown: 修改指定路径/文件的属组 - - 5\) mount: 挂载命令 - - 该文件中的各个字段的解释如下: - - ``` - { - "jobs" : [{ # job数组,一个job对应一个命令集合。job的执行顺序:pre-init -> init -> post-init。 - "name" : "pre-init", - "cmds" : [ - "mkdir /storage/data", # 创建目录 - "chmod 0755 /storage/data", # 修改权限,权限值的格式为0xxx, 如0755 - "mkdir /storage/data/log", - "chmod 0755 /storage/data/log", - "chown 4 4 /storage/data/log", # 修改属组,第一个数字为uid, 第二个数字为gid - ...... - "mount vfat /dev/mmcblock0 /sdcard rw,umask=000" # 挂载,格式为: mount [文件系统类型] [source] [target] [flags] [data] - # 其中flags仅支持:nodev、noexec、nosuid和rdonly - ] - }, { - "name" : "init", - "cmds" : [ # 按cmds数组顺序启动启动服务 - "start shell", # 注意:start与服务名称之间有且只有一个空格 - ...... - "start service1" - ] - }, { - "name" : "post-init", # 最后别执行的job, init进程启动完成后的处理(如驱动初始化后再mount设备) - "cmds" : [] - } - ], - "services" : [{ # service数组,一个service对应一个进程 - "name" : "shell", # 服务名称 - "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"], # 可执行文件全路径,path必须为第一个元素 - "uid" : 0, # 进程的uid,须与二进制文件的uid保持一致 - "gid" : 0, # 进程的gid,须与二进制文件的gid保持一致 - "once" : 0, # 是否为一次性进程,1:进程退出后,init不在重新拉起。0:常驻进程,进程若退出,init将重新拉起 - "importance" : 0, # 是否为关键进程,1:是关键进程,若进程退出,init将会重启单板。0:非关键进程,若进程退出,init不会重启单板 - "caps" : [4294967295] - }, - ...... - ] - } - ``` - -3. vendor/company/product/init\_configs/hals - - 解决方案厂商对OS的适配,需要实现的接口请见各个组件的readme说明文档。 - -4. vendor/company/product/config.json - - config.json为编译构建的主入口,包含了开发板、OS组件和内核等配置信息。以基于hispark\_taurus开发板的ipcamera产品为例,配置文件如下: - - ``` - { - "product_name": "ipcamera", # 产品名称 - "ohos_version": "OpenHarmony 1.0", # 选择的OS版本 - "device_company": "hisilicon", # 芯片厂商 - "board": "hispark_taurus", # 开发板名称 - "kernel_type": "liteos_a", # 选择的内核类型 - "kernel_version": "3.0.0", # 选择的内核版本 - "subsystems": [ - { - "subsystem": "aafwk", # 选择的子系统 - "components": [ - { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] } # 选择的组件和组件特性配置 - ] - }, - { - ...... - } - ...... - 更多子系统和组件 - } - } - ``` - -5. vendor/company/product/fs.yml - - 该文件用于配置文件系统镜像制作过程,将编译产物打包成文件系统镜像,比如用户态根文件系统rootfs.img和可读写的userfs.img。它由多个列表组成,每个列表对应一个文件系统。字段说明如下: - - ``` - fs_dir_name: 必填,声明文件系统文件名, 如rootfs、userfs - fs_dirs: 选填,配置out下文件目录与文件系统文件目录的映射关系,每个文件目录对应一个列表 - source_dir: 选填,out下目标文件目录,若缺失则将根据target_dir在文件系统下创建空目录 - target_dir: 必填,文件系统下对应文件目录 - ignore_files:选填,声明拷贝忽略文件 - dir_mode: 选填,文件目录权限,默认755 - file_mode: 选填,该文件目录下所有文件的权限,默认555 - fs_filemode: 选填,配置需要特殊声明权限的文件,每个文件对应一个列表 - file_dir: 必填,文件系统下具体文件路径 - file_mode: 必填,文件权限声明 - fs_symlink: 选填,配置文件系统软连接 - fs_make_cmd: 必填,配置需要制作文件系统脚本,OS提供的脚本在build/lite/make_rootfs下, 支持linux,liteos内核和ext4、jffs2、vfat格式。也支持芯片解决方案厂商自定义。 - fs_attr: 选填,根据配置项动态调整文件系统 - ``` - - 其中fs\_symlink、fs\_make\_cmd字段支持以下变量: - - - $\{root\_path\} - - 代码根目录,对应gn的$\{ohos\_root\_path\} - - - $\{out\_path\} - - 产品out目录,对应gn的$\{root\_out\_dir\} - - - $\{fs\_dir\} - - 文件系统目录,由以下变量拼接而成 - - - $\{root\_path\} - - $\{fs\_dir\_name\} - - - >![](public_sys-resources/icon-note.gif) **说明:** - >fs.yml是可选的,对于没有文件系统的设备可不配置。 - -6. vendor/company/product/BUILD.gn - - 产品编译的入口,主要用于编译解决方案厂商源码和拷贝启动配置文件。如果某个产品被选择为要编译的产品,那么对应产品目录下的BUILD.gn会默认编译。一个典型的产品编译BUILD.gn应该如下: - - ``` - group("product") { # target名称需与product名称即三级目录名称一致 - deps = [] - # 拷贝init配置 - deps += [ "init_configs" ] - # 其他 - ...... - } - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" deleted file mode 100755 index e85c33895c2a4348209433745b10487457589a5d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 轻量和小型系统编译构建指导 - -- **[编译构建概述](编译构建概述.md)** - -- **[编译构建使用指导](编译构建使用指导.md)** - -- **[编译构建常见问题](编译构建常见问题.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221.md" "b/zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221.md" deleted file mode 100755 index 5f32b5fe5013f986e38b1363270abfa4d02668d2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\351\237\263\350\247\206\351\242\221.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 音视频 - -- **[音视频开发概述](音视频开发概述.md)** - -- **[音视频播放开发指导](音视频播放开发指导.md)** - -- **[音视频录制开发指导](音视频录制开发指导.md)** - - diff --git "a/zh-cn/device-dev/\345\257\274\350\257\273.md" "b/zh-cn/device-dev/\345\257\274\350\257\273.md" index c49e621b918d86e3a96969515fed4605ed142761..99b56c52bd104d6d5a11aa98e6a78ad07bd27714 100644 --- "a/zh-cn/device-dev/\345\257\274\350\257\273.md" +++ "b/zh-cn/device-dev/\345\257\274\350\257\273.md" @@ -48,49 +48,49 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按

整体认知OpenHarmony

- +

获取开发资源

准备开发前相关资源

- +

快速入门

快速熟悉OpenHarmony环境搭建、编译、烧录、调测、运行。

-

轻量和小型系统入门

+

轻量和小型系统快速入门

基础能力使用

使用OpenHarmony提供的基础能力

- +

进阶开发

结合系统能力开发智能设备

- +

移植适配

  • 针对特定芯片做移植适配
  • 对三方库进行移植适配
- +

贡献组件

OpenHarmony贡献功能组件

- +

参考

@@ -118,49 +118,49 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按

整体认知OpenHarmony

- +

获取开发资源

准备开发前相关资源

- +

快速入门

快速熟悉OpenHarmony环境搭建、编译、烧录、调测、运行。

-

标准系统入门

+

标准系统快速入门

基础能力使用

使用OpenHarmony提供的基础能力

- +

进阶开发

结合系统能力开发智能设备

- +

移植适配

对三方库进行移植适配

-

三方库移植指导

+

三方库移植指导

贡献组件

OpenHarmony贡献功能组件

- +

参考

diff --git a/zh-cn/readme.md b/zh-cn/readme.md index d69fd1bcdd4fe9050e0e39a239752d889651b985..3eaa84165113d6597c73e33b98a0adcc20084567 100644 --- a/zh-cn/readme.md +++ b/zh-cn/readme.md @@ -4,51 +4,56 @@ ## 文档目录结构 -- [Openharmony概述](OpenHarmony-Overview_zh.md) -- 轻量和小型系统开发指导(参考内存<128MB) +- [Openharmony概述](OpenHarmony-Overview_zh.md) +- 轻量和小型系统开发指导(参考内存<128MB) - 设备开发 - overview:[设备开发导读](device-dev/导读.md) - quick-start:[快速入门](device-dev/quick-start/Readme-CN.md)(搭建环境、获取源码、编译、烧录等) - - 开发基础能力 - - Kernel:[轻量和小型系统内核](device-dev/kernel/轻量和小型系统内核.md) + - Basic Capability:开发基础能力 + - Kernel:[轻量和小型系统内核](device-dev/kernel/kernel-lite.md) - Drivers:[驱动](device-dev/driver/Readme-CN.md) - Subsystems:[子系统](device-dev/subsystems/Readme-CN.md)(编译构建、图形图像、DFX、XTS等子系统) - Security:[隐私与安全](device-dev/security/Readme-CN.md) - - guide:[开发示例](device-dev/guide/Readme-CN.md) - - [WLAN连接类产品](device-dev/guide/WLAN连接类产品.md)(LED外设控制、集成三方SDK) - - [无屏摄像头类产品](device-dev/guide/无屏摄像头类产品.md)(摄像头控制) - - [带屏摄像头类产品](device-dev/guide/带屏摄像头类产品.md)(屏幕和摄像头控制、视觉应用开发) + - guide:开发示例 + - [WLAN连接类产品](device-dev/guide/device-wifi.md)(LED外设控制、集成三方SDK) + - [无屏摄像头类产品](device-dev/guide/device-iotcamera-control.md)(摄像头控制) + - [带屏摄像头类产品](device-dev/guide/device-camera.md)(屏幕和摄像头控制、视觉应用开发) - - porting:[移植适配](device-dev/porting/Readme-CN.md) - - [三方芯片移植指导](device-dev/porting/三方芯片移植指导.md) - - [三方库移植指导](device-dev/porting/三方库移植指导.md) + - porting:移植适配 + - [三方库移植指导](device-dev/porting/transplant-thirdparty.md) + - [轻量系统芯片移植指导](device-dev/porting/transplant-minichip.md) + - [小型系统芯片移植指导](device-dev/porting/transplant-smallchip.md) - - bundles:[组件开发](device-dev/bundles/Readme-CN.md) - - [组件开发规范](device-dev/bundles/组件开发规范.md) - - [组件开发指南](device-dev/bundles/组件开发指南.md) - - [组件开发示例](device-dev/bundles/组件开发示例.md) + - bundles:组件开发 + - [组件开发规范](device-dev/bundles/bundles-standard-rules.md) + - [组件开发指南](device-dev/bundles/bundles-guide.md) + - [组件开发示例](device-dev/bundles/bundles-demo.md) -- 标准系统开发指导(参考内存≥128MB) +- 标准系统开发指导(参考内存≥128MB) - 设备开发 - overview:[设备开发导读](device-dev/导读.md) - - quick-start:[快速入门](device-dev/quick-start/Readme-CN.md)(搭建环境、获取源码、编译、烧录等) - - 开发基础能力 - - Kernel:[标准系统内核](device-dev/kernel/标准系统内核.md) + - quick-start:[快速入门](device-dev/quick-start/quickstart-standard.md)(搭建环境、获取源码、编译、烧录等) + - Basic Capability:开发基础能力 + - Kernel:[标准系统内核](device-dev/kernel/kernel-standard.md) - Drivers:[驱动](device-dev/driver/Readme-CN.md) - Subsystems:[子系统](device-dev/subsystems/Readme-CN.md)(编译构建、图形图像、DFX、XTS等子系统) - Security:[隐私与安全](device-dev/security/Readme-CN.md) - - guide:[开发示例](device-dev/guide/Readme-CN.md) - - [时钟应用](device-dev/guide/时钟应用开发示例.md) - - [平台驱动](device-dev/guide/平台驱动开发示例.md) - - [外设驱动](device-dev/guide/外设驱动开发示例.md) + - guide:开发示例 + - [时钟应用](device-dev/guide/device-clock-guide.md) + - [平台驱动](device-dev/guide/device-driver-demo.md) + - [外设驱动](device-dev/guide/device-outerdriver-demo.md) + + - porting:移植适配 + + - [三方库移植指导](device-dev/porting/transplant-thirdparty.md) + - [标准系统芯片移植指导](device-dev/porting/standard-system-porting-guide.md) - - porting:[移植适配](device-dev/porting/Readme-CN.md) - - bundles:[组件开发](device-dev/bundles/Readme-CN.md) - - [组件开发规范](device-dev/bundles/组件开发规范.md) - - [组件开发指南](device-dev/bundles/组件开发指南.md) - - [组件开发示例](device-dev/bundles/组件开发示例.md) + - bundles:组件开发 + - [组件开发规范](device-dev/bundles/bundles-standard-rules.md) + - [组件开发指南](device-dev/bundles/bundles-guide.md) + - [组件开发示例](device-dev/bundles/bundles-demo.md) - 应用开发 @@ -58,7 +63,8 @@ - media:[媒体](application-dev/media/Readme-CN.md) - connectivity:[网络与连接](application-dev/connectivity/Readme-CN.md) - js-reference:[JS参考规范](application-dev/js-reference/Readme-CN.md) -- glossary:[术语](device-dev/glossary/术语.md) +- 许可证及版权信息检查工具:[开源合规审查工具](https://gitee.com/openharmony-sig/tools_oat) +- glossary:[术语](device-dev/glossary/glossary.md) ## 版本更新