提交 9f214e8f 编写于 作者: O openharmony_ci 提交者: Gitee

!1083 文档更新-3.1beta版本发布

Merge pull request !1083 from duangavin123/OpenHarmony-3.1-Beta
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
/**
* @addtogroup ADC
* @{
*
* @brief 定义用于模/数转换器驱动程序开发的标准ADC API。
* 此ADC模块抽象了不同系统平台的ADC功能,以提供稳定的API,用于模/数转换器驱动程序开发。您可以使用此模块获取/释放ADC设备句柄。
*
* @since 1.0
*/
/**
* @file adc_if.h
*
* @brief 声明标准ADC接口函数。
*
* @since 1.0
*/
#ifndef ADC_IF_H
#define ADC_IF_H
#include "hdf_platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct AdcIoMsg {
/** ADC设备号 */
uint32_t number;
/** ADC设备通道号 */
uint32_t channel;
};
/**
* @brief 获取ADC设备的句柄。
* 在访问ADC设备之前,必须调用此函数。
*
* @param number ADC设备ID。
*
* @return 如果操作成功,则返回指向ADC设备的DevHandle的指针;否则返回NULL。
*
* @since 1.0
*/
DevHandle AdcOpen(uint32_t number);
/**
* @brief 释放ADC设备的句柄。
* 如果不再需要访问ADC设备,则应调用此函数关闭其句柄,以便释放未使用的内存资源。
*
* @param handle 指向通过{@link AdcOpen}获得的ADC设备的设备句柄的指针。
*
* @since 1.0
*/
void AdcClose(DevHandle handle);
/**
* @brief 从ADC设备读取指定大小的数据。
*
* @param handle 指向通过{@link AdcOpen}获得的ADC设备的设备句柄的指针。
* @param channel ADC设备通道。
* @param val 指向存储读出数据指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
* @since 1.0
*/
int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* ADC_IF_H */
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
/**
* @addtogroup HDMI
* @{
*
* @brief 声明基本高清多媒体接口(HDMI)功能的标准API。
* 您可以使用此模块访问HDMI,并使驱动程序能够操作HDMI接收器设备。
* 这些功能包括在HDMI上启动和停止传输,设置一些属性,并读取接收器设备的EDID数据。
*
* @since 1.0
*/
/**
* @file hdmi_if.h
*
* @brief 声明标准HDMI接口函数。
*
* @since 1.0
*/
#ifndef HDMI_IF_H
#define HDMI_IF_H
#include "hdf_platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/**
* @brief HDMI接收器设备的EDID的最大长度为512字节。
*
* @since 1.0
*/
#define HDMI_EDID_MAX_LEN 512
/**
* @brief 色深
* 详见HDMI协议1.4第6.2.4节。
*
* @since 1.0
*/
enum HdmiDeepColor {
HDMI_DEEP_COLOR_24BITS = 0,
HDMI_DEEP_COLOR_30BITS = 1,
HDMI_DEEP_COLOR_36BITS = 2,
HDMI_DEEP_COLOR_48BITS = 3,
HDMI_DEEP_COLOR_OFF = 0xff,
HDMI_DEEP_COLOR_BUTT,
};
/**
* @brief 视频位深度。
* 详见HDMI协议1.4第6.6节。
*
* @since 1.0
*/
enum HdmiVideoBitDepth {
HDMI_VIDEO_BIT_DEPTH_8 = 0,
HDMI_VIDEO_BIT_DEPTH_10 = 1,
HDMI_VIDEO_BIT_DEPTH_12 = 2,
HDMI_VIDEO_BIT_DEPTH_16 = 3,
HDMI_VIDEO_BIT_DEPTH_OFF,
};
/**
* @brief 色彩空间。
* 详见HDMI协议1.4第6节。
*
* @since 1.0
*/
enum HdmiColorSpace {
HDMI_COLOR_SPACE_RGB = 0,
HDMI_COLOR_SPACE_YCBCR422 = 1,
HDMI_COLOR_SPACE_YCBCR444 = 2,
HDMI_COLOR_SPACE_YCBCR420 = 3,
HDMI_COLOR_SPACE_BUTT,
};
/**
* @brief 比色法。
* 详见HDMI协议1.4第6.7节和HDMI协议2.0第7.2节。
*
* @since 1.0
*/
enum HdmiColorimetry {
HDMI_COLORIMETRY_NO_DATA = 0,
HDMI_COLORIMETRY_ITU601 = 1,
HDMI_COLORIMETRY_ITU709 = 2,
HDMI_COLORIMETRY_EXTENDED = 3,
};
/**
* @brief 扩展比色法。
* 详见HDMI协议1.4第6.7节和HDMI协议2.0第7.2节。
*
* @since 1.0
*/
enum HdmiExtendedColorimetry {
HDMI_EXTENDED_COLORIMETRY_XV_YCC_601 = 0,
HDMI_EXTENDED_COLORIMETRY_XV_YCC_709 = 1,
HDMI_EXTENDED_COLORIMETRY_S_YCC_601 = 2,
HDMI_EXTENDED_COLORIMETRY_OPYCC_601 = 3,
HDMI_EXTENDED_COLORIMETRY_OPRGB = 4,
HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM = 5,
HDMI_EXTENDED_COLORIMETRY_BT2020 = 6,
HDMI_EXTENDED_COLORIMETRY_ADDITIONAL = 7,
HDMI_EXTENDED_COLORIMETRY_BUTT,
};
/**
* @brief 量化范围。
* 详见HDMI协议1.4第6.6节和HDMI协议2.0第7.3节。
*
* @since 1.0
*/
enum HdmiQuantizationRange {
HDMI_QUANTIZATION_RANGE_DEFAULT = 0,
HDMI_QUANTIZATION_RANGE_LIMITED = 1,
HDMI_QUANTIZATION_RANGE_FULL = 2,
HDMI_QUANTIZATION_RANGE_BUTT,
};
/**
* @brief YCC量化范围。
* 详见HDMI协议1.4第6.6节和HDMI协议2.0第7.3节。
*
* @since 1.0
*/
enum HdmiYccQuantizationRange {
HDMI_YCC_QUANTIZATION_RANGE_LIMITED = 0,
HDMI_YCC_QUANTIZATION_RANGE_FULL = 1,
HDMI_YCC_QUANTIZATION_RANGE_BUTT,
};
/**
* @brief 视频三维结构。
* 详见HDMI协议1.4第8.2.3节。
*
* @since 1.0
*/
enum HdmiVideo3dStructure {
HDMI_VS_VIDEO_3D_FRAME_PACKING = 0,
HDMI_VS_VIDEO_3D_FIELD_ALTERNATIVE = 1,
HDMI_VS_VIDEO_3D_LINE_ALTERNATIVE = 2,
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_FULL = 3,
HDMI_VS_VIDEO_3D_L_DEPTH = 4,
HDMI_VS_VIDEO_3D_L_DEPTH_GFX_GFX_DEPTH = 5,
HDMI_VS_VIDEO_3D_TOP_AND_BOTTOM = 6,
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_HALF = 8,
HDMI_VS_VIDEO_3D_BUTT,
};
/**
* @brief 影像时序。
* 详见HDMI协议1.4第8.2.3节。
*
* @since 1.0
*/
enum HdmiVideoTiming {
HDMI_VIDEO_TIMING_NONE = 0,
HDMI_VIDEO_TIMING_640X480P60 = 1,
HDMI_VIDEO_TIMING_720X480P60 = 2,
HDMI_VIDEO_TIMING_720X480P120 = 3,
HDMI_VIDEO_TIMING_720X480P240 = 4,
HDMI_VIDEO_TIMING_720X576P50 = 5,
HDMI_VIDEO_TIMING_720X576P100 = 6,
HDMI_VIDEO_TIMING_720X576P200 = 7,
HDMI_VIDEO_TIMING_1280X720P24 = 8,
HDMI_VIDEO_TIMING_1280X720P25 = 9,
HDMI_VIDEO_TIMING_1280X720P30 = 10,
HDMI_VIDEO_TIMING_1280X720P48 = 11,
HDMI_VIDEO_TIMING_1280X720P50 = 12,
HDMI_VIDEO_TIMING_1280X720P60 = 13,
HDMI_VIDEO_TIMING_1280X720P100 = 14,
HDMI_VIDEO_TIMING_1280X720P120 = 15,
HDMI_VIDEO_TIMING_1440X240P60 = 16,
HDMI_VIDEO_TIMING_1440X288P50 = 17,
HDMI_VIDEO_TIMING_1440X480I60 = 18,
HDMI_VIDEO_TIMING_1440X480P60 = 19,
HDMI_VIDEO_TIMING_1440X480I120 = 20,
HDMI_VIDEO_TIMING_1440X480I240 = 21,
HDMI_VIDEO_TIMING_1440X576I50 = 22,
HDMI_VIDEO_TIMING_1440X576P50 = 23,
HDMI_VIDEO_TIMING_1440X576I60 = 24,
HDMI_VIDEO_TIMING_1440X576I100 = 25,
HDMI_VIDEO_TIMING_1440X576I200 = 26,
HDMI_VIDEO_TIMING_2880X288P50 = 27,
HDMI_VIDEO_TIMING_2880X480I60 = 28,
HDMI_VIDEO_TIMING_2880X480P60 = 29,
HDMI_VIDEO_TIMING_2880X240I60 = 30,
HDMI_VIDEO_TIMING_2880X576I50 = 31,
HDMI_VIDEO_TIMING_2880X576P50 = 32,
HDMI_VIDEO_TIMING_1680X720P24 = 33,
HDMI_VIDEO_TIMING_1680X720P25 = 34,
HDMI_VIDEO_TIMING_1680X720P30 = 35,
HDMI_VIDEO_TIMING_1680X720P48 = 36,
HDMI_VIDEO_TIMING_1680X720P50 = 37,
HDMI_VIDEO_TIMING_1680X720P60 = 38,
HDMI_VIDEO_TIMING_1680X720P100 = 39,
HDMI_VIDEO_TIMING_1680X720P120 = 40,
HDMI_VIDEO_TIMING_2560X1080P24 = 41,
HDMI_VIDEO_TIMING_2560X1080P25 = 42,
HDMI_VIDEO_TIMING_2560X1080P30 = 43,
HDMI_VIDEO_TIMING_2560X1080P48 = 44,
HDMI_VIDEO_TIMING_2560X1080P50 = 45,
HDMI_VIDEO_TIMING_2560X1080P60 = 46,
HDMI_VIDEO_TIMING_2560X1080P100 = 47,
HDMI_VIDEO_TIMING_2560X1080P120 = 48,
HDMI_VIDEO_TIMING_1920X1080I60 = 49,
HDMI_VIDEO_TIMING_1920X1080P60 = 50,
HDMI_VIDEO_TIMING_1920X1080I50 = 51,
HDMI_VIDEO_TIMING_1920X1080P50 = 52,
HDMI_VIDEO_TIMING_1920X1080P24 = 53,
HDMI_VIDEO_TIMING_1920X1080P25 = 54,
HDMI_VIDEO_TIMING_1920X1080P30 = 55,
HDMI_VIDEO_TIMING_1920X1080P48 = 56,
HDMI_VIDEO_TIMING_1920X1080I100 = 57,
HDMI_VIDEO_TIMING_1920X1080I120 = 58,
HDMI_VIDEO_TIMING_1920X1080P120 = 59,
HDMI_VIDEO_TIMING_1920X1080P100 = 60,
HDMI_VIDEO_TIMING_3840X2160P24 = 61,
HDMI_VIDEO_TIMING_3840X2160P25 = 62,
HDMI_VIDEO_TIMING_3840X2160P30 = 63,
HDMI_VIDEO_TIMING_3840X2160P48 = 64,
HDMI_VIDEO_TIMING_3840X2160P50 = 65,
HDMI_VIDEO_TIMING_3840X2160P60 = 66,
HDMI_VIDEO_TIMING_3840X2160P100 = 67,
HDMI_VIDEO_TIMING_3840X2160P120 = 68,
HDMI_VIDEO_TIMING_4096X2160P24 = 69,
HDMI_VIDEO_TIMING_4096X2160P25 = 70,
HDMI_VIDEO_TIMING_4096X2160P30 = 71,
HDMI_VIDEO_TIMING_4096X2160P48 = 72,
HDMI_VIDEO_TIMING_4096X2160P50 = 73,
HDMI_VIDEO_TIMING_4096X2160P60 = 74,
HDMI_VIDEO_TIMING_4096X2160P100 = 75,
HDMI_VIDEO_TIMING_4096X2160P120 = 76,
HDMI_VIDEO_TIMING_5120X2160P24 = 77,
HDMI_VIDEO_TIMING_5120X2160P25 = 78,
HDMI_VIDEO_TIMING_5120X2160P30 = 79,
HDMI_VIDEO_TIMING_5120X2160P48 = 80,
HDMI_VIDEO_TIMING_5120X2160P50 = 81,
HDMI_VIDEO_TIMING_5120X2160P60 = 82,
HDMI_VIDEO_TIMING_5120X2160P100 = 83,
HDMI_VIDEO_TIMING_5120X2160P120 = 84,
HDMI_VIDEO_TIMING_7680X4320P24 = 85,
HDMI_VIDEO_TIMING_7680X4320P25 = 86,
HDMI_VIDEO_TIMING_7680X4320P30 = 87,
HDMI_VIDEO_TIMING_7680X4320P48 = 88,
HDMI_VIDEO_TIMING_7680X4320P50 = 89,
HDMI_VIDEO_TIMING_7680X4320P60 = 90,
HDMI_VIDEO_TIMING_7680X4320P100 = 91,
HDMI_VIDEO_TIMING_7680X4320P120 = 92,
HDMI_VIDEO_TIMING_10240X4320P24 = 93,
HDMI_VIDEO_TIMING_10240X4320P25 = 94,
HDMI_VIDEO_TIMING_10240X4320P30 = 95,
HDMI_VIDEO_TIMING_10240X4320P48 = 96,
HDMI_VIDEO_TIMING_10240X4320P50 = 97,
HDMI_VIDEO_TIMING_10240X4320P60 = 98,
HDMI_VIDEO_TIMING_10240X4320P100 = 99,
HDMI_VIDEO_TIMING_10240X4320P120 = 100,
HDMI_VIDEO_TIMING_VESA_DEFINE = 101,
HDMI_VIDEO_TIMING_VESA_800X600_60 = 102,
HDMI_VIDEO_TIMING_VESA_848X480_60 = 103,
HDMI_VIDEO_TIMING_VESA_1024X768_60 = 104,
HDMI_VIDEO_TIMING_VESA_1280X720_60 = 105,
HDMI_VIDEO_TIMING_VESA_1280X768_60 = 106,
HDMI_VIDEO_TIMING_VESA_1280X768_60_RB = 107,
HDMI_VIDEO_TIMING_VESA_1280X800_60 = 108,
HDMI_VIDEO_TIMING_VESA_1280X800_60_RB = 109,
HDMI_VIDEO_TIMING_VESA_1280X960_60 = 110,
HDMI_VIDEO_TIMING_VESA_1280X1024_60 = 111,
HDMI_VIDEO_TIMING_VESA_1360X768_60 = 112,
HDMI_VIDEO_TIMING_VESA_1366X768_60 = 113,
HDMI_VIDEO_TIMING_VESA_1400X1050_60 = 114,
HDMI_VIDEO_TIMING_VESA_1440X900_60 = 115,
HDMI_VIDEO_TIMING_VESA_1440X900_60_RB = 116,
HDMI_VIDEO_TIMING_VESA_1440X1050_60 = 117,
HDMI_VIDEO_TIMING_VESA_1440X1050_60_RB = 118,
HDMI_VIDEO_TIMING_VESA_1600X900_60_RB = 119,
HDMI_VIDEO_TIMING_VESA_1600X1200_60 = 120,
HDMI_VIDEO_TIMING_VESA_1680X1050_60 = 113,
HDMI_VIDEO_TIMING_VESA_1680X1050_60_RB = 114,
HDMI_VIDEO_TIMING_VESA_1792X1344_60 = 115,
HDMI_VIDEO_TIMING_VESA_1856X1392_60 = 116,
HDMI_VIDEO_TIMING_VESA_1920X1080_60 = 117,
HDMI_VIDEO_TIMING_VESA_1920X1200_60 = 118,
HDMI_VIDEO_TIMING_VESA_1920X1200_60_RB = 119,
HDMI_VIDEO_TIMING_VESA_1920X1440_60 = 120,
HDMI_VIDEO_TIMING_VESA_2048X1152_60 = 121,
HDMI_VIDEO_TIMING_VESA_2560X1440_60_RB = 122,
HDMI_VIDEO_TIMING_VESA_2560X1600_60 = 123,
HDMI_VIDEO_TIMING_VESA_2560X1600_60_RB = 124,
HDMI_VIDEO_TIMING_USER_DEFINE = 125,
HDMI_VIDEO_TIMING_USER_1920X2160_30 = 126,
HDMI_VIDEO_TIMING_USER_2560X1440_30 = 127,
HDMI_VIDEO_TIMING_USER_2560X1440_60 = 128,
HDMI_VIDEO_TIMING_USER_1280X720_60 = 129,
HDMI_VIDEO_TIMING_USER_1366X768_60 = 130,
HDMI_VIDEO_TIMING_USER_1600X900_60_RB = 131,
HDMI_VIDEO_TIMING_USER_1920X1080_60 = 132,
HDMI_VIDEO_TIMING_USER_2048X1152_60 = 133,
HDMI_VIDEO_TIMING_BUTT,
};
/**
* @brief 图片的纵横比。
* 详见HDMI协议1.4第8.2.1节。
*
* @since 1.0
*/
enum HdmiPictureAspectRatio {
HDMI_PICTURE_ASPECT_NO_DATA = 0,
HDMI_PICTURE_ASPECT_4_3 = 1,
HDMI_PICTURE_ASPECT_16_9 = 2,
HDMI_PICTURE_ASPECT_64_27 = 3,
HDMI_PICTURE_ASPECT_256_135 = 4,
HDMI_PICTURE_ASPECT_BUTT = 5,
};
/**
* @brief 活动格式的长宽比。
* 详见HDMI协议1.4第8.2.1节。
*
* @since 1.0
*/
enum HdmiActiveFormatAspectRatio {
HDMI_ACTIVE_FORMAT_ASPECT_16_9_TOP = 2,
HDMI_ACTIVE_FORMAT_ASPECT_14_9_TOP = 3,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_CENTER = 4,
HDMI_ACTIVE_FORMAT_ASPECT_PICTURE = 8,
HDMI_ACTIVE_FORMAT_ASPECT_4_3 = 9,
HDMI_ACTIVE_FORMAT_ASPECT_16_9 = 10,
HDMI_ACTIVE_FORMAT_ASPECT_14_9 = 11,
HDMI_ACTIVE_FORMAT_ASPECT_4_3_SP_14_9 = 13,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_14_9 = 14,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_4_3 = 15,
HDMI_ACTIVE_FORMAT_ASPECT_BUTT,
};
/**
* @brief NUP(非均匀图片缩放)。
* 详见HDMI协议1.4第8.2.1节。
*
* @since 1.0
*/
enum HdmiNups {
HDMI_NUPS_UNKNOWN = 0, /* 没有已知的非均匀缩放 */
HDMI_NUPS_HORIZONTAL = 1, /* 图片已水平缩放 */
HDMI_NUPS_VERTICAL = 2, /* 图片已垂直缩放 */
HDMI_NUPS_BOTH = 3, /* 图片已水平和垂直缩放 */
};
/**
* @brief 定义视频属性结构。
*
* @since 1.0
*/
struct HdmiVideoAttr {
uint32_t tmdsClock; /* 单位:千赫 */
uint32_t pixelClock; /* 单位:千赫 */
uint32_t pixelRepeat;
enum HdmiColorSpace colorSpace;
enum HdmiColorimetry colorimetry;
enum HdmiExtendedColorimetry extColorimetry;
enum HdmiQuantizationRange quantization;
enum HdmiYccQuantizationRange yccQuantization;
enum HdmiDeepColor deepColor;
enum HdmiVideo3dStructure _3dStruct;
enum HdmiVideoTiming timing;
enum HdmiPictureAspectRatio aspect;
enum HdmiActiveFormatAspectRatio activeAspect;
enum HdmiNups nups;
bool xvycc;
};
/**
* @brief 音频编码类型。
* 详见HDMI协议1.4第7节。
*
* @since 1.0
*/
enum HdmiAudioCodingType {
HDMI_AUDIO_CODING_TYPE_STREAM = 0,
HDMI_AUDIO_CODING_TYPE_LPCM = 1,
HDMI_AUDIO_CODING_TYPE_AC3 = 2,
HDMI_AUDIO_CODING_TYPE_MPEG1 = 3,
HDMI_AUDIO_CODING_TYPE_MP3 = 4,
HDMI_AUDIO_CODING_TYPE_MPEG2 = 5,
HDMI_AUDIO_CODING_TYPE_AAC_LC = 6,
HDMI_AUDIO_CODING_TYPE_DTS = 7,
HDMI_AUDIO_CODING_TYPE_ATRAC = 8,
HDMI_AUDIO_CODING_TYPE_OBA = 9,
HDMI_AUDIO_CODING_TYPE_EAC3 = 10,
HDMI_AUDIO_CODING_TYPE_DTS_HD = 11,
HDMI_AUDIO_CODING_TYPE_MLP = 12,
HDMI_AUDIO_CODING_TYPE_DST = 13,
HDMI_AUDIO_CODING_TYPE_WMA_PRO = 14,
HDMI_AUDIO_CODING_TYPE_CXT = 15,
};
/**
* @brief 音频接口类型。
*
* @since 1.0
*/
enum HdmiAudioInterfaceType {
HDMI_AUDIO_IF_TYPE_I2S = 0, /* I2S总线 */
HDMI_AUDIO_IF_TYPE_SPDIF = 1, /* 索尼/飞利浦数字接口 */
HDMI_AUDIO_IF_TYPE_OTHER,
};
/**
* @brief 音频位深度。
* 详见HDMI协议1.4第7节。
*
* @since 1.0
*/
enum HdmiAudioBitDepth {
HDMI_ADIO_BIT_DEPTH_UNKNOWN,
HDMI_ADIO_BIT_DEPTH_8 = 8,
HDMI_ADIO_BIT_DEPTH_16 = 16,
HDMI_ADIO_BIT_DEPTH_18 = 18,
HDMI_ADIO_BIT_DEPTH_20 = 20,
HDMI_ADIO_BIT_DEPTH_24 = 24,
HDMI_ADIO_BIT_DEPTH_32 = 32,
HDMI_ADIO_BIT_DEPTH_BUTT,
};
/**
* @brief 用于音频的采样率。
* 详见HDMI协议1.4第7.3节。
*
* @since 1.0
*/
enum HdmiSampleRate {
HDMI_SAMPLE_RATE_UNKNOWN,
HDMI_SAMPLE_RATE_8K = 8000,
HDMI_SAMPLE_RATE_11K = 11025,
HDMI_SAMPLE_RATE_12K = 12000,
HDMI_SAMPLE_RATE_16K = 16000,
HDMI_SAMPLE_RATE_22K = 22050,
HDMI_SAMPLE_RATE_24K = 24000,
HDMI_SAMPLE_RATE_32K = 32000,
HDMI_SAMPLE_RATE_44K = 44100,
HDMI_SAMPLE_RATE_48K = 48000,
HDMI_SAMPLE_RATE_88K = 88200,
HDMI_SAMPLE_RATE_96K = 96000,
HDMI_SAMPLE_RATE_176K = 176400,
HDMI_SAMPLE_RATE_192K = 192000,
HDMI_SAMPLE_RATE_768K = 768000,
HDMI_SAMPLE_RATE_BUTT,
};
/**
* @brief 音频格式通道。
* 详见HDMI协议1.4第7节。
*
* @since 1.0
*/
enum HdmiAudioFormatChannel {
HDMI_AUDIO_FORMAT_CHANNEL_2 = 2,
HDMI_AUDIO_FORMAT_CHANNEL_3,
HDMI_AUDIO_FORMAT_CHANNEL_4,
HDMI_AUDIO_FORMAT_CHANNEL_5,
HDMI_AUDIO_FORMAT_CHANNEL_6,
HDMI_AUDIO_FORMAT_CHANNEL_7,
HDMI_AUDIO_FORMAT_CHANNEL_8,
HDMI_AUDIO_FORMAT_CHANNEL_BUTT,
};
/**
* @brief 定义音频属性结构。
*
* @since 1.0
*/
struct HdmiAudioAttr {
enum HdmiAudioCodingType codingType;
enum HdmiAudioInterfaceType ifType;
enum HdmiAudioBitDepth bitDepth;
enum HdmiSampleRate sampleRate;
bool downSample;
enum HdmiAudioFormatChannel channels;
};
/**
* @brief 电光传递函数(EOTF)。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
enum HdmiEotfType {
HDMI_EOTF_SDR_LUMIN = 0, /* 传统gamma-SDR亮度范围 */
HDMI_EOTF_HDR_LUMIN = 1, /* 传统gamma-HDR亮度范围 */
HDMI_EOTF_SMPTE_ST_2048 = 2, /* SMPTE ST 2048 */
HDMI_EOTF_HLG = 3, /* 基于ITU-R BT.2100-0的混合对数伽马(HLG) */
HDMI_EOTF_BUTT,
};
/**
* @brief hdr色度计。
* 详见HDMI协议2.1。
*
* @since 1.0
*/
enum HdmiHdrColormetry {
HDMI_HDR_COLORIMETRY_NONE,
HDMI_HDR_COLORIMETRY_ITU_601,
HDMI_HDR_COLORIMETRY_ITU_709,
HDMI_HDR_COLORIMETRY_EXTENDED,
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709,
HDMI_HDR_EXTENDED_COLORIMETRY_S_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_RGB,
HDMI_HDR_EXTENDED_COLORIMETRY_2020_CONST_LUMINOUS, /* BT2020 c_ycc */
HDMI_HDR_EXTENDED_COLORIMETRY_2020_NON_CONST_LUMINOUW
};
/**
* @brief hdr模式。
* 详见HDMI协议2.1。
*
* @since 1.0
*/
enum HdmiHdrMode {
HDMI_HDR_MODE_DISABLE, /* HDR和杜比模式禁用 */
HDMI_HDR_MODE_DOLBY_NORMAL, /* 杜比正常(ycbcr422-12位)模式启用 */
HDMI_HDR_MODE_DOLBY_TUNNELING, /* 杜比隧道(RGB-8bit)模式启用 */
HDMI_HDR_MODE_CEA_861_3, /* HDR标准模式启用(根据<CEA-861-3.2015>) */
HDMI_HDR_MODE_CEA_861_3_AUTHEN, /* HDR授权模式 */
HDMI_HDR_MODE_BUTT
};
/**
* @brief hdr用户模式。
* 详见HDMI协议2.1。
*
* @since 1.0
*/
enum HdmiHdrUserMode {
HDMI_HDR_USERMODE_SDR,
HDMI_HDR_USERMODE_HDR10,
HDMI_HDR_USERMODE_DOLBY,
HDMI_HDR_USERMODE_BUTT
};
/**
* @brief 静态元数据类型。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
enum HdmiStaticMetadataType {
HDMI_DRM_STATIC_METADATA_TYPE_1 = 0, /* 静态元数据类型1 */
HDMI_DRM_STATIC_METADATA_BUTT,
};
/**
* @brief 静态元数据描述符1st。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
struct HdmiStaticMetadataDescriptor1st {
uint16_t displayPrimaries0X; /* display_primaries_x[0], in units of 0.00002 */
uint16_t displayPrimaries0Y; /* display_primaries_y[0], in units of 0.00002 */
uint16_t displayPrimaries1X; /* display_primaries_x[1], in units of 0.00002 */
uint16_t displayPrimaries1Y; /* display_primaries_y[1], in units of 0.00002 */
uint16_t displayPrimaries2X; /* display_primaries_x[2], in units of 0.00002 */
uint16_t displayPrimaries2Y; /* display_primaries_y[2], in units of 0.00002 */
uint16_t whitePointX; /* white_point_x, in units of 0.00002 */
uint16_t whitePointY; /* white_point_y, in units of 0.00002 */
uint16_t maxDisplayMasteringLuminance; /* max_display_mastering_luminance, in units of 1 cd/m^2 */
uint16_t minDisplayMasteringLuminance; /* min_display_mastering_luminance, in units of 0.0001 cd/m^2 */
uint16_t maxContentLightLevel; /* Maximum Content Light Level, in units of 1 cd/m^2 */
uint16_t maxFrameAverageLightLevel; /* Maximum Frame-average Light Level, in units of 1 cd/m^2 */
};
/**
* @brief 定义静态元数据描述符。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
union HdmiStaticMetadataDescriptor {
struct HdmiStaticMetadataDescriptor1st type1;
};
/**
* @brief 定义hdr属性结构。
*
* @since 1.0
*/
struct HdmiHdrAttr {
enum HdmiHdrMode mode;
enum HdmiHdrUserMode userMode;
/* 当模式为HDMI_HDR_mode_CEA_861_3时,以下成员有效 */
enum HdmiEotfType eotfType;
enum HdmiStaticMetadataType metadataType;
union HdmiStaticMetadataDescriptor descriptor;
enum HdmiHdrColormetry colorimetry;
};
/**
* @brief 定义hdmi HPD(热插拔检测)回调信息。
*
* @since 1.0
*/
struct HdmiHpdCallbackInfo {
void *data;
void (*callbackFunc)(void *data, bool hdp);
};
/**
* @brief 打开具有指定总线号的HDMI控制器。
* 在使用HDMI接口之前,您可以获取HDMI控制器的设备句柄。
* 通过调用HdmiOpen,此函数与HdmiClose成对使用。
*
* @param busNum 总线号。
*
* @return 如果操作成功,则返回HDMI控制器的设备句柄DevHandle;否则返回NULL。
*
* @since 1.0
*/
DevHandle HdmiOpen(uint16_t busNum);
/**
* @brief 启动HDMI传输。
* 此函数与HdmiStop成对使用。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiStart(DevHandle handle);
/**
* @brief 停止HDMI传输。
* 此函数与HdmiStart成对使用。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiStop(DevHandle handle);
/**
* @brief HDMI声音图像消隐设置。
* 首先将显示设备置于黑屏静音状态,等待HDMI输出设备开关。接着发送清除AVMute信号,启动显示设备。通过此设置,切换过程中的花屏现象将会被屏蔽掉。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param enable 是否启用avmute。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiAvmuteSet(DevHandle handle, bool enable);
/**
* @brief 设置色深。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param color 要设置的色深,请参见HdmiDeepColor。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color);
/**
* @brief 获取色深。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param color 指向要获取的色深的指针,请参见HdmiDeepColor。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color);
/**
* @brief 设置视频属性。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param attr 指向要设置的视频属性的指针,请参见HdmiVideoAttr。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr);
/**
* @brief 设置音频属性。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param attr 指向要设置的音频属性的指针,请参见HdmiAudioAttr。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr);
/**
* @brief 设置HDR属性。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param attr 指向要设置的hdr属性的指针,请参见HdmiHdrAttr。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr);
/**
* @brief HDMI读取接收器设备的原始EDID数据。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param buffer 指向要读取的数据的指针。
* @param len 要读取的数据的长度。
*
* @return 如果操作成功,返回读取数据的长度;如果操作失败,则返回负值或0。
*
* @since 1.0
*/
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
/**
* @brief 注册HPD(热插拔检测)回调函数。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param callback 指向回调信息的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo *callback);
/**
* @brief HDMI注销HPD(热插拔检测)回调函数。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
* @since 1.0
*/
int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle);
/**
* @brief 关闭HDMI控制器。
* 使用HDMI接口后,可以通过调用HdmiClose关闭HDMI控制器。此函数与HdmiOpen成对使用。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @since 1.0
*/
void HdmiClose(DevHandle handle);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_IF_H */
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
/**
* @addtogroup I3C
* @{
*
* @brief 提供改进的Improved Inter-Integrated Circuit (I3C)接口。
* 该模块允许驱动程序在I3C控制器上执行操作,以访问I3C总线上的设备。
* 包括创建和销毁I3C控制器句柄以及读取和写入数据。
*
* @since 1.0
*/
/**
* @file i3c_if.h
*
* @brief 声明标准I3C接口函数。
*
* @since 1.0
*/
#ifndef I3C_IF_H
#define I3C_IF_H
#include "hdf_platform.h"
#include "i3c_ccc.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
enum TransMode {
/** I2C传输模式 */
I2C_MODE = 0,
/** I3C传输模式 */
I3C_MODE,
/** CCC(通用命令代码)模式 */
CCC_CMD_MODE,
};
enum I3cBusMode {
/** 单数据速率模式 */
I3C_BUS_SDR_MODE = 0,
/** 高数据速率模式 */
I3C_BUS_HDR_MODE,
};
/**
* @brief 定义I3C控制器的配置。
*
* @since 1.0
*/
struct I3cConfig {
/** I3C总线模式 */
enum I3cBusMode busMode;
/** 当前主设备,当控制器是主设备时,其为NULL */
struct I3cDevice *curMaster;
};
/**
* @brief 定义I3C传输、I2C传输或发送CCC(通用命令代码)期间使用的I3C传输消息。
*
* @attention 此结构不限制len指定的数据传输长度,允许的最大长度由特定控制器确定。
* 设备地址addr表示原始设备地址,不需要包含读/写标志位。
* @since 1.0
*/
struct I3cMsg {
/** 目标设备的地址 */
uint16_t addr;
/** 用于存储传输数据的缓冲区地址 */
uint8_t *buf;
/** 传输数据的长度 */
uint16_t len;
/**
* 传输模式标志 | 说明
* ------------| -----------------------
* I2C_FLAG_READ | 读标志
* I2C_FLAG_READ_NO_ACK | 无确认读取标志
* I2C_FLAG_IGNORE_NO_ACK | 忽略无确认标志
* I2C_FLAG_NO_START | 无启动条件标志
* I2C_FLAG_STOP | 停止条件标志
*/
uint16_t flags;
/** 传输模式选择,默认为I2C_MODE */
enum TransMode mode;
/** CCC(通用命令代码)结构,用于CCC_CMD_MODE传输模式 */
struct I3cCccCmd *ccc;
/** I3C错误代码,由驱动程序更新 */
uint16_t err;
};
/**
* @brief 定义I3C IBI(带内中断)的数据。
*
* @attention 生成IBI时,IBI函数中的有效载荷和buf可获得IBI数据。
*
* @since 1.0
*/
struct I3cIbiData {
/** 有效载荷数据长度。IBI有效负载数据的长度。当IBI已生成,读取时请勿修改。 */
uint32_t payload;
/** 数据缓冲区。有效负载数据的指针。 */
uint8_t *buf;
};
enum I3cFlag {
/** 读标志。值1表示读取操作,0表示写入操作。 */
I3C_FLAG_READ = (0x1 << 0),
/** 无ACK读标志。值1表示在读取过程中没有发送ACK信号。 */
I3C_FLAG_READ_NO_ACK = (0x1 << 11),
/** 忽略ACK标志。值1表示忽略非ACK信号。 */
I3C_FLAG_IGNORE_NO_ACK = (0x1 << 12),
/** 无启动条件标志。值1表示消息没有启动条件转移。 */
I3C_FLAG_NO_START = (0x1 << 14),
/** 停止条件标志。值1表示当前传输以停止条件结束。 */
I3C_FLAG_STOP = (0x1 << 15),
};
/**
* @brief IBI(带内中断)回调函数。
* 使用{@link I3cRequestIbi}将其连接到I3C设备。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param addr 重新设置IBI(带内中断)的设备地址。
* @param data IBI的数据结构。
*
* @return 如果操作成功,则返回0;否则返回负值。
* @since 1.0
*/
typedef int32_t (*I3cIbiFunc)(DevHandle handle, uint16_t addr, struct I3cIbiData data);
/**
* @brief 获取I3C控制器的句柄。
* 在访问I3C总线之前,必须调用此函数。
*
* @param number I3C控制器ID。
*
* @return 如果操作成功,则返回指向I3C控制器的DevHandle的指针;否则返回NULL。
*
* @since 1.0
*/
DevHandle I3cOpen(int16_t number);
/**
* @brief 释放I3C控制器的句柄。
* 如果不再需要访问I3C控制器,则应调用此函数关闭其句柄,以便释放未使用的内存资源。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
*
* @since 1.0
*/
void I3cClose(DevHandle handle);
/**
* @brief 启动到I3C设备或兼容的I2C设备的传输,或者向支持的I3C设备发送CCC(通用命令代码)。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param msg 指向I3C传输消息结构数组的指针。
* @param count 消息结构数组的长度。
* @param mode 传输模式。
*
* @return 如果操作成功,返回传输的消息结构数;
* @see I3cMsg
* @attention 此结构不限制len指定的数据传输长度。 特定的 I3C 控制器决定了允许的最大长度。 设备地址addr表示原始设备地址,不需要包含读/写标志位。
*
* @since 1.0
*/
int32_t I3cTransfer(DevHandle handle, struct I3cMsg *msg, int16_t count, enum TransMode mode);
/**
* @brief 重新设置受支持的I3C设备的IBI(带内中断)。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param addr 重新设置IBI(带内中断)的设备地址。
* @param func IBI回调函数。
* @param payload 有效负载数据的长度,以字节为单位。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t payload);
/**
* @brief 释放{@link I3cRequestIbi}重新设置的IBI(带内中断)。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param addr 要释放IBI的设备的地址。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cFreeIbi(DevHandle handle, uint16_t addr);
/**
* @brief 设置I3C控制器的配置。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param config 要设置的配置结构的指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config);
/**
* @brief 获取I3C控制器的配置。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param config 用于存储配置的结构体。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* I3C_IF_H */
/** @} */
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
/**
* @addtogroup MIPI CSI
* @{
*
* @brief 定义用于外设接收端驱动程序开发的标准MIPI CSI API。
* 此MIPI CSI模块抽象了不同系统平台的MIPI CSI功能,以提供稳定的API。
* 用于外设接收端驱动程序开发。您可以使用此模块获取/释放MIPI CSI设备句柄。
*
* @since 1.0
*/
/**
* @file mipi_csi_if.h
*
* @brief 声明用于显示驱动程序开发的标准MIPI CSI API。
*
*
*
* @since 1.0
*/
#ifndef MIPI_CSI_IF_H
#define MIPI_CSI_IF_H
#include "hdf_platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/**
* @brief MIPI RX的MIPI设备支持的最大通道数。
*
* @since 1.0
*/
#define MIPI_LANE_NUM 4
/**
* @brief Mipi Rx的LVDS设备支持的最大通道数。
*
* @since 1.0
*/
#define LVDS_LANE_NUM 4
/**
* @brief 定义支持的最大虚拟通道数。
*
* @since 1.0
*/
#define WDR_VC_NUM 4
/**
* @brief 为LVDS的每个虚拟通道定义同步代码的数量。
*
* @since 1.0
*/
#define SYNC_CODE_NUM 4
/**
* @brief 最多3组扩展数据类型。
*
* @since 1.0
*/
#define MAX_EXT_DATA_TYPE_NUM 3
/**
* @brief Mipi-Rx的通道分布。
*
* @since 1.0
*/
typedef enum {
LANE_DIVIDE_MODE_0 = 0,
LANE_DIVIDE_MODE_1 = 1,
LANE_DIVIDE_MODE_BUTT
} LaneDivideMode;
/**
* @brief MIPI接收输入接口类型。
*
* @since 1.0
*/
typedef enum {
/** mipi */
INPUT_MODE_MIPI = 0x0,
/** SUB_LVDS */
INPUT_MODE_SUBLVDS = 0x1,
/** LVDS */
INPUT_MODE_LVDS = 0x2,
/* HISPI */
INPUT_MODE_HISPI = 0x3,
/** CMOS */
INPUT_MODE_CMOS = 0x4,
/** BT601 */
INPUT_MODE_BT601 = 0x5,
/** BT656 */
INPUT_MODE_BT656 = 0x6,
/** BT1120 */
INPUT_MODE_BT1120 = 0x7,
/** MIPI Bypass */
INPUT_MODE_BYPASS = 0x8,
INPUT_MODE_BUTT
} InputMode;
/**
* @brief MIPI接收速率。
*
* @since 1.0
*/
typedef enum {
/** output 1 pixel per clock */
MIPI_DATA_RATE_X1 = 0,
/** output 2 pixel per clock */
MIPI_DATA_RATE_X2 = 1,
MIPI_DATA_RATE_BUTT
} MipiDataRate;
/**
* @brief Mipi图像区域。
*
* @since 1.0
*/
typedef struct {
int x;
int y;
unsigned int width;
unsigned int height;
} ImgRect;
/**
* @brief 传输的数据类型。
*
* @since 1.0
*/
typedef enum {
DATA_TYPE_RAW_8BIT = 0,
DATA_TYPE_RAW_10BIT,
DATA_TYPE_RAW_12BIT,
DATA_TYPE_RAW_14BIT,
DATA_TYPE_RAW_16BIT,
DATA_TYPE_YUV420_8BIT_NORMAL,
DATA_TYPE_YUV420_8BIT_LEGACY,
DATA_TYPE_YUV422_8BIT,
/** YUV422 8位转换用户定义16位原始数据 */
DATA_TYPE_YUV422_PACKED,
DATA_TYPE_BUTT
} DataType;
/**
* @brief 定义YUV和原始数据格式以及位深度。
*
* @since 1.0
*/
typedef struct {
uint8_t devno;
unsigned int num;
unsigned int extDataBitWidth[MAX_EXT_DATA_TYPE_NUM];
unsigned int extDataType[MAX_EXT_DATA_TYPE_NUM];
} ExtDataType;
/**
* @brief MIPI D-PHY WDR模式定义。
*
* @since 1.0
*/
typedef enum {
HI_MIPI_WDR_MODE_NONE = 0x0,
/** Virtual Channel */
HI_MIPI_WDR_MODE_VC = 0x1,
/** Data Type */
HI_MIPI_WDR_MODE_DT = 0x2,
/** DOL Mode */
HI_MIPI_WDR_MODE_DOL = 0x3,
HI_MIPI_WDR_MODE_BUTT
} MipiWdrMode;
/**
* @brief Mipi设备属性。
*
* @since 1.0
*/
typedef struct {
/** 数据类型:8/10/12/14/16位 */
DataType inputDataType;
/** MIPI WDR模式定义 */
MipiWdrMode wdrMode;
/** 通道id: -1 - 禁用 */
short laneId[MIPI_LANE_NUM];
union {
/** 由HI_MIPI_WDR_MODE_DT使用 */
short dataType[WDR_VC_NUM];
};
} MipiDevAttr;
/**
* @brief LVDS WDR模式定义。
*
* @since 1.0
*/
typedef enum {
HI_WDR_MODE_NONE = 0x0,
HI_WDR_MODE_2F = 0x1,
HI_WDR_MODE_3F = 0x2,
HI_WDR_MODE_4F = 0x3,
HI_WDR_MODE_DOL_2F = 0x4,
HI_WDR_MODE_DOL_3F = 0x5,
HI_WDR_MODE_DOL_4F = 0x6,
HI_WDR_MODE_BUTT
} WdrMode;
/**
* @brief LVDS同步模式。
*
* @since 1.0
*/
typedef enum {
/** 传感器SOL、EOL、SOF、EOF */
LVDS_SYNC_MODE_SOF = 0,
/** SAV, EAV */
LVDS_SYNC_MODE_SAV,
LVDS_SYNC_MODE_BUTT
} LvdsSyncMode;
/**
* @brief LVDS 列同步类型。
*
* @since 1.0
*/
typedef enum {
LVDS_VSYNC_NORMAL = 0x00,
LVDS_VSYNC_SHARE = 0x01,
LVDS_VSYNC_HCONNECT = 0x02,
LVDS_VSYNC_BUTT
} LvdsVsyncType;
/**
* @brief LVDS-Vsync列同步参数。
*
* @since 1.0
*/
typedef struct {
LvdsVsyncType syncType;
/* 当 sync_type 为 LVDS_VSYNC_HCONNECT 时,需要配置 hblank1 和 hblank2,表示 Hconnect 的消隐区长度 */
unsigned short hblank1;
unsigned short hblank2;
} LvdsVsyncAttr;
/**
* @brief 帧ID类型。
*
* @since 1.0
*/
typedef enum {
LVDS_FID_NONE = 0x00,
/** SAV 4th中的帧标识id */
LVDS_FID_IN_SAV = 0x01,
/** 第一个数据中的帧标识id */
LVDS_FID_IN_DATA = 0x02,
LVDS_FID_BUTT
} LvdsFidType;
/**
* @brief 帧ID配置信息。
*
* @since 1.0
*/
typedef struct {
LvdsFidType fidType;
/** 索尼DOL有帧信息线,在DOL H连接模式下,
应将此标志配置为false以禁用输出帧信息行。 */
unsigned char outputFil;
} LvdsFidAttr;
/**
* @brief 位大小端模式。
*
* @since 1.0
*/
typedef enum {
LVDS_ENDIAN_LITTLE = 0x0,
LVDS_ENDIAN_BIG = 0x1,
LVDS_ENDIAN_BUTT
} LvdsBitEndian;
/**
* @brief LVDS/SUBSLVDS/HiSPi设备属性。
*
* @since 1.0
*/
typedef struct {
/** 数据类型:8/10/12/14位 */
DataType inputDataType;
/** 波分复用模式 */
WdrMode wdrMode;
/** 同步模式:SOF,SAV */
LvdsSyncMode syncMode;
/** 正常、共享、连接 */
LvdsVsyncAttr vsyncAttr;
/** 帧识别码 */
LvdsFidAttr fidAttr;
/** 数据端:小/大 */
LvdsBitEndian dataEndian;
/** 同步代码endian:小/大 */
LvdsBitEndian syncCodeEndian;
/** 通道id: -1 - 禁用 */
short laneId[LVDS_LANE_NUM];
/** 每个vc有4个参数,syncCode[i]:
同步模式是SYNC_MODE_SOF:SOF、EOF、SOL、EOL
同步模式是SYNC_MODE_SAV:无效SAV、无效eav、有效SAV、有效eav */
unsigned short syncCode[LVDS_LANE_NUM][WDR_VC_NUM][SYNC_CODE_NUM];
} LvdsDevAttr;
/**
* @brief 组合设备的属性。
* 组合设备属性,由于 MIPI Rx 能够对接 CSI-2、LVDS、HiSPi 等时序,所以将 MIPI Rx 称为组合设备。
*
* @since 1.0
*/
typedef struct {
/** 设备号 */
uint8_t devno;
/** 输入模式:MIPI/LVDS/SUBSLVDS/HISPI/DC */
InputMode inputMode;
MipiDataRate dataRate;
/** MIPI Rx设备裁剪区域(与原始传感器输入图像大小相对应) */
ImgRect imgRect;
union {
MipiDevAttr mipiAttr;
LvdsDevAttr lvdsAttr;
};
} ComboDevAttr;
/**
* @brief 共模电压模式。
*
* @since 1.0
*/
typedef enum {
PHY_CMV_GE1200MV = 0x00,
PHY_CMV_LT1200MV = 0x01,
PHY_CMV_BUTT
} PhyCmvMode;
/**
* @brief 获取具有指定通道ID的MIPI CSI设备句柄。
*
* @param id 表示 MIPI CSI通道id。
*
* @return 如果操作成功,则返回MIPI CSI设备句柄;否则返回NULL。
*
* @since 1.0
*/
DevHandle MipiCsiOpen(uint8_t id);
/**
* @brief 释放MIPI CSI设备句柄。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
*
* @since 1.0
*/
void MipiCsiClose(DevHandle handle);
/**
* @brief 将Mipi、CMOS或LVDS摄像机的参数设置到控制器。
* 参数包括工作模式、图像面积、图像深度、数据速率和物理通道。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param pAttr 指向属性的指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr);
/**
* @brief 设置共模电压模式。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param devno 总共有2个设备编号,指向0或1。
* @param cmvMode 共模电压模式参数。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode);
/**
* @brief 复位传感器。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsResetSource 传感器的复位信号线号在软件中称为传感器的复位源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource);
/**
* @brief 撤销复位传感器。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsResetSource 传感器的复位信号线号在软件中称为传感器的复位源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource);
/**
* @brief 复位 MIPI RX。
* 不同的s32WorkingViNum有不同的enSnsType。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI Rx或者SLVS 设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev);
/**
* @brief 未设置的MIPI RX.
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI Rx或者SLVS 设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev);
/**
* @brief 设置Mipi Rx的通道分布。
* 根据硬件连接形式选择具体模式。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param laneDivideMode 通道划分模式参数。
*
* @since 1.0
*/
int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode);
/**
* @brief 使能mipi的时钟。
* 根据上层函数电泳传递的enSnsType参数决定是用 MIPI 还是LVDS。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI接收或LVDS设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev);
/**
* @brief 关闭Mipi的时钟。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI接收或LVDS设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev);
/**
* @brief 启用Mipi上的传感器时钟。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsClkSource 传感器的时钟信号线号,在软件中称为传感器的时钟源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource);
/**
* @brief 关闭传感器时钟。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsClkSource 传感器的时钟信号线号,在软件中称为传感器的时钟源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource);
/**
* @brief 设置YUV和原始数据格式以及位深度。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param dataType 指向图像数据格式的指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType* dataType);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MIPI_CSI_IF_H */
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* 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.
*/
/**
* @addtogroup USB
* @{
*
* @brief Declares USB-related APIs, including the custom data types and functions
* used to obtain descriptors, interface objects, and request objects, and to submit requests.
*
* @since 3.0
* @version 1.0
*/
/**
* @file usbd_client.h
*
* @brief Defines the usbd Interface.
*
* @since 3.0
* @version 1.0
*/
#ifndef USBD_CLIENT_H
#define USBD_CLIENT_H
#include "usb_param.h"
#include "usbd_subscriber.h"
namespace OHOS {
namespace USB {
class UsbdClient {
public:
/* *
* @brief 打开设备,建立连接
*
* @param dev usb设备地址信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t OpenDevice(const UsbDev &dev);
/* *
* @brief 关闭设备,释放与设备相关的所有系统资源
*
* @param dev usb设备地址信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t CloseDevice(const UsbDev &dev);
/* *
* @brief 获取设备描述符device
*
* @param dev usb设备地址信息
* @param decriptor usb设备描述符信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t GetDeviceDescriptor(const UsbDev &dev, std::vector<uint8_t> &decriptor);
/* *
* @brief 根据String ID获取设备的字符串描述符string
*
* @param dev usb设备地址信息
* @param descId usb的string ID
* @param decriptor 获取usb设备config信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t GetStringDescriptor(const UsbDev &dev, uint8_t descId, std::vector<uint8_t> &decriptor);
/* *
* @brief 根据config ID获取设备的配置描述符config
*
* @param dev usb设备地址信息
* @param descId usb的config ID
* @param decriptor 获取usb设备config信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t GetConfigDescriptor(const UsbDev &dev, uint8_t descId, std::vector<uint8_t> &decriptor);
/* *
* @brief 获取原始描述符
*
* @param dev usb设备地址信息
* @param decriptor usb设备原始描述符
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t GetRawDescriptor(const UsbDev &dev, std::vector<uint8_t> &decriptor);
/* *
* @brief 设置当前的config信息
*
* @param dev usb设备地址信息
* @param configIndex usb设备config信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t SetConfig(const UsbDev &dev, uint8_t configIndex);
/* *
* @brief 获取当前的config信息
*
* @param dev usb设备地址信息
* @param configIndex usb设备config信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t GetConfig(const UsbDev &dev, uint8_t &configIndex);
/* *
* @brief 打开接口,并申明独占接口,必须在数据传输前执行
*
* @param dev usb设备地址信息
* @param interfaceid usb设备interface ID
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t ClaimInterface(const UsbDev &dev, uint8_t interfaceid);
/* *
* @brief 关闭接口,释放接口的占用,在停止数据传输后执行
*
* @param dev usb设备地址信息
* @param interfaceid usb设备interface ID
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t ReleaseInterface(const UsbDev &dev, uint8_t interfaceid);
/* *
* @brief 设置指定接口的备选设置,用于在具有相同ID但不同备用设置的两个接口之间进行选择
*
* @param dev usb设备地址信息
* @param interfaceid usb设备interface ID
* @param altIndex interface 的 AlternateSetting 信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t SetInterface(const UsbDev &dev, uint8_t interfaceid, uint8_t altIndex);
/* *
* @brief 在给定端点上执行批量数据读取,返回读取的数据和长度,端点方向必须为数据读取可以设置超时时间
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param timeout 超时时间
* @param data 获取写入的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t
BulkTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
/* *
* @brief 在给定端点上执行批量数据写入,返回读取的数据和长度,端点方向必须为数据写入
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param timeout 超时时间
* @param data 写入的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t
BulkTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, const std::vector<uint8_t> &data);
/* *
* @brief 对此设备执行端点零的控制事务,传输方向由请求类型决定。如果requestType&
* USB_ENDPOINT_DIR_MASK是USB_DIR_OUT,则传输是写入,如果是USB_DIR_IN,则传输是读取。
*
* @param dev usb设备地址信息
* @param ctrl usb设备控制数据包结构
* @param data 读取/写入 的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t ControlTransfer(const UsbDev &dev, const UsbCtrlTransfer &ctrl, std::vector<uint8_t> &data);
/* *
* @brief 在给定端点上执行中断数据读取,返回读取的数据和长度,端点方向必须为数据读取
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param timeout 超时时间
* @param data 读取的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t
InterruptTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
/* *
* @brief 在给定端点上执行中断数据写入,返回读取的数据和长度,端点方向必须为数据写入
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param timeout 超时时间
* @param data 读取的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t
InterruptTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
/* *
* @brief 在给定端点上执行等时数据读取,返回读取的数据和长度,端点方向必须为数据读取
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param timeout 超时时间
* @param data 读取的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t IsoTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
/* *
* @brief 在给定端点上执行等时数据写入,返回读取的数据和长度,端点方向必须为数据写入
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param timeout 超时时间
* @param data 读取的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t
IsoTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
/* *
* @brief 将指定的端点进行异步数据发送或者接收请求,数据传输方向由端点方向决定
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param clientData 用户数据
* @param buffer 传输数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t RequestQueue(const UsbDev &dev,
const UsbPipe &pipe,
const std::vector<uint8_t> &clientData,
const std::vector<uint8_t> &buffer);
/* *
* @brief 等待RequestQueue异步请求的操作结果
*
* @param dev usb设备地址信息
* @param clientData 用户数据
* @param buffer 传输数据
* @param timeout 超时时间
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t
RequestWait(const UsbDev &dev, std::vector<uint8_t> &clientData, std::vector<uint8_t> &buffer, int32_t timeout);
/* *
* @brief 取消待处理的数据请求
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t RequestCancel(const UsbDev &dev, const UsbPipe &pipe);
/* *
* @brief 获取从设备支持的功能列表(按位域表示)(从设备)
*
* @param funcs 获取当前设备的function的值
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t GetCurrentFunctions(int32_t &funcs);
/* *
* @brief 设置从设备支持的功能列表(按位域表示)(从设备)
*
* @param funcs 传入设备支持的function的值
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t SetCurrentFunctions(int32_t funcs);
/* *
* @brief 关闭设备,释放与设备相关的所有系统资源
*
* @param portId port接口 ID
* @param powerRole 电源角色的值
* @param dataRole 数据角色的值
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t SetPortRole(int32_t portId, int32_t powerRole, int32_t dataRole);
/* *
* @brief 查询port端口的当前设置
*
* @param portId port接口 ID
* @param powerRole 电源角色的值
* @param dataRole 数据角色的值
* @param mode 模式的值
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t QueryPort(int32_t &portId, int32_t &powerRole, int32_t &dataRole, int32_t &mode);
/* *
* @brief 绑定订阅者
*
* @param subscriber 订阅者信息
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static ErrCode BindUsbdSubscriber(const sptr<UsbdSubscriber> &subscriber);
/* *
* @brief 解绑订阅者
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static ErrCode UnbindUsbdSubscriber();
/* *
* @brief 异步批量读取数据,传输大量数据时使用
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param length 打算以什么长度读取数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t BulkRequstDataSize(const UsbDev &dev, const UsbPipe &pipe, uint32_t &length);
/* *
* @brief 与BulkRequstDataSize配合使用,获取读取结果
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param data 读取到的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t BulkReadData(const UsbDev &dev, const UsbPipe &pipe, std::vector<uint8_t> &data);
/* *
* @brief 异步批量写数据,传输大量数据时使用
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param data 要写入的数据
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t BulkWriteData(const UsbDev &dev, const UsbPipe &pipe, const std::vector<uint8_t> &data);
/* *
* @brief 与BulkWriteData配合使用,获取写入状态,由length描述
*
* @param dev usb设备地址信息
* @param pipe usb设备pipe信息
* @param length 已经写入的数据长度
*
* @return 0 表示成功,其他返回值表示失败
* @since 3.0
*/
static int32_t BulkGetWriteCompleteLength(const UsbDev &dev, const UsbPipe &pipe, uint32_t &length);
private:
static void PrintBuffer(const char *title, const uint8_t *buffer, uint32_t length);
static int32_t SetDeviceMessage(MessageParcel &data, const UsbDev &dev);
static int32_t SetBufferMessage(MessageParcel &data, const std::vector<uint8_t> &tdata);
static int32_t GetBufferMessage(MessageParcel &data, std::vector<uint8_t> &tdata);
static sptr<IRemoteObject> GetUsbdService();
static ErrCode DoDispatch(uint32_t cmd, MessageParcel &data, MessageParcel &reply);
};
} // namespace USB
} // namespace OHOS
#endif // USBD_CLIENT_H
...@@ -48,7 +48,7 @@ root { ...@@ -48,7 +48,7 @@ root {
## 编写驱动代码<a name="section177988005"></a> ## 编写驱动代码<a name="section177988005"></a>
基于HDF框架编写的sample驱动代码如下: 基于HDF框架编写的sample驱动代码如下(编译参考 [驱动开发](driver-hdf-development.md))
``` ```
#include <fcntl.h> #include <fcntl.h>
...@@ -120,7 +120,7 @@ HDF_INIT(g_sampleDriverEntry); ...@@ -120,7 +120,7 @@ HDF_INIT(g_sampleDriverEntry);
## 编写用户程序和驱动交互代码<a name="section6205173816412"></a> ## 编写用户程序和驱动交互代码<a name="section6205173816412"></a>
基于HDF框架编写的用户态程序和驱动交互的代码如下: 基于HDF框架编写的用户态程序和驱动交互的代码如下(代码可以放在目录drivers/adapter/uhdf下面编译,build.gn可以参考drivers/framework/sample/platform/uart/dev/build.gn)
``` ```
#include <fcntl.h> #include <fcntl.h>
......
...@@ -1455,7 +1455,7 @@ HDF_INIT(g_usbSerialRawDriverEntry); ...@@ -1455,7 +1455,7 @@ HDF_INIT(g_usbSerialRawDriverEntry);
### Device DDK API驱动开发<a name="section615mcpsimp"></a> ### Device DDK API驱动开发<a name="section615mcpsimp"></a>
USB ACM设备核心代码路径为driversperipheralusbgadgetfunctionacmcdcacm.c,其使用示例如下所示,首先根据描述符创建设备,然后获取接口,打开接口,获取Pipe信息,接收Event事件,接着进行USB通信(读写等),设备卸载时候,关闭接口,停止Event接收,删除设备。 USB ACM设备核心代码路径为drivers/peripheral/usb/gadget/function/acmcdcacm.c,其使用示例如下所示,首先根据描述符创建设备,然后获取接口,打开接口,获取Pipe信息,接收Event事件,接着进行USB通信(读写等),设备卸载时候,关闭接口,停止Event接收,删除设备。
``` ```
1、创建设备 1、创建设备
......
...@@ -14,8 +14,7 @@ ...@@ -14,8 +14,7 @@
- [获取方式3:从镜像站点获取](#section1186691118430) - [获取方式3:从镜像站点获取](#section1186691118430)
- [获取方式4:从github镜像仓库获取\(每天UTC时间23点同步\)](#section23448418360) - [获取方式4:从github镜像仓库获取\(每天UTC时间23点同步\)](#section23448418360)
- [源码目录](#section1072115612811) - [源码目录简介](#section1072115612811)
## OpenHarmony介绍<a name="section6370143622110"></a> ## OpenHarmony介绍<a name="section6370143622110"></a>
...@@ -77,7 +76,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -77,7 +76,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
- **OpenHarmony主干代码获取** - **OpenHarmony主干代码获取**
方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 方式一(推荐):通过repo + ssh下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。
``` ```
repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify
...@@ -85,7 +84,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -85,7 +84,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
repo forall -c 'git lfs pull' repo forall -c 'git lfs pull'
``` ```
方式二:通过repo + https 下载。 方式二:通过repo + https下载。
``` ```
repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
...@@ -93,10 +92,9 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -93,10 +92,9 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
repo forall -c 'git lfs pull' repo forall -c 'git lfs pull'
``` ```
- **OpenHarmony发布版本代码获取**
- **OpenHarmony 发布版本代码获取** OpenHarmony发布版本获取源码方式请参考[Release-Notes](../../release-notes/Readme.md)。
OpenHarmony发布版本源码获取方式请参考[Release-Notes](../../release-notes/Readme.md)。
## 获取方式2:从DevEco Marketplace获取<a name="section463013147412"></a> ## 获取方式2:从DevEco Marketplace获取<a name="section463013147412"></a>
...@@ -113,7 +111,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -113,7 +111,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
官网下载并在本地安装Node.js. 官网下载并在本地安装Node.js.
[Node.js](https://nodejs.org/) 版本需不低于12.x \(包含 npm 6.14.4\),推荐安装 LTS版本。 [Node.js](https://nodejs.org/) 版本需不低于12.x \(包含npm 6.14.4\),推荐安装LTS版本。
2. 通过Node.js自带的npm安装hpm命令行工具。 2. 通过Node.js自带的npm安装hpm命令行工具。
...@@ -175,126 +173,190 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -175,126 +173,190 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
为了获得更好的下载性能,您可以选择从以下站点的镜像库获取源码或者对应的解决方案。 为了获得更好的下载性能,您可以选择从以下站点的镜像库获取源码或者对应的解决方案。
本部分只提供OpenHarmony Master最新版本和LTS最新版本的源码获取方式, 其他版本源码获取方式以及具体版本信息请参考[Release-Notes](../../release-notes/Readme.md) 本部分只提供OpenHarmony Master最新版本和LTS最新版本的获取源码方式, 其他版本获取源码方式以及具体版本信息请参考[Release-Notes](../../release-notes/Readme.md)
**表 1** 源码获取路径 **表 1** 获取源码路径
<a name="table17735923173912"></a> <a name="table17735923173912"></a>
<table><tbody><tr id="row1073515237392"><td class="cellrowborder" valign="top" width="25%"><p id="p5109183611392"><a name="p5109183611392"></a><a name="p5109183611392"></a><strong id="b31091936183918"><a name="b31091936183918"></a><a name="b31091936183918"></a>LTS版本源码</strong></p> <table><thead align="left"><tr id="row1073515237392"><th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.1"><p id="p5109183611392"><a name="p5109183611392"></a><a name="p5109183611392"></a><strong id="b31091936183918"><a name="b31091936183918"></a><a name="b31091936183918"></a>LTS版本源码</strong></p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.2"><p id="p13109436103916"><a name="p13109436103916"></a><a name="p13109436103916"></a><strong id="b191091936153912"><a name="b191091936153912"></a><a name="b191091936153912"></a>版本信息</strong></p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.3"><p id="p610923616398"><a name="p610923616398"></a><a name="p610923616398"></a><strong id="b1210920365393"><a name="b1210920365393"></a><a name="b1210920365393"></a>下载站点</strong></p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.4"><p id="p2109736133914"><a name="p2109736133914"></a><a name="p2109736133914"></a><strong id="b18109113613397"><a name="b18109113613397"></a><a name="b18109113613397"></a>SHA256校验码</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row17736152318398"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1110983610395"><a name="p1110983610395"></a><a name="p1110983610395"></a>全量代码(标准、轻量和小型系统)</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p151091536143915"><a name="p151091536143915"></a><a name="p151091536143915"></a>3.0</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p15931114016546"><a name="p15931114016546"></a><a name="p15931114016546"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/code-v3.0-LTS.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p3770144281415"><a name="p3770144281415"></a><a name="p3770144281415"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/code-v3.0-LTS.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td>
</tr>
<tr id="row14814218214"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p2481132228"><a name="p2481132228"></a><a name="p2481132228"></a>标准系统解决方案(二进制)</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p94811121629"><a name="p94811121629"></a><a name="p94811121629"></a>3.0</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1358555631"><a name="p1358555631"></a><a name="p1358555631"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/standard.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p10581551639"><a name="p10581551639"></a><a name="p10581551639"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/standard.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td>
</tr>
<tr id="row473612318396"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p511014369394"><a name="p511014369394"></a><a name="p511014369394"></a>Hi3861解决方案(二进制)</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p0110036193911"><a name="p0110036193911"></a><a name="p0110036193911"></a>3.0</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p29291940175415"><a name="p29291940175415"></a><a name="p29291940175415"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_pegasus.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p134864584147"><a name="p134864584147"></a><a name="p134864584147"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_pegasus.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td>
</tr>
<tr id="row873614239395"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p11110113633913"><a name="p11110113633913"></a><a name="p11110113633913"></a>Hi3518解决方案(二进制)</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p18110193613391"><a name="p18110193613391"></a><a name="p18110193613391"></a>3.0</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p125681045181518"><a name="p125681045181518"></a><a name="p125681045181518"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_aries.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p4607175915149"><a name="p4607175915149"></a><a name="p4607175915149"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_aries.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td>
</tr>
<tr id="row1273682343914"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p15110123693919"><a name="p15110123693919"></a><a name="p15110123693919"></a>Hi3516解决方案-LiteOS(二进制)</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p1211012362396"><a name="p1211012362396"></a><a name="p1211012362396"></a>3.0</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p10455184661518"><a name="p10455184661518"></a><a name="p10455184661518"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p84951102150"><a name="p84951102150"></a><a name="p84951102150"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td>
</tr>
<tr id="row18945941460"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p12945204118618"><a name="p12945204118618"></a><a name="p12945204118618"></a>Hi3516解决方案-Linux(二进制)</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p7686415384"><a name="p7686415384"></a><a name="p7686415384"></a>3.0</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p156861155812"><a name="p156861155812"></a><a name="p156861155812"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus_linux.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p16686201510815"><a name="p16686201510815"></a><a name="p16686201510815"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus_linux.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td>
</tr>
<tr id="row167371123163914"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p10110143610393"><a name="p10110143610393"></a><a name="p10110143610393"></a>RELEASE-NOTES</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p13109436103916"><a name="p13109436103916"></a><a name="p13109436103916"></a><strong id="b191091936153912"><a name="b191091936153912"></a><a name="b191091936153912"></a>版本信息</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p141101436193911"><a name="p141101436193911"></a><a name="p141101436193911"></a>3.0</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p610923616398"><a name="p610923616398"></a><a name="p610923616398"></a><strong id="b1210920365393"><a name="b1210920365393"></a><a name="b1210920365393"></a>下载站点</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p88931840195416"><a name="p88931840195416"></a><a name="p88931840195416"></a><a href="https://gitee.com/openharmony/docs/blob/OpenHarmony-3.0-LTS/zh-cn/release-notes/OpenHarmony-v3.0-LTS.md" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p2109736133914"><a name="p2109736133914"></a><a name="p2109736133914"></a><strong id="b18109113613397"><a name="b18109113613397"></a><a name="b18109113613397"></a>SHA256校验码</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p039662242117"><a name="p039662242117"></a><a name="p039662242117"></a>-</p>
</td> </td>
</tr> </tr>
<tr id="row17736152318398"><td class="cellrowborder" valign="top" width="25%"><p id="p1110983610395"><a name="p1110983610395"></a><a name="p1110983610395"></a>全量代码(标准、轻量和小型系统)</p> <tr id="row573719239393"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p104146493390"><a name="p104146493390"></a><a name="p104146493390"></a><strong id="b12414104919398"><a name="b12414104919398"></a><a name="b12414104919398"></a>Master版本源码</strong></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p151091536143915"><a name="p151091536143915"></a><a name="p151091536143915"></a>3.0</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p194141849163919"><a name="p194141849163919"></a><a name="p194141849163919"></a><strong id="b441494913918"><a name="b441494913918"></a><a name="b441494913918"></a>版本信息</strong></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p15931114016546"><a name="p15931114016546"></a><a name="p15931114016546"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/code-v3.0-LTS.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p8414649193919"><a name="p8414649193919"></a><a name="p8414649193919"></a><strong id="b341584914393"><a name="b341584914393"></a><a name="b341584914393"></a>下载站点</strong></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p3770144281415"><a name="p3770144281415"></a><a name="p3770144281415"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/code-v3.0-LTS.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p13415149133914"><a name="p13415149133914"></a><a name="p13415149133914"></a><strong id="b8415114953915"><a name="b8415114953915"></a><a name="b8415114953915"></a>SHA256校验码</strong></p>
</td> </td>
</tr> </tr>
<tr id="row14814218214"><td class="cellrowborder" valign="top" width="25%"><p id="p2481132228"><a name="p2481132228"></a><a name="p2481132228"></a>标准系统解决方案(二进制</p> <tr id="row18518114121312"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p4437184283419"><a name="p4437184283419"></a><a name="p4437184283419"></a>全量代码Beta版本(标准、轻量和小型系统</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p94811121629"><a name="p94811121629"></a><a name="p94811121629"></a>3.0</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p15437144213345"><a name="p15437144213345"></a><a name="p15437144213345"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p1358555631"><a name="p1358555631"></a><a name="p1358555631"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/standard.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p64379420343"><a name="p64379420343"></a><a name="p64379420343"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/code-v3.1-Beta.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p10581551639"><a name="p10581551639"></a><a name="p10581551639"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/standard.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p13437842103414"><a name="p13437842103414"></a><a name="p13437842103414"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/code-v3.1-Beta.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row473612318396"><td class="cellrowborder" valign="top" width="25%"><p id="p511014369394"><a name="p511014369394"></a><a name="p511014369394"></a>Hi3861解决方案(二进制)</p> <tr id="row461814235717"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p0618124216579"><a name="p0618124216579"></a><a name="p0618124216579"></a>Hi3516标准系统解决方案(二进制)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p0110036193911"><a name="p0110036193911"></a><a name="p0110036193911"></a>3.0</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p156181142145714"><a name="p156181142145714"></a><a name="p156181142145714"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p29291940175415"><a name="p29291940175415"></a><a name="p29291940175415"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_pegasus.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p16619174275717"><a name="p16619174275717"></a><a name="p16619174275717"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/standard_hi3516.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p134864584147"><a name="p134864584147"></a><a name="p134864584147"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_pegasus.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p79771324121813"><a name="p79771324121813"></a><a name="p79771324121813"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/standard_hi3516.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row873614239395"><td class="cellrowborder" valign="top" width="25%"><p id="p11110113633913"><a name="p11110113633913"></a><a name="p11110113633913"></a>Hi3518解决方案(二进制)</p> <tr id="row162201392319"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p2220191315"><a name="p2220191315"></a><a name="p2220191315"></a>RK3568标准系统解决方案(二进制)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p18110193613391"><a name="p18110193613391"></a><a name="p18110193613391"></a>3.0</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p6220191312"><a name="p6220191312"></a><a name="p6220191312"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p125681045181518"><a name="p125681045181518"></a><a name="p125681045181518"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_aries.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p522019916317"><a name="p522019916317"></a><a name="p522019916317"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/standard_rk3568.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p4607175915149"><a name="p4607175915149"></a><a name="p4607175915149"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_aries.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p18742268187"><a name="p18742268187"></a><a name="p18742268187"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/standard_rk3568.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row1273682343914"><td class="cellrowborder" valign="top" width="25%"><p id="p15110123693919"><a name="p15110123693919"></a><a name="p15110123693919"></a>Hi3516解决方案-LiteOS(二进制)</p> <tr id="row148666201519"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p18867820165113"><a name="p18867820165113"></a><a name="p18867820165113"></a>Hi3861解决方案(二进制)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p1211012362396"><a name="p1211012362396"></a><a name="p1211012362396"></a>3.0</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p108671520115118"><a name="p108671520115118"></a><a name="p108671520115118"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p10455184661518"><a name="p10455184661518"></a><a name="p10455184661518"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p19867202085113"><a name="p19867202085113"></a><a name="p19867202085113"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/hispark_pegasus.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p84951102150"><a name="p84951102150"></a><a name="p84951102150"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p193613276183"><a name="p193613276183"></a><a name="p193613276183"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/hispark_pegasus.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row18945941460"><td class="cellrowborder" valign="top" width="25%"><p id="p12945204118618"><a name="p12945204118618"></a><a name="p12945204118618"></a>Hi3516解决方案-Linux(二进制)</p> <tr id="row6114461545"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p630312351557"><a name="p630312351557"></a><a name="p630312351557"></a>Hi3516解决方案-LiteOS(二进制)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p7686415384"><a name="p7686415384"></a><a name="p7686415384"></a>3.0</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p1612646125413"><a name="p1612646125413"></a><a name="p1612646125413"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p156861155812"><a name="p156861155812"></a><a name="p156861155812"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus_linux.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p8123467546"><a name="p8123467546"></a><a name="p8123467546"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/hispark_taurus.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p16686201510815"><a name="p16686201510815"></a><a name="p16686201510815"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.0/hispark_taurus_linux.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p197721270187"><a name="p197721270187"></a><a name="p197721270187"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/hispark_taurus.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row167371123163914"><td class="cellrowborder" valign="top" width="25%"><p id="p10110143610393"><a name="p10110143610393"></a><a name="p10110143610393"></a>RELEASE-NOTES</p> <tr id="row152143765612"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p530833917567"><a name="p530833917567"></a><a name="p530833917567"></a>Hi3516解决方案-Linux(二进制)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p141101436193911"><a name="p141101436193911"></a><a name="p141101436193911"></a>3.0</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p19213372563"><a name="p19213372563"></a><a name="p19213372563"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p88931840195416"><a name="p88931840195416"></a><a name="p88931840195416"></a><a href="https://gitee.com/openharmony/docs/blob/OpenHarmony-3.0-LTS/zh-cn/release-notes/Readme.md" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1921337205612"><a name="p1921337205612"></a><a name="p1921337205612"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/hispark_taurus_linux.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p039662242117"><a name="p039662242117"></a><a name="p039662242117"></a>-</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p14441122810188"><a name="p14441122810188"></a><a name="p14441122810188"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/hispark_taurus_linux.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row573719239393"><td class="cellrowborder" valign="top" width="25%"><p id="p104146493390"><a name="p104146493390"></a><a name="p104146493390"></a><strong id="b12414104919398"><a name="b12414104919398"></a><a name="b12414104919398"></a>Master版本源码</strong></p> <tr id="row21051465512"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p11105116105112"><a name="p11105116105112"></a><a name="p11105116105112"></a>标准系统包(Mac)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p194141849163919"><a name="p194141849163919"></a><a name="p194141849163919"></a><strong id="b441494913918"><a name="b441494913918"></a><a name="b441494913918"></a>版本信息</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p4294113595317"><a name="p4294113595317"></a><a name="p4294113595317"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p8414649193919"><a name="p8414649193919"></a><a name="p8414649193919"></a><strong id="b341584914393"><a name="b341584914393"></a><a name="b341584914393"></a>下载站点</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p111053665115"><a name="p111053665115"></a><a name="p111053665115"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/ohos -sdk-mac.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p13415149133914"><a name="p13415149133914"></a><a name="p13415149133914"></a><strong id="b8415114953915"><a name="b8415114953915"></a><a name="b8415114953915"></a>SHA256校验码</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p10106662517"><a name="p10106662517"></a><a name="p10106662517"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/ohos -sdk-mac.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row18518114121312"><td class="cellrowborder" valign="top" width="25%"><p id="p4437184283419"><a name="p4437184283419"></a><a name="p4437184283419"></a>Beta版本(标准系统</p> <tr id="row7241392536"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p14957549155319"><a name="p14957549155319"></a><a name="p14957549155319"></a>标准系统包(Windows\Linux</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p15437144213345"><a name="p15437144213345"></a><a name="p15437144213345"></a>2.2 Beta2</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p52418397533"><a name="p52418397533"></a><a name="p52418397533"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p64379420343"><a name="p64379420343"></a><a name="p64379420343"></a><a href="https://repo.huaweicloud.com/harmonyos/os/2.2-Beta2/code-v2.2-beta2_20210730.tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p424539135319"><a name="p424539135319"></a><a name="p424539135319"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/ohos -sdk-tar.gz" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p13437842103414"><a name="p13437842103414"></a><a name="p13437842103414"></a><a href="https://repo.huaweicloud.com/harmonyos/os/2.2-Beta2/code-v2.2-beta2_20210730.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p3309465414"><a name="p3309465414"></a><a name="p3309465414"></a><a href="https://repo.huaweicloud.com/harmonyos/os/3.1-Beta/ohos -sdk-tar.gz .sha256" target="_blank" rel="noopener noreferrer">SHA256校验码</a></p>
</td> </td>
</tr> </tr>
<tr id="row1873817234394"><td class="cellrowborder" valign="top" width="25%"><p id="p1341618491393"><a name="p1341618491393"></a><a name="p1341618491393"></a>RELEASE-NOTES</p> <tr id="row1663285502319"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1961810962416"><a name="p1961810962416"></a><a name="p1961810962416"></a>RELEASE-NOTES</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p7416184953916"><a name="p7416184953916"></a><a name="p7416184953916"></a>2.2 Beta2</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p146331255172318"><a name="p146331255172318"></a><a name="p146331255172318"></a>3.1 Beta</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p194161849133911"><a name="p194161849133911"></a><a name="p194161849133911"></a><a href="https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-v2.2-beta2.md" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p18800131862419"><a name="p18800131862419"></a><a name="p18800131862419"></a><a href="https://gitee.com/openharmony/docs/tree/OpenHarmony-3.1-Beta/zh-cn/release-notes/OpenHarmony-v3.1-beta.md" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p1841619490395"><a name="p1841619490395"></a><a name="p1841619490395"></a>-</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p8633855132314"><a name="p8633855132314"></a><a name="p8633855132314"></a>-</p>
</td> </td>
</tr> </tr>
<tr id="row19937626418"><td class="cellrowborder" valign="top" width="25%"><p id="p1938221842"><a name="p1938221842"></a><a name="p1938221842"></a><strong id="b1393619251243"><a name="b1393619251243"></a><a name="b1393619251243"></a>编译工具链</strong></p> <tr id="row19937626418"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1938221842"><a name="p1938221842"></a><a name="p1938221842"></a><strong id="b1393619251243"><a name="b1393619251243"></a><a name="b1393619251243"></a>编译工具链</strong></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p1093810218417"><a name="p1093810218417"></a><a name="p1093810218417"></a><strong id="b1416114641015"><a name="b1416114641015"></a><a name="b1416114641015"></a>版本信息</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p1093810218417"><a name="p1093810218417"></a><a name="p1093810218417"></a><strong id="b1416114641015"><a name="b1416114641015"></a><a name="b1416114641015"></a>版本信息</strong></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p9938132648"><a name="p9938132648"></a><a name="p9938132648"></a><strong id="b14842143351015"><a name="b14842143351015"></a><a name="b14842143351015"></a>下载站点</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p9938132648"><a name="p9938132648"></a><a name="p9938132648"></a><strong id="b14842143351015"><a name="b14842143351015"></a><a name="b14842143351015"></a>下载站点</strong></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p12520113711011"><a name="p12520113711011"></a><a name="p12520113711011"></a><strong id="b17520237181015"><a name="b17520237181015"></a><a name="b17520237181015"></a>SHA256校验码</strong></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p12520113711011"><a name="p12520113711011"></a><a name="p12520113711011"></a><strong id="b17520237181015"><a name="b17520237181015"></a><a name="b17520237181015"></a>SHA256校验码</strong></p>
</td> </td>
</tr> </tr>
<tr id="row204197817410"><td class="cellrowborder" valign="top" width="25%"><p id="p8419118242"><a name="p8419118242"></a><a name="p8419118242"></a>编译工具链获取清单</p> <tr id="row204197817410"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p8419118242"><a name="p8419118242"></a><a name="p8419118242"></a>编译工具链获取清单</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p10876124517162"><a name="p10876124517162"></a><a name="p10876124517162"></a>-</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p10876124517162"><a name="p10876124517162"></a><a name="p10876124517162"></a>-</p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p1542078742"><a name="p1542078742"></a><a name="p1542078742"></a><a href="https://repo.huaweicloud.com/harmonyos/os/2.0/tool_chain/" target="_blank" rel="noopener noreferrer">站点</a></p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1542078742"><a name="p1542078742"></a><a name="p1542078742"></a><a href="https://repo.huaweicloud.com/harmonyos/os/2.0/tool_chain/" target="_blank" rel="noopener noreferrer">站点</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="25%"><p id="p134201881147"><a name="p134201881147"></a><a name="p134201881147"></a>-</p> <td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p134201881147"><a name="p134201881147"></a><a name="p134201881147"></a>-</p>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -302,7 +364,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -302,7 +364,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
## 获取方式4:从github镜像仓库获取\(每天UTC时间23点同步\)<a name="section23448418360"></a> ## 获取方式4:从github镜像仓库获取\(每天UTC时间23点同步\)<a name="section23448418360"></a>
方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[GitHub帮助中心](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account))。 方式一(推荐):通过repo + ssh下载(需注册公钥,请参考[GitHub帮助中心](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account))。
``` ```
repo init -u git@github.com:openharmony/manifest.git -b master --no-repo-verify repo init -u git@github.com:openharmony/manifest.git -b master --no-repo-verify
...@@ -310,7 +372,7 @@ repo sync -c ...@@ -310,7 +372,7 @@ repo sync -c
repo forall -c 'git lfs pull' repo forall -c 'git lfs pull'
``` ```
方式二:通过repo + https 下载。 方式二:通过repo + https下载。
``` ```
repo init -u https://github.com/openharmony/manifest.git -b master --no-repo-verify repo init -u https://github.com/openharmony/manifest.git -b master --no-repo-verify
...@@ -318,9 +380,9 @@ repo sync -c ...@@ -318,9 +380,9 @@ repo sync -c
repo forall -c 'git lfs pull' repo forall -c 'git lfs pull'
``` ```
## 源码目录<a name="section1072115612811"></a> ## 源码目录简介<a name="section1072115612811"></a>
下表是OpenHarmony源码的目录及简单说明 下表是OpenHarmony源码目录
**表 2** 源码目录 **表 2** 源码目录
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
本示例将运行源码中的camera示例代码,通过本示例可以实现使用开发板进行拍照、录像及预览等功能。 本示例将运行源码中的camera示例代码,通过本示例可以实现使用开发板进行拍照、录像及预览等功能。
- 本示例源码路径为“applications/sample/camera/media/camera\_sample.cpp”。 - 本示例源码路径为“applications/sample/camera/media/camera\_sample.cpp”。
- 在运行本示例前需先完成编译烧录、运行镜像等步骤,相关操作请参考[Hi3516快速入门](../quick-start/oem_minitinier_des_3516.md#section26131214194212) - 在运行本示例前需先完成编译烧录、运行镜像等步骤,相关操作请参考[Hi3516快速入门](../quick-start/quickstart-lite-overview.md)
>![](../public_sys-resources/icon-note.gif) **说明:** >![](../public_sys-resources/icon-note.gif) **说明:**
>开发板启动后默认会加载launcher应用,应用的图形界面默认显示在媒体图层上方,会影响camera\_sample的演示结果,因此需要在编译或是打包时去掉launcher应用。 >开发板启动后默认会加载launcher应用,应用的图形界面默认显示在媒体图层上方,会影响camera\_sample的演示结果,因此需要在编译或是打包时去掉launcher应用。
......
# 真机运行<a name="ZH-CN_TOPIC_0000001054809161"></a> # 真机运行<a name="ZH-CN_TOPIC_0000001054809161"></a>
应用编译打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[Hi3516快速入门](../quick-start/oem_minitinier_des_3516.md#section26131214194212)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载三方应用。 应用编译打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[Hi3516快速入门](../quick-start/quickstart-lite-overview.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载三方应用。
1. 将IDE编译的未签名应用安装包和安装工具(镜像文件生成目录中的dev\_tools)放在sdcard中,将sdcard插入开发板卡槽。 1. 将IDE编译的未签名应用安装包和安装工具(镜像文件生成目录中的dev\_tools)放在sdcard中,将sdcard插入开发板卡槽。
2. 应用安装默认要校验签名,需要执行以下命令,关闭签名校验。 2. 应用安装默认要校验签名,需要执行以下命令,关闭签名校验。
......
# 应用实例<a name="ZH-CN_TOPIC_0000001055686082"></a> # 应用实例<a name="ZH-CN_TOPIC_0000001055686082"></a>
- 开发板介绍、编译烧录、运行镜像等操作请参考[Hi3518快速入门](../quick-start/oem_minitinier_des_3518.md#section14815247616),编译结果包含示例,结果文件为out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample,可将文件通过读卡器复制至TF卡中,或者修改camera\_sample的编译脚本将结果文件复制至rootfs.img中。 - 开发板介绍、编译烧录、运行镜像等操作请参考[Hi3518快速入门](../quick-start/quickstart-lite-overview.md),编译结果包含示例,结果文件为out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample,可将文件通过读卡器复制至TF卡中,或者修改camera\_sample的编译脚本将结果文件复制至rootfs.img中。
修改applications/sample/camera/media/BUILD.gn中的output\_dir。 修改applications/sample/camera/media/BUILD.gn中的output\_dir。
......
...@@ -335,25 +335,25 @@ Input模型由三层驱动组成,开发者适配一款全新触摸屏驱动只 ...@@ -335,25 +335,25 @@ Input模型由三层驱动组成,开发者适配一款全新触摸屏驱动只
其中touch\_gt911.o为本示例中追加的内容。 其中touch\_gt911.o为本示例中追加的内容。
2. 具体编译及烧录操作请参考[标准系统快速入门编译及烧录章节](../quick-start/quickstart-standard-burn.md) 2. 具体编译及烧录操作请参考[标准系统快速入门编译及烧录章节](../quick-start/quickstart-standard-overview.md)
## 调试验证<a name="section62577313482"></a> ## 调试验证<a name="section62577313482"></a>
如下所示为开机启动日志部分截取 如下所示为开机启动日志部分截取
``` ```
[I/HDF_INPUT_DRV] HdfInputManagerInit: enter // 管理驱动层初始化 [I/HDF_INPUT_DRV] HdfInputManagerInit: enter // 管理驱动层初始化
[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // 初始化成功 [I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // 初始化成功
[I/osal_cdev] add cdev hdf_input_host success [I/osal_cdev] add cdev hdf_input_host success
[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // 公共驱动层初始化 [I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // 公共驱动层初始化
[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // 初始化成功 [I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // 初始化成功
[I/osal_cdev] add cdev hdf_input_event1 success [I/osal_cdev] add cdev hdf_input_event1 success
[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // 器件驱动层初始化 [I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // 器件驱动层初始化
[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060 [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_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] ChipDriverInit: chipDetect succ, ret = 0
[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch [I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch
[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // 初始化成功 [I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // 初始化成功
``` ```
## Input模型工作流程解析<a name="section1578569154917"></a> ## Input模型工作流程解析<a name="section1578569154917"></a>
......
...@@ -10,7 +10,7 @@ OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力, ...@@ -10,7 +10,7 @@ OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力,
## 开发<a name="section13857170163412"></a> ## 开发<a name="section13857170163412"></a>
1. 请先完成[《Hi3861快速入门》](../quick-start/oem_minitinier_des_3861.md#section19352114194115) 1. 请先完成[《Hi3861快速入门》](../quick-start/quickstart-lite-overview.md)
LED控制参考示例存放于applications/sample/wifi-iot/app/iothardware/led\_example.c文件中。 LED控制参考示例存放于applications/sample/wifi-iot/app/iothardware/led\_example.c文件中。
...@@ -101,7 +101,7 @@ OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力, ...@@ -101,7 +101,7 @@ OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力,
## 验证<a name="section1949121910344"></a> ## 验证<a name="section1949121910344"></a>
编译过程请参考《[Hi3861快速入门-源码编译](../quick-start/quickstart-lite-steps-hi3861-connection.md#section191121332125319)》,烧录过程请参考《[Hi3861快速入门-镜像烧录](../quick-start/quickstart-lite-steps-hi3861-connection.md#section3288165814218)》。 编译过程请参考《[Hi3861快速入门-源码编译](../quick-start/quickstart-lite-steps-hi3861-building.md)》,烧录过程请参考《[Hi3861快速入门-镜像烧录](../quick-start/quickstart-lite-steps-hi3861-burn.md)》。
完成以上两步后,按下RST键复位模组,可发现LED在周期性闪烁,与预期相符,验证完毕。 完成以上两步后,按下RST键复位模组,可发现LED在周期性闪烁,与预期相符,验证完毕。
......
...@@ -57,7 +57,7 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) ...@@ -57,7 +57,7 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args)
clang --target=arm-liteos --sysroot=prebuilts/lite/sysroot -o helloworld helloworld.c clang --target=arm-liteos --sysroot=prebuilts/lite/sysroot -o helloworld helloworld.c
``` ```
**clang**:参考[LLVM安装指导](../quick-start/quickstart-lite-env-setup-linux.md)安装LLVM编译器。 **clang**:参考[LLVM安装指导](../quick-start/quickstart-lite-package-environment.md)安装LLVM编译器。
**--target**:--target=arm-liteos,指定编译平台为arm-liteos。 **--target**:--target=arm-liteos,指定编译平台为arm-liteos。
......
# 开发板移植 ## 概述
目前OpenHarmony已经成立了SIG组[sig-devboard](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md)。该SIG组以支持更多第三方开发板为目标,提供开发板移植的支撑。 目前OpenHarmony已经成立了SIG组[sig-devboard](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md)。该SIG组以支持更多第三方开发板为目标,提供开发板移植的支撑。
在了解开发板移植前,需要先了解一下OpenHarmony对设备的分类。不同设备类型的移植方法会有较大差异。 在了解开发板移植前,需要先了解一下OpenHarmony对设备的分类。不同设备类型的移植方法会有较大差异。
...@@ -19,7 +19,7 @@ repo init -u https://gitee.com/openharmony-sig/manifest.git -b master -m devboar ...@@ -19,7 +19,7 @@ repo init -u https://gitee.com/openharmony-sig/manifest.git -b master -m devboar
其他下载步骤与主线相同。 其他下载步骤与主线相同。
## 开始移植你的开发板 ## 芯片移植指导
- [轻量系统芯片移植指导](porting-minichip.md) - [轻量系统芯片移植指导](porting-minichip.md)
- [移植准备](porting-chip-prepare.md) - [移植准备](porting-chip-prepare.md)
...@@ -49,11 +49,16 @@ repo init -u https://gitee.com/openharmony-sig/manifest.git -b master -m devboar ...@@ -49,11 +49,16 @@ repo init -u https://gitee.com/openharmony-sig/manifest.git -b master -m devboar
- [移植概述](porting-smallchip-driver-overview.md) - [移植概述](porting-smallchip-driver-overview.md)
- [平台驱动移植](porting-smallchip-driver-plat.md) - [平台驱动移植](porting-smallchip-driver-plat.md)
- [器件驱动移植](porting-smallchip-driver-oom.md) - [器件驱动移植](porting-smallchip-driver-oom.md)
- [标准系统移植指南](standard-system-porting-guide.md) - [标准系统芯片移植指导](standard-system-porting-guide.md)
- [一种快速移植OpenHarmony Linux内核的方法](porting-linux-kernel.md) - [标准系统移植指南](standard-system-porting-guide.md)
- [一种快速移植OpenHarmony Linux内核的方法](porting-linux-kernel.md)
- [轻量和小型系统三方库移植指导]( porting-thirdparty.md)
- [概述](porting-thirdparty-overview.md)
- [CMake方式组织编译的库移植](porting-thirdparty-cmake.md)
- [Makefile方式组织编译的库移植](porting-thirdparty-makefile.md)
# 三方库移植 ## 芯片移植案例
- [轻量系统芯片移植案例](porting-minichip-cases.md)
- [带屏解决方案之恒玄芯片移植案例](porting-bes2600w-on-minisystem-display-demo.md)
- [概述](porting-thirdparty-overview.md)
- [CMake方式组织编译的库移植](porting-thirdparty-cmake.md)
- [Makefile方式组织编译的库移植](porting-thirdparty-makefile.md)
\ No newline at end of file
# 轻量带屏解决方案之恒玄芯片移植案例
本文章基于恒玄科技`BES2600W`芯片的欧智通[Multi-modal V200Z-R开发板](https://gitee.com/openharmony/device_board_fnlink),进行轻量带屏开发板的标准移植,开发了智能开关面板样例,同时实现了`ace_engine_lite``graphic_ui``aafwk_lite``appexecfwk_lite``HDF`等部件基于`OpenHarmony LiteOS-M`内核的适配。移植架构上采用`Board``SoC`分离的方案,工具链`Newlib C`库与`Musl C`库可选,`LiteOS-M`内核编译采用`gn`结合`Kconfig`图形化配置等需求。
## 编译构建
### 目录规划
本案例在芯片移植架构方面进行了一些改进,以前的芯片适配目录规划为:
```
device
└── <device_company>
   └── <device_name>
```
这样会导致,小熊派`BearPi-HM Nano`开发板与润和的`HiSpark Pegasus`开发板使用小海思的`hi3861``SoC`时,需要在这两款开发板里面都放置一份重复的代码。为了解决该问题,本案例将单板厂商与`SoC`厂商进行分离,可以参考[Board和SoC解耦的设计思路](https://gitee.com/openharmony-sig/sig-content/blob/master/devboard/docs/board-soc-arch-design.md),并把芯片适配目录规划为:
```
device
├── board --- 单板厂商目录
│   └── fnlink --- 单板厂商名字:欧智通
│   └── v200zr --- 单板名:v200zr
└── soc --- SoC厂商目录
└── bestechnic --- SoC厂商名字:恒玄
└── bes2600 --- SoC Series名:bes2600是一个系列,里面包含bes2600w等SoC名
```
产品样例目录规划为:
```
vendor
└── bestechnic --- 开发产品样例厂商目录,恒玄开发的带屏样例,因此以bestechnic命名
└── display_demo --- 产品名字:以智能开关面板的带屏显示样例
```
### 预编译适配
在进行移植之前,需要进行预编译适配。
预编译适配主要使用`hb set`命令,设置整个项目的根目录、单板目录、产品目录、单板公司名等环境变量,为编译做准备。
具体的预编译适配步骤如下:
1.`vendor/bestechnic/display_demo`目录下新增`config.json`文件,用于描述这个产品样例所使用的单板、内核等信息,描述信息可参考如下内容:
```
{
"product_name": "display_demo", --- 用于hb set进行选择时,显示的产品名称
"type": "mini", --- 构建系统的类型,mini/small/standard
"version": "3.0", --- 构建系统的版本,1.0/2.0/3.0
"device_company": "fnlink", --- 单板厂商名,用于编译时找到/device/board/fnlink目录
"board": "v200zr", --- 单板名,用于编译时找到/device/board/fnlink/v200zr目录
"kernel_type": "liteos_m", --- 内核类型,因为OpenHarmony支持多内核,一块单板可能适配了多个内核,所以需要指定某个内核进行编译
"kernel_version": "3.0.0", --- 内核版本,一块单板可能适配了多个linux内核版本,所以需要指定某个具体的内核版本进行编译
"subsystems": [ ] --- 选择所需要编译构建的子系统
}
```
2.`vendor/bestechnic/display_demo`目录下新增`config.json`文件,用于描述这个产品样例所使用的单板、内核等信息,描述信息可参考如下内容:
```
# Kernel type, e.g. "linux", "liteos_a", "liteos_m".
kernel_type = "liteos_m" --- 内核类型,跟config.json中kernel_type对应
# Kernel version.
kernel_version = "3.0.0" --- 内核版本,跟config.json中kernel_version对应
```
3. 验证`hb set`配置是否正确,输入`hb set`能够显示如下图片表示配置正确。
详细地,执行`hb set`输入项目根目录,并且回车,遍历所有`//vendor/<product_company>/<product_name>`目录下的`config.json`,给出可选产品编译选项,`config.json``product_name`用于显示产品名,`device_company``board`用于关联出`//device/board/<device_company>/<board>`目录,并且匹配`<any_dir_name>/config.gni`文件,如果能够匹配多个文件,表示该单板适配了多个内核,那么可以根据`config.json``kernel_type``kernel_version`来唯一匹配`config.gni``kernel_type``kernel_version`,这样就可以确定了需要编译适配了哪个内核的单板。
![hb set](figure/bes2600_hb_set.png)
​ 通过`hb env`可以查看选择出来的预编译环境变量。
![hb env](figure/bes2600_hb_env.png)
在执行`hb build`之前,需要准备好`LiteOS-M`内核适配,具体适配步骤请参考[内核移植](内核移植)
## 内核移植
内核移植需要完成`LiteOS-M Kconfig`适配、`gn`的编译构建和内核启动最小适配。
### LiteOS-M Kconfig适配
`//kernel/liteos_m`目录下执行`make menuconfig`命令,完成编译配置选项的选择。在`Makefile`文件中,会将`hb env`的结果转换成环境变量,即`PRODUCT_PATH``DEVICE_PATH``BOARD_COMPANY`。如下代码块所示:
```
$(foreach line,$(shell hb env | sed 's/\[OHOS INFO\]/ohos/g;s/ /_/g;s/:_/=/g' || true),$(eval $(line)))
ifneq ($(ohos_kernel),liteos_m)
$(error The selected product ($(ohos_product)) is not a liteos_m kernel type product)
endif
--- 将hb env的每一行输出转化为变量形式,例如将[OHOS INFO] device company: fnlink转换为ohos_device_company=fnlink
……
ifeq ($(BOARD_COMPANY),)
BOARD_COMPANY:=$(ohos_device_company)
endif
……
export BOARD_COMPANY
--- 将ohos_device_company转化为BOARD_COMPANY环境变量
```
`//kernel/liteos_m/Kconfig`文件中使用这些导出的环境变量,`Kconfiglib`采用`ulfalizer`开发基于`python`的版本,[源码地址](https://github.com/ulfalizer/Kconfiglib)[功能介绍连接参考](https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/kconfig/kconfiglib.py),里面用到了`orsource`关键字,其中`o`表示`optional`,表示这个文件是否存在可选,`r`表示`relative`,表示这个文件相对当前文件的相对路径。
```
config SOC_COMPANY
string "SoC company name to locate soc build path"
help
This option specifies the SoC company name, used to locate the build path for soc. This option is set by the
SoC's Kconfig file, and should be exactly the same with SoC company path, and the user should generally avoid
modifying it via the menu configuration.
orsource "../../device/board/*/Kconfig.liteos_m.shields" --- 将所有扩展板配置信息加载进来,因为单板厂商A提供扩展板可以给单板厂商B使用,所以这里使用*匹配所有的扩展板,而非BOARD_COMPANY。另外由于OpenHarmony支持多内核设计,Kconfig文件采用liteos_m作为后缀,在进行单板适配过程中,其他内核在适配过程中,可以使用对应的内核名作为后缀名进行扩展。
orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.defconfig.boards" --- 加载BOARD_COMPANY的所有单板预定义配置
choice
prompt "Board Selection"
orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.boards" --- 提供Board选择列表
endchoice
orsource "../../device/soc/*/Kconfig.liteos_m.defconfig" --- 加载所有SoC的默认配置定义
choice
prompt "SoC Series Selection"
orsource "../../device/soc/*/Kconfig.liteos_m.series" --- 提供所有SoC Series选择列表
endchoice
orsource "../../device/soc/*/Kconfig.liteos_m.soc" --- 加载所有SoC配置
```
`//kernel/liteos_m/Kconfig`文件可以看出需要在`//device/board/fnlink`目录下新增如下`Kconfig`文件进行适配:
```
.
├── v200zr --- v200zr单板配置目录
│   ├── Kconfig.liteos_m.board --- 提供v200zr单板的配置选项
│   ├── Kconfig.liteos_m.defconfig.board --- 提供v200zr单板的默认配置项
│   └── liteos_m
│   └── config.gni
├── Kconfig.liteos_m.boards --- 提供fnlink单板厂商下Boards配置信息
├── Kconfig.liteos_m.defconfig.boards --- 提供fnlink单板厂商下Boards默认配置信息
├── Kconfig.liteos_m.shields --- 提供fnlink单板厂商下扩展板配置信息
└── shields --- fnlink单板厂商的扩展板目录
├── v200zr-t0 --- fnlink单板厂商的扩展板v200zr-t0
│   ├── Kconfig.liteos_m.defconfig.shield --- 扩展板v200zr-t0默认配置
│   └── Kconfig.liteos_m.shield --- 扩展板v200zr-t0配置信息
├── v200zr-t1
│   ├── Kconfig.liteos_m.defconfig.shield
│   └── Kconfig.liteos_m.shield
└── Kconfig.liteos_m.shields
```
`v200zr/Kconfig.liteos_m.board`需要配置选择该单板的选项,以及它依赖的`SoC`,如下:
```
config BOARD_v200zr
bool "select board v200zr"
depends on SOC_BES2600W --- v200zr单板用的bes2600w的SoC,只有 bes2600w的SoC被选择后,v200zr单板配置选项才可见,可以被选择。
```
`v200zr/Kconfig.liteos_m.defconfig.board`需要配置选择该单板后,默认定义 `BOARD` 的名字为 `"v200zr"` ,如下:
```
if BOARD_v200zr
config BOARD
string --- string后没有带提示,因此用户不可见
default "v200zr"
endif # BOARD_v200zr
```
`//kernel/liteos_m/Kconfig`文件可以看出需要在`//device/soc/bestechnic`目录下新增如下`Kconfig`文件进行适配:
```
.
├── bes2600 --- bes2600 SoC系列
│   ├── Kconfig.liteos_m.defconfig.bes2600w --- bestechnic芯片厂商bes2600w SoC Series配置
│   ├── Kconfig.liteos_m.defconfig.series --- bestechnic芯片厂商bes2600默认配置
│   ├── Kconfig.liteos_m.series --- bestechnic芯片厂商bes2600 SoC Series配置
│   └── Kconfig.liteos_m.soc --- bestechnic芯片厂商bes2600 SoC配置
├── Kconfig.liteos_m.defconfig --- bestechnic芯片厂商SoC默认配置
├── Kconfig.liteos_m.series --- bestechnic芯片厂商SoC Series配置
└── Kconfig.liteos_m.soc --- bestechnic芯片厂商 SoC配置
```
`bes2600/Kconfig.liteos_m.series` 需要配置`bes2600 SoC series`,以及它的芯片架构等信息,如下:
```
config SOC_SERIES_BES2600 --- 提供bes2600 SoC Series选项
bool "Bestechnic 2600 Series"
select ARM --- 选择bes2600后,默认选择ARM架构
select SOC_COMPANY_BESTECHNIC --- 选择bes2600后,默认选择bestechnic芯片公司,驱动会依赖这个宏配置,选择配置编译对应厂商的驱动
select CPU_CORTEX_M33 --- 选择bes2600后,默认选择cortex-m33 CPU
help
Enable support for Bestechnic 2600 series
```
`bes2600/Kconfig.liteos_m.soc` 需要提供`bes2600 SoC series`下有多少个具体的`SoC`可供选择,如下:
```
choice
prompt "Bestechnic 2600 series SoC"
depends on SOC_SERIES_BES2600 --- 只有选择了bes2600 Series后,才会出现如下配置选项
config SOC_BES2600W --- 增加bes2600w SoC配置选择项
bool "SoC BES2600w"
endchoice
```
`bes2600/Kconfig.liteos_m.defconfig.series` 需要提供`bes2600 SoC series`选择后的默认配置,如下:
```
if SOC_SERIES_BES2600 --- 选择了bes2600 Series后,才会增加如下默认配置选项
rsource "Kconfig.liteos_m.defconfig.bes2600w" --- 增加bes2600w SoC的默认配置
config SOC_SERIES --- 增加SOC_SERIES的默认配置
string
default "bes2600"
endif
```
配置完成后,还需要根据 `kernel/liteos_m/Makefile` 文件配置`make menuconfig``defconfig`保存路径:
```
ifeq ($(TEE:1=y),y)
tee = _tee
endif
ifeq ($(RELEASE:1=y),y)
CONFIG ?= $(PRODUCT_PATH)/kernel_configs/release$(tee).config
else
CONFIG ?= $(PRODUCT_PATH)/kernel_configs/debug$(tee).config --- 配置文件保存在$(CONFIG)中,由产品最终定义
endif
……
update_config menuconfig:
$(HIDE)test -f "$(CONFIG)" && cp -v "$(CONFIG)" .config && menuconfig $(args) && savedefconfig --out "$(CONFIG)"
```
在这个例子中,`defconfig`配置路径为 `$(PRODUCT_PATH)/kernel_configs/debug.config`,创建该文件后,内容为空,产品的目录文件结构如下:
```
.
└── display_demo
├── config.json
└── kernel_configs
└── debug.config
```
配置完成后,在 `kernel/liteos_m` 目录下执行 `make menuconfig`能够对`SoC Series`/`SoC`/`Board`进行选择,如下:
![board make menuconfig](figure/bes2600_board_make_menuconfig.png)
结果将自动保存在`$(PRODUCT_PATH)/kernel_configs/debug.config`,下次执行`make menuconfig`时会导出保存的结果。
### gn编译适配
在上一步`Kconfig`的图形化配置后,将其生成的配置结果可以作为`gn`编译的输入,以控制不同模块是否编译。另外为了解决之前`gn`编写时,随意include的问题,内核编译做了模块化编译的设计,使得整个编译逻辑更加清晰,设计思路请参考[LiteOS-M内核BUILD.gn编写指南](https://gitee.com/caoruihong/kernel_liteos_m/wikis/LiteOS-M%E5%86%85%E6%A0%B8BUILD.gn%E7%BC%96%E5%86%99%E6%8C%87%E5%8D%97)
`kernel/liteos_m/BUILD.gn` 中,指定了`Board``SoC`的编译入口为`//device/board/fnlink``//device/soc/bestechnic`
```
deps += [ "//device/board/$device_company" ]
deps += [ "//device/soc/$LOSCFG_SOC_COMPANY" ]
```
`//device/board/fnlink/BUILD.gn`中,新增内容如下:
```
if (ohos_kernel_type == "liteos_m") { --- 由于多内核设计,对于LiteOS-M内核适配,需要用宏来隔离
import("//kernel/liteos_m/liteos.gni") --- 引入内核gn编写模板
module_name = get_path_info(rebase_path("."), "name") --- 动态获取当前文件目录作为模块名,防止目录名修改后,这里还需要跟着修改
module_group(module_name) { --- 采用module_group模板
modules = [ --- 添加需要编译的模块
]
}
}
```
同理`//device/soc/bestechnic/BUILD.gn`也是一样。
### 内核启动适配
内核启动适配的文件路径在 `//device/soc/bestechnic/bes2600/liteos_m/sdk/bsp/rtos/liteos/liteos_m/board.c`
内核启动适配总体思路如下:
1. 中断向量的初始化`os_vector_init` ,初始化中断的处理函数。
2. 内核初始化`osKernelInitialize`
3. 创建线程`board_main`,进行芯片平台初始化。
4. 内核启动,开始调度线程`osKernelStart`
其中,本章节详细对第3步进行展开,其他几步为对内核函数调用,不作详细描述。
第3步中`board_main`在启动`OHOS_SystemInit`之前,需要初始化必要的动作,如下:
```
...
if(!ret) {
...
OhosSystemAdapterHooks(); --- 系统启动时候设置钩子,启动OpenHarmonyOHOS_SystemInit的之前完成打印和驱动的初始化
...
OHOS_SystemInit(); --- 启动OpenHarmony服务,以及组件初始化
}
....
```
`OhosSystemAdapterHooks`函数在`device/soc/bestechnic/bes2600/liteos_m/components/utils/src/hm_sys.c`文件中,如下:
```
int OhosSystemAdapterHooks(void)
{
init_trace_system(); --- 初始化打印函数
DeviceManagerStart(); --- 调用DeviceManagerStart函数进行HDF驱动初始化,这个过程会调用单板代码中的驱动配置文件hdf.hcs以及drivers源码实现
return 0;
}
```
### littlefs文件系统移植
文件系统使用的是`littlefs`,适配过程中,需要在指定路径下放置文件系统预置文件,根据配置可自动生成文件系统镜像,可以实现自动化生成和打包到烧录包中。
1. 配置指定目录放置打包文件系统`config.json`,通过`flash_partition_dir`指定目录:
```
"flash_partition_dir": "fs" --- 表示在vendor/bestechnic/display_demo/fs目录下放置文件系统预置文件
```
2. 在指定目录`vendor/bestechnic/display_demo/fs`下放置两部分内容:
- `wifi_Download_cfg.yaml`:镜像的烧录配置文件,可以根据实际情况调整分区。
- `/data/data`:第一个/`data`是挂载的根目录;第二个`data`是根目录里面的`data`目录,里面可以存放预置文件,或者在第二个`data`的同级目录再创建一个目录,打包的时候只认第一个`data`挂载根目录。
3. `config.json`中根据`wifi_Download_cfg.yaml`最后调整结果。
- `fs_src`配置文件系统挂载名字。
- `fs_name`是最后生成文件系统的名字。
- `block_size`配置成`4K`对齐,建议不修改。
- `fs_size`是生成文件系统的大小。
- `burn_name`是烧录`bin`名字的大小。
- `enable` 表示是否生成这个文件系统
4.`//device/soc/bestechnic/bes2600/liteos_m/components/hdf_config/hdf.hcs`文件配置文件系统的烧录的起始地址、文件系统的大小以及读数据块的大小`block_size`等信息,参考配置如下:
```
misc {
fs_config {
littlefs_config {
match_attr = "littlefs_config";
mount_points = ["/data"];
partitions = [10];
block_size = [4096];
block_count = [1024];
}
}
storage_config {
flash_config {
match_attr = "flash_config";
partitions = [10];
owner = [0];
description = ["littlefs"];
start_addr = [0xB60000];
length = [0x400000];
options = [3];
}
}
}
```
最后在`device/soc/bestechnic/bes2600/liteos_m/components/fs/fs_init.c`中,通过`hdf`加载数据,进行读写`flash`,如下:
```
static int32_t FsDriverInit(struct HdfDeviceObject *object)
{
if (object == NULL) {
return HDF_FAILURE;
}
if (object->property) {
if (FsGetResource(fs, object->property) != HDF_SUCCESS) {
HDF_LOGE("%s: FsGetResource failed", __func__);
return HDF_FAILURE;
}
}
for (int i = 0; i < sizeof(fs) / sizeof(fs[0]); i++) {
if (fs[i].mount_point == NULL)
continue;
fs[i].lfs_cfg.read = littlefs_block_read;
fs[i].lfs_cfg.prog = littlefs_block_write;
fs[i].lfs_cfg.erase = littlefs_block_erase;
fs[i].lfs_cfg.sync = littlefs_block_sync;
fs[i].lfs_cfg.read_size = 256;
fs[i].lfs_cfg.prog_size = 256;
fs[i].lfs_cfg.cache_size = 256;
fs[i].lfs_cfg.lookahead_size = 16;
fs[i].lfs_cfg.block_cycles = 1000;
SetDefaultMountPath(i, fs[i].mount_point);
int ret = mount(NULL, fs[i].mount_point, "littlefs", 0, &fs[i].lfs_cfg);
HDF_LOGI("%s: mount fs on '%s' %s\n", __func__, fs[i].mount_point, (ret == 0) ? "succeed" : "failed");
}
return HDF_SUCCESS;
}
```
### C库适配
在轻量系统中,C库适配比较复杂,设计思路请参考[LiteOS-M内核支持musl与newlib平滑切换方案](https://gitee.com/arvinzzz/ohos_kernel_design_specification/blob/master/liteos_m/%E6%94%AF%E6%8C%81newlib/%E5%86%85%E6%A0%B8%E9%80%82%E9%85%8Dnewlib%E6%96%B9%E6%A1%88%E6%80%9D%E8%B7%AF.md),由于我们的工具链采用 [gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2](https://gitee.com/link?target=https%3A%2F%2Fdeveloper.arm.com%2F-%2Fmedia%2FFiles%2Fdownloads%2Fgnu-rm%2F10.3-2021.10%2Fgcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2) 自带`newlib`的C库,那么系统移植整体采用`newlib`的C库。那么在内核的`make menuconfig`中选择`newlib`,如下图:
![image-20211212191013553](figure/bes2600_newlib_make_menuconfig.png)
#### malloc适配
malloc适配参考[The Red Hat newlib C Library-malloc](https://sourceware.org/newlib/libc.html#malloc)。实现malloc适配有以下两种方法:
- 实现 `_sbrk_r` 函数。这种方法中,内存分配函数使用`newlib`中的。
- 实现 `_malloc_r`, `_realloc_r`, `_reallocf_r`, `_free_r`, `_memalign_r`, 和 `_malloc_usable_size_r`。这种方法中,内存分配函数可以使用内核的。
为了方便地根据业务进行内存分配算法调优和问题定位,在这两种方法中,本案例选择后者。
首先,由于`newlib`中已经存在这些函数的符号,因此需要用到`gcc``wrap`的链接选项替换这些函数符号为内核的实现,内核的实现为 `//kernel/liteos_m/kal/libc/newlib/porting/src/malloc.c`
然后,在`//device/board/fnlink/v200zr/liteos_m/config.gni`的新增这些函数的`wrap`链接选项。
```
board_ld_flags += [
"-Wl,--wrap=_malloc_r",
"-Wl,--wrap=_realloc_r",
"-Wl,--wrap=_reallocf_r",
"-Wl,--wrap=_free_r",
"-Wl,--wrap=_memalign_r",
"-Wl,--wrap=_malloc_usable_size_r",
]
```
#### vsprintf等适配
参考 https://sourceware.org/newlib/libc.html#vfprintf ,实现 `vprintf`, `vfprintf`, `printf`, `snprintf``sprintf`
类似`malloc`适配,首先要提供这些函数的实现,`//device/soc/bestechnic/bes2600/liteos_m/components/utils/src/printf.c`,本案例直接采用开源协议友好的实现。与`malloc`适配不同的是,这个函数由芯片原厂提供。因为就打印来说,根据项目的需要,实现可大可小,内核不方便提供统一的实现。
然后,在`//device/board/fnlink/v200zr/liteos_m/config.gni`的新增这些函数的wrap链接选项。
```
board_ld_flags += [
"-Wl,--wrap=printf",
"-Wl,--wrap=sprintf",
"-Wl,--wrap=snprintf",
"-Wl,--wrap=vsnprintf",
"-Wl,--wrap=vprintf",
]
```
#### open等适配
这部分实现由内核统一实现,芯片适配无须关注,内核文件`//kernel/liteos_m/kal/libc/newlib/porting/src/fs.c`,适配了`newlib``_read``_write`等函数,如下:
```
……
ssize_t _read(int fd, void *buf, size_t nbyte)
{
return LOS_Read(fd, buf, nbyte);
}
ssize_t _write(int fd, const void *buf, size_t nbyte)
{
return LOS_Write(fd, buf, nbyte);
}
off_t _lseek(int fd, off_t offset, int whence)
{
return LOS_Lseek(fd, offset, whence);
}
……
```
## 板级系统移植
### 驱动移植
#### SoC芯片平台HDF驱动移植
驱动适配相关文件放置在`drivers/adapter/platform`中,对应有`gpio``i2c``pwm``spi``uart``watchdog`,都是通过`HDF`机制加载,本章节以`gpio`为例进行详细说明。
##### GPIO驱动适配
`gpio`驱动适配需要完成编译的适配、源码的适配。
`//drivers/adapter/platform/gpio/BUILD.gn`文件中,描述了恒玄`gpio`驱动的编译适配。如下:
```
module_switch = defined(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO) --- 如果打开HDF的GPIO配置开关,才进行如下编译
module_name = get_path_info(rebase_path("."), "name")
hdf_driver(module_name) {
sources = []
if (defined(LOSCFG_SOC_COMPANY_BESTECHNIC)) { --- 如果打开恒玄的芯片配置开关,才进行恒玄GPIO的驱动编译
sources += [ "gpio_bes.c" ]
}
include_dirs = [ "." ]
}
```
`//drivers/adapter/platform/gpio/gpio_bes.c`文件中,描述了恒玄`gpio`驱动的源码适配。
首先,按照`OpenHarmony``HDF`驱动框架加载驱动基本适配框架,如下:
```
struct HdfDriverEntry g_GpioDriverEntry = {
.moduleVersion = 1,
.moduleName = "BES_GPIO_MODULE_HDF",
.Bind = GpioDriverBind,
.Init = GpioDriverInit,
.Release = GpioDriverRelease,
};
HDF_INIT(g_GpioDriverEntry); --- 通过HDF_INIT 加载GPIO驱动
```
然后,在初始化的时候会获取`hcs`参数进行初始化,如下:
```
static int32_t GpioDriverInit(struct HdfDeviceObject *device)
{
int32_t ret;
struct GpioCntlr *gpioCntlr = NULL;
if (device == NULL) {
HDF_LOGE("%s: device is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
gpioCntlr = GpioCntlrFromDevice(device); --- gpioCntlr节点变量就可以获取具体gpio配置
if (gpioCntlr == NULL) {
...
```
编码规范和设计思想见[bes 驱动适配PR](https://gitee.com/openharmony/drivers_adapter/pulls/278)的评论。
#### Board外设器件HDF驱动移植
`Board`外设器件表示通过`SoC`平台总线连接的外设器件,在本案例中,显示屏属于外设器件,其驱动适配放在`//device/board/fnlink/drivers/liteos_m`目录中。
##### 显示驱动适配
`SoC`驱动适配,在`//device/board/fnlink/drivers/liteos_m/display/BUILD.gn`文件中,根据`hdf_driver`模板加载驱动模块,如下:
```
module_name = get_path_info(rebase_path("."), "name")
hdf_driver(module_name) {
sources = [
"zzw395.c",
]
include_dirs = [
"//drivers/peripheral/display/interfaces/include",
...
]
}
```
`//device/board/fnlink/drivers/liteos_m/display/zzw395.c`文件中,根据驱动框架加载显示驱动,如下:
```
static struct HdfDriverEntry g_ZZW395DriverEntry = {
.moduleVersion = 1,
.moduleName = "HDF_PANEL_ZZW395",
.Bind = PanelDriverBind,
.Init = PanelDriverInit,
.Release = PanelDriverRelease,
};
HDF_INIT(g_ZZW395DriverEntry);
```
其中的驱动参数根据`hcs`配置,在`PanelDriverInit`初始化时加载,如下:
```
static int32_t PanelDriverInit(struct HdfDeviceObject *object)
{
if (object == NULL) {
return HDF_FAILURE;
}
HDF_LOGD("%s entry !!!", __func__);
if (object->property) {
if (PanelGetResource(&priv, object->property) != HDF_SUCCESS) {
HDF_LOGE("%s: PanelGetResource failed", __func__);
return HDF_FAILURE;
}
}
...
```
### OpenHarmony子系统适配
`OpenHarmony`子系统适配一般包含两部分:
-`config.json`中增加对应子系统和部件,这样编译系统会将该部件纳入编译目标中。
- 针对该部件的`HAL`层接口进行硬件适配,或者可选的软件功能适配。
#### communication子系统适配
##### wifi_lite部件适配
首先,在`config.json`文件中,增加`communication`子系统的`wifi_lite`部件,如下:
```
{
"subsystem": "communication",
"components": [
{
"component": "wifi_lite",
"optional": "true"
}
]
},
```
`wifi_lite`部件在`//build/lite/components/communication.json`文件中,描述如下:
```
{
"component": "wifi_lite",
……
"targets": [
"//foundation/communication/wifi_lite:wifi" --- wifi_lite的编译目标
],
……
},
```
`//foundation/communication/wifi_lite/BUILD.gn`文件中,描述需要适配的接口头文件路径,如下:
```
config("include") {
include_dirs = [ "interfaces/wifiservice" ] --- 因为wifi_lite只提供头文件,不提供wifi的具体实现,所以wifi模块暴露出适配的目录路径提供给硬件厂商来适配,厂商提供wifi协议栈源码实现。
}
group("wifi") {
public_configs = [ ":include" ]
}
```
因为在本案例中,`wifi`属于`SoC`提供的功能,所以适配源码放在`SoC``//device/soc/bestechnic/hals/communication/wifi_lite/wifiservice`目录下,包含`wifi_device.c``wifi_hotspot.c`分别适配`wifi_device.h``wifi_hotspot.h`。如下:
```
……
WifiErrorCode Scan(void) --- wifi_device.c中扫描wifi热点的函数,对wifi_device.h中Scan函数的适配实现
{
WifiErrorCode ret = ERROR_WIFI_BUSY;
if (IsWifiActive() != WIFI_STA_ACTIVE)
return ERROR_WIFI_IFACE_INVALID;
if (g_HalHmosWifiInfo.scan_state == SCAN_REQUEST ||
g_HalHmosWifiInfo.scan_state == SCAN_TRIGGER)
return ERROR_WIFI_BUSY;
HalHmosWifiLock();
ret = ((HalHmosSendEvent(HMOS_ON_WIFI_SCAN_STATE_CHANGED, NULL) == 0) ? WIFI_SUCCESS : ERROR_WIFI_BUSY);
HalHmosWifiUnLock();
return ret;
}
……
int GetSignalLevel(int rssi, int band) --- wifi_hotspot.c中获取wifi信号热点函数,对wifi_hotspot.h中GetSignalLevel函数的适配实现。
{
if (band == HOTSPOT_BAND_TYPE_2G) {
if (rssi >= RSSI_LEVEL_4_2_G)
return RSSI_LEVEL_4;
if (rssi >= RSSI_LEVEL_3_2_G)
return RSSI_LEVEL_3;
if (rssi >= RSSI_LEVEL_2_2_G)
return RSSI_LEVEL_2;
if (rssi >= RSSI_LEVEL_1_2_G)
return RSSI_LEVEL_1;
}
if (band == HOTSPOT_BAND_TYPE_5G) {
if (rssi >= RSSI_LEVEL_4_5_G)
return RSSI_LEVEL_4;
if (rssi >= RSSI_LEVEL_3_5_G)
return RSSI_LEVEL_3;
if (rssi >= RSSI_LEVEL_2_5_G)
return RSSI_LEVEL_2;
if (rssi >= RSSI_LEVEL_1_5_G)
return RSSI_LEVEL_1;
}
return ERROR_WIFI_INVALID_ARGS;
}
```
##### LWIP部件适配
`LiteOS-M kernel`目录下默认配置了`lwip`,因而具有编译功能,可以在`kernel`组件中指定`lwip`编译的目录。如下:
```
{
"subsystem": "kernel",
"components": [
{
"component": "liteos_m",
"features": [
"ohos_kernel_liteos_m_lwip_path = \"//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1\"" --- 指定在芯片厂商目录中进行适配
]
}
]
},
```
`//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1/BUILD.gn`文件中,描述了`lwip`的编译,如下:
```
import("//kernel/liteos_m/liteos.gni")
import("$LITEOSTHIRDPARTY/lwip/lwip.gni")
import("$LITEOSTOPDIR/components/net/lwip-2.1/lwip_porting.gni")
module_switch = defined(LOSCFG_NET_LWIP_SACK)
module_name = "lwip"
kernel_module(module_name) {
sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES -
[ "$LWIPDIR/api/sockets.c" ] + [ "porting/src/ethernetif.c" ] --- 增加ethernetif.c文件,用以适配ethernet网卡的初始化适配
defines = [ "LITEOS_LWIP=1" ]
defines += [ "CHECKSUM_BY_HARDWARE=1" ]
}
config("public") {
defines = [ "_BSD_SOURCE=1" ]
include_dirs =
[ "porting/include" ] + LWIP_PORTING_INCLUDE_DIRS + LWIP_INCLUDE_DIRS
}
```
`//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1/porting/include/lwip/lwipopts.h`文件中,说明原有`lwip`配置选项保持不变,软总线会依赖这些配置选项,并且新增硬件适配的配置项,如下:
```
#ifndef _PORTING_LWIPOPTS_H_
#define _PORTING_LWIPOPTS_H_
#include_next "lwip/lwipopts.h" --- 保持原来的配置项不变
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_CHECKSUM_ON_COPY 0
#define CHECKSUM_GEN_UDP 0 --- 新增硬件适配选项
#endif /* _PORTING_LWIPOPTS_H_ */
```
`//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1/porting/src/ethernetif.c`文件中,说明对`ethernet`网卡初始化的适配,如下:
```
err_t
ethernetif_init(struct netif *netif)
{
……
#ifdef CHECKSUM_BY_HARDWARE
eth_hw_checksum_init();
#endif
……
netif->linkoutput = low_level_output;
netif->drv_send = liteos_low_level_output;
netif->hwaddr_len = NETIF_MAX_HWADDR_LEN;
low_level_init(netif);
driverif_init(netif);
return ERR_OK;
……
}
```
#### 系统基本能力适配
本小节主要从移植的角度出发,分析适配过程中,需要操作或者注意的事项。
##### startup子系统适配
``startup`子系统适配`bootstrap_lite`/`syspara_lite`两个部件。请在`vendor/bestechnic_bak/display_demo/config.json`中新增对应的配置选项。
```
{
"subsystem": "startup",
"components": [
{
"component": "bootstrap_lite" --- bootstrap_lite 部件
},
{
"component": "syspara_lite", --- syspara_lite 部件
"features": [
"enable_ohos_startup_syspara_lite_use_posix_file_api = true"
]
}
]
},
```
适配`bootstrap_lite`部件时,需要在连接脚本文件`//device/soc/bestechnic/bes2600/liteos_m/sdk/bsp/out/best2600w_liteos/_best2001.lds`中手动新增如下段:
```
__zinitcall_bsp_start = .;
KEEP (*(.zinitcall.bsp0.init))
KEEP (*(.zinitcall.bsp1.init))
KEEP (*(.zinitcall.bsp2.init))
KEEP (*(.zinitcall.bsp3.init))
KEEP (*(.zinitcall.bsp4.init))
__zinitcall_bsp_end = .;
__zinitcall_device_start = .;
KEEP (*(.zinitcall.device0.init))
KEEP (*(.zinitcall.device1.init))
KEEP (*(.zinitcall.device2.init))
KEEP (*(.zinitcall.device3.init))
KEEP (*(.zinitcall.device4.init))
__zinitcall_device_end = .;
__zinitcall_core_start = .;
KEEP (*(.zinitcall.core0.init))
KEEP (*(.zinitcall.core1.init))
KEEP (*(.zinitcall.core2.init))
KEEP (*(.zinitcall.core3.init))
KEEP (*(.zinitcall.core4.init))
__zinitcall_core_end = .;
__zinitcall_sys_service_start = .;
KEEP (*(.zinitcall.sys.service0.init))
KEEP (*(.zinitcall.sys.service1.init))
KEEP (*(.zinitcall.sys.service2.init))
KEEP (*(.zinitcall.sys.service3.init))
KEEP (*(.zinitcall.sys.service4.init))
__zinitcall_sys_service_end = .;
__zinitcall_sys_feature_start = .;
KEEP (*(.zinitcall.sys.feature0.init))
KEEP (*(.zinitcall.sys.feature1.init))
KEEP (*(.zinitcall.sys.feature2.init))
KEEP (*(.zinitcall.sys.feature3.init))
KEEP (*(.zinitcall.sys.feature4.init))
__zinitcall_sys_feature_end = .;
__zinitcall_run_start = .;
KEEP (*(.zinitcall.run0.init))
KEEP (*(.zinitcall.run1.init))
KEEP (*(.zinitcall.run2.init))
KEEP (*(.zinitcall.run3.init))
KEEP (*(.zinitcall.run4.init))
__zinitcall_run_end = .;
__zinitcall_app_service_start = .;
KEEP (*(.zinitcall.app.service0.init))
KEEP (*(.zinitcall.app.service1.init))
KEEP (*(.zinitcall.app.service2.init))
KEEP (*(.zinitcall.app.service3.init))
KEEP (*(.zinitcall.app.service4.init))
__zinitcall_app_service_end = .;
__zinitcall_app_feature_start = .;
KEEP (*(.zinitcall.app.feature0.init))
KEEP (*(.zinitcall.app.feature1.init))
KEEP (*(.zinitcall.app.feature2.init))
KEEP (*(.zinitcall.app.feature3.init))
KEEP (*(.zinitcall.app.feature4.init))
__zinitcall_app_feature_end = .;
__zinitcall_test_start = .;
KEEP (*(.zinitcall.test0.init))
KEEP (*(.zinitcall.test1.init))
KEEP (*(.zinitcall.test2.init))
KEEP (*(.zinitcall.test3.init))
KEEP (*(.zinitcall.test4.init))
__zinitcall_test_end = .;
__zinitcall_exit_start = .;
KEEP (*(.zinitcall.exit0.init))
KEEP (*(.zinitcall.exit1.init))
KEEP (*(.zinitcall.exit2.init))
KEEP (*(.zinitcall.exit3.init))
KEEP (*(.zinitcall.exit4.init))
__zinitcall_exit_end = .;
```
需要新增上述段是因为`bootstrap_init`提供的对外接口,见`//utils/native/lite/include/ohos_init.h`文件,采用的是灌段的形式,最终会保存到上述链接段中。主要的服务自动初始化宏如下表格所示:
| 接口名 | 描述 |
| ---------------------- | -------------------------------- |
| SYS_SERVICE_INIT(func) | 标识核心系统服务的初始化启动入口 |
| SYS_FEATURE_INIT(func) | 标识核心系统功能的初始化启动入口 |
| APP_SERVICE_INIT(func) | 标识应用层服务的初始化启动入口 |
| SYS_FEATURE_INIT(func) | 标识应用层功能的初始化启动入口 |
![](../public_sys-resources/icon-note.gif) **说明:**
通过上面加载的组件编译出来的lib文件需要手动加入强制链接。
​ 如在 `vendor/bestechnic/display_demo/config.json` 中配置了`bootstrap_lite` 部件
```
{
"subsystem": "startup",
"components": [
{
"component": "bootstrap_lite"
},
...
]
},
```
​ `bootstrap_lite`部件会编译`//base/startup/bootstrap_lite/services/source/bootstrap_service.c`,该文件中,通过`SYS_SERVICE_INIT`将`Init`函数符号灌段到`__zinitcall_sys_service_start`和`__zinitcall_sys_service_end`中,由于`Init`函数是没有函数显示调用它,所以需要将它强制链接到最终的镜像。如下:
```
static void Init(void)
{
static Bootstrap bootstrap;
bootstrap.GetName = GetName;
bootstrap.Initialize = Initialize;
bootstrap.MessageHandle = MessageHandle;
bootstrap.GetTaskConfig = GetTaskConfig;
bootstrap.flag = FALSE;
SAMGR_GetInstance()->RegisterService((Service *)&bootstrap);
}
SYS_SERVICE_INIT(Init); --- 通过SYS启动即SYS_INIT启动就需要强制链接生成的lib
```
​ 在`//base/startup/bootstrap_lite/services/source/BUILD.gn`文件中,描述了在`out/v200zr/display_demo/libs` 生成 `libbootstrap.a`,如下:
```
static_library("bootstrap") {
sources = [
"bootstrap_service.c",
"system_init.c",
]
....
```
​ 那么需要在 `vendor/bestechnic/display_demo/config.json` 配置强制链接库`bootstrap`,如下:
```
"bin_list": [
{
"elf_name": "wifiiot",
"bsp_target_name": "best2600w_liteos",
"signature": "false",
"burn_name": "rtos_main",
"enable": "true",
"force_link_libs": [
"bootstrap", --- 强制链接libbootstrap.a
...
]
},
```
适配`syspara_lite`部件时,系统参数会最终写到文件中进行持久化保存。在轻量系统中,文件操作相关接口有`POSIX`接口与`HalFiles`接口这两套实现。
因为对接内核的文件系统,采用`POSIX`相关的接口,所以`features`字段中需要增加`enable_ohos_startup_syspara_lite_use_posix_file_api = true`。
如果对接`HalFiles`相关的接口实现的,则无须修改。
在适配`GetSerial`接口时,开发板不像产线生产过程那样,会写入一个具体的`Serial Number`,因而需要确定一个数据对开发板进行唯一标识。本案例采用`WiFi Mac`地址进行适配。
```
#define ETH_ALEN 6
#define MAC_BITS 4
#define MAC_HIGH_MASK 0xf0
#define MAC_LOW_MASK 0x0f
#define HEX_A 0xa
#define CHAR_NUM_OFFSET 0x30
#define CHAR_CAPITAL_OFFSET 0x37
#define STR_END_FLAG '\0'
typedef unsigned char u8;
static char serialNumber[2*ETH_ALEN + 1]; --- 最后一位留作'\0'结束符标识
static char Hex2Char(u8 hex)
{
if (hex < HEX_A) {
return hex + CHAR_NUM_OFFSET; --- 将数值0转为char的'0'
} else {
return hex + CHAR_CAPITAL_OFFSET; --- 将数值0xa转为char的'A'
}
}
const char* HalGetSerial(void)
{
char macAddr[ETH_ALEN];
// as devboard has no production serial number, we just
// use wifi mac address as device serial number.
if (serialNumber[0] == STR_END_FLAG) { --- 只有第一次调用时,才去获取mac地址
extern int bwifi_get_own_mac(u8 *addr);
bwifi_get_own_mac(macAddr); --- 获取mac地址
int j = 0;
for (int i = 0; i < ETH_ALEN; i++) {
u8 lowFour, highFour;
highFour = (macAddr[i] & MAC_HIGH_MASK) >> MAC_BITS;
serialNumber[j] = Hex2Char(highFour);
j++;
lowFour = macAddr[i] & MAC_LOW_MASK;
serialNumber[j] = Hex2Char(lowFour);
j++;
} --- 将mac地址值转化为serial number
}
return serialNumber;
}
```
##### hiviewdfx子系统适配
进行`hiviewdfx`子系统适配需要添加`hilog_lite`部件,直接在`config.json`文件配置即可。
```
{
"subsystem": "hiviewdfx",
"components": [
{
"component": "hilog_lite",
"optional": "true"
}
]
},
```
配置完成之后,在`//device/soc/bestechnic/bes2600/liteos_m/components/utils/src/hm_sys.c`中注册日志输出实现函数。
```
boolean HilogProc_Impl(const HiLogContent *hilogContent, uint32 len)
{
char tempOutStr[LOG_FMT_MAX_LEN] = {0};
if (LogContentFmt(tempOutStr, sizeof(tempOutStr), hilogContent) > 0) {
printf(tempOutStr);
#ifdef LOG_FLUSH
hHiviewRegisterHilogProc(HilogProc_Impl);al_trace_flush_buffer();
#endif
}
return TRUE;
}
HiviewRegisterHilogProc(HilogProc_Impl);
```
##### distributedschedule子系统适配
进行`distributedschedule`子系统适配需要添加`samgr_lite`部件,直接在`config.json`配置即可。
```
{
"subsystem": "distributedschedule",
"components": [
{
"component": "samgr_lite",
"features": [
"config_ohos_distributedschedule_samgr_lite_shared_task_size = 4096"
]
}
]
},
```
在轻量系统中,`samgr_lite`配置的共享任务栈大小默认为`0x800`。当函数调用栈较大时,会出现栈溢出的问题。在本次适配过程中,将其调整为`0x1000`。
##### utils子系统适配
进行`utils`子系统适配需要添加`kv_store`/`js_builtin`/`timer_task`/`kal_timer`部件,直接在`config.json`配置即可。
```
{
"subsystem": "utils",
"components": [
{
"component": "kv_store",
"features": [
"enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true"
]
},
{
"component": "js_builtin"
},
{
"component": "timer_task"
},
{
"component": "kal_timer",
}
]
},
```
与适配`syspara_lite`部件类似,适配`kv_store`部件时,键值对会写到文件中。在轻量系统中,文件操作相关接口有`POSIX`接口与`HalFiles`接口这两套实现。因为对接内核的文件系统,采用`POSIX`相关的接口,所以`features`需要增加`enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true`。如果对接`HalFiles`相关的接口实现的,则无须修改。
#### 图形显示子系统适配
##### graphic子系统适配
进行`graphic`子系统适配需要添加`graphic_utils`部件,直接在`config.json`配置即可。
```
"components": [
{
"component": "graphic_utils",
"features": [
"enable_ohos_graphic_utils_product_config = true"
]
},
{
"component": "ui"
}
]
}
```
`graphic`配置文件见 `//vendor/bestechnic/display_demo/graphic_config/product_graphic_lite_config.h`。
`graphic`适配见`//device/soc/bestechnic/bes2600/liteos_m/components/ui`, 主要功能如下:
- `display_device`:实例化`BaseGfxEngine`。
- `touch_input`:实例化`PointerInputDevice`。
- `UiMainTask`:初始化字体引擎,执行渲染任务等。
`graphic`子系统层次:
```
aafwk_lite + appexecfwk_lite (AMS + BMS)
|
ace_engine_lite + jerryscript + i18n_lite + resmgr_lite + utils/native/lite/... (ACE,JS引擎及其依赖)
|
graphic_ui + graphic_utils (图形框架)
|
giflib + libjpeg + libpng + qrcodegen + freetype... (图形第三方库)
```
图形应用示例见文件`//vendor/bestechnic/display_demo/tests/app.cpp`,如下:
```
/* ui app entry */
void RunApp()
{
#ifdef UI_TEST
AnimatorDemoStart(); --- native ui demo
#elif defined(ABILITY_TEST)
StartJSApp(); --- js demo
#endif
}
void AppEntry(void)
{
UiMain();
}
APP_FEATURE_INIT(AppEntry);
```
##### ace子系统适配
进行`ace`子系统适配需要添加`ace_engine_lite`部件,直接在`config.json`配置即可。
{
"subsystem": "ace",
"components": [
{
"component": "ace_engine_lite",
"features": [
"enable_ohos_ace_engine_lite_product_config = true"
]
}
]
},
`ace_engine_lite`部件配置文件见 `//vendor/bestechnic/display_demo/ace_lite_config/product_acelite_config.h`。
`ace_lite`的应用采用js语言进行开发,详细步骤如下:
1. 用`DevEco Studio`编写js应用,参考[轻量级智能穿戴开发](https://developer.harmonyos.com/cn/docs/documentation/doc-references/lite-wearable-file-0000001176751380)。
2. 使用预览功能进行预览,并且得到js包:`entry\.preview\intermediates\res\debug\lite\assets\js\default`。
3. 将js包放到对应的文件系统目录下,文件系统路径为`vendor/bestechnic/display_demo/fs/data/data/js`,如下:
```
├── app.js
├── common
├── i18n
├── manifest.json
└── pages
```
4. 最终编译生成系统镜像,烧录到单板后,系统会从`app.js`加载启动`ace`的应用。
##### aafwk子系统适配
进行`aafwk`子系统适配需要添加`aafwk_lite`部件,直接在`config.json`配置即可。
```
{
"subsystem": "aafwk",
"components": [
{
"component": "aafwk_lite",
"features": [
"enable_ohos_appexecfwk_feature_ability = true", --- 支持FA特性,即包含图形能力
"config_ohos_aafwk_ams_task_size = 4096" --- 配置ams栈的大小
]
}
]
},
```
`aafwk_lite`相关的应用样例见`vendor/bestechnic/display_demo/tests/ability`目录,包含`launcher`和`js app`这两类应用,应用的函数调用流程描述如下:
1. `launcher`应用,通过`InstallLauncher`安装`BundleName`为 `"com.huawei.launcher"`的`native ui`应用,在`AbilityMgrSliteFeature`启动后会调用`AbilityMgrHandler::StartLauncher()`启动`launcher`应用。
2. `StartJSApp`应用,通过`StartAbility`启动任意`Want`,通过将`want data`传递`JS_APP_PATH`,
`SetWantData(&want, JS_APP_PATH, strlen(JS_APP_PATH) + 1)`。
##### appexecfwk子系统适配
进行`appexecfwk`子系统适配需要添加`appexecfwk_lite`部件,直接在`config.json`配置即可。
```
{
"subsystem": "appexecfwk",
"components": [
{
"component": "appexecfwk_lite"
}
]
},
```
## PCS兼容性认证
### XTS用例
`XTS`测试参考资料见[xts参考资料](https://www.openharmony.cn/xts/),进行`XTS`子系统适配需要添加`xts_acts`/`xts_tools`部件,直接在`config.json`配置即可,配置如下:
{
"subsystem": "xts",
"components": [
{ "component": "xts_acts", "features":
[
"config_ohos_xts_acts_utils_lite_kv_store_data_path = \"/data\"",
"enable_ohos_test_xts_acts_use_thirdparty_lwip = true"
]
},
{ "component": "xts_tools", "features":[] }
]
}
其中,
- `config_ohos_xts_acts_utils_lite_kv_store_data_path` 是配置挂载文件系统根目录的名字。
- `enable_ohos_test_xts_acts_use_thirdparty_lwip` 表示如果使用`thirdparty/lwip`目录下的源码编译,则设置为`true`,否则设置为`false`。
全部跑完会有显示`xx Tests xx Failures xx Ignored`,如下:
```
...
[16:53:43:438]../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:793:testKvStoreMaxSize004:PASS
[16:53:43:438]+-------------------------------------------+
[16:53:43:438]
[16:53:43:438]-----------------------
[16:53:43:438]32 Tests 0 Failures 0 Ignored
[16:53:43:438]OK
[16:53:43:439]All the test suites finished!
```
### 报告提交
将上图`XTS`用例的情况保存为测试报告,上传到`OpenHarmony`兼容性测试网站进行认证,作为`sig`仓库转正到`master`仓库的必要条件。详细步骤如下:
步骤1:将`XTS`测试报告压缩成`zip`文件。
步骤2:生成测试报告的`SHA`校验码。本案例是将`zip`文件传到在线生成`hash`的[网站]( https://tool.lmeee.com/jiami/filehash)生成`SHA`校验码。
步骤3:进入`OpenHarmony`[兼容性测试网站](https://www.openharmony.cn/old/#/Compatibility_test)上传报告。
- 其中`API Level`填写报告中的`"sdkApiLevel"`字段
- `OS`版本号填写报告中的`"OS Version"`字段。
步骤4:点击`个人空间`-`我的兼容性测试`看到查看审核状态。
![审核状态](figure/bes2600_xts_state.png)
## todo
后续会补充以下方面的移植:
- 蓝牙
- `bms`包安装
- 音频播放
- 验证运行`JS`的`bytecode`
- 分布式能力:`dsoftbus`、`dms`、`dm`
- 分布式音乐播放器样例
# 轻量系统芯片移植案例
- **[轻量带屏解决方案之恒玄芯片移植案例](porting-bes2600w-on-minisystem-display-demo.md)**
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
## 编译环境搭建<a name="section3336103410314"></a> ## 编译环境搭建<a name="section3336103410314"></a>
首先请搭建OpenHarmony基础环境,步骤请参考轻量和小型系统入门[linux环境搭建](../quick-start/quickstart-lite-env-setup-linux.md)。用户态和LiteOS-A的内核态编译均使用llvm编译器编译,安装方法在搭建基础环境中已提供。若选择移植linux内核,请执行如下命令安装gcc-arm-linux-gnueabi交叉编译工具链,用于编译linux内核态镜像: 首先请搭建OpenHarmony基础环境,步骤请参考轻量和小型系统入门[linux环境搭建](../quick-start/quickstart-lite-package-environment.md)。用户态和LiteOS-A的内核态编译均使用llvm编译器编译,安装方法在搭建基础环境中已提供。若选择移植linux内核,请执行如下命令安装gcc-arm-linux-gnueabi交叉编译工具链,用于编译linux内核态镜像:
``` ```
sudo apt-get install gcc-arm-linux-gnueabi sudo apt-get install gcc-arm-linux-gnueabi
......
...@@ -6,6 +6,6 @@ ...@@ -6,6 +6,6 @@
- **[小型系统芯片移植指导](porting-smallchip.md)** - **[小型系统芯片移植指导](porting-smallchip.md)**
- **[标准系统移植指](standard-system-porting-guide.md)** - **[标准系统移植指](standard-system-porting-guide.md)**
# 快速入门 # 快速入门
- [轻量和小型系统入门](quickstart-lite.md) - [轻量和小型系统入门](quickstart-lite.md)
- [概述](quickstart-lite-overview.md) - [轻量与小型系统入门概述](quickstart-lite-overview.md)
- [入门介绍](quickstart-lite-introduction.md) - [搭建轻量与小型系统环境](quickstart-lite-env-setup.md)
- [Hi3861开发板介绍](oem_minitinier_des_3861.md) - [搭建系统环境概述](quickstart-lite-env-setup-overview.md)
- [Hi3516开发板介绍](oem_minitinier_des_3516.md) - [开发环境准备](quickstart-lite-env-prepare.md)
- [Hi3518开发板介绍](oem_minitinier_des_3518.md) - [获取源码](quickstart-lite-sourcecode-acquire.md)
- [搭建系统环境](quickstart-lite-env-setup.md) - [使用安装包方式搭建编译环境](quickstart-lite-package-environment.md)
- [概述](quickstart-lite-env-setup-overview.md) - [使用Docker方式搭建编译环境](quickstart-lite-docker-environment.md)
- [Windows开发环境准备](quickstart-lite-env-setup-windows.md) - [常见问题](quickstart-lite-env-setup-faqs.md)
- [获取源码及Ubuntu编译环境准备](quickstart-lite-env-setup-linux.md)
- [常见问题](quickstart-lite-env-setup-faqs.md) - [运行“Hello World”](quickstart-lite-steps.md)
- [开发步骤](quickstart-lite-steps.md) - [Hi3861开发板](quickstart-lite-steps-hi3861.md)
- [Hi3861开发板](quickstart-lite-steps-hi3861.md) - [安装开发板环境](quickstart-lite-steps-hi3861-setting.md)
- [安装开发板环境](quickstart-lite-steps-hi3861-setting.md) - [新建应用程序](quickstart-lite-steps-hi3861-application-framework.md)
- [WLAN联网(编译、烧录)](quickstart-lite-steps-hi3861-connection.md) - [编译](quickstart-lite-steps-hi3861-building.md)
- [运行Hello World](quickstart-lite-steps-hi3861-running.md) - [烧录](quickstart-lite-steps-hi3861-burn.md)
- [常见问题](quickstart-lite-steps-hi3861-faqs.md) - [调试验证](quickstart-lite-steps-hi3861-debug.md)
- [Hi3516开发板](quickstart-lite-steps-hi3516.md) - [运行](quickstart-lite-steps-hi3816-running.md)
- [安装开发板环境](quickstart-lite-steps-hi3516-setting.md) - [常见问题](quickstart-lite-steps-hi3861-faqs.md)
- [运行Hello OHOS(编译、烧录)](quickstart-lite-steps-hi3516-running.md)
- [驱动开发示例](quickstart-lite-steps-hi3516-program.md) - [Hi3516开发板](quickstart-lite-steps-hi3516.md)
- [常见问题](quickstart-lite-steps-hi3516-faqs.md) - [安装开发板环境](quickstart-lite-steps-hi3516-setting.md)
- [Hi3518开发板](quickstart-lite-steps-hi3518.md) - [新建应用程序](quickstart-lite-steps-hi3516-application-framework.md)
- [安装开发板环境](quickstart-lite-steps-hi3518-setting.md) - [编译](quickstart-lite-steps-hi3516-building.md)
- [运行Hello OHOS(编译、烧录)](quickstart-lite-steps-hi3518-running.md) - [烧录](quickstart-lite-steps-hi3516-burn.md)
- [常见问题](quickstart-lite-steps-hi3518-faqs.md) - [运行](quickstart-lite-steps-hi3516-running.md)
- [标准系统入门](quickstart-standard.md) - [常见问题](quickstart-lite-steps-hi3516-faqs.md)
- [入门介绍](quickstart-standard-overview.md)
- [搭建Windows开发环境](quickstart-standard-windows-environment.md) - [Hi3518开发板](quickstart-lite-steps-hi3518.md)
- [搭建Ubuntu环境\(获取源码及编译,Docker方式\)](quickstart-standard-docker-environment.md) - [安装开发板环境](quickstart-lite-steps-hi3518-setting.md)
- [搭建Ubuntu环境\(获取源码及编译,安装包方式\)](quickstart-standard-package-environment.md) - [新建应用程序](quickstart-lite-steps-hi3518-application-framework.md)
- [镜像烧录](quickstart-standard-burn.md) - [编译](quickstart-lite-steps-hi3518-building.md)
- [镜像运行](quickstart-standard-running.md) - [烧录](quickstart-lite-steps-hi3518-burn.md)
- [常见问题](quickstart-standard-faqs.md) - [运行](quickstart-lite-steps-hi3518-running.md)
\ No newline at end of file - [常见问题](quickstart-lite-steps-hi3518-faqs.md)
- [附录](quickstart-lite-introduction.md)
- [Hi3861开发板介绍](quickstart-lite-introduction-hi3861.md)
- [Hi3516开发板介绍](quickstart-lite-introduction-hi3516.md)
- [Hi3518开发板介绍](quickstart-lite-introduction-hi3518.md)
- [标准系统入门](quickstart-standard.md)
- [标准系统入门简介](quickstart-standard-overview.md)
- [标准系统开发环境准备(仅Hi3516需要)](quickstart-standard-env-setup.md)
- [获取源码](quickstart-standard-sourcecode-acquire.md)
- [运行“Hello World”](quickstart-standard-running.md)
- [Hi3516开发板](quickstart-standard-running-hi3516.md)
- [创建应用程序](quickstart-standard-running-hi3516-create.md)
- [编译](quickstart-standard-running-hi3516-build.md)
- [烧录](quickstart-standard-running-hi3516-burn.md)
- [运行](quickstart-standard-running-hi3516-run.md)
- [RK3568开发板](quickstart-standard-running-rk3568.md)
- [创建应用程序](quickstart-standard-running-rk3568-create.md)
- [编译](quickstart-standard-running-rk3568-build.md)
- [烧录](quickstart-standard-running-rk3568-burn.md)
- [运行](quickstart-standard-running-rk3568-run.md)
- [常见问题](quickstart-standard-faqs.md)
- [附录](quickstart-standard-appendix.md)
- [Hi3516开发板介绍](quickstart-standard-appendix-hi3516.md)
- [RK3568开发板介绍](quickstart-standard-appendix-rk3568.md)
\ No newline at end of file
# 使用Docker方式搭建编译环境<a name="ZH-CN_TOPIC_0000001171455558"></a>
- [安装Docker](#section7337134183512)
- [获取Docker环境](#section15666113905015)
使用安装包方式搭建Ubuntu编译环境步骤如下:
1. 安装Docker
2. 获取Docker环境:
想要详细了解OpenHarmony编译构建模块功能的开发者可参考[编译构建使用指南](../subsystems/subsys-build-mini-lite.md)
## 安装Docker<a name="section7337134183512"></a>
- 请参考[官方指导](https://docs.docker.com/engine/install/)
## 获取Docker环境<a name="section15666113905015"></a>
>![](../public_sys-resources/icon-note.gif) **说明:**
>不同的源码版本要匹配使用对应版本的Docker环境,本文以Master主干代码为例进行说明。
OpenHarmony的Docker镜像托管在[HuaweiCloud SWR](https://console.huaweicloud.com/swr/?region=cn-south-1#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage)上。开发者可以通过该镜像在很大程度上简化编译前的环境配置。下文将介绍具体使用步骤。
**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:**
1. 获取Docker镜像。
```
docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5
```
2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。
```
docker run -it -v $(pwd):/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构建环境。
```
docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5
```
# 开发环境准备<a name="ZH-CN_TOPIC_0000001193328250"></a>
- [系统要求](#zh-cn_topic_0000001072959308_section1865184385215)
- [安装DevEco Device Tool](#zh-cn_topic_0000001072959308_section86587531620)
DevEco Device Tool Ubuntu版本支持OpenHarmony源码开发、编译、烧录的一站式开发环境,因此,本章节为您介绍在Ubuntu环境下,如何搭建一套完整的可视化开发环境。
## 系统要求<a name="zh-cn_topic_0000001072959308_section1865184385215"></a>
- Ubuntu18及以上版本,内存推荐16 GB及以上。
- 系统的用户名不能含有中文字符。
- 只能使用普通用户角色搭建开发环境。
## 安装DevEco Device Tool<a name="zh-cn_topic_0000001072959308_section86587531620"></a>
DevEco Device Tool基于Visual Studio Code进行扩展,在Visual Studio Code上以插件方式运行,Visual Studio Code版本为1.60及以上。同时,DevEco Device Tool还依赖Python工具,并要求Python为3.8\~3.9版本。
在安装过程中,DevEco Device Tool会自动检查Visual Studio Code和Python,如果检测到Visual Studio Code、Python未安装或版本不符合要求,安装程序会自动安装Visual Studio Code和Python。
1. 将Ubuntu Shell环境修改为bash。
1. 执行如下命令,确认输出结果为bash。如果输出结果不是bash,请根据步骤2,将Ubuntu shell修改为bash。
```
ls -l /bin/sh
```
![](figures/zh-cn_image_0000001194078294.png)
2. 打开终端工具,执行如下命令,输入密码,然后选择**No**,将Ubuntu shell由dash修改为bash。
```
sudo dpkg-reconfigure dash
```
![](figures/zh-cn_image_0000001238878219.png)
2. 下载[DevEco Device Tool 3.0 Beta2](https://device.harmonyos.com/cn/ide#download_beta)Linux版本,下载时,请先使用华为开发者帐号进行登录后下载。如未注册华为开发者账号,请先[注册](https://developer.huawei.com/consumer/cn/doc/start/registration-and-verification-0000001053628148)
3. 解压DevEco Device Tool软件包并对解压后的文件夹进行赋权。
1. 进入DevEco Device Tool软件包目录,执行如下命令解压软件包,其中devicetool-linux-tool-3.0.0.200.zip为软件包名称,请根据实际进行修改。
```
unzip devicetool-linux-tool-3.0.0.300.zip
```
2. 进入解压后的文件夹,执行如下命令,赋予安装文件可执行权限,其中devicetool-linux-tool-3.0.0.300.sh请根据实际进行修改。
```
chmod u+x devicetool-linux-tool-3.0.0.300.sh
```
4. 执行如下命令,安装DevEco Device Tool,其中devicetool-linux-tool-3.0.0.300.sh请根据实际进行修改。
>![](../public_sys-resources/icon-note.gif) **说明:**
>安装过程中,会自动检查Visual Studio Code和Python是否安装,且版本符合要求,其中Visual Studio Code为1.60及以上版本,Python为3.8\~3.9版本。如果不满足,则安装过程中会自动安装,提示“Do you want to continue?”,请输入“Y”后继续安装。
```
sudo ./devicetool-linux-tool-3.0.0.300.sh -- --install-plugins
```
安装完成后,当界面输出“Deveco Device Tool successfully installed.”时,表示DevEco Device Tool安装成功。
![](figures/zh-cn_image_0000001239348791.png)
5. 安装完成后,在Ubuntu左下角的![](figures/zh-cn_image_0000001075566984.png)中,启动Visual Studio Code。
6. 启动Visual Studio Code,DevEco Device Tool运行依赖C/C++、CodeLLDB插件,请点击Visual Studio Code左侧的![](figures/button.png)按钮,分别搜索和安装C/C++、CodeLLDB插件。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果在插件市场安装C/C++和CodeLLDB插件不成功,可手动下载插件后进行安装,具体请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/documentation/guide/offline_plugin_install-0000001074376846)。
![](figures/deveco-device-tool-install-sucessful.png)
7. 重启Visual Studio Code,点击![](figures/zh-cn_image_0000001239226427.png)进入DevEco Device Tool工具界面。至此,DevEco Device Tool Ubuntu开发环境安装完成。![](figures/zh-cn_image_0000001194668634.png)
# 常见问题<a name="ZH-CN_TOPIC_0000001128470858"></a> # 常见问题<a name="ZH-CN_TOPIC_0000001216935337"></a>
- [安装hb过程中,出现乱码、段错误](#section411894616119) - [hb 安装过程中出现乱码、段错误](#section411894616119)
- [安装hb过程中,提示"cannot import 'sysconfig' from 'distutils'"](#section629417571626) - [hb 安装过程中提示"cannot import 'sysconfig' from 'distutils'"](#section629417571626)
- [安装hb过程中,提示"module 'platform' has no attribute 'linux\_distribution'"](#section10871523332) - [hb 安装过程中提示"module 'platform' has no attribute 'linux\_distribution'"](#section10871523332)
- [安装hb过程中,提示"Could not find a version that satisfies the requirement ohos-build"](#section47351657163213) - [hb 安装过程中提示"Could not find a version that satisfies the requirement ohos-build"](#section47351657163213)
- [Linux编译服务器终端输入不识别的命令时提示“ImportError: No module named apt\_pkg”](#section159891252236) - [Linux编译服务器终端输入不识别的命令时提示“ImportError: No module named apt\_pkg”](#section159891252236)
## 安装hb过程中,出现乱码、段错误<a name="section411894616119"></a> ## hb 安装过程中出现乱码、段错误<a name="section411894616119"></a>
- **现象描述** - **现象描述**
...@@ -26,11 +26,11 @@ ...@@ -26,11 +26,11 @@
``` ```
## 安装hb过程中,提示"cannot import 'sysconfig' from 'distutils'"<a name="section629417571626"></a> ## hb 安装过程中提示"cannot import 'sysconfig' from 'distutils'"<a name="section629417571626"></a>
- **现象描述** - **现象描述**
执行“python3 -m pip install --user ohos-build”提示"cannot import 'sysconfig' from 'distutils'" 执行“python3 -m pip install --user ohos-build”提示"cannot import 'sysconfig' from 'distutils'"
- **可能原因** - **可能原因**
...@@ -46,11 +46,11 @@ ...@@ -46,11 +46,11 @@
``` ```
## 安装hb过程中,提示"module 'platform' has no attribute 'linux\_distribution'"<a name="section10871523332"></a> ## hb 安装过程中提示"module 'platform' has no attribute 'linux\_distribution'"<a name="section10871523332"></a>
- **现象描述** - **现象描述**
执行“python3 -m pip install --user ohos-build”提示"module 'platform' has no attribute 'linux\_distribution'" 执行“python3 -m pip install --user ohos-build”提示"module 'platform' has no attribute 'linux\_distribution'"
- **可能原因** - **可能原因**
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
``` ```
## 安装hb过程中,提示"Could not find a version that satisfies the requirement ohos-build"<a name="section47351657163213"></a> ## hb 安装过程中提示"Could not find a version that satisfies the requirement ohos-build"<a name="section47351657163213"></a>
- **现象描述** - **现象描述**
......
# 获取源码及Ubuntu编译环境准备<a name="ZH-CN_TOPIC_0000001174350605"></a>
- [获取软件](#section1897711811517)
- [获取源码](#section1545225464016)
- [安装必要的库和工具](#section108201740181219)
- [安装Python3](#section1238412211211)
- [安装LLVM\(仅OpenHarmony\_v1.x分支/标签需要\)](#section12202192215415)
- [安装hb](#section15794154618411)
- [前提条件](#section1083283711515)
- [安装方法](#section11518484814)
- [卸载方法](#section3512551574)
系统要求:Ubuntu16.04及以上64位系统版本。
编译环境搭建包含如下几步:
1. 获取源码
2. 安装必要的库和工具
3. 安装python3
4. 安装LLVM\(仅OpenHarmony\_v1.x分支/标签需要\)
5. 安装hb
>![](../public_sys-resources/icon-notice.gif) **须知:**
>- 针对Ubuntu编译环境我们提供了对应的Docker,该Docker封装了相关编译工具,选择使用Docker的开发者可跳过此章节。Docker使用可参考[Docker方式获取编译环境](../get-code/gettools-acquire.md#section107932281315)。
>- 通常系统默认安装samba、vim等常用软件,需要做适当适配以支持Linux服务器与Windows工作台之间的文件共享。
>- 想要详细了解OpenHarmony编译构建模块功能的开发者可参考[编译构建使用指南](../subsystems/subsys-build-mini-lite.md)。
## 获取软件<a name="section1897711811517"></a>
Linux服务器通用环境配置需要的工具及其获取途径如下表所示:
**表 1** Linux服务器开发工具及获取途径
<a name="table6299192712513"></a>
<table><thead align="left"><tr id="row122993276512"><th class="cellrowborder" valign="top" width="25.779999999999998%" id="mcps1.2.4.1.1"><p id="p1829914271858"><a name="p1829914271858"></a><a name="p1829914271858"></a>开发工具</p>
</th>
<th class="cellrowborder" valign="top" width="30.819999999999997%" id="mcps1.2.4.1.2"><p id="p429918274517"><a name="p429918274517"></a><a name="p429918274517"></a>用途</p>
</th>
<th class="cellrowborder" valign="top" width="43.4%" id="mcps1.2.4.1.3"><p id="p12997271757"><a name="p12997271757"></a><a name="p12997271757"></a>获取途径</p>
</th>
</tr>
</thead>
<tbody><tr id="row45863354112"><td class="cellrowborder" valign="top" width="25.779999999999998%" headers="mcps1.2.4.1.1 "><p id="p3587173513117"><a name="p3587173513117"></a><a name="p3587173513117"></a>源码</p>
</td>
<td class="cellrowborder" valign="top" width="30.819999999999997%" headers="mcps1.2.4.1.2 "><p id="p258713581118"><a name="p258713581118"></a><a name="p258713581118"></a>功能开发</p>
</td>
<td class="cellrowborder" valign="top" width="43.4%" headers="mcps1.2.4.1.3 "><p id="p16587835171114"><a name="p16587835171114"></a><a name="p16587835171114"></a>参考<a href="../get-code/sourcecode-acquire.md">源码获取</a></p>
</td>
</tr>
<tr id="row020505735919"><td class="cellrowborder" valign="top" width="25.779999999999998%" headers="mcps1.2.4.1.1 "><p id="p1220513576596"><a name="p1220513576596"></a><a name="p1220513576596"></a>必要的库和工具</p>
</td>
<td class="cellrowborder" valign="top" width="30.819999999999997%" headers="mcps1.2.4.1.2 "><p id="p2206157145919"><a name="p2206157145919"></a><a name="p2206157145919"></a>编译所需的必要工具和库(如打包、镜像制作等)</p>
</td>
<td class="cellrowborder" valign="top" width="43.4%" headers="mcps1.2.4.1.3 "><p id="p920675719597"><a name="p920675719597"></a><a name="p920675719597"></a>通过互联网获取</p>
</td>
</tr>
<tr id="row430016273514"><td class="cellrowborder" valign="top" width="25.779999999999998%" headers="mcps1.2.4.1.1 "><p id="p330015271158"><a name="p330015271158"></a><a name="p330015271158"></a>Python3.7+</p>
</td>
<td class="cellrowborder" valign="top" width="30.819999999999997%" headers="mcps1.2.4.1.2 "><p id="p43003270510"><a name="p43003270510"></a><a name="p43003270510"></a>编译构建工具</p>
</td>
<td class="cellrowborder" valign="top" width="43.4%" headers="mcps1.2.4.1.3 "><p id="p34760459518"><a name="p34760459518"></a><a name="p34760459518"></a>通过互联网获取</p>
</td>
</tr>
<tr id="row7531362055"><td class="cellrowborder" valign="top" width="25.779999999999998%" headers="mcps1.2.4.1.1 "><p id="p1467122152710"><a name="p1467122152710"></a><a name="p1467122152710"></a>LLVM(仅OpenHarmony_v1.x分支/标签需要)</p>
</td>
<td class="cellrowborder" valign="top" width="30.819999999999997%" headers="mcps1.2.4.1.2 "><p id="p1739432372718"><a name="p1739432372718"></a><a name="p1739432372718"></a>编译工具链</p>
</td>
<td class="cellrowborder" valign="top" width="43.4%" headers="mcps1.2.4.1.3 "><p id="p59711534202610"><a name="p59711534202610"></a><a name="p59711534202610"></a>通过互联网获取</p>
</td>
</tr>
<tr id="row1644079184919"><td class="cellrowborder" valign="top" width="25.779999999999998%" headers="mcps1.2.4.1.1 "><p id="p744115914493"><a name="p744115914493"></a><a name="p744115914493"></a>hb</p>
</td>
<td class="cellrowborder" valign="top" width="30.819999999999997%" headers="mcps1.2.4.1.2 "><p id="p1244114913492"><a name="p1244114913492"></a><a name="p1244114913492"></a><span id="text565372520148"><a name="text565372520148"></a><a name="text565372520148"></a>OpenHarmony</span>编译构建命令行工具</p>
</td>
<td class="cellrowborder" valign="top" width="43.4%" headers="mcps1.2.4.1.3 "><p id="p1463918124619"><a name="p1463918124619"></a><a name="p1463918124619"></a>通过互联网获取</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-notice.gif) **须知:**
>- 如果后续通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装gn、ninja编译工具。
>- (推荐)如果后续通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装gn、ninja、LLVM编译工具。安装gn、ninja、LLVM编译工具时,请确保编译工具的环境变量路径唯一。
## 获取源码<a name="section1545225464016"></a>
开发者需要在Linux服务器上下载并解压一套源代码,请参见[源码获取](../get-code/sourcecode-acquire.md)
## 安装必要的库和工具<a name="section108201740181219"></a>
使用如下apt-get命令安装编译所需的必要的库和工具:
```
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 cpio device-tree-compiler
```
## 安装Python3<a name="section1238412211211"></a>
1. 打开Linux编译服务器终端。
2. 输入如下命令,查看python版本号:
```
python3 --version
```
如果低于python3.7版本,不建议直接升级,请按照如下步骤重新安装。以python3.8为例,按照以下步骤安装python。
1. 运行如下命令,查看Ubuntu版本:
```
cat /etc/issue
```
2. 根据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
```
## 安装LLVM\(仅OpenHarmony\_v1.x分支/标签需要\)<a name="section12202192215415"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:**
>如果下载的源码为OpenHarmony\_v1.x分支/标签, 请按下面的步骤安装9.0.0版本的llvm。
>如果下载的源码为Master及OpenHarmony\_v2.x分支/标签,可直接跳过本小节,hb会自动下载最新的llvm。
1. 打开Linux编译服务器终端。
2. [下载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 -C ~/
```
4. 设置环境变量。
```
vim ~/.bashrc
```
将以下命令拷贝到.bashrc文件的最后一行,保存并退出。
```
export PATH=~/llvm/bin:$PATH
```
5. 生效环境变量。
```
source ~/.bashrc
```
## 安装hb<a name="section15794154618411"></a>
### 前提条件<a name="section1083283711515"></a>
请先安装Python 3.7.4及以上版本,请见[安装Python3](#section1238412211211)
### 安装方法<a name="section11518484814"></a>
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
```
### 卸载方法<a name="section3512551574"></a>
```
python3 -m pip uninstall ohos-build
```
>![](../public_sys-resources/icon-notice.gif) **须知:**
>如果安装hb的过程中遇到问题,请参见下文[常见问题](quickstart-lite-env-setup-faqs.md)进行解决。
# 概述<a name="ZH-CN_TOPIC_0000001128470854"></a> # 搭建系统环境概述<a name="ZH-CN_TOPIC_0000001217013851"></a>
OpenHarmony可以使用DevEco Device Tool进行开发、编译、烧录、调测等。 OpenHarmony可以使用DevEco Device Tool进行开发、编译、烧录、调测等。
当前DevEco Device Tool发布了Windows和Ubuntu两个版本,本文以Windows版本进行相应开发介绍。 当前DevEco Device Tool发布了Windows和Ubuntu两个版本,本文以Ubuntu版本进行相应开发介绍。
使用Ubuntu版本的开发者可参阅[操作指导](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905)
当前Windows版本(除Hi3861外)尚不支持在Windows平台下编译,需要在Ubuntu平台下编译,下文将介绍如何搭建对应的OpenHarmony轻量和小型系统的开发环境和编译环境。
# Windows开发环境准备<a name="ZH-CN_TOPIC_0000001216018805"></a>
- [安装DevEco Device Tool](#zh-cn_topic_0000001058091994_section10761564496)
系统要求:
- Windows 10 64位系统。
- 系统的用户名不能含有中文字符。
## 安装DevEco Device Tool<a name="zh-cn_topic_0000001058091994_section10761564496"></a>
DevEco Device Tool以插件方式运行,基于Visual Studio Code进行扩展,同时DevEco Device Tool运行依赖Python,Node.js和hpm工具。
DevEco Device Tool支持一体化安装,即DevEco Device Tool安装向导会检测系统是否安装Visual Studio Code、Python、Node.js、hpm的适配版本,当安装向导未检测到这些软件时,会给出相应的提示,根据提示勾选要自动安装的软件,安装向导会自动下载相应的软件进行安装。
安装DevEco Device Tool,**主机的用户名不能包含中文字符**,否则在运行DevEco Device Tool时,DevEco Home界面会一直处于Loading状态,导致不能正常使用
1. 获取软件,请使用华为开发者帐号登录[https://device.harmonyos.com/cn/ide\#download\_beta](https://device.harmonyos.com/cn/ide#download_beta),下载DevEco Device Tool V3.0 Beta1及以上版本。如未注册华为开发者账号,请先[注册](https://developer.huawei.com/consumer/cn/doc/start/registration-and-verification-0000001053628148)
2. 解压DevEco Device Tool压缩包,双击安装包程序,点击Next进行安装。
3. 设置DevEco Device Tool的安装路径,点击Next。
4. 根据安装向导提示,勾选要自动安装的软件,点击Next。
![](figures/Snap28.png)
>![](../public_sys-resources/icon-note.gif) **说明:**
>当安装向导检测到系统中已安装可兼容的Python版本,会提示用户可选择已安装的可兼容的Python版本,也可选择下载推荐的Python版本。
5. 在以下界面点击Next,进行软件下载和安装。
![](figures/Snap8.png)
6. 在弹出的Python安装向导中,勾选“**Add Python 3.8 to PATH**”,然后点击**Install Now**开始安装,等待安装完成后,点击**Close**
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装可兼容的Python版本,且用户选择了已安装的可兼容的Python版本,则Python安装向导不会弹出,用户不需要执行此步骤。
>如果安装DevEco Device Tool 2.1 Release版本,Python版本只能为3.8.x版本,不能安装最新的Python3.9.x版本。如果安装DevEco Device Tool V3.0 Beta1及以上版本,Python版本只能为3.8.x或3.9.x版本。
![](figures/Snap34.png)
7. 在弹出的Visual Studio Code安装向导中,根据向导提示安装Visual Studio Code,安装过程中,请勾选“添加到PATH(重启后生效)”。
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装正确的Visual Studio Code版本,则Visual Studio Code安装向导不会弹出,用户不需要执行此步骤。
![](figures/Snap33.png)
8. 在弹出的Node.js安装向导中,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装正确的Node.js版本,则Node.js安装向导不会弹出,用户不需要执行此步骤。
9. 等待DevEco Device Tool安装向导自动安装hpm和DevEco Device Tool插件,直至安装完成,点击**Finish**,关闭DevEco Device Tool安装向导。
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装正确的hpm版本,则不会进行hpm软件的下载和安装。
10. 启动Visual Studio Code,会自动安装DevEco Device Tool依赖的C/C++、CodeLLDB插件。等待安装完成后,点击Visual Studio Code左侧的![](figures/button.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/deveco-device-tool-install-sucessful.png)
# 搭建系统环境<a name="ZH-CN_TOPIC_0000001128311058"></a> # 搭建轻量与小型系统环境<a name="ZH-CN_TOPIC_0000001216535391"></a>
- **[概述](quickstart-lite-env-setup-overview.md)** - **[搭建系统环境概述](quickstart-lite-env-setup-overview.md)**
- **[Windows开发环境准备](quickstart-lite-env-setup-windows.md)** - **[开发环境准备](quickstart-lite-env-prepare.md)**
- **[获取源码及Ubuntu编译环境准备](quickstart-lite-env-setup-linux.md)** - **[获取源码](quickstart-lite-sourcecode-acquire.md)**
- **[使用安装包方式搭建编译环境](quickstart-lite-package-environment.md)**
- **[使用Docker方式搭建编译环境](quickstart-lite-docker-environment.md)**
- **[常见问题](quickstart-lite-env-setup-faqs.md)** - **[常见问题](quickstart-lite-env-setup-faqs.md)**
......
# Hi3516开发板介绍<a name="ZH-CN_TOPIC_0000001174350603"></a> # Hi3516开发板介绍<a name="ZH-CN_TOPIC_0000001171934020"></a>
- [简介](#section26131214194212) - [简介](#section26131214194212)
- [开发板规格](#section15192203316533) - [开发板规格](#section15192203316533)
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。 Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。
**图 1** Hi3516单板正面外观图<a name="fig6340825506"></a> **图 1** Hi3516单板正面外观图<a name="fig11402183715219"></a>
![](figures/Hi3516单板正面外观图.png "Hi3516单板正面外观图")
![](figures/3516正面.png)
## 开发板规格<a name="section15192203316533"></a> ## 开发板规格<a name="section15192203316533"></a>
...@@ -28,10 +30,10 @@ Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代I ...@@ -28,10 +30,10 @@ Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代I
</tr> </tr>
<tr id="row21721687435"><td class="cellrowborder" valign="top" width="14.77%" headers="mcps1.2.3.1.1 "><p id="p817216810435"><a name="p817216810435"></a><a name="p817216810435"></a><strong id="b1172016266246"><a name="b1172016266246"></a><a name="b1172016266246"></a>外部器件</strong></p> <tr id="row21721687435"><td class="cellrowborder" valign="top" width="14.77%" headers="mcps1.2.3.1.1 "><p id="p817216810435"><a name="p817216810435"></a><a name="p817216810435"></a><strong id="b1172016266246"><a name="b1172016266246"></a><a name="b1172016266246"></a>外部器件</strong></p>
</td> </td>
<td class="cellrowborder" valign="top" width="85.22999999999999%" headers="mcps1.2.3.1.2 "><a name="ul179543016208"></a><a name="ul179543016208"></a><ul id="ul179543016208"><li>以太网口</li><li>音频视频<a name="ul5941311869"></a><a name="ul5941311869"></a><ul id="ul5941311869"><li>1路语音输入</li><li>1路单声道(AC_L)输出,接3W功放(LM4871)</li><li>MicroHDMI(1路HDMI 1.4)</li></ul> <td class="cellrowborder" valign="top" width="85.22999999999999%" headers="mcps1.2.3.1.2 "><a name="ul179543016208"></a><a name="ul179543016208"></a><ul id="ul179543016208"><li>以太网口</li><li>音频视频<a name="ul5941311869"></a><a name="ul5941311869"></a><ul id="ul5941311869"><li>1路语音输入</li><li>1路单声道(AC_L)输出,接3W功放(LM4871)</li><li>MicroHDMI(1路HDMI 1.4)</li></ul>
</li><li>摄像头<a name="ul924263620"></a><a name="ul924263620"></a><ul id="ul924263620"><li>传感器IMX335</li><li>镜头M12,焦距4mm,光圈1.8</li></ul> </li><li>摄像头<a name="ul924263620"></a><a name="ul924263620"></a><ul id="ul924263620"><li>传感器IMX335</li><li>镜头M12,焦距4mm,光圈1.8</li></ul>
</li><li>显示屏<a name="ul101471711667"></a><a name="ul101471711667"></a><ul id="ul101471711667"><li>LCD连接器(2.35寸)</li><li>LCD连接器(5.5寸)</li></ul> </li><li>显示屏<a name="ul101471711667"></a><a name="ul101471711667"></a><ul id="ul101471711667"><li>LCD连接器(2.35寸)</li><li>LCD连接器(5.5寸)</li></ul>
</li><li>外部器件及接口<a name="ul089255556"></a><a name="ul089255556"></a><ul id="ul089255556"><li>SD卡接口</li><li>JTAG/I2S 接口</li><li>ADC接口</li><li>舵机接口</li><li>Grove连接器</li><li>USB2.0(Type C)</li><li>功能按键3个,2个用户自定义按键,1个升级按键</li><li>LED指示灯,绿灯,红灯</li></ul> </li><li>外部器件及接口<a name="ul089255556"></a><a name="ul089255556"></a><ul id="ul089255556"><li>SD卡接口</li><li>JTAG/I2S 接口</li><li>ADC接口</li><li>舵机接口</li><li>Grove连接器</li><li>USB2.0(Type C)</li><li>功能按键3个,2个用户自定义按键,1个升级按键</li><li>LED指示灯,绿灯,红灯</li></ul>
</li></ul> </li></ul>
</td> </td>
</tr> </tr>
......
# Hi3518开发板介绍<a name="ZH-CN_TOPIC_0000001174270693"></a> # Hi3518开发板介绍<a name="ZH-CN_TOPIC_0000001171455554"></a>
- [简介](#section14815247616) - [简介](#section14815247616)
- [开发板规格](#section765112478446) - [开发板规格](#section765112478446)
...@@ -7,11 +7,13 @@ ...@@ -7,11 +7,13 @@
Hi3518EV300作为新一代智慧视觉处理SOC,集成新一代ISP\(Image Signal Processor\)以及H.265视频压缩编码器,同时采用先进低功耗工艺和低功耗架构设计,使其在低码率、高画质、低功耗等方面引领行业水平。 Hi3518EV300作为新一代智慧视觉处理SOC,集成新一代ISP\(Image Signal Processor\)以及H.265视频压缩编码器,同时采用先进低功耗工艺和低功耗架构设计,使其在低码率、高画质、低功耗等方面引领行业水平。
**图 1** Hi3518EV300单板正面外观图<a name="fig73059502010"></a> **图 1** Hi3518EV300单板正面外观图<a name="fig1187174485310"></a>
![](figures/Hi3518EV300单板正面外观图.png "Hi3518EV300单板正面外观图") ![](figures/Hi3518EV300单板正面外观图.png "Hi3518EV300单板正面外观图")
**图 2** Hi3518EV300单板背面外观图<a name="fig14828141713116"></a> **图 2** Hi3518EV300单板背面外观图<a name="fig73195258113"></a>
![](figures/Hi3518EV300单板背面外观图.png "Hi3518EV300单板背面外观图")
![](figures/Hi3518正背面.png)
## 开发板规格<a name="section765112478446"></a> ## 开发板规格<a name="section765112478446"></a>
......
# Hi3861开发板介绍<a name="ZH-CN_TOPIC_0000001174270685"></a> # Hi3861开发板介绍<a name="ZH-CN_TOPIC_0000001217013855"></a>
- [简介](#section19352114194115) - [简介](#section19352114194115)
- [资源和约束](#section82610215014) - [资源和约束](#section82610215014)
...@@ -7,32 +7,36 @@ ...@@ -7,32 +7,36 @@
## 简介<a name="section19352114194115"></a> ## 简介<a name="section19352114194115"></a>
Hi3861 WLAN模组是一片大约2cm\*5cm大小的开发板,是一款高度集成的2.4GHz WLAN SoC芯片,集成IEEE 802.11b/g/n基带和RF(Radio Frequency)电路。支持OpenHarmony,并配套提供开放、易用的开发和调试运行环境。 Hi3861开发板是一片大约2cm\*5cm大小的开发板,是一款高度集成的2.4GHz WLAN SoC芯片,集成IEEE 802.11b/g/n基带和RF(Radio Frequency)电路。支持OpenHarmony,并配套提供开放、易用的开发和调试运行环境。
**图 1** Hi3861 WLAN模组外观图<a name="fig5781557185810"></a> **图 1** Hi3861开发板外观图<a name="fig1663155016295"></a>
![](figures/Hi3861-WLAN模组外观图.png "Hi3861-WLAN模组外观图") ![](figures/Hi3861开发板外观图.png "Hi3861开发板外观图")
另外,Hi3861 WLAN模组还可以通过与Hi3861底板连接,扩充自身的外设能力,底板如下图所示。 另外,Hi3861开发板还可以通过与Hi3861底板连接,扩充自身的外设能力,底板如下图所示。
**图 2** Hi3861底板外观图<a name="fig12182375916"></a> **图 2** Hi3861底板外观图<a name="fig111746288192"></a>
![](figures/Hi3861底板外观图.png "Hi3861底板外观图")
![](figures/zh-cn_image_0000001171455564.png)
- RF电路包括功率放大器PA(Power Amplifier)、低噪声放大器LNA(Low Noise Amplifier)、RF Balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s物理层速率。 - 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 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芯片集成高性能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芯片适用于智能家电等物联网智能终端领域。 - Hi3861芯片适用于智能家电等物联网智能终端领域。
**图 3** Hi3861功能框图<a name="fig1367035113590"></a> **图 3** Hi3861功能框图<a name="f0d52fa2f3b094c688c805a373a6ec970"></a>
![](figures/Hi3861功能框图.png "Hi3861功能框图")
![](figures/zh-cn_image_0000001171455566.png)
## 资源和约束<a name="section82610215014"></a> ## 资源和约束<a name="section82610215014"></a>
Hi3861 WLAN模组资源十分有限,整板共2MB FLASH,352KB RAM。在编写业务代码时,需注意资源使用效率。 Hi3861开发板资源十分有限,整板共2MB FLASH,352KB RAM。在编写业务代码时,需注意资源使用效率。
## 开发板规格<a name="section169054431017"></a> ## 开发板规格<a name="section169054431017"></a>
**表 1** Hi3861 WLAN模组规格清单 **表 1** Hi3861开发板规格清单
<a name="t672b053e2ac94cbdb5244857fed4764e"></a> <a name="t672b053e2ac94cbdb5244857fed4764e"></a>
<table><thead align="left"><tr id="r54b3810e43d24e1887c1d6a41394996b"><th class="cellrowborder" valign="top" width="18.060000000000002%" id="mcps1.2.3.1.1"><p id="a2b235e9ed55f4338886788f140e648a0"><a name="a2b235e9ed55f4338886788f140e648a0"></a><a name="a2b235e9ed55f4338886788f140e648a0"></a>规格类型</p> <table><thead align="left"><tr id="r54b3810e43d24e1887c1d6a41394996b"><th class="cellrowborder" valign="top" width="18.060000000000002%" id="mcps1.2.3.1.1"><p id="a2b235e9ed55f4338886788f140e648a0"><a name="a2b235e9ed55f4338886788f140e648a0"></a><a name="a2b235e9ed55f4338886788f140e648a0"></a>规格类型</p>
......
# 入门介绍<a name="ZH-CN_TOPIC_0000001181550103"></a> # 附录<a name="ZH-CN_TOPIC_0000001216693903"></a>
- **[Hi3861开发板介绍](oem_minitinier_des_3861.md)** - **[Hi3861开发板介绍](quickstart-lite-introduction-hi3861.md)**
- **[Hi3516开发板介绍](oem_minitinier_des_3516.md)** - **[Hi3516开发板介绍](quickstart-lite-introduction-hi3516.md)**
- **[Hi3518开发板介绍](oem_minitinier_des_3518.md)** - **[Hi3518开发板介绍](quickstart-lite-introduction-hi3518.md)**
# 概述<a name="ZH-CN_TOPIC_0000001128311060"></a> # 轻量与小型系统入门概述<a name="ZH-CN_TOPIC_0000001216935335"></a>
OpenHarmony轻量和小型系统适用于内存较小的IOT设备,本文选取了三款典型开发板:Hi3861 WLAN模组、Hi3516DV300、Hi3518EV300,并基于上述三款开发板进行开发介绍 OpenHarmony轻量和小型系统适用于内存较小的IOT设备。通过本文,开发者可以快速熟悉OpenHarmony轻量和小型系统的环境搭建、编译、烧录、调测以及运行“Hello World”等
通过本文,开发者可以快速熟悉OpenHarmony轻量和小型系统的环境搭建、编译、烧录、调测以及简单应用及驱动开发等。 轻量和小型系统的开发有以下两种方法:
- 用Windows环境进行开发和烧录,使用Linux环境进行编译。
- 统一使用Linux环境进行开发、编译和烧录。
因目前Windows系统不支持编译,暂时无法全部使用Windows环境进行开发,开发者可根据使用习惯选择合适的开发方法。
本文将介绍第二种方法,下方所有操作均在Linux环境下进行。
本文选取了三款典型开发板:Hi3861 WLAN模组、Hi3516DV300、Hi3518EV300,并基于上述三款开发板进行开发介绍。开发板的具体外观和规格可参见[本文附录](quickstart-lite-introduction-hi3861.md#section19352114194115),开发者可根据需要自行购买的开发板。
轻量和小型系统快速入门流程如下图所示,其中搭建编译环境环节可根据实际情况选择Docker方式或安装包方式其中一种即可。
>![](../public_sys-resources/icon-note.gif) **说明:**
>Docker环境已经封装了相关编译工具,开发者在使用该Docker环境时可以省去Ubuntu编译环境及开发板环境的的搭建操作。
**图 1** 轻量和小型系统快速入门流程<a name="fig642616212336"></a>
![](figures/轻量和小型系统快速入门流程.png "轻量和小型系统快速入门流程")
# 使用安装包方式搭建编译环境<a name="ZH-CN_TOPIC_0000001171615528"></a>
- [安装必要的库和工具](#section108201740181219)
- [安装hb](#section15794154618411)
- [安装LLVM\(仅OpenHarmony\_v1.x分支/标签需要\)](#section711117144296)
使用安装包方式搭建Ubuntu编译环境步骤如下:
1. 安装必要的库和工具:编译所需的必要工具和库(如打包、镜像制作等)
2. 安装hb:OpenHarmony编译构建命令行工具
3. 安装LLVM\(仅OpenHarmony\_v1.x分支/标签需要\)
想要详细了解OpenHarmony编译构建模块功能的开发者可参考[编译构建使用指南](../subsystems/subsys-build-mini-lite.md)
## 安装必要的库和工具<a name="section108201740181219"></a>
使用如下apt-get命令安装编译所需的必要的库和工具:
```
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 cpio device-tree-compiler
```
## 安装hb<a name="section15794154618411"></a>
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
```
>![](../public_sys-resources/icon-notice.gif) **须知:**
>若安装hb的过程中遇到问题,请参见下文[常见问题](quickstart-lite-env-setup-faqs.md)进行解决。
## 安装LLVM\(仅OpenHarmony\_v1.x分支/标签需要\)<a name="section711117144296"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:**
>如果下载的源码为OpenHarmony\_v1.x分支/标签, 请按下面的步骤安装9.0.0版本的llvm。
>如果下载的源码为Master及非OpenHarmony\_v1.x分支/标签,可直接跳过本小节,hb会自动下载最新的llvm。
1. 打开Linux编译服务器终端。
2. [下载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 -C ~/
```
4. 设置环境变量。
```
vim ~/.bashrc
```
将以下命令拷贝到.bashrc文件的最后一行,保存并退出。
```
export PATH=~/llvm/bin:$PATH
```
5. 生效环境变量。
```
source ~/.bashrc
```
# 获取源码<a name="ZH-CN_TOPIC_0000001177086414"></a>
- [前提条件](#section21887149017)
- [操作步骤](#section349724435812)
## 前提条件<a name="section21887149017"></a>
1. 注册码云gitee账号。
2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)
3. 安装[git客户端](https://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
```
## 操作步骤<a name="section349724435812"></a>
>![](../public_sys-resources/icon-note.gif) **说明:**
>Master主干为开发分支,开发者可通过Master主干获取最新特性。发布版本代码相对比较稳定,开发者可基于发布版本代码进行商用功能开发。
- **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发布版本代码获取**
OpenHarmony发布版本获取源码方式请参考[Release-Notes](../get-code/../../release-notes/Readme.md)。
# 新建应用程序<a name="ZH-CN_TOPIC_0000001171455556"></a>
下方将通过修改源码的方式展示如何编写简单程序,输出“Hello OHOS!”。请在[获取源码](quickstart-lite-sourcecode-acquire.md)章节下载的源码目录中进行下述操作。
1. 新建目录及源码。
新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。
```
#include <stdio.h>
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":[] }
]
},
```
# 编译<a name="ZH-CN_TOPIC_0000001171615520"></a>
下方将介绍如何使用Hi3516开发板进行编译。使用安装包方式与docker方式搭建Ubuntu编译环境,编译步骤相同。
1. 请进入源码根目录,执行如下命令进行编译:
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果使用Docker方式搭建编译环境,请在[获取Docker环境](quickstart-lite-docker-environment.md#section15666113905015)中进入的Docker构建环境中,执行如下命令进行编译。
```
hb set(设置编译路径)
.(选择当前路径)
选择ipcamera_hispark_taurus并回车
hb build -f(执行编译)
```
**图 1** Hi3516编译设置图例-Docker方式<a name="fig1355483082115"></a>
![](figures/Hi3516编译设置图例-Docker方式.png "Hi3516编译设置图例-Docker方式")
2. 编译结束后,出现“ipcamera\_hispark\_taurus build success”字样,则证明构建成功。
>![](../public_sys-resources/icon-notice.gif) **须知:**
>烧录相关文件获取路径:
>结果文件:out/hispark\_taurus/ipcamera\_hispark\_taurus。
>U-boot文件:device/hisilicon/hispark\_taurus/sdk\_liteos/uboot/out/boot/u-boot-hi3516dv300.bin。
# 烧录<a name="ZH-CN_TOPIC_0000001171774080"></a>
- [前提条件](#section762111572589)
- [使用网口烧录](#section12323175612487)
烧录是指将编译后的程序文件下载到芯片开发板上的动作,为后续的程序调试提供基础。DevEco Device Tool提供一键烧录功能,操作简单,能快捷、高效的完成程序烧录,提升烧录的效率。
DevEco Device Tool以插件方式运行,基于Visual Studio Code进行扩展,用户可点击Visual Studio Code左侧栏的![](figures/2021-01-27_170334.png)图标打开DevEco Device Tool。
Hi3516开发板的代码烧录支持USB烧录、网口烧录和串口烧录三种方式。此处仅以网口烧录为例进行说明,其它方式请参考[Hi3516DV300开发板烧录](../toctopics/ide-hi3516-upload.md)
## 前提条件<a name="section762111572589"></a>
1. 在DevEco Device Tool工具中点击**Import Project**导入新建应用程序章节修改后的源码文件。
![](figures/import-project.png)
2. 选择源码导入时,系统会提示该工程不是DevEco Device Tool工程,点击**Import**
![](figures/import-project-confirm.png)
3. MCU选择HiSilicom\_Arm下的Hi3516DV300,Board选择hi3516dv300,Framework选择Hb,然后点击**Import**完成导入。
![](figures/hi3516-import-projects.png)
## 使用网口烧录<a name="section12323175612487"></a>
1. 请连接好电脑和待烧录开发板,需要同时连接串口、网口和电源,具体可参考[Hi3516DV300开发板介绍](https://device.harmonyos.com/cn/docs/documentation/guide/quickstart-lite-introduction-hi3516-0000001152041033)
2. 查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。
Windows系统,打开设备管理器查看并记录对应的串口号,或在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/record-the-serial-port-number.png)
Linux系统,在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/Snap22.png)
3. 在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/zh-cn_image_0000001222969587.png)
4. 在“hi3516dv300”页签,设置烧录选项,包括upload\_partitions、upload\_port和upload\_protocol。
- upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。
- upload\_port:选择已查询的串口号。
- upload\_protocol:选择烧录协议,固定选择“hiburn-net”。
![](figures/zh-cn_image_0000001177474882.png)
5. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516DV300网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/documentation/guide/set_ipaddress-0000001141825075)
6. 设置网口烧录的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/ip-address-information.png)
7. 分别检查待烧录文件的烧录信息,DevEco Device Tool已预置默认的烧录文件信息,可根据实际情况进行调整。待烧录文件包括:fastboot、kernel、rootfs和userfs。
1. 在“hi3516dv300\_fastboot”页签,在New Option选项中选择需要修改的项,例如partition\_bin(烧录文件路径)、partition\_addr(烧录文件起始地址)、partition\_length(烧录文件分区长度)等。
![](figures/zh-cn_image_0000001222994321.png)
2. 然后在Partition Options中,分别修改上述步骤中选择的修改项。
>![](../public_sys-resources/icon-note.gif) **说明:**
>在设置烧录分区起始地址和分区长度时,应根据实际待烧录文件的大小进行设置,要求设置的烧录分区大小,要大于待烧录文件的大小;同时,各烧录文件的分区地址设置不能出现重叠。
![](figures/zh-cn_image_0000001223185957.png)
3. 按照相同的方法修改kernel、rootfs和userfs的烧录文件信息。
8. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
9. 点击**Open**打开工程文件,然后在“PROJECT TASKS”中,点击hi3516dv300下的**Upload**按钮,启动烧录。
![](figures/hi3516-upload-start-burning.png)
10. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。
![](figures/hi3516-restart-the-development-board.png)
11. 重新上电后,界面提示如下信息时,表示烧录成功。
![](figures/hi3516-burning-succeeded-net.png)
12. 烧录成功后,请根据镜像运行章节进行操作,启动系统。
# 常见问题<a name="ZH-CN_TOPIC_0000001128470856"></a> # 常见问题<a name="ZH-CN_TOPIC_0000001171615522"></a>
- [烧写选择串口后提示“Error: Opening COMxx: Access denied”](#section627268185113) - [烧写选择串口后提示“Error: Opening COMxx: Access denied”](#section627268185113)
- [Windows电脑与单板网络连接失败](#section195391036568) - [Windows电脑与单板网络连接失败](#section195391036568)
- [烧写失败](#section571164016565) - [烧写失败](#section571164016565)
- [编译构建过程中,提示找不到“python”](#section1039835245619) - [编译构建过程中,提示找不到“python”](#section1039835245619)
- [串口无回显](#section14871149155911) - [串口无回显](#section14871149155911)
## 烧写选择串口后提示“Error: Opening COMxx: Access denied”<a name="section627268185113"></a> ## 烧写选择串口后提示“Error: Opening COMxx: Access denied”<a name="section627268185113"></a>
- **现象描述** - **现象描述**
点击烧写并选择串口后,出现“Error: Opening COMxx: Access denied” 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied
![](figures/Failed-to-open-the-serial-port.png) **图 1** 打开串口失败图<a name="fig066333283916"></a>
![](figures/打开串口失败图.png "打开串口失败图")
- **可能原因** - **可能原因**
串口已经被占用。 串口已经被占用。
- 解决方法 - **解决办法**
1. 按图依次选择下拉框,查找带有serial-xx的终端。
**图 2** 查找是否存在占用串口的终端<a name="fig165994164420"></a>
![](figures/查找是否存在占用串口的终端.png "查找是否存在占用串口的终端")
2. 点击标号中的垃圾桶图标,关闭串口。
检查主机中可能占用该端口的工具,关闭即可。若是当前工具占用,可按以下步骤排查并关闭: **图 3** 关闭串口终端<a name="fig7911282453"></a>
![](figures/关闭串口终端.png "关闭串口终端")
1. 排查终端窗口列表,检查是否被monitor或其他终端占用 3. 重新点击烧写,选择串口并开始烧写程序
![](figures/terminal-list.png) **图 4** 重新启动烧写任务<a name="fig1138624316485"></a>
2. 找到占用,点击垃圾桶图标,关闭占用。 ![](figures/changjian1.png)
## Windows电脑与单板网络连接失败<a name="section195391036568"></a> ## Windows电脑与单板网络连接失败<a name="section195391036568"></a>
...@@ -35,8 +45,8 @@ ...@@ -35,8 +45,8 @@
点击烧写并选择串口后,无法获取文件。 点击烧写并选择串口后,无法获取文件。
**图 1** 网络不通,Hi3516单板无法获取文件<a name="fig135261439195819"></a> **图 5** 网络不通,单板无法获取文件图<a name="fig5218920223"></a>
![](figures/网络不通-Hi3516单板无法获取文件.png "网络不通-Hi3516单板无法获取文件") ![](figures/网络不通-单板无法获取文件图.png "网络不通-单板无法获取文件图")
- **可能原因** - **可能原因**
...@@ -49,19 +59,23 @@ ...@@ -49,19 +59,23 @@
1. 检查网线是否连接。 1. 检查网线是否连接。
2. 点击Windows防火墙。 2. 点击Windows防火墙。
![](figures/hi3516-network-and-firewall-setting.png) **图 6** 网络防火墙设置图<a name="fig62141417794"></a>
![](figures/网络防火墙设置图.png "网络防火墙设置图")
3. 点击“允许应用通过防火墙”。 3. 点击“允许应用通过防火墙”。
![](figures/hi3516-firewall-and-network-protection.png) **图 7** 防火墙和网络保护界面图<a name="fig20703151111116"></a>
![](figures/防火墙和网络保护界面图.png "防火墙和网络保护界面图")
4. 查找Visual Studio Code应用。 4. 查找Visual Studio Code应用。
![](figures/hi3516-selecting-the-visual-studio-code-application.png) **图 8** 查找Visual Studio Code应用图<a name="fig462316612165"></a>
![](figures/查找Visual-Studio-Code应用图.png "查找Visual-Studio-Code应用图")
5. 勾选Visual Studio Code的专用和公用网络的访问权限。 5. 勾选Visual Studio Code的专用和公用网络的访问权限。
![](figures/hi3516-allowing-the-visual-studio-code-application-to-access-the-network.png) **图 9** 允许Visual Studio Code应用访问网络<a name="fig132725269184"></a>
![](figures/允许Visual-Studio-Code应用访问网络.png "允许Visual-Studio-Code应用访问网络")
## 烧写失败<a name="section571164016565"></a> ## 烧写失败<a name="section571164016565"></a>
...@@ -83,24 +97,30 @@ ...@@ -83,24 +97,30 @@
- **现象描述** - **现象描述**
![](figures/symptom-for-not-finding-python.png) ![](figures/zh-cn_image_0000001216693913.png)
- **可能原因**1
- **可能原因1**
没有装python。 没有装python。
- **解决办法** - **解决办法**1
按照[安装Python环境](../quick-start/quickstart-lite-env-setup-linux.md) 使用如下命令安装Python,下方以Python3.8为例
- **可能原因2** ```
sudo apt-get install python3.8
```
![](figures/reason-for-not-finding-python.png)
- **解决办法** - **可能原因**2
usr/bin目录下没有python软链接。
![](figures/zh-cn_image_0000001217013865.png)
- **解决办法**2
usr/bin目录下没有python软链接,请运行以下命令: 请运行以下命令:
``` ```
# cd /usr/bin/ # cd /usr/bin/
...@@ -111,7 +131,7 @@ ...@@ -111,7 +131,7 @@
例: 例:
![](figures/solution.png) ![](figures/zh-cn_image_0000001216693915.png)
## 串口无回显<a name="section14871149155911"></a> ## 串口无回显<a name="section14871149155911"></a>
...@@ -128,7 +148,7 @@ ...@@ -128,7 +148,7 @@
修改串口号。 修改串口号。
请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行修改串口号。 请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行内[步骤1](#section627268185113)修改串口号。
- **可能原因2** - **可能原因2**
...@@ -151,11 +171,11 @@ ...@@ -151,11 +171,11 @@
2. 根据USB烧写步骤烧写U-boot文件。 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文件进行烧写。 按照[Hi3516系列USB烧写步骤](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。
3. 烧写完成后,登录串口如下图所示。 3. 烧写完成后,登录串口如下图所示。
**图 2** U-boot烧写完成串口显示图<a name="zh-cn_topic_0000001053466255_fig155914681910"></a> **图 10** U-boot烧写完成串口显示图<a name="zh-cn_topic_0000001053466255_fig155914681910"></a>
![](figures/U-boot烧写完成串口显示图.png "U-boot烧写完成串口显示图") ![](figures/U-boot烧写完成串口显示图.png "U-boot烧写完成串口显示图")
# 驱动开发示例<a name="ZH-CN_TOPIC_0000001174350613"></a>
- [驱动程序介绍](#s8efc1952ebfe4d1ea717182e108c29bb)
- [编译和烧录](#section660016185110)
- [镜像运行](#section333215226219)
- [下一步学习](#section9712145420182)
本节指导开发者在单板上运行第一个驱动程序,其中包括驱动程序介绍、编译、烧写、运行等步骤。
## 驱动程序介绍<a name="s8efc1952ebfe4d1ea717182e108c29bb"></a>
下面基于HDF框架,提供一个简单的UART(Universal Asynchronous Receiver/Transmitter)平台驱动开发样例,包含配置文件的添加,驱动代码的实现以及用户态程序和驱动交互的流程。驱动程序源码位于drivers/framework/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)/drivers/framework/sample/platform/uart
```
4. 用户程序和驱动交互代码。
UART驱动成功初始化后,会创建/dev/uartdev-5设备节点,通过设备节点与UART驱动交互的代码如下:
```
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#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/hdf.json驱动配置中hdf\_hi3516dv300\_liteos\_a组件下的targets中增加hello\_uart\_sample组件,代码如下:
```
{
"components": [
{
"component": "hdf_hi3516dv300_liteos_a",
...
"targets": [
"//drivers/framework/sample/platform/uart:hello_uart_sample"
]
}
]
}
```
>![](../public_sys-resources/icon-note.gif) **说明:**
>如上代码均为示例代码,完整代码可以在drivers/framework/sample查看。
>示例代码默认不参与编译,需要手动添加到编译脚本中。
## 编译和烧录<a name="section660016185110"></a>
参考《运行Hello OHOS》进行编译和烧录:[编译](quickstart-lite-steps-hi3516-running.md#section1077671315253)[烧录](quickstart-lite-steps-hi3516-running.md#section1347011412201)
## 镜像运行<a name="section333215226219"></a>
1. 连接串口。
>![](../public_sys-resources/icon-notice.gif) **须知:**
>若无法连接串口,请参考[常见问题](quickstart-lite-steps-hi3516-faqs.md#section14871149155911)进行排查。
**图 1** 连接串口图<a name="fig124315964718"></a>
![](figures/连接串口图.png "连接串口图")
1. 单击**Monitor**打开串口。
2. 连续输入回车直到串口显示"hisilicon"。
3. 单板初次启动或修改启动参数,请进入[步骤2](#li109940111259),否则进入[步骤3](#li448312542515)。
2. <a name="li109940111259"></a>(单板初次启动必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,若不修改参数只需执行一次。每次复位单板均会自动进入系统。
>![](../public_sys-resources/icon-notice.gif) **须知:**
>U-boot引导程序默认会有2秒的等待时间,用户可使用回车打断等待并显示"hisilicon",通过**reset**命令可再次启动系统。
**表 1** U-boot修改命令
<a name="zh-cn_topic_0000001151888681_table1323441103813"></a>
<table><thead align="left"><tr id="zh-cn_topic_0000001151888681_row1423410183818"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="zh-cn_topic_0000001151888681_p623461163818"><a name="zh-cn_topic_0000001151888681_p623461163818"></a><a name="zh-cn_topic_0000001151888681_p623461163818"></a>执行命令</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="zh-cn_topic_0000001151888681_p42341014388"><a name="zh-cn_topic_0000001151888681_p42341014388"></a><a name="zh-cn_topic_0000001151888681_p42341014388"></a>命令解释</p>
</th>
</tr>
</thead>
<tbody><tr id="zh-cn_topic_0000001151888681_row1623471113817"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p102341719385"><a name="zh-cn_topic_0000001151888681_p102341719385"></a><a name="zh-cn_topic_0000001151888681_p102341719385"></a>setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p92347120389"><a name="zh-cn_topic_0000001151888681_p92347120389"></a><a name="zh-cn_topic_0000001151888681_p92347120389"></a>读取FLASH起始地址为0x800(单位为512B,即1MB),大小为0x4800(单位为512B,即9MB)的内容到0x80000000的内存地址,该大小(9MB)与IDE中所填写OHOS_Image.bin文件大小<strong id="zh-cn_topic_0000001151888681_b15685648113111"><a name="zh-cn_topic_0000001151888681_b15685648113111"></a><a name="zh-cn_topic_0000001151888681_b15685648113111"></a>必须相同</strong>。</p>
</td>
</tr>
<tr id="zh-cn_topic_0000001151888681_row12234912381"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p172306219392"><a name="zh-cn_topic_0000001151888681_p172306219392"></a><a name="zh-cn_topic_0000001151888681_p172306219392"></a>setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p13489329396"><a name="zh-cn_topic_0000001151888681_p13489329396"></a><a name="zh-cn_topic_0000001151888681_p13489329396"></a>表示设置启动参数,输出模式为串口输出,波特率为115200,数据位8,rootfs挂载于emmc器件,文件系统类型为vfat,</p>
<p id="zh-cn_topic_0000001151888681_p12481832163913"><a name="zh-cn_topic_0000001151888681_p12481832163913"></a><a name="zh-cn_topic_0000001151888681_p12481832163913"></a>“rootaddr=10M rootsize=20M rw”处对应填入rootfs.img的烧写起始位置与长度,此处与IDE中新增rootfs.img文件时所填大小<strong id="zh-cn_topic_0000001151888681_b24816327398"><a name="zh-cn_topic_0000001151888681_b24816327398"></a><a name="zh-cn_topic_0000001151888681_b24816327398"></a>必须相同</strong>。</p>
</td>
</tr>
<tr id="zh-cn_topic_0000001151888681_row18234161153820"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p823417118386"><a name="zh-cn_topic_0000001151888681_p823417118386"></a><a name="zh-cn_topic_0000001151888681_p823417118386"></a>saveenv</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p32341616389"><a name="zh-cn_topic_0000001151888681_p32341616389"></a><a name="zh-cn_topic_0000001151888681_p32341616389"></a>表示保存当前配置。</p>
</td>
</tr>
<tr id="zh-cn_topic_0000001151888681_row192345113811"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p7235111183819"><a name="zh-cn_topic_0000001151888681_p7235111183819"></a><a name="zh-cn_topic_0000001151888681_p7235111183819"></a>reset</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p123781411114016"><a name="zh-cn_topic_0000001151888681_p123781411114016"></a><a name="zh-cn_topic_0000001151888681_p123781411114016"></a>表示复位单板。</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-notice.gif) **须知:**
>**“go 0x80000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。
3. <a name="li448312542515"></a>输入**“reset”**指令并回车,重启单板,启动成功如下图,输入回车串口显示OHOS字样。
**图 2** 系统启动图<a name="fig14618415485"></a>
![](figures/系统启动图.png "系统启动图")
4. 根目录下,在命令行输入指令“**./bin/hello\_uart**”执行写入的demo程序,显示成功结果如下所示。
```
OHOS # ./bin/hello_uart
OHOS # HELLO UART!
```
## 下一步学习<a name="section9712145420182"></a>
恭喜,您已完成Hi3516 快速上手!建议您下一步进入[带屏摄像头产品开发](../guide/device-camera.md)的学习 。
# 运行Hello OHOS(编译、烧录)<a name="ZH-CN_TOPIC_0000001174270695"></a> # 运行<a name="ZH-CN_TOPIC_0000001216535389"></a>
- [新建应用程序](#section204672145202)
- [编译](#section1077671315253)
- [烧录](#section1347011412201)
- [使用网口烧录](#section1935410617363)
- [镜像运行](#section24721014162010)
- [执行应用程序](#section5276734182615)
本节指导开发者在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello OHOS!”。
## 新建应用程序<a name="section204672145202"></a>
1. 新建目录及源码
新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。
```
#include <stdio.h>
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":[] }
]
},
```
## 编译<a name="section1077671315253"></a>
如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/gettools-acquire.md#section107932281315)的编译操作。如果Linux编译环境通过软件包方式安装,请进入源码根目录,执行如下命令进行编译:
```
hb set(设置编译路径)
.(选择当前路径)
选择ipcamera_hispark_taurus@hisilicon并回车
hb build -f(执行编译)
```
**图 1** Hi3516编译设置图例<a name="fig1458988766"></a>
![](figures/Hi3516编译设置图例.png "Hi3516编译设置图例")
结果文件生成在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
## 烧录<a name="section1347011412201"></a>
Hi3516开发板的代码烧录支持USB烧录、网口烧录和串口烧录三种方式。此处仅以网口烧录为例进行说明。
### 使用网口烧录<a name="section1935410617363"></a>
Hi3516DV300开发板使用网口烧录方式,支持Windows和Linux系统。
1. 请连接好电脑和待烧录开发板,需要同时连接串口、网口和电源,具体可参考[Hi3516DV300开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3516-0000001152041033)
2. <a name="zh-cn_topic_0000001056443961_li142386399535"></a>打开电脑的设备管理器,查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:** - [镜像运行](#section11324753143912)
>如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - [下一步学习](#section9712145420182)
![](figures/hi3516-record-the-serial-port-number.png)
3. 打开DevEco Device Tool,在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/hi3516-deveco-device-tool-setting.png)
4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3516DV300开发板进行适配,无需单独修改。
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/hi3516-upload-options.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/ip-address-information.png) ## 镜像运行<a name="section11324753143912"></a>
8. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
9. 打开工程文件,点击![](figures/hi3516-deveco-device-tool-logo.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3516dv300下的**Upload**按钮,启动烧录。
![](figures/hi3516-upload-start-burning.png)
10. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。
![](figures/hi3516-restart-the-development-board.png)
11. 重新上电后,界面提示如下信息时,表示烧录成功。
![](figures/hi3516-burning-succeeded-net.png)
12. 烧录成功后,请根据镜像运行章节进行操作,启动系统。
### 镜像运行<a name="section24721014162010"></a>
在完成Hi3516DV300的烧录后,还需要设置BootLoader引导程序,才能运行OpenHarmony系统。 在完成Hi3516DV300的烧录后,还需要设置BootLoader引导程序,才能运行OpenHarmony系统。
...@@ -221,15 +22,12 @@ Hi3516DV300开发板使用网口烧录方式,支持Windows和Linux系统。 ...@@ -221,15 +22,12 @@ Hi3516DV300开发板使用网口烧录方式,支持Windows和Linux系统。
![](figures/monitor.png) ![](figures/monitor.png)
4. 然后根据界面提示进行操作,直到在界面打印**OHOS \#**信息,表示系统启动成功。 4. 当界面打印回显信息,点击Enter按钮,直到界面显示OHOS \#信息,表示系统启动成功。
![](figures/reboot_success.png) ![](figures/reboot_success.png)
## 执行应用程序<a name="section5276734182615"></a> ## 下一步学习<a name="section9712145420182"></a>
根目录下,在命令行输入指令“**./bin/helloworld**”执行写入的demo程序,显示成功结果如下图所示。
**图 2** 启动并成功执行应用程序图<a name="fig149821431194515"></a> 恭喜您,已完成Hi3516的快速上手!建议您下一步进入[带屏摄像头产品开发](../guide/device-iotcamera.md)的学习 。
![](figures/启动并成功执行应用程序图.png "启动并成功执行应用程序图")
# 安装开发板环境<a name="ZH-CN_TOPIC_0000001174270689"></a> # 安装开发板环境<a name="ZH-CN_TOPIC_0000001216693901"></a>
- [Hi3516工具要求](#section179175261196) - [Hi3516工具要求](#section179175261196)
- [硬件要求](#section5840424125014) - [硬件要求](#section5840424125014)
- [软件要求](#section965634210501) - [软件要求](#section965634210501)
- [安装Linux服务器工具](#section182916865219) - [安装Linux服务器工具](#section182916865219)
- [将Linux shell改为bash](#section1715027152617)
- [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251) - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251)
- [安装文件打包工具及Java虚拟机环境](#section16199102083717) - [安装文件打包工具及Java虚拟机环境](#section16199102083717)
...@@ -15,57 +14,37 @@ ...@@ -15,57 +14,37 @@
### 硬件要求<a name="section5840424125014"></a> ### 硬件要求<a name="section5840424125014"></a>
- Hi3516DV300 IoT Camera开发板 - Hi3516DV300 IoT Camera开发板
- USB转串口线、网线(Windows工作台通过USB转串口线、网线与Hi3516DV300 开发板连接) - USB转串口线、网线(Linux工作台通过USB转串口线、网线与Hi3516DV300 开发板连接)
各硬件连接关系如下图所示。
**图 1** Hi3516开发硬件连线图<a name="fig86246141414"></a>
![](figures/Hi3516开发硬件连线图.png "Hi3516开发硬件连线图")
### 软件要求<a name="section965634210501"></a> ### 软件要求<a name="section965634210501"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:** >![](../public_sys-resources/icon-notice.gif) **须知:**
>本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section182916865219)章节 >本节描述安装包方式搭建编译环境的操作步骤。如果使用Docker方式安装编译环境,请跳过此章节,直接从[新建应用程序](quickstart-lite-steps-hi3516-application-framework.md)开始操作
Hi3516开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 Hi3516开发板对Linux服务器通用环境配置需要的工具及其用途如下表所示。
**表 1** Linux服务器开发工具及获取途径 **表 1** Linux服务器开发工具及用途
<a name="table6299192712513"></a> <a name="table6299192712513"></a>
<table><thead align="left"><tr id="row122993276512"><th class="cellrowborder" valign="top" width="25.112511251125113%" id="mcps1.2.4.1.1"><p id="p1829914271858"><a name="p1829914271858"></a><a name="p1829914271858"></a>开发工具</p> <table><thead align="left"><tr id="row122993276512"><th class="cellrowborder" valign="top" width="62.4%" id="mcps1.2.3.1.1"><p id="p1829914271858"><a name="p1829914271858"></a><a name="p1829914271858"></a>开发工具</p>
</th> </th>
<th class="cellrowborder" valign="top" width="15.13151315131513%" id="mcps1.2.4.1.2"><p id="p429918274517"><a name="p429918274517"></a><a name="p429918274517"></a>用途</p> <th class="cellrowborder" valign="top" width="37.6%" id="mcps1.2.3.1.2"><p id="p429918274517"><a name="p429918274517"></a><a name="p429918274517"></a>用途</p>
</th>
<th class="cellrowborder" valign="top" width="59.75597559755976%" id="mcps1.2.4.1.3"><p id="p12997271757"><a name="p12997271757"></a><a name="p12997271757"></a>获取途径</p>
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody><tr id="row167343191518"><td class="cellrowborder" valign="top" width="25.112511251125113%" headers="mcps1.2.4.1.1 "><p id="p467443191517"><a name="p467443191517"></a><a name="p467443191517"></a>bash</p> <tbody><tr id="row14885193315201"><td class="cellrowborder" valign="top" width="62.4%" headers="mcps1.2.3.1.1 "><p id="p137174662119"><a name="p137174662119"></a><a name="p137174662119"></a>编译基础软件包(仅ubuntu 20+需要)</p>
</td>
<td class="cellrowborder" valign="top" width="15.13151315131513%" headers="mcps1.2.4.1.2 "><p id="p0674153114151"><a name="p0674153114151"></a><a name="p0674153114151"></a>命令行处理工具</p>
</td> </td>
<td class="cellrowborder" valign="top" width="59.75597559755976%" headers="mcps1.2.4.1.3 "><p id="p116746312151"><a name="p116746312151"></a><a name="p116746312151"></a>系统配置</p> <td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.2.3.1.2 "><p id="p258814561424"><a name="p258814561424"></a><a name="p258814561424"></a>编译依赖的基础软件包</p>
</td> </td>
</tr> </tr>
<tr id="row14885193315201"><td class="cellrowborder" valign="top" width="25.112511251125113%" headers="mcps1.2.4.1.1 "><p id="p137174662119"><a name="p137174662119"></a><a name="p137174662119"></a>编译基础软件包(仅ubuntu 20+需要)</p> <tr id="row52253812238"><td class="cellrowborder" valign="top" width="62.4%" headers="mcps1.2.3.1.1 "><p id="p28007392236"><a name="p28007392236"></a><a name="p28007392236"></a>dosfstools、mtools、mtd-utils</p>
</td> </td>
<td class="cellrowborder" valign="top" width="15.13151315131513%" headers="mcps1.2.4.1.2 "><p id="p258814561424"><a name="p258814561424"></a><a name="p258814561424"></a>编译依赖的基础软件包</p> <td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.2.3.1.2 "><p id="p98008390232"><a name="p98008390232"></a><a name="p98008390232"></a>文件打包工具</p>
</td>
<td class="cellrowborder" valign="top" width="59.75597559755976%" headers="mcps1.2.4.1.3 "><p id="p1749611716181"><a name="p1749611716181"></a><a name="p1749611716181"></a>通过互联网获取</p>
</td> </td>
</tr> </tr>
<tr id="row52253812238"><td class="cellrowborder" valign="top" width="25.112511251125113%" headers="mcps1.2.4.1.1 "><p id="p28007392236"><a name="p28007392236"></a><a name="p28007392236"></a>dosfstools、mtools、mtd-utils</p> <tr id="row29204072315"><td class="cellrowborder" valign="top" width="62.4%" headers="mcps1.2.3.1.1 "><p id="p5921190162318"><a name="p5921190162318"></a><a name="p5921190162318"></a>Java 虚拟机环境</p>
</td>
<td class="cellrowborder" valign="top" width="15.13151315131513%" headers="mcps1.2.4.1.2 "><p id="p98008390232"><a name="p98008390232"></a><a name="p98008390232"></a>文件打包工具</p>
</td> </td>
<td class="cellrowborder" valign="top" width="59.75597559755976%" headers="mcps1.2.4.1.3 "><p id="p280018394233"><a name="p280018394233"></a><a name="p280018394233"></a>通过apt-get install安装</p> <td class="cellrowborder" valign="top" width="37.6%" headers="mcps1.2.3.1.2 "><p id="p17921110152311"><a name="p17921110152311"></a><a name="p17921110152311"></a>编译、调试和运行Java程序</p>
</td>
</tr>
<tr id="row29204072315"><td class="cellrowborder" valign="top" width="25.112511251125113%" headers="mcps1.2.4.1.1 "><p id="p5921190162318"><a name="p5921190162318"></a><a name="p5921190162318"></a>Java虚拟机环境</p>
</td>
<td class="cellrowborder" valign="top" width="15.13151315131513%" headers="mcps1.2.4.1.2 "><p id="p17921110152311"><a name="p17921110152311"></a><a name="p17921110152311"></a>编译、调试和运行Java程序</p>
</td>
<td class="cellrowborder" valign="top" width="59.75597559755976%" headers="mcps1.2.4.1.3 "><p id="p16921805237"><a name="p16921805237"></a><a name="p16921805237"></a>通过apt-get install安装</p>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -73,33 +52,6 @@ Hi3516开发板对Linux服务器通用环境配置需要的工具及其获取途 ...@@ -73,33 +52,6 @@ Hi3516开发板对Linux服务器通用环境配置需要的工具及其获取途
## 安装Linux服务器工具<a name="section182916865219"></a> ## 安装Linux服务器工具<a name="section182916865219"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:**
>- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装hc-gen编译工具。
>- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。
### 将Linux shell改为bash<a name="section1715027152617"></a>
查看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+需要)<a name="section45512412251"></a> ### 安装编译依赖基础软件(仅Ubuntu 20+需要)<a name="section45512412251"></a>
执行以下命令进行安装: 执行以下命令进行安装:
...@@ -110,11 +62,9 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev ...@@ -110,11 +62,9 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev
### 安装文件打包工具及Java虚拟机环境<a name="section16199102083717"></a> ### 安装文件打包工具及Java虚拟机环境<a name="section16199102083717"></a>
1. 打开Linux编译服务器终端 运行如下命令,安装dosfstools、mtools、mtd-utils、Java运行时环境(JRE)和Java sdk 开发工具包。
2. 运行如下命令,安装dosfstools、mtools、mtd-utils、Java运行时环境(JRE)和Java sdk 开发工具包。
```
sudo apt-get install dosfstools mtools mtd-utils default-jre default-jdk
```
```
sudo apt-get install dosfstools mtools mtd-utils default-jre default-jdk
```
# Hi3516开发板<a name="ZH-CN_TOPIC_0000001128470852"></a> # Hi3516开发板<a name="ZH-CN_TOPIC_0000001217013857"></a>
- **[安装开发板环境](quickstart-lite-steps-hi3516-setting.md)** - **[安装开发板环境](quickstart-lite-steps-hi3516-setting.md)**
- **[运行Hello OHOS(编译、烧录)](quickstart-lite-steps-hi3516-running.md)** - **[新建应用程序](quickstart-lite-steps-hi3516-application-framework.md)**
- **[驱动开发示例](quickstart-lite-steps-hi3516-program.md)** - **[编译](quickstart-lite-steps-hi3516-building.md)**
- **[烧录](quickstart-lite-steps-hi3516-burn.md)**
- **[运行](quickstart-lite-steps-hi3516-running.md)**
- **[常见问题](quickstart-lite-steps-hi3516-faqs.md)** - **[常见问题](quickstart-lite-steps-hi3516-faqs.md)**
......
# 新建应用程序<a name="ZH-CN_TOPIC_0000001171615524"></a>
下方将通过修改源码的方式展示如何编写简单程序,输出“Hello OHOS!”。请在[获取源码](quickstart-lite-sourcecode-acquire.md)章节下载的源码目录中进行下述操作。
1. 新建目录及源码。
新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。
```
#include <stdio.h>
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":[] }
]
},
```
# 编译<a name="ZH-CN_TOPIC_0000001216935341"></a>
下方将介绍如何使用Hi3518开发板进行编译。使用安装包方式与docker方式搭建Ubuntu编译环境,编译命令相同。
1. 请进入源码根目录,执行如下命令进行编译:
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果使用Docker方式搭建编译环境,请在[获取Docker环境](quickstart-lite-docker-environment.md#section15666113905015)中进入的Docker构建环境中,执行如下命令进行编译。
```
hb set(设置编译路径)
.(选择当前路径)
选择ipcamera_hispark_aries并回车
hb build -f(执行编译)
```
**图 1** Hi3518编译设置图例-Docker方式<a name="fig6140152061211"></a>
![](figures/Hi3518编译设置图例-Docker方式.png "Hi3518编译设置图例-Docker方式")
2. 编译结束后,出现“ipcamera\_hispark\_aries build success”字样,则证明构建成功。
>![](../public_sys-resources/icon-notice.gif) **须知:**
>烧录相关文件获取路径:
>结果文件:out/hispark\_aries/ipcamera\_hispark\_aries。
>U-boot文件:device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin。
# 烧录<a name="ZH-CN_TOPIC_0000001216693905"></a>
- [前提条件](#section14614124417580)
- [使用串口烧录](#section195291211181215)
烧录是指将编译后的程序文件下载到芯片开发板上的动作,为后续的程序调试提供基础。DevEco Device Tool提供一键烧录功能,操作简单,能快捷、高效的完成程序烧录,提升烧录的效率。
DevEco Device Tool以插件方式运行,基于Visual Studio Code进行扩展,用户可点击Visual Studio Code左侧栏的![](figures/2021-01-27_170334.png)图标打开DevEco Device Tool。
Hi3518EV300开发板的代码烧录支持USB烧录和串口烧录两种方式,其中:
- **Windows系统:支持USB烧录和串口烧录。**
- **Linux系统:支持串口烧录**
Hi3861V100在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。
此处仅以Linux系统下串口烧录方式为例进行说明。
## 前提条件<a name="section14614124417580"></a>
1. 在DevEco Device Tool工具中点击**Import Project**导入新建应用程序章节修改后的源码文件。
![](figures/import-project.png)
2. 选择源码导入时,系统会提示该工程不是DevEco Device Tool工程,点击**Import**
![](figures/import-project-confirm.png)
3. MCU选择HiSilicom\_Arm下的Hi3518EV300,Board选择hi3518ev300,Framework选择Hb,然后点击**Import**完成导入。
![](figures/hi3518-import-projects.png)
## 使用串口烧录<a name="section195291211181215"></a>
1. 请连接好电脑和待烧录开发板,需要同时连接串口和电源口,具体可参考[Hi3518EV300开发板介绍](https://device.harmonyos.com/cn/docs/documentation/guide/quickstart-lite-introduction-hi3518-0000001105201138)
2. 查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。
Windows系统,打开设备管理器查看并记录对应的串口号,或在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/record-the-serial-port-number.png)
Linux系统,在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/Snap22.png)
3. 在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/zh-cn_image_0000001222981447.png)
4. 在“hi3518ev300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。
- upload\_port:选择已查询的串口号。
- upload\_protocol:选择烧录协议,固定选择“hiburn-serial”。
- upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。
![](figures/Snap24.png)
5. 分别检查待烧录文件的烧录信息,DevEco Device Tool已预置默认的烧录文件信息,可根据实际情况进行调整。待烧录文件包括:fastboot、kernel、rootfs和userfs。
1. 在“hi3518ev300\_fastboot”页签,在New Option选项中选择需要修改的项,例如partition\_bin(烧录文件路径)、partition\_addr(烧录文件起始地址)、partition\_length(烧录文件分区长度)等。
![](figures/zh-cn_image_0000001177301516.png)
2. 然后在Partition Options中,分别修改上述步骤中选择的修改项。
>![](../public_sys-resources/icon-note.gif) **说明:**
>在设置烧录分区起始地址和分区长度时,应根据实际待烧录文件的大小进行设置,遵循以下原则:
>- 要求设置的烧录分区大小,要大于待烧录文件的大小。
>- 同时,各烧录文件的分区地址设置不能出现重叠。
>- 总的烧录分区大小不能超过16MB。
![](figures/zh-cn_image_0000001222781271.png)
3. 按照相同的方法修改kernel、footfs和userfs的烧录文件信息。
6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
7. 点击**Open**打开工程文件,然后在“PROJECT TASKS”中,点击hi3518ev300下的**Upload**按钮,启动烧录。
![](figures/zh-cn_image_0000001117329380.png)
8. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。
![](figures/zh-cn_image_0000001074287476.png)
9. 重新上电后,界面提示如下信息时,表示烧录成功。
![](figures/zh-cn_image_0000001073838982.png)
10. 烧录成功后,请根据镜像运行章节进行操作,启动系统。
# 常见问题<a name="ZH-CN_TOPIC_0000001128311064"></a> # 常见问题<a name="ZH-CN_TOPIC_0000001216935339"></a>
- [烧写选择串口后,提示“Error: Opening COMxx: Access denied”](#section1498892119619) - [烧写选择串口后提示失败](#section1498892119619)
- [Windows电脑与单板网络连接失败](#section8512971816) - [Windows电脑与单板网络连接失败](#section8512971816)
- [烧写失败](#section1767804111198) - [烧写失败](#section1767804111198)
- [编译构建过程中,提示找不到“python”](#zh-cn_topic_0000001053466255_section1039835245619) - [编译构建过程中,提示找不到“python”](#zh-cn_topic_0000001053466255_section1039835245619)
- [串口无回显](#zh-cn_topic_0000001053466255_section14871149155911) - [串口无回显](#zh-cn_topic_0000001053466255_section14871149155911)
## 烧写选择串口后,提示“Error: Opening COMxx: Access denied”<a name="section1498892119619"></a> ## 烧写选择串口后提示失败<a name="section1498892119619"></a>
- **现象描述** - **现象描述**
点击烧写并选择串口后,出现“Error: Opening COMxx: Access denied” 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied
![](figures/Failed-to-open-the-serial-port.png) **图 1** 打开串口失败图<a name="zh-cn_topic_0000001053466255_fig066333283916"></a>
![](figures/打开串口失败图-1.png "打开串口失败图-1")
- **可能原因** - **可能原因**
串口已经被占用。 串口已经被占用。
- 解决方法 - **解决办法**
1. 按图依次选择下拉框,查找带有serial-xx的终端。
**图 2** 查找是否存在占用串口的终端<a name="zh-cn_topic_0000001053466255_fig165994164420"></a>
![](figures/查找是否存在占用串口的终端-2.png "查找是否存在占用串口的终端-2")
检查主机中可能占用该端口的工具,关闭即可。若是当前工具占用,可按以下步骤排查并关闭: 2. 点击标号中的垃圾桶图标,关闭串口。
1. 排查终端窗口列表,检查是否被monitor或其他终端占用。 **图 3** 关闭串口终端<a name="zh-cn_topic_0000001053466255_fig7911282453"></a>
![](figures/关闭串口终端-3.png "关闭串口终端-3")
![](figures/terminal-list.png) 3. 重新点击烧写,选择串口并开始烧写程序。
2. 找到占用,点击垃圾桶图标,关闭占用。 **图 4** 重新启动烧写任务<a name="zh-cn_topic_0000001053466255_fig1138624316485"></a>
![](figures/changjian1-4.png)
## Windows电脑与单板网络连接失败<a name="section8512971816"></a> ## Windows电脑与单板网络连接失败<a name="section8512971816"></a>
...@@ -35,8 +45,8 @@ ...@@ -35,8 +45,8 @@
点击烧写并选择串口后,无法获取文件。 点击烧写并选择串口后,无法获取文件。
**图 1** 网络不通,Hi3518单板无法获取文件<a name="zh-cn_topic_0000001053466255_fig5218920223"></a> **图 5** 网络不通,单板无法获取文件图<a name="zh-cn_topic_0000001053466255_fig5218920223"></a>
![](figures/网络不通-Hi3518单板无法获取文件.png "网络不通-Hi3518单板无法获取文件") ![](figures/网络不通-单板无法获取文件图-5.png "网络不通-单板无法获取文件图-5")
- **可能原因** - **可能原因**
...@@ -49,19 +59,23 @@ ...@@ -49,19 +59,23 @@
1. 检查网线是否连接。 1. 检查网线是否连接。
2. 点击Windows防火墙。 2. 点击Windows防火墙。
![](figures/hi3518-network-and-firewall-setting.png) **图 6** 网络防火墙设置图<a name="zh-cn_topic_0000001053466255_fig62141417794"></a>
![](figures/网络防火墙设置图-6.png "网络防火墙设置图-6")
3. 点击“允许应用通过防火墙”。 3. 点击“允许应用通过防火墙”。
![](figures/hi3518-firewall-and-network-protection.png) **图 7** 防火墙和网络保护界面图<a name="zh-cn_topic_0000001053466255_fig20703151111116"></a>
![](figures/防火墙和网络保护界面图-7.png "防火墙和网络保护界面图-7")
4. 查找Visual Studio Code应用。 4. 查找Visual Studio Code应用。
![](figures/hi3518-selecting-the-visual-studio-code-application.png) **图 8** 查找Visual Studio Code应用图<a name="zh-cn_topic_0000001053466255_fig462316612165"></a>
![](figures/查找Visual-Studio-Code应用图-8.png "查找Visual-Studio-Code应用图-8")
5. 勾选Visual Studio Code的专用和公用网络的访问权限。 5. 勾选Visual Studio Code的专用和公用网络的访问权限。
![](figures/hi3518-allowing-the-visual-studio-code-application-to-access-the-network.png) **图 9** 允许Visual Studio Code应用访问网络<a name="zh-cn_topic_0000001053466255_fig132725269184"></a>
![](figures/允许Visual-Studio-Code应用访问网络-9.png "允许Visual-Studio-Code应用访问网络-9")
## 烧写失败<a name="section1767804111198"></a> ## 烧写失败<a name="section1767804111198"></a>
...@@ -83,24 +97,18 @@ ...@@ -83,24 +97,18 @@
- **现象描述** - **现象描述**
![](figures/hi3518-error-for-not-finding-python.png) ![](figures/zh-cn_image_0000001171774086.png)
- **可能原因1**
没有装python。 - **可能原因**
- **解决办法**
请按照[安装Python环境](../quick-start/quickstart-lite-env-setup-linux.md)。
- **可能原因2** usr/bin目录下没有python软链接。
![](figures/hi3518-reason-no-python-soft-link.png) ![](figures/zh-cn_image_0000001171615534.png)
- **解决办法** - **解决办法**
usr/bin目录下没有python软链接,请运行以下命令: 请运行以下命令:
``` ```
# cd /usr/bin/ # cd /usr/bin/
...@@ -111,7 +119,7 @@ ...@@ -111,7 +119,7 @@
例: 例:
![](figures/hi3518-solution-set-python-soft-link.png) ![](figures/zh-cn_image_0000001216535401.png)
## 串口无回显<a name="zh-cn_topic_0000001053466255_section14871149155911"></a> ## 串口无回显<a name="zh-cn_topic_0000001053466255_section14871149155911"></a>
...@@ -151,10 +159,10 @@ ...@@ -151,10 +159,10 @@
2. 根据USB烧写步骤烧写U-boot文件。 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文件进行烧写。 按照[Hi3518系列USB烧写步骤](https://device.harmonyos.com/cn/docs/documentation/guide/hi3518_upload-0000001057313128)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。
3. 烧写完成后,登录串口如下图所示。 3. 烧写完成后,登录串口如下图所示。
![](figures/login-serial-port.png) ![](figures/zh-cn_image_0000001216535397.png)
# 运行Hello OHOS(编译、烧录)<a name="ZH-CN_TOPIC_0000001174350607"></a> # 运行<a name="ZH-CN_TOPIC_0000001217013853"></a>
- [新建应用程序](#section1550972416485) - [镜像运行](#section1081111115589)
- [编译](#section234175193114)
- [烧录](#section7609155824819)
- [镜像运行](#section17612105814480)
- [下一步学习](#section9712145420182) - [下一步学习](#section9712145420182)
本节指导开发者在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello OHOS!”。 ## 镜像运行<a name="section1081111115589"></a>
## 新建应用程序<a name="section1550972416485"></a>
1. 新建目录及源码
新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。
```
#include <stdio.h>
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":[] }
]
},
```
## 编译<a name="section234175193114"></a>
如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/gettools-acquire.md#section107932281315)的编译操作。如果Linux编译环境通过软件包方式安装,进入源码根目录,执行如下命令进行编译:
```
hb set(设置编译路径)
.(选择当前路径)
选择ipcamera_hispark_aries@hisilicon并回车
hb build -f(执行编译)
```
结果文件生成在out/hispark\_aries/ipcamera\_hispark\_aries目录下。
**图 1** Hi3518编译设置图例<a name="fig12982192583111"></a>
![](figures/Hi3518编译设置图例.png "Hi3518编译设置图例")
>![](../public_sys-resources/icon-notice.gif) **须知:**
>Hi3518EV300单板的U-boot文件获取路径:device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin
## 烧录<a name="section7609155824819"></a>
烧录是指将编译后的程序文件下载到芯片开发板上的动作,为后续的程序调试提供基础。DevEco Device Tool提供一键烧录功能,操作简单,能快捷、高效的完成程序烧录,提升烧录的效率。
Hi3518EV300开发板的代码烧录支持USB烧录和串口烧录两种方式,其中:
- **Windows系统:支持USB烧录和串口烧录。**
- **Linux系统:支持串口烧录,如果采用的是Linux+Windows双系统,也支持USB烧录。**
同一种烧录方式(如串口烧录),在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。
此处仅以USB烧录为例进行说明。
1. 请连接好电脑和待烧录开发板,需要同时连接串口和USB口,具体可参考[Hi3518EV300开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3518-0000001105201138)
2. <a name="zh-cn_topic_0000001057313128_li46411811196"></a>打开电脑的设备管理器,查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。
![](figures/hi3518-record-the-serial-port-number.png)
3. 打开DevEco Device Tool,在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/hi3518-deveco-device-tool-setting.png)
4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3518EV300开发板进行适配,无需单独修改。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果待烧录文件是直接通过拷贝的方式获取,需要手动修改待烧录文件的路径。打开待烧录文件的页签,在Partition Settings的New Opiton的下拉列表中,选择Partition\_bin,然后在Partition Opiton的Partition\_bin设置待烧录文件的路径。
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/upload-options.png)
6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
7. 打开工程文件,点击![](figures/hi3518-deveco-device-tool-logo.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3518ev300\_fastboot下的**Erase**按钮,擦除U-Boot。
![](figures/erase-u-Boot.png)
8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(下电再上电)。
![](figures/hi3518-restart-the-development-board.png)
9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。
![](figures/u-boot-erased-successfully.png)
10. 擦除完成后,点击hi3518ev300下的**Upload**按钮,启动烧录。
![](figures/hi3518-upload.png)
11. 启动烧录后,界面提示如下信息时,表示烧录成功。
![](figures/hi3518-burning-succeeded.png)
12. 烧录成功后,请根据镜像运行章节进行操作,启动系统。
## 镜像运行<a name="section17612105814480"></a>
在完成Hi3518EV300的烧录后,还需要设置BootLoader引导程序,才能运行OpenHarmony系统。 在完成Hi3518EV300的烧录后,还需要设置BootLoader引导程序,才能运行OpenHarmony系统。
...@@ -225,7 +22,7 @@ Hi3518EV300开发板的代码烧录支持USB烧录和串口烧录两种方式, ...@@ -225,7 +22,7 @@ Hi3518EV300开发板的代码烧录支持USB烧录和串口烧录两种方式,
![](figures/hi3518-monitor.png) ![](figures/hi3518-monitor.png)
4. 然后根据界面提示进行操作,直到在界面打印OHOS \#信息,表示系统启动成功。 4. 当界面打印回显信息,点击Enter按钮,直到界面显示OHOS \#信息,表示系统启动成功。
![](figures/hi3518-reboot-success.png) ![](figures/hi3518-reboot-success.png)
......
# 安装开发板环境<a name="ZH-CN_TOPIC_0000001128470862"></a> # 安装开发板环境<a name="ZH-CN_TOPIC_0000001171615526"></a>
- [Hi3518环境搭建](#section1724111409282) - [Hi3518环境搭建](#section1724111409282)
- [硬件要求](#section487353718276) - [硬件要求](#section487353718276)
- [软件要求](#section17315193935817) - [软件要求](#section17315193935817)
- [安装Linux服务器工具](#section8831868501) - [安装Linux服务器工具](#section8831868501)
- [将Linux shell改为bash](#section434110241084)
- [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section25911132141020) - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section25911132141020)
- [安装文件打包工具](#section390214473129) - [安装文件打包工具](#section390214473129)
...@@ -15,18 +14,12 @@ ...@@ -15,18 +14,12 @@
### 硬件要求<a name="section487353718276"></a> ### 硬件要求<a name="section487353718276"></a>
- Hi3518EV300 IoT Camera开发板 - Hi3518EV300 IoT Camera开发板
- USB转串口线、网线(Windows工作台通过USB转串口线、网线与开发板连接) - USB转串口线、网线(Linux工作台通过USB转串口线、网线与开发板连接)
各硬件连接关系如下图所示。
**图 1** Hi3518开发硬件连线图<a name="fig145521530134016"></a>
![](figures/Hi3518开发硬件连线图.png "Hi3518开发硬件连线图")
### 软件要求<a name="section17315193935817"></a> ### 软件要求<a name="section17315193935817"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:** >![](../public_sys-resources/icon-notice.gif) **须知:**
>本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section8831868501)章节 >本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节,从[新建应用程序](quickstart-lite-steps-hi3518-application-framework.md)开始操作
Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。
...@@ -41,14 +34,7 @@ Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途 ...@@ -41,14 +34,7 @@ Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody><tr id="row18630134151917"><td class="cellrowborder" valign="top" width="23.332333233323332%" headers="mcps1.2.4.1.1 "><p id="p1563113417199"><a name="p1563113417199"></a><a name="p1563113417199"></a>bash</p> <tbody><tr id="row7598468212"><td class="cellrowborder" valign="top" width="23.332333233323332%" headers="mcps1.2.4.1.1 "><p id="p659815642111"><a name="p659815642111"></a><a name="p659815642111"></a>编译基础软件包(仅ubuntu 20+需要)</p>
</td>
<td class="cellrowborder" valign="top" width="14.65146514651465%" headers="mcps1.2.4.1.2 "><p id="p463193418190"><a name="p463193418190"></a><a name="p463193418190"></a>命令行处理工具</p>
</td>
<td class="cellrowborder" valign="top" width="62.016201620162015%" headers="mcps1.2.4.1.3 "><p id="p1063118344191"><a name="p1063118344191"></a><a name="p1063118344191"></a>系统配置</p>
</td>
</tr>
<tr id="row7598468212"><td class="cellrowborder" valign="top" width="23.332333233323332%" headers="mcps1.2.4.1.1 "><p id="p659815642111"><a name="p659815642111"></a><a name="p659815642111"></a>编译基础软件包(仅ubuntu 20+需要)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="14.65146514651465%" headers="mcps1.2.4.1.2 "><p id="p137174662119"><a name="p137174662119"></a><a name="p137174662119"></a>编译依赖的基础软件包</p> <td class="cellrowborder" valign="top" width="14.65146514651465%" headers="mcps1.2.4.1.2 "><p id="p137174662119"><a name="p137174662119"></a><a name="p137174662119"></a>编译依赖的基础软件包</p>
</td> </td>
...@@ -67,33 +53,6 @@ Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途 ...@@ -67,33 +53,6 @@ Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途
## 安装Linux服务器工具<a name="section8831868501"></a> ## 安装Linux服务器工具<a name="section8831868501"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:**
>- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装hc-gen编译工具。
>- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。
### 将Linux shell改为bash<a name="section434110241084"></a>
查看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+需要)<a name="section25911132141020"></a> ### 安装编译依赖基础软件(仅Ubuntu 20+需要)<a name="section25911132141020"></a>
执行以下命令进行安装: 执行以下命令进行安装:
...@@ -104,11 +63,9 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev ...@@ -104,11 +63,9 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev
### 安装文件打包工具<a name="section390214473129"></a> ### 安装文件打包工具<a name="section390214473129"></a>
1. 打开Linux编译服务器终端。 运行如下命令,安装dosfstools,mtools,mtd-utils。
2. 运行如下命令,安装dosfstools,mtools,mtd-utils。
```
sudo apt-get install dosfstools mtools mtd-utils
```
```
sudo apt-get install dosfstools mtools mtd-utils
```
# Hi3518开发板<a name="ZH-CN_TOPIC_0000001128311052"></a> # Hi3518开发板<a name="ZH-CN_TOPIC_0000001216535385"></a>
- **[安装开发板环境](quickstart-lite-steps-hi3518-setting.md)** - **[安装开发板环境](quickstart-lite-steps-hi3518-setting.md)**
- **[运行Hello OHOS(编译、烧录)](quickstart-lite-steps-hi3518-running.md)** - **[新建应用程序](quickstart-lite-steps-hi3518-application-framework.md)**
- **[编译](quickstart-lite-steps-hi3518-building.md)**
- **[烧录](quickstart-lite-steps-hi3518-burn.md)**
- **[运行](quickstart-lite-steps-hi3518-running.md)**
- **[常见问题](quickstart-lite-steps-hi3518-faqs.md)** - **[常见问题](quickstart-lite-steps-hi3518-faqs.md)**
......
# 运行<a name="ZH-CN_TOPIC_0000001171774076"></a>
- [运行结果](#section18115713118)
- [下一步学习](#section9712145420182)
## 运行结果<a name="section18115713118"></a>
示例代码编译、烧录、运行、调测后,重启开发板后将自动在界面输出如下结果:
```
ready to OS start
FileSystem mount ok.
wifi init success!
[DEMO] Hello world.
```
## 下一步学习<a name="section9712145420182"></a>
恭喜,您已完成Hi3861开发板快速上手!建议您下一步进入[WLAN产品开发](../guide/device-wlan-led-control.md)的学习 。
# 运行Hello World<a name="ZH-CN_TOPIC_0000001128311062"></a> # 新建应用程序<a name="ZH-CN_TOPIC_0000001216535387"></a>
- [修改源码](#section79601457101015) 下方将通过修改源码的方式展示如何编写简单程序,输出“Hello world.”。请在[获取源码](quickstart-lite-sourcecode-acquire.md)章节下载的源码目录中进行下述操作。
- [调测验证](#section1621064881419)
- [printf打印](#section5204547123316)
- [根据asm文件进行问题定位](#section15919111423416)
- [运行结果](#section18115713118)
- [下一步学习](#section9712145420182)
本示例将演示如何编写简单业务,输出“Hello World”,初步了解OpenHarmony如何运行在开发板上。
## 修改源码<a name="section79601457101015"></a>
bugfix和新增业务两种情况,涉及源码修改。下面以新增业务(my\_first\_app)为例,向开发者介绍如何进行源码修改。
1. <a name="li5479332115116"></a>确定目录结构。 1. <a name="li5479332115116"></a>确定目录结构。
...@@ -87,73 +75,3 @@ bugfix和新增业务两种情况,涉及源码修改。下面以新增业务 ...@@ -87,73 +75,3 @@ bugfix和新增业务两种情况,涉及源码修改。下面以新增业务
- myapp是目标,指向./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn中的static\_library\("myapp"\)。 - myapp是目标,指向./applications/sample/wifi-iot/app/my\_first\_app/BUILD.gn中的static\_library\("myapp"\)。
## 调测验证<a name="section1621064881419"></a>
目前调试验证的方法有两种,分别为通过printf打印日志、通过asm文件定位panic问题,开发者可以根据具体业务情况选择。
由于本示例业务简单,采用printf打印日志的调试方式即可。下面开始介绍这两种调试手段的使用方法。
### printf打印<a name="section5204547123316"></a>
代码中增加printf维测,信息会直接打印到串口上。开发者可在业务关键路径或业务异常位置增加日志打印,如下所示。
```
void HelloWorld(void)
{
printf("[DEMO] Hello world.\n");
}
```
### 根据asm文件进行问题定位<a name="section15919111423416"></a>
系统异常退出时,会在串口上打印异常退出原因调用栈信息,如下文所示。通过解析异常栈信息可以定位异常位置。
```
=======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/WadRecvCB-function.png)
4. 完成代码排查及修改。
## 运行结果<a name="section18115713118"></a>
示例代码编译、烧录、运行、调测后,在串口界面会显示如下结果:
```
ready to OS start
FileSystem mount ok.
wifi init success!
[DEMO] Hello world.
```
## 下一步学习<a name="section9712145420182"></a>
恭喜,您已完成Hi3861 WLAN模组快速上手!建议您下一步进入[WLAN产品开发](../guide/device-wlan.md)的学习 。
# 编译<a name="ZH-CN_TOPIC_0000001171455552"></a>
- [编译(Docker方式搭建环境)](#section681942105819)
- [编译(安装包方式搭建环境)](#section17726113335715)
本节描述如何进行Hi3861 开发板的编译,根据上方搭建Ubuntu环境方式的不同,编译方式也有所区别。
- 如果Ubuntu编译环境通过Docker方式安装,请参见下方[编译(Docker方式搭建环境)](#section681942105819)
- 如果Ubuntu编译环境通过安装包方式安装,请参见下方[编译(安装包方式搭建环境)](#section17726113335715)
## 编译(Docker方式搭建环境)<a name="section681942105819"></a>
1. 请在[获取Docker环境](quickstart-lite-docker-environment.md#section15666113905015)中进入的Docker构建环境中,执行如下命令进行编译:
```
hb set(设置编译路径)
.(选择当前路径)
选择wifiiot_hispark_pegasus@hisilicon并回车
hb build -f(执行编译)
```
**图 1** Hi3861编译设置图例-Docker方式<a name="fig129467368177"></a>
![](figures/Hi3861编译设置图例-Docker方式.png "Hi3861编译设置图例-Docker方式")
2. 编译结束后,出现“wifiiot\_hispark\_pegasus build success”字样,则证明构建成功。
>![](../public_sys-resources/icon-notice.gif) **须知:**
>烧录结果文件文件获取路径:out/hispark\_pegasus/wifiiot\_hispark\_pegasus。
## 编译(安装包方式搭建环境)<a name="section17726113335715"></a>
1. 打开DevEco Device Tool工具,点击“View \> Terminal”,进入终端界面。
**图 2** IDE终端工具打开方法<a name="fig1975813338510"></a>
![](figures/1.png)
2. 进入代码根路径,并在终端窗口,执行脚本命令“hb set”、“.”,选择需要编译的版本“wifiiot\_hispark\_pegasus”。
**图 3** 在终端界面选择目标构建版本示意图<a name="fig17727115215612"></a>
![](figures/3.png)
3. 执行“hb build”启动版本构建。
**图 4** 在终端界面执行编译命令示意图<a name="fig5493164414573"></a>
![](figures/4.png)
4. 编译结束后,如果出现“wifiiot\_hispark\_pegasus build success”字样,则证明构建成功,如下图所示。
**图 5** 编译成功示意图<a name="fig1262101218463"></a>
![](figures/5.png)
5. 构建成功后,会在./out/wifiiot/路径中生成以下文件,使用如下命令可以查看,至此编译构建流程结束。
```
ls -l out/hispark_pegasus/wifiiot_hispark_pegasus/
```
**图 6** 编译文件存放目录示意图<a name="fig38521346164618"></a>
![](figures/3-0.png)
# 烧录<a name="ZH-CN_TOPIC_0000001171934014"></a>
- [前提条件](#section1535374111495)
- [使用串口烧录](#section5551201122719)
烧录是指将编译后的程序文件下载到芯片开发板上的动作,为后续的程序调试提供基础。DevEco Device Tool提供一键烧录功能,操作简单,能快捷、高效的完成程序烧录,提升烧录的效率。
DevEco Device Tool以插件方式运行,基于Visual Studio Code进行扩展,用户可点击Visual Studio Code左侧栏的![](figures/2021-01-27_170334.png)图标打开DevEco Device Tool。
**Hi3861V100开发板支持串口烧录方式,Linux系统串口烧录协议为hiburn-serial。**具体操作步骤如下:
## 前提条件<a name="section1535374111495"></a>
1. 在DevEco Device Tool工具中点击**Import Project**导入新建应用程序章节修改后的源码文件。
![](figures/import-project.png)
2. 选择源码导入时,系统会提示该工程不是DevEco Device Tool工程,点击**Import**
![](figures/import-project-confirm.png)
3. MCU选择Hi3861,Board选择Hi3861,Framework选择Hb,然后点击**Import**完成导入。
![](figures/hi3861-import-projects.png)
## 使用串口烧录<a name="section5551201122719"></a>
1. 请连接好电脑和待烧录开发板,需要连接USB口,具体可参考[Hi3861V100开发板介绍](https://device.harmonyos.com/cn/docs/documentation/guide/quickstart-lite-introduction-hi3861-0000001105041324)[Hi3861V100开发板介绍](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3861.md)。
2. 查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果对应的串口异常,请根据[Hi3861V100开发板串口驱动安装](https://device.harmonyos.com/cn/docs/documentation/guide/hi3861-drivers-0000001058153433)安装USB转串口的驱动程序。
Window系统,打开设备管理器查看并记录对应的串口号,或在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/hi3861-record-the-serial-port-number.png)
Linux系统,在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/Snap23.png)
3. 在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/zh-cn_image_0000001222999125.png)
4. 在“hi3861”页签,设置烧录选项,包括upload\_port、upload\_protocol和upload\_partitions。
- upload\_port:选择已查询的串口号。
- upload\_protocol:选择烧录协议,选择“hiburn-serial”。
- upload\_partitions:选择待烧录的文件,默认选择hi3861\_app。
![](figures/zh-cn_image_0000001177798424.png)
5. 检查待烧录文件的烧录信息,DevEco Device Tool已预置默认的烧录文件信息,可根据实际情况进行调整。
1. 在“hi3861\_app”页签,在New Option选项中选择需要修改的项,例如partition\_bin(烧录文件路径)、partition\_addr(烧录文件起始地址)、partition\_length(烧录文件分区长度)等。
![](figures/zh-cn_image_0000001177480146.png)
2. 然后在Partition Options中,分别修改上述步骤中选择的修改项。
>![](../public_sys-resources/icon-note.gif) **说明:**
>在设置烧录分区起始地址和分区长度时,应根据实际待烧录文件的大小进行设置,要求设置的烧录分区大小,要大于待烧录文件的大小。
![](figures/zh-cn_image_0000001223000051.png)
6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
7. 点击**Open**打开工程文件,然后在“PROJECT TASKS”中,点击hi3861下的**Upload**按钮,启动烧录。
![](figures/hi3861-upload.png)
8. 启动烧录后,显示如下提示信息时,请按开发板上的RST按钮重启开发板。
![](figures/zh-cn_image_0000001174595590.png)
9. 重新上电后,界面提示如下信息时,表示烧录成功。
![](figures/hi3861-burning-succeeded.png)
# WLAN联网(编译、烧录)<a name="ZH-CN_TOPIC_0000001174350611"></a>
- [编译](#section191121332125319)
- [镜像烧录](#section3288165814218)
- [WLAN模组联网](#section194671619167)
本示例将演示如何通过AT命令完成WLAN模组与网关联网。
## 编译<a name="section191121332125319"></a>
本节描述如何在Linux服务器上进行WLAN模组版本的编译。
如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/gettools-acquire.md#section107932281315)的编译操作。如果Linux编译环境通过软件包方式安装,请参考如下步骤。
1. 打开DevEco Device Tool工具,点击“View \> Terminal”,进入终端界面。
**图 1** IDE终端工具打开方法<a name="fig755583241511"></a>
![](figures/IDE终端工具打开方法.png "IDE终端工具打开方法")
在终端界面使用ssh命令连接linux服务器,如“ssh user@ipaddr”。
**图 2** 终端界面示意图<a name="fig14407256101510"></a>
![](figures/终端界面示意图.png "终端界面示意图")
2. 进入代码根路径,并在终端窗口,执行脚本命令“hb set”、“.”,选择需要编译的版本“wifiiot\_hispark\_pegasus”。
**图 3** 在终端界面选择目标构建版本示意图<a name="fig191035701814"></a>
![](figures/在终端界面选择目标构建版本示意图.png "在终端界面选择目标构建版本示意图")
3. 执行“hb build”启动版本构建。
**图 4** 在终端界面执行编译命令示意图<a name="fig10635942111916"></a>
![](figures/在终端界面执行编译命令示意图.png "在终端界面执行编译命令示意图")
4. 编译结束后,如果出现“wifiiot\_hispark\_pegasus build success”字样,则证明构建成功,如下图所示。
**图 5** 编译成功示意图<a name="fig195291328182015"></a>
![](figures/编译成功示意图.png "编译成功示意图")
5. 构建成功后,会在./out/wifiiot/路径中生成以下文件,使用如下命令可以查看,至此编译构建流程结束。
```
ls -l out/hispark_pegasus/wifiiot_hispark_pegasus/
```
**图 6** 编译文件存放目录示意图<a name="fig112257131214"></a>
![](figures/编译文件存放目录示意图.png "编译文件存放目录示意图")
## 镜像烧录<a name="section3288165814218"></a>
烧录是指将编译后的程序文件下载到芯片开发板上的动作,为后续的程序调试提供基础。DevEco Device Tool提供一键烧录功能,操作简单,能快捷、高效的完成程序烧录,提升烧录的效率。
**Hi3861V100开发板支持串口烧录方式,其中Windows系统串口烧录协议包括burn-serial和hiburn-serial,Linux系统串口烧录协议为hiburn-serial。**
>![](../public_sys-resources/icon-note.gif) **说明:**
>Windows下的两种烧录协议**burn-serial**和**hiburn-serial**,在操作上没有区别,**burn-serial**协议主要是为了兼容历史版本工程。
Hi3861V100在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。
1. 请连接好电脑和待烧录开发板,需要连接USB口,具体可参考[Hi3861V100开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3861-0000001105041324)
2. 打开电脑的设备管理器,查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果对应的串口异常,请根据[Hi3861V100开发板串口驱动安装](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3861-drivers-0000001058153433)安装USB转串口的驱动程序。
![](figures/hi3861-record-the-serial-port-number.png)
3. 打开DevEco Device Tool,在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/hi3861-deveco-device-tool-setting.png)
4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3861V100开发板进行适配,无需单独修改。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果待烧录文件是直接通过拷贝的方式获取,需要手动修改待烧录文件的路径。打开待烧录文件的页签,在Partition Settings的New Opiton的下拉列表中,选择Partition\_bin,然后在Partition Opiton的Partition\_bin设置待烧录文件的路径。
5. 在“hi3861”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。
- upload\_port:选择步骤2中查询的串口号。
- upload\_protocol:选择烧录协议,Windows系统可以选择“burn-serial”或“hiburn-serial”,Linux系统只能选择“hiburn-serial”。
- upload\_partitions:选择待烧录的文件,默认选择hi3861\_app。
![](figures/options.png)
6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
7. 打开工程文件,在DevEco Device Tool界面的“PROJECT TASKS”中,点击hi3861下的**Upload**按钮,启动烧录。
![](figures/hi3861-upload.png)
8. 启动烧录后,显示如下提示信息时,请按开发板上的RST按钮重启开发板。
![](figures/hi3861-restart-the-development-board.png)
9. 重新上电后,界面提示如下信息时,表示烧录成功。
![](figures/hi3861-burning-succeeded.png)
## WLAN模组联网<a name="section194671619167"></a>
完成版本构建及烧录后,下面开始介绍如何在串口终端上执行AT命令,使WLAN模组联网。
1. 保持Windows工作台和WLAN模组的连接状态,在DevEco工具最下方,点击“DevEco:Serial Monitor”按钮。
**图 7** 打开DevEco串口终端示意图<a name="fig464411253297"></a>
![](figures/打开DevEco串口终端示意图.png "打开DevEco串口终端示意图")
2. 复位WLAN模组,终端界面显示“ready to OS start”,则启动成功。
**图 8** WLAN复位成功示意图<a name="fig3327108143016"></a>
![](figures/WLAN复位成功示意图.png "WLAN复位成功示意图")
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模组联网成功示意图<a name="fig7672858203010"></a>
![](figures/WLAN模组联网成功示意图.png "WLAN模组联网成功示意图")
# 调试验证<a name="ZH-CN_TOPIC_0000001171774082"></a>
- [printf打印](#section42891145143811)
- [根据asm文件进行问题定位](#section754719373917)
完成烧录之后,用户可根据需要进行调试验证。目前调试验证的方法有以下两种,开发者可以根据具体业务情况选择。
1. 通过printf打印日志
2. 通过asm文件定位panic问题
由于本示例业务简单,采用printf打印日志的调试方式即可。下方将介绍这两种调试手段的使用方法。
## printf打印<a name="section42891145143811"></a>
代码中增加printf维测,信息会直接打印到串口上。开发者可在业务关键路径或业务异常位置增加日志打印,如下所示:
```
void HelloWorld(void)
{
printf("[DEMO] Hello world.\n");
}
```
## 根据asm文件进行问题定位<a name="section754719373917"></a>
系统异常退出时,会在串口上打印异常退出原因调用栈信息,如下文所示。通过解析异常栈信息可以定位异常位置。
```
=======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_0000001185334336.png)
4. 完成代码排查及修改。
# 常见问题<a name="ZH-CN_TOPIC_0000001128311054"></a> # 常见问题<a name="ZH-CN_TOPIC_0000001171934016"></a>
- [安装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 'Crypto'”](#section982315398121)
- [编译构建过程中,提示“No module named 'ecdsa'”](#section102035451216) - [编译构建过程中,提示“No module named 'ecdsa'”](#section102035451216)
- [编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0”](#section4498158162320) - [编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0”](#section4498158162320)
- [编译构建过程中,提示找不到“-lgcc”](#section11181036112615) - [编译构建过程中,提示找不到“-lgcc”](#section11181036112615)
- [编译构建过程中,提示找不到“python”](#section1571810194619) - [编译构建过程中,提示找不到“python”](#section1571810194619)
- [编译构建过程中,提示找不到“python3”](#section108385316482) - [编译构建过程中,提示找不到“python3”](#section108385316482)
- [安装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)
- [安装 kconfiglib时,遇到lsb\_release错误](#section691681635814) - [安装 kconfiglib时,遇到lsb\_release错误](#section691681635814)
## 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”<a name="section1221016541119"></a>
- **现象描述**
安装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”<a name="section1913477181213"></a>
- **现象描述**
安装python3过程中出现以下错误:
```
-bash: make: command not found
```
- **可能原因**
环境中未安装“make”。
- **解决办法**
1、通过命令“apt-get install make”在线安装。
2、完成后,重新安装python3。
## 安装python3过程中,提示“zlib not available”<a name="section108211415131210"></a>
- **现象描述**
安装python3过程中出现以下错误:
```
zipimport.ZipImportError: can't decompress data; zlib not available
```
- **可能原因**
环境中未安装“zlib”。
- **解决办法**
方法1:通过命令“apt-get install zlib”在线安装。
方法2:如果软件源中没有该软件,请从“www.zlib.net”下载版本代码,并离线安装。
![](figures/download-zlib.png)
完成下载后,通过以下命令安装:
```
# tar xvf zlib-1.2.11.tar.gz
# cd zlib-1.2.11
# ./configure
# make && make install
```
完成后,重新安装python3。
## 安装python3过程中,提示“No module named '\_ctypes'”<a name="section2062268124"></a>
- **现象描述**
安装python3过程中出现以下错误:
```
ModuleNotFoundError:No module named ‘_ctypes’
```
- **可能原因**
环境中未安装“libffi”和“libffi-devel”。
- **解决办法**
1、通过命令“apt-get install libffi\* -y”,在线安装。
2、完成后,重新安装python3。
## 编译构建过程中,提示“No module named 'Crypto'”<a name="section982315398121"></a> ## 编译构建过程中,提示“No module named 'Crypto'”<a name="section982315398121"></a>
- **现象描述** - **现象描述**
...@@ -131,11 +32,11 @@ ...@@ -131,11 +32,11 @@
方法1:通过命令“pip3 install Crypto”,在线安装。 方法1:通过命令“pip3 install Crypto”,在线安装。
方法2:离线安装 方法2:离线安装
通过网页[https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files),下载源码。 通过网页[https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files),下载源码。
![](figures/Download-the-source-code.png) ![](figures/zh-cn_image_0000001171615542.png)
将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”。 将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”。
...@@ -166,7 +67,7 @@ ...@@ -166,7 +67,7 @@
通过网页[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files),下载安装包。 通过网页[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files),下载安装包。
![](figures/download-ecdsa.png) ![](figures/zh-cn_image_0000001171455574.png)
将安装包放置Linux服务器中,并安装“pip3 install ecdsa-0.15-py2.py3-none-any.whl”。 将安装包放置Linux服务器中,并安装“pip3 install ecdsa-0.15-py2.py3-none-any.whl”。
...@@ -193,11 +94,11 @@ ...@@ -193,11 +94,11 @@
方法1:通过命令“pip3 install six”,在线安装。 方法1:通过命令“pip3 install six”,在线安装。
方法2:离线安装 方法2:离线安装
通过网页[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files),下载安装包。 通过网页[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files),下载安装包。
![](figures/download-six.png) ![](figures/zh-cn_image_0000001217013871.png)
将源码放置在Linux服务器中,并安装“pip3 install six-1.14.0-py2.py3-none-any.whl”。 将源码放置在Linux服务器中,并安装“pip3 install six-1.14.0-py2.py3-none-any.whl”。
...@@ -250,15 +151,21 @@ ...@@ -250,15 +151,21 @@
- **解决办法** - **解决办法**
请按照[安装Python环境](../quick-start/quickstart-lite-env-setup-linux.md) 请使用如下命令安装Python,下方以Python3.8为例。
```
sudo apt-get install python3.8
```
- **可能原因2** - **可能原因2**
![](figures/reason-no-python-soft-link.png) usr/bin目录下没有python软链接
![](figures/zh-cn_image_0000001171774098.png)
- **解决办法** - **解决办法**
usr/bin目录下没有python软链接,请运行以下命令添加软链接: 请运行以下命令添加软链接:
``` ```
# cd /usr/bin/ # cd /usr/bin/
...@@ -269,7 +176,7 @@ ...@@ -269,7 +176,7 @@
例: 例:
![](figures/solution-add-soft-link.png) ![](figures/zh-cn_image_0000001171934032.png)
## 编译构建过程中,提示找不到“python3”<a name="section108385316482"></a> ## 编译构建过程中,提示找不到“python3”<a name="section108385316482"></a>
...@@ -285,7 +192,106 @@ ...@@ -285,7 +192,106 @@
- **解决办法** - **解决办法**
请按照[安装python](../quick-start/quickstart-lite-env-setup-linux.md)。 请使用如下命令安装Python3。
```
sudo apt-get install python3.8
```
## 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”<a name="section1221016541119"></a>
- **现象描述**
安装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”<a name="section1913477181213"></a>
- **现象描述**
安装python3过程中出现以下错误:
```
-bash: make: command not found
```
- **可能原因**
环境中未安装“make”。
- **解决办法**
1. 通过命令“apt-get install make”在线安装。
2. 完成后,重新安装python3。
## 安装python3过程中,提示“zlib not available”<a name="section108211415131210"></a>
- **现象描述**
安装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'”<a name="section2062268124"></a>
- **现象描述**
安装python3过程中出现以下错误:
```
ModuleNotFoundError:No module named ‘_ctypes’
```
- **可能原因**
环境中未安装“libffi”和“libffi-devel”。
- **解决办法**
1、通过命令“apt-get install libffi\* -y”,在线安装。
2、完成后,重新安装python3。
## 安装 kconfiglib时,遇到lsb\_release错误<a name="section691681635814"></a> ## 安装 kconfiglib时,遇到lsb\_release错误<a name="section691681635814"></a>
...@@ -300,10 +306,10 @@ ...@@ -300,10 +306,10 @@
- **可能原因** - **可能原因**
lsb\_release模块基于的python版本与现有python版本不一致 lsb\_release模块基于的python版本与现有python版本不一致
- **解决办法** - **解决办法**
执行"find / -name lsb\_release",找到lsb\_release位置并删除,如:"sudo rm -rf /usr/bin/lsb\_release" 执行"find / -name lsb\_release",找到lsb\_release位置并删除,如:"sudo rm -rf /usr/bin/lsb\_release"
# 安装开发板环境<a name="ZH-CN_TOPIC_0000001174270691"></a> # 安装开发板环境<a name="ZH-CN_TOPIC_0000001216935343"></a>
- [Hi3861工具要求](#section466851916410) - [Hi3861工具要求](#section466851916410)
- [硬件要求](#section19202111020215) - [硬件要求](#section19202111020215)
...@@ -10,85 +10,49 @@ ...@@ -10,85 +10,49 @@
- [安装python模块](#section88701892341) - [安装python模块](#section88701892341)
- [安装gcc\_riscv32(WLAN模组类编译工具链)](#section34435451256) - [安装gcc\_riscv32(WLAN模组类编译工具链)](#section34435451256)
- [安装USB转串口驱动](#section1027732411513)
## Hi3861工具要求<a name="section466851916410"></a> ## Hi3861工具要求<a name="section466851916410"></a>
### 硬件要求<a name="section19202111020215"></a> ### 硬件要求<a name="section19202111020215"></a>
- Linux服务器 - Linux工作台
- Windows工作台(主机电脑) - Hi3861开发板
- Hi3861 WLAN模组 - USB Type-C线(Linux工作台通过USB与Hi3861开发板连接)
- USB Type-C线(Windows工作台通过USB与Hi3861 WLAN模组连接)
各硬件连接关系如下图所示。
**图 1** Hi3861开发硬件连线图<a name="fig285519359396"></a>
![](figures/Hi3861开发硬件连线图.png "Hi3861开发硬件连线图")
### 软件要求<a name="section727451210318"></a> ### 软件要求<a name="section727451210318"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:** >![](../public_sys-resources/icon-notice.gif) **须知:**
>本节描述采用安装包方式安装相关工具的操作步骤。如果是Docker方式安装,无需安装[表1](#table6299192712513)中的Linux服务器相关工具,只需安装Windows工作台工具即可 >本节描述采用安装包方式安装相关工具的操作步骤。如果使用Docker方式安装,无需安装[表1](#table6299192712513)中的相关工具,请直接从[新建应用程序](quickstart-lite-steps-hi3861-application-framework.md)开始操作
Hi3861开发板需要的工具如下表所示。 Hi3861开发板需要的工具如下表所示。
**表 1** Hi3861开发板需要的工具 **表 1** Hi3861开发板需要安装的工具
<a name="table6299192712513"></a> <a name="table6299192712513"></a>
<table><thead align="left"><tr id="row122993276512"><th class="cellrowborder" valign="top" width="17.54%" id="mcps1.2.5.1.1"><p id="p162491657102110"><a name="p162491657102110"></a><a name="p162491657102110"></a>平台类型</p> <table><thead align="left"><tr id="row122993276512"><th class="cellrowborder" valign="top" width="51.15%" id="mcps1.2.3.1.1"><p id="p1829914271858"><a name="p1829914271858"></a><a name="p1829914271858"></a>开发工具</p>
</th>
<th class="cellrowborder" valign="top" width="23.59%" id="mcps1.2.5.1.2"><p id="p1829914271858"><a name="p1829914271858"></a><a name="p1829914271858"></a>开发工具</p>
</th>
<th class="cellrowborder" valign="top" width="22.58%" id="mcps1.2.5.1.3"><p id="p429918274517"><a name="p429918274517"></a><a name="p429918274517"></a>用途</p>
</th> </th>
<th class="cellrowborder" valign="top" width="36.29%" id="mcps1.2.5.1.4"><p id="p12997271757"><a name="p12997271757"></a><a name="p12997271757"></a>获取途径</p> <th class="cellrowborder" valign="top" width="48.85%" id="mcps1.2.3.1.2"><p id="p429918274517"><a name="p429918274517"></a><a name="p429918274517"></a>用途</p>
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody><tr id="row935218593572"><td class="cellrowborder" valign="top" width="17.54%" headers="mcps1.2.5.1.1 "><p id="p105554418586"><a name="p105554418586"></a><a name="p105554418586"></a>Linux服务器</p> <tbody><tr id="row935218593572"><td class="cellrowborder" valign="top" width="51.15%" headers="mcps1.2.3.1.1 "><p id="p45551740589"><a name="p45551740589"></a><a name="p45551740589"></a>编译基础软件包(仅ubuntu 20+需要)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="23.59%" headers="mcps1.2.5.1.2 "><p id="p45551740589"><a name="p45551740589"></a><a name="p45551740589"></a>编译基础软件包(仅ubuntu 20+需要)</p> <td class="cellrowborder" valign="top" width="48.85%" headers="mcps1.2.3.1.2 "><p id="p655594115814"><a name="p655594115814"></a><a name="p655594115814"></a>编译依赖的基础软件包</p>
</td>
<td class="cellrowborder" valign="top" width="22.58%" headers="mcps1.2.5.1.3 "><p id="p655594115814"><a name="p655594115814"></a><a name="p655594115814"></a>编译依赖的基础软件包</p>
</td>
<td class="cellrowborder" valign="top" width="36.29%" headers="mcps1.2.5.1.4 "><p id="p165558415589"><a name="p165558415589"></a><a name="p165558415589"></a>通过互联网获取</p>
</td> </td>
</tr> </tr>
<tr id="row1397335913612"><td class="cellrowborder" valign="top" width="17.54%" headers="mcps1.2.5.1.1 "><p id="p3711468218"><a name="p3711468218"></a><a name="p3711468218"></a>Linux服务器</p> <tr id="row1397335913612"><td class="cellrowborder" valign="top" width="51.15%" headers="mcps1.2.3.1.1 "><p id="p097355911620"><a name="p097355911620"></a><a name="p097355911620"></a>SCons3.0.4+</p>
</td>
<td class="cellrowborder" valign="top" width="23.59%" headers="mcps1.2.5.1.2 "><p id="p097355911620"><a name="p097355911620"></a><a name="p097355911620"></a>SCons3.0.4+</p>
</td> </td>
<td class="cellrowborder" valign="top" width="22.58%" headers="mcps1.2.5.1.3 "><p id="p1973195917619"><a name="p1973195917619"></a><a name="p1973195917619"></a>编译构建工具</p> <td class="cellrowborder" valign="top" width="48.85%" headers="mcps1.2.3.1.2 "><p id="p1973195917619"><a name="p1973195917619"></a><a name="p1973195917619"></a>编译构建工具</p>
</td>
<td class="cellrowborder" valign="top" width="36.29%" headers="mcps1.2.5.1.4 "><p id="p1722663441514"><a name="p1722663441514"></a><a name="p1722663441514"></a>通过互联网获取</p>
</td> </td>
</tr> </tr>
<tr id="row1968013216717"><td class="cellrowborder" valign="top" width="17.54%" headers="mcps1.2.5.1.1 "><p id="p2681632977"><a name="p2681632977"></a><a name="p2681632977"></a>Linux服务器</p> <tr id="row1968013216717"><td class="cellrowborder" valign="top" width="51.15%" headers="mcps1.2.3.1.1 "><p id="p1991501391312"><a name="p1991501391312"></a><a name="p1991501391312"></a>python模块:setuptools、kconfiglib、pycryptodome、six、ecdsa</p>
</td>
<td class="cellrowborder" valign="top" width="23.59%" headers="mcps1.2.5.1.2 "><p id="p1991501391312"><a name="p1991501391312"></a><a name="p1991501391312"></a>python模块:setuptools、kconfiglib、pycryptodome、six、ecdsa</p>
</td>
<td class="cellrowborder" valign="top" width="22.58%" headers="mcps1.2.5.1.3 "><p id="p968120325715"><a name="p968120325715"></a><a name="p968120325715"></a>编译构建工具</p>
</td> </td>
<td class="cellrowborder" valign="top" width="36.29%" headers="mcps1.2.5.1.4 "><p id="p268116326711"><a name="p268116326711"></a><a name="p268116326711"></a>通过互联网获取</p> <td class="cellrowborder" valign="top" width="48.85%" headers="mcps1.2.3.1.2 "><p id="p968120325715"><a name="p968120325715"></a><a name="p968120325715"></a>编译构建工具</p>
</td> </td>
</tr> </tr>
<tr id="row020914491313"><td class="cellrowborder" valign="top" width="17.54%" headers="mcps1.2.5.1.1 "><p id="p20209749103116"><a name="p20209749103116"></a><a name="p20209749103116"></a>Linux服务器</p> <tr id="row020914491313"><td class="cellrowborder" valign="top" width="51.15%" headers="mcps1.2.3.1.1 "><p id="p7209104910317"><a name="p7209104910317"></a><a name="p7209104910317"></a>gcc riscv32</p>
</td> </td>
<td class="cellrowborder" valign="top" width="23.59%" headers="mcps1.2.5.1.2 "><p id="p7209104910317"><a name="p7209104910317"></a><a name="p7209104910317"></a>gcc riscv32</p> <td class="cellrowborder" valign="top" width="48.85%" headers="mcps1.2.3.1.2 "><p id="p102093498311"><a name="p102093498311"></a><a name="p102093498311"></a>编译构建工具</p>
</td>
<td class="cellrowborder" valign="top" width="22.58%" headers="mcps1.2.5.1.3 "><p id="p102093498311"><a name="p102093498311"></a><a name="p102093498311"></a>编译构建工具</p>
</td>
<td class="cellrowborder" valign="top" width="36.29%" headers="mcps1.2.5.1.4 "><p id="p321054953116"><a name="p321054953116"></a><a name="p321054953116"></a>通过互联网获取</p>
</td>
</tr>
<tr id="row1596703610215"><td class="cellrowborder" valign="top" width="17.54%" headers="mcps1.2.5.1.1 "><p id="p071946112113"><a name="p071946112113"></a><a name="p071946112113"></a>Windows工作台</p>
</td>
<td class="cellrowborder" valign="top" width="23.59%" headers="mcps1.2.5.1.2 "><p id="p1044974291416"><a name="p1044974291416"></a><a name="p1044974291416"></a>CH341SER.EXE</p>
</td>
<td class="cellrowborder" valign="top" width="22.58%" headers="mcps1.2.5.1.3 "><p id="p94491342131413"><a name="p94491342131413"></a><a name="p94491342131413"></a>USB转串口驱动</p>
</td>
<td class="cellrowborder" valign="top" width="36.29%" headers="mcps1.2.5.1.4 "><p id="p6449184214148"><a name="p6449184214148"></a><a name="p6449184214148"></a><a href="http://www.wch.cn/search?q=ch340g&amp;t=downloads" target="_blank" rel="noopener noreferrer">http://www.wch.cn/search?q=ch340g&amp;t=downloads</a></p>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -96,10 +60,6 @@ Hi3861开发板需要的工具如下表所示。 ...@@ -96,10 +60,6 @@ Hi3861开发板需要的工具如下表所示。
## 安装Linux编译工具<a name="section497484245614"></a> ## 安装Linux编译工具<a name="section497484245614"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:**
>- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装gcc\_riscv32编译工具。
>- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装gcc\_riscv32编译工具。安装gcc\_riscv32编译工具时,请确保编译工具的环境变量路径唯一。
### 安装编译依赖基础软件(仅Ubuntu 20+需要)<a name="section45512412251"></a> ### 安装编译依赖基础软件(仅Ubuntu 20+需要)<a name="section45512412251"></a>
执行以下命令进行安装: 执行以下命令进行安装:
...@@ -110,20 +70,19 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev ...@@ -110,20 +70,19 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev
### 安装Scons<a name="section7438245172514"></a> ### 安装Scons<a name="section7438245172514"></a>
1. 打开Linux编译服务器终端。 1. 运行如下命令,安装SCons安装包。
2. 运行如下命令,安装SCons安装包。
``` ```
python3 -m pip install scons python3 -m pip install scons
``` ```
3. 运行如下命令,查看是否安装成功。如果安装成功,查询结果下图所示。 2. 运行如下命令,查看是否安装成功。如果安装成功,查询结果下图所示。
``` ```
scons -v scons -v
``` ```
**图 2** SCons安装成功界面,版本要求3.0.4以上<a name="fig151441613316"></a> **图 1** SCons安装成功界面,版本要求3.0.4以上<a name="fig922558123418"></a>
![](figures/SCons安装成功界面-版本要求3-0-4以上.png "SCons安装成功界面-版本要求3-0-4以上") ![](figures/SCons安装成功界面-版本要求3-0-4以上.png "SCons安装成功界面-版本要求3-0-4以上")
...@@ -219,14 +178,14 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev ...@@ -219,14 +178,14 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev
### 安装gcc\_riscv32(WLAN模组类编译工具链)<a name="section34435451256"></a> ### 安装gcc\_riscv32(WLAN模组类编译工具链)<a name="section34435451256"></a>
>![](../public_sys-resources/icon-notice.gif) **须知:** >![](../public_sys-resources/icon-notice.gif) **须知:**
>- Hi3861平台仅支持使用libgcc运行时库的静态链接,不建议开发者使用libgcc运行时库的动态链接,以免产品需遵从GPLV3许可证。 >- Hi3861开发板平台仅支持使用libgcc运行时库的静态链接,不建议开发者使用libgcc运行时库的动态链接,以免产品需遵从GPLV3许可证。
>- 通过下述步骤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步。 >- 通过下述步骤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编译服务器终端。 1. 打开Linux编译服务器终端。
2. 环境准备,请安装"gcc, g++, bison, flex, makeinfo"软件,确保工具链能正确编译。 2. 环境准备,请安装"gcc, g++, bison, flex, makeinfo"软件,确保工具链能正确编译。
``` ```
sudo apt-get install gcc g++ flex bison texinfo 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交叉编译工具链。 3. 下载riscv-gnu-toolchain交叉编译工具链。
...@@ -308,19 +267,10 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev ...@@ -308,19 +267,10 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev
16. 设置环境变量。 16. 设置环境变量。
>![](../public_sys-resources/icon-note.gif) **说明:** >![](../public_sys-resources/icon-note.gif) **说明:**
>如果直接采用编译好的riscv32 gcc包,请参照如下步骤设置环境变量: >如果直接采用编译好的riscv32 gcc包,请先执行以下命令将压缩包解压到根目录:
>1. 将压缩包解压到根目录 >```
> ``` >tar -xvf gcc_riscv32-linux-7.3.0.tar.gz -C ~
> tar -xvf gcc_riscv32-linux-7.3.0.tar.gz -C ~ >```
> ```
>2. 设置环境变量。
> ```
> vim ~/.bashrc
> ```
>3. 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。
> ```
> export PATH=~/gcc_riscv32/bin:$PATH
> ```
``` ```
vim ~/.bashrc vim ~/.bashrc
...@@ -345,14 +295,3 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev ...@@ -345,14 +295,3 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev
``` ```
## 安装USB转串口驱动<a name="section1027732411513"></a>
相关步骤在Windows工作台操作。
1. 点击链接[下载CH341SER USB转串口](http://www.hihope.org/download/download.aspx?mtt=8)驱动程序。
2. 点击安装包,安装驱动程序。
3. 驱动安装完成后,重新插拔USB接口,串口信息显示如下图所示。
![](figures/serial-port-entry.png)
# Hi3861开发板<a name="ZH-CN_TOPIC_0000001174350609"></a> # Hi3861开发板<a name="ZH-CN_TOPIC_0000001171774078"></a>
- **[安装开发板环境](quickstart-lite-steps-hi3861-setting.md)** - **[安装开发板环境](quickstart-lite-steps-hi3861-setting.md)**
- **[WLAN联网(编译、烧录)](quickstart-lite-steps-hi3861-connection.md)** - **[新建应用程序](quickstart-lite-steps-hi3861-application-framework.md)**
- **[运行Hello World](quickstart-lite-steps-hi3861-running.md)** - **[编译](quickstart-lite-steps-hi3861-building.md)**
- **[烧录](quickstart-lite-steps-hi3861-burn.md)**
- **[调试验证](quickstart-lite-steps-hi3861-debug.md)**
- **[运行](quickstart-lite-steps-hi3816-running.md)**
- **[常见问题](quickstart-lite-steps-hi3861-faqs.md)** - **[常见问题](quickstart-lite-steps-hi3861-faqs.md)**
......
# 开发步骤<a name="ZH-CN_TOPIC_0000001128470860"></a> # 运行“Hello World”<a name="ZH-CN_TOPIC_0000001171934018"></a>
- **[Hi3861开发板](quickstart-lite-steps-hi3861.md)** - **[Hi3861开发板](quickstart-lite-steps-hi3861.md)**
......
# 轻量和小型系统入门<a name="ZH-CN_TOPIC_0000001112826850"></a> # 轻量和小型系统入门<a name="ZH-CN_TOPIC_0000001112826850"></a>
- **[概述](quickstart-lite-overview.md)** - **[轻量与小型系统入门概述](quickstart-lite-overview.md)**
- **[入门介绍](quickstart-lite-introduction.md)** - **[搭建轻量与小型系统环境](quickstart-lite-env-setup.md)**
- **[搭建系统环境](quickstart-lite-env-setup.md)** - **[运行“Hello World”](quickstart-lite-steps.md)**
- **[开发步骤](quickstart-lite-steps.md)** - **[附录](quickstart-lite-introduction.md)**
# Hi3516开发板介绍<a name="ZH-CN_TOPIC_0000001188526456"></a>
- [开发板简介](#zh-cn_topic_0000001053666242_section047719215429)
- [开发板规格](#zh-cn_topic_0000001053666242_section15192203316533)
## 开发板简介<a name="zh-cn_topic_0000001053666242_section047719215429"></a>
Hi3516DV300是新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器、高性能NNIE引擎,在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。
**图 1** Hi3516单板正面外观图<a name="fig202901538183412"></a>
![](figures/Hi3516单板正面外观图.png "Hi3516单板正面外观图")
## 开发板规格<a name="zh-cn_topic_0000001053666242_section15192203316533"></a>
**表 1** Hi3516开发板规格清单
<a name="zh-cn_topic_0000001053666242_table31714894311"></a>
<table><thead align="left"><tr id="zh-cn_topic_0000001053666242_row10171198194310"><th class="cellrowborder" valign="top" width="22.52%" id="mcps1.2.3.1.1"><p id="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"><a name="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"></a><a name="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"></a>规格类型</p>
</th>
<th class="cellrowborder" valign="top" width="77.48%" id="mcps1.2.3.1.2"><p id="zh-cn_topic_0000001053666242_p9702458104014"><a name="zh-cn_topic_0000001053666242_p9702458104014"></a><a name="zh-cn_topic_0000001053666242_p9702458104014"></a>规格清单</p>
</th>
</tr>
</thead>
<tbody><tr id="zh-cn_topic_0000001053666242_row0171168114311"><td class="cellrowborder" valign="top" width="22.52%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001053666242_p1698185431418"><a name="zh-cn_topic_0000001053666242_p1698185431418"></a><a name="zh-cn_topic_0000001053666242_p1698185431418"></a><strong id="zh-cn_topic_0000001053666242_b127621861200"><a name="zh-cn_topic_0000001053666242_b127621861200"></a><a name="zh-cn_topic_0000001053666242_b127621861200"></a>处理器及内部存储</strong></p>
</td>
<td class="cellrowborder" valign="top" width="77.48%" headers="mcps1.2.3.1.2 "><a name="zh-cn_topic_0000001053666242_ul1147113537186"></a><a name="zh-cn_topic_0000001053666242_ul1147113537186"></a><ul id="zh-cn_topic_0000001053666242_ul1147113537186"><li>Hi3516DV300芯片</li><li>DDR3 1GB</li><li>eMMC4.5,8GB容量</li></ul>
</td>
</tr>
<tr id="zh-cn_topic_0000001053666242_row21721687435"><td class="cellrowborder" valign="top" width="22.52%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001053666242_p817216810435"><a name="zh-cn_topic_0000001053666242_p817216810435"></a><a name="zh-cn_topic_0000001053666242_p817216810435"></a><strong id="zh-cn_topic_0000001053666242_b1172016266246"><a name="zh-cn_topic_0000001053666242_b1172016266246"></a><a name="zh-cn_topic_0000001053666242_b1172016266246"></a>外部器件</strong></p>
</td>
<td class="cellrowborder" valign="top" width="77.48%" headers="mcps1.2.3.1.2 "><a name="zh-cn_topic_0000001053666242_ul179543016208"></a><a name="zh-cn_topic_0000001053666242_ul179543016208"></a><ul id="zh-cn_topic_0000001053666242_ul179543016208"><li>以太网口</li><li>音频视频<a name="zh-cn_topic_0000001053666242_ul5941311869"></a><a name="zh-cn_topic_0000001053666242_ul5941311869"></a><ul id="zh-cn_topic_0000001053666242_ul5941311869"><li>1路语音输入</li><li>1路单声道(AC_L)输出,接3W功放(LM4871)</li><li>MicroHDMI(1路HDMI 1.4)</li></ul>
</li><li>摄像头<a name="zh-cn_topic_0000001053666242_ul924263620"></a><a name="zh-cn_topic_0000001053666242_ul924263620"></a><ul id="zh-cn_topic_0000001053666242_ul924263620"><li>传感器IMX335</li><li>镜头M12,焦距4mm,光圈1.8</li></ul>
</li><li>显示屏<a name="zh-cn_topic_0000001053666242_ul101471711667"></a><a name="zh-cn_topic_0000001053666242_ul101471711667"></a><ul id="zh-cn_topic_0000001053666242_ul101471711667"><li>LCD连接器(2.35寸)</li><li>LCD连接器(5.5寸)</li></ul>
</li><li>外部器件及接口<a name="zh-cn_topic_0000001053666242_ul089255556"></a><a name="zh-cn_topic_0000001053666242_ul089255556"></a><ul id="zh-cn_topic_0000001053666242_ul089255556"><li>SD卡接口</li><li>JTAG/I2S接口</li><li>ADC接口</li><li>舵机接口</li><li>Grove连接器</li><li>USB2.0(Type C)</li><li>功能按键3个,2个用户自定义按键,1个升级按键</li><li>LED指示灯,绿灯,红灯</li></ul>
</li></ul>
</td>
</tr>
</tbody>
</table>
# RK3568开发板介绍<a name="ZH-CN_TOPIC_0000001188686354"></a>
- [开发板简介](#zh-cn_topic_0000001053666242_section047719215429)
- [开发板规格](#zh-cn_topic_0000001053666242_section15192203316533)
## 开发板简介<a name="zh-cn_topic_0000001053666242_section047719215429"></a>
RK3568开发板基于Rockchip RK3568芯片,集成双核心架构GPU以及高效能NPU;搭载四核64位Cortex-A55处理器,采用22nm先进工艺,主频高达2.0GHz;支持蓝牙、Wi-Fi、音频、视频和摄像头等功能,拥有丰富的扩展接口,支持多种视频输入输出接口;配置双千兆自适应RJ45以太网口,可满足NVR、工业网关等多网口产品需求。
**图 1** RK3568开发板正面<a name="fig1621416475181"></a>
![](figures/RK3568开发板正面.png "RK3568开发板正面")
**图 2** RK3568开发板背面<a name="fig16541171141914"></a>
![](figures/RK3568开发板背面.png "RK3568开发板背面")
## 开发板规格<a name="zh-cn_topic_0000001053666242_section15192203316533"></a>
**表 1** RK3568开发板规格说明
<a name="table36411410122616"></a>
<table><thead align="left"><tr id="row166411110142615"><th class="cellrowborder" valign="top" width="17.169999999999998%" id="mcps1.2.3.1.1"><p id="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"><a name="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"></a><a name="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"></a>规格类型</p>
</th>
<th class="cellrowborder" valign="top" width="82.83%" id="mcps1.2.3.1.2"><p id="zh-cn_topic_0000001053666242_p9702458104014"><a name="zh-cn_topic_0000001053666242_p9702458104014"></a><a name="zh-cn_topic_0000001053666242_p9702458104014"></a>规格清单</p>
</th>
</tr>
</thead>
<tbody><tr id="row9641171062612"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p162810206274"><a name="p162810206274"></a><a name="p162810206274"></a>显示接口</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul7771205752919"></a><a name="ul7771205752919"></a><ul id="ul7771205752919"><li>1×HDMI2.0(Type-A)接口,支持4K/60fps输出</li><li>2×MIPI接口,支1920*1080@60fps输出</li><li>1×eDP接口,支持2K@60fps输出</li></ul>
</td>
</tr>
<tr id="row18641121042615"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p1033185410277"><a name="p1033185410277"></a><a name="p1033185410277"></a>音频接口</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul128286520307"></a><a name="ul128286520307"></a><ul id="ul128286520307"><li>1×8ch I2S/TDM/PDM</li><li>1×HDMI音频输出</li><li>1×喇叭输出</li><li>1×耳机输出</li><li>1×麦克风,板载音频输入</li></ul>
</td>
</tr>
<tr id="row6641710192612"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p5331354152713"><a name="p5331354152713"></a><a name="p5331354152713"></a>以太网</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul18121111513011"></a><a name="ul18121111513011"></a><ul id="ul18121111513011"><li>2×GMAC(10/100/1000M)</li></ul>
</td>
</tr>
<tr id="row564118100267"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p333954112719"><a name="p333954112719"></a><a name="p333954112719"></a>无线网络</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul5121115123012"></a><a name="ul5121115123012"></a><ul id="ul5121115123012"><li>SDIO接口,支持WIFI6 5G/2.5G,BT4.2</li></ul>
</td>
</tr>
<tr id="row17641210162616"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p633125462710"><a name="p633125462710"></a><a name="p633125462710"></a>摄像头接口</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul1012191513012"></a><a name="ul1012191513012"></a><ul id="ul1012191513012"><li>MIPI-CSI2,1x4-lane/2x2-lane@2.5Gbps/lane</li></ul>
</td>
</tr>
<tr id="row156411810102611"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p386217610283"><a name="p386217610283"></a><a name="p386217610283"></a>USB</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul181212015103013"></a><a name="ul181212015103013"></a><ul id="ul181212015103013"><li>2×USB2.0 Host,Type-A</li><li>1×USB3.0 Host,Type-A</li><li>1×USB3.0 OTG</li></ul>
</td>
</tr>
<tr id="row206422107263"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p7862136182813"><a name="p7862136182813"></a><a name="p7862136182813"></a>PCIe</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul20721102111307"></a><a name="ul20721102111307"></a><ul id="ul20721102111307"><li>1×2Lanes PCIe3.0 Connector (RC Mode)</li></ul>
</td>
</tr>
<tr id="row660615129285"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p9481746202811"><a name="p9481746202811"></a><a name="p9481746202811"></a>SATA</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul167214215304"></a><a name="ul167214215304"></a><ul id="ul167214215304"><li>1×SATA3.0 Connector</li></ul>
</td>
</tr>
<tr id="row4821762812"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p1848164632810"><a name="p1848164632810"></a><a name="p1848164632810"></a>SDMMC</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul3721112113306"></a><a name="ul3721112113306"></a><ul id="ul3721112113306"><li>1×Micro SD Card3.0</li></ul>
</td>
</tr>
<tr id="row1678422114288"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p1148174614285"><a name="p1148174614285"></a><a name="p1148174614285"></a>按键</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul1272116218301"></a><a name="ul1272116218301"></a><ul id="ul1272116218301"><li>1×Vol+/Recovery</li><li>1×Reset</li><li>1×Power</li><li>1×Vol-</li><li>1×Mute</li></ul>
</td>
</tr>
<tr id="row11615324102818"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p248184620280"><a name="p248184620280"></a><a name="p248184620280"></a>调试</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul372212133018"></a><a name="ul372212133018"></a><ul id="ul372212133018"><li>1×调试串口</li></ul>
</td>
</tr>
<tr id="row157361119142813"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p348204652814"><a name="p348204652814"></a><a name="p348204652814"></a>RTC</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul4722172117308"></a><a name="ul4722172117308"></a><ul id="ul4722172117308"><li>1×RTC</li></ul>
</td>
</tr>
<tr id="row283612559284"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p1442220405295"><a name="p1442220405295"></a><a name="p1442220405295"></a>IR</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul27221821153016"></a><a name="ul27221821153016"></a><ul id="ul27221821153016"><li>1×IR</li></ul>
</td>
</tr>
<tr id="row327681132916"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p1742274032919"><a name="p1742274032919"></a><a name="p1742274032919"></a>三色灯</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul172292183018"></a><a name="ul172292183018"></a><ul id="ul172292183018"><li>3×LED</li></ul>
</td>
</tr>
<tr id="row65001419202920"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p842264019298"><a name="p842264019298"></a><a name="p842264019298"></a>G-sensor</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul13722172103018"></a><a name="ul13722172103018"></a><ul id="ul13722172103018"><li>1×G-sensor</li></ul>
</td>
</tr>
<tr id="row1147411299"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p542211408293"><a name="p542211408293"></a><a name="p542211408293"></a>FAN</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul14722152153010"></a><a name="ul14722152153010"></a><ul id="ul14722152153010"><li>1×Fan</li></ul>
</td>
</tr>
<tr id="row757237182919"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p134221740132920"><a name="p134221740132920"></a><a name="p134221740132920"></a>扩展接口</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul12722521133017"></a><a name="ul12722521133017"></a><ul id="ul12722521133017"><li>20Pin扩展接口包括:</li><li>2×ADC接口</li><li>2×I2C接口</li><li>7×GPIO口(或者3×gpio + 4×uart信号)</li><li>3×VCC电源(12V、3.3V、5V)</li></ul>
</td>
</tr>
<tr id="row0467258192811"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p8422940102910"><a name="p8422940102910"></a><a name="p8422940102910"></a>底板尺寸</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul16723202114304"></a><a name="ul16723202114304"></a><ul id="ul16723202114304"><li>180mm×130mm</li></ul>
</td>
</tr>
<tr id="row203158173296"><td class="cellrowborder" valign="top" width="17.169999999999998%" headers="mcps1.2.3.1.1 "><p id="p3422174012917"><a name="p3422174012917"></a><a name="p3422174012917"></a>PCB规格</p>
</td>
<td class="cellrowborder" valign="top" width="82.83%" headers="mcps1.2.3.1.2 "><a name="ul7723132183012"></a><a name="ul7723132183012"></a><ul id="ul7723132183012"><li>4 层板</li></ul>
</td>
</tr>
</tbody>
</table>
# 附录<a name="ZH-CN_TOPIC_0000001234044677"></a>
- **[Hi3516开发板介绍](quickstart-standard-appendix-hi3516.md)**
- **[RK3568开发板介绍](quickstart-standard-appendix-rk3568.md)**
# 镜像烧录<a name="ZH-CN_TOPIC_0000001153557088"></a>
- [前提条件](#section18547185418328)
- [使用网口烧录](#section1965361953312)
标准系统烧录,在V2.2 Beta1及以上版本支持。
Hi3516DV300支持烧录标准系统,其烧录方式包括USB烧录、网口烧录和串口烧录三种方式,其中:
- **Windows系统:支持USB烧录、网口烧录和串口烧录**
- **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)。
## 前提条件<a name="section18547185418328"></a>
在DevEco Device Tool中,选择**Import Project**打开待烧录文件所在文件夹,其中MCU选择**HiSilicon\_Arm\_Linux**下的Hi3516DV300,Framework选择“Ohos-sources”或“Hpm”。
![](figures/hisilicon-arm-linux.png)
## 使用网口烧录<a name="section1965361953312"></a>
Hi3516DV300开发板使用网口烧录方式,支持Windows和Linux系统。
1. 请连接好电脑和待烧录开发板,需要同时连接串口、网口和电源,具体可参考[Hi3516DV300开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3516-0000001152041033)
2. <a name="zh-cn_topic_0000001056443961_li1050616379507"></a>打开电脑的设备管理器,查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。
![](figures/hi3516-record-the-serial-port-number.png)
3. 打开DevEco Device Tool,在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/hi3516-deveco-device-tool-setting.png)
4. 在“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/upload-options-1.png)
5. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516DV300网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/ide/user-guides/set_ipaddress-0000001141825075)
6. 设置网口烧录的IP地址信息,设置如下选项:
- upload\_net\_server\_ip:选择步骤5中设置的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/ip-address-information-2.png)
7. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
8. 打开工程文件,点击![](figures/2021-01-27_170334.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3516dv300下的**Upload**按钮,启动烧录。
![](figures/zh-cn_image_0000001215342695.png)
9. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。
![](figures/hi3516-restart-the-development-board.png)
10. 重新上电后,界面提示如下信息时,表示烧录成功。
![](figures/hi3516-burning-succeeded-net.png)
11. 烧录完成后,请根据[标准系统镜像运行](https://device.harmonyos.com/cn/docs/start/introduce/quickstart-standard-running-0000001142160948)进行下一步操作,完成系统启动。
# 开发环境准备<a name="ZH-CN_TOPIC_0000001193328250"></a>
- [系统要求](#zh-cn_topic_0000001072959308_section1865184385215)
- [安装DevEco Device Tool](#zh-cn_topic_0000001072959308_section86587531620)
DevEco Device Tool Ubuntu版本支持OpenHarmony源码开发、编译、烧录的一站式开发环境,因此,本章节为您介绍在Ubuntu环境下,如何搭建一套完整的可视化开发环境。
## 系统要求<a name="zh-cn_topic_0000001072959308_section1865184385215"></a>
- Ubuntu18及以上版本,内存推荐16 GB及以上。
- 系统的用户名不能含有中文字符。
- 只能使用普通用户角色搭建开发环境。
## 安装DevEco Device Tool<a name="zh-cn_topic_0000001072959308_section86587531620"></a>
DevEco Device Tool基于Visual Studio Code进行扩展,在Visual Studio Code上以插件方式运行,Visual Studio Code版本为1.60及以上。同时,DevEco Device Tool还依赖Python工具,并要求Python为3.8\~3.9版本。
在安装过程中,DevEco Device Tool会自动检查Visual Studio Code和Python,如果检测到Visual Studio Code、Python未安装或版本不符合要求,安装程序会自动安装Visual Studio Code和Python。
1. 将Ubuntu Shell环境修改为bash。
1. 执行如下命令,确认输出结果为bash。如果输出结果不是bash,请根据步骤2,将Ubuntu shell修改为bash。
```
ls -l /bin/sh
```
![](figures/zh-cn_image_0000001194078294.png)
2. 打开终端工具,执行如下命令,输入密码,然后选择**No**,将Ubuntu shell由dash修改为bash。
```
sudo dpkg-reconfigure dash
```
![](figures/zh-cn_image_0000001238878219.png)
2. 下载[DevEco Device Tool 3.0 Beta2](https://device.harmonyos.com/cn/ide#download_beta)Linux版本,下载时,请先使用华为开发者帐号进行登录后下载。如未注册华为开发者账号,请先[注册](https://developer.huawei.com/consumer/cn/doc/start/registration-and-verification-0000001053628148)
3. 解压DevEco Device Tool软件包并对解压后的文件夹进行赋权。
1. 进入DevEco Device Tool软件包目录,执行如下命令解压软件包,其中devicetool-linux-tool-3.0.0.200.zip为软件包名称,请根据实际进行修改。
```
unzip devicetool-linux-tool-3.0.0.300.zip
```
2. 进入解压后的文件夹,执行如下命令,赋予安装文件可执行权限,其中devicetool-linux-tool-3.0.0.300.sh请根据实际进行修改。
```
chmod u+x devicetool-linux-tool-3.0.0.300.sh
```
4. 执行如下命令,安装DevEco Device Tool,其中devicetool-linux-tool-3.0.0.300.sh请根据实际进行修改。
>![](../public_sys-resources/icon-note.gif) **说明:**
>安装过程中,会自动检查Visual Studio Code和Python是否安装,且版本符合要求,其中Visual Studio Code为1.60及以上版本,Python为3.8\~3.9版本。如果不满足,则安装过程中会自动安装,提示“Do you want to continue?”,请输入“Y”后继续安装。
```
sudo ./devicetool-linux-tool-3.0.0.300.sh -- --install-plugins
```
安装完成后,当界面输出“Deveco Device Tool successfully installed.”时,表示DevEco Device Tool安装成功。
![](figures/zh-cn_image_0000001239348791.png)
5. 安装完成后,在Ubuntu左下角的![](figures/zh-cn_image_0000001075566984.png)中,启动Visual Studio Code。
6. 启动Visual Studio Code,DevEco Device Tool运行依赖C/C++、CodeLLDB插件,请点击Visual Studio Code左侧的![](figures/button.png)按钮,分别搜索和安装C/C++、CodeLLDB插件。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果在插件市场安装C/C++和CodeLLDB插件不成功,可手动下载插件后进行安装,具体请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/documentation/guide/offline_plugin_install-0000001074376846)。
![](figures/deveco-device-tool-install-sucessful.png)
7. 重启Visual Studio Code,点击![](figures/zh-cn_image_0000001239226427.png)进入DevEco Device Tool工具界面。至此,DevEco Device Tool Ubuntu开发环境安装完成。![](figures/zh-cn_image_0000001194668634.png)
# 常见问题<a name="ZH-CN_TOPIC_0000001166804465"></a> # 常见问题<a name="ZH-CN_TOPIC_0000001188205126"></a>
- [编译构建过程中,提示"ImportError: No module named apt\_pkg"](#section1864714601214)
## 编译构建过程中,提示"ImportError: No module named apt\_pkg"<a name="section1864714601214"></a>
- **现象描述** - **现象描述**
Linux编译服务器终端输入不识别的命令时,提示"ImportError: No module named apt\_pkg" Linux编译服务器终端输入不识别的命令时,提示"ImportError: No module named apt\_pkg"
- **可能原因** - **可能原因**
......
# 入门介绍<a name="ZH-CN_TOPIC_0000001166764513"></a> # 标准系统入门简介<a name="ZH-CN_TOPIC_0000001188365096"></a>
- [快速入门流程](#section7825218111517) - [快速入门流程](#section7825218111517)
- [开发板简介](#zh-cn_topic_0000001053666242_section047719215429)
- [开发板规格](#zh-cn_topic_0000001053666242_section15192203316533)
开发者可通过本文快速掌握OpenHarmony标准系统的环境搭建、编译、烧录、启动等操作。标准系统可以使用Windows环境进行开发、烧录,使用Linux环境进行编译。 开发者可通过本文快速掌握OpenHarmony标准系统的环境搭建、编译、烧录、运行等操作。标准系统的开发有以下两种方法:
本文将以当前推荐的Hi3516DV300开发板为例对上述操作进行说明。 - 使用Windows环境进行开发和烧录,使用Linux环境进行编译。
- 统一使用Linux环境进行开发、编译和烧录。
因目前Windows系统不支持编译,暂时无法全部使用Windows环境进行开发,开发者可根据使用习惯选择合适的开发方法。
本文将介绍第二种方法,**所有操作均在Linux环境下进行**
## 快速入门流程<a name="section7825218111517"></a> ## 快速入门流程<a name="section7825218111517"></a>
标准系统快速入门流程如下图所示,其中“搭建Ubuntu环境及编译”环节可根据实际情况选择docker方式或工具包方式其中一种即可。 标准系统快速入门流程如下图所示,其中编译源码环节可根据实际情况选择docker方式或安装包方式其中一种即可。
**图 1** 标准环境快速入门流程<a name="fig19162195553211"></a> >![](../public_sys-resources/icon-note.gif) **说明:**
![](figures/标准环境快速入门流程.png "标准环境快速入门流程") >Docker环境已经封装了相关编译工具,开发者在使用该Docker环境时可以省去Ubuntu编译环境及开发板环境的的搭建操作。
## 开发板简介<a name="zh-cn_topic_0000001053666242_section047719215429"></a> **图 1** 标准系统快速入门流程<a name="fig20982640223"></a>
![](figures/标准系统快速入门流程.png "标准系统快速入门流程")
Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。
**图 2** Hi3516单板正面外观图<a name="fig202901538183412"></a>
![](figures/Hi3516单板正面外观图-0.png "Hi3516单板正面外观图-0")
## 开发板规格<a name="zh-cn_topic_0000001053666242_section15192203316533"></a>
**表 1** Hi3516开发板规格清单
<a name="zh-cn_topic_0000001053666242_table31714894311"></a>
<table><thead align="left"><tr id="zh-cn_topic_0000001053666242_row10171198194310"><th class="cellrowborder" valign="top" width="14.77%" id="mcps1.2.3.1.1"><p id="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"><a name="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"></a><a name="zh-cn_topic_0000001053666242_a2b235e9ed55f4338886788f140e648a0"></a>规格类型</p>
</th>
<th class="cellrowborder" valign="top" width="85.22999999999999%" id="mcps1.2.3.1.2"><p id="zh-cn_topic_0000001053666242_p9702458104014"><a name="zh-cn_topic_0000001053666242_p9702458104014"></a><a name="zh-cn_topic_0000001053666242_p9702458104014"></a>规格清单</p>
</th>
</tr>
</thead>
<tbody><tr id="zh-cn_topic_0000001053666242_row0171168114311"><td class="cellrowborder" valign="top" width="14.77%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001053666242_p1698185431418"><a name="zh-cn_topic_0000001053666242_p1698185431418"></a><a name="zh-cn_topic_0000001053666242_p1698185431418"></a><strong id="zh-cn_topic_0000001053666242_b127621861200"><a name="zh-cn_topic_0000001053666242_b127621861200"></a><a name="zh-cn_topic_0000001053666242_b127621861200"></a>处理器及内部存储</strong></p>
</td>
<td class="cellrowborder" valign="top" width="85.22999999999999%" headers="mcps1.2.3.1.2 "><a name="zh-cn_topic_0000001053666242_ul1147113537186"></a><a name="zh-cn_topic_0000001053666242_ul1147113537186"></a><ul id="zh-cn_topic_0000001053666242_ul1147113537186"><li>Hi3516DV300芯片</li><li>DDR3 1GB</li><li>eMMC4.5,8GB容量</li></ul>
</td>
</tr>
<tr id="zh-cn_topic_0000001053666242_row21721687435"><td class="cellrowborder" valign="top" width="14.77%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001053666242_p817216810435"><a name="zh-cn_topic_0000001053666242_p817216810435"></a><a name="zh-cn_topic_0000001053666242_p817216810435"></a><strong id="zh-cn_topic_0000001053666242_b1172016266246"><a name="zh-cn_topic_0000001053666242_b1172016266246"></a><a name="zh-cn_topic_0000001053666242_b1172016266246"></a>外部器件</strong></p>
</td>
<td class="cellrowborder" valign="top" width="85.22999999999999%" headers="mcps1.2.3.1.2 "><a name="zh-cn_topic_0000001053666242_ul179543016208"></a><a name="zh-cn_topic_0000001053666242_ul179543016208"></a><ul id="zh-cn_topic_0000001053666242_ul179543016208"><li>以太网口</li><li>音频视频<a name="zh-cn_topic_0000001053666242_ul5941311869"></a><a name="zh-cn_topic_0000001053666242_ul5941311869"></a><ul id="zh-cn_topic_0000001053666242_ul5941311869"><li>1路语音输入</li><li>1路单声道(AC_L)输出,接3W功率放大器(LM4871)</li><li>MicroHDMI(1路HDMI 1.4)</li></ul>
</li><li>摄像头<a name="zh-cn_topic_0000001053666242_ul924263620"></a><a name="zh-cn_topic_0000001053666242_ul924263620"></a><ul id="zh-cn_topic_0000001053666242_ul924263620"><li>传感器IMX335</li><li>镜头M12,焦距4mm,光圈1.8</li></ul>
</li><li>显示屏<a name="zh-cn_topic_0000001053666242_ul101471711667"></a><a name="zh-cn_topic_0000001053666242_ul101471711667"></a><ul id="zh-cn_topic_0000001053666242_ul101471711667"><li>LCD连接器(2.35寸)</li><li>LCD连接器(5.5寸)</li></ul>
</li><li>外部器件及接口<a name="zh-cn_topic_0000001053666242_ul089255556"></a><a name="zh-cn_topic_0000001053666242_ul089255556"></a><ul id="zh-cn_topic_0000001053666242_ul089255556"><li>SD卡接口</li><li>JTAG/I2S接口</li><li>ADC接口</li><li>舵机接口</li><li>Grove连接器</li><li>USB2.0(Type C)</li><li>功能按键3个,2个用户自定义按键,1个升级按键</li><li>LED指示灯,绿灯,红灯</li></ul>
</li></ul>
</td>
</tr>
</tbody>
</table>
# 搭建Ubuntu环境\(获取源码及编译,安装包方式\)<a name="ZH-CN_TOPIC_0000001119804790"></a>
- [安装依赖工具](#section18431165519244)
- [获取标准系统源码](#section113751052102517)
- [前提条件](#section102871547153314)
- [操作步骤](#section429012478331)
- [执行prebuilts](#section0495320152619)
- [编译](#section1664835963517)
## 安装依赖工具<a name="section18431165519244"></a>
安装命令如下:
```
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 ruby
```
>![](../public_sys-resources/icon-note.gif) **说明:**
>以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。其中Python要求安装Python 3.7及以上版本,此处以Python 3.8为例。
## 获取标准系统源码<a name="section113751052102517"></a>
### 前提条件<a name="section102871547153314"></a>
1. 注册码云gitee账号。
2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)
3. 安装[git客户端](https://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
```
### 操作步骤<a name="section429012478331"></a>
可通过下方两种方式获取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'
```
## 执行prebuilts<a name="section0495320152619"></a>
在源码根目录下执行脚本,安装编译器及二进制工具。
```
bash build/prebuilts_download.sh
```
下载的prebuilts二进制默认存放在与OpenHarmony同目录下的OpenHarmony\_2.0\_canary\_prebuilts下。
## 编译<a name="section1664835963517"></a>
在Linux环境进行如下操作:
1. 进入源码根目录,执行如下命令进行版本编译。
```
./build.sh --product-name {product_name}
```
\{product\_name\}为当前版本支持的平台,比如:Hi3516DV300
2. 检查编译结果。编译完成后,log中显示如下:
```
build system image successful.
=====build Hi3516DV300 successful.
```
编译所生成的文件都归档在out/{device_name}/目录下,结果镜像输出在out/{device_name}/packages/phone/images/ 目录下。
>![](../public_sys-resources/icon-note.gif) **说明:**
>其他模块化编译操作,可参见[编译构建指导](../subsystems/subsys-build-standard-large.md)。
3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](quickstart-standard-burn.md)
# 搭建Ubuntu环境\(获取源码及编译,Docker方式\)<a name="ZH-CN_TOPIC_0000001119805112"></a> # 源码编译<a name="ZH-CN_TOPIC_0000001233803245"></a>
- [获取标准系统源码](#section8761819202511) - [使用Docker方式获取编译工具链](#section181431248132513)
- [前提条件](#section102871547153314) - [执行prebuilts](#section111934551605)
- [操作步骤](#section429012478331) - [安装Docker](#section1466184743915)
- [获取Docker环境](#section615912103552)
- [执行prebuilts](#section0495320152619) - [使用安装包方式获取编译工具链](#section65647482593)
- [获取Docker环境](#section181431248132513) - [安装依赖工具](#section83441888010)
- [编译](#section92391739152318) - [执行prebuilts](#section6389714142011)
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)的内容。
## 获取标准系统源码<a name="section8761819202511"></a>
### 前提条件<a name="section102871547153314"></a>
1. 注册码云gitee账号。
2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)
3. 安装[git客户端](https://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工具,可以执行如下命令。 - [编译](#section92391739152318)
```
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
```
安装编译工具链后,即可对源码进行编译。在Linux环境下获取编译工具链有以下两种方式,二者选其一即可:
### 操作步骤<a name="section429012478331"></a> 1. Docker方式
可通过下方两种方式获取OpenHarmony主干代码,两种方式二选一即可。建议新建个文件夹,在此文件夹下执行以下命令,下载源码,此文件夹即为源码根目录 OpenHarmony标准系统为开发者提供的Docker环境已经将对应的编译工具链进行了封装,开发者可省略对应工具的安装
方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 2. 安装包方式
``` 使用安装包方式获取编译工具链时,开发者需自行安装相应的依赖工具。
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 下载。
``` ## 使用Docker方式获取编译工具链<a name="section181431248132513"></a>
repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
repo sync -c
repo forall -c 'git lfs pull'
```
## 执行prebuilts<a name="section0495320152619"></a> ### 执行prebuilts<a name="section111934551605"></a>
在源码根目录下执行脚本,安装编译器及二进制工具。 在源码根目录下执行脚本,安装编译器及二进制工具。
...@@ -65,9 +32,11 @@ repo forall -c 'git lfs pull' ...@@ -65,9 +32,11 @@ repo forall -c 'git lfs pull'
bash build/prebuilts_download.sh bash build/prebuilts_download.sh
``` ```
下载的prebuilts二进制默认存放在与OpenHarmony同目录下的OpenHarmony\_2.0\_canary\_prebuilts下。 ### 安装Docker<a name="section1466184743915"></a>
## 获取Docker环境<a name="section181431248132513"></a> 请参考[官方指导](https://docs.docker.com/engine/install/)
### 获取Docker环境<a name="section615912103552"></a>
**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** **方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:**
...@@ -106,20 +75,52 @@ bash build/prebuilts_download.sh ...@@ -106,20 +75,52 @@ bash build/prebuilts_download.sh
``` ```
## 使用安装包方式获取编译工具链<a name="section65647482593"></a>
### 安装依赖工具<a name="section83441888010"></a>
请在终端中输入如下命令安装编译相关的依赖工具:
```
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 ruby
```
>![](../public_sys-resources/icon-note.gif) **说明:**
>以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。其中Python要求安装Python 3.7及以上版本,此处以Python 3.8为例。
### 执行prebuilts<a name="section6389714142011"></a>
在源码根目录下执行脚本,安装编译器及二进制工具。
```
bash build/prebuilts_download.sh
```
## 编译<a name="section92391739152318"></a> ## 编译<a name="section92391739152318"></a>
1. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 1. 进入源码根目录,执行如下命令进行版本编译。
>![](../public_sys-resources/icon-note.gif) **说明:**
>使用Docker方式获取编译工具链的,请直接通过[获取Docker环境](#section615912103552)最后一步进入的Docker构建环境执行如下命令。
```
./build.sh --product-name Hi3516DV300 --ccache
```
2. 检查编译结果。编译完成后,log中显示如下:
``` ```
./build.sh --product-name {product_name} build system image successful.
=====build Hi3516DV300 successful.
``` ```
\{product\_name\}为当前版本支持的平台。比如:Hi3516DV300等 编译所生成的文件都归档在out/\{device\_name\}/目录下,结果镜像输出在out/\{device\_name\}/packages/phone/images/ 目录下
编译所生成的文件都归档在out/{device_name}/目录下,结果镜像输出在 out/{device_name}/packages/phone/images/ 目录下。 >![](../public_sys-resources/icon-note.gif) **说明:**
>其他模块化编译操作,可参见[编译构建指导](../subsystems/subsys-build-standard-large.md)。
2. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](quickstart-standard-burn.md) 3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](quickstart-standard-running-hi3516-burn.md)
>![](../public_sys-resources/icon-note.gif) **说明:** >![](../public_sys-resources/icon-note.gif) **说明:**
>退出Docker执行exit命令即可 >若使用Docker环境进行编译,执行exit命令即可退出Docker
# 镜像烧录<a name="ZH-CN_TOPIC_0000001188683564"></a>
- [前提条件](#section1956213516576)
- [使用网口烧录](#section14587120161217)
标准系统烧录,在DevEco Device Tool V2.2 Beta1及以上版本支持,下方烧录操作均在DevEco Device Tool中进行。
DevEco Device Tool以插件方式运行,基于Visual Studio Code进行扩展,用户可点击Visual Studio Code左侧栏的![](figures/2021-01-27_170334-10.png)图标打开DevEco Device Tool。
Hi3516DV300支持烧录标准系统,其烧录方式包括USB烧录、网口烧录和串口烧录三种方式,其中:
- **Windows系统:支持USB烧录、网口烧录和串口烧录**
- **Linux系统:支持串口烧录和网口烧录。**
同一种烧录方式(如网口烧录),在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。
下方以Linux系统下,网口烧录方式为例进行OpenHarmony标准系统烧录,其他两种烧录方式请参照[Hi3516DV300烧录指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)
## 前提条件<a name="section1956213516576"></a>
1. 在DevEco Device Tool工具中点击**Import Project**导入新建应用程序章节修改后的源码文件。
![](figures/import-project.png)
2. 选择源码导入时,系统会提示该工程不是DevEco Device Tool工程,点击**Import**
![](figures/import-project-confirm.png)
3. MCU选择**HiSilicon\_Arm\_Linux**下的Hi3516DV300,Board选择hi3516dv300,Framework选择“Ohos-sources”,然后点击**Import**完成导入。
![](figures/hisilicon-arm-linux.png)
## 使用网口烧录<a name="section14587120161217"></a>
1. 请连接好电脑和待烧录开发板,需要同时连接串口和USB口,具体可参考[Hi3516DV300开发板介绍](https://device.harmonyos.com/cn/docs/documentation/guide/quickstart-lite-introduction-hi3516-0000001152041033)[Hi3516DV300开发板介绍](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-introduction-hi3516.md)。
2. 查看并记录对应的串口号。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。
Windows系统,打开设备管理器查看并记录对应的串口号,或在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/record-the-serial-port-number.png)
Linux系统,在DevEco Device Tool中,点击QUICK ACCESS \> DevEco Home \> Device,查看并记录对应的串口号。
![](figures/Snap22.png)
3. 在QUICK ACCESS \> DevEco Home \> Projects中,点击**Settings**打开工程配置界面。
![](figures/zh-cn_image_0000001177608370.png)
4. 在“hi3516dv300”页签,设置烧录选项,包括upload\_partitions、upload\_port和upload\_protocol。
- upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、boot、updater、misc、system、vendor和userdata。
- upload\_port:选择已查询的串口号。
- upload\_protocol:选择烧录协议,固定选择“hiburn-usb”。
![](figures/zh-cn_image_0000001177478136.png)
5. 分别检查待烧录文件的烧录信息,DevEco Device Tool已预置默认的烧录文件信息,可根据实际情况进行调整。待烧录文件包括:fastboot、boot、updater、misc、system、vendor和userdata。
1. 在“hi3516dv300\_fastboot”页签,在New Option选项中选择需要修改的项,例如partition\_bin(烧录文件路径)、partition\_addr(烧录文件起始地址)、partition\_length(烧录文件分区长度)等。
![](figures/zh-cn_image_0000001222997983.png)
2. 然后在Partition Options中,分别修改上述步骤中选择的修改项。
>![](../public_sys-resources/icon-note.gif) **说明:**
>在设置烧录分区起始地址和分区长度时,应根据实际待烧录文件的大小进行设置,要求设置的烧录分区大小,要大于待烧录文件的大小;同时,各烧录文件的分区地址设置不能出现重叠。
![](figures/zh-cn_image_0000001222794413.png)
3. 按照相同的方法修改boot、updater和misc的烧录文件信息。
6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。
7. 点击**Open**打开工程文件,然后在“PROJECT TASKS”中,点击fastboot下的**Erase**按钮,擦除U-Boot。
![](figures/zh-cn_image_0000001163045527.png)
8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(插拔USB连线)。
![](figures/zh-cn_image_0000001114129426.png)
9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。
![](figures/zh-cn_image_0000001113969536.png)
10. 擦除完成后,点击hi3516dv300下的**Upload**按钮,启动烧录。
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果您是第一次在工作台烧录Hi3516DV300/Hi3518EV300开发板,可能烧录失败,提示“not find the Devices”,请根据[Hi3516DV300/Hi3518EV300开发板USB驱动安装](https://device.harmonyos.com/cn/docs/documentation/guide/usb_driver-0000001058690393)进行处理后再重新烧录。
![](figures/1-11.png)
11. 启动烧录后,界面提示如下信息时,表示烧录成功。
![](figures/zh-cn_image_0000001160649343.png)
12. 烧录完成后,请根据标准系统镜像运行进行下一步操作,完成系统启动。
# 创建应用程序<a name="ZH-CN_TOPIC_0000001233924721"></a>
下方将通过修改源码的方式展示如何在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello World!”。
这里演示在原有applications子系统下,添加hello部件以及该部件下的helloworld模块。
示例完整目录如下。
```
applications/standard/hello
├── helloworld
│ ├── include
│ │ └── helloworld.h
│ └── src
│ └── helloworld.c
├── BUILD.gn
├── ohos.build
productdefine/common
└── products
└── Hi3516DV300.json
```
下方为新建应用程序步骤,请在[获取源码](quickstart-standard-sourcecode-acquire.md)章节下载的源码目录中进行下述操作:
1. 新建目录及源码。
新建applications/standard/hello/helloworld/src/helloworld.c目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改World为OHOS)。其中helloworld.h包含字符串打印函数HelloPrint的声明。当前应用程序可支持标准C及C++的代码开发。
```
#include <stdio.h>
#include "helloworld.h"
int main(int argc, char **argv)
{
HelloPrint();
return 0;
}
void HelloPrint()
{
printf("\n************************************************\n");
printf("\n\t\tHello World!\n");
printf("\n************************************************\n");
}
```
再添加头文件applications/standard/hello/helloworld/include/helloworld.h,代码如下所示。
```
#ifndef HELLOWORLD_H
#define HELLOWORLD_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
void HelloPrint();
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // HELLOWORLD_H
```
2. 新建编译组织文件。
1. 新建applications/standard/hello/BUILD.gn文件,内容如下所示。
```
import("//build/ohos.gni") # 导入编译模板
ohos_executable("helloworld") { # 可执行模块
sources = [ # 模块源码
"src/helloworld.c"
]
include_dirs = [ # 模块依赖头文件目录
"include"
]
cflags = []
cflags_c = []
cflags_cc = []
ldflags = []
configs = []
deps =[] # 部件内部依赖
part_name = "hello" # 所属部件名称,必选
install_enable = true # 是否默认安装(缺省默认不安装),可选
}
```
2. 新建applications/standard/hello/ohos.build文件,添加hello部件描述,内容如下所示。
```
{
"subsystem": "applications", # 子系统名
"parts": { # 包含部件
"hello": { # 新建部件名
"version": "1.0.0", # 版本
"variants": [ # 变种版本
"wearable",
"phone"
],
"module_list": [ # 部件包含模块的gn目标
"//applications/standard/hello:helloworld"
],
"inner_kits": [ # 提供给其他部件的接口
],
"test_list": [ # 测试用例
]
}
}
}
```
ohos.build文件包含两个部分,第一部分subsystem说明该子系统的名称,parts定义该子系统包含的部件,要添加一个部件,需要把该部件对应的内容添加进parts中去。添加的时候需要指明该部件包含的模块module\_list,假如有提供给其它部件的接口,需要在inner\_kits中说明,假如有测试用例,需要在test\_list中说明,inner\_kits与test\_list没有也可以不添加。
3. 修改产品配置文件。
在productdefine\\common\\products\\Hi3516DV300.json中添加对应的部件,直接添加到原有部件后即可(如下代码加粗部分)。
```
"usb:usb_manager_native":{},
"applications:prebuilt_hap":{},
"applications:hello":{}, # "部件所属子系统名:部件名":{}
"wpa_supplicant-2.9:wpa_supplicant-2.9":{},
```
# 镜像运行<a name="ZH-CN_TOPIC_0000001188523652"></a>
- [启动系统](#section85351839162211)
- [运行“Hello World”](#section137849131182)
- [下一步](#section5600113114323)
## 启动系统<a name="section85351839162211"></a>
烧录完成后通过以下步骤运行系统:
>![](../public_sys-resources/icon-note.gif) **说明:**
>初次烧写标准系统,需要完成以下配置,后续烧写或者启动,可以跳过以下操作。
1. 在DevEco Device Tool中,点击Monitor,打开串口工具。
![](figures/open-the-serial-port-tool.png)
2. 重启开发板,在倒计时结束前,按任意键进入系统。
![](figures/press-any-key-to-enter-the-system.gif)
3. 通过以下两条命令设置启动参数。
```
setenv bootargs 'mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M clk_ignore_unused rootdelay=10 hardware=Hi3516DV300 init=/init root=/dev/ram0 rw blkdevparts=mmcblk0:1M(boot),15M(kernel),20M(updater),2M(misc),3307M(system),256M(vendor),-(userdata)';
```
```
setenv bootcmd 'mmc read 0x0 0x82000000 0x800 0x4800; bootm 0x82000000'
```
![](figures/setenv-bootargs.png)
4. 保存参数设置。
```
save
```
![](figures/Save-the-parameter-settings.png)
5. 重启开发板,完成系统启动。
```
reset
```
![](figures/start-the-system.png)
## 运行“Hello World”<a name="section137849131182"></a>
设备启动后打开串口工具,在任意目录下输入命令helloworld后回车,即出现“Hello World!”字样。
![](figures/zh-cn_image_0000001193533352.png)
## 下一步<a name="section5600113114323"></a>
恭喜!您已经完成了OpenHarmony标准系统的快速入门,接下来可[开发一个小示例](../guide/device-clock-guide.md),进一步熟悉OpenHarmony的开发。
# Hi3516开发板<a name="ZH-CN_TOPIC_0000001188686298"></a>
- **[创建应用程序](quickstart-standard-running-hi3516-create.md)**
- **[源码编译](quickstart-standard-running-hi3516-build.md)**
- **[镜像烧录](quickstart-standard-running-hi3516-burn.md)**
- **[镜像运行](quickstart-standard-running-hi3516-run.md)**
# 源码编译<a name="ZH-CN_TOPIC_0000001188207862"></a>
- [使用Docker方式获取编译工具链](#section181431248132513)
- [执行prebuilts](#section111934551605)
- [安装Docker](#section1466184743915)
- [获取Docker环境](#section615912103552)
- [使用安装包方式获取编译工具链](#section65647482593)
- [安装依赖工具](#section83441888010)
- [执行prebuilts](#section6389714142011)
- [编译](#section92391739152318)
安装编译工具链后,即可对源码进行编译。在Linux环境下获取编译工具链有以下两种方式,二者选其一即可:
1. Docker方式
OpenHarmony标准系统为开发者提供的Docker环境已经将对应的编译工具链进行了封装,开发者可省略对应工具的安装。
2. 安装包方式
使用安装包方式获取编译工具链时,开发者需自行安装相应的依赖工具。
## 使用Docker方式获取编译工具链<a name="section181431248132513"></a>
### 执行prebuilts<a name="section111934551605"></a>
在源码根目录下执行脚本,安装编译器及二进制工具。
```
bash build/prebuilts_download.sh
```
### 安装Docker<a name="section1466184743915"></a>
请参考[官方指导](https://docs.docker.com/engine/install/)
### 获取Docker环境<a name="section615912103552"></a>
**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:**
1. 获取Docker镜像。
```
docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.5
```
2. 进入源码根目录执行如下命令,从而进入Docker构建环境。
```
docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.5
```
**方式二:通过Dockerfile 构建本地Docker镜像进行构建**
1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。
```
git clone https://gitee.com/openharmony/docs.git
```
2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。
```
cd docs/docker/standard
./build.sh
```
3. 进入源码根目录执行如下命令,从而进入Docker构建环境。
```
docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.5
```
## 使用安装包方式获取编译工具链<a name="section65647482593"></a>
### 安装依赖工具<a name="section83441888010"></a>
请在终端中输入如下命令安装编译相关的依赖工具:
```
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 ruby
```
>![](../public_sys-resources/icon-note.gif) **说明:**
>以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。其中Python要求安装Python 3.7及以上版本,此处以Python 3.8为例。
### 执行prebuilts<a name="section6389714142011"></a>
在源码根目录下执行脚本,安装编译器及二进制工具。
```
bash build/prebuilts_download.sh
```
## 编译<a name="section92391739152318"></a>
1. 进入源码根目录,执行如下命令进行版本编译。
>![](../public_sys-resources/icon-note.gif) **说明:**
>使用Docker方式获取编译工具链的,请直接通过[获取Docker环境](#section615912103552)最后一步进入的Docker构建环境执行如下命令。
```
./build.sh --product-name rk3568 --ccache
```
2. 检查编译结果。编译完成后,log中显示如下:
```
post_process
=====build rk3568 successful.
```
编译所生成的文件都归档在out/\{device\_name\}/目录下,结果镜像输出在out/\{device\_name\}/packages/phone/images/ 目录下。
>![](../public_sys-resources/icon-note.gif) **说明:**
>其他模块化编译操作,可参见[编译构建指导](../subsystems/subsys-build-standard-large.md)。
3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](quickstart-standard-running-hi3516-burn.md)
>![](../public_sys-resources/icon-note.gif) **说明:**
>若使用Docker环境进行编译,执行exit命令即可退出Docker。
# 镜像烧录<a name="ZH-CN_TOPIC_0000001233805979"></a>
请参考:[HiHope\_DAYU200烧写工具及指南](https://gitee.com/hihope_iot/docs/blob/master/HiHope_DAYU200/%E7%83%A7%E5%86%99%E5%B7%A5%E5%85%B7%E5%8F%8A%E6%8C%87%E5%8D%97/HiHope-DAYU200%E9%95%9C%E5%83%8F%E7%83%A7%E5%BD%95%E6%8C%87%E5%8D%97.pdf)
# 创建应用程序<a name="ZH-CN_TOPIC_0000001234205905"></a>
下方将通过修改源码的方式展示如何在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello World!”。
这里演示在原有applications子系统下,添加hello部件以及该部件下的helloworld模块。
示例完整目录如下。
```
applications/standard/hello
├── helloworld
│ ├── include
│ │ └── helloworld.h
│ └── src
│ └── helloworld.c
├── BUILD.gn
├── ohos.build
productdefine/common
└── products
└── rk3568.json
```
下方为新建应用程序步骤,请在[获取源码](quickstart-standard-sourcecode-acquire.md)章节下载的源码目录中进行下述操作:
1. 新建目录及源码。
新建applications/standard/hello/helloworld/src/helloworld.c目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改World为OHOS)。其中helloworld.h包含字符串打印函数HelloPrint的声明。当前应用程序可支持标准C及C++的代码开发。
```
#include <stdio.h>
#include "helloworld.h"
int main(int argc, char **argv)
{
HelloPrint();
return 0;
}
void HelloPrint()
{
printf("\n************************************************\n");
printf("\n\t\tHello World!\n");
printf("\n************************************************\n");
}
```
再添加头文件applications/standard/hello/helloworld/include/helloworld.h,代码如下所示。
```
#ifndef HELLOWORLD_H
#define HELLOWORLD_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
void HelloPrint();
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // HELLOWORLD_H
```
2. 新建编译组织文件。
1. 新建applications/standard/hello/BUILD.gn文件,内容如下所示。
```
import("//build/ohos.gni") # 导入编译模板
ohos_executable("helloworld") { # 可执行模块
sources = [ # 模块源码
"src/helloworld.c"
]
include_dirs = [ # 模块依赖头文件目录
"include"
]
cflags = []
cflags_c = []
cflags_cc = []
ldflags = []
configs = []
deps =[] # 部件内部依赖
part_name = "hello" # 所属部件名称,必选
install_enable = true # 是否默认安装(缺省默认不安装),可选
}
```
2. 新建applications/standard/hello/ohos.build文件,添加hello部件描述,内容如下所示。
```
{
"subsystem": "applications", # 子系统名
"parts": { # 包含部件
"hello": { # 新建部件名
"version": "1.0.0", # 版本
"variants": [ # 变种版本
"wearable",
"phone"
],
"module_list": [ # 部件包含模块的gn目标
"//applications/standard/hello:helloworld"
],
"inner_kits": [ # 提供给其他部件的接口
],
"test_list": [ # 测试用例
]
}
}
}
```
ohos.build文件包含两个部分,第一部分subsystem说明该子系统的名称,parts定义该子系统包含的部件,要添加一个部件,需要把该部件对应的内容添加进parts中去。添加的时候需要指明该部件包含的模块module\_list,假如有提供给其它部件的接口,需要在inner\_kits中说明,假如有测试用例,需要在test\_list中说明,inner\_kits与test\_list没有也可以不添加。
3. 修改产品配置文件。
在productdefine\\common\\products\\rk3568.json中添加对应的部件,直接添加到原有部件后即可(如下代码加粗部分)。
```
"usb:usb_manager_native":{},
"applications:prebuilt_hap":{},
"applications:hello":{},
"wpa_supplicant-2.9:wpa_supplicant-2.9":{},
```
# 镜像运行<a name="ZH-CN_TOPIC_0000001233927469"></a>
- [启动系统](#section646361191511)
- [运行“Hello World”](#section11845976150)
## 启动系统<a name="section646361191511"></a>
镜像烧录完成并连接电源线之后,系统将会自动启动。开发板附带的屏幕呈现以下界面,表明系统已运行成功。
**图 1** 系统启动效果图<a name="fig1642274764110"></a>
![](figures/系统启动效果图.jpg "系统启动效果图")
## 运行“Hello World”<a name="section11845976150"></a>
- 设备启动后打开串口工具(以putty为例),波特率设置为1500000,连接设备。
![](figures/rk3568-run-configuration.png)
- 打开串口后,在任意目录(以设备根目录为例)下输入命令helloworld后回车,即出现“Hello World!”字样。
![](figures/rk3568-helloworld.png)
# RK3568开发板<a name="ZH-CN_TOPIC_0000001234047409"></a>
- **[创建应用程序](quickstart-standard-running-rk3568-create.md)**
- **[源码编译](quickstart-standard-running-rk3568-build.md)**
- **[镜像烧录](quickstart-standard-running-rk3568-burn.md)**
- **[镜像运行](quickstart-standard-running-rk3568-run.md)**
# 镜像运行<a name="ZH-CN_TOPIC_0000001142160948"></a> # 运行“Hello World”<a name="ZH-CN_TOPIC_0000001188526386"></a>
- [镜像运行](#section153991115191314) - **[Hi3516开发板](quickstart-standard-running-hi3516.md)**
- [下一步](#section5600113114323)
## 镜像运行<a name="section153991115191314"></a> - **[RK3568开发板](quickstart-standard-running-rk3568.md)**
烧录完成后通过以下步骤运行系统:
>![](../public_sys-resources/icon-note.gif) **说明:**
>初次烧写标准系统,需要完成以下配置,后续烧写或者启动,可以跳过以下操作。
1. 在DevEco Device Tool中,点击Monitor,打开串口工具。
![](figures/open-the-serial-port-tool.png)
2. 重启开发板,在倒计时结束前,按任意键进入系统。
![](figures/press-any-key-to-enter-the-system.gif)
3. 通过以下两条命令设置启动参数。
```
setenv bootargs 'mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M clk_ignore_unused rootdelay=10 hardware=Hi3516DV300 init=/init root=/dev/ram0 rw blkdevparts=mmcblk0:1M(boot),15M(kernel),20M(updater),2M(misc),3307M(system),256M(vendor),-(userdata)';
```
```
setenv bootcmd 'mmc read 0x0 0x82000000 0x800 0x4800; bootm 0x82000000'
```
![](figures/zh-cn_image_0000001172030062.png)
4. 保存参数设置。
```
save
```
![](figures/Save-the-parameter-settings.png)
5. 重启开发板,完成系统启动。
```
reset
```
![](figures/start-the-system.png)
## 下一步<a name="section5600113114323"></a>
恭喜!您已经完成了OpenHarmony标准系统的快速入门,接下来可[开发一个小示例](../guide/device-clock-guide.md),进一步熟悉OpenHarmony的开发。
# 获取源码<a name="ZH-CN_TOPIC_0000001188523654"></a>
### 前提条件<a name="section1787412417496"></a>
1. 注册码云gitee账号。
2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)
3. 安装[git客户端](https://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
```
### 获取方式<a name="section1715918316415"></a>
>![](../public_sys-resources/icon-note.gif) **说明:**
>Master主干为开发分支,开发者可通过Master主干获取最新特性。发布版本代码相对比较稳定,开发者可基于发布版本代码进行商用功能开发。
- **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发布版本代码获取**
OpenHarmony发布版本获取源码方式请参考[Release-Notes](../get-code/../../release-notes/Readme.md)。
# Windows开发环境准备<a name="ZH-CN_TOPIC_0000001216019037"></a>
- [安装DevEco Device Tool](#zh-cn_topic_0000001058091994_section10761564496)
系统要求:
- Windows 10 64位系统。
- 系统的用户名不能含有中文字符。
## 安装DevEco Device Tool<a name="zh-cn_topic_0000001058091994_section10761564496"></a>
DevEco Device Tool以插件方式运行,基于Visual Studio Code进行扩展,同时DevEco Device Tool运行依赖Python,Node.js和hpm工具。
DevEco Device Tool支持一体化安装,即DevEco Device Tool安装向导会检测系统是否安装Visual Studio Code、Python、Node.js、hpm的适配版本,当安装向导未检测到这些软件时,会给出相应的提示,根据提示勾选要自动安装的软件,安装向导会自动下载相应的软件进行安装。
安装DevEco Device Tool,**主机的用户名不能包含中文字符**,否则在运行DevEco Device Tool时,DevEco Home界面会一直处于Loading状态,导致不能正常使用
1. 获取软件,请使用华为开发者帐号登录[https://device.harmonyos.com/cn/ide\#download\_beta](https://device.harmonyos.com/cn/ide#download_beta),下载DevEco Device Tool V3.0 Beta1及以上版本。如未注册华为开发者账号,请先[注册](https://developer.huawei.com/consumer/cn/doc/start/registration-and-verification-0000001053628148)
2. 解压DevEco Device Tool压缩包,双击安装包程序,点击Next进行安装。
3. 设置DevEco Device Tool的安装路径,点击Next。
4. 根据安装向导提示,勾选要自动安装的软件,点击Next。
![](figures/Snap28.png)
>![](../public_sys-resources/icon-note.gif) **说明:**
>当安装向导检测到系统中已安装可兼容的Python版本,会提示用户可选择已安装的可兼容的Python版本,也可选择下载推荐的Python版本。
5. 在以下界面点击Next,进行软件下载和安装。
![](figures/Snap8.png)
6. 在弹出的Python安装向导中,勾选“**Add Python 3.8 to PATH**”,然后点击**Install Now**开始安装,等待安装完成后,点击**Close**
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装可兼容的Python版本,且用户选择了已安装的可兼容的Python版本,则Python安装向导不会弹出,用户不需要执行此步骤。
>如果安装DevEco Device Tool 2.1 Release版本,Python版本只能为3.8.x版本,不能安装最新的Python3.9.x版本。如果安装DevEco Device Tool V3.0 Beta1及以上版本,Python版本只能为3.8.x或3.9.x版本。
![](figures/Snap34.png)
7. 在弹出的Visual Studio Code安装向导中,根据向导提示安装Visual Studio Code,安装过程中,请勾选“添加到PATH(重启后生效)”。
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装正确的Visual Studio Code版本,则Visual Studio Code安装向导不会弹出,用户不需要执行此步骤。
![](figures/Snap33.png)
8. 在弹出的Node.js安装向导中,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装正确的Node.js版本,则Node.js安装向导不会弹出,用户不需要执行此步骤。
9. 等待DevEco Device Tool安装向导自动安装hpm和DevEco Device Tool插件,直至安装完成,点击**Finish**,关闭DevEco Device Tool安装向导。
>![](../public_sys-resources/icon-note.gif) **说明:**
>当DevEco Device Tool安装向导检测系统已安装正确的hpm版本,则不会进行hpm软件的下载和安装。
10. 启动Visual Studio Code,会自动安装DevEco Device Tool依赖的C/C++、CodeLLDB插件。等待安装完成后,点击Visual Studio Code左侧的![](figures/button.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/deveco-device-tool-install-sucessful.png)
# 标准系统入门<a name="ZH-CN_TOPIC_0000001111221726"></a> # 标准系统入门<a name="ZH-CN_TOPIC_0000001111221726"></a>
- **[入门介绍](quickstart-standard-overview.md)** - **[标准系统入门简介](quickstart-standard-overview.md)**
- **[Windows开发环境准备](quickstart-standard-windows-environment.md)** - **[标准系统开发环境准备(仅Hi3516需要)](quickstart-standard-env-setup.md)**
- **[搭建Ubuntu环境\(获取源码及编译,Docker方式\)](quickstart-standard-docker-environment.md)** - **[获取源码](quickstart-standard-sourcecode-acquire.md)**
- **[搭建Ubuntu环境\(获取源码及编译,安装包方式\)](quickstart-standard-package-environment.md)** - **[运行“Hello World”](quickstart-standard-running.md)**
- **[镜像烧录](quickstart-standard-burn.md)**
- **[镜像运行](quickstart-standard-running.md)**
- **[常见问题](quickstart-standard-faqs.md)** - **[常见问题](quickstart-standard-faqs.md)**
- **[附录](quickstart-standard-appendix.md)**
...@@ -40,18 +40,10 @@ ...@@ -40,18 +40,10 @@
- [唤醒词识别SDK的开发示例](subsys-aiframework-demo-sdk.md) - [唤醒词识别SDK的开发示例](subsys-aiframework-demo-sdk.md)
- [唤醒词识别插件的开发示例](subsys-aiframework-demo-plugin.md) - [唤醒词识别插件的开发示例](subsys-aiframework-demo-plugin.md)
- [唤醒词识别配置文件的开发示例](subsys-aiframework-demo-conf.md) - [唤醒词识别配置文件的开发示例](subsys-aiframework-demo-conf.md)
- [数据管理](subsys-database.md)
- [关系型数据库](subsys-database-relational.md)
- [关系型数据库概述](subsys-database-relational-overview.md)
- [关系型数据库开发指导](subsys-database-relational-guide.md)
- [Sensor服务](subsys-sensor.md) - [Sensor服务](subsys-sensor.md)
- [Sensor服务子系概述](subsys-sensor-overview.md) - [Sensor服务子系概述](subsys-sensor-overview.md)
- [Sensor服务子系使用指导](subsys-sensor-guide.md) - [Sensor服务子系使用指导](subsys-sensor-guide.md)
- [Sensor服务子系使用实例](subsys-sensor-demo.md) - [Sensor服务子系使用实例](subsys-sensor-demo.md)
- [Usb服务子系统](subsys-usbservice.md)
- [USB服务子系统概述](subsys-usbservice-overview.md)
- [USB服务子系统使用指导](subsys-usbservice-guide.md)
- [USB服务子系统使用实例](subsys-usbservice-demo.md)
- [用户程序框架](subsys-application-framework.md) - [用户程序框架](subsys-application-framework.md)
- [概述](subsys-application-framework-overview.md) - [概述](subsys-application-framework-overview.md)
- [搭建环境](subsys-application-framework-envbuild.md) - [搭建环境](subsys-application-framework-envbuild.md)
...@@ -79,8 +71,15 @@ ...@@ -79,8 +71,15 @@
- [DFX概述](subsys-dfx-overview.md) - [DFX概述](subsys-dfx-overview.md)
- [HiLog开发指导](subsys-dfx-hilog-rich.md) - [HiLog开发指导](subsys-dfx-hilog-rich.md)
- [HiLog\_Lite开发指导](subsys-dfx-hilog-lite.md) - [HiLog\_Lite开发指导](subsys-dfx-hilog-lite.md)
- [HiTrace开发指导](subsys-dfx-hitrace.md)
- [HiCollie开发指导](subsys-dfx-hicollie.md)
- [HiSysEvent开发指导](subsys-dfx-hisysevent.md) - [HiSysEvent开发指导](subsys-dfx-hisysevent.md)
- [HiSysEvent打点指导](subsys-dfx-hisysevent-write.md)
- [HiSysEvent订阅指导](subsys-dfx-hisysevent-read.md)
- [HiSysEvent查询指导](subsys-dfx-hisysevent-select.md)
- [HiSysEvent工具使用指导](subsys-dfx-hisysevent-tool.md)
- [研发工具链](subsys-toolchain.md) - [研发工具链](subsys-toolchain.md)
- [bytrace使用指导](subsys-toolchain-bytrace-guide.md) - [bytrace使用指导](subsys-toolchain-bytrace-guide.md)
- [hdc\_std 使用指导](subsys-toolchain-hdc-guide.md) - [hdc\_std 使用指导](subsys-toolchain-hdc-guide.md)
- [hiperf 使用指南](subsys-toolchain-hiperf.md)
- [XTS认证用例开发指导](subsys-xts-guide.md) - [XTS认证用例开发指导](subsys-xts-guide.md)
# 关系型数据库开发指导
## 场景介绍
关系型数据库是在SQLite基础上实现的本地数据操作机制,提供给用户无需编写原生SQL语句就能进行数据增删改查的方法,同时也支持原生SQL语句操作。
## 接口说明
### 数据库的创建和删除
关系型数据库提供了数据库创建方式,以及对应的删除接口,涉及的API如下所示。
表1 数据库创建和删除API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| RdbStoreConfig | RdbStoreConfig(const std::string &path, <br> StorageMode storageMode = StorageMode::MODE_DISK, <br> bool readOnly = false, <br> const std::vector<uint8_t> &encryptKey = std::vector<uint8_t>(), <br> const std::string &journalMode = "", <br> const std::string &syncMode = "", <br> const std::string &databaseFileType = "", <br> const std::string &databaseFileSecurityLevel = "") | 对数据库进行配置,包括设置数据库名、存储模式、日志模式、同步模式,是否为只读,及数据库加密。 <ul><li> path:数据库路径;</li><li> readOnly:是否只读;</li><li> storageMode:存储模式;</li><li> encryptKey:加密密钥; </li><li> journalMode:日志模式;</li><li> syncMode:同步模式;</li><li> databaseFileType:数据库类型; </li><li> databaseFileSecurityLevel:安全等级 </li></ul> |
| RdbOpenCallback | int OnCreate(RdbStore &rdbStore) | 数据库创建时被回调,开发者可以在该方法中初始化表结构,并添加一些应用使用到的初始化数据。 |
| RdbOpenCallback | int OnUpgrade(RdbStore &rdbStore, int currentVersion, int targetVersion) | 数据库升级时被回调。 |
| RdbOpenCallback | int OnDowngrade(RdbStore &rdbStore, int currentVersion, int targetVersion) | 数据库降级时被回调。 |
| RdbHelper | std::shared_ptr\<RdbStore\> GetRdbStore(const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback, int &errCode) | 根据配置创建或打开数据库。 |
| RdbHelper | int DeleteRdbStore(const std::string &path) | 删除指定的数据库。 |
### 数据库的加密
关系型数据库提供数据库加密的能力,在创建数据库时若指定了密钥,则会创建为加密数据库。再次使用此数据库时,需要指定该密钥,才能正确打开数据库。
表2 数据库修改密钥API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| RdbStore | int ChangeEncryptKey(const std::vector<uint8_t> &newKey) | 为数据库设置新的加密密钥。注:仅支持加密数据库更换加密密钥。 |
### 数据库谓词的使用
关系型数据库提供了用于设置数据库操作条件的谓词AbsRdbPredicates,其中包括两个实现子类RdbPredicates和RawRdbPredicates:
- RdbPredicates:开发者无需编写复杂的SQL语句,仅通过调用该类中条件相关的方法,如equalTo、notEqualTo、groupBy、orderByAsc、beginsWith等,就可自动完成SQL语句拼接,方便用户聚焦业务操作。
- RawRdbPredicates:可满足复杂SQL语句的场景,支持开发者自己设置where条件子句和whereArgs参数。不支持equalTo等条件接口的使用。
表7 数据库谓词API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| RdbPredicates | AbsPredicates *EqualTo(std::string field, std::string value) | 设置谓词条件,满足field字段与value值相等。 |
| RdbPredicates | AbsPredicates *NotEqualTo(std::string field, std::string value) | 设置谓词条件,满足field字段与value值不相等。 |
| RdbPredicates | AbsPredicates *BeginsWith(std::string field, std::string value) | 设置谓词条件,满足field字段以value值开头。 |
| RdbPredicates | AbsPredicates *Between(std::string field, std::string low, std::string high) | 设置谓词条件,满足field字段在最小值low和最大值high之间。 |
| RdbPredicates | AbsPredicates *OrderByAsc(std::string field) | 设置谓词条件,根据field字段升序排列。 |
| RdbPredicates | void SetWhereClause(std::string whereClause) | 设置where条件子句。 |
| RdbPredicates | void SetWhereArgs(std::vector\<std::string\> whereArgs) | 设置whereArgs参数,该值表示where子句中占位符的值。 |
### 数据表的增删改查
关系型数据库提供对本地数据增删改查操作的能力,相关API如下所示。
- 新增
关系型数据库提供了插入数据的接口,通过ValuesBucket输入要存储的数据,通过返回值判断是否插入成功,插入成功时返回最新插入数据所在的行号,失败时则返回-1。
表3 数据表插入API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| RdbStore | int Insert(int64_t &outRowId, const std::string &table, const ValuesBucket &initialValues) | 向数据库插入数据。<ul><li>table:待添加数据的表名。 </li><li> initialValues:以ValuesBucket存储的待插入的数据。它提供一系列put方法,如PutString(const std::string &columnName, const std::string &value),PutDouble(const std::string &columnName, double value),用于向ValuesBucket中添加数据。</li></ul> |
- 删除
调用删除接口,通过AbsRdbPredicates指定删除条件。该接口的返回值表示删除的数据行数,可根据此值判断是否删除成功。如果删除失败,则返回0。
表5 数据表删除API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| RdbStore | int Delete(int &deletedRows, const AbsRdbPredicates &predicates) | 删除数据。<ul><li> deletedRows:删除的记录条数。 </li><li> predicates:Rdb谓词,指定了删除操作的表名和条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。<ul><li> RdbPredicates:支持调用谓词提供的equalTo等接口,设置更新条件。</li><li> RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。 </li></ul></li></ul> |
- 更新
调用更新接口,传入要更新的数据,并通过AbsRdbPredicates指定更新条件。该接口的返回值表示更新操作影响的行数。如果更新失败,则返回0。
表4 数据表更新API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| RdbStore | int Update(int &changedRows, const ValuesBucket &values, const AbsRdbPredicates &predicates) | 更新数据库表中符合谓词指定条件的数据。<ul><li> changedRows:更新的记录条数。 </li><li> values:以ValuesBucket存储的要更新的数据。 </li><li> predicates:指定了更新操作的表名和条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。<ul><li> RdbPredicates:支持调用谓词提供的equalTo等接口,设置更新条件。</li><li> RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。 </li></ul></li></ul> |
- 查询
关系型数据库提供了两种查询数据的方式:
- 直接调用查询接口。使用该接口,会将包含查询条件的谓词自动拼接成完整的SQL语句进行查询操作,无需用户传入原生的SQL语句。
- 执行原生的SQL语句进行查询操作。
表6 数据表查询API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| RdbStore | std::unique_ptr<AbsSharedResultSet> Query(const AbsRdbPredicates &predicates, const std::vector\<std::string\> columns) | 查询数据。<ul><li> predicates:谓词,可以设置查询条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。<ul><li> RdbPredicates:支持调用谓词提供的equalTo等接口,设置更新条件。</li><li> RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。 </li></ul> <li> columns:规定查询返回的列。</li></ul></li></ul> |
| RdbStore | std::unique_ptr<AbsSharedResultSet> QuerySql(const std::string &sql, const std::vector\<std::string\> &selectionArgs = std::vector\<std::string\>()) | 执行原生的用于查询操作的SQL语句。<ul><li> sql:原生用于查询的sql语句。</li><li> selectionArgs:sql语句中占位符参数的值,若select语句中没有使用占位符,该参数可以设置为null。</li></ul> |
### 查询结果集的使用
关系型数据库提供了查询返回的结果集ResultSet,其指向查询结果中的一行数据,供用户对查询结果进行遍历和访问。ResultSet对外API如下所示。
表8 结果集API
| 类名 | 接口名 | 描述 |
| ---- | ---- | ---- |
| ResultSet | int GoTo(int offset) | 从结果集当前位置移动指定偏移量。 |
| ResultSet | int GoToRow(int position) | 将结果集移动到指定位置。 |
| ResultSet | int GoToNextRow() | 将结果集向后移动一行。 |
| ResultSet | int GoToPreviousRow() | 将结果集向前移动一行。 |
| ResultSet | int IsStarted(bool &result) | 判断结果集是否被移动过。 |
| ResultSet | int IsEnded(bool &result) | 判断结果集是否被移动到最后一行之后。 |
| ResultSet | int IsAtFirstRow(bool &result) | 判断结果集当前位置是否在第一行。 |
| ResultSet | int IsAtLastRow(bool &result) | 判断结果集当前位置是否在最后一行。 |
| ResultSet | int GetRowCount(int &count) | 获取当前结果集中的记录条数。 |
| ResultSet | int GetColumnCount(int &count) | 获取结果集中的列数。 |
| ResultSet | int GetString(int columnIndex, std::string &value) | 获取当前行指定列的值,以String类型返回。 |
| ResultSet | int GetBlob(int columnIndex, std::vector\<uint8_t\> &blob) | 获取当前行指定列的值,以字节数组形式返回。 |
| ResultSet | int GetDouble(int columnIndex, double &value) | 获取当前行指定列的值,以double型返回。 |
## 约束与限制
无。
## 开发步骤
1. 创建数据库。
a. 配置数据库相关信息,包括数据库的名称、存储模式、是否为只读模式等。
b. 初始化数据库表结构和相关数据。
c. 创建数据库。
示例代码如下:
```
const std::string DATABASE_NAME = RDB_TEST_PATH + "RdbStoreTest.db";
const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, salary REAL, blobType BLOB)";
class OpenCallback : public RdbOpenCallback {
public:
int OnCreate(RdbStore &rdbStore) override;
int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override;
};
int OpenCallback::OnCreate(RdbStore &store)
{
return store.ExecuteSql(CREATE_TABLE_TEST);
}
RdbStoreConfig config(DATABASE_NAME);
OpenCallback callback;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, callback, 0);
```
2. 插入数据。
a. 构造要插入的数据,以ValuesBucket形式存储。
b. 调用关系型数据库提供的插入接口。
c. 创建数据库。
示例代码如下:
```
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("Tom"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
store->Insert(id, "test", values);
```
3. 查询数据。
a. 构造用于查询的谓词对象,设置查询条件。
b. 指定查询返回的数据列。
c. 调用查询接口查询数据。
d. 调用结果集接口,遍历返回结果。
示例代码如下:
```
std::vector<std::string> columns = {"id", "name", "age", "salary"};
RdbPredicates predicates("test");
predicates.EqualTo("age", "25")->OrderByAsc("salary");
std::unique_ptr<ResultSet> resultSet = store->Query(predicates, columns)
resultSet.goToNextRow();
```
# 关系型数据库概述
关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。OpenHarmony关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。
## 基本概念
- 关系型数据库
基于关系模型来管理数据的数据库,以行和列的形式存储数据。
- 谓词
数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
- 结果集
指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便的拿到用户想要的数据。
- SQLite数据库
一款遵守ACID的轻型开源关系型数据库管理系统。
## 运作机制
OpenHarmony关系型数据库对外提供通用的操作接口(即Rdb Store接口),底层使用第三方开源组件SQLite作为持久化存储引擎,支持SQLite具有的所有数据库特性。
**图1** 关系型数据库运作机制
![](figure/zh-cn_image_0000001115980740.png)
## 默认配置
- 如果不指定数据库的日志模式,那么系统默认日志方式是WAL(Write Ahead Log)模式。
- 如果不指定数据库的落盘模式,那么系统默认落盘方式是FULL模式。
- OpenHarmony数据库使用的共享内存默认大小是8MB,单次查询使用的共享内存默认大小是2MB。
## 约束与限制
- 数据库中连接池的最大数量是4个,用以管理用户的读操作。
- 为保证数据的准确性,数据库同一时间只能支持一个写操作。
# 关系型数据库
- **[关系型数据库概述](subsys-database-relational-overview.md)**
- **[关系型数据库开发指导](subsys-database-relational-guide.md)**
# 轻量级数据存储开发指导
## 场景介绍
轻量级数据存储功能通常用于保存应用的一些常用配置信息,并不适合需要存储大量数据和频繁改变数据的场景。应用的数据保存在文件中,这些文件可以持久化地存储在设备上。需要注意的是,应用访问的实例包含文件所有数据,这些数据会一直加载在设备的内存中,直到应用主动从内存中将其移除前,应用可以通过Preferences的API进行数据操作。
## 接口说明
轻量级存储为应用提供key-value键值型的文件数据处理能力,支持应用对数据进行轻量级存储及查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括字符串型、布尔型、整数型、长整型、浮点型、双精度类型和字符串数组。
**创建存储实例**
读取指定文件,将数据加载到Preferences实例,即可创建一个存储实例,用于数据操作。
**表 1** 轻量级数据存储实例创建接口
| 类名 | 方法名 | 描述 |
| --- | ----- | ----|
| PreferencesHelper | static std::shared_ptr<Preferences> GetPreferences(const std::string &path, int &errCode); | path:应用程序内部数据存储路径。<br/>errCode:错误码。<br/>返回值:轻量级存储实例。 |
**存入数据**
通过Put系列方法,可以增加或修改Preferences实例中的数据。
**表 2** 轻量级偏好数据库存入接口
| 类名 | 方法名 | 描述 |
| --- | ----- | ----|
| Preferences | int PutInt(const std::string &key, int value); | key:将要存储的key名称,不能为空。<br/>value:将要存储的value。<br/>返回值:错误码。 |
| Preferences | int PutString(const std::string &key, const std::string &value); | key:将要存储的key名称,不能为空。<br/>value:将要存储的value。<br/>返回值:错误码。 |
| Preferences | int PutBool(const std::string &key, bool value); | key:将要存储的key名称,不能为空。<br/>value:将要存储的value。<br/>返回值:错误码。 |
| Preferences | int PutLong(const std::string &key, int64_t value); | key:将要存储的key名称,不能为空。<br/>value:将要存储的value。<br/>返回值:错误码。 |
| Preferences | int PutFloat(const std::string &key, float value); | key:将要存储的key名称,不能为空。<br/>value:将要存储的value。<br/>返回值:错误码。 |
| Preferences | int PutDouble(const std::string &key, double value); | key:将要存储的key名称,不能为空。<br/>value:将要存储的value。<br/>返回值:错误码。 |
| Preferences | int PutStringSet(const std::string &key, const std::set\<std::string\> &value); | key:将要存储的key名称,不能为空。<br/>value:将要存储的。<br/>返回值:错误码。 |
**读取数据**
通过调用Get系列方法,可以读取Preferences中的数据。
**表 3** 轻量级数据读取接口
| 类名 | 方法名 | 描述 |
| --- | ----- | ----|
| Preferences | bool GetBool(const std::string &key, bool defValue); | key:要获取的存储key名称,不能为空。<br/>defValue:若获取失败或value不存在返回此默认值。<br/>返回值:value。 |
| Preferences | std::string GetString(const std::string &key, const std::string &defValue); | key:要获取的存储key名称,不能为空。<br/>defValue:若获取失败或value不存在返回此默认值。<br/>返回值:value。 |
| Preferences | bool GetBool(const std::string &key, bool defValue); | key:要获取的存储key名称,不能为空。<br/>defValue:若获取失败或value不存在返回此默认值。<br/>返回值:value。 |
| Preferences | float GetFloat(const std::string &key, float defValue); | key:要获取的存储key名称,不能为空。<br/>defValue:若获取失败或value不存在返回此默认值。<br/>返回值:value。 |
| Preferences | double GetDouble(const std::string &key, double defValue); | key:要获取的存储key名称,不能为空。<br/>defValue:若获取失败或value不存在返回此默认值。<br/>返回值:value。 |
| Preferences | int64_t GetLong(const std::string &key, int64_t defValue); | key:要获取的存储key名称,不能为空。<br/>defValue:若获取失败或value不存在返回此默认值。<br/>返回值:value。 |
| Preferences | std::set\<std::string\> GetStringSet(const std::string &key, std::set\<std::string\> &defValue); | key:要获取的存储key名称,不能为空。<br/>defValue:若获取失败或value不存在返回此默认值。<br/>返回值:value。 |
**数据持久化**
通过执行flush或者flushSync方法,应用可以将缓存的数据再次写回文本文件中进行持久化存储。
**表 5** 轻量级数据数据持久化接口
| 类名 | 方法名 | 描述 |
| --- | ----- | ----|
| Preferences | void Flush(); | 将Preferences实例通过异步线程回写入文件中。 |
| Preferences | int FlushSync(); | 将Preferences实例通过同步线程回写入文件中,并返回错误码。 |
**订阅数据变化**
订阅数据变化需要指定PreferencesObserver作为回调方法。订阅的key的值发生变更后,当执行flush方法时,PreferencesObserver被回调。
**表 5** 轻量级数据变化订阅接口
| 类名 | 方法名 | 描述 |
| --- | ----- | ----|
| Preferences | void RegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver); | preferencesObserver:需要订阅的回调对象实例。 |
| Preferences | void UnRegisterObserver(std::shared_ptr<PreferencesObserver> preferencesObserver); | preferencesObserver:需要注销订阅的回调对象实例。 |
**删除数据文件**
通过调用以下两种接口,可以删除数据实例或对应的文件。
**表 6** 轻量级数据存储删除接口
| 类名 | 方法名 | 描述 |
| --- | ----- | ----|
| PreferencesHelper | int DeletePreferences(const std::string &path); | 将Preferences实例从内存中移除,同时删除其在设备上的持久化文件。path:应用程序内部数据存储路径。<br/>返回值:错误码。 |
| PreferencesHelper | int RemovePreferencesFromCache(const std::string &path); | 仅将Preferences实例从内存中移除。path:应用程序内部数据存储路径。<br/>返回值:错误码。 |
## 开发步骤
1. 准备工作,引入preferences以及相关的头文件到开发环境。
``` C++
头文件路径://distributeddatamgr_appdatamgr/interfaces/innerkits/native_preferences/include
```
2. 获取Preferences实例。
读取指定文件,将数据加载到Preferences实例,用于数据操作。
``` C++
int errCode = E_OK;
Preferences pref = PreferencesHelper::GetPreferences(PREF_TEST_PATH + "test.xml", errCode); // PREF_TEST_PATH须为应用沙箱路径。
EXPECT_EQ(errCode, E_OK);
```
3. 存入数据。
使用Preferences put方法保存数据到缓存的实例中。
```C++
pref->PutString("test", "remove");
```
4. 读取数据。
使用Preferences get方法读取数据。
``` C++
std::string ret = pref->GetString("test", "defaultValue");
EXPECT_EQ(ret, "remove");
```
5. 数据持久化。
应用存入数据到Preferences实例后,可以通过flush或者flushSync方法将Preferences实例回写到文件中。
```C++
int err = pref->FlushSync();
EXPECT_EQ(ret, E_OK);
```
6. 订阅数据变化。
应用订阅数据变化需要指定PreferencesObserver作为回调方法。订阅的key的值发生变更后,当执行flush或者flushSync方法时,PreferencesObserver被触发回调。不再需要PreferencesObserver时请注销。
自定义类,实现PreferencesObserver接口:
``` C++
class PreferencesObserverCounter : public PreferencesObserver {
public:
virtual ~PreferencesObserverCounter();
void OnChange(Preferences &preferences, const std::string &key) override;
std::atomic_int notifyTimes;
static const std::vector<std::string> NOTIFY_KEYS_VECTOR;
};
PreferencesObserverCounter::~PreferencesObserverCounter() {}
void PreferencesObserverCounter::OnChange(Preferences &preferences, const std::string &key)
{
for (auto it = NOTIFY_KEYS_VECTOR.cbegin(); it != NOTIFY_KEYS_VECTOR.cend(); it++) {
if (key.compare(*it)) {
notifyTimes++;
break;
}
}
}
const std::vector<std::string> PreferencesObserverCounter::NOTIFY_KEYS_VECTOR = { PreferencesTest::KEY_TEST_INT_ELEMENT,
PreferencesTest::KEY_TEST_LONG_ELEMENT, PreferencesTest::KEY_TEST_FLOAT_ELEMENT,
PreferencesTest::KEY_TEST_BOOL_ELEMENT, PreferencesTest::KEY_TEST_STRING_ELEMENT };
```
订阅数据变化,并触发执行回调方法:
``` C++
std::shared_ptr<PreferencesObserver> counter =
std::shared_ptr<PreferencesObserver>(new PreferencesObserverCounter());
pref->RegisterObserver(counter); // 注册数据变化的回调。
pref->PutString(PreferencesTest::KEY_TEST_STRING_ELEMENT, "test");
pref->Flush(); // 触发执行counter的onChanged回调方法。
EXPECT_EQ(static_cast<PreferencesObserverCounter *>(counter.get())->notifyTimes, 1);
/* same value */
pref->PutInt(PreferencesTest::KEY_TEST_INT_ELEMENT, 2);
pref->PutString(PreferencesTest::KEY_TEST_STRING_ELEMENT, "test");
pref->Flush();
EXPECT_EQ(static_cast<PreferencesObserverCounter *>(counter.get())->notifyTimes, 2);
pref->UnRegisterObserver(counter); // 注销注册数据变化的回调。
```
7. 删除指定文件。
从使用PreferencesHelper内存中移除指定文件对应的Preferences单实例,并删除指定文件及其备份文件、损坏文件。删除指定文件时,应用不允许再使用该实例进行数据操作,否则会出现数据一致性问题。删除后,数据及文件将不可恢复。
``` C++
pref = nullptr;
int ret = PreferencesHelper::DeletePreferences("/data/test/test");
EXPECT_EQ(ret, E_OK);
```
# 轻量级数据存储概述
轻量级数据存储适用于对Key-Value结构的数据进行存取和持久化操作。应用获取某个轻量级存储对象后,该存储对象中的数据将会被缓存在内存中,以便应用获得更快的数据存取速度。应用也可以将缓存的数据再次写回文本文件中进行持久化存储,由于文件读写将产生不可避免的系统资源开销,建议应用减少对持久化文件的读写频率。
## 基本概念
- **Key-Value数据结构**
一种键值结构数据类型。Key是不重复的关键字,Value是数据值。
- **非关系型数据库**
区别于关系数据库,不保证遵循ACID(Atomic、Consistency、Isolation及Durability)特性,不采用关系模型来组织数据,数据之间无关系。
## 运作机制
1. 应用通过指定Preferences文件将其中的数据加载到Preferences实例,系统会通过静态容器将该实例存储在内存中,同一应用或进程中每个文件仅存在一个Preferences实例,直到应用主动从内存中移除该实例或者删除该Preferences文件。
2. 应用获取到Preferences文件对应的实例后,可以从Preferences实例中读取数据,或者将数据存入Preferences实例中。通过调用flush或者flushSync方法可以将Preferences实例中的数据回写到文件里。
**图 1** 轻量级数据存储运作机制<a name="fig1657785713509"></a>
![](figure/zh-cn_image_0000001192123772.png)
## 约束与限制
- 因Preferences实例会加载到内存中,建议存储的数据不超过一万条,并及时清理不再使用的实例,以便减少非内存开销。
- 数据中的key为string类型,要求非空且字符长度不超过80个。
- 当数据中的value为string类型时,允许为空,字符长度不超过8192个。
# 轻量级数据存储
- **[轻量级数据存储概述](subsys-data-storage-overview.md)**
- **[轻量级数据存储开发指导](subsys-data-storage-guide.md)**
# 数据管理 # 数据管理
- **[关系型数据库](subsys-database-relational.md)** - **[轻量级数据存储](subsys-data-storage.md)**
# HiCollie开发指导<a name="ZH-CN_TOPIC_0000001231255509"></a>
- [概述](#section3432134085116)
- [接口说明](#section139261151145116)
- [效果](#section1589120102458)
- [开发实例](#section13905646534)
- [C++接口开发实例](#section9797199145316)
- [线程卡死监控](#section1734221332)
- [超时监控](#section2186947140)
## 概述<a name="section3432134085116"></a>
HiCollie提供了软件看门狗功能。针对系统服务死锁、应用主线程阻塞,用户业务流程超时等故障,HiCollie提供了一套统一的用于故障检测和故障日志生成的框架,提供软件超时故障日志,辅助定位软件超时问题。
## 接口说明<a name="section139261151145116"></a>
**表 1** C++接口功能描述表
<a name="table19452225011"></a>
<table><thead align="left"><tr id="row1517803543518"><th class="cellrowborder" valign="top" width="19.698030196980305%" id="mcps1.2.4.1.1"><p id="p484763319529"><a name="p484763319529"></a><a name="p484763319529"></a>所属类</p>
</th>
<th class="cellrowborder" valign="top" width="35.82641735826417%" id="mcps1.2.4.1.2"><p id="p1684719339523"><a name="p1684719339523"></a><a name="p1684719339523"></a>接口定义</p>
</th>
<th class="cellrowborder" valign="top" width="44.47555244475552%" id="mcps1.2.4.1.3"><p id="p284773315220"><a name="p284773315220"></a><a name="p284773315220"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row1361184632117"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p6700155032113"><a name="p6700155032113"></a><a name="p6700155032113"></a>XCollieChecker类接口</p>
</td>
<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p18699115019217"><a name="p18699115019217"></a><a name="p18699115019217"></a>virtual void CheckBlock()</p>
</td>
<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p18700175062115"><a name="p18700175062115"></a><a name="p18700175062115"></a>接口功能:卡死检测回调函数。</p>
<p id="p13700125012216"><a name="p13700125012216"></a><a name="p13700125012216"></a>输入参数:无。</p>
<p id="p13700650162114"><a name="p13700650162114"></a><a name="p13700650162114"></a>输出参数:无。</p>
<p id="p3700850192115"><a name="p3700850192115"></a><a name="p3700850192115"></a>返回值:无。</p>
</td>
</tr>
<tr id="row8945182185017"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p79451227506"><a name="p79451227506"></a><a name="p79451227506"></a>XCollieChecker类接口</p>
</td>
<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p647534064612"><a name="p647534064612"></a><a name="p647534064612"></a>virtual void CheckThreadBlock()</p>
</td>
<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p127630177475"><a name="p127630177475"></a><a name="p127630177475"></a>接口功能:线程卡死检测回调函数。</p>
<p id="p18763111794719"><a name="p18763111794719"></a><a name="p18763111794719"></a>输入参数:无。</p>
<p id="p87631176478"><a name="p87631176478"></a><a name="p87631176478"></a>输出参数:无。</p>
<p id="p3764111718473"><a name="p3764111718473"></a><a name="p3764111718473"></a>返回值:无。</p>
</td>
</tr>
<tr id="row149924222486"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p11643173114810"><a name="p11643173114810"></a><a name="p11643173114810"></a>XCollie类接口</p>
</td>
<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p16289114074812"><a name="p16289114074812"></a><a name="p16289114074812"></a>void RegisterXCollieChecker(const sptr&lt;XCollieChecker&gt; &amp;checker, unsigned int type)</p>
</td>
<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p186437319482"><a name="p186437319482"></a><a name="p186437319482"></a>接口功能:线程卡死检测回调函数注册。</p>
<p id="p112011591133"><a name="p112011591133"></a><a name="p112011591133"></a>输入参数:</p>
<a name="ul7783192181413"></a><a name="ul7783192181413"></a><ul id="ul7783192181413"><li>checker:XCollieChecker实例指针。</li><li>type:卡死检测类型,取值设置为XCOLLIE_THREAD。</li></ul>
<p id="p166439314482"><a name="p166439314482"></a><a name="p166439314482"></a>输出参数:无。</p>
<p id="p564393112485"><a name="p564393112485"></a><a name="p564393112485"></a>返回值:无。</p>
</td>
</tr>
<tr id="row594519275012"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p294512211505"><a name="p294512211505"></a><a name="p294512211505"></a>XCollie类接口</p>
</td>
<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p81561310145215"><a name="p81561310145215"></a><a name="p81561310145215"></a>int SetTimer(const std::string &amp;name, unsigned int timeout, std::function&lt;void (void *)&gt; func, void *arg, unsigned int flag)</p>
</td>
<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p174279246538"><a name="p174279246538"></a><a name="p174279246538"></a>接口功能:添加定时器。</p>
<p id="p1998141221410"><a name="p1998141221410"></a><a name="p1998141221410"></a>输入参数:</p>
<a name="ul845512153147"></a><a name="ul845512153147"></a><ul id="ul845512153147"><li>name:定时器名称。</li><li>timeout:超时时间,单位为秒。</li><li>func:超时回调函数。</li><li>arg:超时回调函数参数指针。</li><li>flag:定时器操作类型。<p id="p1242762435310"><a name="p1242762435310"></a><a name="p1242762435310"></a>XCOLLIE_FLAG_DEFAULT // 其他三个选项功能之和</p>
<p id="p1542712435312"><a name="p1542712435312"></a><a name="p1542712435312"></a>XCOLLIE_FLAG_NOOP // 仅调用超时回调函数</p>
<p id="p15427112416531"><a name="p15427112416531"></a><a name="p15427112416531"></a>XCOLLIE_FLAG_LOG // 生成超时故障日志</p>
<p id="p242762455314"><a name="p242762455314"></a><a name="p242762455314"></a>XCOLLIE_FLAG_RECOVERY // 进程退出</p>
</li></ul>
<p id="p15427102445311"><a name="p15427102445311"></a><a name="p15427102445311"></a>输出参数:无。</p>
<p id="p144271424155316"><a name="p144271424155316"></a><a name="p144271424155316"></a>返回值:成功返回定时器标识,失败返回-1。</p>
</td>
</tr>
<tr id="row1294692165010"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p19461929506"><a name="p19461929506"></a><a name="p19461929506"></a>XCollie类接口</p>
</td>
<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p119467215012"><a name="p119467215012"></a><a name="p119467215012"></a>bool UpdateTimer(int id, unsigned int timeout)</p>
</td>
<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p3831253185713"><a name="p3831253185713"></a><a name="p3831253185713"></a>接口功能:更新定时器。</p>
<p id="p10649172815148"><a name="p10649172815148"></a><a name="p10649172815148"></a>输入参数:</p>
<a name="ul1628783221411"></a><a name="ul1628783221411"></a><ul id="ul1628783221411"><li>id:定时器标识。</li><li>timeout:超时时间,单位为秒。</li></ul>
<p id="p11831115375719"><a name="p11831115375719"></a><a name="p11831115375719"></a>输出参数:无。</p>
<p id="p38311853105716"><a name="p38311853105716"></a><a name="p38311853105716"></a>返回值:成功返回true,失败返回false。</p>
</td>
</tr>
<tr id="row594682175013"><td class="cellrowborder" valign="top" width="19.698030196980305%" headers="mcps1.2.4.1.1 "><p id="p194614212504"><a name="p194614212504"></a><a name="p194614212504"></a>XCollie类接口</p>
</td>
<td class="cellrowborder" valign="top" width="35.82641735826417%" headers="mcps1.2.4.1.2 "><p id="p1435552713588"><a name="p1435552713588"></a><a name="p1435552713588"></a>void CancelTimer(int id)</p>
</td>
<td class="cellrowborder" valign="top" width="44.47555244475552%" headers="mcps1.2.4.1.3 "><p id="p06791131580"><a name="p06791131580"></a><a name="p06791131580"></a>接口功能:取消定时器。</p>
<p id="p868013165815"><a name="p868013165815"></a><a name="p868013165815"></a>输入参数:定时器标识。</p>
<p id="p12680537587"><a name="p12680537587"></a><a name="p12680537587"></a>输出参数:无。</p>
<p id="p768015317586"><a name="p768015317586"></a><a name="p768015317586"></a>返回值:无。</p>
</td>
</tr>
</tbody>
</table>
## 效果<a name="section1589120102458"></a>
日志打印:
```
timeout: TimeoutTimer start at 1611040305 to check 1s ago
----------StacktraceCatcher CurrentTime:2021-01-19 15:11:45 Unexecuted(-1)(LogType:Stacktrace Pid:27689 Process:XCollieTimeoutModuleTest)----------
----- pid 27689 at 2021-01-19 15:11:45 -----
Cmd line: ./XCollieTimeoutModuleTest
ABI: 'arm64'
"XCollieTimeoutM" sysTid=27689
#01 pc 00000000000174cc /data/test/XCollieTimeoutModuleTest
```
## 开发实例<a name="section13905646534"></a>
### C++接口开发实例<a name="section9797199145316"></a>
### 线程卡死监控<a name="section1734221332"></a>
线程卡死监控功能需要开发者实现两个卡死检测回调函数,XCollieChecker类的CheckBlock和CheckThreadBlock接口函数。实现了该回调函数之后,开发者还需要通过XCollie类的RegisterXCollieChecker函数,将该回调函数的类实例成功注册。卡死监控线程会定时执行全部已成功注册的回调函数,检查线程逻辑完成标志位,判定已经成功注册的线程逻辑是否被卡死。
1. 源代码开发
包含头文件:
```
#include "xcollie.h"
```
在业务代码中使用:
```
void MyXCollieChecker::CheckLock()
{
/* time consuming job */
}
void MyXCollieChecker::CheckThreadBlock()
{
/* time consuming job */
}
sptr<XCollieChecker> checker = new MyXCollieChecker("MyXCollieChecker");
XCollie::GetInstance().RegisterXCollieChecker(checker,
(XCOLLIE_LOCK | XCOLLIE_THREAD));
......
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx:libxcollie" ]
```
### 超时监控<a name="section2186947140"></a>
单个进程通过SetTimer接口函数添加定时器最多可以设置128个,超过上限则添加定时器操作会失败。
1. 源代码开发
包含头文件:
```
#include "xcollie.h"
```
在业务代码中使用(添加/更新/取消):
```
std::function<void(void *)> callback = [](void *args)
{
/* dump helpful information */
};
int id = XCollie::GetInstance().SetTimer("MyXCollieTimer", 10, callback ,nullptr, XCOLLIE_FLAG_LOG);
/* time consuming job */
XCollie::GetInstance().UpdateTimer(id, 5);
/* time consuming job */
XCollie::GetInstance().CancelTimer(id);
......
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx:libxcollie" ]
```
# HiLog\_Lite开发指导<a name="ZH-CN_TOPIC_0000001089263241"></a> # HiLog\_Lite开发指导<a name="ZH-CN_TOPIC_0000001185815838"></a>
- [概述](#section775017517390) - [概述](#section775017517390)
- [接口说明](#section114412157402) - [接口说明](#section114412157402)
......
# HiLog开发指导<a name="ZH-CN_TOPIC_0000001081129329"></a> # HiLog开发指导
- [概述](#section8154107175019) - [概述](#概述)
- [接口说明](#section6748124155012) - [接口说明](#接口说明)
- [开发实例](#section102728581536) - [开发实例](#开发实例)
- [C使用示例](#section12916224185417) - [C使用示例](#c使用示例)
- [C++使用示例](#section19399185610547) - [C++使用示例](#c-使用示例)
## 概述
## 概述<a name="section8154107175019"></a>
HiLog是OpenHarmony日志系统,提供给系统框架、服务、以及应用打印日志,记录用户操作、系统运行状态等。 HiLog是OpenHarmony日志系统,提供给系统框架、服务、以及应用打印日志,记录用户操作、系统运行状态等。
本章节内容对标准系统类设备(参考内存≥128MB)适用。 本章节内容对标准系统类设备(参考内存≥128MB)适用。
## 接口说明<a name="section6748124155012"></a>
**表 1** C++、C的函数接口
<a name="table94501354193619"></a>
<table><thead align="left"><tr id="row954285483614"><th class="cellrowborder" colspan="2" valign="top" id="mcps1.2.4.1.1"><p id="p16542254203611"><a name="p16542254203611"></a><a name="p16542254203611"></a><strong id="b17542185414366"><a name="b17542185414366"></a><a name="b17542185414366"></a>C++</strong></p>
</th>
<th class="cellrowborder" valign="top" id="mcps1.2.4.1.2"><p id="p185431554163619"><a name="p185431554163619"></a><a name="p185431554163619"></a><strong id="b175431054123617"><a name="b175431054123617"></a><a name="b175431054123617"></a>C</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row954305418361"><td class="cellrowborder" valign="top" width="18.388161183881614%" headers="mcps1.2.4.1.1 "><p id="p3543754183618"><a name="p3543754183618"></a><a name="p3543754183618"></a><strong id="b45431554113615"><a name="b45431554113615"></a><a name="b45431554113615"></a></strong></p>
</td>
<td class="cellrowborder" valign="top" width="43.53564643535647%" headers="mcps1.2.4.1.1 "><p id="p10544105453610"><a name="p10544105453610"></a><a name="p10544105453610"></a><strong id="b22281259122314"><a name="b22281259122314"></a><a name="b22281259122314"></a>方法</strong></p>
</td>
<td class="cellrowborder" valign="top" width="38.076192380761924%" headers="mcps1.2.4.1.2 "><p id="p17969916192614"><a name="p17969916192614"></a><a name="p17969916192614"></a><strong id="b1654320344267"><a name="b1654320344267"></a><a name="b1654320344267"></a>方法/宏</strong></p>
</td>
</tr>
<tr id="row8544115410361"><td class="cellrowborder" rowspan="7" valign="top" width="18.388161183881614%" headers="mcps1.2.4.1.1 "><p id="p16544154183615"><a name="p16544154183615"></a><a name="p16544154183615"></a>HiLog</p>
</td>
<td class="cellrowborder" valign="top" width="43.53564643535647%" headers="mcps1.2.4.1.1 "><p id="p1326662513016"><a name="p1326662513016"></a><a name="p1326662513016"></a>int Debug(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="38.076192380761924%" headers="mcps1.2.4.1.2 "><p id="p18697644105619"><a name="p18697644105619"></a><a name="p18697644105619"></a>HILOG_DEBUG(type, ...)</p>
</td>
</tr>
<tr id="row754495418366"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p86951544155610"><a name="p86951544155610"></a><a name="p86951544155610"></a>int Info(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p96931344145615"><a name="p96931344145615"></a><a name="p96931344145615"></a>HILOG_INFO(type, ...)</p>
</td>
</tr>
<tr id="row95441954113614"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1769224485619"><a name="p1769224485619"></a><a name="p1769224485619"></a>int Warn(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1969194465613"><a name="p1969194465613"></a><a name="p1969194465613"></a>HILOG_WARN(type, ...)</p>
</td>
</tr>
<tr id="row45448547369"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p4748102365615"><a name="p4748102365615"></a><a name="p4748102365615"></a>int Error(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p15747142375613"><a name="p15747142375613"></a><a name="p15747142375613"></a>HILOG_ERROR(type, ...)</p>
</td>
</tr>
<tr id="row12545125453610"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p5745132318560"><a name="p5745132318560"></a><a name="p5745132318560"></a>int Fatal(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p107441123175615"><a name="p107441123175615"></a><a name="p107441123175615"></a>HILOG_FATAL(type, ...)</p>
</td>
</tr>
<tr id="row1454565433611"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1574242345618"><a name="p1574242345618"></a><a name="p1574242345618"></a>NA</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p197416239562"><a name="p197416239562"></a><a name="p197416239562"></a>int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)</p>
</td>
</tr>
<tr id="row165451854193617"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p64411913343"><a name="p64411913343"></a><a name="p64411913343"></a>boolean IsLoggable(unsigned int domain, const char *tag, LogLevel level)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p107388238561"><a name="p107388238561"></a><a name="p107388238561"></a>bool HiLogIsLoggable(unsigned int domain, const char *tag, LogLevel level)</p>
</td>
</tr>
<tr id="row154535415367"><td class="cellrowborder" valign="top" width="18.388161183881614%" headers="mcps1.2.4.1.1 "><p id="p795821952317"><a name="p795821952317"></a><a name="p795821952317"></a>HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="43.53564643535647%" headers="mcps1.2.4.1.1 "><p id="p20464133712224"><a name="p20464133712224"></a><a name="p20464133712224"></a>struct HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="38.076192380761924%" headers="mcps1.2.4.1.2 "><p id="p1360616314276"><a name="p1360616314276"></a><a name="p1360616314276"></a>LOG_DOMAIN</p>
<p id="p4698145992513"><a name="p4698145992513"></a><a name="p4698145992513"></a>LOG_TAG</p>
</td>
</tr>
</tbody>
</table>
**表 2** C++接口说明函数参数和功能
<a name="table19597131833715"></a>
<table><thead align="left"><tr id="row7839141817375"><th class="cellrowborder" valign="top" width="8.27%" id="mcps1.2.4.1.1"><p id="p383919182379"><a name="p383919182379"></a><a name="p383919182379"></a><strong id="b0839191863717"><a name="b0839191863717"></a><a name="b0839191863717"></a></strong></p>
</th>
<th class="cellrowborder" valign="top" width="31.41%" id="mcps1.2.4.1.2"><p id="p168392018203711"><a name="p168392018203711"></a><a name="p168392018203711"></a><strong id="b4208111244510"><a name="b4208111244510"></a><a name="b4208111244510"></a>方法</strong></p>
</th>
<th class="cellrowborder" valign="top" width="60.31999999999999%" id="mcps1.2.4.1.3"><p id="p168391618193717"><a name="p168391618193717"></a><a name="p168391618193717"></a><strong id="b521141218453"><a name="b521141218453"></a><a name="b521141218453"></a>描述</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row383911183378"><td class="cellrowborder" rowspan="6" valign="top" width="8.27%" headers="mcps1.2.4.1.1 "><p id="p10839318133713"><a name="p10839318133713"></a><a name="p10839318133713"></a>HiLog</p>
</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p12483951497"><a name="p12483951497"></a><a name="p12483951497"></a>int Debug(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p684013182375"><a name="p684013182375"></a><a name="p684013182375"></a>功能:输出 debug 级别日志。</p>
<p id="p1384081812377"><a name="p1384081812377"></a><a name="p1384081812377"></a>输入参数:</p>
<a name="ul169441595136"></a><a name="ul169441595136"></a><ul id="ul169441595136"><li>label:用于标识输出日志的类型、业务领域、TAG。</li><li>format:常量格式字符串,包含参数类型、隐私标识。未加隐私标识的缺省为隐私参数。</li><li>fmt:格式化变参描述字符串。</li></ul>
<p id="p591585615123"><a name="p591585615123"></a><a name="p591585615123"></a>输出参数:无</p>
<p id="p1620144161310"><a name="p1620144161310"></a><a name="p1620144161310"></a>返回值:大于等于0,成功;小于0,失败。</p>
</td>
</tr>
<tr id="row16840101803720"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p482832616141"><a name="p482832616141"></a><a name="p482832616141"></a>int Info(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p9562039395"><a name="p9562039395"></a><a name="p9562039395"></a>功能:输出 info 级别日志。</p>
<p id="p198849129150"><a name="p198849129150"></a><a name="p198849129150"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row198401818193712"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1705727151413"><a name="p1705727151413"></a><a name="p1705727151413"></a>int Warn(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p873814715151"><a name="p873814715151"></a><a name="p873814715151"></a>功能:输出 warn 级别日志。</p>
<p id="p17738847151515"><a name="p17738847151515"></a><a name="p17738847151515"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row118401118203714"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p55044284141"><a name="p55044284141"></a><a name="p55044284141"></a>int Error(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1558516489153"><a name="p1558516489153"></a><a name="p1558516489153"></a>功能:输出 error 级别日志。</p>
<p id="p1558534841512"><a name="p1558534841512"></a><a name="p1558534841512"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row3840171813374"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p8306152914144"><a name="p8306152914144"></a><a name="p8306152914144"></a>int Fatal(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p625734912152"><a name="p625734912152"></a><a name="p625734912152"></a>功能:输出 fatal 级别日志。</p>
<p id="p1125712491157"><a name="p1125712491157"></a><a name="p1125712491157"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row6840818193716"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p421952291617"><a name="p421952291617"></a><a name="p421952291617"></a>boolean IsLoggable(unsigned int domain, const char *tag, LogLevel level)</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p3722152951615"><a name="p3722152951615"></a><a name="p3722152951615"></a>功能:检查指定业务领域、TAG、级别的日志是否可以打印。</p>
<p id="p117221929201613"><a name="p117221929201613"></a><a name="p117221929201613"></a>输入参数:</p>
<a name="ul1372214296164"></a><a name="ul1372214296164"></a><ul id="ul1372214296164"><li>domain:指定日志业务领域。</li><li>tag: 指定日志TAG。</li><li>level: 指定日志level。</li></ul>
<p id="p572242911167"><a name="p572242911167"></a><a name="p572242911167"></a>输出参数:无</p>
<p id="p6722162991617"><a name="p6722162991617"></a><a name="p6722162991617"></a>返回值:如果指定domain、tag、level日志可以打印则返回true;否则返回false。</p>
</td>
</tr>
<tr id="row15841191813371"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 "><p id="p98771141182714"><a name="p98771141182714"></a><a name="p98771141182714"></a>HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p137234972715"><a name="p137234972715"></a><a name="p137234972715"></a>struct HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p48419181372"><a name="p48419181372"></a><a name="p48419181372"></a>功能:初始化日志标签参数。</p>
<p id="p335055115288"><a name="p335055115288"></a><a name="p335055115288"></a>成员参数:</p>
<a name="ul1235085115287"></a><a name="ul1235085115287"></a><ul id="ul1235085115287"><li>domain:指定日志业务领域。</li><li>tag: 指定日志TAG。</li><li>level: 指定日志level。</li></ul>
</td>
</tr>
</tbody>
</table>
## 开发实例<a name="section102728581536"></a>
### C使用示例<a name="section12916224185417"></a>
1. 在.c源文件中,包含hilog头文件:
```
#include "hilog/log.h"
```
定义domain、tag:
```
#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0 // 标识业务领域,范围0x0~0xFFFFF
#define LOG_TAG "MY_TAG"
```
打印日志:
```
HILOG_INFO(LOG_CORE, "Failed to visit %{private}s, reason:%{public}d.", url, errno);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
```
### C++使用示例<a name="section19399185610547"></a>
1. 在.h类定义头文件中,包含hilog头文件:
```
#include "hilog/log.h"
```
如果类头文件中需要日志打印,在头文件中类定义起始处 定义 LABEL:
```
class MyClass {
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "MY_TAG"};
......
}
```
如果类头文件中没有日志打印,在类实现文件中 定义 LABEL:
```
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "MY_TAG"};
```
打印日志:
```
HiLog::Info(LABEL, "Failed to visit %{private}s, reason:%{public}d.", url, errno);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx:libhilog" ]
```
## 接口说明
**表1** C++、C的函数接口
| **C++** | | **C** |
| -------- | -------- | -------- |
| **类** | **方法** | **方法/宏** |
| HiLog | int&nbsp;Debug(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | HILOG_DEBUG(type,&nbsp;...) |
| | int&nbsp;Info(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | HILOG_INFO(type,&nbsp;...) |
| | int&nbsp;Warn(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | HILOG_WARN(type,&nbsp;...) |
| | int&nbsp;Error(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | HILOG_ERROR(type,&nbsp;...) |
| | int&nbsp;Fatal(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | HILOG_FATAL(type,&nbsp;...) |
| | NA | int&nbsp;HiLogPrint(LogType&nbsp;type,&nbsp;LogLevel&nbsp;level,&nbsp;unsigned&nbsp;int&nbsp;domain,&nbsp;const&nbsp;char&nbsp;\*tag,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) |
| | boolean&nbsp;IsLoggable(unsigned&nbsp;int&nbsp;domain,&nbsp;const&nbsp;char&nbsp;\*tag,&nbsp;LogLevel&nbsp;level) | bool&nbsp;HiLogIsLoggable(unsigned&nbsp;int&nbsp;domain,&nbsp;const&nbsp;char&nbsp;\*tag,&nbsp;LogLevel&nbsp;level) |
| HiLogLabel | struct&nbsp;HiLogLabel | LOG_DOMAIN<br/>LOG_TAG |
**表3** C++接口说明函数参数和功能
| **类** | **方法** | **描述** |
| -------- | -------- | -------- |
| HiLog | int&nbsp;Debug(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | 功能:输出&nbsp;debug&nbsp;级别日志。<br/>输入参数:<br/>-&nbsp;label:用于标识输出日志的类型、业务领域、TAG。<br/>-&nbsp;format:常量格式字符串,包含参数类型、隐私标识。未加隐私标识的缺省为隐私参数。<br/>-&nbsp;fmt:格式化变参描述字符串。<br/>输出参数:无<br/>返回值:大于等于0,成功;小于0,失败。 |
| | int&nbsp;Info(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | 功能:输出&nbsp;info&nbsp;级别日志。<br/>参数说明同&nbsp;Debug&nbsp;接口。 |
| | int&nbsp;Warn(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | 功能:输出&nbsp;warn&nbsp;级别日志。<br/>参数说明同&nbsp;Debug&nbsp;接口。 |
| | int&nbsp;Error(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | 功能:输出&nbsp;error&nbsp;级别日志。<br/>参数说明同&nbsp;Debug&nbsp;接口。 |
| | int&nbsp;Fatal(const&nbsp;HiLogLabel&nbsp;&amp;label,&nbsp;const&nbsp;char&nbsp;\*fmt,&nbsp;...) | 功能:输出&nbsp;fatal&nbsp;级别日志。<br/>参数说明同&nbsp;Debug&nbsp;接口。 |
| | boolean&nbsp;IsLoggable(unsigned&nbsp;int&nbsp;domain,&nbsp;const&nbsp;char&nbsp;\*tag,&nbsp;LogLevel&nbsp;level) | 功能:检查指定业务领域、TAG、级别的日志是否可以打印。<br/>输入参数:<br/>-&nbsp;domain:指定日志业务领域。<br/>-&nbsp;tag:&nbsp;指定日志TAG。<br/>-&nbsp;level:&nbsp;指定日志level。<br/>输出参数:无<br/>返回值:如果指定domain、tag、level日志可以打印则返回true;否则返回false。 |
| HiLogLabel | struct&nbsp;HiLogLabel | 功能:初始化日志标签参数。<br/>成员参数:<br/>-&nbsp;domain:指定日志业务领域。<br/>-&nbsp;tag:&nbsp;指定日志TAG。<br/>-&nbsp;level:&nbsp;指定日志level。 |
## 开发实例
### C使用示例
1. 在.c源文件中,包含hilog头文件:
```
#include "hilog/log.h"
```
定义domain、tag:
```
#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0 // 标识业务领域,范围0x0~0xFFFFF
#define LOG_TAG "MY_TAG"
```
打印日志:
```
HILOG_INFO(LOG_CORE, "Failed to visit %{private}s, reason:%{public}d.", url, errno);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
```
### C++使用示例
1. 在.h类定义头文件中,包含hilog头文件:
```
#include "hilog/log.h"
```
如果类头文件中需要日志打印,在头文件中类定义起始处 定义 LABEL:
```
class MyClass {
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "MY_TAG"};
......
}
```
如果类头文件中没有日志打印,在类实现文件中 定义 LABEL:
```
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "MY_TAG"};
```
打印日志:
```
HiLog::Info(LABEL, "Failed to visit %{private}s, reason:%{public}d.", url, errno);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx:libhilog" ]
```
# HiLog开发指导<a name="ZH-CN_TOPIC_0000001185655870"></a>
- [概述](#section8154107175019)
- [接口说明](#section6748124155012)
- [开发实例](#section102728581536)
- [C使用示例](#section12916224185417)
- [C++使用示例](#section19399185610547)
## 概述<a name="section8154107175019"></a>
HiLog是OpenHarmony日志系统,提供给系统框架、服务、以及应用打印日志,记录用户操作、系统运行状态等。
本章节内容对标准系统类设备(参考内存≥128MB)适用。
## 接口说明<a name="section6748124155012"></a>
**表 1** C++、C的函数接口
<a name="table94501354193619"></a>
<table><thead align="left"><tr id="row954285483614"><th class="cellrowborder" valign="top" width="18.258174182581744%" id="mcps1.2.4.1.1"><p id="p16542254203611"><a name="p16542254203611"></a><a name="p16542254203611"></a><strong id="b17542185414366"><a name="b17542185414366"></a><a name="b17542185414366"></a>C++</strong></p>
</th>
<th class="cellrowborder" valign="top" width="43.39566043395661%" id="mcps1.2.4.1.2">&nbsp;&nbsp;</th>
<th class="cellrowborder" valign="top" width="38.34616538346165%" id="mcps1.2.4.1.3"><p id="p185431554163619"><a name="p185431554163619"></a><a name="p185431554163619"></a><strong id="b175431054123617"><a name="b175431054123617"></a><a name="b175431054123617"></a>C</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row954305418361"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 "><p id="p3543754183618"><a name="p3543754183618"></a><a name="p3543754183618"></a><strong id="b45431554113615"><a name="b45431554113615"></a><a name="b45431554113615"></a></strong></p>
</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p10544105453610"><a name="p10544105453610"></a><a name="p10544105453610"></a><strong id="b22281259122314"><a name="b22281259122314"></a><a name="b22281259122314"></a>方法</strong></p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p17969916192614"><a name="p17969916192614"></a><a name="p17969916192614"></a><strong id="b1654320344267"><a name="b1654320344267"></a><a name="b1654320344267"></a>方法/宏</strong></p>
</td>
</tr>
<tr id="row8544115410361"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 "><p id="p16544154183615"><a name="p16544154183615"></a><a name="p16544154183615"></a>HiLog</p>
</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p1326662513016"><a name="p1326662513016"></a><a name="p1326662513016"></a>int Debug(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p18697644105619"><a name="p18697644105619"></a><a name="p18697644105619"></a>HILOG_DEBUG(type, ...)</p>
</td>
</tr>
<tr id="row754495418366"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p86951544155610"><a name="p86951544155610"></a><a name="p86951544155610"></a>int Info(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p96931344145615"><a name="p96931344145615"></a><a name="p96931344145615"></a>HILOG_INFO(type, ...)</p>
</td>
</tr>
<tr id="row95441954113614"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p1769224485619"><a name="p1769224485619"></a><a name="p1769224485619"></a>int Warn(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p1969194465613"><a name="p1969194465613"></a><a name="p1969194465613"></a>HILOG_WARN(type, ...)</p>
</td>
</tr>
<tr id="row45448547369"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p4748102365615"><a name="p4748102365615"></a><a name="p4748102365615"></a>int Error(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p15747142375613"><a name="p15747142375613"></a><a name="p15747142375613"></a>HILOG_ERROR(type, ...)</p>
</td>
</tr>
<tr id="row12545125453610"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p5745132318560"><a name="p5745132318560"></a><a name="p5745132318560"></a>int Fatal(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p107441123175615"><a name="p107441123175615"></a><a name="p107441123175615"></a>HILOG_FATAL(type, ...)</p>
</td>
</tr>
<tr id="row1454565433611"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p1574242345618"><a name="p1574242345618"></a><a name="p1574242345618"></a>NA</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p197416239562"><a name="p197416239562"></a><a name="p197416239562"></a>int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)</p>
</td>
</tr>
<tr id="row165451854193617"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p64411913343"><a name="p64411913343"></a><a name="p64411913343"></a>boolean IsLoggable(unsigned int domain, const char *tag, LogLevel level)</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p107388238561"><a name="p107388238561"></a><a name="p107388238561"></a>bool HiLogIsLoggable(unsigned int domain, const char *tag, LogLevel level)</p>
</td>
</tr>
<tr id="row154535415367"><td class="cellrowborder" valign="top" width="18.258174182581744%" headers="mcps1.2.4.1.1 "><p id="p795821952317"><a name="p795821952317"></a><a name="p795821952317"></a>HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="43.39566043395661%" headers="mcps1.2.4.1.2 "><p id="p20464133712224"><a name="p20464133712224"></a><a name="p20464133712224"></a>struct HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="38.34616538346165%" headers="mcps1.2.4.1.3 "><p id="p1360616314276"><a name="p1360616314276"></a><a name="p1360616314276"></a>LOG_DOMAIN</p>
<p id="p4698145992513"><a name="p4698145992513"></a><a name="p4698145992513"></a>LOG_TAG</p>
</td>
</tr>
</tbody>
</table>
**表 2** C++接口说明函数参数和功能
<a name="table19597131833715"></a>
<table><thead align="left"><tr id="row7839141817375"><th class="cellrowborder" valign="top" width="8.27%" id="mcps1.2.4.1.1"><p id="p383919182379"><a name="p383919182379"></a><a name="p383919182379"></a><strong id="b0839191863717"><a name="b0839191863717"></a><a name="b0839191863717"></a></strong></p>
</th>
<th class="cellrowborder" valign="top" width="31.41%" id="mcps1.2.4.1.2"><p id="p168392018203711"><a name="p168392018203711"></a><a name="p168392018203711"></a><strong id="b4208111244510"><a name="b4208111244510"></a><a name="b4208111244510"></a>方法</strong></p>
</th>
<th class="cellrowborder" valign="top" width="60.31999999999999%" id="mcps1.2.4.1.3"><p id="p168391618193717"><a name="p168391618193717"></a><a name="p168391618193717"></a><strong id="b521141218453"><a name="b521141218453"></a><a name="b521141218453"></a>描述</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row383911183378"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 "><p id="p10839318133713"><a name="p10839318133713"></a><a name="p10839318133713"></a>HiLog</p>
</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p12483951497"><a name="p12483951497"></a><a name="p12483951497"></a>int Debug(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p684013182375"><a name="p684013182375"></a><a name="p684013182375"></a>功能:输出 debug 级别日志。</p>
<p id="p1384081812377"><a name="p1384081812377"></a><a name="p1384081812377"></a>输入参数:</p>
<a name="ul169441595136"></a><a name="ul169441595136"></a><ul id="ul169441595136"><li>label:用于标识输出日志的类型、业务领域、TAG。</li><li>format:常量格式字符串,包含参数类型、隐私标识。未加隐私标识的缺省为隐私参数。</li><li>fmt:格式化变参描述字符串。</li></ul>
<p id="p591585615123"><a name="p591585615123"></a><a name="p591585615123"></a>输出参数:无</p>
<p id="p1620144161310"><a name="p1620144161310"></a><a name="p1620144161310"></a>返回值:大于等于0,成功;小于0,失败。</p>
</td>
</tr>
<tr id="row16840101803720"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p482832616141"><a name="p482832616141"></a><a name="p482832616141"></a>int Info(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p9562039395"><a name="p9562039395"></a><a name="p9562039395"></a>功能:输出 info 级别日志。</p>
<p id="p198849129150"><a name="p198849129150"></a><a name="p198849129150"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row198401818193712"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p1705727151413"><a name="p1705727151413"></a><a name="p1705727151413"></a>int Warn(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p873814715151"><a name="p873814715151"></a><a name="p873814715151"></a>功能:输出 warn 级别日志。</p>
<p id="p17738847151515"><a name="p17738847151515"></a><a name="p17738847151515"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row118401118203714"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p55044284141"><a name="p55044284141"></a><a name="p55044284141"></a>int Error(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p1558516489153"><a name="p1558516489153"></a><a name="p1558516489153"></a>功能:输出 error 级别日志。</p>
<p id="p1558534841512"><a name="p1558534841512"></a><a name="p1558534841512"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row3840171813374"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p8306152914144"><a name="p8306152914144"></a><a name="p8306152914144"></a>int Fatal(const HiLogLabel &amp;label, const char *fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p625734912152"><a name="p625734912152"></a><a name="p625734912152"></a>功能:输出 fatal 级别日志。</p>
<p id="p1125712491157"><a name="p1125712491157"></a><a name="p1125712491157"></a>参数说明同 Debug 接口。</p>
</td>
</tr>
<tr id="row6840818193716"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p421952291617"><a name="p421952291617"></a><a name="p421952291617"></a>boolean IsLoggable(unsigned int domain, const char *tag, LogLevel level)</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p3722152951615"><a name="p3722152951615"></a><a name="p3722152951615"></a>功能:检查指定业务领域、TAG、级别的日志是否可以打印。</p>
<p id="p117221929201613"><a name="p117221929201613"></a><a name="p117221929201613"></a>输入参数:</p>
<a name="ul1372214296164"></a><a name="ul1372214296164"></a><ul id="ul1372214296164"><li>domain:指定日志业务领域。</li><li>tag: 指定日志TAG。</li><li>level: 指定日志level。</li></ul>
<p id="p572242911167"><a name="p572242911167"></a><a name="p572242911167"></a>输出参数:无</p>
<p id="p6722162991617"><a name="p6722162991617"></a><a name="p6722162991617"></a>返回值:如果指定domain、tag、level日志可以打印则返回true;否则返回false。</p>
</td>
</tr>
<tr id="row15841191813371"><td class="cellrowborder" valign="top" width="8.27%" headers="mcps1.2.4.1.1 "><p id="p98771141182714"><a name="p98771141182714"></a><a name="p98771141182714"></a>HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="31.41%" headers="mcps1.2.4.1.2 "><p id="p137234972715"><a name="p137234972715"></a><a name="p137234972715"></a>struct HiLogLabel</p>
</td>
<td class="cellrowborder" valign="top" width="60.31999999999999%" headers="mcps1.2.4.1.3 "><p id="p48419181372"><a name="p48419181372"></a><a name="p48419181372"></a>功能:初始化日志标签参数。</p>
<p id="p335055115288"><a name="p335055115288"></a><a name="p335055115288"></a>成员参数:</p>
<a name="ul1235085115287"></a><a name="ul1235085115287"></a><ul id="ul1235085115287"><li>domain:指定日志业务领域。</li><li>tag: 指定日志TAG。</li><li>level: 指定日志level。</li></ul>
</td>
</tr>
</tbody>
</table>
## 开发实例<a name="section102728581536"></a>
### C使用示例<a name="section12916224185417"></a>
1. 在.c源文件中,包含hilog头文件:
```
#include "hilog/log.h"
```
定义domain、tag:
```
#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0 // 标识业务领域,范围0x0~0xFFFFF
#define LOG_TAG "MY_TAG"
```
打印日志:
```
HILOG_INFO(LOG_CORE, "Failed to visit %{private}s, reason:%{public}d.", url, errno);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
```
### C++使用示例<a name="section19399185610547"></a>
1. 在.h类定义头文件中,包含hilog头文件:
```
#include "hilog/log.h"
```
如果类头文件中需要日志打印,在头文件中类定义起始处 定义 LABEL:
```
class MyClass {
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "MY_TAG"};
......
}
```
如果类头文件中没有日志打印,在类实现文件中 定义 LABEL:
```
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "MY_TAG"};
```
打印日志:
```
HiLog::Info(LABEL, "Failed to visit %{private}s, reason:%{public}d.", url, errno);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx:libhilog" ]
```
# HiSysEvent订阅指导<a name="ZH-CN_TOPIC_0000001185655868"></a>
- [概述](#section315316685112)
- [接口说明](#section0342191810519)
- [开发实例](#section123181432175110)
- [C++接口实例](#section2016116181902)
## 概述<a name="section315316685112"></a>
HiSysEvent提供了跨进程订阅机制,开发者可以通过注册订阅接口实时获取关注的事件,例如电池模块侦听功耗相关的事件,用于分析耗电情况。
## 接口说明<a name="section0342191810519"></a>
**表 1** HiSysEvent订阅接口
<a name="table1844019587496"></a>
<table><thead align="left"><tr id="row1440058184916"><th class="cellrowborder" valign="top" width="48.120000000000005%" id="mcps1.2.3.1.1"><p id="p19441135844915"><a name="p19441135844915"></a><a name="p19441135844915"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="51.88%" id="mcps1.2.3.1.2"><p id="p13441195815491"><a name="p13441195815491"></a><a name="p13441195815491"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row16441155818499"><td class="cellrowborder" valign="top" width="48.120000000000005%" headers="mcps1.2.3.1.1 "><p id="p877916438211"><a name="p877916438211"></a><a name="p877916438211"></a>int HiSysEventManager::AddEventListener(std::shared_ptr&lt;HiSysEventSubscribeCallBackBase&gt; listener, std::vector&lt;struct ListenerRule&gt;&amp; rules)</p>
</td>
<td class="cellrowborder" valign="top" width="51.88%" headers="mcps1.2.3.1.2 "><p id="p14727325133216"><a name="p14727325133216"></a><a name="p14727325133216"></a>接口功能:注册订阅HiSysEvent系统事件侦听对象,可设置规则订阅某些事件。</p>
<p id="p167271525203213"><a name="p167271525203213"></a><a name="p167271525203213"></a>输入参数:</p>
<a name="ul6717142214919"></a><a name="ul6717142214919"></a><ul id="ul6717142214919"><li>listener:订阅回调对象。</li><li>rules:事件订阅规则。</li></ul>
<p id="p83591223153818"><a name="p83591223153818"></a><a name="p83591223153818"></a>返回值:</p>
<a name="ul12105842111913"></a><a name="ul12105842111913"></a><ul id="ul12105842111913"><li>0:订阅成功,重复订阅。</li><li>1:订阅成功,初次订阅。</li><li>其他返回值:订阅失败。</li></ul>
</td>
</tr>
<tr id="row910319443242"><td class="cellrowborder" valign="top" width="48.120000000000005%" headers="mcps1.2.3.1.1 "><p id="p15104154411248"><a name="p15104154411248"></a><a name="p15104154411248"></a>void HiSysEventManager::RemoveListener(std::shared_ptr&lt;HiSysEventSubscribeCallBackBase&gt; listener)</p>
</td>
<td class="cellrowborder" valign="top" width="51.88%" headers="mcps1.2.3.1.2 "><p id="p1104194420248"><a name="p1104194420248"></a><a name="p1104194420248"></a>接口功能:移除订阅hisysevent系统事件侦听对象。</p>
<p id="p7943171095411"><a name="p7943171095411"></a><a name="p7943171095411"></a>输入参数:</p>
<a name="ul894321075411"></a><a name="ul894321075411"></a><ul id="ul894321075411"><li>listener:订阅回调对象。</li></ul>
<p id="p9744631162515"><a name="p9744631162515"></a><a name="p9744631162515"></a>返回值:无。</p>
</td>
</tr>
</tbody>
</table>
**表 2** ListenerRule订阅规则对象
<a name="table1144011610564"></a>
<table><thead align="left"><tr id="row124411716175611"><th class="cellrowborder" valign="top" width="48.11%" id="mcps1.2.3.1.1"><p id="p19441151675610"><a name="p19441151675610"></a><a name="p19441151675610"></a>属性名称</p>
</th>
<th class="cellrowborder" valign="top" width="51.89%" id="mcps1.2.3.1.2"><p id="p16441171616563"><a name="p16441171616563"></a><a name="p16441171616563"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row174411216105615"><td class="cellrowborder" valign="top" width="48.11%" headers="mcps1.2.3.1.1 "><p id="p496413536613"><a name="p496413536613"></a><a name="p496413536613"></a><span>uint32_t</span> ruleType</p>
</td>
<td class="cellrowborder" valign="top" width="51.89%" headers="mcps1.2.3.1.2 "><p id="p94416160565"><a name="p94416160565"></a><a name="p94416160565"></a>规则类型(匹配范围包括domain以及eventName):</p>
<a name="ul1652866141814"></a><a name="ul1652866141814"></a><ul id="ul1652866141814"><li>1:全字符匹配。</li><li>2:前缀匹配。</li><li>3:正则表达式匹配。</li><li>其他值:无效的匹配方式。</li></ul>
</td>
</tr>
<tr id="row64411816125614"><td class="cellrowborder" valign="top" width="48.11%" headers="mcps1.2.3.1.1 "><p id="p1258135313712"><a name="p1258135313712"></a><a name="p1258135313712"></a>std::string domain</p>
</td>
<td class="cellrowborder" valign="top" width="51.89%" headers="mcps1.2.3.1.2 "><a name="ul14905926102311"></a><a name="ul14905926102311"></a><ul id="ul14905926102311"><li>domain:事件所属领域,如果传入的是空字符串,则默认事件领域字段匹配成功。</li></ul>
</td>
</tr>
<tr id="row244161615619"><td class="cellrowborder" valign="top" width="48.11%" headers="mcps1.2.3.1.1 "><p id="p227913101887"><a name="p227913101887"></a><a name="p227913101887"></a>std::string eventName</p>
</td>
<td class="cellrowborder" valign="top" width="51.89%" headers="mcps1.2.3.1.2 "><a name="ul248063132319"></a><a name="ul248063132319"></a><ul id="ul248063132319"><li>eventName:事件的名称,如果传入的是空字符串,则默认事件名称字段匹配成功。</li></ul>
</td>
</tr>
</tbody>
</table>
**表 3** HiSysEventSubscribeCallBackBase订阅对象
<a name="table1011703742711"></a>
<table><thead align="left"><tr id="row121187375270"><th class="cellrowborder" valign="top" width="48.25%" id="mcps1.2.3.1.1"><p id="p2118143782719"><a name="p2118143782719"></a><a name="p2118143782719"></a>接口名称</p>
</th>
<th class="cellrowborder" valign="top" width="51.74999999999999%" id="mcps1.2.3.1.2"><p id="p4118037152710"><a name="p4118037152710"></a><a name="p4118037152710"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row111823719274"><td class="cellrowborder" valign="top" width="48.25%" headers="mcps1.2.3.1.1 "><p id="p161181537112712"><a name="p161181537112712"></a><a name="p161181537112712"></a>void HiSysEventSubscribeCallBackBase::OnHandle(const std::string&amp; domain, const std::string&amp; eventName, const int eventType, const std::string&amp; eventDetail)</p>
</td>
<td class="cellrowborder" valign="top" width="51.74999999999999%" headers="mcps1.2.3.1.2 "><p id="p1772213111011"><a name="p1772213111011"></a><a name="p1772213111011"></a>接口功能:订阅事件的回调接口。</p>
<p id="p182081719151016"><a name="p182081719151016"></a><a name="p182081719151016"></a>输入参数:</p>
<a name="ul02091819131015"></a><a name="ul02091819131015"></a><ul id="ul02091819131015"><li>domain:事件所属领域。</li><li>eventName:事件的名称。</li><li>eventType:事件类型。</li><li>eventDetail:包含事件相关信息的字符串,以json的形式体现。</li></ul>
<p id="p18209419201010"><a name="p18209419201010"></a><a name="p18209419201010"></a>返回值:无。</p>
</td>
</tr>
</tbody>
</table>
## 开发实例<a name="section123181432175110"></a>
### C++接口实例<a name="section2016116181902"></a>
本实例介绍如何订阅domain=HIVIEWDFX的所有系统事件。
1. 源代码开发:
- 引入对应的头文件:
hisysevent\_manager.h。
- 实现回调接口:
HiSysEventSubscribeCallBackBase::OnHandle\(const std::string& domain, const std::string& eventName, const int eventType, const std::string& eventDetail\)。
- 注册回调对象:
HiSysEventManager::AddEventListener\(std::shared\_ptr<HiSysEventSubscribeCallBackBase\> listener, std::vector<struct ListenerRule\>& rules\)。
```
// 以下是订阅domain=HIVIEWDFX的所有系统事件的应用例子
#include "hisysevent_manager.h"
#include <iostream>
namespace OHOS {
namespace HiviewDFX {
// 实现订阅回调对象的接口
void HiSysEventToolListener::OnHandle(const std::string& domain, const std::string& eventName,
const int eventType, const std::string& eventDetail)
{
std::cout << eventDetail << std::endl;
}
void HiSysEventToolListener::OnServiceDied()
{
std::cout << std::string("service disconnect, exit") << std::endl;
exit(0);
}
} // namespace HiviewDFX
} // namespace OHOS
// 调用订阅接口注册开发实现的订阅对象
auto toolListener = std::make_shared<HiSysEventToolListener>();
struct ListenerRule rule;
rule.ruleType = 1; // 1: default type
rule.domain = "HIVIEWDFX";
std::vector<struct ListenerRule> sysRules;
sysRules.push_back(rule);
HiSysEventManager::AddEventListener(toolListener, sysRules);
```
2. 编译设置:
在BUILD.gn编译文件中,需要添加依赖hisysevent\_native部件的libhisyseventmanager库。
```
external_deps = [ "hisysevent_native:libhisyseventmanager", ]
```
# HiSysEvent查询指导<a name="ZH-CN_TOPIC_0000001231455461"></a>
- [概述](#section279684125212)
- [接口说明](#section03869128521)
- [开发实例](#section14286111855212)
- [C++接口实例](#section162045551743)
## 概述<a name="section279684125212"></a>
HiSysEvent提供了查询接口,支持开发者设置条件查询HiSysEvent事件,例如功耗部件可以通过该接口获取所需的系统事件进行业务分析。
## 接口说明<a name="section03869128521"></a>
**表 1** HiSysEvent查询接口
<a name="table1844019587496"></a>
<table><thead align="left"><tr id="row1440058184916"><th class="cellrowborder" valign="top" width="48.120000000000005%" id="mcps1.2.3.1.1"><p id="p19441135844915"><a name="p19441135844915"></a><a name="p19441135844915"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="51.88%" id="mcps1.2.3.1.2"><p id="p13441195815491"><a name="p13441195815491"></a><a name="p13441195815491"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row16441155818499"><td class="cellrowborder" valign="top" width="48.120000000000005%" headers="mcps1.2.3.1.1 "><p id="p114411558204915"><a name="p114411558204915"></a><a name="p114411558204915"></a>bool HiSysEventManager::QueryHiSysEvent(struct QueryArg&amp; queryArg, std::vector&lt;struct QueryRule&gt;&amp; queryRules, std::shared_ptr&lt;HiSysEventQueryCallBackBase&gt; queryCallBack)</p>
</td>
<td class="cellrowborder" valign="top" width="51.88%" headers="mcps1.2.3.1.2 "><p id="p14727325133216"><a name="p14727325133216"></a><a name="p14727325133216"></a>接口功能:支持设置查询时间段,事件领域,事件名称等,查询满足条件的HiSysEvent事件。</p>
<p id="p167271525203213"><a name="p167271525203213"></a><a name="p167271525203213"></a>输入参数:</p>
<a name="ul6717142214919"></a><a name="ul6717142214919"></a><ul id="ul6717142214919"><li>queryArg:查询参数。</li><li>queryRules:事件过滤规则。</li><li>queryCallBack:查询接口回调对象。</li></ul>
<p id="p83591223153818"><a name="p83591223153818"></a><a name="p83591223153818"></a>返回值:</p>
<a name="ul12105842111913"></a><a name="ul12105842111913"></a><ul id="ul12105842111913"><li>true:查询成功。</li><li>false:查询失败。</li></ul>
</td>
</tr>
</tbody>
</table>
**表 2** QueryArg查询参数对象
<a name="table13783145132014"></a>
<table><thead align="left"><tr id="row11784451112013"><th class="cellrowborder" valign="top" width="47.85%" id="mcps1.2.3.1.1"><p id="p187841351152012"><a name="p187841351152012"></a><a name="p187841351152012"></a>属性名称</p>
</th>
<th class="cellrowborder" valign="top" width="52.15%" id="mcps1.2.3.1.2"><p id="p4784105182019"><a name="p4784105182019"></a><a name="p4784105182019"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row3784451122012"><td class="cellrowborder" valign="top" width="47.85%" headers="mcps1.2.3.1.1 "><p id="p2078414512209"><a name="p2078414512209"></a><a name="p2078414512209"></a>long long beginTime</p>
</td>
<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.2.3.1.2 "><p id="p37844517207"><a name="p37844517207"></a><a name="p37844517207"></a>事件开始时间。</p>
</td>
</tr>
<tr id="row1564913158230"><td class="cellrowborder" valign="top" width="47.85%" headers="mcps1.2.3.1.1 "><p id="p11649191511239"><a name="p11649191511239"></a><a name="p11649191511239"></a>long long endTime</p>
</td>
<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.2.3.1.2 "><p id="p126491715182314"><a name="p126491715182314"></a><a name="p126491715182314"></a>事件结束事件。</p>
</td>
</tr>
<tr id="row461821212236"><td class="cellrowborder" valign="top" width="47.85%" headers="mcps1.2.3.1.1 "><p id="p461841262313"><a name="p461841262313"></a><a name="p461841262313"></a>int maxEvents</p>
</td>
<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.2.3.1.2 "><p id="p1161901214232"><a name="p1161901214232"></a><a name="p1161901214232"></a>返回最大的查询条数。</p>
</td>
</tr>
</tbody>
</table>
**表 3** QueryRule查询规则对象
<a name="table1144011610564"></a>
<table><thead align="left"><tr id="row124411716175611"><th class="cellrowborder" valign="top" width="48.03%" id="mcps1.2.3.1.1"><p id="p19441151675610"><a name="p19441151675610"></a><a name="p19441151675610"></a>属性名称</p>
</th>
<th class="cellrowborder" valign="top" width="51.970000000000006%" id="mcps1.2.3.1.2"><p id="p16441171616563"><a name="p16441171616563"></a><a name="p16441171616563"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row174411216105615"><td class="cellrowborder" valign="top" width="48.03%" headers="mcps1.2.3.1.1 "><p id="p496413536613"><a name="p496413536613"></a><a name="p496413536613"></a><span>uint32_t</span> ruleType</p>
</td>
<td class="cellrowborder" valign="top" width="51.970000000000006%" headers="mcps1.2.3.1.2 "><p id="p94416160565"><a name="p94416160565"></a><a name="p94416160565"></a>规则类型,目前默认是0。</p>
</td>
</tr>
<tr id="row64411816125614"><td class="cellrowborder" valign="top" width="48.03%" headers="mcps1.2.3.1.1 "><p id="p1258135313712"><a name="p1258135313712"></a><a name="p1258135313712"></a>std::string domain;</p>
</td>
<td class="cellrowborder" valign="top" width="51.970000000000006%" headers="mcps1.2.3.1.2 "><a name="ul14905926102311"></a><a name="ul14905926102311"></a><ul id="ul14905926102311"><li>domain:事件所属领域,如果传入的是空字符串,则默认事件领域字段匹配成功。</li></ul>
</td>
</tr>
<tr id="row244161615619"><td class="cellrowborder" valign="top" width="48.03%" headers="mcps1.2.3.1.1 "><p id="p227913101887"><a name="p227913101887"></a><a name="p227913101887"></a>std::vector&lt;std::string&gt; eventList</p>
</td>
<td class="cellrowborder" valign="top" width="51.970000000000006%" headers="mcps1.2.3.1.2 "><a name="ul248063132319"></a><a name="ul248063132319"></a><ul id="ul248063132319"><li>eventList:事件名称的列表,如果传入的是空字符串,则默认事件名称字段匹配成功。</li></ul>
</td>
</tr>
</tbody>
</table>
**表 4** HiSysEventQueryCallBackBase查询回调对象
<a name="table1451320549112"></a>
<table><thead align="left"><tr id="row951420547116"><th class="cellrowborder" valign="top" width="48.03%" id="mcps1.2.3.1.1"><p id="p15141546117"><a name="p15141546117"></a><a name="p15141546117"></a>接口名称</p>
</th>
<th class="cellrowborder" valign="top" width="51.970000000000006%" id="mcps1.2.3.1.2"><p id="p165141654151113"><a name="p165141654151113"></a><a name="p165141654151113"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row35141554151115"><td class="cellrowborder" valign="top" width="48.03%" headers="mcps1.2.3.1.1 "><p id="p4714143785410"><a name="p4714143785410"></a><a name="p4714143785410"></a>void HiSysEventQueryCallBackBase::OnQuery(const ::std::vector&lt;std::string&gt;&amp; sysEvent, const ::std::vector&lt;int64_t&gt;&amp; seq)</p>
</td>
<td class="cellrowborder" valign="top" width="51.970000000000006%" headers="mcps1.2.3.1.2 "><p id="p1772213111011"><a name="p1772213111011"></a><a name="p1772213111011"></a>接口功能:订阅事件查询中的回调。</p>
<p id="p182081719151016"><a name="p182081719151016"></a><a name="p182081719151016"></a>输入参数:</p>
<a name="ul02091819131015"></a><a name="ul02091819131015"></a><ul id="ul02091819131015"><li>sysEvent:返回事件集合。</li><li>seq:事件序列集合。</li></ul>
<p id="p18209419201010"><a name="p18209419201010"></a><a name="p18209419201010"></a>返回值:无。</p>
</td>
</tr>
<tr id="row15141154161111"><td class="cellrowborder" valign="top" width="48.03%" headers="mcps1.2.3.1.1 "><p id="p561110151119"><a name="p561110151119"></a><a name="p561110151119"></a>void HiSysEventQueryCallBackBase::OnComplete(int32_t reason, int32_t total)</p>
</td>
<td class="cellrowborder" valign="top" width="51.970000000000006%" headers="mcps1.2.3.1.2 "><p id="p126315352130"><a name="p126315352130"></a><a name="p126315352130"></a>接口功能:订阅事件查询完成的回调。</p>
<p id="p6631235191316"><a name="p6631235191316"></a><a name="p6631235191316"></a>输入参数:</p>
<a name="ul106383518130"></a><a name="ul106383518130"></a><ul id="ul106383518130"><li>reason:查询结束返回原因,目前默认是0。</li><li>total:本次查询总共返回的事件总数量。</li></ul>
<p id="p176313516133"><a name="p176313516133"></a><a name="p176313516133"></a>返回值:无。</p>
</td>
</tr>
</tbody>
</table>
## 开发实例<a name="section14286111855212"></a>
### C++接口实例<a name="section162045551743"></a>
本实例介绍如何查询所有系统事件。
1. 源代码开发:
- 引入对应的头文件:
hisysevent\_manager.h
- 实现对应的查询回调接口:
void HiSysEventQueryCallBackBase::OnQuery\(const ::std::vector<std::string\>& sysEvent, const ::std::vector<int64\_t\>& seq\)
void HiSysEventQueryCallBackBase::OnComplete\(int32\_t reason, int32\_t total\)
- 在相应的业务逻辑里面调用查询接口:
HiSysEventManager::QueryHiSysEvent\(struct QueryArg& queryArg, std::vector<struct QueryRule\>& queryRules, std::shared\_ptr<HiSysEventQueryCallBackBase\> queryCallBack\)
```
// 以下是查询所有系统事件的应用例子
#include "hisysevent_manager.h"
#include <iostream>
namespace OHOS {
namespace HiviewDFX {
// 实现查询回调的接口
void HiSysEventToolQuery::OnQuery(const ::std::vector<std::string>& sysEvent,
const ::std::vector<int64_t>& seq)
{
for_each(sysEvent.cbegin(), sysEvent.cend(), [](const std::string &tmp) {
std::cout << tmp << std::endl;
});
}
void HiSysEventToolQuery::OnComplete(int32_t reason, int32_t total)
{
return;
}
} // namespace HiviewDFX
} // namespace OHOS
// 调用查询接口获取HiSysEvent事件
auto queryCallBack = std::make_shared<HiSysEventToolQuery>();
struct QueryArg args(clientCmdArg.beginTime, clientCmdArg.endTime, clientCmdArg.maxEvents);
std::vector<struct QueryRule> mRules;
HiSysEventManager::QueryHiSysEvent(args, mRules, queryCallBack);
```
2. 编译设置:
在BUILD.gn编译文件中,需要添加依赖hisysevent\_native部件的libhisyseventmanager库。
```
external_deps = [ "hisysevent_native:libhisyseventmanager", ]
```
# HiSysEvent工具使用指导<a name="ZH-CN_TOPIC_0000001231614021"></a>
- [概述](#section1886702718521)
- [使用指导](#section1210623418527)
## 概述<a name="section1886702718521"></a>
目前系统预制了HiSysEvent小工具,可以通过命令行参数,设置查询条件,查询满足要求的HiSysEvent系统事件,支撑开发者在开发过程中是否打点成功,以及故障定位时系统所发生的事件等研发场景。
## 使用指导<a name="section1210623418527"></a>
1. HiSysEvent工具的参数:
工具预置在/system/bin目录下,命令可以在任意目录执行。
```
hisysevent [-r | -l [-s <time> -e <time> -m <count>]]
-r get real hisysevent log.
-l -s <begin time> -e <end time> -m <max hisysevent count>
get history hisysevent log, begin time should not be earlier than end time.
```
2. 查询实时HiSysEvent事件的命令:
```
hisysevent -r
```
当实时HiSysEvent事件过来的时候,会在控制台上打印一条HiSysEvent事件。
3. 查询历史HiSysEvent事件的命令:
```
hisysevent -l -s <begin time> -e <end time> -m <max hisysevent count>
```
其中-s和-e分别指定了事件生成的开始时间和结束时间,如果没有-s或者-e,代表查询时间无下限/无上限。
-m参数制定了本次查询最多返回的时间条数。
# HiSysEvent打点指导<a name="ZH-CN_TOPIC_0000001231373947"></a>
- [概述](#section77571101789)
- [接口说明](#section13480315886)
- [开发实例](#section112771171317)
## 概述<a name="section77571101789"></a>
HiSysEvent提供OpenHarmony打点接口,通过在关键路径打点记录系统在运行过程中的重要信息,辅助开发者定位问题,此外还支持开发者将数据上传到云进行大数据质量度量。
## 接口说明<a name="section13480315886"></a>
C++打点接口如下:
HiSysEvent类,具体的API详见接口文档 。
**表 1** HiSysEvent接口介绍
<a name="table1972602519328"></a>
<table><thead align="left"><tr id="row5726112593219"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p1472602523216"><a name="p1472602523216"></a><a name="p1472602523216"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p12726112512322"><a name="p12726112512322"></a><a name="p12726112512322"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row47261259328"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p15726112583213"><a name="p15726112583213"></a><a name="p15726112583213"></a>template&lt;typename... Types&gt; static int Write(const std::string &amp;domain, const std::string &amp;eventName, EventType type, Types... keyValues)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p14727325133216"><a name="p14727325133216"></a><a name="p14727325133216"></a>接口功能:记录系统事件。</p>
<p id="p167271525203213"><a name="p167271525203213"></a><a name="p167271525203213"></a>输入参数:</p>
<a name="ul0727102516327"></a><a name="ul0727102516327"></a><ul id="ul0727102516327"><li>domain:事件的相关领域,需要使用预置领域请参考Domain,可自定义领域。自定义领域长度在16个字符以内,有效的字符是0-9、A-Z,以字母开头。</li><li>eventName:事件名,长度在32个字符以内,有效的字符是0-9、A-Z、_,以字母开头,不能以_结尾。</li><li>type:事件类型,参考EventType。</li><li>keyValues:事件参数键值对,支持基本的数据类型、std::string,以及std::vector&lt;基本类型&gt;、std:vector&lt;std::string&gt;。参数名长度在48个字符以内,有效的字符是0-9、A-Z、_,以字母开头,不能以_结尾。参数名的个数在32个以内。</li></ul>
<p id="p1727152513217"><a name="p1727152513217"></a><a name="p1727152513217"></a>返回值:成功返回0,错误返回小于0的值。</p>
</td>
</tr>
</tbody>
</table>
**表 2** HiSysEvent::Domain接口介绍
<a name="table142141234133615"></a>
<table><thead align="left"><tr id="row8214234193616"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p13214183417365"><a name="p13214183417365"></a><a name="p13214183417365"></a>成员</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p1721593463618"><a name="p1721593463618"></a><a name="p1721593463618"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row14215133418366"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p22151634123614"><a name="p22151634123614"></a><a name="p22151634123614"></a>static const std::string AAFWK</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p19215163483612"><a name="p19215163483612"></a><a name="p19215163483612"></a>元能力子系统</p>
</td>
</tr>
<tr id="row10215134203618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1935112710382"><a name="p1935112710382"></a><a name="p1935112710382"></a>static const std::string APPEXECFWK</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p2215183419362"><a name="p2215183419362"></a><a name="p2215183419362"></a>用户程序框架子系统</p>
</td>
</tr>
<tr id="row2021515343365"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p03509723812"><a name="p03509723812"></a><a name="p03509723812"></a>static const std::string ACCOUNT</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p142155348362"><a name="p142155348362"></a><a name="p142155348362"></a>账号子系统</p>
</td>
</tr>
<tr id="row162151334143616"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p2349778386"><a name="p2349778386"></a><a name="p2349778386"></a>static const std::string ACE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p721510342365"><a name="p721510342365"></a><a name="p721510342365"></a>ACE子系统</p>
</td>
</tr>
<tr id="row4215193413618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p173487753812"><a name="p173487753812"></a><a name="p173487753812"></a>static const std::string AI</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p182159347368"><a name="p182159347368"></a><a name="p182159347368"></a>AI业务子系统</p>
</td>
</tr>
<tr id="row112151534193614"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p19348975387"><a name="p19348975387"></a><a name="p19348975387"></a>static const std::string BARRIER_FREE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p6215183412369"><a name="p6215183412369"></a><a name="p6215183412369"></a>无障碍软件服务子系统</p>
</td>
</tr>
<tr id="row1721573415364"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p163474783815"><a name="p163474783815"></a><a name="p163474783815"></a>static const std::string BIOMETRICS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1521583443619"><a name="p1521583443619"></a><a name="p1521583443619"></a>生物特征识别服务子系统</p>
</td>
</tr>
<tr id="row321513423619"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p334617713387"><a name="p334617713387"></a><a name="p334617713387"></a>static const std::string CCRUNTIME</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1421513417361"><a name="p1421513417361"></a><a name="p1421513417361"></a>C/C++运行环境子系统</p>
</td>
</tr>
<tr id="row192165341362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p33458773814"><a name="p33458773814"></a><a name="p33458773814"></a>static const std::string COMMUNICATION</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p2216143411364"><a name="p2216143411364"></a><a name="p2216143411364"></a>公共通信子系统</p>
</td>
</tr>
<tr id="row52162034183611"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1634417123816"><a name="p1634417123816"></a><a name="p1634417123816"></a>static const std::string DEVELOPTOOLS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121643473611"><a name="p1121643473611"></a><a name="p1121643473611"></a>研发工具链子系统</p>
</td>
</tr>
<tr id="row10216133483618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p834314716385"><a name="p834314716385"></a><a name="p834314716385"></a>static const std::string DISTRIBUTED_DATAMGR</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p621693417364"><a name="p621693417364"></a><a name="p621693417364"></a>分布式数据管理子系统</p>
</td>
</tr>
<tr id="row10216153414361"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p8342127193813"><a name="p8342127193813"></a><a name="p8342127193813"></a>static const std::string DISTRIBUTED_SCHEDULE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1321603418362"><a name="p1321603418362"></a><a name="p1321603418362"></a>分布式任务调度子系统</p>
</td>
</tr>
<tr id="row18216934193616"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p6342670388"><a name="p6342670388"></a><a name="p6342670388"></a>static const std::string GLOBAL</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p12162342368"><a name="p12162342368"></a><a name="p12162342368"></a>全球化子系统</p>
</td>
</tr>
<tr id="row1921643473618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p43413743815"><a name="p43413743815"></a><a name="p43413743815"></a>static const std::string GRAPHIC</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p921663443620"><a name="p921663443620"></a><a name="p921663443620"></a>图形子系统</p>
</td>
</tr>
<tr id="row1216113412368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p434015743812"><a name="p434015743812"></a><a name="p434015743812"></a>static const std::string HIVIEWDFX</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p32165345365"><a name="p32165345365"></a><a name="p32165345365"></a>DFX子系统</p>
</td>
</tr>
<tr id="row122165342363"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p333912703815"><a name="p333912703815"></a><a name="p333912703815"></a>static const std::string IAWARE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p82161134113614"><a name="p82161134113614"></a><a name="p82161134113614"></a>本地资源调度管控子系统</p>
</td>
</tr>
<tr id="row221673473618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p233815723812"><a name="p233815723812"></a><a name="p233815723812"></a>static const std::string INTELLI_ACCESSORIES</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121793463615"><a name="p1121793463615"></a><a name="p1121793463615"></a>智能配件业务子系统</p>
</td>
</tr>
<tr id="row1821783414362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p173371976381"><a name="p173371976381"></a><a name="p173371976381"></a>static const std::string INTELLI_TV</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121716345369"><a name="p1121716345369"></a><a name="p1121716345369"></a>智能电视业务子系统</p>
</td>
</tr>
<tr id="row20217123483613"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p733610743820"><a name="p733610743820"></a><a name="p733610743820"></a>static const std::string IVI_HARDWARE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p321723443615"><a name="p321723443615"></a><a name="p321723443615"></a>车机专有硬件服务子系统</p>
</td>
</tr>
<tr id="row112171334143617"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p03351274383"><a name="p03351274383"></a><a name="p03351274383"></a>static const std::string LOCATION</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p6217193453611"><a name="p6217193453611"></a><a name="p6217193453611"></a>位置服务子系统</p>
</td>
</tr>
<tr id="row221773418362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p03359773815"><a name="p03359773815"></a><a name="p03359773815"></a>static const std::string MSDP</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p621714342361"><a name="p621714342361"></a><a name="p621714342361"></a>综合传感处理平台子系统</p>
</td>
</tr>
<tr id="row6217113473615"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p18334177386"><a name="p18334177386"></a><a name="p18334177386"></a>static const std::string MULTI_MEDIA</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1521763418365"><a name="p1521763418365"></a><a name="p1521763418365"></a>媒体子系统</p>
</td>
</tr>
<tr id="row1621719347364"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p18333147173816"><a name="p18333147173816"></a><a name="p18333147173816"></a>static const std::string MULTI_MODAL_INPUT</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p92171234133620"><a name="p92171234133620"></a><a name="p92171234133620"></a>多模输入子系统</p>
</td>
</tr>
<tr id="row1121710348363"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p153320793817"><a name="p153320793817"></a><a name="p153320793817"></a>static const std::string NOTIFICATION</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p10217163414360"><a name="p10217163414360"></a><a name="p10217163414360"></a>事件通知子系统</p>
</td>
</tr>
<tr id="row9217133493616"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p133315763820"><a name="p133315763820"></a><a name="p133315763820"></a>static const std::string POWERMGR</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p321715349360"><a name="p321715349360"></a><a name="p321715349360"></a>电源服务子系统</p>
</td>
</tr>
<tr id="row8217143413368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p163301279387"><a name="p163301279387"></a><a name="p163301279387"></a>static const std::string ROUTER</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p5218123414363"><a name="p5218123414363"></a><a name="p5218123414363"></a>路由器业务子系统</p>
</td>
</tr>
<tr id="row2021813344362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1233027113819"><a name="p1233027113819"></a><a name="p1233027113819"></a>static const std::string SECURITY</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p92181034193613"><a name="p92181034193613"></a><a name="p92181034193613"></a>安全子系统</p>
</td>
</tr>
<tr id="row1321812344367"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p113291753813"><a name="p113291753813"></a><a name="p113291753813"></a>static const std::string SENSORS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p20218143417362"><a name="p20218143417362"></a><a name="p20218143417362"></a>泛Sensor服务子系统</p>
</td>
</tr>
<tr id="row1721810349368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p8328270388"><a name="p8328270388"></a><a name="p8328270388"></a>static const std::string SOURCE_CODE_TRANSFORMER</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121893413614"><a name="p1121893413614"></a><a name="p1121893413614"></a>应用移植子系统</p>
</td>
</tr>
<tr id="row1221812343368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p73273715382"><a name="p73273715382"></a><a name="p73273715382"></a>static const std::string STARTUP</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p021816348364"><a name="p021816348364"></a><a name="p021816348364"></a>启动恢复子系统</p>
</td>
</tr>
<tr id="row62181634113613"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p93261674389"><a name="p93261674389"></a><a name="p93261674389"></a>static const std::string TELEPHONY</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1021843453616"><a name="p1021843453616"></a><a name="p1021843453616"></a>电话服务子系统</p>
</td>
</tr>
<tr id="row2218153416363"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p20326117193818"><a name="p20326117193818"></a><a name="p20326117193818"></a>static const std::string UPDATE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1221813473617"><a name="p1221813473617"></a><a name="p1221813473617"></a>升级服务子系统</p>
</td>
</tr>
<tr id="row921893411361"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p23251372386"><a name="p23251372386"></a><a name="p23251372386"></a>static const std::string USB</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1421963493612"><a name="p1421963493612"></a><a name="p1421963493612"></a>USB服务子系统</p>
</td>
</tr>
<tr id="row102191534183614"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1232397193818"><a name="p1232397193818"></a><a name="p1232397193818"></a>static const std::string WEARABLE_HARDWARE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1921919346367"><a name="p1921919346367"></a><a name="p1921919346367"></a>穿戴专有硬件服务子系统</p>
</td>
</tr>
<tr id="row721963413368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p63041770381"><a name="p63041770381"></a><a name="p63041770381"></a>static const std::string WEARABLE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p18219143493618"><a name="p18219143493618"></a><a name="p18219143493618"></a>穿戴业务子系统</p>
</td>
</tr>
<tr id="row845612549416"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p13457155424112"><a name="p13457155424112"></a><a name="p13457155424112"></a>static const std::string OTHERS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p44573548414"><a name="p44573548414"></a><a name="p44573548414"></a>其它</p>
</td>
</tr>
</tbody>
</table>
**表 3** HiSysEvent::EventType接口介绍
<a name="table0944173117434"></a>
<table><thead align="left"><tr id="row694473134311"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p394413113439"><a name="p394413113439"></a><a name="p394413113439"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p199441431154317"><a name="p199441431154317"></a><a name="p199441431154317"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row1894416312438"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p2094483154311"><a name="p2094483154311"></a><a name="p2094483154311"></a>FAULT</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p5944153124316"><a name="p5944153124316"></a><a name="p5944153124316"></a>故障类型事件</p>
</td>
</tr>
<tr id="row2944193134318"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p494443144312"><a name="p494443144312"></a><a name="p494443144312"></a>STATISTIC</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1494423111435"><a name="p1494423111435"></a><a name="p1494423111435"></a>统计类型事件</p>
</td>
</tr>
<tr id="row094463144311"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p594443184315"><a name="p594443184315"></a><a name="p594443184315"></a>SECURITY</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1194417316435"><a name="p1194417316435"></a><a name="p1194417316435"></a>安全类型事件</p>
</td>
</tr>
<tr id="row1294403119434"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p17944431164319"><a name="p17944431164319"></a><a name="p17944431164319"></a>BEHAVIOR</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p5945203184318"><a name="p5945203184318"></a><a name="p5945203184318"></a>系统行为事件</p>
</td>
</tr>
</tbody>
</table>
## 开发实例<a name="section112771171317"></a>
C++接口实例
1. 源代码开发
在类定义头文件或者类实现源文件中,包含HiSysEvent头文件:
```
#include "hisysevent.h"
```
假设在业务关注应用启动时间start\_app,在业务类实现相关源文件中使用(调用接口打点):
```
HiSysEvent::Write(HiSysEvent::Domain::AAFWK, "start_app", HiSysEvent::EventType::FAULT, "app_name", "com.demo");
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hisysevent_native:libhisysevent" ]
```
# HiSysEvent开发指导<a name="ZH-CN_TOPIC_0000001091101688"></a> # HiSysEvent开发指导<a name="ZH-CN_TOPIC_0000001195021448"></a>
- [概述](#section77571101789) - **[HiSysEvent打点指导](HiSysEvent打点指导.md)**
- [接口说明](#section13480315886)
- [开发实例](#section112771171317)
## 概述<a name="section77571101789"></a> - **[HiSysEvent订阅指导](HiSysEvent订阅指导.md)**
HiSysEvent提供OpenHarmony埋点接口,通过在关键路径埋点记录系统在运行过程中的重要信息,辅助开发者定位问题,此外还支持开发者将数据上传到云进行大数据质量度量。 - **[HiSysEvent查询指导](HiSysEvent查询指导.md)**
## 接口说明<a name="section13480315886"></a> - **[HiSysEvent工具使用指导](HiSysEvent工具使用指导.md)**
C++埋点接口如下:
HiSysEvent类,具体的API详见接口文档 。
**表 1** HiSysEvent接口介绍
<a name="table1972602519328"></a>
<table><thead align="left"><tr id="row5726112593219"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p1472602523216"><a name="p1472602523216"></a><a name="p1472602523216"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p12726112512322"><a name="p12726112512322"></a><a name="p12726112512322"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row47261259328"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p15726112583213"><a name="p15726112583213"></a><a name="p15726112583213"></a>template&lt;typename... Types&gt; static int Write(const std::string &amp;domain, const std::string &amp;eventName, EventType type, Types... keyValues)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p14727325133216"><a name="p14727325133216"></a><a name="p14727325133216"></a>接口功能:记录系统事件。</p>
<p id="p167271525203213"><a name="p167271525203213"></a><a name="p167271525203213"></a>输入参数:</p>
<a name="ul0727102516327"></a><a name="ul0727102516327"></a><ul id="ul0727102516327"><li>domain:事件的相关领域,需要使用预置领域请参考Domain,可自定义领域。自定义领域长度在16个字符以内,有效的字符是0-9、A-Z,以字母开头。</li><li>eventName:事件名,长度在32个字符以内,有效的字符是0-9、a-z、A-Z、_,以字母开头,不能以_结尾。</li><li>type:事件类型,参考EventType。</li><li>keyValues:事件参数键值对,支持基本的数据类型、std::string,以及std::vector&lt;基本类型&gt;、std:vector&lt;std::string&gt;。参数名长度在48个字符以内,有效的字符是0-9、a-z、A-Z、_,以字母开头,不能以_结尾。参数名的个数在32个以内。</li></ul>
<p id="p1727152513217"><a name="p1727152513217"></a><a name="p1727152513217"></a>返回值:成功返回0,错误返回小于0的值。</p>
</td>
</tr>
</tbody>
</table>
**表 2** HiSysEvent::Domain接口介绍
<a name="table142141234133615"></a>
<table><thead align="left"><tr id="row8214234193616"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p13214183417365"><a name="p13214183417365"></a><a name="p13214183417365"></a>成员</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p1721593463618"><a name="p1721593463618"></a><a name="p1721593463618"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row14215133418366"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p22151634123614"><a name="p22151634123614"></a><a name="p22151634123614"></a>static const std::string AAFWK</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p19215163483612"><a name="p19215163483612"></a><a name="p19215163483612"></a>元能力子系统</p>
</td>
</tr>
<tr id="row10215134203618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1935112710382"><a name="p1935112710382"></a><a name="p1935112710382"></a>static const std::string APPEXECFWK</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p2215183419362"><a name="p2215183419362"></a><a name="p2215183419362"></a>用户程序框架子系统</p>
</td>
</tr>
<tr id="row2021515343365"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p03509723812"><a name="p03509723812"></a><a name="p03509723812"></a>static const std::string ACCOUNT</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p142155348362"><a name="p142155348362"></a><a name="p142155348362"></a>账号子系统</p>
</td>
</tr>
<tr id="row162151334143616"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p2349778386"><a name="p2349778386"></a><a name="p2349778386"></a>static const std::string ACE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p721510342365"><a name="p721510342365"></a><a name="p721510342365"></a>ACE子系统</p>
</td>
</tr>
<tr id="row4215193413618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p173487753812"><a name="p173487753812"></a><a name="p173487753812"></a>static const std::string AI</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p182159347368"><a name="p182159347368"></a><a name="p182159347368"></a>AI业务子系统</p>
</td>
</tr>
<tr id="row112151534193614"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p19348975387"><a name="p19348975387"></a><a name="p19348975387"></a>static const std::string BARRIER_FREE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p6215183412369"><a name="p6215183412369"></a><a name="p6215183412369"></a>无障碍软件服务子系统</p>
</td>
</tr>
<tr id="row1721573415364"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p163474783815"><a name="p163474783815"></a><a name="p163474783815"></a>static const std::string BIOMETRICS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1521583443619"><a name="p1521583443619"></a><a name="p1521583443619"></a>生物特征识别服务子系统</p>
</td>
</tr>
<tr id="row321513423619"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p334617713387"><a name="p334617713387"></a><a name="p334617713387"></a>static const std::string CCRUNTIME</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1421513417361"><a name="p1421513417361"></a><a name="p1421513417361"></a>C/C++运行环境子系统</p>
</td>
</tr>
<tr id="row192165341362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p33458773814"><a name="p33458773814"></a><a name="p33458773814"></a>static const std::string COMMUNICATION</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p2216143411364"><a name="p2216143411364"></a><a name="p2216143411364"></a>公共通信子系统</p>
</td>
</tr>
<tr id="row52162034183611"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1634417123816"><a name="p1634417123816"></a><a name="p1634417123816"></a>static const std::string DEVELOPTOOLS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121643473611"><a name="p1121643473611"></a><a name="p1121643473611"></a>研发工具链子系统</p>
</td>
</tr>
<tr id="row10216133483618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p834314716385"><a name="p834314716385"></a><a name="p834314716385"></a>static const std::string DISTRIBUTED_DATAMGR</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p621693417364"><a name="p621693417364"></a><a name="p621693417364"></a>分布式数据管理子系统</p>
</td>
</tr>
<tr id="row10216153414361"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p8342127193813"><a name="p8342127193813"></a><a name="p8342127193813"></a>static const std::string DISTRIBUTED_SCHEDULE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1321603418362"><a name="p1321603418362"></a><a name="p1321603418362"></a>分布式任务调度子系统</p>
</td>
</tr>
<tr id="row18216934193616"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p6342670388"><a name="p6342670388"></a><a name="p6342670388"></a>static const std::string GLOBAL</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p12162342368"><a name="p12162342368"></a><a name="p12162342368"></a>全球化子系统</p>
</td>
</tr>
<tr id="row1921643473618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p43413743815"><a name="p43413743815"></a><a name="p43413743815"></a>static const std::string GRAPHIC</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p921663443620"><a name="p921663443620"></a><a name="p921663443620"></a>图形子系统</p>
</td>
</tr>
<tr id="row1216113412368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p434015743812"><a name="p434015743812"></a><a name="p434015743812"></a>static const std::string HIVIEWDFX</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p32165345365"><a name="p32165345365"></a><a name="p32165345365"></a>DFX子系统</p>
</td>
</tr>
<tr id="row122165342363"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p333912703815"><a name="p333912703815"></a><a name="p333912703815"></a>static const std::string IAWARE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p82161134113614"><a name="p82161134113614"></a><a name="p82161134113614"></a>本地资源调度管控子系统</p>
</td>
</tr>
<tr id="row221673473618"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p233815723812"><a name="p233815723812"></a><a name="p233815723812"></a>static const std::string INTELLI_ACCESSORIES</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121793463615"><a name="p1121793463615"></a><a name="p1121793463615"></a>智能配件业务子系统</p>
</td>
</tr>
<tr id="row1821783414362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p173371976381"><a name="p173371976381"></a><a name="p173371976381"></a>static const std::string INTELLI_TV</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121716345369"><a name="p1121716345369"></a><a name="p1121716345369"></a>智能电视业务子系统</p>
</td>
</tr>
<tr id="row20217123483613"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p733610743820"><a name="p733610743820"></a><a name="p733610743820"></a>static const std::string IVI_HARDWARE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p321723443615"><a name="p321723443615"></a><a name="p321723443615"></a>车机专有硬件服务子系统</p>
</td>
</tr>
<tr id="row112171334143617"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p03351274383"><a name="p03351274383"></a><a name="p03351274383"></a>static const std::string LOCATION</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p6217193453611"><a name="p6217193453611"></a><a name="p6217193453611"></a>位置服务子系统</p>
</td>
</tr>
<tr id="row221773418362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p03359773815"><a name="p03359773815"></a><a name="p03359773815"></a>static const std::string MSDP</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p621714342361"><a name="p621714342361"></a><a name="p621714342361"></a>综合传感处理平台子系统</p>
</td>
</tr>
<tr id="row6217113473615"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p18334177386"><a name="p18334177386"></a><a name="p18334177386"></a>static const std::string MULTI_MEDIA</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1521763418365"><a name="p1521763418365"></a><a name="p1521763418365"></a>媒体子系统</p>
</td>
</tr>
<tr id="row1621719347364"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p18333147173816"><a name="p18333147173816"></a><a name="p18333147173816"></a>static const std::string MULTI_MODAL_INPUT</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p92171234133620"><a name="p92171234133620"></a><a name="p92171234133620"></a>多模输入子系统</p>
</td>
</tr>
<tr id="row1121710348363"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p153320793817"><a name="p153320793817"></a><a name="p153320793817"></a>static const std::string NOTIFICATION</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p10217163414360"><a name="p10217163414360"></a><a name="p10217163414360"></a>事件通知子系统</p>
</td>
</tr>
<tr id="row9217133493616"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p133315763820"><a name="p133315763820"></a><a name="p133315763820"></a>static const std::string POWERMGR</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p321715349360"><a name="p321715349360"></a><a name="p321715349360"></a>电源服务子系统</p>
</td>
</tr>
<tr id="row8217143413368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p163301279387"><a name="p163301279387"></a><a name="p163301279387"></a>static const std::string ROUTER</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p5218123414363"><a name="p5218123414363"></a><a name="p5218123414363"></a>路由器业务子系统</p>
</td>
</tr>
<tr id="row2021813344362"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1233027113819"><a name="p1233027113819"></a><a name="p1233027113819"></a>static const std::string SECURITY</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p92181034193613"><a name="p92181034193613"></a><a name="p92181034193613"></a>安全子系统</p>
</td>
</tr>
<tr id="row1321812344367"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p113291753813"><a name="p113291753813"></a><a name="p113291753813"></a>static const std::string SENSORS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p20218143417362"><a name="p20218143417362"></a><a name="p20218143417362"></a>泛Sensor服务子系统</p>
</td>
</tr>
<tr id="row1721810349368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p8328270388"><a name="p8328270388"></a><a name="p8328270388"></a>static const std::string SOURCE_CODE_TRANSFORMER</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1121893413614"><a name="p1121893413614"></a><a name="p1121893413614"></a>应用移植子系统</p>
</td>
</tr>
<tr id="row1221812343368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p73273715382"><a name="p73273715382"></a><a name="p73273715382"></a>static const std::string STARTUP</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p021816348364"><a name="p021816348364"></a><a name="p021816348364"></a>启动恢复子系统</p>
</td>
</tr>
<tr id="row62181634113613"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p93261674389"><a name="p93261674389"></a><a name="p93261674389"></a>static const std::string TELEPHONY</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1021843453616"><a name="p1021843453616"></a><a name="p1021843453616"></a>电话服务子系统</p>
</td>
</tr>
<tr id="row2218153416363"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p20326117193818"><a name="p20326117193818"></a><a name="p20326117193818"></a>static const std::string UPDATE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1221813473617"><a name="p1221813473617"></a><a name="p1221813473617"></a>升级服务子系统</p>
</td>
</tr>
<tr id="row921893411361"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p23251372386"><a name="p23251372386"></a><a name="p23251372386"></a>static const std::string USB</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1421963493612"><a name="p1421963493612"></a><a name="p1421963493612"></a>USB服务子系统</p>
</td>
</tr>
<tr id="row102191534183614"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1232397193818"><a name="p1232397193818"></a><a name="p1232397193818"></a>static const std::string WEARABLE_HARDWARE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1921919346367"><a name="p1921919346367"></a><a name="p1921919346367"></a>穿戴专有硬件服务子系统</p>
</td>
</tr>
<tr id="row721963413368"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p63041770381"><a name="p63041770381"></a><a name="p63041770381"></a>static const std::string WEARABLE</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p18219143493618"><a name="p18219143493618"></a><a name="p18219143493618"></a>穿戴业务子系统</p>
</td>
</tr>
<tr id="row845612549416"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p13457155424112"><a name="p13457155424112"></a><a name="p13457155424112"></a>static const std::string OTHERS</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p44573548414"><a name="p44573548414"></a><a name="p44573548414"></a>其它</p>
</td>
</tr>
</tbody>
</table>
**表 3** HiSysEvent::EventType接口介绍
<a name="table0944173117434"></a>
<table><thead align="left"><tr id="row694473134311"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p394413113439"><a name="p394413113439"></a><a name="p394413113439"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p199441431154317"><a name="p199441431154317"></a><a name="p199441431154317"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row1894416312438"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p2094483154311"><a name="p2094483154311"></a><a name="p2094483154311"></a>FAULT</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p5944153124316"><a name="p5944153124316"></a><a name="p5944153124316"></a>故障类型事件</p>
</td>
</tr>
<tr id="row2944193134318"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p494443144312"><a name="p494443144312"></a><a name="p494443144312"></a>STATISTIC</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1494423111435"><a name="p1494423111435"></a><a name="p1494423111435"></a>统计类型事件</p>
</td>
</tr>
<tr id="row094463144311"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p594443184315"><a name="p594443184315"></a><a name="p594443184315"></a>SECURITY</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1194417316435"><a name="p1194417316435"></a><a name="p1194417316435"></a>安全类型事件</p>
</td>
</tr>
<tr id="row1294403119434"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p17944431164319"><a name="p17944431164319"></a><a name="p17944431164319"></a>BEHAVIOR</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p5945203184318"><a name="p5945203184318"></a><a name="p5945203184318"></a>系统行为事件</p>
</td>
</tr>
</tbody>
</table>
## 开发实例<a name="section112771171317"></a>
C++接口实例
1. 源代码开发
在类定义头文件或者类实现源文件中,包含HiSysEvent头文件:
```
#include "hisysevent.h"
```
假设在业务关注应用启动时间start\_app,在业务类实现相关源文件中使用(调用接口埋点):
```
HiSysEvent::Write(HiSysEvent::Domain::AAFWK, "start_app", HiSysEvent::EventType::FAULT, "app_name", "com.demo");
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hisysevent_native:libhisysevent" ]
```
# HiTrace开发指导<a name="ZH-CN_TOPIC_0000001186134310"></a>
- [概述](#section3986195420436)
- [应用场景](#section134561822574)
- [业务使用示例](#section63861653124417)
- [接口说明](#section1517945334617)
- [接口形式对比](#section932504474)
- [接口功能参数](#section2514638125)
- [通信调用处理](#section11257133933)
- [开发实例](#section14310412491)
- [C++接口实例](#section114916381509)
- [C接口实例](#section108292107514)
## 概述<a name="section3986195420436"></a>
HiTrace主要是对于跨设备/跨进程/跨线程的业务流程,通过相同的traceid在整个业务流程中传递,将流程处理过程中的调用关系、各种输出信息关联和展现出来,帮助使用者分析、定位问题和系统调优。
## 应用场景<a name="section134561822574"></a>
HiTrace在产品中应用场景如下,包括:
- 端侧业务流程信息(日志、事件等)关联、上报
- 云侧对上报信息的关联展示和分析,辅助问题定位
- IDE对业务流程详细信息、耗时分布进行调试,辅助系统调优
**图 1** HiTrace应用场景<a name="fig179241023125715"></a>
![](figure/HiTrace应用场景.png "HiTrace应用场景")
### 业务使用示例<a name="section63861653124417"></a>
**图 2** 业务调用流程图(跨设备、跨进程同步调用)<a name="fig173491014145819"></a>
![](figure/业务调用流程图(跨设备-跨进程同步调用).png "业务调用流程图(跨设备-跨进程同步调用)")
1. 调试时展示业务流程中的调用关系,进行关键路径分析、功能依赖分析,确定各调用点耗时、调用频率,提前发现性能瓶颈点。
**图 3** 业务调用流程序列图<a name="fig205051834145813"></a>
![](figure/业务调用流程序列图.png "业务调用流程序列图")
**图 4** 业务调用流程性能耗时分布<a name="fig1212812422586"></a>
![](figure/业务调用流程性能耗时分布.png "业务调用流程性能耗时分布")
2. 在日志和事件等信息中自动附加traceid信息,便于开发人员综合分析和快速实现问题定界定位。
## 接口说明<a name="section1517945334617"></a>
HiTrace提供C++、C接口。上层业务主要使用HiTrace跟踪启动、结束接口。
HiTrace实现在C层,主要原理是在一次业务调用流程中,利用通信传递traceid,在业务处理前将traceid设置到当前线程的TLS\(Thread Local Storage\)中,业务处理结束清除当前线程的TLS;这样的话,在业务处理中可以从当前线程的上下文TLS取到traceid,自动附加到日志、事件信息中。
### 接口形式对比<a name="section932504474"></a>
**表 1** C++、C的函数接口
<a name="table0218014155811"></a>
<table><thead align="left"><tr id="row3218171455817"><th class="cellrowborder" valign="top" width="12.540000000000001%" id="mcps1.2.4.1.1">&nbsp;&nbsp;</th>
<th class="cellrowborder" valign="top" width="41.42%" id="mcps1.2.4.1.2"><p id="p17257112417232"><a name="p17257112417232"></a><a name="p17257112417232"></a><strong id="b7257324122319"><a name="b7257324122319"></a><a name="b7257324122319"></a>C++</strong></p>
</th>
<th class="cellrowborder" valign="top" width="46.04%" id="mcps1.2.4.1.3"><p id="p13218151413588"><a name="p13218151413588"></a><a name="p13218151413588"></a><strong id="b5218181416588"><a name="b5218181416588"></a><a name="b5218181416588"></a>C</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row1218714155816"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 "><p id="p10218121475811"><a name="p10218121475811"></a><a name="p10218121475811"></a><strong id="b13218111445813"><a name="b13218111445813"></a><a name="b13218111445813"></a></strong></p>
</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p112189146582"><a name="p112189146582"></a><a name="p112189146582"></a><strong id="b122181814185813"><a name="b122181814185813"></a><a name="b122181814185813"></a>函数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p19219151413589"><a name="p19219151413589"></a><a name="p19219151413589"></a><strong id="b12219514135811"><a name="b12219514135811"></a><a name="b12219514135811"></a>函数</strong></p>
</td>
</tr>
<tr id="row1219111415585"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 "><p id="p15219101455812"><a name="p15219101455812"></a><a name="p15219101455812"></a>HiTrace</p>
</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p821971495820"><a name="p821971495820"></a><a name="p821971495820"></a>HiTraceId Begin(const std::string&amp; name, int flags)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p2219914195817"><a name="p2219914195817"></a><a name="p2219914195817"></a>HiTraceIdStruct HiTraceBegin(const char* name, int flags)</p>
</td>
</tr>
<tr id="row16219171417584"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p021971414588"><a name="p021971414588"></a><a name="p021971414588"></a>void End(const HiTraceId&amp; id)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p16219191435814"><a name="p16219191435814"></a><a name="p16219191435814"></a>void HiTraceEnd(const HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row02191414115819"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p42191143585"><a name="p42191143585"></a><a name="p42191143585"></a>HiTraceId GetId();</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p1221901419588"><a name="p1221901419588"></a><a name="p1221901419588"></a>HiTraceIdStruct HiTraceGetId()</p>
</td>
</tr>
<tr id="row11219131415582"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p6219111415812"><a name="p6219111415812"></a><a name="p6219111415812"></a>void SetId(const HiTraceId&amp; id)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p221971465818"><a name="p221971465818"></a><a name="p221971465818"></a>void HiTraceSetId(const HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row162191814105815"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p12191147586"><a name="p12191147586"></a><a name="p12191147586"></a>void ClearId()</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p18219181445813"><a name="p18219181445813"></a><a name="p18219181445813"></a>void HiTraceClearId()</p>
</td>
</tr>
<tr id="row12219151475812"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p1721981418580"><a name="p1721981418580"></a><a name="p1721981418580"></a>HiTraceId CreateSpan()</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p1121981420584"><a name="p1121981420584"></a><a name="p1121981420584"></a>HiTraceIdStruct HiTraceCreateSpan()</p>
</td>
</tr>
<tr id="row1721911140582"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p18219514195814"><a name="p18219514195814"></a><a name="p18219514195814"></a>void Tracepoint(HiTraceTracepointType type, const HiTraceId&amp; id, const char* fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p3219914175813"><a name="p3219914175813"></a><a name="p3219914175813"></a>void HiTraceTracepoint(HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, ...)</p>
</td>
</tr>
<tr id="row521911410582"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p2219101415814"><a name="p2219101415814"></a><a name="p2219101415814"></a>void Tracepoint(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceId&amp; id, const char* fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p2220141413584"><a name="p2220141413584"></a><a name="p2220141413584"></a>void HiTraceTracepointEx(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, ...)</p>
</td>
</tr>
<tr id="row8220181411586"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 "><p id="p522018149588"><a name="p522018149588"></a><a name="p522018149588"></a>HiTraceId</p>
</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p102201914105811"><a name="p102201914105811"></a><a name="p102201914105811"></a>HiTraceId();</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p16220161419581"><a name="p16220161419581"></a><a name="p16220161419581"></a>void HiTraceInitId(HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row8220191405817"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p162201314155813"><a name="p162201314155813"></a><a name="p162201314155813"></a>HiTraceId(const uint8_t* pIdArray, int len)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p122011425814"><a name="p122011425814"></a><a name="p122011425814"></a>HiTraceIdStruct HiTraceBytesToId(const uint8_t* pIdArray, int len)</p>
</td>
</tr>
<tr id="row1522041435820"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p1422012146587"><a name="p1422012146587"></a><a name="p1422012146587"></a>bool IsValid()</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p1322016149586"><a name="p1322016149586"></a><a name="p1322016149586"></a>int HiTraceIsValid(const HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row8220714155810"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p322021485814"><a name="p322021485814"></a><a name="p322021485814"></a>bool IsFlagEnabled(HiTraceFlag flag)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p922010148583"><a name="p922010148583"></a><a name="p922010148583"></a>int HiTraceIsFlagEnabled(const HiTraceIdStruct* pId, HiTraceFlag flag)</p>
</td>
</tr>
<tr id="row12220161485814"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p1122011140588"><a name="p1122011140588"></a><a name="p1122011140588"></a>void EnableFlag(HiTraceFlag flag)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p152201146583"><a name="p152201146583"></a><a name="p152201146583"></a>void HiTraceEnableFlag(HiTraceIdStruct* pId, HiTraceFlag flag)</p>
</td>
</tr>
<tr id="row922061411589"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p202208143588"><a name="p202208143588"></a><a name="p202208143588"></a>int GetFlags()</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p182206142587"><a name="p182206142587"></a><a name="p182206142587"></a>int HiTraceGetFlags(const HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row82204145589"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p12201414205815"><a name="p12201414205815"></a><a name="p12201414205815"></a>void SetFlags(int flags)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p162201514175813"><a name="p162201514175813"></a><a name="p162201514175813"></a>void HiTraceSetFlags(HiTraceIdStruct* pId, int flags)</p>
</td>
</tr>
<tr id="row152204143585"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p722113147580"><a name="p722113147580"></a><a name="p722113147580"></a>uint64_t GetChainId()</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p322119149584"><a name="p322119149584"></a><a name="p322119149584"></a>uint64_t HiTraceGetChainId(const HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row1221214175815"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p922131445815"><a name="p922131445815"></a><a name="p922131445815"></a>void SetChainId(uint64_t chainId)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p922101411588"><a name="p922101411588"></a><a name="p922101411588"></a>void HiTraceSetChainId(HiTraceIdStruct* pId, uint64_t chainId)</p>
</td>
</tr>
<tr id="row1922115142588"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p1122141414588"><a name="p1122141414588"></a><a name="p1122141414588"></a>uint64_t GetSpanId()</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p32211145584"><a name="p32211145584"></a><a name="p32211145584"></a>uint64_t HiTraceGetSpanId(const HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row4221171414587"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p10221191412588"><a name="p10221191412588"></a><a name="p10221191412588"></a>void SetSpanId(uint64_t spanId)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p42211614105810"><a name="p42211614105810"></a><a name="p42211614105810"></a>void HiTraceSetSpanId(HiTraceIdStruct* pId, uint64_t spanId)</p>
</td>
</tr>
<tr id="row322171425818"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p1722111418582"><a name="p1722111418582"></a><a name="p1722111418582"></a>uint64_t GetParentSpanId()</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p8221314195817"><a name="p8221314195817"></a><a name="p8221314195817"></a>uint64_t HiTraceGetParentSpanId(const HiTraceIdStruct* pId)</p>
</td>
</tr>
<tr id="row622114147589"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p92219145589"><a name="p92219145589"></a><a name="p92219145589"></a>void SetParentSpanId(uint64_t parentSpanId)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p922191435813"><a name="p922191435813"></a><a name="p922191435813"></a>void HiTraceSetParentSpanId(HiTraceIdStruct* pId, uint64_t parentSpanId)</p>
</td>
</tr>
<tr id="row5221614135814"><td class="cellrowborder" valign="top" width="12.540000000000001%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="41.42%" headers="mcps1.2.4.1.2 "><p id="p11221121435820"><a name="p11221121435820"></a><a name="p11221121435820"></a>int ToBytes(uint8_t* pIdArray, int len)</p>
</td>
<td class="cellrowborder" valign="top" width="46.04%" headers="mcps1.2.4.1.3 "><p id="p1122131415814"><a name="p1122131415814"></a><a name="p1122131415814"></a>int HiTraceIdToBytes(const HiTraceIdStruct* pId, uint8_t* pIdArray, int len)</p>
</td>
</tr>
</tbody>
</table>
### 接口功能参数<a name="section2514638125"></a>
**表 2** C++接口说明函数参数和功能
<a name="table19597131833715"></a>
<table><thead align="left"><tr id="row7839141817375"><th class="cellrowborder" valign="top" width="9.8%" id="mcps1.2.4.1.1"><p id="p383919182379"><a name="p383919182379"></a><a name="p383919182379"></a><strong id="b0839191863717"><a name="b0839191863717"></a><a name="b0839191863717"></a></strong></p>
</th>
<th class="cellrowborder" valign="top" width="31.430000000000003%" id="mcps1.2.4.1.2"><p id="p168392018203711"><a name="p168392018203711"></a><a name="p168392018203711"></a><strong id="b4208111244510"><a name="b4208111244510"></a><a name="b4208111244510"></a>方法</strong></p>
</th>
<th class="cellrowborder" valign="top" width="58.77%" id="mcps1.2.4.1.3"><p id="p168391618193717"><a name="p168391618193717"></a><a name="p168391618193717"></a><strong id="b521141218453"><a name="b521141218453"></a><a name="b521141218453"></a>描述</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row383911183378"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 "><p id="p10839318133713"><a name="p10839318133713"></a><a name="p10839318133713"></a>HiTrace</p>
</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p198391118193717"><a name="p198391118193717"></a><a name="p198391118193717"></a>HiTraceId Begin(const std::string&amp; name, int flags)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p684013182375"><a name="p684013182375"></a><a name="p684013182375"></a>功能:启动HiTrace跟踪、生成HiTraceId对象并设置到当前线程TLS中。</p>
<p id="p1384081812377"><a name="p1384081812377"></a><a name="p1384081812377"></a>输入参数:</p>
<a name="ul1537854218177"></a><a name="ul1537854218177"></a><ul id="ul1537854218177"><li>name:业务流程名称。</li><li>flags:跟踪指示位,可以组合使用,具体含义为:<a name="ul18842248101915"></a><a name="ul18842248101915"></a><ul id="ul18842248101915"><li>HITRACE_FLAG_INCLUDE_ASYNC:同时跟踪同步调用和异步调用,缺省只跟踪同步调用。</li><li>HITRACE_FLAG_DONOT_CREATE_SPAN:不创建子分支,缺省创建子分支。</li><li>HITRACE_FLAG_TP_INFO:输出tracepoint信息,缺省不输出。</li><li>HITRACE_FLAG_NO_BE_INFO:不输出起始、结束信息,缺省输出。</li><li>HITRACE_FLAG_DONOT_ENABLE_LOG:不与日志关联输出,缺省关联。</li><li>HITRACE_FLAG_FAULT_TRIGGER:故障触发的跟踪,缺省为正常启动的。</li><li>HITRACE_FLAG_D2D_TP_INFO:输出设备间tracepoint信息,缺省不输出。</li><li>HITRCE_FLAG_DEFAULT: 缺省标志。</li></ul>
</li><li>输出参数:无</li><li>返回值:启动跟踪超过返回有效HiTraceId对象,否则返回无效对象。</li></ul>
<p id="p188401918203713"><a name="p188401918203713"></a><a name="p188401918203713"></a>注意:嵌套启动跟踪时,内层启动调用返回无效对象。</p>
</td>
</tr>
<tr id="row16840101803720"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p13840191893718"><a name="p13840191893718"></a><a name="p13840191893718"></a>void End(const HiTraceId&amp; id)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p3840181820372"><a name="p3840181820372"></a><a name="p3840181820372"></a>功能:根据Begin返回的HiTraceId停止HiTrace跟踪;清除当前线程TLS中HiTraceId内容。</p>
<p id="p9840718103720"><a name="p9840718103720"></a><a name="p9840718103720"></a>输入参数:</p>
<a name="ul2917140133015"></a><a name="ul2917140133015"></a><ul id="ul2917140133015"><li>id:HiTraceId对象。</li></ul>
<p id="p14840151803718"><a name="p14840151803718"></a><a name="p14840151803718"></a>输出参数:无。</p>
<p id="p2840201893719"><a name="p2840201893719"></a><a name="p2840201893719"></a>返回值:无。</p>
</td>
</tr>
<tr id="row198401818193712"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p20840191893718"><a name="p20840191893718"></a><a name="p20840191893718"></a>HiTraceId GetId();</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p98401818123720"><a name="p98401818123720"></a><a name="p98401818123720"></a>功能:从当前线程TLS中获取HiTraceId对象。</p>
<p id="p984001893712"><a name="p984001893712"></a><a name="p984001893712"></a>输入参数:无。</p>
<p id="p2084021817379"><a name="p2084021817379"></a><a name="p2084021817379"></a>输出参数:无。</p>
<p id="p9840418133716"><a name="p9840418133716"></a><a name="p9840418133716"></a>返回值:当前线程上下文的HiTraceId对象。</p>
</td>
</tr>
<tr id="row118401118203714"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p1840151843715"><a name="p1840151843715"></a><a name="p1840151843715"></a>void SetId(const HiTraceId&amp; id)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p384061893715"><a name="p384061893715"></a><a name="p384061893715"></a>功能:设置HiTraceId对象内容到当前线程TLS中。</p>
<p id="p16840718153717"><a name="p16840718153717"></a><a name="p16840718153717"></a>输入参数:</p>
<a name="ul1355016467304"></a><a name="ul1355016467304"></a><ul id="ul1355016467304"><li>id:HiTraceId对象。</li></ul>
<p id="p684051817376"><a name="p684051817376"></a><a name="p684051817376"></a>输出参数:无。</p>
<p id="p884091812374"><a name="p884091812374"></a><a name="p884091812374"></a>返回值:无。</p>
</td>
</tr>
<tr id="row3840171813374"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p18840131873717"><a name="p18840131873717"></a><a name="p18840131873717"></a>void ClearId()</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p584019184379"><a name="p584019184379"></a><a name="p584019184379"></a>功能:清除当前线程TLS中的HiTraceId对象。</p>
<p id="p108401718173714"><a name="p108401718173714"></a><a name="p108401718173714"></a>输入参数:无。</p>
<p id="p1784014183377"><a name="p1784014183377"></a><a name="p1784014183377"></a>输出参数:无。</p>
<p id="p2084041811377"><a name="p2084041811377"></a><a name="p2084041811377"></a>返回值:无。</p>
</td>
</tr>
<tr id="row6840818193716"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p16840171823719"><a name="p16840171823719"></a><a name="p16840171823719"></a>HiTraceId CreateSpan()</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p984031812378"><a name="p984031812378"></a><a name="p984031812378"></a>接口功能:获取当前HiTraceId对象中的分支ID。</p>
<p id="p5840101814371"><a name="p5840101814371"></a><a name="p5840101814371"></a>输入参数:无。</p>
<p id="p20840111843718"><a name="p20840111843718"></a><a name="p20840111843718"></a>输出参数:无。</p>
<p id="p88401218193710"><a name="p88401218193710"></a><a name="p88401218193710"></a>返回值:当前分支ID。</p>
</td>
</tr>
<tr id="row198401118123714"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p178411618183711"><a name="p178411618183711"></a><a name="p178411618183711"></a>void Tracepoint(HiTraceTracepointType type, const HiTraceId&amp; id, const char* fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p88419184373"><a name="p88419184373"></a><a name="p88419184373"></a>功能:根据埋点信息类型输出HiTrace埋点信息,包括时间戳、子分支HiTraceId对象信息。</p>
<p id="p1984116184376"><a name="p1984116184376"></a><a name="p1984116184376"></a>输入参数:</p>
<a name="ul18619103153812"></a><a name="ul18619103153812"></a><ul id="ul18619103153812"><li>type:埋点信息类型,具体为<a name="ul1941510328297"></a><a name="ul1941510328297"></a><ul id="ul1941510328297"><li>HITRACE_TP_CS:Client Send,同步/异步通信客户端发送信息。</li><li>HITRACE_TP_SR:Server Receive, 同步/异步通信服务端接收信息。</li><li>HITRACE_TP_SS:Server Send,同步通信服务端发送响应信息。</li><li>HITRACE_TP_CR:Client Receive,同步通信客户端接收响应信息。</li><li>HITRACE_TP_GENERAL:普通输出信息。</li></ul>
</li><li>id:当前子分支id。</li><li>fmt:格式化变参描述字符串。</li><li>args:变参。</li></ul>
<p id="p11841121863717"><a name="p11841121863717"></a><a name="p11841121863717"></a>输出参数:无。</p>
<p id="p16841161816376"><a name="p16841161816376"></a><a name="p16841161816376"></a>返回值:无。</p>
</td>
</tr>
<tr id="row11841191811379"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p08411318163716"><a name="p08411318163716"></a><a name="p08411318163716"></a>void Tracepoint(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceId&amp; id, const char* fmt, ...)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p68411618153713"><a name="p68411618153713"></a><a name="p68411618153713"></a>功能:根据通信模式、埋点信息类型输出HiTrace埋点信息,包括时间戳、子分支HiTraceId对象信息。</p>
<p id="p98418189375"><a name="p98418189375"></a><a name="p98418189375"></a>输入参数:</p>
<a name="ul914264413811"></a><a name="ul914264413811"></a><ul id="ul914264413811"><li>mode:通信模式,具体为<a name="ul137382469451"></a><a name="ul137382469451"></a><ul id="ul137382469451"><li>HITRACE_CM_DEFAULT:未指定通信模式。</li><li>HITRACE_CM_THREAD:线程间通信。</li><li>HITRACE_CM_PROCESS:进程间通信。</li><li>HITRACE_CM_DEVICE:设备间通信。</li></ul>
</li><li>type:埋点信息类型,具体为<a name="ul19648426458"></a><a name="ul19648426458"></a><ul id="ul19648426458"><li>HITRACE_TP_CS:Client Send,同步/异步通信客户端发送信息。</li><li>HITRACE_TP_SR:Server Receive, 同步/异步通信服务端接收信息。</li><li>HITRACE_TP_SS:Server Send,同步通信服务端发送响应信息。</li><li>HITRACE_TP_CR:Client Receive,同步通信客户端接收响应信息。</li><li>HITRACE_TP_GENERAL:普通输出信息。</li></ul>
</li><li>id:当前子分支id。</li><li>fmt:格式化变参描述字符串。</li><li>args:变参。</li></ul>
<p id="p784111810377"><a name="p784111810377"></a><a name="p784111810377"></a>输出参数:无。</p>
<p id="p1984181810374"><a name="p1984181810374"></a><a name="p1984181810374"></a>返回值:无。</p>
</td>
</tr>
<tr id="row15841191813371"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 "><p id="p28411718143712"><a name="p28411718143712"></a><a name="p28411718143712"></a>HiTraceId</p>
</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p158414182379"><a name="p158414182379"></a><a name="p158414182379"></a>HiTraceId();</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p48419181372"><a name="p48419181372"></a><a name="p48419181372"></a>功能:缺省构造函数,生成无效HiTraceId对象。</p>
<p id="p16841121815372"><a name="p16841121815372"></a><a name="p16841121815372"></a>输入参数:无。</p>
<p id="p17841161803713"><a name="p17841161803713"></a><a name="p17841161803713"></a>输出参数:无。</p>
<p id="p1884121818375"><a name="p1884121818375"></a><a name="p1884121818375"></a>返回值:无。</p>
</td>
</tr>
<tr id="row138418186374"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p19841111813712"><a name="p19841111813712"></a><a name="p19841111813712"></a>HiTraceId(const uint8_t* pIdArray, int len)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p684110183377"><a name="p684110183377"></a><a name="p684110183377"></a>功能:构造函数,根据字节数组创建跟踪HiTraceId对象。</p>
<div class="p" id="p9841151833711"><a name="p9841151833711"></a><a name="p9841151833711"></a>输入参数:<a name="ul783818256482"></a><a name="ul783818256482"></a><ul id="ul783818256482"><li>pIdArray:字节数组指针。</li><li>len:字节数组长度。</li></ul>
</div>
<p id="p484121893716"><a name="p484121893716"></a><a name="p484121893716"></a>输出参数:无。</p>
<p id="p984161813376"><a name="p984161813376"></a><a name="p984161813376"></a>返回值:无。</p>
</td>
</tr>
<tr id="row2084112189377"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p1184271814377"><a name="p1184271814377"></a><a name="p1184271814377"></a>bool IsValid()</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p1084251893713"><a name="p1084251893713"></a><a name="p1084251893713"></a>功能:HiTraceId对象是否有效。</p>
<p id="p1084231815374"><a name="p1084231815374"></a><a name="p1084231815374"></a>输入参数:无。</p>
<p id="p15842121815376"><a name="p15842121815376"></a><a name="p15842121815376"></a>输出参数:无。</p>
<p id="p884261893710"><a name="p884261893710"></a><a name="p884261893710"></a>返回值:true 有效;false 无效。</p>
</td>
</tr>
<tr id="row7842161873716"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p88422188379"><a name="p88422188379"></a><a name="p88422188379"></a>bool IsFlagEnabled(HiTraceFlag flag)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p128421518153712"><a name="p128421518153712"></a><a name="p128421518153712"></a>功能:HiTraceId对象的某标志是否置位。</p>
<p id="p12842518113714"><a name="p12842518113714"></a><a name="p12842518113714"></a>输入参数:</p>
<a name="ul9760031103115"></a><a name="ul9760031103115"></a><ul id="ul9760031103115"><li>flag:跟踪指示位,具体含义见Begin函数中的定义。</li></ul>
<p id="p784217189379"><a name="p784217189379"></a><a name="p784217189379"></a>输出参数:无。</p>
<p id="p98421318143720"><a name="p98421318143720"></a><a name="p98421318143720"></a>返回值:true 该标志置位;false 该标志未置位。</p>
</td>
</tr>
<tr id="row4842318123713"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p8842818103712"><a name="p8842818103712"></a><a name="p8842818103712"></a>void EnableFlag(HiTraceFlag flag)短短</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p1084221893717"><a name="p1084221893717"></a><a name="p1084221893717"></a>功能:设置某跟踪标志位到HiTraceId对象中。</p>
<p id="p484241853710"><a name="p484241853710"></a><a name="p484241853710"></a>输入参数:</p>
<a name="ul144862816319"></a><a name="ul144862816319"></a><ul id="ul144862816319"><li>flag:跟踪指示位,具体含义见Begin函数中的定义。</li></ul>
<p id="p18421018153710"><a name="p18421018153710"></a><a name="p18421018153710"></a>输出参数:无。</p>
<p id="p138421618163715"><a name="p138421618163715"></a><a name="p138421618163715"></a>返回值:无。</p>
</td>
</tr>
<tr id="row128421918153717"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p4842218193714"><a name="p4842218193714"></a><a name="p4842218193714"></a>int GetFlags()</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p12842151803718"><a name="p12842151803718"></a><a name="p12842151803718"></a>功能:获取HiTraceId对象中设置的标志位。</p>
<p id="p108421018193716"><a name="p108421018193716"></a><a name="p108421018193716"></a>输入参数:无。</p>
<p id="p284271843715"><a name="p284271843715"></a><a name="p284271843715"></a>输出参数:无。</p>
<p id="p19842101853716"><a name="p19842101853716"></a><a name="p19842101853716"></a>返回值:跟踪指示位组合,具体含义见Begin函数中的定义。</p>
</td>
</tr>
<tr id="row18842181863712"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p13842718153717"><a name="p13842718153717"></a><a name="p13842718153717"></a>void SetFlags(int flags)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p7842141823718"><a name="p7842141823718"></a><a name="p7842141823718"></a>功能:设置跟踪标志位到HiTraceId对象中。</p>
<p id="p784214187374"><a name="p784214187374"></a><a name="p784214187374"></a>输入参数:</p>
<a name="ul6490121183115"></a><a name="ul6490121183115"></a><ul id="ul6490121183115"><li>flags:跟踪指示位组合,具体含义见Begin函数中的定义。</li></ul>
<p id="p17842141833710"><a name="p17842141833710"></a><a name="p17842141833710"></a>输出参数:无。</p>
<p id="p1842718203716"><a name="p1842718203716"></a><a name="p1842718203716"></a>返回值:无。</p>
</td>
</tr>
<tr id="row68421418163715"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p484221810371"><a name="p484221810371"></a><a name="p484221810371"></a>uint64_t GetChainId()</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p1784231833713"><a name="p1784231833713"></a><a name="p1784231833713"></a>功能:获取跟踪链ID。</p>
<p id="p48428188373"><a name="p48428188373"></a><a name="p48428188373"></a>输入参数:无。</p>
<p id="p158421418163710"><a name="p158421418163710"></a><a name="p158421418163710"></a>输出参数:无。</p>
<p id="p1484217183376"><a name="p1484217183376"></a><a name="p1484217183376"></a>返回值:跟踪链ID。</p>
</td>
</tr>
<tr id="row2842818153719"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p158422182376"><a name="p158422182376"></a><a name="p158422182376"></a>void SetChainId(uint64_t chainId)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p784271815372"><a name="p784271815372"></a><a name="p784271815372"></a>功能:设置跟踪链ID到HiTraceId对象中。</p>
<p id="p3842131883718"><a name="p3842131883718"></a><a name="p3842131883718"></a>输入参数:</p>
<a name="ul45791717103118"></a><a name="ul45791717103118"></a><ul id="ul45791717103118"><li>chainId:跟踪链ID。</li></ul>
<p id="p9842171818371"><a name="p9842171818371"></a><a name="p9842171818371"></a>输出参数:无。</p>
<p id="p2842141853718"><a name="p2842141853718"></a><a name="p2842141853718"></a>返回值:无。</p>
</td>
</tr>
<tr id="row1484217185372"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p12843161817378"><a name="p12843161817378"></a><a name="p12843161817378"></a>uint64_t GetSpanId()</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p1484351820374"><a name="p1484351820374"></a><a name="p1484351820374"></a>接口功能:获取当前HiTraceId对象中的分支ID。</p>
<p id="p584391823715"><a name="p584391823715"></a><a name="p584391823715"></a>输入参数:无。</p>
<p id="p198431418153714"><a name="p198431418153714"></a><a name="p198431418153714"></a>输出参数:无。</p>
<p id="p19843161833719"><a name="p19843161833719"></a><a name="p19843161833719"></a>返回值:当前分支ID。</p>
</td>
</tr>
<tr id="row48438182378"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p184361810373"><a name="p184361810373"></a><a name="p184361810373"></a>void SetSpanId(uint64_t spanId)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p14843171816375"><a name="p14843171816375"></a><a name="p14843171816375"></a>功能:设置分支ID到HiTraceId对象中。</p>
<p id="p1684381811375"><a name="p1684381811375"></a><a name="p1684381811375"></a>输入参数:</p>
<a name="ul1799516134316"></a><a name="ul1799516134316"></a><ul id="ul1799516134316"><li>spanId:分支ID。</li></ul>
<p id="p6843181820372"><a name="p6843181820372"></a><a name="p6843181820372"></a>输出参数:无。</p>
<p id="p8843518113714"><a name="p8843518113714"></a><a name="p8843518113714"></a>返回值:无。</p>
</td>
</tr>
<tr id="row178435181375"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p10843141816371"><a name="p10843141816371"></a><a name="p10843141816371"></a>uint64_t GetParentSpanId()</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p884381819373"><a name="p884381819373"></a><a name="p884381819373"></a>功能:获取当前HiTraceId对象中的父分支ID。</p>
<p id="p1684321812371"><a name="p1684321812371"></a><a name="p1684321812371"></a>输入参数:无。</p>
<p id="p8843131803711"><a name="p8843131803711"></a><a name="p8843131803711"></a>输出参数:无。</p>
<p id="p1584371833710"><a name="p1584371833710"></a><a name="p1584371833710"></a>返回值:父分支ID。</p>
</td>
</tr>
<tr id="row18843161893718"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p6843151819377"><a name="p6843151819377"></a><a name="p6843151819377"></a>void SetParentSpanId(uint64_t parentSpanId)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p1884361803719"><a name="p1884361803719"></a><a name="p1884361803719"></a>功能:设置父分支ID到HiTraceId对象中。</p>
<p id="p0843318113715"><a name="p0843318113715"></a><a name="p0843318113715"></a>输入参数:</p>
<a name="ul1393128173120"></a><a name="ul1393128173120"></a><ul id="ul1393128173120"><li>parentSpanId:父分支ID。</li></ul>
<p id="p138431518153712"><a name="p138431518153712"></a><a name="p138431518153712"></a>输出参数:无。</p>
<p id="p108431418163710"><a name="p108431418163710"></a><a name="p108431418163710"></a>返回值:无。</p>
</td>
</tr>
<tr id="row128435182379"><td class="cellrowborder" valign="top" width="9.8%" headers="mcps1.2.4.1.1 ">&nbsp;&nbsp;</td>
<td class="cellrowborder" valign="top" width="31.430000000000003%" headers="mcps1.2.4.1.2 "><p id="p5843181816371"><a name="p5843181816371"></a><a name="p5843181816371"></a>int ToBytes(uint8_t* pIdArray, int len)</p>
</td>
<td class="cellrowborder" valign="top" width="58.77%" headers="mcps1.2.4.1.3 "><p id="p8843171818378"><a name="p8843171818378"></a><a name="p8843171818378"></a>功能:将HiTraceId对象转换为字节数组,便于缓存或者通信传递。</p>
<p id="p1884391819376"><a name="p1884391819376"></a><a name="p1884391819376"></a>输入参数:</p>
<a name="ul169461002314"></a><a name="ul169461002314"></a><ul id="ul169461002314"><li>pIdArray:字节数组指针,数组长度至少为HITRACE_ID_LEN。</li><li>len: 字节数组长度</li></ul>
<p id="p8843101819379"><a name="p8843101819379"></a><a name="p8843101819379"></a>输出参数:</p>
<a name="ul116274319312"></a><a name="ul116274319312"></a><ul id="ul116274319312"><li>pIdArray:字节数组指针,对象有效时存储转换后的对象数据。</li></ul>
<p id="p8843618143720"><a name="p8843618143720"></a><a name="p8843618143720"></a>返回值:0 转换失败; &gt;0 有效对象转换数组长度。</p>
</td>
</tr>
</tbody>
</table>
## 通信调用处理<a name="section11257133933"></a>
业务使用时跨设备/跨进程/跨线程的调用是通过通信机制实现的,HiTrace需要通信机制传递traceid。
OpenHarmony系统内置部分通信机制(如ZIDL)已经支持传递traceid。
下面描述了同步通信调用传递traceid的处理过程,异步通信调用处理类似。
对于不支持的扩展通信机制可以参照该方式实现。
**图 5** 同步通信处理<a name="fig36822045171020"></a>
![](figure/同步通信处理.png "同步通信处理")
处理流程:
1. client侧业务模块调用begin\(\)接口启动调用链跟踪。
2. client侧业务模块发起同步调用transact,到client侧通信组件。
3. client侧通信组件:
1. 从当前线程TLS中获取traceid。
2. 生成子调用分支(child traceid)。
3. 将child traceid写入同步调用通信数据(transaction data)中。
4. 进行CS埋点(Client Send)。
5. 将通信数据发送到server侧通信组件。
4. server侧通信组件收到通信数据:
1. 从数据消息包中取出traceid。
2. 将traceid设置到当前线程TLS中。
3. 进行SR埋点(Server Receive)。
4. 然后进行同步调用回调(onTransact)到server侧业务模块。
5. server侧业务模块进行服务处理,处理完毕发送处理结果(transact reply)到通信组件。
6. server侧通信组件:
1. 进行SS埋点(Server Send)。
2. 将响应数据发送到client侧通信组件。
3. 清除当前线程TLS中的traceid信息。
7. client侧通信组件收到响应数据:
1. 进行CR埋点(Client Receive)。
2. 发送同步调用响应(transact reply)到client侧业务模块。
8. client侧业务模块进行同步调用响应处理。
9. client侧业务模块在流程结束时调用end\(\)接口停止调用链跟踪。
## 开发实例<a name="section14310412491"></a>
### C++接口实例<a name="section114916381509"></a>
1. 源代码开发
在类定义头文件或者类实现源文件中,包含hitrace头文件:
```
#include "hitrace/trace.h"
```
在业务类实现源文件中使用(启动/结束跟踪):
```
using namespace OHOS::HiviewDFX;
HiTraceId traceId = HiTrace::Begin("MyServiceFlow", HITRACE_FLAG_DEFAULT);
......
HiTrace::End(traceId);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx:libhitrace" ]
```
### C接口实例<a name="section108292107514"></a>
1. 源代码开发
在源文件中,包含hitrace头文件:
```
#include "hitrace/trace.h"
```
在业务类实现源文件中使用(启动/结束跟踪):
```
HiTraceIdStruct traceId = HiTraceBegin("MyServiceFlow", HITRACE_FLAG_DEFAULT);
......
HiTraceEnd(traceId);
```
2. 编译设置,在BUILD.gn里增加子系统SDK依赖:
```
external_deps = [ "hiviewdfx:libhitrace" ]
```
# DFX概述<a name="ZH-CN_TOPIC_0000001075771948"></a> # DFX概述<a name="ZH-CN_TOPIC_0000001185974398"></a>
- [基本概念](#section5635178134811) - [基本概念](#section5635178134811)
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
- HiLog流水日志,轻量系统类设备(参考内存≥128KB)、小型系统类设备(参考内存≥1MB)、标准系统类设备(参考内存≥128MB)适用。 - HiLog流水日志,轻量系统类设备(参考内存≥128KB)、小型系统类设备(参考内存≥1MB)、标准系统类设备(参考内存≥128MB)适用。
- HiSysEvent系统事件埋点,标准系统类设备(参考内存≥128MB)。 - HiTrace分布式跟踪,标准系统类设备(参考内存≥128MB)适用。
- HiCollie卡死故障检测,标准系统类设备(参考内存≥128MB)适用。
- HiSysEvent系统事件埋点,标准系统类设备(参考内存≥128MB)适用。
## 基本概念<a name="section5635178134811"></a> ## 基本概念<a name="section5635178134811"></a>
......
# hiperf 使用指南
- [list 命令](#list-命令)
- [参数说明](#参数说明)
- [使用示例](#使用示例)
- [stat 命令](#stat-命令)
- [参数说明](#参数说明)
- [使用示例](#使用示例)
- [字段说明](#字段说明)
- [record 命令](#record-命令)
- [参数说明](#参数说明)
- [使用示例](#使用示例)
- [report 命令](#report-命令)
- [使用示例](#使用示例)
hiperf是为开发人员提供性能采样分析的工具,基于内核perf机制进行的用户态能力的扩展,可以对指定的程序或者整个系统进行性能采样。
hiperf支持的命令有:list、stat、record、report等,可以通过hiperf -h进行查看。
下面对hiperf的常用命令进行详细说明:
## list 命令
### 参数说明
列出设备上支持的所有perf事件名称,事件名称用于 stat 和 record命令的 -e 和 -g 参数。
```
Usage: hiperf list [event type]
```
| 参数 | 功能说明 |
| -------- | -------- |
| hw | 列出支持的&nbsp;hardware&nbsp;事件(PMU支持) |
| sw | 列出支持的&nbsp;software&nbsp;事件 |
| tp | 列出支持&nbsp;tracepotint&nbsp;事件 |
| cache | 列出支持的&nbsp;cache&nbsp;事件(PMU支持) |
| raw | 列出支持的原始PMU事件 |
### 使用示例
下面列出了设备支持的 HW 事件,并且会提示哪些事件此设备不支持。
```
hiperf list hw
event not support hw-stalled-cycles-backend
event not support hw-stalled-cycles-frontend
event not support hw-ref-cpu-cycles
Supported events for hardware:
hw-cpu-cycles
hw-instructions
hw-cache-references
hw-cache-misses
hw-branch-instructions
hw-branch-misses
hw-bus-cycles
```
## stat 命令
### 参数说明
监听指定目标程序,周期性打印性能计数器的值。
```
Usage: hiperf stat [options]
Collect performance counter information.
```
| 参数 | 功能说明 |
| -------- | -------- |
| -a | 采集监听整个系统的所有线程和默认的性能计数器的值。 |
| -c | 指定cpu&nbsp;id,可以是0,1,2用逗号分隔。 |
| -d&nbsp;&lt;_sec_&gt; | 指定监听的时间,单位为秒。 |
| -i&nbsp;&lt;_ms_&gt; | 指定监听事件的间隔打印时间,单位毫秒。 |
| -e | 指定监听的事件,可以通过list命令查看支持的所有事件,其中event:u&nbsp;或者&nbsp;:k&nbsp;表示限制事件为用户空间或者内核空间。 |
| -g | 指定需要在同一组监听的事件,同一组事件会被放入同一个PMU监听。 |
| --no-inherit | 不监听目标线程/进程启动的子线程。 |
| -p | 指定需要监听的进程pid。 |
| -t | 指定需要监听的线程tid。 |
| --verbose | 显示详细的报告内容,包括一些原始的时间数据等等。 |
### 使用示例
下面是通过 stat 监听整个系统3秒的示例:
```
hiperf stat -d 3 -a
this is root mode, perfEventParanoid assume as -1
Start Profiling...
Timeout exit (total 3009 ms)
count name | comment | coverage
132523 hw-branch-instructions | 15.750 M/sec | (100%)
62554 hw-branch-misses | 47.202372% miss rate | (100%)
6994768 hw-cpu-cycles | 0.832068 GHz | (100%)
1237627 hw-instructions | 5.651758 cycles per instruction | (100%)
248 sw-context-switches | 29.959 K/sec | (100%)
0 sw-page-faults | 0.000 /sec | (100%)
9402580 sw-task-clock | 0.002758 cpus used | (100%)
```
### 字段说明
| 字段名 | 含义 |
| -------- | -------- |
| count | 表示事件发生的次数 |
| name | 事件的名称,在&nbsp;list&nbsp;命令中可以看到所有支持的命令,hw&nbsp;&nbsp;sw&nbsp;的前缀分别代表是hardware事件还是software事件。 |
| comment | 一些经过计算的方便用户阅读的值。例如&nbsp;CPU&nbsp;的相对主频,千位进制换算等等。 |
| coverage | 该事件在PMU中的&nbsp;enable&nbsp;百分比,受限于PMU数量,每次装载的PMU监听事件是有限的。 |
## record 命令
### 参数说明
采样指定目标程序,并且将采样数据保存到指定的文件中(默认为perf.data)
```
Usage: hiperf record [options]
Collect performance sampling information.
```
| 参数 | 功能说明 |
| -------- | -------- |
| -a | 对整个系统的所有进程和线程进行采样。 |
| --exclude-hiperf | 不采样hiperf自身进程。 |
| -c | 指定采样的cpu&nbsp;id。 |
| --cpu-limit&nbsp;&lt;_percent_&gt; | 限定采样过程占用的CPU最大百分比。 |
| -d&nbsp;&lt;sec&gt; | 指定采样时长,单位秒。 |
| -f&nbsp;&lt;freq&gt; | 设置采样事件的触发频率,默认为4000。<br/>说明:该频率越高cpu负载会越高,但是数据采样会越多。 |
| --period&nbsp;&lt;_num_&gt; | 设置采样事件触发周期,以次数为单位,即发生指定的次数后采样一次。 |
| -e | 指定监听的事件,可以通过list命令查看支持的所有事件,其中event:u&nbsp;或者&nbsp;:k&nbsp;可以表示限制事件为用户空间或者内核空间。 |
| -g | 指定需要在同一组监听的事件,同一组事件会被放入同一个PMU监听。 |
| --no-inherit | 不监听目标线程或者进程启动的子线程。 |
| -p | 指定需要监听的进程。 |
| -t | 指定需要监听的线程。 |
| --offcpu | 监听cpu调度事件,它等价于&nbsp;--period&nbsp;1&nbsp;-e&nbsp;sched:sched_switch&nbsp;事件。 |
| -j&nbsp;&lt;_branch_filter1_&gt;[,_branch_filter2_]... | 监听分支预测事件。分支预测就是指令存在多个if&nbsp;else判定的情况下,cpu去预测下一步即将执行哪一条指令。 |
| -s&nbsp;/&nbsp;--call-stack&nbsp;&lt;_fp&nbsp;\\|&nbsp;dwarf[,size]_&gt; | 设置用户栈的回栈方式,支持fp和dwarf两种方式。dwarf&nbsp;后面可以指定采样的用户堆栈大小,默认是&nbsp;65528。 |
| --delay-unwind | 延迟回栈,等到采样结束再进行回栈。 |
| --disable-unwind | 不进行回栈,用户的寄存器和堆栈数据会保存在perf.data中,供离线回栈使用。 |
| --disable-callstack-expend | 默认会对回栈的调用栈信息进行合并扩展,此选项会关闭该功能。 |
| --clockid&nbsp;&lt;_clock&nbsp;type_&gt; | 设置采样数据的时钟源,支持monotonic、boottime、realtime等。 |
| --symbol-dir&nbsp;&lt;_dir_&gt; | 指定符号表路径,如果指定了回栈时会优先使用该路径下的符号表。 |
| -m&nbsp;&lt;_mmap&nbsp;pages_&gt; | 指定缓存的大小,默认值为1024,以页为单位。参数需要为2的幂,范围为&nbsp;[2&nbsp;-&nbsp;1024]。<br/>说明:该值越高,事件丢失率会越低,但是内存占用会增大。 |
| --app&nbsp;&lt;_package&nbsp;name_&gt; | 指定采样的目标应用的包名,默认超时等待时间为10秒。 |
| --data-limit&nbsp;&lt;_SIZE[K\|M|G]_&gt; | 指定采样结果的最大容量,支持K/M/G(B)为单位,默认无大小限制。 |
| -o&nbsp;&lt;_output&nbsp;file&nbsp;name_&gt; | 指定采样数据结果文件名,默认为/data/local/tmp/perf.data。 |
| -z | 启动压缩模式,在保存到文件的时候,会用gzip进行压缩。 |
| --verbose | 采样的时候显示更详细的日志信息。 |
### 使用示例
- 对全系统所有进程采样3秒,并且显示详细的日志信息
```
hiperf record -d 3 -a --verbose
```
- 指定使用fp方式进行回栈
```
hiperf record -s fp -d 3 -a
```
- 指定使用dwarf方式进行回栈
```
hiperf record -s dwarf -d 3 -a
```
- 指定采样offcpu事件
```
hiperf record --offcpu -s dwarf -d 3 -a
```
- 指定延迟回栈
```
hiperf record -d 3 -s dwarf --delay-unwind -a
```
- 禁止回栈,此时会保存堆栈数据到perf.data文件
```
hiperf record -d 3 -s dwarf --disable-unwind -a
```
- 指定追踪的包名,如果指定的包名对应的进程不存在则会延时等待10秒,超时后进程退出
```
hiperf record -d 3 -s dwarf --app com.ohos.launch
```
- 指定对采样结果数据进行压缩保存
```
hiperf record -z -s dwarf -d 3 -a
```
## report 命令
此命令主要用于展示record中抓取的采样数据
```
Usage: hiperf report [option]
Report sampling information from perf.data.
```
| 参数 | 功能说明 |
| -------- | -------- |
| --symbol-dir&nbsp;&lt;_dir_&gt; | 指定符号表路径。 |
| --limit-percent&nbsp;&lt;_number_&gt; | 指定展示结果的最低百分比(低于的不显示)。 |
| -s&nbsp;/&nbsp;--call-stack | 指定该选项后结果数据中会包含详细的调用栈信息。 |
| --call-stack-limit-percent&nbsp;&lt;_number_&gt; | 调用栈的百分比最小值(低于的不显示)。 |
| --proto | 将输入的&nbsp;perf.data&nbsp;文件转换为&nbsp;proto&nbsp;格式,默认文件名为&nbsp;perf.proto。 |
| --json | 将输入的&nbsp;perf.data&nbsp;文件转换为&nbsp;json&nbsp;格式,默认文件名为&nbsp;perf.json。 |
| --branch | 按分支预测的结果地址来展示报告,而不是调用栈的IP地址。 |
| --&lt;_keys_&gt;&nbsp;&lt;_keyname1_&gt;[,_keyname2_][,...] | 按给出的关键字来过滤展示报告,keys支持:comms、pids、tids等&nbsp;例如&nbsp;--comms&nbsp;hiperf,hilog&nbsp;表示仅显示进程/线程名称为&nbsp;hiperf或者hilog的记录条目。 |
| --sort&nbsp;&lt;_key1_&gt;[,_key2_][,...] | 按照给出的关键字来排序和显示,支持:pid、tid、comm等,可以指定多个关键字。 |
| -i&nbsp;&lt;_filename_&gt; | 指定输入的采样数据(默认为perf.data)。 |
| -o&nbsp;&lt;_filename_&gt; | 指定输出的报告文件名。 |
## 使用示例
- 输出采样数据的报告,默认读取perf.data文件
```
hiperf report
```
输出结果举例:
```
Heating count comm pid tid dso func
5.68% 15073949 hiperf_example_ 1085 1091 /system/lib/ld-musl-arm.so.1 malloc
2.57% 6834119 hiperf_example_ 1085 1091 [kernel.kallsyms] vector_swi
2.27% 6013910 hiperf_example_ 1085 1087 /system/lib/ld-musl-arm.so.1 malloc
2.19% 5805738 hiperf_example_ 1085 1091 /system/lib/ld-musl-arm.so.1 vfprintf
2.09% 5543362 hiperf_example_ 1085 1091 [kernel.kallsyms] ktime_get_ts64
report done
```
- 输出采集数据的调用栈报告
```
hiperf report -s
```
- 指定符号表路径
```
hiperf report -s --symbol-dir /data/local/tmp
```
- 指定结果过滤的关键字,指定后会只显示包含该关键字的信息。比如过滤libutils.z.so则命令如下:
```
hiperf report --dsos libuitls.z.so
```
- 指定按照特定的关键字进行排序展示,比如按照dso进行排序:
```
hiperf report --sort dso
```
# USB服务子系使用实例<a name="ZH-CN_TOPIC_0000001092792986"></a>
```
#include <cstdio>
#include <iostream>
#include <map>
#include <mutex>
#include <sstream>
#include <sys/time.h>
#include "if_system_ability_manager.h"
#include "ipc_skeleton.h"
#include "iremote_object.h"
#include "iservice_registry.h"
#include "iusb_srv.h"
#include "string_ex.h"
#include "system_ability_definition.h"
#include "usb_common.h"
#include "usb_device.h"
#include "usb_errors.h"
#include "usb_request.h"
#include "usb_server_proxy.h"
#include "usb_srv_client.h"
const int32_t REQUESTYPE = ((1 << 7) | (0 << 5) | (0 & 0x1f));
const int32_t REQUESTCMD = 6;
const int32_t VALUE = (2 << 8) + 0;
const int32_t TIMEOUT = 5000;
const int32_t ITFCLASS = 10;
const int32_t PRAMATYPE = 2;
const int32_t BUFFERLENGTH = 21;
void GetType(OHOS::USB::USBEndpoint &tep, OHOS::USB::USBEndpoint &outEp, bool &outEpFlg)
{
if ((tep.GetType() == PRAMATYPE)) {
if (tep.GetDirection() == 0) {
outEp = tep;
outEpFlg = true;
}
}
}
bool SelectEndpoint(OHOS::USB::USBConfig config,
std::vector<OHOS::USB::UsbInterface> interfaces,
OHOS::USB::UsbInterface &interface,
OHOS::USB::USBEndpoint &outEp,
bool &outEpFlg)
{
for (int32_t i = 0; i < config.GetInterfaceCount(); ++i) {
OHOS::USB::UsbInterface tif = interfaces[i];
std::vector<OHOS::USB::USBEndpoint> mEndpoints = tif.GetEndpoints();
for (int32_t j = 0; j < tif.GetEndpointCount(); ++j) {
OHOS::USB::USBEndpoint tep = mEndpoints[j];
if ((tif.GetClass() == ITFCLASS) && (tif.GetSubClass() == 0) && (tif.GetProtocol() == PRAMATYPE)) {
GetType(tep, outEp, outEpFlg);
}
}
if (outEpFlg) {
interface = interfaces[i];
return true;
}
std::cout << std::endl;
}
return false;
}
int OpenDeviceTest(OHOS::USB::UsbSrvClient &Instran, OHOS::USB::UsbDevice device, OHOS::USB::USBDevicePipe &pip)
{
int ret = Instran.RequestRight(device.GetName());
std::cout << "device RequestRight ret = " << ret << std::endl;
if (0 != ret) {
std::cout << "device RequestRight failed = " << ret << std::endl;
}
ret = Instran.OpenDevice(device, pip);
return ret;
}
int CtrTransferTest(OHOS::USB::UsbSrvClient &Instran, OHOS::USB::USBDevicePipe &pip)
{
std::cout << "usb_device_test : << Control Transfer >> " << std::endl;
std::vector<uint8_t> vData;
const OHOS::USB::UsbCtrlTransfer tctrl = {REQUESTYPE, REQUESTCMD, VALUE, 0, TIMEOUT};
int ret = Instran.ControlTransfer(pip, tctrl, vData);
if (ret != 0) {
std::cout << "control message read failed width ret = " << ret << std::endl;
} else {
}
std::cout << "control message read success" << std::endl;
return ret;
}
int ClaimTest(OHOS::USB::UsbSrvClient &Instran,
OHOS::USB::USBDevicePipe &pip,
OHOS::USB::UsbInterface &interface,
bool interfaceFlg)
{
if (interfaceFlg) {
std::cout << "ClaimInterface InterfaceInfo:" << interface.ToString() << std::endl;
int ret = Instran.ClaimInterface(pip, interface, true);
if (ret != 0) {
std::cout << "ClaimInterface failed width ret = " << ret << std::endl;
} else {
std::cout << "ClaimInterface success" << std::endl;
}
}
return 0;
}
int BulkTransferTest(OHOS::USB::UsbSrvClient &Instran,
OHOS::USB::USBDevicePipe &pip,
OHOS::USB::USBEndpoint &outEp,
bool interfaceFlg,
bool outEpFlg)
{
if (interfaceFlg) {
std::cout << "usb_device_test : << Bulk transfer start >> " << std::endl;
if (outEpFlg) {
uint8_t buffer[50] = "hello world 123456789";
std::vector<uint8_t> vData(buffer, buffer + BUFFERLENGTH);
int ret = Instran.BulkTransfer(pip, outEp, vData, TIMEOUT);
if (ret != 0) {
std::cout << "Bulk transfer write failed width ret = " << ret << std::endl;
} else {
std::cout << "Bulk transfer write success" << std::endl;
}
return ret;
}
}
return 0;
}
int main(int argc, char **argv)
{
std::cout << "usb_device_test " << std::endl;
static OHOS::USB::UsbSrvClient &Instran = OHOS::USB::UsbSrvClient::GetInstance();
// GetDevices
std::vector<OHOS::USB::UsbDevice> deviceList;
int32_t ret = Instran.GetDevices(deviceList);
if (ret != 0) {
return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
}
if (deviceList.empty()) {
return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
}
OHOS::USB::UsbDevice device = deviceList[0];
std::vector<OHOS::USB::USBConfig> configs = device.GetConfigs();
OHOS::USB::USBConfig config = configs[0];
std::vector<OHOS::USB::UsbInterface> interfaces = config.GetInterfaces();
OHOS::USB::UsbInterface interface;
OHOS::USB::USBEndpoint outEp;
bool interfaceFlg = false;
bool outEpFlg = false;
interfaceFlg = SelectEndpoint(config, interfaces, interface, outEp, outEpFlg);
// OpenDevice
std::cout << "usb_device_test : << OpenDevice >> test begin -> " << std::endl;
OHOS::USB::USBDevicePipe pip;
ret = OpenDeviceTest(Instran, device, pip);
if (ret != 0) {
return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
}
// ControlTransfer
CtrTransferTest(Instran, pip);
// ClaimInterface
ClaimTest(Instran, pip, interface, interfaceFlg);
// BulkTransferWrite
BulkTransferTest(Instran, pip, outEp, interfaceFlg, outEpFlg);
// CloseDevice
std::cout << "usb_device_test : << Close Device >> " << std::endl;
ret = Instran.Close(pip);
if (ret == 0) {
std::cout << "Close device failed width ret = " << ret << std::endl;
return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
} else {
std::cout << "Close Device success" << std::endl;
}
return 0;
}
```
# USB服务子系统使用指导<a name="ZH-CN_TOPIC_0000001077367159"></a>
- [使用步骤](#section18816105182315)
下面使用步骤以bulktransfer为例。
## 使用步骤<a name="section18816105182315"></a>
1. 获取usb service实例
```
static OHOS::USB::UsbSrvClient &g_usbClient = OHOS::USB::UsbSrvClient::GetInstance();
```
2. 获取usb设备列表
```
std::vector<OHOS::USB::UsbDevice> deviceList;
int32_t ret = g_usbClient.GetDevices(deviceList);
```
3. 申请设备权限
```
int32_t ret = g_usbClient.RequestRight(device.GetName());
```
4. 打开设备
```
USBDevicePipe pip;
int32_t et = g_usbClient.OpenDevice(device, pip);
```
5. 配置设备接口
```
ret = g_usbClient.ClaimInterface(pip, interface, true);
interface为deviceList中device的interface。
```
6. 数据传输
```
srvClient.BulkTransfer(pipe, endpoint, vdata, timeout);
```
pipe为打开设备后的数据传输通道,endpoint为device中数据传输的端点,vdata是需要传输或读取的二进制数据块,timeout为传输超时时长.
7. 关闭设备
```
ret = g_usbClient.Close(pip);
```
# USB服务子系统概述<a name="ZH-CN_TOPIC_0000001092893508"></a>
- [概述](#section175431838101617)
- [接口说明](#section83365421647)
- [Host部分](#section83365421658)
- [Device部分](#section83365421669)
- [Port部分](#section83365421670)
## 概述<a name="section175431838101617"></a>
USB设备分为Host设备(主机设备)和Device设备(从设备)。用户可通过Port Service来根据实际业务把运行OpenHarmony的设备切换为Host设备或者Device设备。目前在Host模式下,支持获取USB设备列表,USB设备权限管理,控制传输、批量传输的同异步数据传输等,在Device模式下,支持HDC(调试)、ACM(串口)、ECM(网口)等功能的切换。
**图1** USB服务架构图
![](figure/USB服务架构图.png)
- USB FWK/API:基于USB Service服务,使用NAPI技术,向上提供JS接口。
- USB Service:使用C++代码实现,包含Host、Device、Port三个模块。基于HDI的接口,主要实现USB设备的列表管理、Function 管理、Port管理、USB设备权限管理等功能。
- USB HAL:使用C代码实现,基于Host SDK和Device SDK,封装了对USB设备的基本操作,向上提供C++接口,同时通过HDF框架接收内核上报的信息。
## 接口说明<a name="section83365421647"></a>
- ### Host部分<a name="section83365421658"></a>
<a name="table1513255710559"></a>
<table><thead align="left"><tr id="row171321857155517"><th class="cellrowborder" valign="top" width="10.721072107210723%" id="mcps1.2.4.1.1"><p id="p6132957115511"><a name="p6132957115511"></a><a name="p6132957115511"></a>头文件</p>
</th>
<th class="cellrowborder" valign="top" width="66.36663666366637%" id="mcps1.2.4.1.2"><p id="p14132125715552"><a name="p14132125715552"></a><a name="p14132125715552"></a>接口名称</p>
</th>
<th class="cellrowborder" valign="top" width="22.912291229122914%" id="mcps1.2.4.1.3"><p id="p18132205755516"><a name="p18132205755516"></a><a name="p18132205755516"></a>功能描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row13132357165514"><td class="cellrowborder" rowspan="16" valign="top" width="10.721072107210723%" headers="mcps1.2.4.1.1 "><p id="p15132185775510"><a name="p15132185775510"></a><a name="p15132185775510"></a>usb_srv_client.h</p>
<p id="p18132157175510"><a name="p18132157175510"></a><a name="p18132157175510"></a></p>
<p id="p2133757135510"><a name="p2133757135510"></a><a name="p2133757135510"></a></p>
</td>
<td class="cellrowborder" valign="top" width="66.36663666366637%" headers="mcps1.2.4.1.1 "><p id="p1213365714550"><a name="p1213365714550"></a><a name="p1213365714550"></a>int32_t OpenDevice(const UsbDevice &device, USBDevicePipe &pip);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p201331557185512"><a name="p201331557185512"></a><a name="p201331557185512"></a>打开USB设备,建立连接</p>
</td>
</tr>
<tr id="row171331657185514"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p913305715553"><a name="p913305715553"></a><a name="p913305715553"></a>int32_t HasRight(std::string deviceName);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p161332570553"><a name="p161332570553"></a><a name="p161332570553"></a>判断是否有权访问设备</p>
</td>
</tr>
<tr id="row41331557165518"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p6133145713559"><a name="p6133145713559"></a><a name="p6133145713559"></a>int32_t RequestRight(std::string deviceName);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p131331557175510"><a name="p131331557175510"></a><a name="p131331557175510"></a>请求给定软件包的临时权限以访问设备</p>
</td>
</tr>
<tr id="row77021769584"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p77031566584"><a name="p77031566584"></a><a name="p77031566584"></a>int32_t GetDevices(std::vector<UsbDevice> &deviceList);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1470315695811"><a name="p1470315695811"></a><a name="p1470315695811"></a>获取USB设备列表</p>
</td>
</tr>
<tr id="row71857914585"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1318619155811"><a name="p1318619155811"></a><a name="p1318619155811"></a>int32_t ClaimInterface(USBDevicePipe &pip, const UsbInterface &interface, bool force);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1186597589"><a name="p1186597589"></a><a name="p1186597589"></a>打开接口,并申明独占接口,必须在数据传输前执行</p>
</td>
</tr>
<tr id="row18831119115815"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p48323975814"><a name="p48323975814"></a><a name="p48323975814"></a>int32_t ReleaseInterface(USBDevicePipe &pip, const UsbInterface &interface);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p15832129135813"><a name="p15832129135813"></a><a name="p15832129135813"></a>关闭接口,释放接口的占用,在停止数据传输后执行</p>
</td>
</tr>
<tr id="row71857914585"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1318619155811"><a name="p1318619155811"></a><a name="p1318619155811"></a>int32_t BulkTransfer(USBDevicePipe &pip, const USBEndpoint &endpoint, std::vector<uint8_t> &vdata, int32_t timeout);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1186597589"><a name="p1186597589"></a><a name="p1186597589"></a>在给定端点上执行批量数据传输, 返回读取或发送的数据长度,通过端点方向确定读取或发送数据</p>
</td>
</tr>
<tr id="row18831119115815"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p48323975814"><a name="p48323975814"></a><a name="p48323975814"></a>int32_t ControlTransfer(USBDevicePipe &pip, const UsbCtrlTransfer &ctrl, std::vector<uint8_t> &vdata);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p15832129135813"><a name="p15832129135813"></a><a name="p15832129135813"></a>对此设备执行端点零的控制事务,传输方向由请求类型决定</p>
</td>
</tr>
<tr id="row71857914585"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1318619155811"><a name="p1318619155811"></a><a name="p1318619155811"></a>int32_t SetConfiguration(USBDevicePipe &pip, const USBConfig &config);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1186597589"><a name="p1186597589"></a><a name="p1186597589"></a>设置设备当前使用的配置,通过配置值进行指定</p>
</td>
</tr>
<tr id="row18831119115815"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p48323975814"><a name="p48323975814"></a><a name="p48323975814"></a>int32_t SetInterface(USBDevicePipe &pipe, const UsbInterface &interface);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p15832129135813"><a name="p15832129135813"></a><a name="p15832129135813"></a>设置指定接口的备选设置,用于在具有相同ID但不同备用设置的两个接口之间进行选择</p>
</td>
</tr>
<tr id="row71857914585"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1318619155811"><a name="p1318619155811"></a><a name="p1318619155811"></a>int32_t GetRawDescriptors(std::vector<uint8_t> &vdata);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1186597589"><a name="p1186597589"></a><a name="p1186597589"></a>获取原始的USB描述符</p>
</td>
</tr>
<tr id="row18831119115815"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p48323975814"><a name="p48323975814"></a><a name="p48323975814"></a>int32_t GetFileDescriptor();</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p15832129135813"><a name="p15832129135813"></a><a name="p15832129135813"></a>获取文件描述符</p>
</td>
</tr>
<tr id="row71857914585"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1318619155811"><a name="p1318619155811"></a><a name="p1318619155811"></a>bool Close(const USBDevicePipe &pip);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1186597589"><a name="p1186597589"></a><a name="p1186597589"></a>关闭设备,释放与设备相关的所有系统资源</p>
</td>
</tr>
<tr id="row18831119115815"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p48323975814"><a name="p48323975814"></a><a name="p48323975814"></a>int32_t PipeRequestWait(USBDevicePipe &pip, int64_t timeout, UsbRequest &req);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p15832129135813"><a name="p15832129135813"></a><a name="p15832129135813"></a>获取异步传输结果</p>
</td>
</tr>
<tr id="row71857914585"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1318619155811"><a name="p1318619155811"></a><a name="p1318619155811"></a>int32_t RequestInitialize(UsbRequest &request);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1186597589"><a name="p1186597589"></a><a name="p1186597589"></a>初始化异步数据传输request</p>
</td>
</tr>
<tr id="row18831119115815"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p48323975814"><a name="p48323975814"></a><a name="p48323975814"></a>int32_t RequestFree(UsbRequest &request);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p15832129135813"><a name="p15832129135813"></a><a name="p15832129135813"></a>释放异步数据传输request</p>
</td>
</tr>
<tr id="row1513316577554"><td class="cellrowborder" rowspan="27" valign="top" headers="mcps1.2.4.1.1 ">
<td class="cellrowborder" valign="top" width="66.36663666366637%" headers="mcps1.2.4.1.2 "><p id="p105259109581"><a name="p105259109581"></a><a name="p105259109581"></a>int32_t RequestAbort(UsbRequest &request);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.3 "><p id="p752531095814"><a name="p752531095814"></a><a name="p752531095814"></a>取消待处理的数据请求</p>
</td>
</tr>
<tr id="row172902161193"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16290141681918"><a name="p16290141681918"></a><a name="p16290141681918"></a>int32_t RequestQueue(UsbRequest &request);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1929141611198"><a name="p1929141611198"></a><a name="p1929141611198"></a>将指定的端点进行异步数据发送或者接收请求,数据传输方向由端点方向决定</p>
</td>
</tr>
<tr id="row172902161193"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16290141681918"><a name="p16290141681918"></a><a name="p16290141681918"></a>int32_t BulkRequstDataSize(const UsbDev &dev, const UsbPipe &pipe, uint32_t &length);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1929141611198"><a name="p1929141611198"></a><a name="p1929141611198"></a>异步批量读取数据,传输大量数据时使用</p>
</td>
</tr>
<tr id="row172902161193"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16290141681918"><a name="p16290141681918"></a><a name="p16290141681918"></a>int32_t BulkReadData(const UsbDev &dev, const UsbPipe &pipe, std::vector<uint8_t> &data);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1929141611198"><a name="p1929141611198"></a><a name="p1929141611198"></a>与BulkReadData配合使用,获取读取结果</p>
</td>
</tr>
<tr id="row172902161193"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16290141681918"><a name="p16290141681918"></a><a name="p16290141681918"></a>int32_t BulkWriteData(const UsbDev &dev, const UsbPipe &pipe, const std::vector<uint8_t> &data);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1929141611198"><a name="p1929141611198"></a><a name="p1929141611198"></a>异步批量写数据,传输大量数据时使用</p>
</td>
</tr>
<tr id="row172902161193"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16290141681918"><a name="p16290141681918"></a><a name="p16290141681918"></a>int32_t BulkGetWriteCompleteLength(const UsbDev &dev, const UsbPipe &pipe, uint32_t &length);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1929141611198"><a name="p1929141611198"></a><a name="p1929141611198"></a>与BulkWriteData配合使用,获取写入状态,由length描述</p>
</td>
</tr>
</tbody>
</table>
- ### Device部分<a name="section83365421669"></a>
<a name="table1513255710559"></a>
<table><thead align="left"><tr id="row171321857155517"><th class="cellrowborder" valign="top" width="10.721072107210723%" id="mcps1.2.4.1.1"><p id="p6132957115511"><a name="p6132957115511"></a><a name="p6132957115511"></a>头文件</p>
</th>
<th class="cellrowborder" valign="top" width="66.36663666366637%" id="mcps1.2.4.1.2"><p id="p14132125715552"><a name="p14132125715552"></a><a name="p14132125715552"></a>接口名称</p>
</th>
<th class="cellrowborder" valign="top" width="22.912291229122914%" id="mcps1.2.4.1.3"><p id="p18132205755516"><a name="p18132205755516"></a><a name="p18132205755516"></a>功能描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row13132357165514"><td class="cellrowborder" rowspan="16" valign="top" width="10.721072107210723%" headers="mcps1.2.4.1.1 "><p id="p15132185775510"><a name="p15132185775510"></a><a name="p15132185775510"></a>usb_srv_client.h</p>
<p id="p18132157175510"><a name="p18132157175510"></a><a name="p18132157175510"></a></p>
<p id="p2133757135510"><a name="p2133757135510"></a><a name="p2133757135510"></a></p>
</td>
<td class="cellrowborder" valign="top" width="66.36663666366637%" headers="mcps1.2.4.1.1 "><p id="p1213365714550"><a name="p1213365714550"></a><a name="p1213365714550"></a>int32_t GetCurrentFunctions(int32_t &funcs);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p201331557185512"><a name="p201331557185512"></a><a name="p201331557185512"></a>获取设备模式下的当前USB功能列表的数字组合掩码</p>
</td>
</tr>
<tr id="row171331657185514"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p913305715553"><a name="p913305715553"></a><a name="p913305715553"></a>int32_t SetCurrentFunctions(int32_t funcs);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p161332570553"><a name="p161332570553"></a><a name="p161332570553"></a>在设备模式下设置当前的USB功能列表</p>
</td>
</tr>
<tr id="row41331557165518"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p6133145713559"><a name="p6133145713559"></a><a name="p6133145713559"></a>int32_t UsbFunctionsFromString(std::string funcs);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p131331557175510"><a name="p131331557175510"></a><a name="p131331557175510"></a>将给定的功能列表描述字符串转换为功能列表的数字组合掩码</p>
</td>
</tr>
<tr id="row77021769584"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p77031566584"><a name="p77031566584"></a><a name="p77031566584"></a>std::string UsbFunctionsToString(int32_t funcs);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1470315695811"><a name="p1470315695811"></a><a name="p1470315695811"></a>将给定的功能列表的数字组合掩码转换为功能列表描述字符串</p>
</td>
</tr>
</tbody>
</table>
- ### Port部分<a name="section83365421670"></a>
<a name="table1513255710559"></a>
<table><thead align="left"><tr id="row171321857155517"><th class="cellrowborder" valign="top" width="10.721072107210723%" id="mcps1.2.4.1.1"><p id="p6132957115511"><a name="p6132957115511"></a><a name="p6132957115511"></a>头文件</p>
</th>
<th class="cellrowborder" valign="top" width="66.36663666366637%" id="mcps1.2.4.1.2"><p id="p14132125715552"><a name="p14132125715552"></a><a name="p14132125715552"></a>接口名称</p>
</th>
<th class="cellrowborder" valign="top" width="22.912291229122914%" id="mcps1.2.4.1.3"><p id="p18132205755516"><a name="p18132205755516"></a><a name="p18132205755516"></a>功能描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row13132357165514"><td class="cellrowborder" rowspan="16" valign="top" width="10.721072107210723%" headers="mcps1.2.4.1.1 "><p id="p15132185775510"><a name="p15132185775510"></a><a name="p15132185775510"></a>usb_srv_client.h</p>
<p id="p18132157175510"><a name="p18132157175510"></a><a name="p18132157175510"></a></p>
<p id="p2133757135510"><a name="p2133757135510"></a><a name="p2133757135510"></a></p>
</td>
<td class="cellrowborder" valign="top" width="66.36663666366637%" headers="mcps1.2.4.1.1 "><p id="p1213365714550"><a name="p1213365714550"></a><a name="p1213365714550"></a>int32_t GetSupportedModes(int32_t portId, int32_t &supportedModes);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p201331557185512"><a name="p201331557185512"></a><a name="p201331557185512"></a>获取指定的端口支持的模式列表的组合掩码</p>
</td>
</tr>
<tr id="row171331657185514"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p913305715553"><a name="p913305715553"></a><a name="p913305715553"></a>int32_t SetPortRole(int32_t portId, int32_t powerRole, int32_t dataRole);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p161332570553"><a name="p161332570553"></a><a name="p161332570553"></a>设置指定的端口支持的角色模式,包含充电角色、数据传输角色</p>
</td>
</tr>
<tr id="row41331557165518"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p6133145713559"><a name="p6133145713559"></a><a name="p6133145713559"></a>int32_t GetPorts(std::vector<UsbPort> &usbPorts);</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p131331557175510"><a name="p131331557175510"></a><a name="p131331557175510"></a>获取物理USB端口描述信息列表</p>
</td>
</tr>
</tbody>
</table>
# USB<a name="ZH-CN_TOPIC_0000001052857351"></a>
- **[USB服务子系统概述](subsys-usbservice-overview.md)**
- **[USB服务子系统使用指导](subsys-usbservice-guide.md)**
- **[USB服务子系统使用实例](subsys-usbservice-demo.md)**
\ No newline at end of file
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
- **[分布式远程启动](subsys-remote-start.md)** - **[分布式远程启动](subsys-remote-start.md)**
- **[图形图像](subsys-graphics.md)** - **[图形图像](subsys-graphics.md)**
- **[媒体](subsys-multimedia.md)** - **[媒体](subsys-multimedia.md)**
- **[数据管理](subsys-data.md)**
- **[公共基础](subsys-utils.md)** - **[公共基础](subsys-utils.md)**
- **[AI框架](subsys-aiframework.md)** - **[AI框架](subsys-aiframework.md)**
- **[Sensor服务](subsys-sensor.md)** - **[Sensor服务](subsys-sensor.md)**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册