diff --git a/en/device-dev/driver/Readme-EN.md b/en/device-dev/driver/Readme-EN.md index 18678440ad06c989d251367330af5c65e8d93a59..74bbfd98ee953e2de921c20acd52e4f144975c16 100644 --- a/en/device-dev/driver/Readme-EN.md +++ b/en/device-dev/driver/Readme-EN.md @@ -8,66 +8,19 @@ - [Driver Configuration Management](driver-configuration-management.md) - [HDF Development Example](hdfdevelopment-example.md) -- [Driver Platform](driver-platform.md) +- [Platform Drivers](platform-drivers.md) - [GPIO](gpio.md) - - [GPIO Overview](gpiooverview.md) - - [GPIO Usage Guidelines](gpiousage-guidelines.md) - - [GPIO Usage Example](gpiousage-example.md) - - [I2C](i2c.md) - - [I2C Overview](i2c-overview.md) - - [I2C Usage Guidelines](i2c-usage-guidelines.md) - - [I2C Usage Example](i2c-usage-example.md) - - [RTC](rtc.md) - - [RTC Overview](rtc-overview.md) - - [RTC Usage Guidelines](rtc-usage-guidelines.md) - - [RTC Usage Example](rtc-usage-example.md) - - [SDIO](sdio.md) - - [SDIO Overview](sdiooverview.md) - - [SDIO Usage Guidelines](sdiousage-guidelines.md) - - [SDIO Usage Example](sdiousage-example.md) - - [SPI](spi.md) - - [SPI Overview](spioverview.md) - - [SPI Usage Guidelines](spiusage-guidelines.md) - - [SPI Usage Example](spiusage-example.md) - - [UART](uart.md) - - [UART Overview](uartoverview.md) - - [UART Usage Guidelines](uartusage-guidelines.md) - - [UART Usage Example](uartusage-example.md) - - - [WATCHDOG](watchdog.md) - - [Watchdog Overview](watchdogoverview.md) - - [Watchdog Usage Guidelines](watchdogusage-guidelines.md) - - [Watchdog Usage Example](watchdogusage-example.md) - + - [Watchdog](watchdog.md) - [MIPI DSI](mipi-dsi.md) - - [MIPI DSI Overview](mipi-dsi-overview.md) - - [Usage Guidelines](usage-guidelines.md) - - [Usage Example](usage-example.md) - [Peripherals](peripherals.md) - [LCD](lcd.md) - - [LCD Overview](lcdoverview.md) - - [LCD Development Guidelines](lcddevelopment-guidelines.md) - - [LCD Development Example](lcddevelopment-example.md) - - [TOUCHSCREEN](touchscreen.md) - - [Touchscreen Overview](touchscreenoverview.md) - - [Touchscreen Development Guidelines](touchscreendevelopment-guidelines.md) - - [Touchscreen Development Example](touchscreendevelopment-example.md) - - - [SENSOR](sensor.md) - - [Sensor Driver Overview](sensor-driver-overview.md) - - [Sensor Driver Development Guidelines](sensor-driver-development-guidelines.md) - - [Sensor Driver Development Example](sensor-driver-development-example.md) - - [Sensor Driver Test Guidelines](sensor-driver-test-guidelines.md) - + - [Sensor](sensor.md) - [WLAN](wlan.md) - - [WLAN Overview](wlanoverview.md) - - [WLAN Development Guidelines](wlandevelopment-guidelines.md) - - [WLAN Development Example](wlandevelopment-example.md) diff --git a/en/device-dev/driver/driver-development.md b/en/device-dev/driver/driver-development.md index f9c14ec11f06e6f5c5448751c6967e3de0dac1fa..20f2b610b30401be941e55fd4e4c90669112f07b 100644 --- a/en/device-dev/driver/driver-development.md +++ b/en/device-dev/driver/driver-development.md @@ -5,9 +5,9 @@ ## Introduction -The HDF is designed based on the component-based driver model. It provides more refined driver management to make driver development and deployment more standard. Device drivers of the same type are placed in the same host. You can develop and deploy the drivers separately. One driver can have multiple nodes. The following figure shows the HDF driver management model. +The HDF is designed based on the component-based driver model. It provides more refined driver management to make driver development and deployment more standard. Device drivers of the same type are placed in the same host. You can develop and deploy the drivers separately. One driver can have multiple nodes. [Figure 1](#fig5487113011526) shows the HDF driver model. -**Figure 1** HDF driver management model +**Figure 1** HDF driver model ![](figures/en-us_image_0000001054564784.png) @@ -24,9 +24,9 @@ Driver development based on the HDF consists of two parts: driver implementation ``` #include "hdf_device_desc.h" // Header file that describes the APIs provided by the HDF to the driver. - #include "hdf_log.h" // Header file of the log interface provided by the HDF. + #include "hdf_log.h" // Header file that describes the log APIs provided by the HDF. - #define HDF_LOG_TAG "sample_driver" // Tag contained in logs. If the tag is not specified, HDF_TAG is used by default. + #define HDF_LOG_TAG "sample_driver" // Tag contained in logs. If no tag is not specified, the default HDF_TAG is used. // The driver service interface must be bound to the HDF for you to use the service capability. int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) @@ -123,7 +123,7 @@ Driver development based on the HDF consists of two parts: driver implementation device0 :: deviceNode { // DeviceNode of the sample driver policy = 1; // Driver service release policy. For details, see section Driver Service Management. priority = 100; // Driver startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the device loading sequence is random. - preload = 0; // On-demand driver loading. For details, see "NOTE" at the end of this section. + preload = 0; // On-demand loading of the driver. For details, see "NOTE" at the end of this section. permission = 0664; // Permission for the driver to create device nodes. moduleName = "sample_driver"; // Driver name. The value of this field must be the same as the value of moduleName in the driver entry structure. serviceName = "sample_service"; // Name of the service released by the driver. The name must be unique. diff --git a/en/device-dev/driver/figures/en-us_image_0000001057902344.png b/en/device-dev/driver/figures/en-us_image_0000001123509750.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001057902344.png rename to en/device-dev/driver/figures/en-us_image_0000001123509750.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001072553354.png b/en/device-dev/driver/figures/en-us_image_0000001123514210.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001072553354.png rename to en/device-dev/driver/figures/en-us_image_0000001123514210.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054440624.png b/en/device-dev/driver/figures/en-us_image_0000001123540984.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054440624.png rename to en/device-dev/driver/figures/en-us_image_0000001123540984.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054007499.png b/en/device-dev/driver/figures/en-us_image_0000001123582482.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054007499.png rename to en/device-dev/driver/figures/en-us_image_0000001123582482.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054728498.png b/en/device-dev/driver/figures/en-us_image_0000001123675706.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054728498.png rename to en/device-dev/driver/figures/en-us_image_0000001123675706.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054726248.png b/en/device-dev/driver/figures/en-us_image_0000001123703482.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054726248.png rename to en/device-dev/driver/figures/en-us_image_0000001123703482.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054142582.png b/en/device-dev/driver/figures/en-us_image_0000001123742254.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054142582.png rename to en/device-dev/driver/figures/en-us_image_0000001123742254.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001057342245.png b/en/device-dev/driver/figures/en-us_image_0000001170187071.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001057342245.png rename to en/device-dev/driver/figures/en-us_image_0000001170187071.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001054006983.png b/en/device-dev/driver/figures/en-us_image_0000001170227689.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001054006983.png rename to en/device-dev/driver/figures/en-us_image_0000001170227689.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001057622716.png b/en/device-dev/driver/figures/en-us_image_0000001170229891.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001057622716.png rename to en/device-dev/driver/figures/en-us_image_0000001170229891.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001053926237.png b/en/device-dev/driver/figures/en-us_image_0000001170262141.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001053926237.png rename to en/device-dev/driver/figures/en-us_image_0000001170262141.png diff --git a/en/device-dev/driver/figures/en-us_image_0000001055299108.png b/en/device-dev/driver/figures/en-us_image_0000001170383063.png similarity index 100% rename from en/device-dev/driver/figures/en-us_image_0000001055299108.png rename to en/device-dev/driver/figures/en-us_image_0000001170383063.png diff --git a/en/device-dev/driver/gpio.md b/en/device-dev/driver/gpio.md index a35dc16408feb1ef8d9c6b7ad878a8d99d00fea6..e8f0e7c2075fed687c1f7af2117c6020d6d468a0 100644 --- a/en/device-dev/driver/gpio.md +++ b/en/device-dev/driver/gpio.md @@ -1,9 +1,560 @@ -# GPIO +# GPIO -- **[GPIO Overview](gpiooverview.md)** +- [Overview](#section1635911016188) + - [Available APIs](#section17715915181611) -- **[GPIO Usage Guidelines](gpiousage-guidelines.md)** +- [Usage Guidelines](#section259614242196) + - [How to Use](#section103477714216) + - [Determining a GPIO Pin Number](#section370083272117) + - [Using APIs to Operate GPIO Pins](#section13604050132118) -- **[GPIO Usage Example](gpiousage-example.md)** +- [Usage Example](#section25941262111) +## Overview + +Generally, a general-purpose input/output \(GPIO\) controller manages all GPIO pins by group. Each group of GPIO pins is associated with one or more registers. The GPIO pins are operated by reading data from and writing data to the registers. + +The GPIO APIs define a set of standard functions for performing operations on GPIO pins, including: + +- Setting the pin direction, which can be input or output \(High impedance is not supported currently.\) + +- Reading and writing level values, which can be low or high +- Setting an interrupt service routine \(ISR\) function and interrupt trigger mode for a pin +- Enabling or disabling a pin interrupt + +### Available APIs + +**Table 1** APIs available for the GPIO driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

GPIO read/write

+

GpioRead

+

Reads the level value of a GPIO pin.

+

GpioWrite

+

Writes the level value of a GPIO pin.

+

GPIO settings

+

GpioSetDir

+

Sets the direction for a GPIO pin.

+

GpioGetDir

+

Obtains the direction for a GPIO pin.

+

GPIO interrupt settings

+

GpioSetIrq

+

Sets the ISR function for a GPIO pin.

+

GpioUnSetIrq

+

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

+

GpioEnableIrq

+

Enables a GPIO interrupt.

+

GpioDisableIrq

+

Disables a GPIO interrupt.

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

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

dir

+

Direction to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the direction for a GPIO pin.

+

Negative value

+

Failed to set the direction for a GPIO pin.

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

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

val

+

Pointer to the level value.

+

Return Value

+

Description

+

0

+

Succeeded in reading the level value.

+

Negative value

+

Failed to read the level value.

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

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

val

+

Level value to write.

+

Return Value

+

Description

+

0

+

Succeeded in writing the level value.

+

Negative value

+

Failed to write the level value.

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

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

mode

+

Interrupt trigger mode.

+

func

+

ISR function to set.

+

arg

+

Pointer to the parameters passed to the ISR function.

+

Return Value

+

Description

+

0

+

Succeeded in setting the ISR function for a GPIO pin.

+

Negative value

+

Failed to set the ISR function for a GPIO pin.

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

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

Return Value

+

Description

+

0

+

Succeeded in canceling the ISR function.

+

Negative value

+

Failed to cancel the ISR function.

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

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

Return Value

+

Description

+

0

+

Succeeded in enabling a GPIO interrupt.

+

Negative value

+

Failed to enable a GPIO interrupt.

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

Parameter

+

Description

+

gpio

+

GPIO pin number.

+

Return Value

+

Description

+

0

+

Succeeded in disabling a GPIO interrupt.

+

Negative value

+

Failed to disable a GPIO interrupt.

+
+ + Example: + + ``` + /* ISR function */ + */ + int32_t MyCallBackFunc(uint16_t gpio, void *data) + { + HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); + return 0; + } + + int32_t ret; + /* Set the ISR function to MyCallBackFunc, the parameter to NULL, and the interrupt trigger mode to rising edge. */ + ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); + if (ret != 0) { + HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); + return; + } + + /* Enable an interrupt for GPIO3. */ + ret = GpioEnableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); + return; + } + + /* Disable the interrupt for GPIO3. */ + ret = GpioDisableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); + return; + } + + /* Cancel the ISR function for GPIO3. */ + ret = GpioUnSetIrq(3); + if (ret != 0) { + HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); + return; + } + ``` + + +## Usage Example + +In this example, we test the interrupt trigger of a GPIO pin as follows: Set the ISR function for the pin, set the trigger mode to rising edge and failing edge, write high and low levels to the pin alternately to generate level fluctuation, and observe the execution of the ISR function. + +Select an idle GPIO pin. This example uses a Hi3516D V300 development board and GPIO pin GPIO10\_3, which is numbered GPIO83. + +You can select an idle GPIO pin based on the development board and schematic diagram. + +``` +#include "gpio_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +static uint32_t g_irqCnt; + +/* ISR function */ +static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) +{ + HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); + g_irqCnt++; /* If the ISR function is triggered, the number of global interrupts is incremented by 1. */ + return GpioDisableIrq(gpio); +} + +/* Test case function */ +static int32_t TestCaseGpioIrqEdge(void) +{ + int32_t ret; + uint16_t valRead; + uint16_t mode; + uint16_t gpio = 83; /* Number of the GPIO pin to test */ + uint32_t timeout; + + /* Set the output direction for the pin. */ + ret = GpioSetDir(gpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret); + return ret; + } + + /* Disable the interrupt of the pin. */ + ret = GpioDisableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* Set the ISR function for the pin. The trigger mode is both rising edge and falling edge. */ + mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING; + HDF_LOGE("%s: mode:%0x\n", __func__, mode); + ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* Enable the interrupt for this pin. */ + ret = GpioEnableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret); + (void)GpioUnSetIrq(gpio); + return ret; + } + + g_irqCnt = 0; /* Reset the global counter. */ + timeout = 0; /* Reset the waiting time. */ + /* Wait for the ISR function of this pin to trigger. The timeout duration is 1000 ms. */ + while (g_irqCnt <= 0 && timeout < 1000) { + (void)GpioRead(gpio, &valRead); + (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); + HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout); + OsalMDelay(200); /* wait for irq trigger */ + timeout += 200; + } + (void)GpioUnSetIrq(gpio); + return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; +} +``` diff --git a/en/device-dev/driver/gpiooverview.md b/en/device-dev/driver/gpiooverview.md deleted file mode 100644 index a05df150d2b1b166350337754bb024e4d58e7e67..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/gpiooverview.md +++ /dev/null @@ -1,85 +0,0 @@ -# GPIO Overview - -- [Introduction](#section15318165672215) -- [Available APIs](#section18977142162418) - -## Introduction - -GPIO is short for general-purpose input/output. Generally, a GPIO controller manages all GPIO pins by group. Each group of GPIO pins is associated with one or more registers. The GPIO pins are operated by reading data from and writing data to the registers. - -The GPIO APIs define a set of standard functions for performing operations on GPIO pins, including: - -- Setting the pin direction, which can be input or output \(High impedance is not supported currently.\) - -- Reading and writing level values, which can be low or high -- Setting an interrupt service routine \(ISR\) function and interrupt trigger mode for a pin -- Enabling or disabling a pin interrupt - -## Available APIs - -**Table 1** APIs available for the GPIO driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

GPIO read/write

-

GpioRead

-

Reads the level value of a GPIO pin.

-

GpioWrite

-

Writes the level value of a GPIO pin.

-

GPIO settings

-

GpioSetDir

-

Sets the direction for a GPIO pin.

-

GpioGetDir

-

Obtains the direction for a GPIO pin.

-

GPIO interrupt settings

-

-

-

-

GpioSetIrq

-

Sets the ISR function for a GPIO pin.

-

GpioUnSetIrq

-

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

-

GpioEnableIrq

-

Enables a GPIO interrupt.

-

GpioDisableIrq

-

Disables a GPIO interrupt.

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

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

dir

-

Direction to set.

-

Return Value

-

Description

-

0

-

The setting is successful.

-

Negative value

-

The setting failed.

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

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

val

-

Pointer to the level value.

-

Return Value

-

Description

-

0

-

Succeeded in reading the level value.

-

Negative value

-

Failed to read the level value.

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

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

val

-

Level value to write.

-

Return Value

-

Description

-

0

-

Succeeded in writing the level value.

-

Negative value

-

Failed to write the level value.

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

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

mode

-

Interrupt trigger mode.

-

func

-

ISR function to set.

-

arg

-

Pointer to the parameters passed to the ISR function.

-

Return Value

-

Description

-

0

-

The setting is successful.

-

Negative value

-

The setting failed.

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

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

Return Value

-

Description

-

0

-

The ISR function is canceled.

-

Negative value

-

Failed to cancel the ISR function.

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

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

Return Value

-

Description

-

0

-

The GPIO interrupt is enabled.

-

Negative value

-

Failed to enable a GPIO interrupt.

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

Parameter

-

Description

-

gpio

-

GPIO pin number.

-

Return Value

-

Description

-

0

-

The GPIO interrupt is disabled.

-

Negative value

-

Failed to disable the GPIO interrupt.

-
- - Example: - - ``` - /* ISR function */ - */ - int32_t MyCallBackFunc(uint16_t gpio, void *data) - { - HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); - return 0; - } - - int32_t ret; - /* Set the ISR function to MyCallBackFunc, the parameter to NULL, and the interrupt trigger mode to rising edge. */ - ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); - if (ret != 0) { - HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); - return; - } - - /* Enable an interrupt for GPIO3. */ - ret = GpioEnableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); - return; - } - - /* Disable the interrupt for GPIO3. */ - ret = GpioDisableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); - return; - } - - /* Cancel the ISR function for GPIO3. */ - ret = GpioUnSetIrq(3); - if (ret != 0) { - HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); - return; - } - ``` - - diff --git a/en/device-dev/driver/i2c-overview.md b/en/device-dev/driver/i2c-overview.md deleted file mode 100644 index 407a149be21029b30d63559117a93b846ce70c00..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/i2c-overview.md +++ /dev/null @@ -1,60 +0,0 @@ -# I2C Overview - -- [Introduction](#section5361140416) -- [Available APIs](#section7606310210) - -## Introduction - -- The Inter-Integrated Circuit \(I2C\) is a simple, bidirectional, and synchronous serial bus that uses merely two wires. -- In an I2C communication, one controller communicates with one or more devices through the serial data line \(SDA\) and serial clock line \(SCL\), as shown in [Figure 1](#fig1135561232714). - -- I2C data transfer must begin with a **START** condition and end with a **STOP** condition. Data is transmitted byte-by-byte from the most significant bit to the least significant bit. -- Each I2C node is recognized by a unique address and can serve as either a controller or a device. When the controller needs to communicate with a device, it writes the device address to the bus through broadcast. A device matching this address sends a response to set up a data transfer channel. - -- The I2C APIs define a set of common functions for I2C data transfer, including: - - - I2C controller management: opening or closing an I2C controller - - I2C message transfer: custom transfer by using a message array - - **Figure 1** Physical connection diagram for I2C - ![](figures/physical-connection-diagram-for-i2c.png "physical-connection-diagram-for-i2c") - - -## Available APIs - -**Table 1** APIs available for the I2C driver - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

I2C controller management

-

I2cOpen

-

Opens an I2C controller.

-

I2cClose

-

Closes an I2C controller.

-

I2C message transfer

-

I2cTransfer

-

Performs a custom transfer.

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

Parameter

-

Description

-

number

-

I2C controller ID.

-

Return Value

-

Description

-

NULL

-

Failed to open the I2C controller.

-

Device handle

-

Handle of the I2C controller.

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

Parameter

-

Description

-

handle

-

Handle of an I2C controller.

-

msgs

-

Message array of the data to transfer.

-

count

-

Length of the message array.

-

Return Value

-

Description

-

Positive integer

-

Number of message structures that are successfully transmitted.

-

Negative value

-

Failed to perform the message transfer.

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

Parameter

-

Description

-

handle

-

Handle of an I2C controller.

-
- -``` -I2cClose(i2cHandle); /* Close the I2C controller. */ -``` - diff --git a/en/device-dev/driver/i2c.md b/en/device-dev/driver/i2c.md index 12167aeab9625b16e078335a504c96cf4cfe8422..98c3ddc01c9caffa5f46ba74ff859b805c6e48a8 100644 --- a/en/device-dev/driver/i2c.md +++ b/en/device-dev/driver/i2c.md @@ -1,9 +1,426 @@ -# I2C +# I2C -- **[I2C Overview](i2c-overview.md)** +- [Overview](#section5361140416) + - [Available APIs](#section459052019177) -- **[I2C Usage Guidelines](i2c-usage-guidelines.md)** +- [Usage Guidelines](#section1695201514281) + - [How to Use](#section1338373417288) + - [Opening an I2C Controller](#section13751110132914) + - [Performing I2C Communication](#section9202183372916) + - [Closing an I2C Controller](#section19481164133018) -- **[I2C Usage Example](i2c-usage-example.md)** +- [Usage Example](#section5302202015300) +## Overview + +- The Inter-Integrated Circuit \(I2C\) is a simple, bidirectional, and synchronous serial bus that uses merely two wires. +- In an I2C communication, one controller communicates with one or more devices through the serial data line \(SDA\) and serial clock line \(SCL\), as shown in [Figure 1](#fig1135561232714). + +- I2C data transfer must begin with a **START** condition and end with a **STOP** condition. Data is transmitted byte-by-byte from the most significant bit to the least significant bit. +- Each I2C node is recognized by a unique address and can serve as either a controller or a device. When the controller needs to communicate with a device, it writes the device address to the bus through broadcast. A device matching this address sends a response to set up a data transfer channel. + +- The I2C APIs define a set of common functions for I2C data transfer, including: + + - I2C controller management: opening or closing an I2C controller + - I2C message transfer: custom transfer by using a message array + + **Figure 1** Physical connection diagram for I2C + ![](figures/physical-connection-diagram-for-i2c.png "physical-connection-diagram-for-i2c") + + +### Available APIs + +**Table 1** APIs available for the I2C driver + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

I2C controller management

+

I2cOpen

+

Opens an I2C controller.

+

I2cClose

+

Closes an I2C controller.

+

I2C message transfer

+

I2cTransfer

+

Performs a custom transfer.

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

Parameter

+

Description

+

number

+

I2C controller ID.

+

Return Value

+

Description

+

NULL

+

Failed to open the I2C controller.

+

Device handle

+

Handle of the I2C controller.

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

Parameter

+

Description

+

handle

+

Handle of an I2C controller.

+

msgs

+

Message array of the data to transfer.

+

count

+

Length of the message array.

+

Return Value

+

Description

+

Positive integer

+

Number of message structures that are successfully transmitted.

+

Negative value

+

Failed to perform the message transfer.

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

Parameter

+

Description

+

handle

+

Handle of an I2C controller.

+
+ +``` +I2cClose(i2cHandle); /* Close the I2C controller. */ +``` + +## Usage Example + +This example describes how to use I2C APIs with an I2C device on a development board. + +This example shows a simple register read/write operation on TouchPad on a Hi3516D V300 development board. The basic hardware information is as follows: + +- SoC: hi3516dv300 + +- Touch IC: The I2C address is 0x38, and the bit width of Touch IC's internal register is 1 byte. + +- Schematic diagram: TouchPad is mounted to I2C controller 3. The reset pin of Touch IC is GPIO3. + +In this example, first we reset Touch IC. \(The development board supplies power to Touch IC by default after being powered on, and this use case does not consider the power supply\). Then, we perform a read/write operation on an internal register to test whether the I2C channel is normal. + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The example focuses on I2C device access and verifies the I2C channel. The read and write values of the device register are not concerned. The behavior caused by the read and write operations on the register is determined by the device itself. + +Example: + +``` +#include "i2c_if.h" /* Header file of I2C APIs */ +#include "gpio_if.h" /* Header file of GPIO APIs */ +#include "hdf_log.h" /* Header file for log APIs */ +#include "osal_io.h" /* Header file of I/O read and write APIs */ +#include "osal_time.h" /* Header file of delay and sleep APIs */ + +/* Define a TP device structure to store I2C and GPIO hardware information. */ +struct TpI2cDevice { + uint16_t rstGpio; /* Reset pin */ + uint16_t busId; /* I2C bus ID */ + uint16_t addr; /* I2C device address */ + uint16_t regLen; /* Register bit width */ + DevHandle i2cHandle; /* I2C controller handle */ +}; + +/* I2C pin I/O configuration. For details, see the SoC register manual. */ +#define I2C3_DATA_REG_ADDR 0x112f008c /* Address of the SDA pin configuration register of I2C controller 3 +#define I2C3_CLK_REG_ADDR 0x112f0090 /* Address of the SCL pin configuration register of I2C controller 3 +#define I2C_REG_CFG 0x5f1 /* Configuration values of SDA and SCL pins of I2C controller 3 + +static void TpSocIoCfg(void) +{ + /* Set the I/O function of the two pins corresponding to I2C controller 3 to I2C. */ + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR)); + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR)); +} + +/* Initialize the reset pin of the TP. Pull up the pin for 20 ms, pull down the pin for 50 ms, and then pull up the pin for 20 ms to complete the resetting. */ +static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice) +{ + int32_t ret; + + /* Set the output direction for the reset pin. */ + ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret); + return ret; + } + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst low fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(50); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst high fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + return HDF_SUCCESS; +} + +/* Use I2cTransfer to encapsulate a register read/write auxiliary function. Use flag to indicate the read or write operation. */ +static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen, uint8_t flag) +{ + int index = 0; + unsigned char regBuf[4] = {0}; + struct I2cMsg msgs[2] = {0}; + + /* Perform length adaptation for the single- or dual-byte register. */ + if (tpDevice->regLen == 1) { + regBuf[index++] = regAddr & 0xFF; + } else { + regBuf[index++] = (regAddr >> 8) & 0xFF; + regBuf[index++] = regAddr & 0xFF; + } + + /* Fill in the I2cMsg message structure. */ + msgs[0].addr = tpDevice->addr; + msgs[0].flags = 0; /* The flag is 0, indicating the write operation. */ + msgs[0].len = tpDevice->regLen; + msgs[0].buf = regBuf; + + msgs[1].addr = tpDevice->addr; + msgs[1].flags = (flag == 1)? I2C_FLAG_READ: 0; /* Add the read flag. */ + msgs[1].len = dataLen; + msgs[1].buf = regData; + + if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) { + HDF_LOGE("%s: i2c read err", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +/* TP register read function */ +static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1); +} + +/* TP register write function */ +static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0); +} + +/* Main entry of I2C */ +static int32_t TestCaseI2c(void) +{ + int32_t i; + int32_t ret; + unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC }; + unsigned char bufRead[7] = {0}; + static struct TpI2cDevice tpDevice; + + /* I/O pin function configuration */ + TpSocIoCfg(); + + /* Initialize TP device information. */ + tpDevice.rstGpio = 3; + tpDevice.busId = 3; + tpDevice.addr = 0x38; + tpDevice.regLen = 1; + tpDevice.i2cHandle = NULL; + + /* Initialize the GPIO pin. */ + ret = TestCaseGpioInit(&tpDevice); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: gpio init fail!:%d", __func__, ret); + return ret; + } + + /* Open an I2C controller. */ + tpDevice.i2cHandle = I2cOpen(tpDevice.busId); + if (tpDevice.i2cHandle == NULL) { + HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId); + return -1; + } + + /* Continuously write 7-byte data to register 0xD5 of TP-IC. */ + ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + OsalMSleep(10); + + /* Continuously read 7-byte data from register 0xDO of TP-IC. */ + ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + + HDF_LOGE("%s: tp i2c write&read reg success!", __func__); + for (i = 0; i < 7; i++) { + HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]); + } + + /* Close the I2C controller. */ + I2cClose(tpDevice.i2cHandle); + return ret; +} +``` diff --git a/en/device-dev/driver/lcd.md b/en/device-dev/driver/lcd.md index 9930511412c592f0dc36c9fe4b50ee9f206944a9..855cd171cdd46b66867d31c0f51cb53afffccdfb 100644 --- a/en/device-dev/driver/lcd.md +++ b/en/device-dev/driver/lcd.md @@ -1,9 +1,363 @@ -# LCD +# LCD -- **[LCD Overview](lcdoverview.md)** +- [Overview](#section141575391542) + - [API Description](#section14711163785519) -- **[LCD Development Guidelines](lcddevelopment-guidelines.md)** +- [Development Guidelines](#section12394223125615) + - [How to Develop](#section515923045814) -- **[LCD Development Example](lcddevelopment-example.md)** +- [Development Example](#section7441155155813) +## Overview + +The Liquid Crystal Display \(LCD\) driver powers on the LCD and initializes internal LCD registers through APIs to enable the LCD to work properly. The display driver is developed based on the hardware driver foundation \([HDF](hdfoverview.md)\). It provides power-on, power-off, and sending of the initialization sequence for LCD hardware across OSs and platforms. The display driver model is shown in [Figure 1](#fig69138814229). + +**Figure 1** Architecture of the display driver model +![](figures/architecture-of-the-display-driver-model.png "architecture-of-the-display-driver-model") + +- **Display driver model** + + The display driver model consists of the display common driver layer, SoC adapter layer, and third-party chip driver layer. The display driver model is developed based on the HDF and hides the differences between kernel forms through platform and OSAL APIs so the LCD driver can be migrated between different OSs and chip platforms. The display driver connects to the display common HAL, supports the implementation of Hardware Driver Interfaces \(HDIs\), and provides various driver interfaces for the graphics service through the display HDI. + + - Display common driver layer: connects to the display common HAL through the IOService data channel provided by the HDF to receive and process upper-layer calls in a centralized manner. + + - SoC adapter layer: decouples the display driver from the SoC driver, configures parameters related to the chip platform, and passes calls from the platform driver layer to the LCD driver layer. + + - Third-party chip driver layer: provides LCD-related APIs for sending the LCD initialization sequence, powering on or off the LCD device, and setting the backlight. + + The display driver model, capabilities, and APIs help you simplify the display driver development and improve the efficiency. + + +### API Description + +The LCD interfaces are classified into the Mobile Industry Processor Interface \(MIPI\) Display Serial Interface \(DSI\), Transistor-Transistor Logic \(TTL\) interfaces, and Low Voltage Differential Signaling \(LVDS\) interfaces. The MIPI DSI and TTL interfaces are commonly used. Here is a brief introduction to them. + +- MIPI DSI + + **Figure 2** MIPI DSI + ![](figures/mipi-dsi.png "mipi-dsi") + + The MIPI DSI is defined by MIPI Alliance. It is mainly used for mobile terminal display. The MIPI DSI is used to transmit image data, in compliance with the MIPI protocol. Generally, control information of the MIPI DSI is sent to the peer IC in the form of MIPI packets through the MIPI DSI. No additional interface is required. + +- TTL interface + + **Figure 3** TTL interface + ![](figures/ttl-interface.png "ttl-interface") + + TTL level signals are generated by TTL devices, which are a major type of digital integrated circuits. They are manufactured using the bipolar process and feature high speed, low power consumption, and multiple types. + + The TTL interface is used to transmit data in parallel mode under the control of control signals. It transmits data signals, clock signals, and control signals \(such as line synchronization signals, frame synchronization signals, and data validity signals\). Generally, the LCD of the TTL interface and the read/write of internal registers require additional peripheral interfaces, such as the Serial Peripheral Interface \(SPI\) and Inter-Integrated Circuit \(I2C\). + + +## Development Guidelines + +The display driver model is developed based on the HDF, platform APIs, and APIs at the OS abstraction layer \(OSAL\), and provides a unified driver model for the LCD regardless of the OS \(LiteOS or Linux OS\) and chip platforms \(such as Hi35xx, Hi38xx, and V3S\). + +### How to Develop + +1. Add the LCD driver-related hardware descriptions. +2. Add a driver that adapts to the chip at the SoC adapter layer. +3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for: + - Powering on/off the LCD device + + Based on the LCD hardware connection, use the GPIO interfaces provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier. + + - Sending the initialization sequence + + Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier. + + +4. Implement other HDF interfaces as required, for example, the **Release** interface. +5. Use the HDF to create other device nodes for implementing service logic or debugging as required. + +## Development Example + +Add the device description. + +``` +/* Description of the display driver */ +display :: host { + hostName = "display_host"; + /* Description of the HDF display driver */ + device_hdf_disp :: device { + device0 :: deviceNode { + policy = 2; + priority = 200; + permission = 0660; + moduleName = "HDF_DISP"; + serviceName = "hdf_disp"; + } + } + /* Description of the driver device at the SoC adapter layer */ + device_hi35xx_disp :: device { + device0 :: deviceNode { + policy = 0; + priority = 199; + moduleName = "HI351XX_DISP"; + } + } + /* Description of the LCD driver */ + device_lcd :: device { + device0 :: deviceNode { + policy = 0; + priority = 100; + preload = 0; + moduleName = "LCD_Sample"; + } + device1 :: deviceNode { + policy = 0; + priority = 100; + preload = 2; + moduleName = "LCD_SampleXX"; + } + } +} +``` + +The following example shows how to adapt to the MIPI device to the Hi35xx series chips at the SoC adapter layer: + +``` +static int32_t MipiDsiInit(struct PanelInfo *info) +{ + int32_t ret; + struct DevHandle *mipiHandle = NULL; + struct MipiCfg cfg; + + mipiHandle = MipiDsiOpen(0); + if (mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + cfg.lane = info->mipi.lane; + cfg.mode = info->mipi.mode; + cfg.format = info->mipi.format; + cfg.burstMode = info->mipi.burstMode; + cfg.timing.xPixels = info->width; + cfg.timing.hsaPixels = info->hsw; + cfg.timing.hbpPixels = info->hbp; + cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; + cfg.timing.vsaLines = info->vsw; + cfg.timing.vbpLines = info->vbp; + cfg.timing.vfpLines = info->vfp; + cfg.timing.ylines = info->height; + /* 0 : no care */ + cfg.timing.edpiCmdSize = 0; + cfg.pixelClk = CalcPixelClk(info); + cfg.phyDataRate = CalcDataRate(info); + /* config mipi device */ + ret = MipiDsiSetCfg(mipiHandle, &cfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); + } + MipiDsiClose(mipiHandle); + HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, + cfg.pixelClk, cfg.phyDataRate); + return ret; +} +``` + +The following example shows code for developing an LCD driver: + +``` +#define RESET_GPIO 5 +#define MIPI_DSI0 0 +#define BLK_PWM1 1 +#define PWM_MAX_PERIOD 100000 +/* backlight setting */ +#define MIN_LEVEL 0 +#define MAX_LEVEL 255 +#define DEFAULT_LEVEL 100 + +#define WIDTH 480 +#define HEIGHT 960 +#define HORIZONTAL_BACK_PORCH 20 +#define HORIZONTAL_FRONT_PORCH 20 +#define HORIZONTAL_SYNC_WIDTH 10 +#define VERTIACL_BACK_PORCH 14 +#define VERTIACL_FRONT_PORCH 16 +#define VERTIACL_SYNC_WIDTH 2 +#define FRAME_RATE 60 + +/* PanelInfo structure */ +struct PanelInfo { + uint32_t width; + uint32_t height; + uint32_t hbp; + uint32_t hfp; + uint32_t hsw; + uint32_t vbp; + uint32_t vfp; + uint32_t vsw; + uint32_t frameRate; + enum LcdIntfType intfType; + enum IntfSync intfSync; + struct MipiDsiDesc mipi; + struct BlkDesc blk; + struct PwmCfg pwm; +}; + +/* Initialization sequence of the LCD panel */ +static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; +static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; +static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; +static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; +static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; +static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; +static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; +static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; +static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; +static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; +static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; +static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; +static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; +static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; +static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; +static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; +static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; +static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; +static uint8_t g_payLoad18[] = { + 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, + 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, + 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 +}; +static uint8_t g_payLoad19[] = { 0x11 }; +static uint8_t g_payLoad20[] = { 0x29 }; + +struct DsiCmdDesc g_OnCmd[] = { + { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, + { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, + { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, + { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, + { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, + { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, + { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, + { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, + { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, + { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, + { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, + { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, + { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, + { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, + { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, + { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, + { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, + { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, + { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, + { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, + { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, +}; +static DevHandle g_mipiHandle = NULL; +static DevHandle g_pwmHandle = NULL; + +/* Set the status of the reset pin. */ +static int32_t LcdResetOn(void) +{ + int32_t ret; + ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioSetDir failure, ret:%d", ret); + return HDF_FAILURE; + } + ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioWrite failure, ret:%d", ret); + return HDF_FAILURE; + } + /* delay 20ms */ + OsalMSleep(20); + return HDF_SUCCESS; +} + +static int32_t SampleInit(void) +{ + /* Obtain the MIPI DSI device handle. */ + g_mipiHandle = MipiDsiOpen(MIPI_DSI0); + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t SampleOn(void) +{ + int32_t ret; + /* Power on the LCD. */ + ret = LcdResetOn(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: LcdResetOn failure", __func__); + return HDF_FAILURE; + } + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: g_mipiHandle is null", __func__); + return HDF_FAILURE; + } + /* Send the initialization sequence via MIPI. */ + int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); + int32_t i; + for (i = 0; i < count; i++) { + ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); + if (ret != HDF_SUCCESS) { + HDF_LOGE("MipiDsiTx failure"); + return HDF_FAILURE; + } + } + /* Set MIPI to the high speed (HS) mode. */ + MipiDsiSetHsMode(g_mipiHandle); + return HDF_SUCCESS; +} + +/* PanelInfo structure variables */ +static struct PanelInfo g_panelInfo = { + .width = WIDTH, /* width */ + .height = HEIGHT, /* height */ + .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ + .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ + .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ + .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ + .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ + .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ + .frameRate = FRAME_RATE, /* frame rate */ + .intfType = MIPI_DSI, /* panel interface type */ + .intfSync = OUTPUT_USER, /* output timming type */ + /* mipi config info */ + .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, + /* backlight config info */ + .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, + .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, +}; + +/* Basic APIs that need to be adapted for the chip driver */ +static struct PanelData g_panelData = { + .info = &g_panelInfo, + .init = SampleInit, + .on = SampleOn, + .off = SampleOff, + .setBacklight = SampleSetBacklight, +}; + +/* Entry function of the chip driver */ +int32_t SampleEntryInit(struct HdfDeviceObject *object) +{ + HDF_LOGI("%s: enter", __func__); + if (object == NULL) { + HDF_LOGE("%s: param is null!", __func__); + return HDF_FAILURE; + } + /* Register the chip driver APIs with the platform driver. */ + if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { + HDF_LOGE("%s: PanelDataRegister error!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +struct HdfDriverEntry g_sampleDevEntry = { + .moduleVersion = 1, + .moduleName = "LCD_SAMPLE", + .Init = SampleEntryInit, +}; + +HDF_INIT(g_sampleDevEntry); +``` diff --git a/en/device-dev/driver/lcddevelopment-example.md b/en/device-dev/driver/lcddevelopment-example.md deleted file mode 100644 index 35122ca4fa69878a8c36e658da23082b0c0084e0..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/lcddevelopment-example.md +++ /dev/null @@ -1,291 +0,0 @@ -# LCD Development Example - -Add the device description. - -``` -/* Description of the display driver */ -display :: host { - hostName = "display_host"; - /* Description of the HDF display driver */ - device_hdf_disp :: device { - device0 :: deviceNode { - policy = 2; - priority = 200; - permission = 0660; - moduleName = "HDF_DISP"; - serviceName = "hdf_disp"; - } - } - /* Description of the driver device at the SoC adapter layer */ - device_hi35xx_disp :: device { - device0 :: deviceNode { - policy = 0; - priority = 199; - moduleName = "HI351XX_DISP"; - } - } - /* Description of the LCD driver */ - device_lcd :: device { - device0 :: deviceNode { - policy = 0; - priority = 100; - preload = 0; - moduleName = "LCD_Sample"; - } - device1 :: deviceNode { - policy = 0; - priority = 100; - preload = 2; - moduleName = "LCD_SampleXX"; - } - } -} -``` - -The following example shows how to adapt to the MIPI device to the Hi35xx series chips at the SoC adapter layer: - -``` -static int32_t MipiDsiInit(struct PanelInfo *info) -{ - int32_t ret; - struct DevHandle *mipiHandle = NULL; - struct MipiCfg cfg; - - mipiHandle = MipiDsiOpen(0); - if (mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - cfg.lane = info->mipi.lane; - cfg.mode = info->mipi.mode; - cfg.format = info->mipi.format; - cfg.burstMode = info->mipi.burstMode; - cfg.timing.xPixels = info->width; - cfg.timing.hsaPixels = info->hsw; - cfg.timing.hbpPixels = info->hbp; - cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; - cfg.timing.vsaLines = info->vsw; - cfg.timing.vbpLines = info->vbp; - cfg.timing.vfpLines = info->vfp; - cfg.timing.ylines = info->height; - /* 0 : no care */ - cfg.timing.edpiCmdSize = 0; - cfg.pixelClk = CalcPixelClk(info); - cfg.phyDataRate = CalcDataRate(info); - /* config mipi device */ - ret = MipiDsiSetCfg(mipiHandle, &cfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); - } - MipiDsiClose(mipiHandle); - HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, - cfg.pixelClk, cfg.phyDataRate); - return ret; -} -``` - -The following example shows code for developing an LCD driver: - -``` -#define RESET_GPIO 5 -#define MIPI_DSI0 0 -#define BLK_PWM1 1 -#define PWM_MAX_PERIOD 100000 -/* backlight setting */ -#define MIN_LEVEL 0 -#define MAX_LEVEL 255 -#define DEFAULT_LEVEL 100 - -#define WIDTH 480 -#define HEIGHT 960 -#define HORIZONTAL_BACK_PORCH 20 -#define HORIZONTAL_FRONT_PORCH 20 -#define HORIZONTAL_SYNC_WIDTH 10 -#define VERTIACL_BACK_PORCH 14 -#define VERTIACL_FRONT_PORCH 16 -#define VERTIACL_SYNC_WIDTH 2 -#define FRAME_RATE 60 - -/* Panel information structure */ -struct PanelInfo { - uint32_t width; - uint32_t height; - uint32_t hbp; - uint32_t hfp; - uint32_t hsw; - uint32_t vbp; - uint32_t vfp; - uint32_t vsw; - uint32_t frameRate; - enum LcdIntfType intfType; - enum IntfSync intfSync; - struct MipiDsiDesc mipi; - struct BlkDesc blk; - struct PwmCfg pwm; -}; - -/* Initialization sequence of the LCD panel */ -static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; -static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; -static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; -static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; -static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; -static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; -static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; -static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; -static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; -static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; -static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; -static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; -static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; -static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; -static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; -static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; -static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; -static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; -static uint8_t g_payLoad18[] = { - 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, - 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, - 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 -}; -static uint8_t g_payLoad19[] = { 0x11 }; -static uint8_t g_payLoad20[] = { 0x29 }; - -struct DsiCmdDesc g_OnCmd[] = { - { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, - { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, - { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, - { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, - { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, - { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, - { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, - { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, - { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, - { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, - { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, - { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, - { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, - { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, - { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, - { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, - { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, - { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, - { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, - { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, - { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, -}; -static DevHandle g_mipiHandle = NULL; -static DevHandle g_pwmHandle = NULL; - -/* Set the status of the reset pin. */ -static int32_t LcdResetOn(void) -{ - int32_t ret; - ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioSetDir failure, ret:%d", ret); - return HDF_FAILURE; - } - ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioWrite failure, ret:%d", ret); - return HDF_FAILURE; - } - /* delay 20ms */ - OsalMSleep(20); - return HDF_SUCCESS; -} - -static int32_t SampleInit(void) -{ - /* Obtain the MIPI DSI device handle. */ - g_mipiHandle = MipiDsiOpen(MIPI_DSI0); - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -static int32_t SampleOn(void) -{ - int32_t ret; - /* Power on the LCD. */ - ret = LcdResetOn(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: LcdResetOn failure", __func__); - return HDF_FAILURE; - } - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: g_mipiHandle is null", __func__); - return HDF_FAILURE; - } - /* Send the initialization sequence via MIPI. */ - int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); - int32_t i; - for (i = 0; i < count; i++) { - ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); - if (ret != HDF_SUCCESS) { - HDF_LOGE("MipiDsiTx failure"); - return HDF_FAILURE; - } - } - /* Set MIPI to the high speed (HS) mode. */ - MipiDsiSetHsMode(g_mipiHandle); - return HDF_SUCCESS; -} - -/* PanelInfo structure variables */ -static struct PanelInfo g_panelInfo = { - .width = WIDTH, /* width */ - .height = HEIGHT, /* height */ - .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ - .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ - .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ - .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ - .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ - .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ - .frameRate = FRAME_RATE, /* frame rate */ - .intfType = MIPI_DSI, /* panel interface type */ - .intfSync = OUTPUT_USER, /* output timming type */ - /* mipi config info */ - .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, - /* backlight config info */ - .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, - .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, -}; - -/* Basic APIs that need to be adapted for the chip driver */ -static struct PanelData g_panelData = { - .info = &g_panelInfo, - .init = SampleInit, - .on = SampleOn, - .off = SampleOff, - .setBacklight = SampleSetBacklight, -}; - -/* Entry function of the chip driver */ -int32_t SampleEntryInit(struct HdfDeviceObject *object) -{ - HDF_LOGI("%s: enter", __func__); - if (object == NULL) { - HDF_LOGE("%s: param is null!", __func__); - return HDF_FAILURE; - } - /* Register the chip driver APIs with the platform driver. */ - if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { - HDF_LOGE("%s: PanelDataRegister error!", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -struct HdfDriverEntry g_sampleDevEntry = { - .moduleVersion = 1, - .moduleName = "LCD_SAMPLE", - .Init = SampleEntryInit, -}; - -HDF_INIT(g_sampleDevEntry); -``` - diff --git a/en/device-dev/driver/lcddevelopment-guidelines.md b/en/device-dev/driver/lcddevelopment-guidelines.md deleted file mode 100644 index a7d0f9cb7453fe32c2c9448eba76bd2cac09ec45..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/lcddevelopment-guidelines.md +++ /dev/null @@ -1,23 +0,0 @@ -# LCD Development Guidelines - -- [How to Develop](#section3904154911218) - -The display driver model is developed based on the HDF, platform APIs, and APIs at the OS abstraction layer \(OSAL\), and provides a unified driver model for the LCD regardless of the OS \(LiteOS or Linux OS\) and chip platforms \(such as Hi35xx, Hi38xx, and V3S\). - -## How to Develop - -1. Add the LCD driver-related hardware descriptions. -2. Add a driver that adapts to the chip at the SoC adapter layer. -3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for: - - Powering on/off the LCD device - - Based on the LCD hardware connection, use the GPIO interfaces provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier. - - - Sending the initialization sequence - - Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier. - - -4. Implement other HDF interfaces as required, for example, the **Release** interface. -5. Use the HDF to create other device nodes for implementing service logic or debugging as required. - diff --git a/en/device-dev/driver/lcdoverview.md b/en/device-dev/driver/lcdoverview.md deleted file mode 100644 index 08ba05e1f409a702a3b4334ce7124a4e80f5af57..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/lcdoverview.md +++ /dev/null @@ -1,46 +0,0 @@ -# LCD Overview - -- [Introduction](#section3781515122118) -- [API Description](#section20280192712120) - -## Introduction - -The Liquid Crystal Display \(LCD\) driver powers on the LCD and initializes internal LCD registers APIs to enable the LCD to work properly. The display driver is developed based on the hardware driver foundation \([HDF](hdfoverview.md)\). It provides power-on, power-off, and sending of the initialization sequence for LCD hardware across OSs and platforms. The display driver model is shown in [Figure 1](#fig69138814229). - -**Figure 1** Architecture of the display driver model -![](figures/architecture-of-the-display-driver-model.png "architecture-of-the-display-driver-model") - -- **Display driver model** - - The display driver model consists of the display common driver layer, SoC adapter layer, and third-party chip driver layer. It is developed based on the HDF and hides the differences between kernel forms through platform and OSAL APIs so the LCD driver can be migrated to different OSs and chip platforms. The display driver connects to the display common HAL, supports the implementation of Hardware Driver Interfaces \(HDIs\), and provides various driver interfaces for the graphics service through the display HDI. - - - Display common driver layer: connects to the display common HAL through the IOService data channel provided by the HDF to receive and process various upper-layer calls in a centralized manner. - - - SoC adapter layer: decouples the display driver from the SoC driver, configures parameters related to the chip platform, and passes the calls at the platform driver layer to the LCD driver layer. - - - Third-party chip driver layer: provides LCD-related APIs for sending the LCD initialization sequence, powering on or off the LCD device, and setting the backlight. - - Based on the display driver model, various capabilities, and APIs, you can greatly simplify the display driver development and improve the efficiency. - - -## API Description - -The LCD interfaces are classified into the Mobile Industry Processor Interface \(MIPI\) Display Serial Interface \(DSI\), Transistor Transistor Logic \(TTL\) interfaces, and Low Voltage Differential Signaling \(LVDS\) interfaces. The MIPI DSI and TTL interfaces are commonly used. Here is a brief introduction to them. - -- MIPI DSI - - **Figure 2** MIPI DSI - ![](figures/mipi-dsi.png "mipi-dsi") - - The MIPI DSI is defined by MIPI Alliance. It is mainly used for mobile terminal display. The MIPI DSI is used to transmit image data, in compliance with the MIPI protocol. Generally, control information of the MIPI DSI is sent to the peer IC in the form of MIPI packets through the MIPI DSI. No additional interface is required. - -- TTL interface - - **Figure 3** TTL interface - ![](figures/ttl-interface.png "ttl-interface") - - TTL level signals are generated by TTL devices, which are a major type of digital integrated circuits. They are manufactured using the bipolar process and feature high speed, low power consumption, and multiple types. - - The TTL interface is used to transmit data in parallel mode. It transmits data signals, clock signals, and control signals \(such as line synchronization signals, frame synchronization signals, and data validity signals\) under the control of control signals. Generally, the LCD of the TTL interface and the read/write of internal registers require additional peripheral interfaces, such as the Serial Peripheral Interface \(SPI\) and Inter-Integrated Circuit \(I2C\). - - diff --git a/en/device-dev/driver/mipi-dsi-overview.md b/en/device-dev/driver/mipi-dsi-overview.md deleted file mode 100644 index ec579fba093ecad64f31fd5d00b429878829a652..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/mipi-dsi-overview.md +++ /dev/null @@ -1,84 +0,0 @@ -# MIPI DSI Overview - -- [Introduction](#section1369320102013) -- [Available APIs](#section6577545192317) - -## Introduction - -- The Display Serial Interface \(DSI\) is a specification stipulated by the Mobile Industry Processor Interface \(MIPI\) Alliance, aiming to reduce the cost of display controllers in a mobile device. It defines a serial bus and communication protocol among the host, the source of image data, and the target device. In this way, the DSI can send pixel data or commands to peripherals \(usually LCDs or similar display devices\) in serial mode, or reads information such as status and pixel from the peripherals. - -- MIPI DSI is capable of working in both high speed \(HS\) mode and low power \(LP\) mode. All data lanes can only travel from the DSI host to a peripheral in HS mode, except the first data lane, which can also receive data such as status information and pixels from the peripheral in LP mode. The clock lane is dedicated to transmitting synchronization clock signals in HS mode. - - [Figure 1](#fig1122611461203) shows a simplified DSI interface. Conceptually, a DSI-compliant interface has the same features as interfaces complying with DBI-2 and DPI-2 standards. It sends pixels or commands to a peripheral and can read status or pixel information from the peripheral. The main difference is that the DSI serializes all pixel data, commands, and events that, in traditional interfaces, are conveyed to and from the peripheral on a parallel data bus with additional control signals. - - **Figure 1** DSI transmitting and receiving Interface - ![](figures/dsi-transmitting-and-receiving-interface.png "dsi-transmitting-and-receiving-interface") - - - -## Available APIs - -**Table 1** APIs for MIPI DSI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

Setting/Obtaining MIPI DSI configuration parameters

-

MipiDsiSetCfg

-

Sets configuration parameters for a MIPI DSI device.

-

MipiDsiGetCfg

-

Obtains the configuration parameters of a MIPI DSI device.

-

Obtaining /Releasing device handles

-

MipiDsiOpen

-

Obtains a MIPI DSI device handle.

-

MipiDsiClose

-

Releases a specified MIPI DSI device handle.

-

Setting the LP or HS mode

-

MipiDsiSetLpMode

-

Sets LP mode for a MIPI DSI device.

-

MipiDsiSetHsMode

-

Sets HS mode for a MIPI DSI device.

-

Reading/Sending commands

-

MipiDsiTx

-

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

-

MipiDsiRx

-

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

-
- ->![](public_sys-resources/icon-note.gif) **NOTE:** ->All functions described in this document can be called only in kernel space. - diff --git a/en/device-dev/driver/mipi-dsi.md b/en/device-dev/driver/mipi-dsi.md index f50672962f5c2602a93f63821ac290de3271ad02..698edad62a3f929529342af06aa7ccdcb33cea43 100644 --- a/en/device-dev/driver/mipi-dsi.md +++ b/en/device-dev/driver/mipi-dsi.md @@ -1,9 +1,554 @@ -# MIPI DSI +# MIPI DSI -- **[MIPI DSI Overview](mipi-dsi-overview.md)** +- [Overview](#section16806142183217) + - [Available APIs](#section129611916132011) -- **[Usage Guidelines](usage-guidelines.md)** +- [Usage Guidelines](#section037231715335) + - [How to Use](#section49299119344) + - [Obtains a MIPI DSI device handle.](#section5126155683811) + - [Setting MIPI DSI Configuration Parameters](#section201164274344) + - [Sending/Receiving the Pointer to a Command](#section199401342173415) + - [Releasing the MIPI DSI Device Handle](#section161011610357) -- **[Usage Example](usage-example.md)** +- [Usage Example](#section17470126123520) +## Overview + +- The Display Serial Interface \(DSI\) is a specification stipulated by the Mobile Industry Processor Interface \(MIPI\) Alliance, aiming to reduce the cost of display controllers in a mobile device. It defines a serial bus and communication protocol among the host, the source of image data, and the target device. In this way, the DSI can send pixel data or commands to peripherals \(usually LCDs or similar display devices\) in serial mode, or reads information such as status and pixel from the peripherals. + +- MIPI DSI is capable of working in both high speed \(HS\) mode and low power \(LP\) mode. All data lanes can only travel from the DSI host to a peripheral in HS mode, except the first data lane, which can also receive data such as status information and pixels from the peripheral in LP mode. The clock lane is dedicated to transmitting synchronization clock signals in HS mode. +- [Figure 1](#fig1122611461203) shows a simplified DSI interface. Conceptually, a DSI-compliant interface has the same features as interfaces complying with DBI-2 and DPI-2 standards. It sends pixels or commands to a peripheral and can read status or pixel information from the peripheral. The main difference is that the DSI serializes all pixel data, commands, and events that, in traditional interfaces, are conveyed to and from the peripheral on a parallel data bus with additional control signals. + + **Figure 1** DSI transmitting and receiving interface + ![](figures/dsi-transmitting-and-receiving-interface.png "dsi-transmitting-and-receiving-interface") + + +### Available APIs + +**Table 1** APIs for MIPI DSI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

Setting/Obtaining MIPI DSI configuration parameters

+

MipiDsiSetCfg

+

Sets configuration parameters for a MIPI DSI device.

+

MipiDsiGetCfg

+

Obtains configuration parameters of a MIPI DSI device.

+

Obtaining /Releasing device handles

+

MipiDsiOpen

+

Obtains a MIPI DSI device handle.

+

MipiDsiClose

+

Releases a specified MIPI DSI device handle.

+

Setting the LP or HS mode

+

MipiDsiSetLpMode

+

Sets LP mode for a MIPI DSI device.

+

MipiDsiSetHsMode

+

Sets HS mode for a MIPI DSI device.

+

Reading/Sending commands

+

MipiDsiTx

+

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

+

MipiDsiRx

+

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

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

Parameter

+

Description

+

id

+

MIPI DSI channel ID.

+

Return Value

+

Description

+

NULL

+

Failed to receive the specified command.

+

Device handle

+

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

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

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cfg

+

Pointer to MIPI DSI configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in setting MIPI DSI configuration parameters.

+

Negative value

+

Failed to set MIPI DSI configuration parameters.

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

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cfg

+

Pointer to MIPI DSI configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in receiving the specified command.

+

Negative value

+

Failed to receive the specified command.

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

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cmd

+

Pointer to the command to be sent.

+

Return Value

+

Description

+

0

+

Succeeded in sending the specified command.

+

Negative value

+

Failed to send the specified command.

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

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+

cmd

+

Pointer to the command to be received.

+

readLen

+

Length of the data to read.

+

out

+

Pointer to the read data.

+

Return Value

+

Description

+

0

+

Succeeded in receiving the specified command.

+

Negative value

+

Failed to receive the specified command.

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

Parameter

+

Description

+

handle

+

MIPI DSI device handle.

+
+ +``` +MipiDsiClose(mipiHandle); /* Release the MIPI DSI device handle */ +``` + +## Usage Example + +The following is an example of using a MIPI DSI device: + +``` +#include "hdf.h" +#include "mipi_dsi_if.h" + +void PalMipiDsiTestSample(void) +{ + uint8_t chnId; + int32_t ret; + DevHandle handle = NULL; + + /* Device channel ID */ + chnId = 0; + /* Obtain the MIPI DSI device handle based on a specified channel ID. */ + handle = MipiDsiOpen(chnId); + if (handle == NULL) { + HDF_LOGE("MipiDsiOpen: failed!\n"); + return; + } + /* MIPI DSI configuration parameters */ + struct MipiCfg cfg = {0}; + cfg.lane = DSI_4_LANES; + cfg.mode = DSI_CMD_MODE; + cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; + cfg.format = FORMAT_RGB_24_BIT; + cfg.pixelClk = 174; + cfg.phyDataRate = 384; + cfg.timingInfo.hsaPixels = 50; + cfg.timingInfo.hbpPixels = 55; + cfg.timingInfo.hlinePixels = 1200; + cfg.timingInfo.yResLines = 1800; + cfg.timingInfo.vbpLines = 33; + cfg.timingInfo.vsaLines = 76; + cfg.timingInfo.vfpLines = 120; + cfg.timingInfo.xResPixels = 1342; + /* Set MIPI DSI configuration parameters. */ + ret = MipiDsiSetCfg(g_handle, &cfg); + if (ret != 0) { + HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); + return; + } + /* Send the command for initializing the PANEL register. */ + struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmd == NULL) { + return; + } + cmd->dtype = DTYPE_DCS_WRITE; + cmd->dlen = 1; + cmd->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmd->payload == NULL) { + HdfFree(cmd); + return; + } + *(cmd->payload) = DTYPE_GEN_LWRITE; + MipiDsiSetLpMode(mipiHandle); + ret = MipiDsiTx(mipiHandle, cmd); + MipiDsiSetHsMode(mipiHandle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret); + HdfFree(cmd->payload); + HdfFree(cmd); + return; + } + HdfFree(cmd->payload); + HdfFree(cmd); + /* Pointer to the register that reads the PANEL status */ + uint8_t readVal = 0; + struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmdRead == NULL) { + return; + } + cmdRead->dtype = DTYPE_DCS_READ; + cmdRead->dlen = 1; + cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmdRead->payload == NULL) { + HdfFree(cmdRead); + return; + } + *(cmdRead->payload) = DDIC_REG_STATUS; + MipiDsiSetLpMode(g_handle); + ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); + MipiDsiSetHsMode(g_handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + return; + } + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + /* Release the MIPI DSI device handle. */ + MipiDsiClose(handle); +} +``` diff --git a/en/device-dev/driver/peripherals.md b/en/device-dev/driver/peripherals.md index 42016f572c98cb63bfd17d6994f67367f3c8bc5d..7c9a9629fc13e5a3929bc4aae2419c44cc70b402 100644 --- a/en/device-dev/driver/peripherals.md +++ b/en/device-dev/driver/peripherals.md @@ -4,7 +4,7 @@ - **[TOUCHSCREEN](touchscreen.md)** -- **[SENSOR](sensor.md)** +- **[Sensor](sensor.md)** - **[WLAN](wlan.md)** diff --git a/en/device-dev/driver/driver-platform.md b/en/device-dev/driver/platform-drivers.md similarity index 66% rename from en/device-dev/driver/driver-platform.md rename to en/device-dev/driver/platform-drivers.md index d75727d7407e71e9088a907083d02278462474e3..c7607bb8d079f569092a4a11fc54474f9f260777 100644 --- a/en/device-dev/driver/driver-platform.md +++ b/en/device-dev/driver/platform-drivers.md @@ -1,4 +1,4 @@ -# Driver Platform +# Platform Drivers - **[GPIO](gpio.md)** @@ -12,7 +12,7 @@ - **[UART](uart.md)** -- **[WATCHDOG](watchdog.md)** +- **[Watchdog](watchdog.md)** - **[MIPI DSI](mipi-dsi.md)** diff --git a/en/device-dev/driver/rtc-overview.md b/en/device-dev/driver/rtc-overview.md deleted file mode 100644 index 97aa8a24369a26fed6689751accb5ab46ce7fa89..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/rtc-overview.md +++ /dev/null @@ -1,103 +0,0 @@ -# RTC Overview - -- [Introduction](#section104842041574) -- [Available APIs](#section16892932155715) - -## Introduction - -The real-time clock \(RTC\) driver provides precise real time for the operating system \(OS\). If the OS is powered off, the RTC driver continues to keep track of the system time using an external battery. - -## Available APIs - -**Table 1** APIs provided by the RTC driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

RTC handle

-

RtcOpen

-

Opens the RTC device to obtain its handle.

-

RtcClose

-

Releases a specified handle of the RTC device.

-

RTC time

-

RtcReadTime

-

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

-

RtcWriteTime

-

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

-

RTC alarm

-

RtcReadAlarm

-

Reads the RTC alarm time that was set last time.

-

RtcWriteAlarm

-

Writes the RTC alarm time based on the alarm index.

-

RtcRegisterAlarmCallback

-

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

-

RtcAlarmInterruptEnable

-

Enables or disables RTC alarm interrupts.

-

RTC configuration

-

RtcGetFreq

-

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

-

RtcSetFreq

-

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

-

RtcReset

-

Resets the RTC.

-

Custom register

-

RtcReadReg

-

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

-

RtcWriteReg

-

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

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

Parameter

-

Description

-

void

-

N/A

-

Return Value

-

Description

-

handle

-

Returns the pointer if the operation is successful.

-

NULL

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

cb

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

time

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

time

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

time

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

time

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

alarmIndex

-

Alarm index.

-

enable

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

freq

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

freq

-

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

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

usrDefIndex

-

Index of the custom register.

-

value

-

Register value.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

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

Parameter

-

Description

-

handle

-

Pointer to the RTC device handle.

-

usrDefIndex

-

Index of the custom register.

-

value

-

Register value.

-

Return Value

-

Description

-

0

-

The operation is successful.

-

Negative value

-

The operation fails.

-
- -``` -int32_t ret; -uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ -uint8_t value = 0x10; - -/* Configure a register based on the specified register index. One index corresponds to one byte of the configuration value. */ -ret = RtcWriteReg(handle, usrDefIndex, value); -if (ret != 0) { - /* Process the error. */ -} -``` - diff --git a/en/device-dev/driver/rtc.md b/en/device-dev/driver/rtc.md index 50b89f7b7c1fb24aeac3e2922dce7da627864006..322dac86cfa1e366118f70852c8c37e589ee9695 100644 --- a/en/device-dev/driver/rtc.md +++ b/en/device-dev/driver/rtc.md @@ -1,9 +1,944 @@ -# RTC +# RTC -- **[RTC Overview](rtc-overview.md)** +- [Overview](#section104842041574) + - [Available APIs](#section3373340142215) -- **[RTC Usage Guidelines](rtc-usage-guidelines.md)** +- [Usage Guidelines](#section20636145604113) + - [How to Use](#section16919828134215) + - [Creating an RTC Device Handle](#section1131212144310) + - [Releasing the RTC Device Handle](#section10744117144314) + - [Registering RtcAlarmCallback](#section14839440184320) + - [Performing RTC-related Operations](#section161927578433) -- **[RTC Usage Example](rtc-usage-example.md)** +- [Usage Example](#section1186111020456) +## Overview + +The real-time clock \(RTC\) driver provides precise real time for the operating system \(OS\). If the OS is powered off, the RTC driver continues to keep track of the system time using an external battery. + +### Available APIs + +**Table 1** APIs provided by the RTC driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

RTC handle

+

RtcOpen

+

Opens the RTC device to obtain its handle.

+

RtcClose

+

Releases a specified handle of the RTC device.

+

RTC time

+

RtcReadTime

+

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

+

RtcWriteTime

+

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

+

RTC alarm

+

RtcReadAlarm

+

Reads the RTC alarm time that was set last time.

+

RtcWriteAlarm

+

Writes the RTC alarm time based on the alarm index.

+

RtcRegisterAlarmCallback

+

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

+

RtcAlarmInterruptEnable

+

Enables or disables RTC alarm interrupts.

+

RTC configuration

+

RtcGetFreq

+

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

+

RtcSetFreq

+

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

+

RtcReset

+

Resets the RTC.

+

Custom register

+

RtcReadReg

+

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

+

RtcWriteReg

+

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

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

Parameter

+

Description

+

void

+

NA

+

Return Value

+

Description

+

handle

+

Returns the if the operation is successful.

+

NULL

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

cb

+

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

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

time

+

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

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

time

+

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

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

time

+

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

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

time

+

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

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

alarmIndex

+

Alarm index.

+

enable

+

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

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

freq

+

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

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

freq

+

Frequency to set for the external crystal oscillator, in Hz

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

usrDefIndex

+

Index of the custom register

+

value

+

Pointer to the register value

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Parameter

+

Description

+

handle

+

RTC device handle.

+

usrDefIndex

+

Index of the custom register

+

value

+

Register value

+

Return Value

+

Description

+

0

+

The operation is successful.

+

Negative value

+

The operation fails.

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

Capability

+

Function

+

Description

+

SDIO device opening/closing

+

SdioOpen

+

Opens an SDIO controller with a specified bus number.

+

SdioClose

+

Closes an SDIO controller.

+

SDIO reading/writing

+

SdioReadBytes

+

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

+

SdioWriteBytes

+

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

+

SdioReadBytesFromFixedAddr

+

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

+

SdioWriteBytesToFixedAddr

+

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

+

SdioReadBytesFromFunc0

+

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

+

SdioWriteBytesToFunc0

+

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

+

SDIO block size setting

+

SdioSetBlockSize

+

Sets the block size.

+

SDIO common information retrieval/setting

+

SdioGetCommonInfo

+

Obtains common information.

+

SdioSetCommonInfo

+

Sets common information.

+

SDIO data flushing

+

SdioFlushData

+

Flushes data.

+

SDIO host exclusively claiming or releasing

+

SdioClaimHost

+

Claims a host exclusively.

+

SdioReleaseHost

+

Releases the exclusively claimed host.

+

SDIO device enablement

+

SdioEnableFunc

+

Enables an SDIO device.

+

SdioDisableFunc

+

Disables an SDIO device.

+

SDIO IRQ claiming/releasing

+

SdioClaimIrq

+

Claims an SDIO IRQ.

+

SdioReleaseIrq

+

Releases an SDIO IRQ.

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

Parameter

+

Description

+

mmcBusNum

+

Bus number.

+

config

+

SDIO functionality configurations.

+

Return Value

+

Description

+

NULL

+

Failed to obtain the device handle of an SDIO controller.

+

Device handle

+

Device handle of an SDIO controller.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

Return Value

+

Description

+

0

+

The SDIO device is enabled.

+

Negative value

+

Failed to enable the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

handler

+

Pointer to the SDIO IRQ function.

+

Return Value

+

Description

+

0

+

The SDIO IRQ is claimed.

+

Negative value

+

Failed to claim an SDIO IRQ.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to write.

+

addr

+

Start address where the data is written into.

+

size

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Data is written into the SDIO device.

+

Negative value

+

Failed to write data into the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to read.

+

addr

+

Start address where the data is read from.

+

size

+

Length of the data to read.

+

Return Value

+

Description

+

0

+

Data is read from the SDIO device.

+

Negative value

+

Failed to read data from the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to write.

+

addr

+

Fixed address where the data is written into.

+

size

+

Length of the data to write.

+

scatterLen

+

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

+

Return Value

+

Description

+

0

+

Data is written into the SDIO device.

+

Negative value

+

Failed to write data into the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to read.

+

addr

+

Start address where the data is read from.

+

size

+

Length of the data to read.

+

scatterLen

+

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

+

Return Value

+

Description

+

0

+

Data is read from the SDIO device.

+

Negative value

+

Failed to read data from the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to write.

+

addr

+

Start address where the data is written into.

+

size

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Data is written into the SDIO device.

+

Negative value

+

Failed to write data into the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

data

+

Pointer to the data to read.

+

addr

+

Start address where the data is read from.

+

size

+

Length of the data to read.

+

Return Value

+

Description

+

0

+

Data is read from the SDIO device.

+

Negative value

+

Failed to read data from the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

Return Value

+

Description

+

0

+

The SDIO IRQ is released.

+

Negative value

+

Failed to release the SDIO IRQ.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+

Return Value

+

Description

+

0

+

The SDIO device is disabled.

+

Negative value

+

Failed to disable the SDIO device.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

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

Parameter

+

Description

+

handle

+

Device handle of an SDIO controller.

+
+ +The following example shows how to close an SDIO controller. + +``` +SdioClose(handle); /* Close an SDIO controller. */ +``` + +## Usage Example + +The following example shows how to use an SDIO device. First, open an SDIO controller whose bus number is 1, exclusively claim a host, enable the SDIO device, claim an SDIO IRQ, and then perform SDIO communication \(such as reading and writing\). After the SDIO communication, release the SDIO IRQ, disable the SDIO device, release the host, and close the SDIO controller. + +``` +#include "hdf_log.h" +#include "sdio_if.h" + +#define TEST_FUNC_NUM 1 /* The I/O function whose ID is 1 is used. */ +#define TEST_FBR_BASE_ADDR 0x100 /* FBR base address of the I/O function whose ID is 1 */ +#define TEST_ADDR_OFFSET 9 /* Address offset of the register to read or write */ +#define TEST_DATA_LEN 3 /* Length of the data to read or write */ +#define TEST_BLOCKSIZE 2 /* Size of a data block, in bytes */ + +/* Implement the SDIO IRQ function based on the application. */ +static void SdioIrqFunc(void *data) +{ + if (data == NULL) { + HDF_LOGE("SdioIrqFunc: data is NULL.\n"); + return; + } + /* You need to add specific implementations. */ +} + +void SdioTestSample(void) +{ + int32_t ret; + DevHandle handle = NULL; + uint8_t data[TEST_DATA_LEN] = {0}; + struct SdioFunctionConfig config = {1, 0x123, 0x456}; + uint8_t val; + uint32_t addr; + + /* Open an SDIO controller whose bus number is 1. */ + handle = SdioOpen(1, &config); + if (handle == NULL) { + HDF_LOGE("SdioOpen: failed!\n"); + return; + } + /* Claim a host exclusively. */ + SdioClaimHost(handle); + /* Enable the SDIO device. */ + ret = SdioEnableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); + goto ENABLE_ERR; + } + /* Claim an SDIO IRQ. */ + ret = SdioClaimIrq(handle, SdioIrqFunc); + if (ret != 0) { + HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); + goto CLAIM_IRQ_ERR; + } + /* Set the block size to 2 bytes. */ + ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE); + if (ret != 0) { + HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 3-byte data from the incremental address of an SDIO device. */ + addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET; + ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 3-byte data into the incremental address of an SDIO device. */ + ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 1-byte data from the SDIO device. */ + ret = SdioReadBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 1-byte data into the SDIO device. */ + ret = SdioWriteBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 3-byte data from the fixed address of an SDIO device. */ + ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 1-byte data to the fixed address of an SDIO device. */ + ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Read 1-byte data from SDIO function 0. */ + addr = 0x02; + ret = SdioReadBytesFromFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* Write 1-byte data into SDIO function 0. */ + ret = SdioWriteBytesToFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } +COMM_ERR: + /* Release the SDIO IRQ. */ + ret = SdioReleaseIrq(handle); + if (ret != 0) { + HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); + } +CLAIM_IRQ_ERR: + /* Disable the SDIO device. */ + ret = SdioDisableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); + } +ENABLE_ERR: + /* Release the exclusively claimed host. */ + SdioReleaseHost(handle); + /* Close an SDIO controller. */ + SdioClose(handle); +} +``` diff --git a/en/device-dev/driver/sdiooverview.md b/en/device-dev/driver/sdiooverview.md deleted file mode 100644 index 9890cf8f3c60999f90d41db98e8143600066308b..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sdiooverview.md +++ /dev/null @@ -1,149 +0,0 @@ -# SDIO Overview - -- [Introduction](#section1155271783811) -- [Available APIs](#section10204143763819) - -## Introduction - -- Secure Digital Input/Output \(SDIO\) is a peripheral interface evolved from the Secure Digital \(SD\) memory card interface. The SDIO interface is compatible with SD memory cards and can be connected to devices that support the SDIO interface. -- SDIO is widely used. Currently, many smartphones support SDIO, and many SDIO peripherals are developed for connections to smartphones. Common SDIO peripherals include WLAN, GPS, cameras, and Bluetooth. -- The SDIO bus has two ends, named host and device. All communication starts when the host sends a command. The device can communicate with the host as long as it can parse the command of the host. An SDIO host can connect to multiple devices, as shown in the figure below. - - - CLK signal: clock signal sent from the host to the device - - VDD signal: power signal - - VSS signal: ground signal - - D0-3 signal: four data lines. The DAT1 signal cable is multiplexed as the interrupt line. In 1-bit mode, DAT0 is used to transmit data. In 4-bit mode, DAT0 to DAT3 are used to transmit data. - - CMD signal: used by the host to send commands and the device to respond to commands. - - **Figure 1** Connections between the host and devices in SDIO - - - ![](figures/en-us_image_0000001054280608.png) - -- The SDIO interface defines a set of common methods for operating an SDIO device, including opening and closing an SDIO controller, exclusively claiming and releasing the host, enabling and disabling devices, claiming and releasing an SDIO IRQ, reading and writing data based on SDIO, and obtaining and setting common information. - -## Available APIs - -**Table 1** APIs available for the SDIO driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

SDIO device opening/closing

-

SdioOpen

-

Opens an SDIO controller with a specified bus number.

-

SdioClose

-

Closes an SDIO controller.

-

SDIO reading/writing

-

SdioReadBytes

-

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

-

SdioWriteBytes

-

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

-

SdioReadBytesFromFixedAddr

-

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

-

SdioWriteBytesToFixedAddr

-

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

-

SdioReadBytesFromFunc0

-

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

-

SdioWriteBytesToFunc0

-

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

-

SDIO block size setting

-

SdioSetBlockSize

-

Sets the block size.

-

SDIO common information retrieval/setting

-

SdioGetCommonInfo

-

Obtains common information.

-

SdioSetCommonInfo

-

Sets common information.

-

SDIO data flushing

-

SdioFlushData

-

Flushes data.

-

SDIO host exclusively claiming or releasing

-

SdioClaimHost

-

Claims a host exclusively.

-

SdioReleaseHost

-

Releases the exclusively claimed host.

-

SDIO device enablement

-

SdioEnableFunc

-

Enables an SDIO device.

-

SdioDisableFunc

-

Disables an SDIO device.

-

SDIO IRQ claiming/releasing

-

SdioClaimIrq

-

Claims an SDIO IRQ.

-

SdioReleaseIrq

-

Releases an SDIO IRQ.

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

Parameter

-

Description

-

mmcBusNum

-

Bus number.

-

config

-

SDIO functionality configurations.

-

Return Value

-

Description

-

NULL

-

Failed to obtain the device handle of an SDIO controller.

-

Device handle

-

Device handle of an SDIO controller.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

Return Value

-

Description

-

0

-

The SDIO device is enabled.

-

Negative value

-

Failed to enable the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

handler

-

Pointer to the SDIO IRQ function.

-

Return Value

-

Description

-

0

-

The SDIO IRQ is claimed.

-

Negative value

-

Failed to claim an SDIO IRQ.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to write.

-

addr

-

Start address where the data is written into.

-

size

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Data is written into the SDIO device.

-

Negative value

-

Failed to write data into the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to read.

-

addr

-

Start address where the data is read from.

-

size

-

Length of the data to read.

-

Return Value

-

Description

-

0

-

Data is read from the SDIO device.

-

Negative value

-

Failed to read data from the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to write.

-

addr

-

Fixed address where the data is written into.

-

size

-

Length of the data to write.

-

scatterLen

-

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

-

Return Value

-

Description

-

0

-

Data is written into the SDIO device.

-

Negative value

-

Failed to write data into the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to read.

-

addr

-

Start address where the data is read from.

-

size

-

Length of the data to read.

-

scatterLen

-

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

-

Return Value

-

Description

-

0

-

Data is read from the SDIO device.

-

Negative value

-

Failed to read data from the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to write.

-

addr

-

Start address where the data is written into.

-

size

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Data is written into the SDIO device.

-

Negative value

-

Failed to write data into the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

data

-

Pointer to the data to read.

-

addr

-

Start address where the data is read from.

-

size

-

Length of the data to read.

-

Return Value

-

Description

-

0

-

Data is read from the SDIO device.

-

Negative value

-

Failed to read data from the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

Return Value

-

Description

-

0

-

The SDIO IRQ is released.

-

Negative value

-

Failed to release the SDIO IRQ.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

-

Return Value

-

Description

-

0

-

The SDIO device is disabled.

-

Negative value

-

Failed to disable the SDIO device.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

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

Parameter

-

Description

-

handle

-

Device handle of an SDIO controller.

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

Category

-

API

-

Description

-

Query

-

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

-

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

-

Setting

-

int32_t Enable(int32_t sensorId)

-

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

-

int32_t Disable(int32_t sensorId)

-

Disables a sensor.

-

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

-

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

-

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

-

Sets the data reporting mode for the specified sensor.

-

int32_t SetOption(int32_t sensorId, uint32_t option)

-

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

-

Data subscription and unsubscription

-

int32_t Register(RecordDataCallback cb)

-

Registers the callback for reporting sensor data to the subscriber.

-

int32_t Unregister(void)

-

Unregisters the callback for reporting sensor data.

-

Instance creation

-

const struct SensorInterface *NewSensorInterfaceInstance(void)

-

Creates a SensorInterface instance.

-

int32_t FreeSensorInterfaceInstance(void)

-

Releases the SensorInterface instance.

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

Category

-

API

-

Description

-

Device management

-

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

-

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

-

int32_t DeleteSensorDevice(int32_t sensorId)

-

Deletes a specified sensor from the sensor management module.

-

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

-

Reports data of a specified sensor type.

-

Abstract bus and platform operations

-

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

-

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

-

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

-

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

-

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

-

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

-

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

-

Destroys the scheduled thread created for the sensor.

-

Common configuration

-

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

-

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

-

Configuration parsing

-

-

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

-

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

-

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

-

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

-

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

-

Releases the resources allocated to the sensor configuration data structure.

-

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

-

Obtains the sensor bus handle information.

-

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

-

Releases the sensor bus handle information.

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

Category

-

API

-

Description

-

Basic functions

-

int32_t init(void)

-

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

-

int32_t GetInfo(struct SensorBasicInfo *info)

-

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

-

int32_t Enable(void)

-

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

-

int32_t Disable(void)

-

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

-

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

-

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

-

int32_t SetMode(int32_t mode)

-

Sets the data reporting mode of the current sensor device.

-

int32_t SetOption(uint32_t option)

-

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

-

void ReadSensorData(void)

-

Reads sensor data.

-
- -For details about the API implementation, see the [sensor driver development example](sensor-driver-development-example.md). - diff --git a/en/device-dev/driver/sensor-driver-test-guidelines.md b/en/device-dev/driver/sensor-driver-test-guidelines.md deleted file mode 100644 index 042112036cdad78e9aa732e54c8423f8c3ed115e..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/sensor-driver-test-guidelines.md +++ /dev/null @@ -1,82 +0,0 @@ -# Sensor Driver Test Guidelines - -After the driver is developed, you can develop self-test cases in the sensor unit test to verify the basic functions of the driver. The developer self-test platform is used as the test environment. - -``` -/* Specify whether to report sensor data. */ -static int32_t g_sensorDataFlag = 0; -/* Retain the address of the sensor interface instance. */ -static const struct SensorInterface *g_sensorDev = nullptr; - -/* Register the data reporting function. */ -static int SensorTestDataCallback(struct SensorEvents *event) -{ - if (event == nullptr) { - return -1; - } - float *data = (float*)event->data; - printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, - event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); - if (*data > 1e-5) { - g_sensorDataFlag = 1; - } - return 0; -} -/* Initialize the sensor interface instance before executing the test cases. */ -void HdfSensorTest::SetUpTestCase() -{ - g_sensorDev = NewSensorInterfaceInstance(); - if (g_sensorDev == nullptr) { - printf("test sensorHdi get Module instace failed\n\r"); - } -} -/* Release case resources. */ -void HdfSensorTest::TearDownTestCase() -{ - if (g_sensorDev != nullptr) { - FreeSensorInterfaceInstance(); - g_sensorDev = nullptr; - } -} -/* Verify the sensor driver. */ -HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) -{ - int32_t sensorInterval = 1000000000; /* Data sampling interval, in nanoseconds */ - int32_t pollTime = 5; /* Data sampling duration, in seconds */ - int32_t accelSensorId = 1; /* Acceleration sensor type ID, which is 1 */ - int32_t count = 0; - int ret; - struct SensorInformation *sensorInfo = nullptr; - - ret = g_sensorDev->Register(SensorTestDataCallback) - EXPECT_EQ(SENSOR_NULL_PTR, ret); - - ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); - EXPECT_EQ(0, ret); - if (sensorInfo == nullptr) { - EXPECT_NE(nullptr, sensorInfo); - return; - } - /* Print the obtained sensor list. */ - for (int i = 0; i < count; i++) { - printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); - } - ret = g_sensorDev->Enable(accelSensorId); - EXPECT_EQ(0, ret); - g_sensorDataFlag = 0; - - ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); - EXPECT_EQ(0, ret); - /* Observe the printed data within the period specified by pollTime. */ - OsalSleep(pollTime); - EXPECT_EQ(1, g_sensorDataFlag); - - ret = g_sensorDev->Disable(accelSensorId); - g_sensorDataFlag = 0; - EXPECT_EQ(0, ret); - - ret = g_sensorDev->Unregister(); - EXPECT_EQ(0, ret); -} -``` - diff --git a/en/device-dev/driver/sensor.md b/en/device-dev/driver/sensor.md index f9e8d552c0cbad2c430e9457122a25b1d62ee4df..cf8d8ab7e560f4fadde97a41444ce1d8fe177316 100644 --- a/en/device-dev/driver/sensor.md +++ b/en/device-dev/driver/sensor.md @@ -1,11 +1,929 @@ -# SENSOR +# Sensor -- **[Sensor Driver Overview](sensor-driver-overview.md)** +- [Overview](#section3634112111) + - [Available APIs](#section188213414114) -- **[Sensor Driver Development Guidelines](sensor-driver-development-guidelines.md)** +- [Development Guidelines](#section1140943382) + - [How to Develop](#section7893102915819) -- **[Sensor Driver Development Example](sensor-driver-development-example.md)** +- [Development Example](#section257750691) +- [Test Guidelines](#section106021256121219) -- **[Sensor Driver Test Guidelines](sensor-driver-test-guidelines.md)** +## Overview +The sensor driver module provides APIs for upper-layer sensor services to implement basic sensor capabilities, including querying the sensor list, enabling or disabling a sensor, subscribing to or unsubscribing from sensor data, and setting sensor options. The sensor driver model is developed based on the Hardware Driver Foundation \(HDF\) and supports functions such as cross-OS migration and differentiated device configuration. The following figure shows the architecture of the sensor driver model. + +**Figure 1** Architecture of the sensor driver model +![](figures/architecture-of-the-sensor-driver-model.png "architecture-of-the-sensor-driver-model") + +The sensor driver model offers the following APIs: + +- Hardware Driver Interfaces \(HDIs\) for sensors: These HDIs facilitate service development. +- APIs for implementing sensor driver model capabilities: These APIs implement the capabilities of registering, loading, and unregistering sensor drivers as well as detecting sensor devices depending on the HDF. The APIs include normalized APIs for sensor devices of the same type, APIs for parsing register configurations, abstract APIs for bus access, and abstract platform APIs. +- APIs to be implemented by developers: Based on the HDF Configuration Source \(HCS\), developers can implement differentiated configuration for sensors of the same type and serialized configuration of sensor device parameters. Some sensor device operations can be abstracted as APIs to simplify sensor driver development. + +### Available APIs + +The following table lists the APIs provided by the sensor driver model. + +**Table 1** External APIs provided by the sensor driver model + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Category

+

API

+

Description

+

Query

+

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

+

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

+

Setting

+

int32_t Enable(int32_t sensorId)

+

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

+

int32_t Disable(int32_t sensorId)

+

Disables a sensor.

+

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

+

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

+

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

+

Sets the data reporting mode for the specified sensor.

+

int32_t SetOption(int32_t sensorId, uint32_t option)

+

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

+

Data subscription and unsubscription

+

int32_t Register(RecordDataCallback cb)

+

Registers the callback for reporting sensor data to the subscriber.

+

int32_t Unregister(void)

+

Unregisters the callback for reporting sensor data.

+

Instance creation

+

const struct SensorInterface *NewSensorInterfaceInstance(void)

+

Creates a SensorInterface instance.

+

int32_t FreeSensorInterfaceInstance(void)

+

Releases the SensorInterface instance.

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

Category

+

API

+

Description

+

Device management

+

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

+

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

+

int32_t DeleteSensorDevice(int32_t sensorId)

+

Deletes a specified sensor from the sensor management module.

+

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

+

Reports data of a specified sensor type.

+

Abstract bus and platform operations

+

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

+

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

+

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

+

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

+

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

+

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

+

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

+

Destroys the scheduled thread created for the sensor.

+

Common configuration

+

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

+

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

+

Configuration parsing

+

+

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

+

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

+

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

+

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

+

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

+

Releases the resources allocated to the sensor configuration data structure.

+

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

+

Obtains the sensor bus handle information.

+

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

+

Releases the sensor bus handle information.

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

Category

+

API

+

Description

+

Basic functions

+

int32_t init(void)

+

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

+

int32_t GetInfo(struct SensorBasicInfo *info)

+

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

+

int32_t Enable(void)

+

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

+

int32_t Disable(void)

+

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

+

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

+

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

+

int32_t SetMode(int32_t mode)

+

Sets the data reporting mode of the current sensor device.

+

int32_t SetOption(uint32_t option)

+

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

+

void ReadSensorData(void)

+

Reads sensor data.

+
+ +For details about the API implementation, see Sensor Driver Development Example. + +## Development Guidelines + +Regardless of the OS and system on a chip \(SoC\), the sensor driver is developed based on the HDF, platform, and OSAL APIs to provide a unified driver model for sensor devices. This section uses the acceleration sensor as an example to describe how to develop a sensor driver. + +### How to Develop + +1. Register the acceleration sensor driver. The HDF provides a unified driver management model. The HDF identifies and loads the target module driver based on the configuration of the acceleration sensor module. +2. Initialize and deinitialize the acceleration sensor driver. Using the **init** function, the HDF starts loading the sensor device driver and allocating configuration resources for sensor device data, respectively. Using the **release** function, the HDF releases the resources and configurations loaded by the driver. +3. Parse the configurations of the acceleration sensor register group. For different types of sensors, you must configure their respective HCS configuration files in the HCS, check whether the sensor device is in position during the device driver startup, and then load the corresponding configuration file to generate the configuration structure object. +4. Implement APIs for acceleration sensor driver operations. The driver APIs for various types of sensors, such as **init**, **GetInfo**, **Enable**, **Disable**, **SetBatch**, **SetMode**, **SetOption**, and **ReadSensorData**, are normalized to deliver sensor driver configurations and report sensor data. + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The sensor driver model provides a collection of APIs to implement sensor driver capabilities, including the driver device management, abstract bus and platform operation, general configuration, and configuration parsing capabilities. For details about the APIs, see [Table 2](#table1156812588320). You need to implement the following APIs: some operations to perform on sensors \([Table 3](#table1083014911336)\), differentiated data configuration of the sensor HCS, and verification of basic driver functions. + +## Development Example + +This section uses a code example to demonstrate how to load and start the acceleration sensor driver based on the HDF driver model. For details about the mechanism, see [HDF Driver Development](driver-development.md). This example uses the Bosch BMI160 acceleration sensor that communicates over I2C. + +1. Register the driver entry of the acceleration sensor. + +- Implementation of the entry function + +``` +/* Register the entry structure object of the acceleration sensor. */ +struct HdfDriverEntry g_sensorAccelDevEntry = { + .moduleVersion = 1, /* Version of the acceleration sensor module */ + .moduleName = "HDF_SENSOR_ACCEL", /* Name of the acceleration sensor module. The value must be the same as that of moduleName in the device_info.hcs file. */ + .Bind = BindAccelDriver, /* Binding function of the acceleration sensor */ + .Init = InitAccelDriver, /* Initialization function of the acceleration sensor */ + .Release = ReleaseAccelDriver, /* Resource release function of the acceleration sensor */ +}; + +/* Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind function first and then the Init function. If the Init function fails to be called, the HDF will call Release to release the driver resource and exit. +HDF_INIT(g_sensorAccelDevEntry); +``` + +- Acceleration sensor configuration + +The acceleration sensor model uses the HCS as the configuration source code. For details about the HCS configuration fields, see [Driver Configuration Management](driver-configuration-management.md). + +``` +/* HCS configuration of the acceleration sensor device */ +device_sensor_accel :: device { + device0 :: deviceNode { + policy = 1; /* Policy for providing the driver service */ + priority = 105; /* Driver startup priority (0–200). A larger value indicates a lower priority. The default value 100 is recommended. The sequence for loading devices with the same priority is random. */ + preload = 2; /* Field for specifying whether to load the driver. The value 0 means to load the driver, and 2 means the opposite. */ + permission = 0664; /* Permission for the driver to create device nodes */ + moduleName = "HDF_SENSOR_ACCEL"; /* Driver name. The value must be the same as that of moduleName in the driver entry structure. */ + serviceName = "sensor_accel"; /* Name of the service provided by the driver. The name must be unique. */ + deviceMatchAttr = "hdf_sensor_accel_driver"; /* Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver. */ + } +} +``` + +1. Initialize and deinitialize the acceleration sensor driver. + +- Initialization entry function **init** + +``` +/* Bind the service provided by the acceleration sensor driver to the HDF. */ +int32_t BindAccelDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + + static struct IDeviceIoService service = { + .object = {0}, + .Dispatch = DispatchAccel, + }; + device->service = &service; + + return HDF_SUCCESS; +} +/* After detecting that the device is in position, call RegisterAccelChipOps to register the differentiation adaptation function. */ +int32_t RegisterAccelChipOps(struct AccelOpsCall *ops) +{ + struct AccelDrvData *drvData = NULL; + + CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); + + drvData = AccelGetDrvData(); + drvData->ops.Init = ops->Init; + drvData->ops.ReadData = ops->ReadData; + return HDF_SUCCESS; +} +/* Hook the acceleration sensor driver normalization function. */ +static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo) +{ + struct AccelDrvData *drvData = AccelGetDrvData(); + + (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); + deviceInfo->ops.GetInfo = SetAccelInfo; + deviceInfo->ops.Enable = SetAccelEnable; + deviceInfo->ops.Disable = SetAccelDisable; + deviceInfo->ops.SetBatch = SetAccelBatch; + deviceInfo->ops.SetMode = SetAccelMode; + deviceInfo->ops.SetOption = SetAccelOption; + + if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), + &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) { + HDF_LOGE("%s: copy sensor info failed", __func__); + return HDF_FAILURE; + } + /* The sensor type ID can be configured in the HCS configuration file or here. */ + drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER; + drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER; + + return HDF_SUCCESS; +} +/* Initialize the sensor register. */ +static int32_t InitAccelAfterConfig(void) +{ + struct SensorDeviceInfo deviceInfo; + + if (InitAccelConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel config failed", __func__); + return HDF_FAILURE; + } + + if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: init accel ops failed", __func__); + return HDF_FAILURE; + } + + if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: add accel device failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} +/* Call the device detection function to hook the differentiated device function. */ +static int32_t DetectAccelChip(void) +{ + int32_t num; + int32_t ret; + int32_t loop; + struct AccelDrvData *drvData = AccelGetDrvData(); + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]); + for (loop = 0; loop < num; ++loop) { + if (g_accelDetectIfList[loop].DetectChip != NULL) { + ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg); + if (ret == HDF_SUCCESS) { + drvData->detectFlag = true; + break; + } + } + } + + if (loop == num) { + HDF_LOGE("%s: detect accel device failed", __func__); + drvData->detectFlag = false; + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +/* The entry function of the acceleration sensor driver is used to initialize the structure object of the sensor private data, allocate space for the HCS data configuration object of the sensor, invoke the entry function for initializing the sensor HCS data configuration, detect whether the sensor device is in position, create the sensor data reporting timer, implement the sensor normalization API, and register the sensor device. */ +int32_t InitAccelDriver(struct HdfDeviceObject *device) +{ + /* Obtain the private data structure object of the sensor. */ + struct AccelDrvData *drvData = AccelGetDrvData(); + + /* When detecting sensors of the same type from different vendors, the function checks whether this type of sensors is in position. If yes, it no longer detects the other sensors of this type and directly returns the result. */ + if (drvData->detectFlag) { + HDF_LOGE("%s: accel sensor have detected", __func__); + return HDF_SUCCESS; + } + + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + /* Allocate space for the private data structure objects for storing sensor data configurations. The allocated space needs to be released when the driver is released. */ + drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg)); + if (drvData->accelCfg == NULL) { + HDF_LOGE("%s: malloc sensor config data failed", __func__); + return HDF_FAILURE; + } + + drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; + /* Initializing the sensor configuration data aims to parse the configuration information of the sensor communication bus, basic sensor information, sensor attributes, whether the sensor is in position, and register group information. */ + if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: get sensor base config failed", __func__); + goto Base_CONFIG_EXIT; + } + + if (DetectAccelChip() != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor detect device no exist", __func__); + goto DETECT_CHIP_EXIT; + } + drvData->detectFlag = true; + if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: detect sensor device failed", __func__); + goto REG_CONFIG_EXIT; + } + + if (InitAccelAfterConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel after config failed", __func__); + goto INIT_EXIT; + } + + HDF_LOGI("%s: init accel driver success", __func__); + return HDF_SUCCESS; + +INIT_EXIT: + DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); +REG_CONFIG_EXIT: + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); +DETECT_CHIP_EXIT: + drvData->detectFlag = false; +BASE_CONFIG_EXIT: + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + return HDF_FAILURE; +} + +/* Release the resources allocated during driver initialization. */ +void ReleaseAccelDriver(struct HdfDeviceObject *device) +{ + (void)device; + struct AccelDrvData *drvData = NULL; + + drvData = AccelGetDrvData(); + (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); + drvData->detectFlag = false; + + if (drvData->accelCfg != NULL) { + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + } + + drvData->initStatus = false; +} +``` + +1. Configure the acceleration sensor register group. + +You only need to configure the acceleration sensor data according to the template. Template configuration parsing has been implemented via the **InitSensorConfigData** function and only needs to be called during initialization. If new configuration items are added, you need to modify this function accordingly. + +``` +Acceleration sensor data configuration template (accel_config.hcs) +root { + sensorAccelConfig { + accelChipConfig { + /* Sensor information template */ + template sensorInfo { + sensorName = "accelerometer"; /* Acceleration sensor name. The value contains a maximum of 16 bytes. */ + vendorName = "borsh_bmi160"; /* Sensor vendor name. The value contains a maximum of 16 bytes. */ + firmwareVersion = "1.0"; /* Sensor firmware version. The default value is 1.0. The value contains a maximum of 16 bytes. */ + hardwareVersion = "1.0"; /* Sensor hardware version. The default value is 1.0. The value contains a maximum of 16 bytes. */ + sensorTypeId = 1; /* Sensor type ID. For details, see SensorTypeTag. */ + sensorId = 1; /* Sensor ID, which is defined by the sensor driver developer. The SensorTypeTag enums are recommended. */ + maxRange = 8; /* Maximum measurement range of the sensor. Set this parameter based on your business requirements. */ + precision = 0; /* Sensor accuracy, which is used together with sensor data reporting. For details, see SensorEvents. */ + power = 230; /* Power consumption of the sensor */ + } + /* Template of the bus type and configuration information used by the sensor */ + template sensorBusConfig { + busType = 0; /* 0:i2c 1:spi */ + busNum = 6; /* Device ID allocated to the sensor on the chip */ + busAddr = 0; /* Address allocated to the sensor on the chip */ + regWidth = 1; /* Width of the sensor register address */ + regBigEndian = 0; /* Endian mode of the sensor register */ + } + /* Sensor attribute template */ + template sensorAttr { + chipName = ""; /* Sensor chip name */ + chipIdRegister = 0xf; /* Address of the register detecting whether the sensor is in position */ + chipIdValue = 0xd1; /* Value of the register detecting whether the sensor is in position */ + } + } + } +} + +/* You can modify the template configuration based on the differences of sensor devices. If no modification is made, the default template configuration is used. */ +root { + sensorAccelConfig { + accel_bmi160_chip_config : accelChipConfig { + match_attr = "hdf_sensor_accel_driver"; /* The value must be the same as the match_attr field configured for the acceleration sensor. */ + accelInfo :: sensorInfo { + vendorName = "borsh_bmi160"; + sensorTypeId = 1; + sensorId = 1; + } + accelBusConfig :: sensorBusConfig { + busType = 0; /* I2C communication mode */ + busNum = 6; + busAddr = 0x68; + regWidth = 1; /* 1-byte bit width */ + } + accelAttr :: sensorAttr { + chipName = "bmi160"; + chipIdRegister = 0x00; + chipIdValue = 0xd1; + } + accelRegConfig { + /* regAddr: Register address + value: Register value + mask: Mask of the register value + len: Length (in bytes) of the register value + delay: Register delay (in milliseconds) + opsType: Operation type. The options can be 0 (no operation), 1 (read), 2 (write), 3 (read and check), and 4 (bit update). + calType: Calculation type. The options can be 0 (none), 1 (write), 2 (negate), 3 (XOR) 4, (left shift), and 5 (right shift). + shiftNum: Number of shifts + debug: Debugging switch. The value can be 0 (disabled) or 1 (enabled). + save: Data saving switch. The value can be 0 (not save data) or 1 (save data). + */ + /* Groups of sensor register operations. Registers can be configured in sequence based on the groups. */ + /* Register address, register value, mask of the register value, data length of the register value, register delay, operation type, calculation type, number of shifts, debugging switch, data saving switch */ + /* Initialize the register groups. */ + initSeqConfig = [ + 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + /* Enable the register groups. */ + enableSeqConfig = [ + 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0, + 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0 + ]; + /* Disable the register groups. */ + disableSeqConfig = [ + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + } + } + } +} +``` + +1. Implement APIs for acceleration sensor driver operations. + +You need to implement normalized APIs based on sensor types. + +``` +/* Leave a function empty if it is not used. */ +static int32_t SetAccelInfo(struct SensorBasicInfo *info) +{ + (void)info; + + return HDF_ERR_NOT_SUPPORT; +} +/* Deliver the configuration of enabling the register groups. */ +static int32_t SetAccelEnable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_RUNNING; + + return HDF_SUCCESS; +} +/* Deliver the configuration of disabling the register groups. */ +static int32_t SetAccelDisable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_STOPPED; + + return HDF_SUCCESS; +} +/* Set the sampling interval and data reporting interval of the sensor. */ +static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval) +{ + (void)interval; + + struct AccelDrvData *drvData = AccelGetDrvData(); + drvData->interval = samplingInterval; + + return HDF_SUCCESS; +} +/* Set the data reporting mode of the sensor. Currently, the real-time mode is supported. */ +static int32_t SetAccelMode(int32_t mode) +{ + return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE; +} +/* Set the sensor options. */ +static int32_t SetAccelOption(uint32_t option) +{ + (void)option; + return HDF_ERR_NOT_SUPPORT; +} +``` + +- Differentiated processing APIs + + ``` + /* If a device is detected, register the differentiated processing function to the accel driver model. */ + int32_t DetectAccelBim160Chip(struct SensorCfgData *data) + { + int32_t ret; + struct AccelOpsCall ops; + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + + if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) { + return HDF_SUCCESS; + } + ret = InitAccelPreConfig(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: init BMI160 bus mux config", __func__); + return HDF_FAILURE; + } + if (DetectSensorDevice(data) != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* Differentiated processing function */ + ops.Init = InitBmi160; + ops.ReadData = ReadBmi160Data; + ret = RegisterAccelChipOps(&ops); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: register BMI160 accel failed", __func__); + (void)ReleaseSensorBusHandle(&data->busCfg); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* Initialization processing function */ + static int32_t InitBmi160(struct SensorCfgData *data) + { + int32_t ret; + + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: bmi160 sensor init config failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* Data processing function */ + int32_t ReadBmi160Data(struct SensorCfgData *data) + { + int32_t ret; + struct AccelData rawData = { 0, 0, 0 }; + int32_t tmp[ACCEL_AXIS_NUM]; + struct SensorReportEvent event; + + (void)memset_s(&event, sizeof(event), 0, sizeof(event)); + + ret = ReadBmi160RawData(data, &rawData, &event.timestamp); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + event.sensorId = SENSOR_TAG_ACCELEROMETER; + event.option = 0; + event.mode = SENSOR_WORK_MODE_REALTIME; + + rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G; + rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G; + rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G; + + tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + + event.dataLen = sizeof(tmp); + event.data = (uint8_t *)&tmp; + ret = ReportSensorEvent(&event); + return ret; + } + ``` + +- Data processing function + +Create a sensor timer to periodically sample data based on the configured sampling interval and report the data to the data subscriber. + +``` +/* Scheduled working thread of the sensor */ +static int32_t ReadAccelDataThreadWorker(void *arg) +{ + (void)arg; + int64_t interval; + struct AccelDrvData *drvData = AccelGetDrvData(); + + drvData->threadStatus = SENSOR_THREAD_START; + while (true) { + if (drvData->threadStatus == SENSOR_THREAD_RUNNING) { + if (drvData->ops.ReadData != NULL) { + (void)drvData->ops.ReadData(drvData->accelCfg); + } + interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT)); + OsalMSleep(interval); + } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) { + break; + } else { + OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT); + } + + if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) { + continue; + } + } + + return HDF_SUCCESS; +} +/* Create a sensor timer and initialize the sensor device. */ +static int32_t InitAccelConfig(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) { + HDF_LOGE("%s: accel thread have created", __func__); + return HDF_SUCCESS; + } + + ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + + CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM); + + ret = drvData->ops.Init(drvData->accelCfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + drvData->initStatus = true; + return HDF_SUCCESS; +} +``` + +- Major data structures + +``` +/* Sensor conversion units */ +#define SENSOR_CONVERT_UNIT 1000 +#define SENSOR_1K_UNIT 1024 +/* Sensitivity conversion value of the sensor with a 2g measurement range */ +#define BMI160_ACC_SENSITIVITY_2G 61 +/* Address of the sensor data sampling register */ +#define BMI160_ACCEL_X_LSB_ADDR 0X12 +#define BMI160_ACCEL_X_MSB_ADDR 0X13 +#define BMI160_ACCEL_Y_LSB_ADDR 0X14 +#define BMI160_ACCEL_Y_MSB_ADDR 0X15 +#define BMI160_ACCEL_Z_LSB_ADDR 0X16 +#define BMI160_ACCEL_Z_MSB_ADDR 0X17 +/* Data dimension of the sensor */ +enum AccelAxisNum { + ACCEL_X_AXIS = 0, + ACCEL_Y_AXIS = 1, + ACCEL_Z_AXIS = 2, + ACCEL_AXIS_NUM = 3, +}; +/* Each dimension of the sensor */ +struct AccelData { + int32_t x; + int32_t y; + int32_t z; +}; +/* Private data structure of the sensor */ +struct AccelDrvData { + bool detectFlag; + uint8_t threadStatus; + uint8_t initStatus; + int64_t interval; + struct SensorCfgData *accelCfg; + struct OsalThread thread; + struct AccelOpsCall ops; +}; +/* Differentiation adaptation function */ +struct AccelOpsCall { + int32_t (*Init)(struct SensorCfgData *data); + int32_t (*ReadData)(struct SensorCfgData *data); +}; +``` + +## Test Guidelines + +After the driver is developed, you can develop self-test cases in the sensor unit test to verify the basic functions of the driver. The developer self-test platform is used as the test environment. + +``` +/* Specify whether to report sensor data. */ +static int32_t g_sensorDataFlag = 0; +/* Retain the address of the sensor interface instance. */ +static const struct SensorInterface *g_sensorDev = nullptr; + +/* Register the data reporting function. */ +static int SensorTestDataCallback(struct SensorEvents *event) +{ + if (event == nullptr) { + return -1; + } + float *data = (float*)event->data; + printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, + event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); + if (*data > 1e-5) { + g_sensorDataFlag = 1; + } + return 0; +} +/* Initialize the sensor interface instance before executing the test cases. */ +void HdfSensorTest::SetUpTestCase() +{ + g_sensorDev = NewSensorInterfaceInstance(); + if (g_sensorDev == nullptr) { + printf("test sensorHdi get Module instace failed\n\r"); + } +} +/* Release case resources. */ +void HdfSensorTest::TearDownTestCase() +{ + if (g_sensorDev != nullptr) { + FreeSensorInterfaceInstance(); + g_sensorDev = nullptr; + } +} +/* Verify the sensor driver. */ +HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) +{ + int32_t sensorInterval = 1000000000; /* Data sampling interval, in nanoseconds */ + int32_t pollTime = 5; /* Data sampling duration, in seconds */ + int32_t accelSensorId = 1; /* Acceleration sensor type ID, which is 1 */ + int32_t count = 0; + int ret; + struct SensorInformation *sensorInfo = nullptr; + + ret = g_sensorDev->Register(SensorTestDataCallback) + EXPECT_EQ(SENSOR_NULL_PTR, ret); + + ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); + EXPECT_EQ(0, ret); + if (sensorInfo == nullptr) { + EXPECT_NE(nullptr, sensorInfo); + return; + } + /* Print the obtained sensor list. */ + for (int i = 0; i < count; i++) { + printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); + } + ret = g_sensorDev->Enable(accelSensorId); + EXPECT_EQ(0, ret); + g_sensorDataFlag = 0; + + ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); + EXPECT_EQ(0, ret); + /* Observe the printed data within the period specified by pollTime. */ + OsalSleep(pollTime); + EXPECT_EQ(1, g_sensorDataFlag); + + ret = g_sensorDev->Disable(accelSensorId); + g_sensorDataFlag = 0; + EXPECT_EQ(0, ret); + + ret = g_sensorDev->Unregister(); + EXPECT_EQ(0, ret); +} +``` diff --git a/en/device-dev/driver/spi.md b/en/device-dev/driver/spi.md index c635810c74cbb62be99562f6848983e4b7437058..93b6085f61eb8fa578518eddbf2175f4cd17c0bd 100644 --- a/en/device-dev/driver/spi.md +++ b/en/device-dev/driver/spi.md @@ -1,9 +1,566 @@ -# SPI +# SPI -- **[SPI Overview](spioverview.md)** +- [Overview](#section193356154511) + - [Available APIs](#section232141411476) -- **[SPI Usage Guidelines](spiusage-guidelines.md)** +- [Usage Guidelines](#section71363452477) + - [How to Use](#section32846814820) + - [Obtaining an SPI Device Handle](#section1927265711481) + - [Obtaining SPI Device Configuration Parameters](#section541133418493) + - [Setting SPI Device Configuration Parameters](#section7870106145010) + - [Performing SPI Communication](#section13324155195013) + - [Destroying the SPI Device Handle](#section19661632135117) -- **[SPI Usage Example](spiusage-example.md)** +- [Usage Example](#section06541058155120) +## Overview + +- Serial Peripheral Interface \(SPI\) is a serial bus specification used for high-speed, full-duplex, and synchronous communication. +- SPI is developed by Motorola. It is commonly used for communication with flash memory, real-time clocks, sensors, and analog-to-digital \(A/D\) converters. +- SPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires: + - SCLK: clock signals output from the SPI controller + - MOSI: data output from the SPI controller and input into an SPI device + - MISO: data output from an SPI device and input into the SPI controller + - CS: signals enabled by an SPI device and controlled by the SPI controller + + +- [Figure 1](#fig15227181812587) shows the connection between one SPI controller and two SPI devices \(device A and device B\). In this figure, device A and device B share three pins \(SCLK, MISO, and MOSI\) of the controller. CS0 of device A and CS1 of device B are connected to CS0 and CS1 of the controller, respectively. + +**Figure 1** SPI controller/device connection + + +![](figures/en-us_image_0000001123742254.png) + +- SPI communication is usually initiated by the SPI controller and is operated as follows: + +1. A single SPI device is selected at a time via the CS to communicate with the SPI controller. +2. Clock signals are provided for the selected SPI device via the SCLK. +3. The SPI controller sends data to SPI devices via the MOSI, and receives data from SPI devices via the MISO. + +- SPI can work in one of the following four modes, equivalent to one of the four possible states for Clock Polarity \(CPOL\) and Clock Phase \(CPHA\): + - If both CPOL and CPHA are **0**, the clock signal level is low in the idle state and data is sampled on the first clock edge. + - If CPOL is **0** and CPHA is **1**, the clock signal level is low in the idle state and data is sampled on the second clock edge. + - If CPOL is **1** and CPHA is **0**, the clock signal level is high in the idle state and data is sampled on the first clock edge. + - If both CPOL and CPHA are **1**, the clock signal level is high in the idle state and data is sampled on the second clock edge. + + +- SPI defines a set of common functions for operating an SPI device, including those for: + - Obtaining and releasing the handle of an SPI device. + - Reading or writing data of a specified length from or into an SPI device. + - Customizing data reading or writing via **SpiMsg**. + - Obtaining and setting SPI device configuration parameters. + + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>Currently, these functions are only applicable in the communication initiated by the SPI controller. + +### Available APIs + +**Table 1** APIs for the SPI driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

SPI device handle obtaining/releasing

+

SpiOpen

+

Obtains an SPI device handle.

+

SpiClose

+

Releases an SPI device handle.

+

SPI reading/writing

+

SpiRead

+

Reads data of a specified length from an SPI device.

+

SpiWrite

+

Writes data of a specified length into an SPI device.

+

SpiTransfer

+

Transfers SPI data.

+

SPI device configuration

+

+

SpiSetCfg

+

Sets configuration parameters for an SPI device.

+

SpiGetCfg

+

Obtains configuration parameters of an SPI device.

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

Parameter

+

Description

+

info

+

Pointer to the SPI device descriptor.

+

Return Value

+

Description

+

NULL

+

Failed to obtain an SPI device handle.

+

Device handle

+

Returns the pointer to the SPI device handle.

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

Parameter

+

Description

+

handle

+

SPI device handle.

+

cfg

+

Pointer to SPI device configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in obtaining SPI device configuration parameters.

+

Negative value

+

Failed to obtain SPI device configuration parameters.

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

Parameter

+

Description

+

handle

+

SPI device handle.

+

cfg

+

Pointer to SPI device configuration parameters.

+

Return Value

+

Description

+

0

+

Succeeded in setting SPI device configuration parameters.

+

Negative value

+

Failed to set SPI device configuration parameters.

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

Parameter

+

Description

+

handle

+

SPI device handle.

+

buf

+

Pointer to the data to write.

+

len

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Succeeded in writing data into an SPI device.

+

Negative value

+

Failed to write data into an SPI device.

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

Parameter

+

Description

+

handle

+

SPI device handle.

+

buf

+

Pointer to the data to read.

+

len

+

Length of the data to read.

+

Return Value

+

Description

+

0

+

Succeeded in reading data from an SPI device.

+

Negative value

+

Failed to read data from an SPI device.

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

Parameter

+

Description

+

handle

+

SPI device handle.

+

msgs

+

Pointer to the message array to be transferred.

+

count

+

Number of messages in the message array.

+

Return Value

+

Description

+

0

+

Succeeded in launching the custom transfer.

+

Negative value

+

Failed to launch the custom transfer.

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

Parameter

+

Description

+

handle

+

SPI device handle.

+
+ +``` +PalHandleDestroy(spiHandle); /* Destroy the SPI device handle. */ +``` + +## Usage Example + +The following example shows how to obtain an SPI device handle, set the configuration parameters, and then read or write data from or into the SPI device, and finally destroy the SPI device handle. + +``` +#include "hdf_log.h" +#include "spi_if.h" + +void SpiTestSample(void) +{ + int32_t ret; + struct SpiCfg cfg; /* SPI device configuration information */ + struct SpiDevInfo spiDevinfo; /* SPI device descriptor */ + DevHandle spiHandle = NULL; /* SPI device handle */ + struct SpiMsg msg; /* Custom message to be transferred */ + uint8_t rbuff[4] = { 0 }; + uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; + uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; + + spiDevinfo.busNum = 0; /* SPI device bus number */ + spiDevinfo.csNum = 0; /* SPI device CS number */ + spiHandle = SpiOpen(&spiDevinfo); /* Obtain an SPI device handle based on spiDevinfo. */ + if (spiHandle == NULL) { + HDF_LOGE("SpiOpen: failed\n"); + return; + } + /* Obtain configuration parameters of an SPI device. */ + ret = SpiGetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); + goto err; + } + cfg.maxSpeedHz = 115200; /* Change the maximum clock frequency to 115200. */ + cfg.bitsPerWord = 8; /* Change the word width to 8 bits. */ + /* Set configuration parameters for an SPI device. */ + ret = SpiSetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); + goto err; + } + /* Write specified length of data into an SPI device. */ + ret = SpiWrite(spiHandle, wbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiWrite: failed, ret %d\n", ret); + goto err; + } + /* Read data of a specified length from an SPI device. */ + ret = SpiRead(spiHandle, rbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiRead: failed, ret %d\n", ret); + goto err; + } + msg.wbuf = wbuff2; /* Pointer to the data to write */ + msg.rbuf = rbuff; /* Pointer to the data to read */ + msg.len = 4; /* The length of the data to read or write is 4 bits. */ + msg.csChange = 1; /* Disable the CS before the next transfer. */ + msg.delayUs = 0; /* No delay before the next transfer */ + msg.speed = 115200; /* Speed of this transfer */ + /* Launch a custom transfer. The number of messages to be transferred is 1. */ + ret = SpiTransfer(spiHandle, &msg, 1); + if (ret != 0) { + HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); + goto err; + } +err: + /* Destroy the SPI device handle. */ + SpiClose(spiHandle); +} +``` diff --git a/en/device-dev/driver/spioverview.md b/en/device-dev/driver/spioverview.md deleted file mode 100644 index 46303b336baaec8295a11afacc466aed62809c29..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/spioverview.md +++ /dev/null @@ -1,107 +0,0 @@ -# SPI Overview - -- [Introduction](#section9202632114011) -- [Available APIs](#section1859594134119) - -## Introduction - -- Serial Peripheral Interface \(SPI\) is a serial bus specification used for high-speed, full-duplex, and synchronous communication. -- SPI is developed by Motorola. It is commonly used for communication with flash memory, real-time clocks, sensors, and analog-to-digital \(A/D\) converters. -- SPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires: - - SCLK: clock signals output from the SPI controller - - MOSI: data output from the SPI controller and input into an SPI device - - MISO: data output from an SPI device and input into the SPI controller - - CS: signals enabled by an SPI device and controlled by the SPI controller - - -- [Figure 1](#fig15227181812587) shows the connection between one SPI controller and two SPI devices \(device A and device B\). In this figure, device A and device B share three pins \(SCLK, MISO, and MOSI\) of the controller. CS0 of device A and CS1 of device B are connected to CS0 and CS1 of the controller, respectively. - -**Figure 1** SPI controller/device connection - - -![](figures/en-us_image_0000001054142582.png) - -- SPI communication is usually initiated by the SPI controller and is operated as follows: - -1. A single SPI device is selected at a time via the CS to communicate with the SPI controller. -2. Clock signals are provided for the selected SPI device via the SCLK. -3. The SPI controller sends data to SPI devices via the MOSI, and receives data from SPI devices via the MISO. - -- SPI can work in one of the following four modes, equivalent to one of the four possible states for Clock Polarity \(CPOL\) and Clock Phase \(CPHA\): - - If both CPOL and CPHA are **0**, the clock signal level is low in the idle state and data is sampled on the first clock edge. - - If CPOL is **0** and CPHA is **1**, the clock signal level is low in the idle state and data is sampled on the second clock edge. - - If CPOL is **1** and CPHA is **0**, the clock signal level is high in the idle state and data is sampled on the first clock edge. - - If both CPOL and CPHA are **1**, the clock signal level is high in the idle state and data is sampled on the second clock edge. - - -- SPI defines a set of common functions for operating an SPI device, including those for: - - Obtaining and releasing the handle of an SPI device. - - Reading or writing data of a specified length from or into an SPI device. - - Customizing data reading or writing via **SpiMsg**. - - Obtaining and setting SPI device configuration parameters. - - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Currently, these functions are only applicable in the communication initiated by the SPI controller. - -## Available APIs - -**Table 1** APIs for the SPI driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

SPI device handle obtaining/releasing

-

SpiOpen

-

Obtains an SPI device handle.

-

SpiClose

-

Releases an SPI device handle.

-

SPI reading/writing

-

SpiRead

-

Reads data of a specified length from an SPI device.

-

SpiWrite

-

Writes data of a specified length into an SPI device.

-

SpiTransfer

-

Transfers SPI data.

-

SPI device configuration

-

-

SpiSetCfg

-

Sets configuration parameters for an SPI device.

-

SpiGetCfg

-

Obtains configuration parameters of an SPI device.

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

Parameter

-

Description

-

info

-

Pointer to the SPI device descriptor.

-

Return Value

-

Description

-

NULL

-

Failed to obtain an SPI device handle.

-

Device handle

-

Returns the pointer to the SPI device handle.

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

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

cfg

-

Pointer to SPI device configuration parameters.

-

Return Value

-

Description

-

0

-

Succeeded in obtaining SPI device configuration parameters.

-

Negative value

-

Failed to obtain SPI device configuration parameters.

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

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

cfg

-

Pointer to SPI device configuration parameters.

-

Return Value

-

Description

-

0

-

Succeeded in setting SPI device configuration parameters.

-

Negative value

-

Failed to set SPI device configuration parameters.

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

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

buf

-

Pointer to the data to write.

-

len

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Succeeded in writing data into an SPI device.

-

Negative value

-

Failed to write data into an SPI device.

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

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

buf

-

Pointer to the data to read.

-

len

-

Length of the data to read.

-

Return Value

-

Description

-

0

-

Succeeded in reading data from an SPI device.

-

Negative value

-

Failed to read data from an SPI device.

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

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle.

-

msgs

-

Pointer to the message array to be transferred.

-

count

-

Length of the message array.

-

Return Value

-

Description

-

0

-

Succeeded in launching the custom transfer.

-

Negative value

-

Failed to launch the custom transfer.

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

Parameter

-

Description

-

handle

-

Pointer to the SPI device handle

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

Capability

+

Function

+

Description

+

Obtaining and releasing device handles

+

+

UartOpen

+

Obtains the UART device handle.

+

UartClose

+

Releases a specified UART device handle.

+

Reading and writing data

+

+

UartRead

+

Reads data of a specified length from a UART device.

+

UartWrite

+

Writes data of a specified length into a UART device.

+

Obtaining and setting the baud rate

+

UartGetBaud

+

Obtains the UART baud rate.

+

UartSetBaud

+

Sets the UART baud rate.

+

Obtaining and setting device attributes

+

+

UartGetAttribute

+

Obtains the UART device attributes.

+

UartSetAttribute

+

Sets the UART device attributes.

+

Setting the transmission mode

+

UartSetTransMode

+

Sets the UART transmission mode.

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

Parameter

+

Description

+

port

+

UART port number.

+

Return Value

+

Description

+

NULL

+

Failed to obtain the UART device handle.

+

Device handle

+

UART device handle.

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

Parameter

+

Description

+

handle

+

UART device handle.

+

baudRate

+

Baud rate of the UART to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the UART baud rate.

+

Negative value

+

Failed to set the UART baud rate.

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

Parameter

+

Description

+

handle

+

UART device handle.

+

baudRate

+

Pointer to the UART baud rate.

+

Return Value

+

Description

+

0

+

Succeeded in obtaining the UART baud rate.

+

Negative value

+

Failed to obtain the UART baud rate.

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

Parameter

+

Description

+

handle

+

UART device handle.

+

attribute

+

Pointer to the UART device attributes to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the UART device attributes.

+

Negative value

+

Failed to set the UART device attributes.

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

Parameter

+

Description

+

handle

+

UART device handle.

+

attribute

+

Pointer to the UART device attributes.

+

Return Value

+

Description

+

0

+

Succeeded in obtaining the UART device attributes.

+

Negative value

+

Failed to obtain the UART device attributes.

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

Parameter

+

Description

+

handle

+

UART device handle.

+

mode

+

UART transmission mode to set.

+

Return Value

+

Description

+

0

+

Succeeded in setting the UART transmission mode.

+

Negative value

+

Failed to set the UART transmission mode.

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

Parameter

+

Description

+

handle

+

UART device handle.

+

data

+

Pointer to the data to write.

+

size

+

Length of the data to write.

+

Return Value

+

Description

+

0

+

Succeeded in writing data into the UART device.

+

Negative value

+

Failed to write data into the UART device.

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

Parameter

+

Description

+

handle

+

UART device handle.

+

data

+

Pointer to the buffer for receiving the data.

+

size

+

Length of the data to read.

+

Return Value

+

Description

+

Non-negative value

+

Length of the data read from the UART device.

+

Negative value

+

Failed to read data from the UART device.

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

Parameter

+

Description

+

handle

+

UART device handle.

+
+ +The following example shows how to destroy the UART device handle: + +``` +UartClose(handle); /* Destroy the UART device handle. */ +``` + +## Usage Example + +The following is a usage example of a UART device, including how to obtain the UART device handle, set the baud rate, device attributes, and transmission mode, read data from or write data into the UART device, and then destroy the UART device handle. + +``` +#include "hdf_log.h" +#include "uart_if.h" + +void UartTestSample(void) +{ + int32_t ret; + uint32_t port; + DevHandle handle = NULL; + uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; + uint8_t rbuff[5] = { 0 }; + struct UartAttribute attribute; + attribute.dataBits = UART_ATTR_DATABIT_7; /* Set the number of data bits to 7. */ + attribute.parity = UART_ATTR_PARITY_NONE; /* Set the parity bit to no parity. */ + attribute.stopBits = UART_ATTR_STOPBIT_1; /* Set the stop bit to 1. */ + attribute.rts = UART_ATTR_RTS_DIS; /* Disable the RTS signal. */ + attribute.cts = UART_ATTR_CTS_DIS; /* Disable the CTS signal. */ + attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* Enable RX FIFO. */ + attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* Enable TX FIFO. */ + /* Set the UART port number actually used. */ + port = 1; + /* Obtain the UART device handle. */ + handle = UartOpen(port); + if (handle == NULL) { + HDF_LOGE("UartOpen: failed!\n"); + return; + } + /* Set the UART baud rate to 9600. */ + ret = UartSetBaud(handle, 9600); + if (ret != 0) { + HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); + goto _ERR; + } + /* Set the UART device attributes. */ + ret = UartSetAttribute(handle, &attribute); + if (ret != 0) { + HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); + goto _ERR; + } + /* Set the UART transmission mode to non-blocking mode. */ + ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); + if (ret != 0) { + HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); + goto _ERR; + } + /* Write 5-byte data into the UART device. */ + ret = UartWrite(handle, wbuff, 5); + if (ret != 0) { + HDF_LOGE("UartWrite: failed, ret %d\n", ret); + goto _ERR; + } + /* Read 5-byte data from the UART device. */ + ret = UartRead(handle, rbuff, 5); + if (ret < 0) { + HDF_LOGE("UartRead: failed, ret %d\n", ret); + goto _ERR; + } +_ERR: + /* Destroy the UART device handle. */ + UartClose(handle); +} +``` diff --git a/en/device-dev/driver/uartoverview.md b/en/device-dev/driver/uartoverview.md deleted file mode 100644 index 2238f2ca5564f4f1faa35bf16590c51a6492ad07..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/uartoverview.md +++ /dev/null @@ -1,106 +0,0 @@ -# UART Overview - -- [Introduction](#section14770623164917) -- [Available APIs](#section149505462492) - -## Introduction - -- The Universal Asynchronous Receiver/Transmitter \(UART\) is a universal serial data bus used for asynchronous communication. It enables bi-directional communication between devices in full-duplex mode. -- UART is widely used to print information for debugging or to connect to various external modules such as GPS and Bluetooth. -- A UART is connected to other modules through two wires \(as shown in [Figure 1](#fig209936401896)\) or four wires \(as shown in [Figure 2](#fig1435614171015)\). - - TX: TX pin of the transmitting UART. It is connected to the RX pin of the peer UART. - - RX: RX pin of the receiving UART. It is connected to the TX pin of the peer UART. - - RTS: Request to Send signal pin. It is connected to the CTS pin of the peer UART and is used to indicate whether the local UART is ready to receive data. - - CTS: Clear to Send signal pin. It is connected to the RTS pin of the peer UART and is used to indicate whether the local UART is allowed to send data to the peer end. - - **Figure 1** 2-wire UART communication - - - ![](figures/en-us_image_0000001053926237.png) - - **Figure 2** 4-wire UART communication - - - ![](figures/en-us_image_0000001054007499.png) - - -- The transmitting and receiving UARTs must ensure that they have the same settings on particular attributes such as the baud rate and data format \(start bit, data bit, parity bit, and stop bit\) before they start to communicate. During data transmission, a UART sends data to the peer end over the TX pin and receives data from the peer end over the RX pin. When the size of the buffer used by a UART for storing received data reaches the preset threshold, the RTS signal of the UART changes to **1** \(data cannot be received\), and the peer UART stops sending data to it because its CTS signal does not allow it to send data. -- The UART interface defines a set of common functions for operating a UART port, including obtaining and releasing device handles, reading and writing data of a specified length, and obtaining and setting the baud rate, as well as the device attributes. - -## Available APIs - -**Table 1** APIs for the UART driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

Obtaining and releasing device handles

-

-

UartOpen

-

Obtains the UART device handle.

-

UartClose

-

Releases a specified UART device handle.

-

Reading and writing data

-

-

UartRead

-

Reads data of a specified length from a UART device.

-

UartWrite

-

Writes data of a specified length into a UART device.

-

Obtaining and setting the baud rate

-

UartGetBaud

-

Obtains the UART baud rate.

-

UartSetBaud

-

Sets the UART baud rate.

-

Obtaining and setting device attributes

-

-

UartGetAttribute

-

Obtains the UART device attributes.

-

UartSetAttribute

-

Sets the UART device attributes.

-

Setting the transmission mode

-

UartSetTransMode

-

Sets the UART transmission mode.

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

Parameter

-

Description

-

port

-

UART port number.

-

Return Value

-

Description

-

NULL

-

Failed to obtain the UART device handle.

-

Device handle

-

Pointer to the UART device handle.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

baudRate

-

Baud rate of the UART to set.

-

Return Value

-

Description

-

0

-

Succeeded in setting the UART baud rate.

-

Negative value

-

Failed to set the UART baud rate.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

baudRate

-

Pointer to the UART baud rate.

-

Return Value

-

Description

-

0

-

Succeeded in obtaining the UART baud rate.

-

Negative value

-

Failed to obtain the UART baud rate.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

attribute

-

Pointer to the UART device attributes to set.

-

Return Value

-

Description

-

0

-

Succeeded in setting the UART device attributes.

-

Negative value

-

Failed to set the UART device attributes.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

attribute

-

Pointer to the UART device attributes.

-

Return Value

-

Description

-

0

-

Succeeded in obtaining the UART device attributes.

-

Negative value

-

Failed to obtain the UART device attributes.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

mode

-

UART transmission mode to set.

-

Return Value

-

Description

-

0

-

Succeeded in setting the UART transmission mode.

-

Negative value

-

Failed to set the UART transmission mode.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

data

-

Pointer to the data to write.

-

size

-

Length of the data to write.

-

Return Value

-

Description

-

0

-

Succeeded in writing data into the UART device.

-

Negative value

-

Failed to write data into the UART device.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle.

-

data

-

Pointer to the buffer for receiving the data.

-

size

-

Length of the data to read.

-

Return Value

-

Description

-

Non-negative value

-

Length of the data read from the UART device.

-

Negative value

-

Failed to read data from the UART device.

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

Parameter

-

Description

-

handle

-

Pointer to the UART device handle

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

Parameter

-

Description

-

id

-

MIPI DSI channel ID.

-

Return Value

-

Description

-

NULL

-

Failed to obtain the MIPI DSI channel ID.

-

Device handle

-

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

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

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cfg

-

Pointer to MIPI DSI configuration parameters

-

Return Value

-

Description

-

0

-

Succeeded in setting MIPI DSI configuration parameters.

-

Negative value

-

Failed to set MIPI DSI configuration parameters.

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

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cfg

-

Pointer to MIPI DSI configuration parameters

-

Return Value

-

Description

-

0

-

Succeeded in obtaining MIPI DSI configuration parameters.

-

Negative value

-

Failed to obtain MIPI DSI configuration parameters.

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

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cmd

-

Pointer to the command to be sent

-

Return Value

-

Description

-

0

-

Succeeded in sending the specified command.

-

Negative value

-

Failed to send the specified command.

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

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-

cmd

-

Pointer to the command to be received

-

readLen

-

Length of the data to read.

-

out

-

Pointer to the read data.

-

Return Value

-

Description

-

0

-

Succeeded in receiving the specified command.

-

Negative value

-

Failed to receive the specified command.

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

Parameter

-

Description

-

handle

-

MIPI DSI device handle

-
- -``` -MipiDsiClose(mipiHandle); /* Release the MIPI DSI device handle */ -``` - diff --git a/en/device-dev/driver/watchdog.md b/en/device-dev/driver/watchdog.md index b8f20d1dad97959da8207df5b166e177854a35a9..6a8bcd9802657d57d6bf00786111cacd5e0141b6 100644 --- a/en/device-dev/driver/watchdog.md +++ b/en/device-dev/driver/watchdog.md @@ -1,9 +1,557 @@ -# WATCHDOG +# Watchdog -- **[Watchdog Overview](watchdogoverview.md)** +- [Overview](#section14918241977) + - [Available APIs](#section20177131219818) -- **[Watchdog Usage Guidelines](watchdogusage-guidelines.md)** +- [Usage Guidelines](#section10103184312813) + - [How to Use](#section10181195910815) + - [Opening a Watchdog](#section66089201107) + - [Obtaining the Watchdog Status](#section786624341011) + - [Setting the Timeout Duration](#section182386137111) + - [Obtaining the Timeout Duration](#section1883310371114) + - [Starting a Watchdog](#section82501405123) + - [Feeding a Watchdog](#section3547530101211) + - [Stopping a Watchdog](#section944595841217) + - [Closing a Watchdog](#section96561824121311) -- **[Watchdog Usage Example](watchdogusage-example.md)** +- [Usage Example](#section1724514523135) +## Overview + +A watchdog, also called a watchdog timer, is a hardware timing device. If an error occurs in the main program of the system and fails to reset the watchdog timer, the watchdog timer sends a reset signal to restore the system to a normal state. + +### Available APIs + +**Table 1** Watchdog APIs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Capability

+

Function

+

Description

+

Open/Close

+

WatchdogOpen

+

Opens a watchdog.

+

WatchdogClose

+

Closes a watchdog.

+

Start/Stop

+

WatchdogStart

+

Starts a watchdog.

+

WatchdogStop

+

Stops a watchdog.

+

Timeout duration

+

WatchdogSetTimeout

+

Sets the watchdog timeout duration.

+

WatchdogGetTimeout

+

Obtains the watchdog timeout duration.

+

Status

+

WatchdogGetStatus

+

Obtains the watchdog status.

+

Feeding

+

WatchdogFeed

+

Feeds a watchdog, or resets a watchdog timer.

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

Parameter

+

Description

+

wdtId

+

Watchdog ID.

+

Return Value

+

Description

+

NULL

+

Failed to open the watchdog.

+

DevHandle pointer

+

Pointer to the watchdog handle.

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

Parameter

+

Description

+

handle

+

Watchdog handle.

+

status

+

Pointer to the watchdog status.

+

Return Value

+

Description

+

0

+

The watchdog status is obtained.

+

Negative value

+

Failed to obtain the watchdog status.

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

Parameter

+

Description

+

handle

+

Watchdog handle.

+

seconds

+

Timeout duration, in seconds.

+

Return Value

+

Description

+

0

+

The setting is successful.

+

Negative value

+

Setting failed.

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

Parameter

+

Description

+

handle

+

Watchdog handle.

+

seconds

+

Pointer to the timeout duration, in seconds.

+

Return Value

+

Description

+

0

+

The watchdog status is obtained.

+

Negative value

+

Failed to obtain the watchdog status.

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

Parameter

+

Description

+

handle

+

Watchdog handle.

+

Return Value

+

Description

+

0

+

The watchdog is started.

+

Negative value

+

Failed to start the watchdog.

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

Parameter

+

Description

+

handle

+

Watchdog handle.

+

Return Value

+

Description

+

0

+

The watchdog is fed.

+

Negative value

+

Failed to feed the watchdog.

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

Parameter

+

Description

+

handle

+

Watchdog handle.

+

Return Value

+

Description

+

0

+

The watchdog is stopped.

+

Negative value

+

Stopping the watchdog failed.

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

Parameter

+

Description

+

handle

+

Watchdog handle.

+
+ +``` +/* Close the watchdog. */ +ret = WatchdogClose(handle); +``` + +## Usage Example + +This example provides a complete process for using a watchdog. + +In this example, open a watchdog, set the timeout duration, and start the watchdog. + +- Feed the watchdog periodically to ensure that the system is not reset due to timer expiry. +- Stop feeding the watchdog and check whether the system is reset after the timer expires. + +Example: + +``` +#include "watchdog_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +#define WATCHDOG_TEST_TIMEOUT 2 +#define WATCHDOG_TEST_FEED_TIME 6 + +static int32_t TestCaseWatchdog(void) +{ + int32_t i; + int32_t ret; + uint32_t timeout; + DevHandle handle = NULL; + + /* Open watchdog 0. */ + handle = WatchdogOpen(0); + if (handle == NULL) { + HDF_LOGE("Open watchdog fail!"); + return -1; + } + + /* Set the timeout duration. */ + ret = WatchdogSetTimeout(handle, WATCHDOG_TEST_TIMEOUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* Obtain the configured timeout duration. */ + ret = WatchdogGetTimeout(handle, &timeout); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); + + /* Start the watchdog. The timer starts. */ + ret = WatchdogStart(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* Feed the watchdog every 1s. */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); + ret = WatchdogFeed(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + OsalSleep(1); + } + /* Because the interval for feeding the watchdog is shorter than the timeout duration, the system does not reset, and logs can be printed normally. */ + HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); + + /* Enable the timer to expire by stopping feeding the watchdog. */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: watiting dog buck %d times... \n", __func__, i); + OsalSleep(1); + } + + /* The system resets when the timer expires. If the code is correct, the log below is not displayed. */ + HDF_LOGE("%s: dog has't buck!!! \n", __func__, i); + WatchdogClose(handle); + return -1; +} +``` diff --git a/en/device-dev/driver/watchdogoverview.md b/en/device-dev/driver/watchdogoverview.md deleted file mode 100644 index 04b3b373d03c4773f5bc45ba9ef3ca8cabc29a85..0000000000000000000000000000000000000000 --- a/en/device-dev/driver/watchdogoverview.md +++ /dev/null @@ -1,78 +0,0 @@ -# Watchdog Overview - -- [Introduction](#section3579126111816) -- [Available APIs](#section17429111981812) - -## Introduction - -A watchdog, also called a watchdog timer, is a hardware timing device. If an error occurs in the main program of the system and fails to reset the watchdog timer, the watchdog timer sends a reset signal to restore the system to a normal state. - -## Available APIs - -**Table 1** Watchdog APIs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Capability

-

Function

-

Description

-

Open/Close

-

WatchdogOpen

-

Opens a watchdog.

-

WatchdogClose

-

Closes a watchdog.

-

Start/Stop

-

WatchdogStart

-

Starts a watchdog.

-

WatchdogStop

-

Stops a watchdog.

-

Timeout duration

-

WatchdogSetTimeout

-

Sets the watchdog timeout duration.

-

WatchdogGetTimeout

-

Obtains the watchdog timeout duration.

-

Status

-

WatchdogGetStatus

-

Obtains the watchdog status.

-

Feeding

-

WatchdogFeed

-

Feeds a watchdog, or resets a watchdog timer.

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

Parameter

-

Description

-

wdtId

-

Watchdog ID.

-

Return Value

-

Description

-

NULL

-

Failed to open the watchdog.

-

DevHandle pointer

-

Pointer to the watchdog handle.

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

Parameter

-

Description

-

handle

-

Watchdog handle.

-

status

-

Pointer to the watchdog status.

-

Return Value

-

Description

-

0

-

The watchdog status is obtained.

-

Negative value

-

Failed to obtain the watchdog status.

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

Parameter

-

Description

-

handle

-

Watchdog handle.

-

seconds

-

Timeout duration, in seconds.

-

Return Value

-

Description

-

0

-

The setting is successful.

-

Negative value

-

Setting failed.

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

Parameter

-

Description

-

handle

-

Watchdog handle.

-

seconds

-

Pointer to the timeout duration, in seconds.

-

Return Value

-

Description

-

0

-

The timeout duration is obtained.

-

Negative value

-

Failed to obtain the watchdog status.

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

Parameter

-

Description

-

handle

-

Watchdog handle.

-

Return Value

-

Description

-

0

-

The watchdog is started.

-

Negative value

-

Failed to start the watchdog.

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

Parameter

-

Description

-

handle

-

Watchdog handle.

-

Return Value

-

Description

-

0

-

The watchdog is fed.

-

Negative value

-

Failed to feed the watchdog.

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

Parameter

-

Description

-

handle

-

Watchdog handle.

-

Return Value

-

Description

-

0

-

The watchdog is stopped.

-

Negative value

-

Stopping the watchdog failed.

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

Parameter

-

Description

-

handle

-

Watchdog handle.

-
- -``` -/* Close the watchdog. */ -ret = WatchdogClose(handle); -``` - diff --git a/en/device-dev/driver/wlan.md b/en/device-dev/driver/wlan.md index d6d1fba4014eca409dc4a0d4ef645b1dc9cdffe3..5bc198f48d4a2166091ec2ff7fdfca40d0f26617 100644 --- a/en/device-dev/driver/wlan.md +++ b/en/device-dev/driver/wlan.md @@ -1,9 +1,622 @@ -# WLAN +# WLAN -- **[WLAN Overview](wlanoverview.md)** +- [Overview](#section729758162218) + - [WLAN Driver API Architecture](#section178022416377) + - [Available APIs](#section149681312202415) -- **[WLAN Development Guidelines](wlandevelopment-guidelines.md)** +- [Development Guidelines](#section15957746172412) + - [How to Develop](#section11776186132513) -- **[WLAN Development Example](wlandevelopment-example.md)** +- [Development Example](#section1395253612512) +## Overview + +The WLAN module is developed based on the Hardware Driver Foundation \(HDF\). It supports cross-OS migration, component adaptation, and modular assembly and compilation. Based on the unified APIs provided by the WLAN module, driver developers of WLAN vendors can adapt their driver code and are capable of creating, disabling, scanning, and connecting to WLAN hotspots. The WLAN driver provides the Hardware Driver Interface \(HDI\) layer with the capabilities of setting and obtaining the device MAC address and setting the transmit power. The following figure shows the framework of the [WLAN module](#fig967034316227): + +**Figure 1** WLAN framework + + +![](figures/en-us_image_0000001170383063.png) + +### WLAN Driver API Architecture + +The WLAN module provides the following three types of APIs: + +1. Capability APIs for the HDI layer + +2. Capability APIs directly invoked by drivers + +3. Capability APIs for vendors + +**Figure 2** Available APIs of the WLAN module + + +![](figures/接口分布图4.png) + +### Available APIs + +The WLAN driver module provides APIs that can be directly called by driver developers, such as creating/releasing a **WifiModule**, connecting to/disconnecting from a WLAN hotspot, applying for/releasing a **NetBuf**, and converting between the **pbuf** structure of Lightweight IP \(lwIP\) and a **NetBuf**. [Table 1](#table1521573319472) describes some APIs. + +**Table 1** APIs that can be directly called by driver developers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File

+

Function

+

Description

+

wifi_module.h

+

+

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

+

Creates a WifiModule.

+

void WifiModuleDelete(struct WifiModule *module);

+

Deletes a WifiModule and releases its data.

+

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

+

Deletes a feature from a WifiModule.

+

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

+

Adds a feature to a WifiModule.

+

wifi_mac80211_ops.h

+

int32_t (*startAp)(NetDevice *netDev);

+

Starts an AP.

+

int32_t (*stopAp)(NetDevice *netDev);

+

Stops an AP.

+

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

+

Connects to a hotspot.

+

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

+

Disconnects from a hotspot.

+

hdf_netbuf.h

+

static inline void NetBufQueueInit(struct NetBufQueue *q);

+

Initializes a NetBuf queue.

+

struct NetBuf *NetBufAlloc(uint32_t size);

+

Applies for a NetBuf.

+

void NetBufFree(struct NetBuf *nb);

+

Releases a NetBuf.

+

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

+

Converts the pbuf structure of lwIP to a NetBuf.

+

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

+

Converts a NetBuf to the pbuf structure of lwIP.

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

File

+

Function

+

Description

+

net_device.h

+

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

+

Initializes a NetDevice.

+

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

+

Obtains the state of a NetDevice.

+

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

+

Sets the MAC address.

+

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

+

Deinitializes a NetDevice.

+

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

+

Opens a NetDevice.

+

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

+

Stops a NetDevice.

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

Header File

+

Function

+

Description

+

wifi_hal.h

+

+

int32_t WifiConstruct(struct IWiFi **wifiInstance);

+

Creates an IWiFi object with basic capabilities.

+

int32_t WifiDestruct(struct IWiFi **wifiInstance);

+

Destroys an IWiFi object.

+

int32_t (*start)(struct IWiFi *);

+

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

+

int32_t (*stop)(struct IWiFi *);

+

Stops the channel between the HAL and the driver.

+

wifi_hal_base_feature.h

+

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

+

Obtains the feature type.

+

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

+

Sets the MAC address.

+

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

+

Obtains the device MAC address.

+

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

+

Sets the transmit power.

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

File

-

Function

-

Description

-

wifi_module.h

-

-

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

-

Creates a WifiModule.

-

void WifiModuleDelete(struct WifiModule *module);

-

Deletes and releases data of a WifiModule.

-

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

-

Deletes a feature from a WifiModule.

-

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

-

Adds a feature to a WifiModule.

-

wifi_mac80211_ops.h

-

int32_t (*startAp)(NetDevice *netDev);

-

Starts an AP.

-

int32_t (*stopAp)(NetDevice *netDev);

-

Stops an AP.

-

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

-

Connects to a hotspot.

-

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

-

Disconnects from a hotspot.

-

hdf_netbuf.h

-

static inline void NetBufQueueInit(struct NetBufQueue *q);

-

Initializes a NetBuf queue.

-

struct NetBuf *NetBufAlloc(uint32_t size);

-

Applies for a NetBuf.

-

void NetBufFree(struct NetBuf *nb);

-

Releases a NetBuf.

-

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

-

Converts the pbuf structure of lwIP to a NetBuf.

-

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

-

Converts a NetBuf to the pbuf structure of lwIP.

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

File

-

Function

-

Description

-

net_device.h

-

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

-

Initializes a NetDevice.

-

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

-

Obtains the state of a NetDevice.

-

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

-

Sets the MAC address.

-

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

-

Deinitializes a NetDevice.

-

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

-

Opens a NetDevice.

-

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

-

Stops a NetDevice.

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

Header File

-

Function

-

Description

-

wifi_hal.h

-

-

int32_t WifiConstruct(struct IWiFi **wifiInstance);

-

Creates an IWiFi object with basic capabilities.

-

int32_t WifiDestruct(struct IWiFi **wifiInstance);

-

Destroys an IWiFi object.

-

int32_t (*start)(struct IWiFi *);

-

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

-

int32_t (*stop)(struct IWiFi *);

-

Stops the channel between the HAL and the driver.

-

wifi_hal_base_feature.h

-

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

-

Obtains the feature type.

-

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

-

Sets the MAC address.

-

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

-

Obtains the device MAC address.

-

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

-

Sets the transmit power.

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

Docker Environment

+

System Type

+

Operating Platform

+

Docker Image Repository

+

Tag

+

Standalone Docker environment

+

Mini and small systems

+

Ubuntu or Windows

+

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

+

0.0.5

+

Standard system

+

Ubuntu

+

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

+

0.0.1

+

HPM-based Docker environment

+

Mini and small systems

+

Ubuntu or Windows

+

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

+

0.0.3

+
+ +## Preparations + +Before using the Docker environment, perform the following operations: + +1. Install Docker. For details, see [Install Docker Engine](https://docs.docker.com/engine/install/). +2. Obtain the OpenHarmony source code. For details, see [Source Code Acquisition](source-code-acquisition.md). + + >![](public_sys-resources/icon-note.gif) **NOTE:** + >You do not need to obtain the source code for the HPM-based Docker environment. + + +## Standalone Docker Environment + +The Docker image of OpenHarmony is hosted on [HUAWEI CLOUD SWR](https://console.huaweicloud.com/swr/?region=cn-south-1&locale=en-us#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage). Using the Docker image will help simplify environment configurations needed for the building. The following describes the detailed procedure. + +### Setting Up the Docker Environment for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) + +**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** + +1. Obtain the Docker image. + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + +2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + Run the following command in Ubuntu: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + Run the following command in Windows \(assuming that the source code directory is **D:\\OpenHarmony**\): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +**Method 2: Using the Dockerfile to Build a Local Docker Image** + +1. Obtain the Dockerfile script for a local Docker image. + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: + + ``` + cd docs/docker + ./build.sh + ``` + +3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + Run the following command in Ubuntu: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + Run the following command in Windows \(assuming that the source code directory is **D:\\OpenHarmony**\): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +### Building for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) + +The following uses the Hi3516 platform as an example to describe the build procedure. + +Set the build path to the current path. + +``` +hb set + . +``` + +**Figure 1** Setting page + + +![](figures/en-us_image_0000001101413884.png) + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The mapping between the development board and the building GUI: +>- Hi3861: wifiiot\_hispark\_pegasus@hisilicon +>- Hi3516: ipcamera\_hispark\_taurus@hisilicon +>- Hi3518: ipcamera\_hispark\_aries@hisilicon + +1. Select **ipcamera\_hispark\_taurus@hisilicon** and press **Enter**. +2. Start building. + + ``` + hb build -f + ``` + +3. View the build result. + + The files will be generated in the **out/hispark\_taurus/ipcamera\_hispark\_taurus** directory. + + +### Setting Up the Docker Environment for Standard-System Devices \(reference memory ≥ 128 MB\) + +**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** + +1. Obtain the Docker image. + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**Method 2: Using the Dockerfile to Build a Local Docker Image** + +1. Obtain the Dockerfile script for a local Docker image. + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +### Building for Standard-System Devices \(reference memory ≥ 128 MB\) + +1. Run the preprocessing script in the root directory of the source code. + + ``` + ../scripts/prepare.sh + ``` + +2. Run the following script to start building for standard-system devices \(reference memory ≥ 128 MB\). + + ``` + ./build.sh --product-name {product_name} + ``` + + **product\_name** indicates the platform supported by the current distribution, for example, Hi3516D V300. + + Files generated during building are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>You can exit Docker by simply running the **exit** command. + +## HPM-based Docker Environment + +**docker\_dist** is a template component in the [HPM](https://hpm.harmonyos.com/#/en/home) system. It helps to quickly initialize an HPM project and use the Docker image to quickly build a distribution of OpenHarmony, greatly simplifying environment configurations needed for building. After configuring the Ubuntu and [hpm-cli](https://device.harmonyos.com/en/docs/develop/bundles/oem_bundle_guide_prepare-0000001050129846) development environments, perform the following steps to access the Docker environment: + +### Setting Up the Docker Environment + +1. Initialize the installation template by running the following command in any of the working directories: + + ``` + hpm init -t @ohos/docker_dist + ``` + +2. Modify the **publishAs** field. + + The obtained bundle is of the template type. Open the **bundle.json** file in the current directory and change the value of **publishAs** from **template** to **distribution** as needed. + + +### Obtaining and Building Source Code + +Start building. Docker can be automatically installed only in Ubuntu. If you are using any other operating system, manually install Docker before pulling the image. + +- **Automatically Installing Docker \(Ubuntu\)** + + Running the following command will automatically install Docker, pull the Docker image, and start the pulling and building of the corresponding solution in the container. + + **Method 1:** + + Add a parameter to specify the solution. For example: + + ``` + hpm run docker solution={product} + ``` + + **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. + + **Method 2:** + + Set an environment variable to specify the solution, and then run the build command. + + 1. Select the desired solution. + + ``` + export solution={product} + ``` + + **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. + + 2. Obtain and build the source code. + + ``` + hpm run docker + ``` + + + This example uses the **@ohos/hispark\_taurus** solution for illustration. If the execution is successful, the output is as follows: + + ``` + ... + ohos ipcamera_hispark_taurus build success! + @ohos/hispark_taurus: distribution building completed. + ``` + + +- **Manually Installing Docker \(Non-Ubuntu\)** + + Perform the following operations to install Docker: + + ``` + # Pull the image. + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# Compile the Docker image in the Linux environment. + hpm run distWithDocker solution={product} + # When using Windows, make sure to configure the Git Bash. + hpm config set shellPath "Git Bash path" + hpm run distWithDocker solution={product} + ``` + + diff --git a/en/device-dev/get-code/figures/3.png b/en/device-dev/get-code/figures/3.png index c99cddf919e6f912aa19c43189f1fdbe895764ac..7936efcb1acc374be338d44d8d2911fa82f29076 100644 Binary files a/en/device-dev/get-code/figures/3.png and b/en/device-dev/get-code/figures/3.png differ diff --git a/en/device-dev/get-code/ide.md b/en/device-dev/get-code/ide.md new file mode 100644 index 0000000000000000000000000000000000000000..f3551de3126341e207afe450d509d8d37cc0979a --- /dev/null +++ b/en/device-dev/get-code/ide.md @@ -0,0 +1,17 @@ +# IDE + +- [Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\)](#section2452141120244) +- [Acquiring the Application Development Tool \(HUAWEI DevEco Studio\)](#section0904101019258) + +## Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\) + +HUAWEI DevEco Device Tool is a one-stop integrated development environment \(IDE\) provided to develop applications for OpenHarmony devices. It allows on-demand customization of OpenHarmony components, code editing, building, burning, and debugging, and supports C and C++ languages. This tool is installed in Visual Studio Code as a plug-in. For details, see [HUAWEI DevEco Device Tool](https://device.harmonyos.com/en/ide) and [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). + +The roadmap of Huawei DevEco Device Tool for supporting OpenHarmony device development is shown in the figure below. + +![](figures/3.png) + +## Acquiring the Application Development Tool \(HUAWEI DevEco Studio\) + +HUAWEI DevEco Studio \(DevEco Studio for short\) is a one-stop IDE oriented to Huawei devices in all scenarios. It provides E2E OpenHarmony application development services, ranging from project template creation to development, building, debugging, and release. With DevEco Studio, you will be able to efficiently develop OpenHarmony applications with distributed capabilities while speeding up innovation. For details, see [HUAWEI DevEco Studio](https://developer.harmonyos.com/en/develop/deveco-studio) and [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). + diff --git a/en/device-dev/get-code/source-code-acquisition.md b/en/device-dev/get-code/source-code-acquisition.md index f7a7c3f5c758bcac5d10c91de12a53e406205cfd..1646c8a96402bd54dd77a359cf3364a0a90bb8cb 100644 --- a/en/device-dev/get-code/source-code-acquisition.md +++ b/en/device-dev/get-code/source-code-acquisition.md @@ -26,11 +26,10 @@ The open-source code repositories are available at [https://openharmony.gitee.c ## Overview of Source Code Acquisition -This document describes how to acquire OpenHarmony source code and provides its directory structure. The OpenHarmony code is open to you as [bundles](../bundles/overview.md), which can be obtained in any of the following ways: +This document describes how to acquire OpenHarmony source code and provides its directory structure. The OpenHarmony code is open to you as [bundles](../bundles/development-specifications.md), which can be obtained in any of the following ways: - **Method 1**: Acquire the source code from a code repository. You can use the **repo** or **git** tool to download the latest code from the code repository. - **Method 2**: Obtain the source code from the HarmonyOS Package Manager \(HPM\). Visit the [HPM](https://hpm.harmonyos.com/#/en/home) website, search for your desired open-source distribution, and download the bundle list \(or customize bundles and download the bundle list\). Then use **hpm-cli** to download and install the bundles and compilation toolchain on your local PC. -- **Method 3**: Download the compressed file of a distribution from an image site. This method provides a fast download speed, so you can also use this method for obtaining the source code of an earlier version. ## Method 1: Acquiring Source Code from a Code Repository @@ -40,9 +39,9 @@ This document describes how to acquire OpenHarmony source code and provides its - You have interconnected your software with OpenHarmony and need official certification from OpenHarmony. -- You want to contribute code to the OpenHarmony community after chips, modules, and applications are certified by OpenHarmony. +- You want to contribute code to the OpenHarmony community after obtaining official OpenHarmony certification for chips, modules, and applications. -- You need to address OpenHarmony issues. +- You need to rectify OpenHarmony issues. - You want to learn OpenHarmony source code. @@ -62,7 +61,7 @@ This document describes how to acquire OpenHarmony source code and provides its 4. Run the following commands to install the **repo** tool: ``` - curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. chmod a+x /usr/local/bin/repo pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests ``` @@ -70,7 +69,7 @@ This document describes how to acquire OpenHarmony source code and provides its ### How to Use -**Obtaining the Source Code for Mini, Small, and Standard Systems \(2.0 Canary\)** +**Obtaining the Source Code for Mini/Small/Standard Systems \(2.0 Canary\)** >![](public_sys-resources/icon-note.gif) **NOTE:** >You can obtain the latest features from the master code, and develop commercial functionalities based on the release code, which is more stable. @@ -109,7 +108,7 @@ This document describes how to acquire OpenHarmony source code and provides its - Obtaining the source code of other OpenHarmony releases - For details about how to obtain the source code of other releases, see the [Release Notes](https://gitee.com/openharmony/docs/blob/master/en/release-notes/OpenHarmony-Release-Notes.md). + For details about how to obtain the source code of other OpenHarmony releases, see the [Release Notes](https://gitee.com/openharmony/docs/blob/master/en/release-notes/OpenHarmony-Release-Notes.md). ## Method 2: Acquiring Source Code from HPM @@ -197,7 +196,7 @@ You must install **Node.js** and HPM on your local PC. The installation proced To ensure the download performance, you are advised to download the source code or the corresponding solution from the image library of the respective site listed in the table below. >![](public_sys-resources/icon-note.gif) **NOTE:** ->- The table below provides only the sites for downloading the source code of the latest OpenHarmony Master and LTS versions. For details about earlier versions and how to obtain their source code, see the [Release Notes](https://gitee.com/openharmony/docs/tree/master/en/release-notes). +>- The table below provides only the sites for downloading the latest OpenHarmony master and LTS code. For details about how to obtain the source code of earlier versions, see the [Release Notes](https://gitee.com/openharmony/docs/tree/master/en/release-notes). >- The Master 1.0 version is no longer maintained. **Table 1** Sites for acquiring source code from image sites @@ -225,7 +224,7 @@ To ensure the download performance, you are advised to download the source code

1.1.1

-

Site

+

Download

Download

@@ -261,9 +260,9 @@ To ensure the download performance, you are advised to download the source code

Version Information

-

Site

+

Site

-

SHA-256 Verification Code

+

SHA-256 Verification Code

Full code (for standard systems)

@@ -324,7 +323,7 @@ To ensure the download performance, you are advised to download the source code

Version Information

-

Site

+

Site

SHA-256 Verification Code

@@ -333,7 +332,7 @@ To ensure the download performance, you are advised to download the source code

-

-

Site

+

Download

-

diff --git a/en/device-dev/get-code/tool-acquisition.md b/en/device-dev/get-code/tool-acquisition.md index ddfc607243ddd0682ed23b79e3f95d59ae1addc6..dd1797b10426918c0921386817fb51c1b9e83a3b 100644 --- a/en/device-dev/get-code/tool-acquisition.md +++ b/en/device-dev/get-code/tool-acquisition.md @@ -1,283 +1,7 @@ -# Tool Acquisition +# Tool Acquisition -- [How to Obtain the Docker Environment](#section107932281315) -- [HPM-based Docker](#section485713518337) - - [Setting Up the Docker Environment](#section18957202218355) - - [Building](#section69141039143518) +- **[Docker Environment](docker-environment.md)** -- [Standalone Docker Environment](#section2858536103611) - - [Setting Up the Docker Environment for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\)](#section319412277287) - - [Building for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\)](#section631485163615) - - [Setting Up the Docker Environment for Standard-System Devices \(reference memory ≥ 128 MB\)](#section13585262391) - - [Building for Standard-System Devices \(reference memory ≥ 128 MB\)](#section193711513406) +- **[IDE](ide.md)** -- [Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\)](#section2452141120244) -- [Acquiring the Application Development Tool \(HUAWEI DevEco Studio\)](#section0904101019258) - -## How to Obtain the Docker Environment - -OpenHarmony provides the following two types of Docker environments for you to quickly get the development environment ready: - -- HPM-based Docker environment: applicable when using the HarmonyOS Package Manager \(HPM\) to build a distribution. -- Standalone Docker environment: applicable when using Ubuntu or Windows to build a distribution. - - The following table lists container-based options needed for building in the standalone Docker environment. - - **Table 1** Docker image - - - - - - - - - - - - - - - - -

Docker Image Repository

-

Tag

-

Description

-

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

-

0.0.5

-

The OpenHarmony build environment has been pre-installed. This repository applies to Mini-System Devices (reference memory ≥ 128 KB) and Small-System Devices (reference memory ≥ 1 MB).

-

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

-

0.0.1

-

The OpenHarmony build environment has been pre-installed. This repository applies to Standard-System Devices (reference memory ≥ 128 MB).

-
- - >![](public_sys-resources/icon-note.gif) **NOTE:** - >For details about how to install Docker, see [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/). - - -## HPM-based Docker - -**docker\_dist** is a template component in the [HPM](https://hpm.harmonyos.com/#/en/home) system. It helps to quickly initialize an HPM project and use the Docker image to quickly build a distribution of OpenHarmony, greatly simplifying environment configurations needed for building. After configuring the Ubuntu and [hpm-cli](https://device.harmonyos.com/en/docs/develop/bundles/oem_bundle_guide_prepare-0000001050129846) development environments, perform the following steps to access the Docker environment: - -### Setting Up the Docker Environment - -1. Initialize the installation template by running the following command in any of the working directories: - - ``` - hpm init -t @ohos/docker_dist - ``` - -2. Modify the **publishAs** field. - - The obtained bundle is of the template type. Open the **bundle.json** file in the current directory and change the value of **publishAs** from **template** to **distribution** as needed. - - -### Building - -Start building. Docker can be automatically installed only on Ubuntu. If you are using any other operating system, manually install Docker before pulling the image. - -- **Automatically Installing Docker \(Ubuntu\)** - - Running the following command will automatically install Docker, pull the Docker image, and start the pulling and building of the corresponding solution in the container. - - Method 1: - - Add a parameter to specify the solution. For example: - - ``` - hpm run docker solution={product} - ``` - - **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. - - Method 2: - - Set an environment variable to specify the solution, and then run the build command. - - 1. Select the desired solution. - - ``` - export solution={product} - ``` - - **\{product\}** indicates the solution, for example, **@ohos/hispark\_taurus**, **@ohos/hispark\_aries**, and **@ohos/hispark\_pegasus**. - - 2. Start building. - - ``` - hpm run docker - ``` - - This example uses the **@ohos/hispark\_taurus** solution for illustration. If the execution is successful, the output is as follows: - - ``` - ... - ohos ipcamera_hispark_taurus build success! - @ohos/hispark_taurus: distribution building completed. - ``` - - -- **Manually Installing Docker \(Non-Ubuntu\)** - - Perform the following operations to install Docker: - - ``` - # Pull the image. - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# Compile the Docker image in the Linux environment. - hpm run distWithDocker solution={product} - # When using Windows, make sure to configure the Git Bash. - hpm config set shellPath "Git Bash path" - hpm run distWithDocker solution={product} - ``` - - -## Standalone Docker Environment - -The Docker image of OpenHarmony is hosted on [HUAWEI CLOUD SWR](https://console.huaweicloud.com/swr/?region=cn-south-1&locale=en-us#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage). Using the Docker image will help simplify environment configurations needed for the building. After configuring the development environments, perform the procedures below to access the Docker environment. Both Ubuntu and Windows are supported. The following procedures use Ubuntu as an example. - -### Setting Up the Docker Environment for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) - -**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** - -1. Obtain the Docker image. - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - -2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - - -**Method 2: Using the Dockerfile to Build a Local Docker Image** - -1. Obtain the Dockerfile script for a local Docker image. - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: - - ``` - cd docs/docker - ./build.sh - ``` - -3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony openharmony-docker:0.0.5 - ``` - - -### Building for Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) - -The following uses the Hi3516 platform as an example to describe the build procedure. Run the following build scripts to start building: - -Set the build path to the current path. - -``` -hb set - . -``` - -**Figure 1** Setting page - - -![](figures/en-us_image_0000001101413884.png) - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The mapping between the development board and the building GUI: ->- Hi3861: wifiiot\_hispark\_pegasus@hisilicon ->- Hi3516: ipcamera\_hispark\_taurus@hisilicon ->- Hi3518: ipcamera\_hispark\_aries@hisilicon - -1. Select **ipcamera\_hispark\_taurus@hisilicon** and press **Enter**. -2. Start building. - - ``` - hb build -f - ``` - -3. View the build result. - - The files will be generated in the **out/hispark\_taurus/ipcamera\_hispark\_taurus** directory. - - -### Setting Up the Docker Environment for Standard-System Devices \(reference memory ≥ 128 MB\) - -**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** - -1. Obtain the Docker image. - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - -2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - - -**Method 2: Using the Dockerfile to Build a Local Docker Image** - -1. Obtain the Dockerfile script for a local Docker image. - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: - - ``` - cd docs/docker/standard - ./build.sh - ``` - -3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: - - ``` - docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 - ``` - - -### Building for Standard-System Devices \(reference memory ≥ 128 MB\) - -1. Run the preprocessing script in the root directory of the source code. - - ``` - ../scripts/prepare.sh - ``` - -2. Run the following script to start building for Standard-System Devices \(reference memory ≥ 128 MB\). - - ``` - ./build.sh --product-name {product_name} - ``` - - **product\_name** indicates the platform supported by the current distribution, for example, Hi3516D V300. - - Files generated during compilation are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->You can exit Docker by simply running the **exit** command. - -## Acquiring the Device Development Tool \(HUAWEI DevEco Device Tool\) - -HUAWEI DevEco Device Tool is a one-stop integrated development environment \(IDE\) provided to develop applications for OpenHarmony-based smart devices. It allows on-demand customization of OpenHarmony components, code editing, compilation, burning, and debugging, and supports C and C++ languages. This tool is installed in Visual Studio Code as a plug-in. For details, see [Tool Acquisition](https://device.harmonyos.com/en/ide) and [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). - -The roadmap of Huawei DevEco Device Tool for supporting OpenHarmony device development is shown in the figure below. - -![](figures/3.png) - -## Acquiring the Application Development Tool \(HUAWEI DevEco Studio\) - -HUAWEI DevEco Studio \(DevEco Studio for short\) is a one-stop IDE oriented to Huawei devices in all scenarios. It provides E2E OpenHarmony application development services, ranging from project template creation to development, compilation, debugging, and release. With DevEco Studio, you will be able to efficiently develop OpenHarmony applications with distributed capabilities while speeding up innovation. For details, see [Tool Acquisition](https://developer.harmonyos.com/en/develop/deveco-studio) and [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). diff --git a/en/device-dev/guide/Readme-EN.md b/en/device-dev/guide/Readme-EN.md index 31bb3cfd5f930e15379766651d890690ab24f29c..66faa01846f2a827da6df370ecb98299781e7c6f 100644 --- a/en/device-dev/guide/Readme-EN.md +++ b/en/device-dev/guide/Readme-EN.md @@ -1,10 +1,10 @@ -# Development Examples +# Device Development - [WLAN-connected Products](wlan-connected-products.md) - - [LED Peripheral Control](led-peripheral-control.md) - - [Overview](overview.md) - - [Development](development.md) - - [Verification](verification.md) + - [Overview](overview.md) + - [Development](development.md) + - [Verification](verification.md) + - [Third-Party SDK Integration](third-party-sdk-integration.md) - [Cameras Without a Screen](cameras-without-a-screen.md) - [Camera Control](camera-control.md) @@ -41,15 +41,16 @@ - [How to Develop](how-to-develop.md) - [Signing and Packaging](signing-and-packaging.md) - [Running on the Device](running-on-the-device-9.md) + - [FAQs](faqs-10.md) - [Development Example for Platform Drivers](development-example-for-platform-drivers.md) - - [Overview](overview-10.md) - - [Preparations](preparations-11.md) - - [Development](development-12.md) + - [Overview](overview-11.md) + - [Preparations](preparations-12.md) + - [Development](development-13.md) - [Building and Burning](building-and-burning.md) - [Development Example for Peripheral Drivers](development-example-for-peripheral-drivers.md) - - [Overview](overview-13.md) + - [Overview](overview-14.md) - [Hardware Resources](hardware-resources.md) - [Input Driver Model](input-driver-model.md) @@ -59,7 +60,7 @@ - [Configuring the Touchscreen](configuring-the-touchscreen.md) - [Adapting to the Private Drivers of the Touchscreen](adapting-to-the-private-drivers-of-the-touchscreen.md) - - [Building and Burning](building-and-burning-14.md) + - [Building and Burning](building-and-burning-15.md) - [Debugging and Verification](debugging-and-verification.md) - [Startup Log Analysis](startup-log-analysis.md) diff --git a/en/device-dev/guide/building-and-burning-14.md b/en/device-dev/guide/building-and-burning-15.md similarity index 100% rename from en/device-dev/guide/building-and-burning-14.md rename to en/device-dev/guide/building-and-burning-15.md diff --git a/en/device-dev/guide/debugging-and-packaging.md b/en/device-dev/guide/debugging-and-packaging.md index 97df7e21ab4e36ac3420ba1494bf8452fa5f226e..2d4c192fb9c4948b510b6f0ad85d9e50f0a50a03 100644 --- a/en/device-dev/guide/debugging-and-packaging.md +++ b/en/device-dev/guide/debugging-and-packaging.md @@ -1,4 +1,4 @@ # Debugging and Packaging -After the code is compiled, debug your application and package it into an App Pack. For details about how to debug and package an application, see [Debugging Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/debug_overview-0000001053822404) and [Building Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/build_overview-0000001055075201) in the [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). Currently, IPCamera applications do not support signature. You should release an unsigned App Pack. +After the code is compiled, debug your application and package it into an App Pack. For details about how to debug and package an application, see [Debugging Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ide_debug_device-0000001053822404) and [Building Your App](https://developer.harmonyos.com/en/docs/documentation/doc-guides/build_overview-0000001055075201) in the [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). Currently, IPCamera applications do not support signature. You should release an unsigned App Pack. diff --git a/en/device-dev/guide/development-12.md b/en/device-dev/guide/development-13.md similarity index 100% rename from en/device-dev/guide/development-12.md rename to en/device-dev/guide/development-13.md diff --git a/en/device-dev/guide/development-example-for-peripheral-drivers.md b/en/device-dev/guide/development-example-for-peripheral-drivers.md index 4333c26e067bd1ce6981ef3e0a558e5f03578822..4cf054e30c54e1a78a75d0710c20dd5357d73547 100644 --- a/en/device-dev/guide/development-example-for-peripheral-drivers.md +++ b/en/device-dev/guide/development-example-for-peripheral-drivers.md @@ -1,12 +1,12 @@ # Development Example for Peripheral Drivers -- **[Overview](overview-13.md)** +- **[Overview](overview-14.md)** - **[Setting Up the Environment](setting-up-the-environment.md)** - **[Developing a Touchscreen Driver](developing-a-touchscreen-driver.md)** -- **[Building and Burning](building-and-burning-14.md)** +- **[Building and Burning](building-and-burning-15.md)** - **[Debugging and Verification](debugging-and-verification.md)** diff --git a/en/device-dev/guide/development-example-for-platform-drivers.md b/en/device-dev/guide/development-example-for-platform-drivers.md index fbb47fb7d32d8b300c97f77d4f5fff0f1d616501..7e35c4dbfcf093c1d26247e6240c4b89ab144b49 100644 --- a/en/device-dev/guide/development-example-for-platform-drivers.md +++ b/en/device-dev/guide/development-example-for-platform-drivers.md @@ -1,10 +1,10 @@ # Development Example for Platform Drivers -- **[Overview](overview-10.md)** +- **[Overview](overview-11.md)** -- **[Preparations](preparations-11.md)** +- **[Preparations](preparations-12.md)** -- **[Development](development-12.md)** +- **[Development](development-13.md)** - **[Building and Burning](building-and-burning.md)** diff --git a/en/device-dev/guide/input-driver-model.md b/en/device-dev/guide/input-driver-model.md index a4f2cdb3720235bcf0fd941caf6ae05c68792bd8..dc90f115f3a774274b52f9199fc6af2e5f005fd9 100644 --- a/en/device-dev/guide/input-driver-model.md +++ b/en/device-dev/guide/input-driver-model.md @@ -8,5 +8,5 @@ The input driver model mainly consists of the device manager, common drivers, an In addition, the input driver model implements functions for reporting input data and parsing input device configurations. -For details about the input driver model, see [Touchscreen Overview](https://device.harmonyos.com/en/docs/develop/drive/oem_drive_touch_des-0000001052857350)[Touchscreen Overview](../driver/touchscreenoverview.md). +For details about the input driver model, see [Touchscreen Overview](../driver/touchscreen.md). diff --git a/en/device-dev/guide/led-peripheral-control.md b/en/device-dev/guide/led-peripheral-control.md deleted file mode 100644 index abe05cea370b4b7743e120ce2207aa54834de1b1..0000000000000000000000000000000000000000 --- a/en/device-dev/guide/led-peripheral-control.md +++ /dev/null @@ -1,9 +0,0 @@ -# LED Peripheral Control - -- **[Overview](overview.md)** - -- **[Development](development.md)** - -- **[Verification](verification.md)** - - diff --git a/en/device-dev/guide/overview-10.md b/en/device-dev/guide/overview-11.md similarity index 100% rename from en/device-dev/guide/overview-10.md rename to en/device-dev/guide/overview-11.md diff --git a/en/device-dev/guide/overview-13.md b/en/device-dev/guide/overview-14.md similarity index 100% rename from en/device-dev/guide/overview-13.md rename to en/device-dev/guide/overview-14.md diff --git a/en/device-dev/guide/photographing-3.md b/en/device-dev/guide/photographing-3.md index 7d6450e761f1a0d4823c683ae95546de5a0a18fb..eda733f15340836efaf5e6d25417821836bc333d 100644 --- a/en/device-dev/guide/photographing-3.md +++ b/en/device-dev/guide/photographing-3.md @@ -385,6 +385,7 @@ None Surface *surface = Surface::CreateSurface(); if (surface == nullptr) { delete fc; + return; } surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ fc->AddSurface(*surface); diff --git a/en/device-dev/guide/photographing.md b/en/device-dev/guide/photographing.md index a1617550bfbd2352e3bb1fc4739d93ed25f8fb78..a8da63373f6c284ee608836d504e38e5ee7c1569 100644 --- a/en/device-dev/guide/photographing.md +++ b/en/device-dev/guide/photographing.md @@ -385,6 +385,7 @@ None Surface *surface = Surface::CreateSurface(); if (surface == nullptr) { delete fc; + return; } surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ fc->AddSurface(*surface); diff --git a/en/device-dev/guide/preparations-11.md b/en/device-dev/guide/preparations-12.md similarity index 100% rename from en/device-dev/guide/preparations-11.md rename to en/device-dev/guide/preparations-12.md diff --git a/en/device-dev/guide/running-on-the-device-9.md b/en/device-dev/guide/running-on-the-device-9.md index b97c20b8a10a83bdcd1c7216a5d231212abb341d..24ee3034d3955b33096ed0bd1c53970e2ff6b4c0 100644 --- a/en/device-dev/guide/running-on-the-device-9.md +++ b/en/device-dev/guide/running-on-the-device-9.md @@ -1,6 +1,6 @@ # Running on the Device -Before you install the app and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). Burn OpenHarmony into the development board, and run it on the board. For details about how to build, burn, and run an image, see [Getting Started with Hi3516](../quick-start/how-to-develop-12.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the app: +Before you install the app and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/tool_install-0000001050164976). Burn OpenHarmony into the development board, and run it on the board. For details about how to build, burn, and run an image, see [Getting Started with Hi3516](../quick-start/standard-system.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the app: 1. Obtain the HDC client from the following path: diff --git a/en/device-dev/guide/running-on-the-device.md b/en/device-dev/guide/running-on-the-device.md index 79167a2934ce10c5e799b2c59d09830ac68e7ac4..91094bd0cdac0db24108e37a958efd8e5e7b5643 100644 --- a/en/device-dev/guide/running-on-the-device.md +++ b/en/device-dev/guide/running-on-the-device.md @@ -1,8 +1,8 @@ # Running on the Device -Before you install the application and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/tool_install-0000001050164976). Burn OpenHarmony into the development board, and run it on the board. For details about how to compile, burn, and run an image, see the [Getting Started with Hi3516](../quick-start/hi3516-development-board.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the application: +Before you install the application and run it on the development board, install the DevEco Device Tool by following operations provided in [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). Burn OpenHarmony into the development board, and run it on the board. For details about how to compile, burn, and run an image, see the [Hi3516 Development Board](../quick-start/hi3516-development-board.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the application: -1. Store the compiled unsigned application installation package and installation tool in an SD card and insert the SD card into the development board slot. The installation tool is in **idev\_tools** of the directory where the image file is generated. +1. Store the compiled unsigned application installation package and installation tool in an SD card and insert the SD card into the development board slot. The installation tool is in **dev\_tools** of the directory where the image file is generated. 2. Run the following command to disable signature verification, which is enabled by default for application installation: ``` diff --git a/en/device-dev/guide/use-case-5.md b/en/device-dev/guide/use-case-5.md index f4e481e1cef8c4815def24a9aa9c604df9b01680..588b3b8addbefced4208d220eeac28dfe9f6af6a 100644 --- a/en/device-dev/guide/use-case-5.md +++ b/en/device-dev/guide/use-case-5.md @@ -3,7 +3,7 @@ This use case takes **camera\_sample** \(contained in the source code\) as an example for photographing, recording, and previewing on the development board. - You can obtain source code of the sample from **applications/sample/camera/media/camera\_sample.cpp**. -- Before running the sample camera, you need to compile, burn, and run the image. For details, see [Getting Started with Hi3516](../quick-start/hi3516-development-board.md). +- Before running the sample camera, you need to compile, burn, and run the image. For details, see [Hi3516 Development Board](../quick-start/hi3516-development-board.md). >![](public_sys-resources/icon-note.gif) **NOTE:** >After the development board is started, the home screen is loaded and displayed above the media layer by default. To prevent covering **camera\_sample**, you should remove the home screen during compilation or packaging. diff --git a/en/device-dev/guide/use-case.md b/en/device-dev/guide/use-case.md index 274e2d375df15cf35285544f1c48c37f6b8e3c94..0847510fb3ad77af238ced704cc3ec071cadd0f7 100644 --- a/en/device-dev/guide/use-case.md +++ b/en/device-dev/guide/use-case.md @@ -1,6 +1,6 @@ # Use Case -- For details about the development board, compilation, burning, and image running, see [Getting Started with Hi3518](../quick-start/hi3518-development-board.md). A compilation result file of sample code is stored in **out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample**. You can copy the file to a TF card, or modify the compilation script of **camera\_sample** to copy the result to **rootfs.img**. +- For details about the development board, compilation, burning, and image running, see [Hi3518 Development Board](../quick-start/hi3518-development-board.md). A compilation result file of sample code is stored in **out/ipcamera\_hi3518ev300/dev\_tools/bin/camera\_sample**. You can copy the file to a TF card, or modify the compilation script of **camera\_sample** to copy the result to **rootfs.img**. Modify **output\_dir** in **applications/sample/camera/media/BUILD.gn**. diff --git a/en/device-dev/guide/wlan-connected-products.md b/en/device-dev/guide/wlan-connected-products.md index 184f46eb0e144c6d086c2b35264557825fe5bb8e..b06843d5c1aabd428f24e5e9299f41388b776531 100644 --- a/en/device-dev/guide/wlan-connected-products.md +++ b/en/device-dev/guide/wlan-connected-products.md @@ -1,5 +1,11 @@ # WLAN-connected Products -- **[LED Peripheral Control](led-peripheral-control.md)** +- **[Overview](overview.md)** + +- **[Development](development.md)** + +- **[Verification](verification.md)** + +- **[Third-Party SDK Integration](third-party-sdk-integration.md)** diff --git a/en/device-dev/kernel/Readme-EN.md b/en/device-dev/kernel/Readme-EN.md index 2ec9f17abde6255b6bfb7b20df50fac5357972ea..632db9a594c4addf991b9b8e2c20ee1e46ff8020 100644 --- a/en/device-dev/kernel/Readme-EN.md +++ b/en/device-dev/kernel/Readme-EN.md @@ -1,7 +1,7 @@ # Kernel -- [Lite Kernel](lite-kernel.md) - - [OpenHarmony Lite Kernel Basic Functions](openharmony-lite-kernel-basic-functions.md) +- [Kernel for Mini and Small Systems](kernel-for-mini-and-small-systems.md) + - [Basic Kernel](basic-kernel.md) - [Process](process.md) - [Thread](thread.md) - [Memory](memory.md) @@ -86,7 +86,7 @@ - [Magic Key Usage](magic-key-usage.md) - [User-Space Exception Information](user-space-exception-information.md) -- [Linux Kernel](linux-kernel.md) +- [Kernel for Standard Systems](kernel-for-standard-systems.md) - [Linux Kernel Overview](linux-kernel-overview.md) - [Guidelines for Using Patches on OpenHarmony Development Boards](guidelines-for-using-patches-on-openharmony-development-boards.md) - [Guidelines for Compiling and Building the Linux Kernel](guidelines-for-compiling-and-building-the-linux-kernel.md) diff --git a/en/device-dev/kernel/openharmony-lite-kernel-basic-functions.md b/en/device-dev/kernel/basic-kernel.md similarity index 60% rename from en/device-dev/kernel/openharmony-lite-kernel-basic-functions.md rename to en/device-dev/kernel/basic-kernel.md index 8e3d07b35fb20071a4799e33f88480253820194f..ba8c2da4bd4e435d1e9f789d7ac33526d90d0fe4 100644 --- a/en/device-dev/kernel/openharmony-lite-kernel-basic-functions.md +++ b/en/device-dev/kernel/basic-kernel.md @@ -1,4 +1,4 @@ -# OpenHarmony Lite Kernel Basic Functions +# Basic Kernel - **[Process](process.md)** diff --git a/en/device-dev/kernel/lite-kernel.md b/en/device-dev/kernel/kernel-for-mini-and-small-systems.md similarity index 55% rename from en/device-dev/kernel/lite-kernel.md rename to en/device-dev/kernel/kernel-for-mini-and-small-systems.md index 3927b0fb506a8a301ca2b168f58e99170365406a..5f89928742c258eef81bcaad2de9772be208f4ef 100644 --- a/en/device-dev/kernel/lite-kernel.md +++ b/en/device-dev/kernel/kernel-for-mini-and-small-systems.md @@ -1,6 +1,6 @@ -# Lite Kernel +# Kernel for Mini and Small Systems -- **[OpenHarmony Lite Kernel Basic Functions](openharmony-lite-kernel-basic-functions.md)** +- **[Basic Kernel](basic-kernel.md)** - **[OpenHarmony Lite Kernel File System](openharmony-lite-kernel-file-system.md)** diff --git a/en/device-dev/kernel/linux-kernel.md b/en/device-dev/kernel/kernel-for-standard-systems.md similarity index 82% rename from en/device-dev/kernel/linux-kernel.md rename to en/device-dev/kernel/kernel-for-standard-systems.md index 9391b466f5f056bda10b6cff24a0142cce6fef51..8d387b3cc01fdbce5d256b3f0cfdee160224a696 100644 --- a/en/device-dev/kernel/linux-kernel.md +++ b/en/device-dev/kernel/kernel-for-standard-systems.md @@ -1,4 +1,4 @@ -# Linux Kernel +# Kernel for Standard Systems - **[Linux Kernel Overview](linux-kernel-overview.md)** diff --git a/en/device-dev/quick-start/overview.md b/en/device-dev/overview.md similarity index 81% rename from en/device-dev/quick-start/overview.md rename to en/device-dev/overview.md index 63cb2b8be145243d7324f5d29d28b303cad6d6aa..4a5832db5a9e81baccd6d4cbb4bf500c0f5a06a3 100644 --- a/en/device-dev/quick-start/overview.md +++ b/en/device-dev/overview.md @@ -30,6 +30,9 @@ In addition, OpenHarmony provides a series of optional system components that ca ## Document Outline +- [Mini and Small System Development Guidelines](#table3762949121211) +- [Standard System Development Guidelines](#table17667535516) + **Table 1** Mini and small system development guidelines \(reference memory < 128 MB\) @@ -45,49 +48,49 @@ In addition, OpenHarmony provides a series of optional system components that ca

Getting familiar with OpenHarmony

- +

Development resources

Preparing for your development

- +

Quick start

Getting started with setup, build, burning, debugging, and running of OpenHarmony

-

Getting Started for Mini and Small Systems

+

Getting Started for Mini and Small Systems

Basic capabilities

Using basic capabilities of OpenHarmony

- +

Advanced development

Developing smart devices based on system capabilities

- +

Porting and adaptation

  • Porting and adapting the OpenHarmony to an SoC
  • Porting and adapting the OpenHarmony to a third-party library
- +

Contributing components

Contributing components to OpenHarmony

- +

Reference

@@ -111,53 +114,53 @@ In addition, OpenHarmony provides a series of optional system components that ca -

About OpenHarmony

+

About OpenHarmony

-

Getting familiar with OpenHarmony

+

Getting familiar with OpenHarmony

- +

Development resources

Preparing for your development

- +

Quick start

Getting started with setup, build, burning, debugging, and running of OpenHarmony

-

Getting Started for Standard System

+

Getting Started for Standard System

Basic capabilities

-

Using basic capabilities of OpenHarmony

+

Using basic capabilities of OpenHarmony

- +

Advanced development

Developing smart devices based on system capabilities

- +

Porting and adaptation

Porting and adapting the OpenHarmony to a third-party library

-

Third-Party Library Porting Guide

+

Third-Party Library Porting Guide

Contributing components

-

Contributing components to OpenHarmony

+

Contributing components to OpenHarmony

- +

Reference

diff --git a/en/device-dev/porting/Readme-EN.md b/en/device-dev/porting/Readme-EN.md index b4f760b020e0cd05bae29470c24a27d49696bb63..19358865944306c284b052025edf7ff622ab9baa 100644 --- a/en/device-dev/porting/Readme-EN.md +++ b/en/device-dev/porting/Readme-EN.md @@ -1,4 +1,4 @@ -# Porting Guide +# Third-Party Library Porting Guide - [Third-Party Library Porting Guide](third-party-library-porting-guide.md) - [Overview](overview.md) diff --git a/en/device-dev/porting/porting-a-library-built-using-cmake.md b/en/device-dev/porting/porting-a-library-built-using-cmake.md index a7d399c983a5841878aa59c6c4bd01dec39d4135..14cf6c7028e991bb73c0ae2a381d5ab49635ec6f 100644 --- a/en/device-dev/porting/porting-a-library-built-using-cmake.md +++ b/en/device-dev/porting/porting-a-library-built-using-cmake.md @@ -227,7 +227,7 @@ The following steps show how to configure and modify the toolchains for cross-co 1. Set up the OpenHarmony environment. - Using Hi3518EV300 as an example, compile the OpenHarmony image and burn it to the development board. For details, see [Developing the First Example Program Running on Hi3518](https://gitee.com/openharmony/docs/blob/master/docs-en/quick-start/developing-the-first-example-program-running-on-hi3518.md). + Using Hi3518EV300 as an example, compile the OpenHarmony image and burn it to the development board. For details, see [Developing the First Example Program Running on Hi3518](https://device.harmonyos.com/en/docs/start/introduce/oem_development_ex_3518-0000001105528572). The following screen is displayed after a successful login to the OS. @@ -306,7 +306,7 @@ The following steps show how to configure and modify the toolchains for cross-co

GN file for adding the third-party library to the OpenHarmony project

-

openHarmony/third_party/double-conversion/build_thirdpaty.py

+

openHarmony/third_party/double-conversion/build_thirdparty.py

Script file for GN to call the shell command to convert compilation from GN to CMake.

diff --git a/en/device-dev/porting/system-modules.md b/en/device-dev/porting/system-modules.md index 686ea0751d80679d063a624cf1eceb04c415fbd0..3484579267a00f1c2576bde63501efc60fc72d5f 100644 --- a/en/device-dev/porting/system-modules.md +++ b/en/device-dev/porting/system-modules.md @@ -22,5 +22,5 @@ For details about how to use SAMGR, see [samgr\_lite](https://gitee.com/openhar The design for X \(DFX\) subsystem mainly includes design for reliability \(DFR\) and design for testability \(DFT\), providing code maintenance and testing. -For details, see [dfx](../subsystems/dfx.md). +For details, see **[DFX](../subsystems/DFX.md)**. diff --git a/en/device-dev/quick-start/Readme-EN.md b/en/device-dev/quick-start/Readme-EN.md index 4aab1f04bc1ebcfdf3856df5a8f7b02d9cf26265..8dc877bf65ca566b3ec191ba5f5d332c2d13a58d 100644 --- a/en/device-dev/quick-start/Readme-EN.md +++ b/en/device-dev/quick-start/Readme-EN.md @@ -1,6 +1,5 @@ # Getting Started -- [Overview](overview.md) - [Mini and Small Systems](mini-and-small-systems.md) - [Overview](overview-0.md) - [Introduction to the Development Boards](introduction-to-the-development-boards.md) @@ -33,12 +32,10 @@ - [FAQs](faqs-6.md) - [Standard System](standard-system.md) - - [Overview](overview-7.md) - - [Environment Setup](environment-setup-8.md) - - [Overview](overview-9.md) - - [Windows Development Environment](windows-development-environment-10.md) - - [Preparing the Ubuntu Build Environment](preparing-the-ubuntu-build-environment.md) - - [FAQs](faqs-11.md) - - - [How to Develop](how-to-develop-12.md) + - [Introduction](introduction.md) + - [Setting Up Windows Development Environment](setting-up-windows-development-environment.md) + - [Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code](setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md) + - [Setting Up Ubuntu Development Environment with Installation Package and Building Source Code](setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md) + - [Burning Images](burning-images.md) + - [FAQs](faqs-7.md) diff --git a/en/device-dev/quick-start/burning-images.md b/en/device-dev/quick-start/burning-images.md new file mode 100644 index 0000000000000000000000000000000000000000..b63966d94334be8ec473b7d641fb4f36c33b8866 --- /dev/null +++ b/en/device-dev/quick-start/burning-images.md @@ -0,0 +1,205 @@ +# Burning Images + +- [Next](#section5600113114323) + +Programming flash memory of a regular system requires DevEco Device Tool v2.2 Beta1 or later. + +The Hi3516DV300 of the Hi3516 series development boards supports programming flash memory of a regular system through the USB port, network port, or serial port, where: + +- **Windows system: Supports programming through the USB port, serial port, or network port** +- **Linux system: Supports programming through the serial port or network port \(Linux+Windows dual system: Also supports programming through the USB port\)** + +Except for environment setup, the operations of programming are the same for Windows and Linux. + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>Currently, the Hi3516D V300 development board supports system burning over the network port, USB port, or serial port. This document uses the network port as an example. For details about system burning over other ports, see [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681). + +### Prerequisites + +[Open a project](https://device.harmonyos.com/en/docs/ide/user-guides/open_project-0000001071680043) in DevEco Device Tool and select the folder where the file to be programmed is located. Select **Hi3516DV300** for the development board type and **Hb** for **Framework**. + +### Programming Flash Memory Through the Network Port + +The Hi3516DV300 supports programming through the network port in Windows or Linux. + +1. Connect the PC and the target development board through the power port, serial port, and network port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_camera_start_3516-0000001052670587). +2. Open Device Manager, then check and record the serial port number corresponding to the development board. + + >![](public_sys-resources/icon-note.gif) **NOTE:** + >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). + + ![](figures/en-us_image_0000001114129428.png) + +3. Open DevEco Device Tool and go to **Projects** \> **Settings**. + + ![](figures/2021-01-27_170334-18.png) + +4. On the **Partition Configuration** tab page, enter the information about the files to be programmed, including the following. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Binary

+

Memory

+

System

+

Address

+

Length

+

Board

+

Type

+

fastboot

+

Select u-boot-hi3516dv300_emmc.bin.

+

emmc

+

none

+

0x000000

+

0x100000

+

Select hi3516dv300.

+

NA

+

boot

+

Select uImage.

+

emmc

+

none

+

0x100000

+

0xf00000

+

NA

+

updater

+

Select updater.img.

+

emmc

+

ext3/4

+

0x1000000

+

0x1400000

+

NA

+

misc

+

Leave it blank.

+

emmc

+

none

+

0x2400000

+

0x100000

+

NA

+

system

+

Select system.img.

+

emmc

+

ext3/4

+

0x2500000

+

0xceb00000

+

NA

+

vendor

+

Select vendor.img.

+

emmc

+

ext3/4

+

0xd1000000

+

0x10000000

+

NA

+

userdata

+

Select userdata.img.

+

emmc

+

ext3/4

+

0xe1000000

+

0x5b800000

+

NA

+
+ + ![](figures/en-us_image_0000001160527611.png) + +5. On the **hi3516dv300** tab page, configure the programming options. + + - **upload\_port**: Select the serial port number obtained in step [2](#en-us_topic_0000001056443961_li1050616379507). + - **upload\_protocol**: Select the programming protocol **hiburn-net**. + - **upload\_partitions**: Select the file to be programmed, including the following: fastboot, boot, updater, misc, system, vendor, and userdata. + + ![](figures/en-us_image_0000001117621400.png) + +6. Check and set the IP address of the network adapter connected to the development board. For details, see [Setting the IP Address of the Network Port for Programming on Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/set_ipaddress-0000001141825075). +7. Set the IP address of the network port for programming: + + - **upload\_net\_server\_ip**: Select the IP address set in [6](en-us_topic_0000001056443961.md#li1558813168234), such as 192.168.1.2. + - **upload\_net\_client\_mask**: Set the subnet mask of the development board, such as 255.255.255.0. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. + - **upload\_net\_client\_gw**: Set the gateway of the development board, such as 192.168.1.1. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. + - **upload\_net\_client\_ip**: Set the IP address of the development board, such as 192.168.1.3. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. + + ![](figures/en-us_image_0000001117463460.png) + +8. When you finish modifying, click **Save** in the upper right corner. +9. Open the project file, go to ![](figures/2021-01-27_170334-19.png) \> **PROJECT TASKS** \> **fastboot** \> **Erase** to erase U-boot. + + ![](figures/en-us_image_0000001163045527.png) + +10. When the following message is displayed, power off the development board and then power it on. + + ![](figures/en-us_image_0000001114129432.png) + +11. Start programming. When the following message is displayed, it indicates that the programming is successful. + + ![](figures/en-us_image_0000001113969542.png) + + +## Next + +Congratulations! You have completed the quick start for the standard system. Get yourself familiar with OpenHarmony by a [Development Example for Clock App](../guide/development-example-for-clock-apps.md). + diff --git a/en/device-dev/quick-start/developing-a-driver.md b/en/device-dev/quick-start/developing-a-driver.md index ab35222428df5f2d3c2b909f178486c45c4c9e40..6c57fde80bf1f8b93cd500152bcc0999fd4faa77 100644 --- a/en/device-dev/quick-start/developing-a-driver.md +++ b/en/device-dev/quick-start/developing-a-driver.md @@ -1,4 +1,4 @@ -# Developing a Driver +# Developing a Driver - [Introduction to Driver](#s8efc1952ebfe4d1ea717182e108c29bb) - [Compiling and Burning](#section660016185110) @@ -439,7 +439,7 @@ Compile and burn images by referring to [Building](../quick-start/running-a-hel 1. Click **Monitor** to enable the serial port. 2. Press **Enter** repeatedly until **hisilicon** displays. - 3. Go to step [2](running-a-hello-ohos-program.md#l5b42e79a33ea4d35982b78a22913b0b1) if the board is started for the first time or the startup parameters need to be modified; go to step [3](running-a-hello-ohos-program.md#ld26f18828aa44c36bfa36be150e60e49) otherwise. + 3. Go to step [2](running-a-hello-ohos-program.md#en-us_topic_0000001151888681_l5b42e79a33ea4d35982b78a22913b0b1) if the board is started for the first time or the startup parameters need to be modified; go to step [3](running-a-hello-ohos-program.md#en-us_topic_0000001151888681_ld26f18828aa44c36bfa36be150e60e49) otherwise. 2. \(Mandatory when the board is started for the first time\) Modify the bootcmd and bootargs parameters of U-boot. You need to perform this step only once if the parameters need not to be modified during the operation. The board automatically starts after it is reset. diff --git a/en/device-dev/quick-start/environment-setup-7.md b/en/device-dev/quick-start/environment-setup-7.md deleted file mode 100644 index ef15df388b11feb122f95d983f3232819c631f78..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/environment-setup-7.md +++ /dev/null @@ -1,11 +0,0 @@ -# Environment Setup - -- **[Overview](overview-8.md)** - -- **[Windows Development Environment](windows-development-environment-9.md)** - -- **[Ubuntu Build Environment](ubuntu-build-environment-10.md)** - -- **[FAQs](faqs-11.md)** - - diff --git a/en/device-dev/quick-start/environment-setup-8.md b/en/device-dev/quick-start/environment-setup-8.md deleted file mode 100644 index 2428c3c9e47baa0d290309f02302c9b49a9336fd..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/environment-setup-8.md +++ /dev/null @@ -1,11 +0,0 @@ -# Environment Setup - -- **[Overview](overview-9.md)** - -- **[Windows Development Environment](windows-development-environment-10.md)** - -- **[Preparing the Ubuntu Build Environment](preparing-the-ubuntu-build-environment.md)** - -- **[FAQs](faqs-11.md)** - - diff --git a/en/device-dev/quick-start/environment-setup.md b/en/device-dev/quick-start/environment-setup.md index d1b7756c427d8503df33e4091497f2a54abf3a79..289f31965d0c38aea69d9ff15c917b6df62d8019 100644 --- a/en/device-dev/quick-start/environment-setup.md +++ b/en/device-dev/quick-start/environment-setup.md @@ -1,4 +1,4 @@ -# Environment Setup +# Environment Setup - **[Overview](overview-1.md)** diff --git a/en/device-dev/quick-start/faq.md b/en/device-dev/quick-start/faq.md index b1c6da1ec2a9aa32b80bc52b228db109730b05df..b1ed6400050ae7938c1873878e305e8779acac1f 100644 --- a/en/device-dev/quick-start/faq.md +++ b/en/device-dev/quick-start/faq.md @@ -1,4 +1,4 @@ -# FAQ +# FAQ - [What should I do if garbled characters and segmentation faults occur during hb installation?](#section411894616119) - [What should I do if the message "cannot import 'sysconfig' from 'distutils'" is displayed during hb installation?](#section629417571626) diff --git a/en/device-dev/quick-start/faqs-2.md b/en/device-dev/quick-start/faqs-2.md deleted file mode 100644 index d85c04678ebb9340c0f9a240f9a143642177d280..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/faqs-2.md +++ /dev/null @@ -1,172 +0,0 @@ -# FAQs - -- [What should I do when the images failed to be burnt over the selected serial port?](#section627268185113) -- [What should I do when Windows-based PC failed to be connected to the board?](#section195391036568) -- [What should I do when the image failed to be burnt?](#section571164016565) -- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#section1039835245619) -- [What should I do when no command output is displayed?](#section14871149155911) - -## What should I do when the images failed to be burnt over the selected serial port? - -- **Symptom** - - **Error: Opening COMxx: Access denied** is displayed after clicking **Burn** and selecting a serial port. - - **Figure 1** Failed to open the serial port - ![](figures/failed-to-open-the-serial-port.png "failed-to-open-the-serial-port") - -- **Possible Causes** - - The serial port has been used. - -- **Solutions** - -1. Search for the terminal using serial-xx from the drop-down list in the **TERMINAL** panel. - - **Figure 2** Checking whether the serial port is used - ![](figures/checking-whether-the-serial-port-is-used.png "checking-whether-the-serial-port-is-used") - -2. Click the dustbin icon as shown in the following figure to disable the terminal using the serial port. - - **Figure 3** Disabling the terminal using the serial port - ![](figures/disabling-the-terminal-using-the-serial-port.png "disabling-the-terminal-using-the-serial-port") - -3. Click **Burn**, select the serial port, and start burning images again. - - **Figure 4** Restarting burning - - - ![](figures/changjian1.png) - - -## What should I do when Windows-based PC failed to be connected to the board? - -- **Symptom** - - The file image cannot be obtained after clicking **Burn** and selecting a serial port. - - **Figure 5** Failed to obtain the image file due to unavailable connection - ![](figures/failed-to-obtain-the-image-file-due-to-unavailable-connection.png "failed-to-obtain-the-image-file-due-to-unavailable-connection") - -- **Possible Causes** - - The board is disconnected from the Windows-based PC. - - Windows Firewall does not allow Visual Studio Code to access the network. - -- **Solutions** - -1. Check whether the network cable is properly connected. -2. Click **Windows Firewall**. - - **Figure 6** Network and firewall setting - ![](figures/network-and-firewall-setting.png "network-and-firewall-setting") - -3. Click **Firewall & network protection**, and on the displayed page, click **Allow applications to communicate through Windows Firewall**. - - **Figure 7** Firewall and network protection - ![](figures/firewall-and-network-protection.png "firewall-and-network-protection") - -4. Select the Visual Studio Code application - - **Figure 8** Selecting the Visual Studio Code application - ![](figures/selecting-the-visual-studio-code-application.png "selecting-the-visual-studio-code-application") - -5. Select the **Private** and **Public** network access rights for the Visual Studio Code application. - - **Figure 9** Allowing the Visual Studio Code application to access the network - ![](figures/allowing-the-visual-studio-code-application-to-access-the-network.png "allowing-the-visual-studio-code-application-to-access-the-network") - - -## What should I do when the image failed to be burnt? - -- **Symptom** - - The burning status is not displayed after clicking **Burn** and selecting a serial port. - -- **Possible Causes** - - The IDE is not restarted after the DevEco plug-in is installed. - -- **Solutions** - - Restart the IDE. - - -## What should I do when the message indicating Python cannot be found is displayed during compilation and building? - -- **Symptom** - - ![](figures/en-us_image_0000001105056492.png) - - -- **Possible Cause 1**: Python is not installed. -- **Solutions** - - Install Python by referring to [Installing and Configuring Python](../quick-start/ubuntu-build-environment.md). - -- **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. - - ![](figures/en-us_image_0000001151976069.png) - -- **Solutions** - - Run the following commands: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - Example: - - ![](figures/en-us_image_0000001152176139.png) - - -## What should I do when no command output is displayed? - -- **Symptom** - - The serial port shows that the connection has been established. After the board is restarted, nothing is displayed when you press **Enter**. - -- **Possible Cause 1** - - The serial port is connected incorrectly. - -- **Solutions** - - Change the serial port number. - - Start **Device Manager** to check whether the serial port connected to the board is the same as that connected to the terminal device. If the serial ports are different, perform step [1](../quick-start/running-a-hello-ohos-program.md) in the **Running an Image** section to change the serial port number. - - -- **Possible Cause 2** - - The U-boot of the board is damaged. - -- **Solutions** - - Burn the U-boot. - - If the fault persists after you perform the preceding operations, the U-boot of the board may be damaged. You can burn the U-boot by performing the following steps: - - -1. Obtain the U-boot file. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The U-boot file of the two boards can be obtained from the following paths, respectively. - >Hi3516D V300: **device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin** - >Hi3518E V300: **device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin** - -2. Burn the U-boot file by following the procedures for burning a U-boot file over USB. - - Select the U-boot files of corresponding development boards for burning by referring to [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Programming Flash Memory on the Hi3518](https://device.harmonyos.com/en/docs/ide/user-guides/hi3518_upload-0000001057313128) - -3. Log in to the serial port after the burning is complete. - - **Figure 10** Serial port displayed after the U-boot is burnt - ![](figures/serial-port-displayed-after-the-u-boot-is-burnt.png "serial-port-displayed-after-the-u-boot-is-burnt") - - diff --git a/en/device-dev/quick-start/faqs-3.md b/en/device-dev/quick-start/faqs-3.md index f756777596c26d45581846666d5bf7a16ab3c632..12c3a207b5cb348e0fc45f60c7985eacb886e61b 100644 --- a/en/device-dev/quick-start/faqs-3.md +++ b/en/device-dev/quick-start/faqs-3.md @@ -1,4 +1,4 @@ -# FAQs +# FAQs - [What should I do when the images failed to be burnt over the selected serial port?](#section627268185113) - [What should I do when Windows-based PC failed to be connected to the board?](#section195391036568) @@ -97,7 +97,7 @@ - **Symptom** - ![](figures/en-us_image_0000001105056492.png) + ![](figures/en-us_image_0000001174270715.png) - **Possible Cause 1**: Python is not installed. @@ -107,7 +107,7 @@ - **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. - ![](figures/en-us_image_0000001151976069.png) + ![](figures/en-us_image_0000001128470880.png) - **Solutions** @@ -122,7 +122,7 @@ Example: - ![](figures/en-us_image_0000001152176139.png) + ![](figures/en-us_image_0000001174270713.png) ## What should I do when no command output is displayed? diff --git a/en/device-dev/quick-start/faqs-5.md b/en/device-dev/quick-start/faqs-5.md deleted file mode 100644 index 86fbd180f7f576ae1c9e7a97cfea432ed7220e2e..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/faqs-5.md +++ /dev/null @@ -1,174 +0,0 @@ -# FAQs - -- [What should I do when the images failed to be burnt over the selected serial port?](#section1498892119619) -- [What should I do when Windows-based PC failed to be connected to the board?](#section8512971816) -- [What should I do when the image failed to be burnt?](#section1767804111198) -- [What should I do when the message indicating Python cannot be found is displayed during compilation and building?](#en-us_topic_0000001053466255_section1039835245619) -- [What should I do when no command output is displayed?](#en-us_topic_0000001053466255_section14871149155911) - -## What should I do when the images failed to be burnt over the selected serial port? - -- **Symptom** - - **Error: Opening COMxx: Access denied** is displayed after clicking **Burn** and selecting a serial port. - - **Figure 1** Failed to open the serial port - ![](figures/failed-to-open-the-serial-port-9.png "failed-to-open-the-serial-port-9") - -- **Possible Causes** - - The serial port has been used. - -- **Solutions** - -1. Search for the terminal using serial-xx from the drop-down list in the **TERMINAL** panel. - - **Figure 2** Checking whether the serial port is used - ![](figures/checking-whether-the-serial-port-is-used-10.png "checking-whether-the-serial-port-is-used-10") - -2. Click the dustbin icon as shown in the following figure to disable the terminal using the serial port. - - **Figure 3** Disabling the terminal using the serial port - ![](figures/disabling-the-terminal-using-the-serial-port-11.png "disabling-the-terminal-using-the-serial-port-11") - -3. Click **Burn**, select the serial port, and start burning images again. - - **Figure 4** Restarting burning - - - ![](figures/changjian1-12.png) - - -## What should I do when Windows-based PC failed to be connected to the board? - -- **Symptom** - - The file image cannot be obtained after clicking **Burn** and selecting a serial port. - - **Figure 5** Failed to obtain the image file due to unavailable connection - ![](figures/failed-to-obtain-the-image-file-due-to-unavailable-connection-13.png "failed-to-obtain-the-image-file-due-to-unavailable-connection-13") - -- **Possible Causes** - - The board is disconnected from the Windows-based PC. - - Windows Firewall does not allow Visual Studio Code to access the network. - -- **Solutions** - -1. Check whether the network cable is properly connected. -2. Click **Windows Firewall**. - - **Figure 6** Network and firewall setting - ![](figures/network-and-firewall-setting-14.png "network-and-firewall-setting-14") - -3. Click **Firewall & network protection**, and on the displayed page, click **Allow applications to communicate through Windows Firewall**. - - **Figure 7** Firewall and network protection - ![](figures/firewall-and-network-protection-15.png "firewall-and-network-protection-15") - -4. Select the Visual Studio Code application - - **Figure 8** Selecting the Visual Studio Code application - ![](figures/selecting-the-visual-studio-code-application-16.png "selecting-the-visual-studio-code-application-16") - -5. Select the **Private** and **Public** network access rights for the Visual Studio Code application. - - **Figure 9** Allowing the Visual Studio Code application to access the network - ![](figures/allowing-the-visual-studio-code-application-to-access-the-network-17.png "allowing-the-visual-studio-code-application-to-access-the-network-17") - - -## What should I do when the image failed to be burnt? - -- **Symptom** - - The burning status is not displayed after clicking **Burn** and selecting a serial port. - -- **Possible Causes** - - The IDE is not restarted after the DevEco plug-in is installed. - -- **Solutions** - - Restart the IDE. - - -## What should I do when the message indicating Python cannot be found is displayed during compilation and building? - -- **Symptom** - - ![](figures/en-us_image_0000001105376260.png) - - -- **Possible Cause 1** - - Python is not installed. - -- **Solutions** - - Install Python by referring to [Installing and Configuring Python](../quick-start/ubuntu-build-environment.md). - -- **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. - - ![](figures/en-us_image_0000001105216304.png) - -- **Solutions** - - Run the following commands: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - Example: - - ![](figures/en-us_image_0000001152256235.png) - - -## What should I do when no command output is displayed? - -- **Symptom** - - The serial port shows that the connection has been established. After the board is restarted, nothing is displayed when you press **Enter**. - -- **Possible Cause 1** - - The serial port is connected incorrectly. - -- **Solutions** - - Change the serial port number. - - Start **Device Manager** to check whether the serial port connected to the board is the same as that connected to the terminal device. If the serial ports are different, perform step [1](../quick-start/running-a-hello-ohos-program.md) in the **Running an Image** section to change the serial port number. - - -- **Possible Cause 2** - - The U-boot of the board is damaged. - -- **Solutions** - - Burn the U-boot. - - If the fault persists after you perform the preceding operations, the U-boot of the board may be damaged. You can burn the U-boot by performing the following steps: - - -1. Obtain the U-boot file. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >The U-boot file of the two boards can be obtained from the following paths, respectively. - >Hi3516D V300: **device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin** - >Hi3518E V300: **device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin** - -2. Burn the U-boot file by following the procedures for burning a U-boot file over USB. - - Select the U-boot files of corresponding development boards for burning by referring to [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Programming Flash Memory on the Hi3518](https://device.harmonyos.com/en/docs/ide/user-guides/hi3518_upload-0000001057313128) - -3. Log in to the serial port after the burning is complete. - - ![](figures/en-us_image_0000001105536118.png) - - diff --git a/en/device-dev/quick-start/faqs-6.md b/en/device-dev/quick-start/faqs-6.md index b428e3cf9fa250e5f077130f331806683bfbd8cf..05d53356aed9ab16ac8fe65e19da9dbe70089533 100644 --- a/en/device-dev/quick-start/faqs-6.md +++ b/en/device-dev/quick-start/faqs-6.md @@ -1,4 +1,4 @@ -# FAQs +# FAQs - [What should I do when the images failed to be burnt over the selected serial port?](#section1498892119619) - [What should I do when Windows-based PC failed to be connected to the board?](#section8512971816) @@ -97,7 +97,7 @@ - **Symptom** - ![](figures/en-us_image_0000001105376260.png) + ![](figures/en-us_image_0000001174270743.png) - **Possible Cause 1** @@ -110,7 +110,7 @@ - **Possible Cause 2**: The soft link that points to the Python does not exist in the usr/bin directory. - ![](figures/en-us_image_0000001105216304.png) + ![](figures/en-us_image_0000001174270739.png) - **Solutions** @@ -125,7 +125,7 @@ Example: - ![](figures/en-us_image_0000001152256235.png) + ![](figures/en-us_image_0000001174350661.png) ## What should I do when no command output is displayed? @@ -169,6 +169,6 @@ 3. Log in to the serial port after the burning is complete. - ![](figures/en-us_image_0000001105536118.png) + ![](figures/en-us_image_0000001174350659.png) diff --git a/en/device-dev/quick-start/faqs-11.md b/en/device-dev/quick-start/faqs-7.md similarity index 88% rename from en/device-dev/quick-start/faqs-11.md rename to en/device-dev/quick-start/faqs-7.md index 1a0b63cdc83f58505a315d982274ade0ffaa8a59..649bcba046dcb5d9429291e69e44cc933bbbd077 100644 --- a/en/device-dev/quick-start/faqs-11.md +++ b/en/device-dev/quick-start/faqs-7.md @@ -1,4 +1,4 @@ -# FAQs +# FAQs - **Symptom** diff --git a/en/device-dev/quick-start/faqs.md b/en/device-dev/quick-start/faqs.md index 67bf3ab4671f458cde77df06005ebd128a57eeec..43db6c0373612483fa0cc1e752058e256bf9665e 100644 --- a/en/device-dev/quick-start/faqs.md +++ b/en/device-dev/quick-start/faqs.md @@ -1,4 +1,4 @@ -# FAQs +# FAQs - [What should I do when the message configure: error: no acceptable C compiler found in $PATH is displayed during Python 3 installation?](#section1221016541119) - [What should I do when the message -bash: make: command not found is displayed during Python 3 installation?](#section1913477181213) @@ -134,7 +134,7 @@ - Download the source code from [https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files). - ![](figures/en-us_image_0000001151976061.png) + ![](figures/en-us_image_0000001128470864.png) - Save the source code package to the Linux server, decompress the package, and run the **python3 setup.py install** command to install **Crypto**. - Rebuild an environment. @@ -164,7 +164,7 @@ - Download the installation package from [https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files). - ![](figures/en-us_image_0000001152176131.png) + ![](figures/en-us_image_0000001128311072.png) - Save the installation package to the Linux server and run the **pip3 install ecdsa-0.15-py2.py3-none-any.whl** command to install **ecdsa**. - Rebuild an environment. @@ -194,7 +194,7 @@ - Download the installation package from [https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files). - ![](figures/en-us_image_0000001152056191.png) + ![](figures/en-us_image_0000001174270699.png) - Save the source code to the Linux server and run the **pip3 install six-1.14.0-py2.py3-none-any.whl** command to install **six**. - Rebuild an environment. @@ -247,7 +247,7 @@ - **Possible Cause 2:** The soft link that points to the Python does not exist in the **usr/bin** directory. - ![](figures/en-us_image_0000001105376252.png) + ![](figures/en-us_image_0000001128311070.png) - **Solutions** @@ -262,7 +262,7 @@ Example: - ![](figures/en-us_image_0000001105216296.png) + ![](figures/en-us_image_0000001174350623.png) ## What should I do when an error with **lsb\_release** occurs during **kconfiglib** installation? diff --git a/en/device-dev/quick-start/figures/1-19.png b/en/device-dev/quick-start/figures/1-19.png deleted file mode 100644 index 8ed1535a6bc23dc5bd02fbd5a3f1392f46ad8d83..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/1-19.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/1-20.png b/en/device-dev/quick-start/figures/1-20.png deleted file mode 100644 index 8ed1535a6bc23dc5bd02fbd5a3f1392f46ad8d83..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/1-20.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334-17.png b/en/device-dev/quick-start/figures/2021-01-27_170334-17.png deleted file mode 100644 index 1e7dd2cdb515e871a1c5d34b3332b097bc02351b..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/2021-01-27_170334-17.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334-18.png b/en/device-dev/quick-start/figures/2021-01-27_170334-18.png index 5b573a4ddfe89fe25cb1b567736823244fdb9e97..1e7dd2cdb515e871a1c5d34b3332b097bc02351b 100644 Binary files a/en/device-dev/quick-start/figures/2021-01-27_170334-18.png and b/en/device-dev/quick-start/figures/2021-01-27_170334-18.png differ diff --git a/en/device-dev/quick-start/figures/2021-01-27_170334-6.png b/en/device-dev/quick-start/figures/2021-01-27_170334-6.png deleted file mode 100644 index 5b573a4ddfe89fe25cb1b567736823244fdb9e97..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/2021-01-27_170334-6.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/2021-01-27_181047.png b/en/device-dev/quick-start/figures/2021-01-27_181047.png deleted file mode 100644 index 587ca51a1010c3fefcc79be73ffc5584075551ed..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/2021-01-27_181047.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/2021-01-28_112953.png b/en/device-dev/quick-start/figures/2021-01-28_112953.png deleted file mode 100644 index a3a92549a345ad7ebb1d0142a50d2c41c4ede9f4..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/2021-01-28_112953.png and /dev/null differ diff --git "a/en/device-dev/quick-start/figures/3516\346\255\243\351\235\242-17.png" "b/en/device-dev/quick-start/figures/3516\346\255\243\351\235\242-17.png" new file mode 100644 index 0000000000000000000000000000000000000000..1ccb47f20022261cc291e8b435f263c00e8d4a27 Binary files /dev/null and "b/en/device-dev/quick-start/figures/3516\346\255\243\351\235\242-17.png" differ diff --git a/en/device-dev/quick-start/figures/allowing-the-visual-studio-code-application-to-access-the-network-17.png b/en/device-dev/quick-start/figures/allowing-the-visual-studio-code-application-to-access-the-network-17.png deleted file mode 100644 index 13d77ce93c78ac07039c8f09741db1db1d05a124..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/allowing-the-visual-studio-code-application-to-access-the-network-17.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/changjian1-12.png b/en/device-dev/quick-start/figures/changjian1-12.png deleted file mode 100644 index 208a4fbace342514f59f0000c4d50f5dc9321f0f..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/changjian1-12.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/checking-whether-the-serial-port-is-used-10.png b/en/device-dev/quick-start/figures/checking-whether-the-serial-port-is-used-10.png deleted file mode 100644 index cfa0ceb21f5a11d459b93721f512309c9d6da2ac..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/checking-whether-the-serial-port-is-used-10.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/chuankou1-7.png b/en/device-dev/quick-start/figures/chuankou1-7.png deleted file mode 100644 index 8eb26425f53028a08eb40e3037ecd302f3082270..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/chuankou1-7.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/disabling-the-terminal-using-the-serial-port-11.png b/en/device-dev/quick-start/figures/disabling-the-terminal-using-the-serial-port-11.png deleted file mode 100644 index 0c1f60638087d0fe56127f2f842244355afad85f..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/disabling-the-terminal-using-the-serial-port-11.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001078313582.png b/en/device-dev/quick-start/figures/en-us_image_0000001078313582.png deleted file mode 100644 index d09a7cc3c72dff150d1a06ab4a7fcaebb7de3265..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001078313582.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001113969536.png b/en/device-dev/quick-start/figures/en-us_image_0000001113969536.png deleted file mode 100644 index baac7b26450b8bc195a0db0bb3bb41119c0d9828..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001113969536.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001114129426.png b/en/device-dev/quick-start/figures/en-us_image_0000001114129426.png deleted file mode 100644 index c5548cb227bd024b49aa3adba0a20869581448e8..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001114129426.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001117621400.png b/en/device-dev/quick-start/figures/en-us_image_0000001117621400.png new file mode 100644 index 0000000000000000000000000000000000000000..bfb378217e99536cf076deecfb0f0677cb51eef8 Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001117621400.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001119945810.png b/en/device-dev/quick-start/figures/en-us_image_0000001119945810.png deleted file mode 100644 index 8a4060e64fdd059143a3ec1adb9ee6937fa4af84..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001119945810.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001120802173.png b/en/device-dev/quick-start/figures/en-us_image_0000001120802173.png deleted file mode 100644 index 5576e74b99dc2ae0ea635d3f684b560b93fce516..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001120802173.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001120802383.png b/en/device-dev/quick-start/figures/en-us_image_0000001120802383.png deleted file mode 100644 index 4921a82341b8828a6117343b77f7c92b0d99a2c6..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001120802383.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001121061169.png b/en/device-dev/quick-start/figures/en-us_image_0000001121061169.png deleted file mode 100644 index 5081b5a4be6269549d271afe84f96f7f489fc419..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001121061169.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001105524466.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311066.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001105524466.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311066.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001105216304.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311070.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001105216304.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311070.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001152176131.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311072.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001152176131.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311072.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001096963405.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311090.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001096963405.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311090.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001078089378.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311092.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001078089378.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311092.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001073835952.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311094.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001073835952.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311094.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311096.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311096.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd7b0a67ce7110774979284e69c462058723756 Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001128311096.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001160649343.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311098.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001160649343.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311098.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311100.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311100.png new file mode 100644 index 0000000000000000000000000000000000000000..61aec8202ac830a3598ef2c8a413be30c5a742f0 Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001128311100.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128311104.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311104.png new file mode 100644 index 0000000000000000000000000000000000000000..773abcd91a0c0ee1d3f5f87218216fc337d8f62f Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001128311104.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001078404538.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311116.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001078404538.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311116.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001057235392.png b/en/device-dev/quick-start/figures/en-us_image_0000001128311118.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001057235392.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128311118.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001151976061.png b/en/device-dev/quick-start/figures/en-us_image_0000001128470864.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001151976061.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128470864.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001105376252.png b/en/device-dev/quick-start/figures/en-us_image_0000001128470880.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001105376252.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128470880.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001073057176.png b/en/device-dev/quick-start/figures/en-us_image_0000001128470900.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001073057176.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128470900.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470902.png b/en/device-dev/quick-start/figures/en-us_image_0000001128470902.png new file mode 100644 index 0000000000000000000000000000000000000000..43e43b52b677660cec4d049784b246aebe1a2434 Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001128470902.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001160529355.png b/en/device-dev/quick-start/figures/en-us_image_0000001128470904.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001160529355.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128470904.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001128470906.png b/en/device-dev/quick-start/figures/en-us_image_0000001128470906.png new file mode 100644 index 0000000000000000000000000000000000000000..281958fe76a787acc5d0b98f5ea248fa5abf2405 Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001128470906.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001078244328.png b/en/device-dev/quick-start/figures/en-us_image_0000001128470922.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001078244328.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128470922.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001096154076.png b/en/device-dev/quick-start/figures/en-us_image_0000001128471042.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001096154076.png rename to en/device-dev/quick-start/figures/en-us_image_0000001128471042.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001160528243.png b/en/device-dev/quick-start/figures/en-us_image_0000001160528243.png deleted file mode 100644 index 571af4fc8e53f59f246496ad670cc6b84f4473f3..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001160528243.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001160649345.png b/en/device-dev/quick-start/figures/en-us_image_0000001160649345.png deleted file mode 100644 index 1819a2816fa617fa6389646fd6a4b1ab0d97272d..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/en-us_image_0000001160649345.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001152056191.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270699.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001152056191.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270699.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001105216296.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270713.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001105216296.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270713.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001105056492.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270715.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001105056492.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270715.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270727.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270727.png new file mode 100644 index 0000000000000000000000000000000000000000..2609aa029260a137c76c299fead396c07b8c8e45 Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001174270727.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001116405268.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270729.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001116405268.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270729.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001163529159.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270731.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001163529159.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270731.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270733.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270733.png new file mode 100644 index 0000000000000000000000000000000000000000..72dd05e3ae1eb91156df98cb1915b6264b3bbe5a Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001174270733.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174270735.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270735.png new file mode 100644 index 0000000000000000000000000000000000000000..2710fef9266dde76a9c555bc2edecebd8e3d8d1b Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001174270735.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001152256221.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270737.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001152256221.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270737.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001151976069.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270739.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001151976069.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270739.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001105376260.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270743.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001105376260.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270743.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001163569275.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270749.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001163569275.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270749.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001074285712.png b/en/device-dev/quick-start/figures/en-us_image_0000001174270751.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001074285712.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174270751.png diff --git "a/en/device-dev/quick-start/figures/3861\350\203\214\351\235\242.png" b/en/device-dev/quick-start/figures/en-us_image_0000001174350615.png similarity index 100% rename from "en/device-dev/quick-start/figures/3861\350\203\214\351\235\242.png" rename to en/device-dev/quick-start/figures/en-us_image_0000001174350615.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001152176139.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350623.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001152176139.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350623.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001073388838.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350633.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001073388838.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350633.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001163568181.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350641.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001163568181.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350641.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001073242197.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350643.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001073242197.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350643.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001160529359.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350647.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001160529359.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350647.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001077956808.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350649.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001077956808.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350649.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350651.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350651.png new file mode 100644 index 0000000000000000000000000000000000000000..686385e096a24ec1906169d2b11f75030c386b9f Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001174350651.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001174350653.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350653.png new file mode 100644 index 0000000000000000000000000000000000000000..e0dc22d338e23ca54b973597bf9f94ae4fd08a42 Binary files /dev/null and b/en/device-dev/quick-start/figures/en-us_image_0000001174350653.png differ diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001105536118.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350659.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001105536118.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350659.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001152256235.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350661.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001152256235.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350661.png diff --git a/en/device-dev/quick-start/figures/en-us_image_0000001074445364.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350669.png similarity index 100% rename from en/device-dev/quick-start/figures/en-us_image_0000001074445364.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350669.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001143154485.png b/en/device-dev/quick-start/figures/en-us_image_0000001174350781.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001143154485.png rename to en/device-dev/quick-start/figures/en-us_image_0000001174350781.png diff --git a/en/device-dev/quick-start/figures/failed-to-obtain-the-image-file-due-to-unavailable-connection-13.png b/en/device-dev/quick-start/figures/failed-to-obtain-the-image-file-due-to-unavailable-connection-13.png deleted file mode 100644 index 548e03da4b76123cb67d41cbd1de4a0f33f5ef4b..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/failed-to-obtain-the-image-file-due-to-unavailable-connection-13.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/failed-to-open-the-serial-port-9.png b/en/device-dev/quick-start/figures/failed-to-open-the-serial-port-9.png deleted file mode 100644 index 25308b9cab52a166955e70ada35c3191d90dd64c..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/failed-to-open-the-serial-port-9.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/firewall-and-network-protection-15.png b/en/device-dev/quick-start/figures/firewall-and-network-protection-15.png deleted file mode 100644 index 82faf7d05d2a40e9deae2649a1f59fccea67bdc2..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/firewall-and-network-protection-15.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/getting-started-for-the-standard-system.png b/en/device-dev/quick-start/figures/getting-started-for-the-standard-system.png new file mode 100644 index 0000000000000000000000000000000000000000..216265660cd0364189cd438da8b7e2600a7a5099 Binary files /dev/null and b/en/device-dev/quick-start/figures/getting-started-for-the-standard-system.png differ diff --git a/en/device-dev/quick-start/figures/network-and-firewall-setting-14.png b/en/device-dev/quick-start/figures/network-and-firewall-setting-14.png deleted file mode 100644 index 9487849c5f8a860e9680016ff3657404b2c0ad6e..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/network-and-firewall-setting-14.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/selecting-the-visual-studio-code-application-16.png b/en/device-dev/quick-start/figures/selecting-the-visual-studio-code-application-16.png deleted file mode 100644 index 81812f492838b439ea507d4afb763ff751c0a467..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/selecting-the-visual-studio-code-application-16.png and /dev/null differ diff --git a/en/device-dev/quick-start/figures/successful-system-startup-and-program-execution-8.png b/en/device-dev/quick-start/figures/successful-system-startup-and-program-execution-8.png deleted file mode 100644 index 6a85551cd30c8c0576c138d86dc66ddf73dccb44..0000000000000000000000000000000000000000 Binary files a/en/device-dev/quick-start/figures/successful-system-startup-and-program-execution-8.png and /dev/null differ diff --git a/en/device-dev/quick-start/hi3516-development-board.md b/en/device-dev/quick-start/hi3516-development-board.md index 39c132f0a8319e74b4bdb0e5cad6c6d6beef3993..53148cbe9a1fba7264055edc9fdad8eb193c00ad 100644 --- a/en/device-dev/quick-start/hi3516-development-board.md +++ b/en/device-dev/quick-start/hi3516-development-board.md @@ -1,4 +1,4 @@ -# Hi3516 Development Board +# Hi3516 Development Board - [Introduction](#section26131214194212) - [Development Board Specifications](#section15192203316533) diff --git a/en/device-dev/quick-start/hi3516.md b/en/device-dev/quick-start/hi3516.md index 17987269923620c2ceb55de66d076c128da4da15..e33aa899315932687a01de028a7f0fccba0a91b2 100644 --- a/en/device-dev/quick-start/hi3516.md +++ b/en/device-dev/quick-start/hi3516.md @@ -1,4 +1,4 @@ -# Hi3516 +# Hi3516 - **[Setting Up the Environment](setting-up-the-environment-2.md)** diff --git a/en/device-dev/quick-start/hi3518-development-board.md b/en/device-dev/quick-start/hi3518-development-board.md index 1ba46e856f9b491ab4e240ab888ea3fe5a2fc803..262d456b50b47d8c91593999dd5a8f2d5a935d66 100644 --- a/en/device-dev/quick-start/hi3518-development-board.md +++ b/en/device-dev/quick-start/hi3518-development-board.md @@ -1,4 +1,4 @@ -# Hi3518 Development Board +# Hi3518 Development Board - [Introduction](#section14815247616) - [Development Board Specifications](#section765112478446) diff --git a/en/device-dev/quick-start/hi3518.md b/en/device-dev/quick-start/hi3518.md index 3f7e2e5dcd0bddac839cd3184a3a27920df556e6..817d4c826164210f795e36503f49dded0c49529e 100644 --- a/en/device-dev/quick-start/hi3518.md +++ b/en/device-dev/quick-start/hi3518.md @@ -1,4 +1,4 @@ -# Hi3518 +# Hi3518 - **[Setting Up the Environment](setting-up-the-environment-4.md)** diff --git a/en/device-dev/quick-start/hi3861-development-board.md b/en/device-dev/quick-start/hi3861-development-board.md index 4e9d3ce1665264cd57b814aaea67f1f5039c9cd8..6790ab0fe64db575950bef8225613438ccbad63a 100644 --- a/en/device-dev/quick-start/hi3861-development-board.md +++ b/en/device-dev/quick-start/hi3861-development-board.md @@ -1,4 +1,4 @@ -# Hi3861 Development Board +# Hi3861 Development Board - [Introduction](#section19352114194115) - [Resources and Constraints](#section82610215014) @@ -19,7 +19,7 @@ The Hi3861 WLAN module can also be connected to the Hi3861 mother board to expan **Figure 2** Appearance of the Hi3861 mother board -![](figures/en-us_image_0000001119945810.png) +![](figures/en-us_image_0000001174350615.png) - The RF circuit includes modules such as the power amplifier \(PA\), low noise amplifier \(LNA\), RF Balun, antenna switch, and power management. It supports a standard bandwidth of 20 MHz and a narrow bandwidth of 5 MHz or 10 MHz, and provides a maximum rate of 72.2 Mbit/s at the physical layer. - The Hi3861 WLAN baseband supports the orthogonal frequency division multiplexing \(OFDM\) technology and is backward compatible with the direct sequence spread spectrum \(DSSS\) and complementary code keying \(CCK\) technologies. In addition, the Hi3861 WLAN baseband supports various data rates specified in the IEEE 802.11 b/g/n protocol. @@ -29,7 +29,7 @@ The Hi3861 WLAN module can also be connected to the Hi3861 mother board to expan **Figure 3** Hi3861 functions - ![](figures/en-us_image_0000001105524466.png) + ![](figures/en-us_image_0000001128311066.png) ## Resources and Constraints diff --git a/en/device-dev/quick-start/hi3861.md b/en/device-dev/quick-start/hi3861.md index 8032fdd2ab4b2f7e0a23dcb8b127733d1c1900dc..100cdfcabc277a736ed2238f4b8cd93e345624a0 100644 --- a/en/device-dev/quick-start/hi3861.md +++ b/en/device-dev/quick-start/hi3861.md @@ -1,4 +1,4 @@ -# Hi3861 +# Hi3861 - **[Setting Up the Environment](setting-up-the-environment.md)** diff --git a/en/device-dev/quick-start/how-to-develop-12.md b/en/device-dev/quick-start/how-to-develop-12.md deleted file mode 100644 index f6fe9c7a06d672e94059bb92f907cf1e96311cc1..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/how-to-develop-12.md +++ /dev/null @@ -1,246 +0,0 @@ -# How to Develop - -- [Environment Setup](#section1246439101710) -- [Build](#section375234715135) -- [Burning](#section111671738101213) - - [Prerequisites](#section1458192114718) - - [Programming Flash Memory Through the USB Port](#section18423113662120) - -- [Development Example](#section5600113114323) - -## Environment Setup - -For details about setting up the standard OpenHarmony environment, see [Setting Up the Environment](overview-9.md). - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->For details about the environment requirements of the third-party development board, refer to the official guide of the development board. - -## Build - -If you are using the Docker environment, refer to the Docker usage guide to build the system. If you are using the installation package, perform the following operations in the Linux environment. - -1. Go to the root directory of the source code and run the following command to build the distribution. - - ``` - ./build.sh --product-name Hi3516DV300 - ``` - - **product\_name** indicates the platform supported by the current distribution, - -2. Check the build result. After the build is complete, the following information is displayed in the log: - - ``` - build system image successful. - =====build Hi3516DV300 successful. - ``` - - Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >For details about module-specific build operations, see [Compilation and Building Overview](../subsystems/building-guidelines-for-the-standard-system.md). - - -## Burning - -Programming flash memory of a regular system requires DevEco Device Tool v2.2 Beta1 or later. - -The Hi3516DV300 of the Hi3516 series development boards supports programming flash memory of a regular system through the USB port, network port, or serial port, where: - -- **Windows system: Supports programming through the USB port, serial port, or network port** -- **Linux system: Supports programming through the serial port or network port \(Linux+Windows dual system: Also supports programming through the USB port\)** - -Except for environment setup, the burning operations are the same for Windows and Linux. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Currently, the Hi3516D V300 development board supports system burning over the USB port, network port, or serial port. This document uses the USB port as an example. For details about system burning over other ports, see [Programming Flash Memory on the Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_upload-0000001052148681). - -### Prerequisites - -[Open a project](https://device.harmonyos.com/en/docs/ide/user-guides/open_project-0000001071680043) in DevEco Device Tool and select the folder where the file to be programmed is located. Select **Hi3516DV300** for the development board type and **Hb** for **Framework**. - -### Programming Flash Memory Through the USB Port - -The Hi3516DV300 supports programming through the USB port in Windows or Linux+Windows environment. - -1. Connect the PC and the target development board through the serial port and USB port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_camera_start_3516-0000001052670587). -2. Open Device Manager, then check and record the serial port number corresponding to the development board. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). - - ![](figures/en-us_image_0000001160529359.png) - -3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - - ![](figures/2021-01-27_170334-17.png) - -4. On the **Partition Configuration** tab page, enter the information about the files to be programmed, including the following. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Binary

-

Memory

-

System

-

Address

-

Length

-

Board

-

Type

-

fastboot

-

Select u-boot-hi3516dv300_emmc.bin.

-

emmc

-

none

-

0x000000

-

0x100000

-

Select hi3516dv300.

-

NA

-

boot

-

Select uImage.

-

emmc

-

none

-

0x100000

-

0xf00000

-

NA

-

updater

-

Select updater.img.

-

emmc

-

ext3/4

-

0x1000000

-

0x1400000

-

NA

-

misc

-

Leave it blank.

-

emmc

-

none

-

0x2400000

-

0x100000

-

NA

-

system

-

Select system.img.

-

emmc

-

ext3/4

-

0x2500000

-

0xceb00000

-

NA

-

vendor

-

Select vendor.img.

-

emmc

-

ext3/4

-

0xd1000000

-

0x10000000

-

NA

-

userdata

-

Select userdata.img.

-

emmc

-

ext3/4

-

0xe1000000

-

0x5b800000

-

NA

-
- - ![](figures/en-us_image_0000001160527611.png) - -5. On the **hi3516dv300** tab page, configure the programming options. - - - **upload\_port**: Select the serial port number obtained in step 2. - - **upload\_protocol**: Select the programming protocol **hiburn-usb**. - - **upload\_partitions**: Select the file to be programmed, including the following: fastboot, boot, updater, misc, system, vendor, and userdata. - - ![](figures/en-us_image_0000001160528243.png) - -6. When you finish modifying, click **Save** in the upper right corner. -7. Open the project file, go to ![](figures/2021-01-27_170334-18.png) \> **PROJECT TASKS** \> **fastboot** \> **Erase** to erase U-boot. - - ![](figures/en-us_image_0000001163045527.png) - -8. When the following message is displayed, power off the development board and then power it on. - - ![](figures/en-us_image_0000001114129426.png) - -9. If the following message is displayed, it indicates that U-Boot is erased successfully. - - ![](figures/en-us_image_0000001113969536.png) - -10. Go to **hi3516dv300** \> **Upload** to start programming. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If this is the first time you program flash memory on the Hi3516 or Hi3518 board, the message "not find the Devices" may be displayed. In this case, follow the steps in [Installing the USB Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/usb_driver-0000001058690393) and start programming again. - - ![](figures/1-19.png) - -11. If the following message is displayed, it indicates that the programming is successful. - - ![](figures/en-us_image_0000001160649343.png) - - -## Development Example - -You have completed the quick start for the standard system. Get yourself familiar with OpenHarmony by a [Development Example for Platform Drivers](../guide/overview-10.md). - diff --git a/en/device-dev/quick-start/how-to-develop.md b/en/device-dev/quick-start/how-to-develop.md index 1d961ebf4b57ac2a26aa4e377987a6bddd50c2d2..3e5f705cb569a6d3c7f9543dd24a75159e1682aa 100644 --- a/en/device-dev/quick-start/how-to-develop.md +++ b/en/device-dev/quick-start/how-to-develop.md @@ -1,4 +1,4 @@ -# How to Develop +# How to Develop - **[Hi3861](hi3861.md)** diff --git a/en/device-dev/quick-start/introduction-to-the-development-boards.md b/en/device-dev/quick-start/introduction-to-the-development-boards.md index 6703a78fe6d3e877145d5198435d3c2f99c971c4..3848dad5841c053f27b1b5f6280a8a34cb6b41c4 100644 --- a/en/device-dev/quick-start/introduction-to-the-development-boards.md +++ b/en/device-dev/quick-start/introduction-to-the-development-boards.md @@ -1,4 +1,4 @@ -# Introduction to the Development Boards +# Introduction to the Development Boards - **[Hi3861 Development Board](hi3861-development-board.md)** diff --git a/en/device-dev/quick-start/introduction.md b/en/device-dev/quick-start/introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..7209c5c0f18b55e253bca942025b9d0682e390b3 --- /dev/null +++ b/en/device-dev/quick-start/introduction.md @@ -0,0 +1,54 @@ +# Introduction + +- [Quick Start Process](#section7825218111517) +- [Introduction to the Development Board](#en-us_topic_0000001053666242_section047719215429) +- [Development Board Specifications](#en-us_topic_0000001053666242_section15192203316533) + +This document helps you quickly understand how to set up a standard OpenHarmony system, and how to build, burn, and start the system. You can develop the standard system in Windows and build source code in Linux. + +This document uses the recommended Hi3516D V300 development board as an example. + +## Quick Start Process + +The following figure shows the process of getting started for the standard system, during which, you can set up the Ubuntu development environment in Docker mode or by using the installation package. + +**Figure 1** Getting started for the standard system +![](figures/getting-started-for-the-standard-system.png "getting-started-for-the-standard-system") + +## Introduction to the Development Board + +Hi3516D V300 is a next-generation system on chip \(SoC\) designed for the industry-dedicated smart HD IP camera. It introduces a next-generation image signal processor \(ISP\), the H.265 video compression encoder, and a high-performance NNIE engine, leading the industry in terms of low bit rate, high image quality, intelligent processing and analysis, and low power consumption. + +**Figure 2** Hi3516D V300 front view + + +![](figures/3516正面-17.png) + +## Development Board Specifications + +**Table 1** Specifications of the Hi3516 development board + + + + + + + + + + + + + +

Item

+

Description

+

Processor and internal memory

+
  • Hi3516D V300
  • 1 GB DDR3
  • 8 GB eMMC4.5
+

External components

+
  • Ethernet port
  • Audio and video
    • One voice input
    • One mono (AC_L) output, connected to a 3 W power amplifier (LM4871)
    • Micro-HDMI (one HDMI 1.4)
    +
  • Cameras
    • Sensor IMX335
    • M12 lens with a focal length of 4 mm and an aperture of 1.8
    +
  • Display
    • 2.35-inch LCD connector
    • 5.5-inch LCD connector
    +
  • External components and interfaces
    • microSD card interface
    • JTAG/I2S interface
    • ADC interface
    • Steer gear interface
    • Grove connector
    • USB 2.0 (Type C)
    • Three function keys: two custom keys and one update key
    • LED indicator (including green and red)
    +
+
+ diff --git a/en/device-dev/quick-start/overview-0.md b/en/device-dev/quick-start/overview-0.md index 9a73241369434d4ec249a00b0f9231c5a9d83a3a..8a7a6ba8fdb2b61d099ce7b399c04efe6056f5d6 100644 --- a/en/device-dev/quick-start/overview-0.md +++ b/en/device-dev/quick-start/overview-0.md @@ -1,4 +1,4 @@ -# Overview +# Overview The mini and small OpenHarmony systems are suitable for IoT devices with limited memory. This document describes the system development with three typical development boards: Hi3861 WLAN module, Hi3516D V300, and Hi3518E V300. diff --git a/en/device-dev/quick-start/overview-1.md b/en/device-dev/quick-start/overview-1.md index d490f51d2ebc128dda830e011b63b20e637b1136..5b5feef48c5ae0f1668069c6cb4fce756fe4b2b6 100644 --- a/en/device-dev/quick-start/overview-1.md +++ b/en/device-dev/quick-start/overview-1.md @@ -1,4 +1,4 @@ -# Overview +# Overview Use the DevEco Device Tool for development, build, burning, and debugging of OpenHarmony. diff --git a/en/device-dev/quick-start/overview-6.md b/en/device-dev/quick-start/overview-6.md deleted file mode 100644 index c4f01181922cdde3dd4924e6ef8978c03f260a1c..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/overview-6.md +++ /dev/null @@ -1,4 +0,0 @@ -# Overview - -This document helps you quickly understand how to set up a standard OpenHarmony system, and how to build, burn, and start the system. This document uses the recommended Hi3516D V300 development board as an example. - diff --git a/en/device-dev/quick-start/overview-7.md b/en/device-dev/quick-start/overview-7.md deleted file mode 100644 index c4f01181922cdde3dd4924e6ef8978c03f260a1c..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/overview-7.md +++ /dev/null @@ -1,4 +0,0 @@ -# Overview - -This document helps you quickly understand how to set up a standard OpenHarmony system, and how to build, burn, and start the system. This document uses the recommended Hi3516D V300 development board as an example. - diff --git a/en/device-dev/quick-start/overview-8.md b/en/device-dev/quick-start/overview-8.md deleted file mode 100644 index 050e338e9d4009463c20bb282f0c8b9bd9f69370..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/overview-8.md +++ /dev/null @@ -1,58 +0,0 @@ -# Overview - -- [Introduction](#section18217135811916) -- [Environment Requirements](#section466851916410) - - [Hardware](#section19682305453) - - [Software](#section1595725202314) - - -## Introduction - -In a standard system, you can use the DevEco Device Tool for development and burning in Windows, and for build in Linux. This document describes how to set up the environment. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The procedure for setting up a Windows standard-system environment is basically the same as that for setting up a Windows mini- or small-system environment. Therefore, you can skip section [Windows Development Environment](windows-development-environment-9.md) if you have set up a Windows mini- or small-system environment. - -## Environment Requirements - -### Hardware - -- Linux compile server -- Windows workstation \(host computer\) - -### Software - -**Table 1** Development platform requirements - - - - - - - - - - - - - - - - - - -

Platform

-

Software

-

Description

-

Remarks

-

Linux compile server

-

Operating system

-

Ubuntu 18.04 64-bit or later is used for the Linux OS, and bash is used as the shell. The server hardware specifications are as follows:

-
  • Hard disk: at least 400 GB
  • CPU: at least 8 cores
  • Memory: at least 32 GB
-

Common software such as samba and vim is installed in the OS by default. Adaptation is required to support Linux file sharing.

-

You can develop programs on the Windows workstation or Linux server via a remote login.

-

Windows workstation

-

Operating system

-

Windows XP/Windows7/Windows10

-
- diff --git a/en/device-dev/quick-start/overview-9.md b/en/device-dev/quick-start/overview-9.md deleted file mode 100644 index 2afccc92c3ac98b0d6f181c1ba69f706364a0562..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/overview-9.md +++ /dev/null @@ -1,58 +0,0 @@ -# Overview - -- [Introduction](#section18217135811916) -- [Environment Requirements](#section466851916410) - - [Hardware](#section19682305453) - - [Software](#section1595725202314) - - -## Introduction - -In a standard OpenHarmony system, you can use the DevEco Device Tool for development and burning in Windows, and for build in Linux. This document describes how to set up the environment. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->The procedure for setting up a Windows standard-system environment is basically the same as that for setting up a Windows mini- or small-system environment. Therefore, you can skip section [Windows Development Environment](windows-development-environment-10.md) if you have set up a Windows mini- or small-system environment. - -## Environment Requirements - -### Hardware - -- Linux compile server -- Windows workstation \(host computer\) - -### Software - -**Table 1** Development platform requirements - - - - - - - - - - - - - - - - - - -

Platform

-

Software

-

Description

-

Remarks

-

Linux compile server

-

Operating system

-

Ubuntu 18.04 64-bit or later is used for the Linux OS, and bash is used as the shell. The server hardware specifications are as follows:

-
  • Hard disk: at least 400 GB
  • CPU: at least 8 cores
  • Memory: at least 32 GB
-

Common software such as samba and vim is installed in the OS by default. Adaptation is required to support Linux file sharing.

-

You can develop programs on the Windows workstation or Linux server via a remote login.

-

Windows workstation

-

Operating system

-

Windows XP/Windows7/Windows10

-
- diff --git a/en/device-dev/quick-start/preparing-the-ubuntu-build-environment.md b/en/device-dev/quick-start/preparing-the-ubuntu-build-environment.md deleted file mode 100644 index e1f0774daadb6d6f807a95c16affac8e8a630b27..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/preparing-the-ubuntu-build-environment.md +++ /dev/null @@ -1,69 +0,0 @@ -# Preparing the Ubuntu Build Environment - -- [Method 1: Setting up an Ubuntu Build Environment Using a Docker Environment](#section1643363843714) - - [Obtaining Standard-System Source Code](#section58448331029) - - [Installing and Using the Docker Environment](#section22916211916) - -- [Method 2: Setting up an Ubuntu Build Environment Using an Installation Package](#section25961010189) - - [Installing Dependent Tools](#section109262032104819) - - [Obtaining Standard-System Source Code](#section6325556113718) - - [Obtaining prebuilts](#section16453104219209) - - -You can use either the Docker environment or installation package provided by OpenHarmony to set up an Ubuntu build environment. This section describes the two methods. - -## Method 1: Setting up an Ubuntu Build Environment Using a Docker Environment - -The standard OpenHarmony system provides a Docker environment which encapsulates build tools. To use the Docker environment, perform the following steps: - -1. Obtain the standard-system source code. -2. Install and use the Docker environment. - -### Obtaining Standard-System Source Code - -Obtain the [standard-system source code](https://repo.huaweicloud.com/harmonyos/os/2.0/code-2.0-canary.tar.gz). The obtained source code is the static code. If you want to obtain the latest source code from Gitee, use [repo](../get-code/source-code-acquisition.md). - -### Installing and Using the Docker Environment - -For details, see [Installing and Using Docker](../get-code/tool-acquisition.md). - -## Method 2: Setting up an Ubuntu Build Environment Using an Installation Package - -The procedure is as follows: - -1. Install dependent tools. -2. Obtain the standard-system source code. -3. Obtain prebuilts. - -### Installing Dependent Tools - -The installation command is as follows: - -``` -sudo apt-get install binutils git-core 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 lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 -``` - ->![](public_sys-resources/icon-caution.gif) **CAUTION:** ->The preceding command is applicable to Ubuntu 18.04. For other Ubuntu versions, use the corresponding installation commands based on the installation package name. If the Ubuntu version is later than 18.04, Python 2.7 and python-minimal must be installed. - -### Obtaining Standard-System Source Code - -Obtain the [standard-system source code](https://repo.huaweicloud.com/harmonyos/os/2.0/code-2.0-canary.tar.gz). The obtained source code is the static code. If you want to obtain the latest source code from Gitee, use [repo](../get-code/source-code-acquisition.md). - -### Obtaining prebuilts - -1. Go to the OpenHarmony working directory. - - ``` - cd OpenHarmony - ``` - -2. Execute the following script: - - ``` - build/prebuilts_download.sh - ``` - - By default, the downloaded prebuilts binary file is stored in **OpenHarmony\_2.0\_canary\_prebuilts** \(which is in the same directory as **OpenHarmony**\). - - diff --git a/en/device-dev/quick-start/running-a-hello-ohos-program-4.md b/en/device-dev/quick-start/running-a-hello-ohos-program-4.md deleted file mode 100644 index 62c151696188113379a554af194eae697f0f22b4..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/running-a-hello-ohos-program-4.md +++ /dev/null @@ -1,268 +0,0 @@ -# Running a Hello OHOS Program - -- [Creating a Program](#section1550972416485) -- [Building](#section234175193114) -- [Burning](#section7609155824819) -- [Running an Image](#section17612105814480) -- [Follow-up Learning](#section9712145420182) - -This section describes how to create, compile, burn, and run the first program, and finally print **Hello OHOS!** on the develop board. - -## Creating a Program - -1. Create a directory and the program source code. - - Create the **applications/sample/camera/apps/src/helloworld.c** directory and file whose code is shown in the following example. You can customize the content to be printed. For example, you can change **OHOS** to **World**. You can use either C or C++ to develop a program. - - ``` - #include - - int main(int argc, char **argv) - { - printf("\n************************************************\n"); - printf("\n\t\tHello OHOS!\n"); - printf("\n************************************************\n\n"); - - return 0; - } - ``` - -2. Create a build file. - - Create the **applications/sample/camera/apps/BUILD.gn** file. The file content is as follows: - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("hello-OHOS") { - features = [ ":helloworld" ] - } - executable("helloworld") { - output_name = "helloworld" - sources = [ "src/helloworld.c" ] - include_dirs = [] - defines = [] - cflags_c = [] - ldflags = [] - } - ``` - -3. Add a new component. - - Add the configuration of the **hello\_world\_app** component to the **build/lite/components/applications.json** file. The sample code below shows some configurations defined in the **applications.json** file, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) - - ``` - { - "components": [ - { - "component": "camera_sample_communication", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/communication" - ], - "targets": [ - "//applications/sample/camera/communication:sample" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##start## - { - "component": "hello_world_app", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/apps" - ], - "targets": [ - "//applications/sample/camera/apps:hello-OHOS" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##end## - { - "component": "camera_sample_app", - "description": "Camera related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/launcher", - "applications/sample/camera/cameraApp", - "applications/sample/camera/setting", - "applications/sample/camera/gallery", - "applications/sample/camera/media" - ], - ``` - -4. Modify the board configuration file. - - Add the **hello\_world\_app** component to the **vendor/hisilicon/hispark\_aries/config.json** file. The sample code below shows the configurations of the **applications** subsystem, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) - - ``` - { - "subsystem": "applications", - "components": [ - ##start## - { "component": "hello_world_app", "features":[] }, - ##end## - { "component": "camera_sample_app", "features":[] } - - ] - }, - ``` - - -## Building - -If the Linux environment is installed using Docker, perform the compilation by referring to [Using Docker to Prepare the Build Environment](../get-code/tool-acquisition.md). If the Linux compilation environment is installed using a software package, execute the following commands to compile source code in the root directory of the source code package. - -``` -hb set (Set the building path.) -. (Select the current path.) -Select ipcamera_hispark_aries@hisilicon and press Enter. -hb build -f (Start building.) -``` - -The result files are generated in the **out/hispark\_aries/ipcamera\_hispark\_aries** directory. - -**Figure 1** Settings -![](figures/settings-4.png "settings-4") - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->The U-boot file of the Hi3518E V300 development board can be obtained from the following path: device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin - -## Burning - -The USB port is the only burning mode supported by the Hi3518 development board. - -1. Connect the PC and the target development board through the serial port and USB port. In this section, the Hi3518EV300 is used as an example. For details, please refer to [Introduction to the Hi3518 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_camera_start_hi3518-0000001050170473). -2. Open Device Manager, then check and record the serial port number corresponding to the development board. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). - - ![](figures/en-us_image_0000001073057176.png) - -3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - - ![](figures/en-us_image_0000001077956808.png) - -4. On the **hi3518ev300** tab page, set the programming options. - - - **upload\_port**: Select the serial port number obtained in step [2](#en-us_topic_0000001057313128_li46411811196). - - **upload\_protocol**: Select the programming protocol **hiburn-usb**. - - **upload\_partitions**: Select the file to be programmed. By default, the **fastboot**, **kernel**, **rootfs**, and **userfs** files are programmed at the same time. - - ![](figures/en-us_image_0000001096963405.png) - -5. Switch between the **hi3518ev300\_fastboot**, **hi3518ev300\_kernel**, **hi3518ev300\_rootfs**, and **hi3518ev300\_userfs** tab pages, and modify the settings. In general cases, you can leave the fields at their default settings. To change the default settings, select the target item in the **New Option** field first. - - ![](figures/2021-01-28_112953.png) - -6. When you finish modifying, click **Save** in the upper right corner. - - ![](figures/2021-01-27_170334-5.png) - -7. Open the project file, go to ![](figures/2021-01-27_170334-6.png) \> **PROJECT TASKS** \> **partition:hi3518ev300\_fastboot** \> **Erase** to erase U-boot. - - ![](figures/2021-01-27_181047.png) - -8. When the following message is displayed, power off the development board and then power it on. - - ![](figures/en-us_image_0000001078089378.png) - -9. If the following message is displayed, it indicates that U-Boot is erased successfully. - - ![](figures/en-us_image_0000001073835952.png) - -10. Go to **env:hi3518ev300** \> **Upload** to start programming. - - ![](figures/en-us_image_0000001121061169.png) - -11. If the following message is displayed, it indicates that the programming is successful. - - ![](figures/en-us_image_0000001073242197.png) - - -## Running an Image - -1. Connect to a serial port. - - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >If the connection fails, rectify the fault by referring to [FAQs](../quick-start/faqs-2.md). - - **Figure 2** Serial port connection - - - ![](figures/chuankou1-7.png) - - 1. Click **Monitor** to enable the serial port. The **TERMINAL** window is displayed. - 2. Press **Enter** repeatedly until **hisilicon** displays. - 3. Go to [step 2](#li9441185382314) if the board is started for the first time or the startup parameters need to be modified; go to [step 3](#li6442853122312) otherwise. - -2. \(Mandatory for the first burning\) Modify the **bootcmd** and **bootargs** parameters of U-boot. This step is a fixed operation and the result can be saved. However, you need to perform the following steps again if U-boot needs to be reburnt. - - **Table 1** Parameters of the U-boot - - - - - - - - - - - - - - - - - - - - - - -

Command

-

Description

-

setenv bootcmd "sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000";

-

Run this command to set the content of bootcmd. Select the flash whose number is 0, and read content that has a size of 0x600000 (6 MB) and a start address of 0x100000 to memory address 0x40000000. The size must be the same as that of the OHOS_Image.bin file in the IDE.

-

setenv bootargs "console=ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7 M rootsize=8 M";

-

In this command, bootargs is set to the serial port output, the baud rate is 115200, the data bit is 8, and the rootfs is mounted to the flash memory. The file system type is set to jffs2 rw, which provides the read-write attribute for the JFFS2 file system. rootaddr=7 M rootsize=8 M indicates the actual start address and length of the rootfs.img file to be burnt, respectively. The file size must be the same as that of the rootfs.img file in the IDE.

-

saveenv

-

saveenv means to save the current configuration.

-

reset

-

reset means to reset the board.

-

pri

-

pri means to view the displayed parameters.

-
- - >![](public_sys-resources/icon-notice.gif) **NOTICE:** - >**go 0x40000000** \(optional\) indicates that the command is fixed in the startup parameters by default and the board automatically starts after it is reset. If you want to manually start the board, press **Enter** in the countdown phase of the U-boot startup to interrupt the automatic startup. - -3. If **hisilicon \#** is displayed during the startup, run the **reset** command. After the system automatically starts and **OHOS** is displayed, run the **./bin/helloworld** command and then press **Enter**. The system is started successfully if information shown in the following figure is displayed. - - **Figure 3** Successful system startup and program execution - ![](figures/successful-system-startup-and-program-execution-8.png "successful-system-startup-and-program-execution-8") - - -## Follow-up Learning - -Congratulations! You have finished all steps! You are advised to go on learning how to develop [Cameras with a Screen](../guide/cameras-with-a-screen.md). - diff --git a/en/device-dev/quick-start/running-a-hello-ohos-program-5.md b/en/device-dev/quick-start/running-a-hello-ohos-program-5.md index 713bd45a6bda1acfa95c9b2061669fd5475ebb1a..e3f5d5e2955b1b44c9999d567a171ca426f5104b 100644 --- a/en/device-dev/quick-start/running-a-hello-ohos-program-5.md +++ b/en/device-dev/quick-start/running-a-hello-ohos-program-5.md @@ -1,4 +1,4 @@ -# Running a Hello OHOS Program +# Running a Hello OHOS Program - [Creating a Program](#section1550972416485) - [Building](#section234175193114) @@ -46,9 +46,9 @@ This section describes how to create, compile, burn, and run the first program, } ``` -3. Add a new component. +3. Add a component. - Add the configuration of the **hello\_world\_app** component to the **build/lite/components/applications.json** file. The sample code below shows some configurations defined in the **applications.json** file, and the code between **\#\#start\#\#** and **\#\#end\#\#** is the new configuration \(Delete the rows where **\#\#start\#\#** and **\#\#end\#\#** are located after the configurations are added.\) + Add the configuration of the **hello\_world\_app** component to the **build/lite/components/applications.json** file. The sample code below shows some configurations defined in the **applications.json** file, and the code between **"\#\#start\#\#"** and **"\#\#end\#\#"** is the new configuration \(Delete the rows where **"\#\#start\#\#"** and **"\#\#end\#\#"** are located after the configurations are added.\) ``` { @@ -128,7 +128,7 @@ This section describes how to create, compile, burn, and run the first program, ## Building -If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/tool-acquisition.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: +If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: ``` hb set (Set the building path.) @@ -143,53 +143,53 @@ The result files are generated in the **out/hispark\_aries/ipcamera\_hispark\_a ![](figures/settings-4.png "settings-4") >![](public_sys-resources/icon-notice.gif) **NOTICE:** ->The U-boot file of the Hi3518E V300 development board can be obtained from the following path: device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin +>The U-Boot file of the Hi3518E V300 development board can be obtained from the following path: device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin ## Burning The USB port is the only burning mode supported by the Hi3518 development board. -1. Connect the PC and the target development board through the serial port and USB port. In this section, the Hi3518EV300 is used as an example. For details, please refer to [Introduction to the Hi3518 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_camera_start_hi3518-0000001050170473). +1. Connect the PC and the target development board through the serial port and USB port. In this section, the Hi3518EV300 is used as an example. For details, see [Introduction to the Hi3518 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des_3518-0000001105201138). 2. Open Device Manager, then check and record the serial port number corresponding to the development board. >![](public_sys-resources/icon-note.gif) **NOTE:** >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). - ![](figures/en-us_image_0000001073057176.png) + ![](figures/en-us_image_0000001128470900.png) 3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - ![](figures/en-us_image_0000001077956808.png) + ![](figures/en-us_image_0000001174350649.png) 4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. 5. On the **hi3518ev300** tab page, set the programming options. - - **upload\_port**: Select the serial port number obtained in step [2](#en-us_topic_0000001057313128_li46411811196). + - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001057313128_li46411811196). - **upload\_protocol**: Select the programming protocol **hiburn-usb**. - **upload\_partitions**: Select the file to be programmed. By default, the **fastboot**, **kernel**, **rootfs**, and **userfs** files are programmed at the same time. - ![](figures/en-us_image_0000001096963405.png) + ![](figures/en-us_image_0000001128311090.png) 6. When you finish modifying, click **Save** in the upper right corner. -7. Open the project file, go to ![](figures/2021-01-27_170334-5.png) \> **PROJECT TASKS** \> **hi3518ev300\_fastboot** \> **Erase** to erase U-boot. +7. Open the project file and click ![](figures/2021-01-27_170334-5.png). In the DevEco Device Tool window, choose **PROJECT TASKS** \> **hi3518ev300\_fastboot** \> **Erase** to erase U-Boot. - ![](figures/en-us_image_0000001163529159.png) + ![](figures/en-us_image_0000001174270731.png) 8. When the following message is displayed, power off the development board and then power it on. - ![](figures/en-us_image_0000001078089378.png) + ![](figures/en-us_image_0000001128311092.png) 9. If the following message is displayed, it indicates that U-Boot is erased successfully. - ![](figures/en-us_image_0000001073835952.png) + ![](figures/en-us_image_0000001128311094.png) 10. Go to **hi3518ev300** \> **Upload** to start programming. - ![](figures/en-us_image_0000001163568181.png) + ![](figures/en-us_image_0000001174350641.png) 11. If the following message is displayed, it indicates that the programming is successful. - ![](figures/en-us_image_0000001073242197.png) + ![](figures/en-us_image_0000001174350643.png) ## Running an Image @@ -208,9 +208,9 @@ The USB port is the only burning mode supported by the Hi3518 development board. 2. Press **Enter** repeatedly until **hisilicon** displays. 3. Go to [step 2](#li9441185382314) if the board is started for the first time or the startup parameters need to be modified; go to [step 3](#li6442853122312) otherwise. -2. \(Mandatory for the first burning\) Modify the **bootcmd** and **bootargs** parameters of U-boot. This step is a fixed operation and the result can be saved. However, you need to perform the following steps again if U-boot needs to be reburnt. +2. \(Mandatory for first-time burning\) Modify the **bootcmd** and **bootargs** parameters of U-Boot. This step is a fixed operation and the result can be saved. However, you need to perform the following steps again if U-Boot needs to be reburnt. - **Table 1** Parameters of the U-boot + **Table 1** Parameters of the U-Boot

Command

@@ -248,7 +248,7 @@ The USB port is the only burning mode supported by the Hi3518 development board.
>![](public_sys-resources/icon-notice.gif) **NOTICE:** - >**go 0x40000000** \(optional\) indicates that the command is fixed in the startup parameters by default and the board automatically starts after it is reset. If you want to manually start the board, press **Enter** in the countdown phase of the U-boot startup to interrupt the automatic startup. + >**go 0x40000000** \(optional\) indicates that the command is fixed in the startup parameters by default and the board automatically starts after it is reset. If you want to manually start the board, press **Enter** in the countdown phase of the U-Boot startup to interrupt the automatic startup. 3. If **hisilicon \#** is displayed during the startup, run the **reset** command. After the system automatically starts and **OHOS** is displayed, run the **./bin/helloworld** command and then press **Enter**. The system is started successfully if information shown in the following figure is displayed. diff --git a/en/device-dev/quick-start/running-a-hello-ohos-program.md b/en/device-dev/quick-start/running-a-hello-ohos-program.md index 5f38a61c19e21dfa897231cf60086708b586ca67..19bf8bf16abb4c45546b42a8d4bf1f5551ce19e1 100644 --- a/en/device-dev/quick-start/running-a-hello-ohos-program.md +++ b/en/device-dev/quick-start/running-a-hello-ohos-program.md @@ -1,4 +1,4 @@ -# Running a Hello OHOS Program +# Running a Hello OHOS Program - [Creating a Program](#section204672145202) - [Building](#section1077671315253) @@ -129,7 +129,7 @@ This section describes how to create, compile, burn, and run the first program, ## Building -If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/tool-acquisition.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: +If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). If the Linux environment is installed using a software package, go to the root directory of the source code and run the following commands for source code compilation: ``` hb set (Set the building path.) @@ -150,49 +150,49 @@ The result files are generated in the **out/hispark\_taurus/ipcamera\_hispark\_ The Hi3516 development board allows you to burn flash memory over the USB port, serial port, or network port. The following uses the network port burning as an example. -1. Connect the PC and the target development board through the power port, serial port, and network port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_camera_start_3516-0000001052670587). +1. Connect the PC and the target development board through the power port, serial port, and network port. In this section, the Hi3516DV300 is used as an example. For details, please refer to [Introduction to the Hi3516 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des_3516-0000001152041033). 2. Open Device Manager, then check and record the serial port number corresponding to the development board. >![](public_sys-resources/icon-note.gif) **NOTE:** >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3516 or Hi3518 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695). - ![](figures/en-us_image_0000001114129428.png) + ![](figures/en-us_image_0000001174350647.png) 3. Open DevEco Device Tool and go to **Projects** \> **Settings**. ![](figures/2021-01-27_170334.png) 4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. -5. On the **hi3516dv300** tab page, configure the programming options. +5. On the **hi3516dv300** tab page, set the programming options. - - **upload\_port**: Select the serial port number obtained in step [2](#en-us_topic_0000001056443961_li142386399535). + - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001056443961_li142386399535). - **upload\_protocol**: Select the programming protocol **hiburn-net**. - **upload\_partitions**: Select the file to be programmed. By default, the **fastboot**, **kernel**, **rootfs**, and **userfs** files are programmed at the same time. - ![](figures/en-us_image_0000001160529355.png) + ![](figures/en-us_image_0000001128470904.png) 6. Check and set the IP address of the network adapter connected to the development board. For details, see [Setting the IP Address of the Network Port for Programming on Hi3516](https://device.harmonyos.com/en/docs/ide/user-guides/set_ipaddress-0000001141825075). 7. Set the IP address of the network port for programming: - - **upload\_net\_server\_ip**: Select the IP address set in [6](#en-us_topic_0000001056443961_li1558813168234), such as 192.168.1.2. - - **upload\_net\_client\_mask**: Set the subnet mask of the development board, such as 255.255.255.0. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. - - **upload\_net\_client\_gw**: Set the gateway of the development board, such as 192.168.1.1. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. - - **upload\_net\_client\_ip**: Set the IP address of the development board, such as 192.168.1.3. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. + - **upload\_net\_server\_ip**: Select the IP address set in [6](#en-us_topic_0000001056443961_li1558813168234). Example: 192.168.1.2. + - **upload\_net\_client\_mask**: Set the subnet mask of the development board, such as 255.255.255.0. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 255.255.255.0. + - **upload\_net\_client\_gw**: Set the gateway of the development board, such as 192.168.1.1. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 192.168.1.1. + - **upload\_net\_client\_ip**: Set the IP address of the development board, such as 192.168.1.3. Once the **upload\_net\_server\_ip** field is set, this field will be automatically populated. Example: 192.168.1.3. - ![](figures/en-us_image_0000001117463460.png) + ![](figures/en-us_image_0000001174270733.png) 8. When you finish modifying, click **Save** in the upper right corner. -9. Open the project file and go to ![](figures/2021-01-27_170334-2.png) \> **PROJECT TASKS** \> **hi3516dv300** \> **Upload** to start programming. +9. Open the project file and click ![](figures/2021-01-27_170334-2.png). In the DevEco Device Tool window, choose **PROJECT TASKS** \> **hi3516dv300** \> **Upload** to start programming. - ![](figures/en-us_image_0000001116405268.png) + ![](figures/en-us_image_0000001174270729.png) 10. When the following message is displayed, power off the development board and then power it on. - ![](figures/en-us_image_0000001114129432.png) + ![](figures/en-us_image_0000001128470906.png) -11. Start programming. When the following message is displayed, it indicates that the programming is successful. +11. Start burning. When the following message is displayed, the burning is successful. - ![](figures/en-us_image_0000001113969542.png) + ![](figures/en-us_image_0000001128311098.png) ## Running an Image diff --git a/en/device-dev/quick-start/running-a-hello-world-program.md b/en/device-dev/quick-start/running-a-hello-world-program.md index 8cb794b97c38fb0ae33cc2c32b80370bb9245584..033f919351f898df2b656b5512bedf524a613adb 100644 --- a/en/device-dev/quick-start/running-a-hello-world-program.md +++ b/en/device-dev/quick-start/running-a-hello-world-program.md @@ -1,4 +1,4 @@ -# Running a Hello World Program +# Running a Hello World Program - [Modifying Source Code](#section79601457101015) - [Debugging and Verification](#section1621064881419) @@ -135,7 +135,7 @@ To parse the call stack information, the **Hi3861\_wifiiot\_app.asm** file is 3. Determine that an exception occurs in the **WadRecvCB** function based on the call stack information. - ![](figures/en-us_image_0000001152256221.png) + ![](figures/en-us_image_0000001174270737.png) 4. Check and modify the code. diff --git a/en/device-dev/quick-start/setting-up-the-environment-1.md b/en/device-dev/quick-start/setting-up-the-environment-1.md deleted file mode 100644 index 49586bc1993e592982cc191d1e38c96a1eaa8b89..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-the-environment-1.md +++ /dev/null @@ -1,151 +0,0 @@ -# Setting Up the Environment - -- [Environment Requirements](#section179175261196) - - [Hardware](#section5840424125014) - - [Software](#section965634210501) - -- [Installing Linux Build Tools](#section182916865219) - - [Changing Linux Shell to Bash](#section1715027152617) - - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section45512412251) - - [Installing a File Packing Tool](#section1969111820270) - - [Installing the JVM](#section1692618112713) - - -## Environment Requirements - -### Hardware - -- Hi3516D V300 IoT camera development board -- USB-to-serial cable and network cable \(The Windows workstation is connected to the Hi3516D V300 development board through the USB-to-serial cable and network cable.\) - -The following figure shows the hardware connections. - -**Figure 1** Hardware connections - - -![](figures/矩形备份-292.png) - -### Software - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->This section describes how to use an installation package to set up the compilation and development environment. If you are going to use Docker to set up the environment, skip this section and [Installing Linux Build Tools](#section182916865219). - -The following table describes the tools required for setting up the general environment for a Linux server of the Hi3516 development board and how to obtain these tools. - -**Table 1** Development tools and obtaining methods - - - - - - - - - - - - - - - - - - - - - - - - -

Development Tool

-

Description

-

How to Obtain

-

bash

-

Processes CLI commands.

-

System configuration

-

Basic software package for compilation and building (required only for Ubuntu 20+)

-

Provides a basic software package for compilation and building.

-

Internet

-

dosfstools, mtools, and mtd-utils

-

Pack files.

-

apt-get install

-

Java virtual machine (JVM)

-

Compiles, debugs, and runs Java programs.

-

apt-get install

-
- -## Installing Linux Build Tools - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install compilation tools like **LLVM** and **hc-gen**. ->- \(Recommended\) If you obtain the source code through an image site or a code repository, you should install **hc-gen**. When installing the compilation tool, ensure that its environment variable path is unique. - -### Changing Linux Shell to Bash - -Check whether bash is used as the shell. - -``` -ls -l /bin/sh -``` - -If **/bin/sh -\> bash** is not displayed, do as follows to change shell to bash. - -**Method 1:** Run the following command on the device and then click **No**. - -``` -sudo dpkg-reconfigure dash -``` - -**Method 2:** Run the first command to delete **sh** and then run the second command to create a new soft link. - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) - -Install the software. - -``` -sudo apt-get install build-essential && sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install make && sudo apt-get install zlib* && sudo apt-get install libffi-dev -``` - -### Installing a File Packing Tool - -1. Start a Linux server. -2. Install **dosfstools**. - - ``` - sudo apt-get install dosfstools - ``` - -3. Install **mtools**. - - ``` - sudo apt-get install mtools - ``` - -4. Install **mtd-utils**. - - ``` - sudo apt-get install mtd-utils - ``` - - -### Installing the JVM - -1. Start a Linux server. -2. Install the Java Runtime Environment \(JRE\). - - ``` - sudo apt-get install default-jre - ``` - -3. Install the Java Development Kit \(JDK\). - - ``` - sudo apt-get install default-jdk - ``` - - diff --git a/en/device-dev/quick-start/setting-up-the-environment-2.md b/en/device-dev/quick-start/setting-up-the-environment-2.md index 1c3604b02e1ab335b5ae9d4480b59826bccbe253..0e8430d75a7fa0bfe54420a0fcb8638108732710 100644 --- a/en/device-dev/quick-start/setting-up-the-environment-2.md +++ b/en/device-dev/quick-start/setting-up-the-environment-2.md @@ -1,4 +1,4 @@ -# Setting Up the Environment +# Setting Up the Environment - [Environment Requirements](#section179175261196) - [Hardware](#section5840424125014) diff --git a/en/device-dev/quick-start/setting-up-the-environment-3.md b/en/device-dev/quick-start/setting-up-the-environment-3.md deleted file mode 100644 index 7f27e367398083b4f12aa2f2346b449b73d56109..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/setting-up-the-environment-3.md +++ /dev/null @@ -1,156 +0,0 @@ -# Setting Up the Environment - -- [Environment Requirements](#section1724111409282) - - [Hardware](#section487353718276) - - [Software Requirements](#section17315193935817) - -- [Installing Linux Build Tools](#section8831868501) - - [Changing Linux Shell to Bash](#section1715027152617) - - [Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\)](#section45512412251) - - [Installing a File Packing Tool](#section1686964015274) - - [Installing hc-gen](#section18706403274) - - -## Environment Requirements - -### Hardware - -- Hi3518E V300 IoT camera development board -- USB-to-serial cable and network cable \(The Windows workstation is connected to the Hi3518E V300 development board through the USB-to-serial cable and network cable.\) - - The following figure shows the hardware connections. - - -**Figure 1** Hardware connections -![](figures/hardware-connections-3.png "hardware-connections-3") - -### Software Requirements - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->This section describes how to use an installation package to set up the compilation and development environment. If you are going to use Docker to set up the environment, skip this section and [Installing Linux Build Tools](#section8831868501). - -The following table describes the tools required for setting up the general environment for a Linux server of the Hi3518 development board and how to obtain these tools. - -**Table 1** Development tools and obtaining methods - - - - - - - - - - - - - - - - - - - - -

Development Tool

-

Description

-

How to Obtain

-

bash

-

Processes CLI commands.

-

System configuration

-

Basic software package for compilation and building (required only for Ubuntu 20+)

-

Provides a basic software package for compilation and building.

-

Internet

-

dosfstools, mtools, and mtd-utils

-

Pack files.

-

apt-get install

-
- -## Installing Linux Build Tools - ->![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- If you acquire the source code using an HPM component or HPM CLI tool, you do not need to install **hc-gen**. ->- \(Recommended\) If you obtain the source code through an image site or a code repository, you should install the compilation tool **hc-gen**. When installing the compilation tool, ensure that its environment variable path is unique. - -### Changing Linux Shell to Bash - -Check whether bash is used as the shell. - -``` -ls -l /bin/sh -``` - -If **/bin/sh -\> bash** is not displayed, do as follows to change shell to bash. - -**Method 1:** Run the following command on the device and then click **No**. - -``` -sudo dpkg-reconfigure dash -``` - -**Method 2:** Run the first command to delete **sh** and then run the second command to create a new soft link. - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### Installing Basic Software Used for Compilation and Building \(Required Only for Ubuntu 20+\) - -Install the software. - -``` -sudo apt-get install build-essential && sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install make && sudo apt-get install zlib* && sudo apt-get install libffi-dev -``` - -### Installing a File Packing Tool - -1. Start a Linux server. -2. Install **dosfstools**. - - ``` - sudo apt-get install dosfstools - ``` - -3. Install **mtools**. - - ``` - sudo apt-get install mtools - ``` - -4. Install **mtd-utils**. - - ``` - sudo apt-get install mtd-utils - ``` - - -### Installing hc-gen - -1. Start a Linux server. -2. Download [hc-gen](https://repo.huaweicloud.com/harmonyos/compiler/hc-gen/0.65/linux/hc-gen-0.65-linux.tar). -3. Decompress the hc-gen installation package to **\~/hc-gen** on the Linux server. - - ``` - tar -xvf hc-gen-0.65-linux.tar -C ~/ - ``` - -4. Set an environment variable. - - ``` - vim ~/.bashrc - ``` - - Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - - ``` - export PATH=~/hc-gen:$PATH - ``` - -5. Validate the environment variable. - - ``` - source ~/.bashrc - ``` - - diff --git a/en/device-dev/quick-start/setting-up-the-environment-4.md b/en/device-dev/quick-start/setting-up-the-environment-4.md index e8938baf915d5fc9fad719a6c46684307c607d56..606871622b0805662544e092fd9c1e64e4f1cb27 100644 --- a/en/device-dev/quick-start/setting-up-the-environment-4.md +++ b/en/device-dev/quick-start/setting-up-the-environment-4.md @@ -1,4 +1,4 @@ -# Setting Up the Environment +# Setting Up the Environment - [Environment Requirements](#section1724111409282) - [Hardware](#section487353718276) diff --git a/en/device-dev/quick-start/setting-up-the-environment.md b/en/device-dev/quick-start/setting-up-the-environment.md index 382dc5ac66d2cd78bfb6bd1e307b9a362b1aafee..9eb8b040c6320fb44813778e45d0cfe647623a74 100644 --- a/en/device-dev/quick-start/setting-up-the-environment.md +++ b/en/device-dev/quick-start/setting-up-the-environment.md @@ -1,4 +1,4 @@ -# Setting Up the Environment +# Setting Up the Environment - [Environment Requirements](#section466851916410) - [Hardware](#section19202111020215) @@ -362,6 +362,6 @@ Perform the following operations on the Windows station. 2. Install the driver. 3. After the driver is installed, remove and then insert the USB cable. The serial port entry should be displayed as shown in the following figure. - ![](figures/en-us_image_0000001057235392.png) + ![](figures/en-us_image_0000001174350633.png) diff --git a/en/device-dev/quick-start/setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md b/en/device-dev/quick-start/setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md new file mode 100644 index 0000000000000000000000000000000000000000..0a3ca86c3294e3af31e06cd636d3c886c897ce94 --- /dev/null +++ b/en/device-dev/quick-start/setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md @@ -0,0 +1,118 @@ +# Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code + +- [Obtaining Standard-System Source Code](#section8761819202511) + - [Prerequisites](#section102871547153314) + - [Procedure](#section429012478331) + +- [Obtaining the Docker Environment](#section181431248132513) +- [Building Source Code](#section92391739152318) + +The standard OpenHarmony system provides a Docker environment which encapsulates build tools. + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>- Before using Docker, install it by following instructions in [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/). +>- You can also use the [installation package](setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md) to set up the Ubuntu development environment. + +## Obtaining Standard-System Source Code + +### Prerequisites + +1. Register your account with Gitee. +2. Register an SSH public key for access to Gitee. +3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)), and configure basic user information. + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. Run the following commands to install the **repo** tool: + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### Procedure + +Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +Method 2: Use the **repo** tool to download the source code over HTTPS. + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## Obtaining the Docker Environment + +**Method 1: Obtaining the Docker image from HUAWEI CLOUD SWR** + +1. Obtain the Docker image. + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**Method 2: Using the Dockerfile to build a local docker image** + +1. Obtain the Dockerfile script for a local Docker image. + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. Go to the directory of the Dockerfile code and run the following command to build the Docker image: + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. Go to the root directory of OpenHarmony code and run the following command to access the Docker build environment: + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +## Building Source Code + +1. Run the preprocessing script in the root directory of the source code. + + ``` + ../scripts/prepare.sh + ``` + +2. Run the following script to start building for Standard-System Devices \(reference memory ≥ 128 MB\): + + ``` + ./build.sh --product-name {product_name} + ``` + + **product\_name** indicates the product supported by the current distribution, for example, **Hi3516DV300**. + + Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + +3. Burn the image. For details, see [Burning Images](burning-images.md). + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>You can exit Docker by simply running the **exit** command. + diff --git a/en/device-dev/quick-start/setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md b/en/device-dev/quick-start/setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md new file mode 100644 index 0000000000000000000000000000000000000000..0aaa9188a038d1279efdb270e4ffc2ac04ea2273 --- /dev/null +++ b/en/device-dev/quick-start/setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md @@ -0,0 +1,98 @@ +# Setting Up Ubuntu Development Environment with Installation Package and Building Source Code + +- [Installing Dependent Tools](#section18431165519244) +- [Obtaining Standard-System Source Code](#section113751052102517) + - [Prerequisites](#section102871547153314) + - [Procedure](#section429012478331) + +- [Running prebuilts](#section0495320152619) +- [Building Source Code](#section1664835963517) + +## Installing Dependent Tools + +The installation command is as follows: + +``` +sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip +``` + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The preceding command is applicable to Ubuntu 18.04. For other Ubuntu versions, modify the preceding installation command based on the installation package name. + +## Obtaining Standard-System Source Code + +### Prerequisites + +1. Register your account with Gitee. +2. Register an SSH public key for access to Gitee. +3. Install the [git client](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading)), and configure basic user information. + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. Run the following commands to install the **repo** tool: + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo # If you do not have the access permission to this directory, download the tool to any other accessible directory and configure the directory to the environment variable. + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### Procedure + +Method 1 \(recommended\): Use the **repo** tool to download the source code over SSH. \(You must have registered an SSH public key for access to Gitee.\) + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +Method 2: Use the **repo** tool to download the source code over HTTPS. + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## Running prebuilts + +Go to the root directory of the source code and run the following script to install the compiler and binary tool: + +``` +bash build/prebuilts_download.sh +``` + +By default, the downloaded prebuilts binary file is stored in **OpenHarmony\_2.0\_canary\_prebuilts** \(which is in the same directory as **OpenHarmony**\). + +## Building Source Code + +Perform the following operations in the Linux environment: + +1. Go to the root directory of the source code and run the following command to build the distribution. + + ``` + ./build.sh --product-name {product_name} + ``` + + **product\_name** indicates the product supported by the current distribution, for example, **Hi3516DV300**. + +2. Check the build result. After the build is complete, the following information is displayed in the log: + + ``` + build system image successful. + =====build Hi3516DV300 successful. + ``` + + Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. + + >![](public_sys-resources/icon-note.gif) **NOTE:** + >For details about module-specific build operations, see [Compilation and Building Overview](../subsystems/building-guidelines-for-the-standard-system.md). + +3. Burn the image. For details, see [Burning Images](burning-images.md). + diff --git a/en/device-dev/quick-start/windows-development-environment-9.md b/en/device-dev/quick-start/setting-up-windows-development-environment.md similarity index 99% rename from en/device-dev/quick-start/windows-development-environment-9.md rename to en/device-dev/quick-start/setting-up-windows-development-environment.md index 91c42c4f088d5f467479bb40cd1819e67277cfe4..4308389e169c415c5a502738359d0eed094fd3fc 100644 --- a/en/device-dev/quick-start/windows-development-environment-9.md +++ b/en/device-dev/quick-start/setting-up-windows-development-environment.md @@ -1,4 +1,4 @@ -# Windows Development Environment +# Setting Up Windows Development Environment - [Obtaining the Software](#en-us_topic_0000001058091994_section1483143015558) - [Installing Visual Studio Code](#en-us_topic_0000001058091994_section71401018163318) diff --git a/en/device-dev/quick-start/standard-system.md b/en/device-dev/quick-start/standard-system.md index 33f6ed2a876d5ef8f93d7ee22c0546ea37ba9c67..f0aa95fdac24012324baa361c8958305bcfd436f 100644 --- a/en/device-dev/quick-start/standard-system.md +++ b/en/device-dev/quick-start/standard-system.md @@ -1,9 +1,15 @@ # Standard System -- **[Overview](overview-7.md)** +- **[Introduction](introduction.md)** -- **[Environment Setup](environment-setup-8.md)** +- **[Setting Up Windows Development Environment](setting-up-windows-development-environment.md)** -- **[How to Develop](how-to-develop-12.md)** +- **[Setting Up Ubuntu Development Environment in Docker Mode and Building Source Code](setting-up-ubuntu-development-environment-in-docker-mode-and-building-source-code.md)** + +- **[Setting Up Ubuntu Development Environment with Installation Package and Building Source Code](setting-up-ubuntu-development-environment-with-installation-package-and-building-source-code.md)** + +- **[Burning Images](burning-images.md)** + +- **[FAQs](faqs-7.md)** diff --git a/en/device-dev/quick-start/ubuntu-build-environment-10.md b/en/device-dev/quick-start/ubuntu-build-environment-10.md deleted file mode 100644 index 6b44c27dfc7b0a91a0564f60fd486865db8b242b..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/ubuntu-build-environment-10.md +++ /dev/null @@ -1,149 +0,0 @@ -# Ubuntu Build Environment - -- [Setting up a Ubuntu Build Environment Using a Docker Environment](#section1643363843714) - - [Obtaining System Source Code](#section58448331029) - - [Installing and Using the Docker Environment](#section22916211916) - -- [Setting up a Ubuntu Build Environment Using an Installation Package](#section25961010189) - - [Obtaining Standard-System Source Code](#section15424183111912) - - [Installing Dependent Tools](#section109262032104819) - - [Obtaining prebuilts](#section16453104219209) - - [Configuring the Node.js Environment and Obtaining the Node\_modules Dependency Package](#section133741330192119) - - [Installing the hc-gen Tool](#section149281248182116) - - -You can use either the Docker environment or installation package provided by OpenHarmony to set up a Ubuntu build environment. This section describes the two methods. - -## Setting up a Ubuntu Build Environment Using a Docker Environment - -The standard OpenHarmony system provides a Docker environment which encapsulates build tools. To use the Docker environment, perform the following steps: - -1. Obtain the system source code. -2. Install and use the Docker environment. - -### Obtaining System Source Code - -For details, see [Source Code Acquisition](../get-code/source-code-acquisition.md). - -### Installing and Using the Docker Environment - -For details, see [Installing and Using Docker](../get-code/tool-acquisition.md). - -## Setting up a Ubuntu Build Environment Using an Installation Package - -The procedure is as follows: - -1. Obtain the system source code. -2. Install dependent tools. -3. Obtain prebuilts. -4. Configure the Node.js environment and obtain the Node\_modules dependency package. -5. Install the hc-gen tool. - -### Obtaining Standard-System Source Code - -For details, see [Source Code Acquisition](../get-code/source-code-acquisition.md). - -### Installing Dependent Tools - -The installation command is as follows: - -``` -sudo apt-get install binutils git-core 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 lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 python2.7 python-minimal -``` - -### Obtaining prebuilts - -1. Go to the OpenHarmony working directory. - - ``` - cd OpenHarmony - ``` - -2. Download the script. - - ``` - curl https://gitee.com/landwind/script-tools/raw/master/Shell/OpenHarmony/OpenHarmony_2.0_canary_prebuilts_download.sh >./prebuilts_download.sh - ``` - -3. Download and decompress the prebuilts package in a specified directory. - - ``` - bash ./prebuilts_download.sh - ``` - - By default, binary files are stored in the **OpenHarmony\_2.0\_canary\_prebuilts** directory, which is in the same directory as **OpenHarmony**. To change the storage path, change the value of **bin\_dir** in **prebuilts\_download.sh**. - -4. Return to the previous directory. - - ``` - cd - - ``` - - -### Configuring the Node.js Environment and Obtaining the Node\_modules Dependency Package - -To build the JS framework, you need to download and configure Node.js on a Linux server. The procedure is as follows: - -1. Download Node.js on a Linux server. - - ``` - mkdir -p OpenHarmony/prebuilts/build-tools/common/nodejs # Create the nodejs directory. - cd OpenHarmony/prebuilts/build-tools/common/nodejs # Go to the nodejs directory. - wget --no-check-certificate https://nodejs.org/download/release/v12.18.4/node-v12.18.4-linux-x64.tar.gz # Download the Node.js package. - ``` - -2. Decompress the Node.js package and configure the Node.js environment. - - ``` - tar -zxvf node-v12.18.4-linux-x64.tar.gz # Decompress the Node.js package. - echo "export PATH=`pwd`/node-v12.18.4-linux-x64/bin:${PATH}" >> ~/.bashrc;source ~/.bashrc # Set a Node.js environment variable. - cd - # Return to the previous directory. - ``` - -3. Go to the **third\_party/jsframework** directory of the OpenHarmony code and download the **node\_modules** package. - - ``` - cd OpenHarmony/third_party/jsframework # Go to the jsframework directory. - npm install # Download the node_modules package. - cd - # Return to the previous directory. - ``` - -4. Store the **node\_modules** package in the **prebuilts/build-tools/common/js-framework** directory of the OpenHarmony code. - - ``` - mkdir -p OpenHarmony/prebuilts/build-tools/common/js-framework # Create the js-framework directory. - cp -rp OpenHarmony/third_party/jsframework/node_modules OpenHarmony/prebuilts/build-tools/common/js-framework/ - ``` - - -### Installing the hc-gen Tool - -hc-gen is used to compile the driver. To install hc-gen, perform the following steps: - -1. Start a Linux server. -2. Download [hc-gen](https://repo.huaweicloud.com/harmonyos/compiler/hc-gen/0.65/linux/hc-gen-0.65-linux.tar). -3. Decompress the hc-gen installation package to **\~/hc-gen** on the Linux server. - - ``` - tar -xvf hc-gen-0.65-linux.tar -C ~/ - ``` - -4. Set an environment variable. - - ``` - vim ~/.bashrc - ``` - - Copy the following command to the last line of the **.bashrc** file, save the file, and exit. - - ``` - export PATH=~/hc-gen:$PATH - ``` - -5. Validate the environment variable. - - ``` - source ~/.bashrc - ``` - - diff --git a/en/device-dev/quick-start/ubuntu-build-environment.md b/en/device-dev/quick-start/ubuntu-build-environment.md index 9c141637b5a7efad7834c91138be34c9a648f4f6..57782ef1846c3626ae726276bb36dd66aa163c9b 100644 --- a/en/device-dev/quick-start/ubuntu-build-environment.md +++ b/en/device-dev/quick-start/ubuntu-build-environment.md @@ -1,4 +1,4 @@ -# Ubuntu Build Environment +# Ubuntu Build Environment - [Obtaining Source Code and Tools](#section1897711811517) - [Obtaining Source Code](#section1545225464016) @@ -24,9 +24,9 @@ Perform the following steps to set up the build environment: 6. Install hb. >![](public_sys-resources/icon-notice.gif) **NOTICE:** ->- Docker is provided for the Ubuntu build environment, which encapsulates related build tools. If you use Docker to prepare the build environment, you do not need to perform the following steps in this section. Instead, refer to [Using Docker to Prepare the Build Environment](../get-code/tool-acquisition.md). +>- Docker is provided for the Ubuntu build environment, which encapsulates related build tools. If you use Docker to prepare the build environment, you do not need to perform the following steps in this section. Instead, refer to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). >- By default, basic software, such as Samba and Vim, is installed in the system. Adaptation on the software is required to support file sharing between the Linux server and the Windows workstation. ->- For details about the compilation and building subsystem of OpenHarmony, see the [Compilation and Building Overview](../subsystems/compilation-and-building-overview.md). +>- For details about the compilation and building subsystem of OpenHarmony, see the [Compilation and Building Overview](../subsystems/compilation-and-building.md). ## Obtaining Source Code and Tools diff --git a/en/device-dev/quick-start/windows-development-environment-10.md b/en/device-dev/quick-start/windows-development-environment-10.md deleted file mode 100644 index 91c42c4f088d5f467479bb40cd1819e67277cfe4..0000000000000000000000000000000000000000 --- a/en/device-dev/quick-start/windows-development-environment-10.md +++ /dev/null @@ -1,183 +0,0 @@ -# Windows Development Environment - -- [Obtaining the Software](#en-us_topic_0000001058091994_section1483143015558) -- [Installing Visual Studio Code](#en-us_topic_0000001058091994_section71401018163318) -- [Installing Python](#en-us_topic_0000001058091994_section16266553175320) -- [Installing Node.js](#en-us_topic_0000001058091994_section5353233124511) -- [Installing hpm](#en-us_topic_0000001058091994_section173054793610) -- [Installing the DevEco Device Tool Plug-in](#en-us_topic_0000001058091994_section4336315185716) - -Operating system: 64-bit version of Windows 10. - -DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedure includes five parts: - -1. Installing Visual Studio Code -2. Installing Python -3. Installing Node.js -4. Installing hpm -5. Installing the DevEco Device Tool Plug-in - -## Obtaining the Software - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Tool

-

Description

-

Version

-

Obtaining Channel

-

Visual Studio Code

-

Code editing tool

-

V1.53 or later (64-bit)

-

https://code.visualstudio.com/Download

-

Python

-

Programming tool

-

v3.7.4–3.8.x (64-bit)

-

https://www.python.org/downloads/

-

Node.js

-

The npm environment provider

-

v12.0.0 or later (64-bit)

-

https://nodejs.org/en/download/

-

hpm

-

Package manager

-

Latest version

-

Run the following command:

-
npm install -g @ohos/hpm-cli
-

DevEco Device Tool

-

Plug-in for the OpenHarmony source code compilation, programming, and debugging

-

v2.2 Beta1

-

https://device.harmonyos.com/en/ide#download

-

Log in with your HUAWEI ID to download it. You can register an account here.

-
- -## Installing Visual Studio Code - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If you have installed Visual Studio Code, open the CLT and run **code --version** to check whether the version is 1.53 or later. If the version number is returned, it indicates that the environment variables are set correctly. - -1. Double-click the Visual Studio Code package to install it. During the installation, select **Add to PATH \(requires shell restart\)**. - - ![](figures/en-us_image_0000001057335403.png) - -2. After the installation is complete, restart the computer for the environment variables of Visual Studio Code to take effect. -3. Open the CLT and run **code --version**. If the version number can be displayed, it indicates that the installation is successful. - -## Installing Python - -1. Double-click the Python software package, select **Add Python xx to PATH**, and click **Install Now**. - - ![](figures/en-us_image_0000001096154076.png) - -2. After the installation is complete, click **Close**. - - ![](figures/en-us_image_0000001142794291.png) - -3. Open the CLT, and run **python --version** to check the installation result. - - ![](figures/en-us_image_0000001143154485.png) - -4. In the CLT, run the following commands to set the pip source for downloading the dependencies required for later installation: - - ``` - pip config set global.trusted-host repo.huaweicloud.com - pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple - pip config set global.timeout 120 - ``` - - -## Installing Node.js - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If you have installed Node.js, open the CLT and run **node -v** to check whether the version is 12.0.0 or later. - -1. Run the downloaded software package to install. Use the default settings when following the installation wizard, and click **Next** until **Finish** is displayed. During the installation, Node.js will automatically set the system Path environment variable to the installation directory of **node.exe**. -2. Open the CLT and run **node -v**. If the version number of Node.js is displayed, it indicates that Node.js has been successfully installed. - - ![](figures/en-us_image_0000001056814287.png) - - -## Installing hpm - -Before installing hpm, ensure that Node.js has been installed - -and that your network can access the Internet. If your network requires a proxy to access the Internet, [set up the npm proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032) first. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->If hpm has been installed, run **npm update -g @ohos/hpm-cli** to update it to the latest version. - -1. You are advised to set the npm source to an image in China, for example, a HUAWEI CLOUD image source. - - ``` - npm config set registry https://repo.huaweicloud.com/repository/npm/ - ``` - -2. Open the CLT and run the following command to install the latest version of hpm: - - ``` - npm install -g @ohos/hpm-cli - ``` - - ![](figures/en-us_image_0000001073840162.png) - -3. After the installation is complete, run the following command to obtain the installation result: - - ``` - hpm -V - ``` - - ![](figures/en-us_image_0000001100641602.png) - - -## Installing the DevEco Device Tool Plug-in - -To install the DevEco Device Tool plug-in, ensure that the **user name of the host cannot contain Chinese characters**; otherwise, the plug-in may fail to run. - -DevEco Device Tool will automatically download and install the C/C++ and CodeLLDB plug-ins from the Visual Studio Code Marketplace during the installation process. Therefore, make sure Visual Studio Code can access the Internet. If your network requires a proxy to access the Internet, [set up the Visual Studio Code proxy](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144) first. - ->![](public_sys-resources/icon-note.gif) **NOTE:** ->Before installing DevEco Device Tool, ensure that Visual Studio Code is closed. - -1. Decompress the DevEco Device Tool plug-in package and double-click the installer to install. -2. During the installation, the dependency files \(such as C/C++ and CodeLLDB plug-ins\) and execution programs required by DevEco Device Tool are automatically installed. - - ![](figures/en-us_image_0000001072468991.png) - -3. After the installation is complete, the CLT is automatically closed. -4. Open Visual Studio Code, click the ![](figures/en-us_image_0000001072757874.png) button on the left, and check whether C/C++, CodeLLDB, and DevEco Device Tool are listed in **INSTALLED**. - - >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the C/C++ and CodeLLDB plug-ins fail to be installed, DevEco Device Tool cannot run properly. To solve the issue, see [Installing the C/C++ and CodeLLDB Plug-ins Offline](https://device.harmonyos.com/en/docs/ide/user-guides/offline_plugin_install-0000001074376846). - - ![](figures/en-us_image_0000001142802505.png) - - diff --git a/en/device-dev/quick-start/windows-development-environment.md b/en/device-dev/quick-start/windows-development-environment.md index 9480f387cd1291caf27824c9edacdadc3f78587d..d0824ce00ea9573806c2a4c75f1df00a2de9aa0e 100644 --- a/en/device-dev/quick-start/windows-development-environment.md +++ b/en/device-dev/quick-start/windows-development-environment.md @@ -1,4 +1,4 @@ -# Windows Development Environment +# Windows Development Environment - [Obtaining the Software](#en-us_topic_0000001058091994_section1483143015558) - [Installing Visual Studio Code](#en-us_topic_0000001058091994_section71401018163318) @@ -87,7 +87,7 @@ DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedu 1. Double-click the Visual Studio Code package to install it. During the installation, select **Add to PATH \(requires shell restart\)**. - ![](figures/en-us_image_0000001057335403.png) + ![](figures/en-us_image_0000001174350653.png) 2. After the installation is complete, restart the computer for the environment variables of Visual Studio Code to take effect. 3. Open the CLT and run **code --version**. If the version number can be displayed, it indicates that the installation is successful. @@ -96,15 +96,15 @@ DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedu 1. Double-click the Python software package, select **Add Python xx to PATH**, and click **Install Now**. - ![](figures/en-us_image_0000001096154076.png) + ![](figures/en-us_image_0000001128471042.png) 2. After the installation is complete, click **Close**. - ![](figures/en-us_image_0000001142794291.png) + ![](figures/en-us_image_0000001128311104.png) 3. Open the CLT, and run **python --version** to check the installation result. - ![](figures/en-us_image_0000001143154485.png) + ![](figures/en-us_image_0000001174350781.png) 4. In the CLT, run the following commands to set the pip source for downloading the dependencies required for later installation: @@ -123,7 +123,7 @@ DevEco Device Tool is a plug-in for Visual Studio Code. The installation procedu 1. Run the downloaded software package to install. Use the default settings when following the installation wizard, and click **Next** until **Finish** is displayed. During the installation, Node.js will automatically set the system Path environment variable to the installation directory of **node.exe**. 2. Open the CLT and run **node -v**. If the version number of Node.js is displayed, it indicates that Node.js has been successfully installed. - ![](figures/en-us_image_0000001056814287.png) + ![](figures/en-us_image_0000001128311096.png) ## Installing hpm @@ -147,7 +147,7 @@ and that your network can access the Internet. If your network requires a proxy npm install -g @ohos/hpm-cli ``` - ![](figures/en-us_image_0000001073840162.png) + ![](figures/en-us_image_0000001128311100.png) 3. After the installation is complete, run the following command to obtain the installation result: @@ -155,7 +155,7 @@ and that your network can access the Internet. If your network requires a proxy hpm -V ``` - ![](figures/en-us_image_0000001100641602.png) + ![](figures/en-us_image_0000001174270735.png) ## Installing the DevEco Device Tool Plug-in @@ -170,14 +170,14 @@ DevEco Device Tool will automatically download and install the C/C++ and CodeLLD 1. Decompress the DevEco Device Tool plug-in package and double-click the installer to install. 2. During the installation, the dependency files \(such as C/C++ and CodeLLDB plug-ins\) and execution programs required by DevEco Device Tool are automatically installed. - ![](figures/en-us_image_0000001072468991.png) + ![](figures/en-us_image_0000001128470902.png) 3. After the installation is complete, the CLT is automatically closed. -4. Open Visual Studio Code, click the ![](figures/en-us_image_0000001072757874.png) button on the left, and check whether C/C++, CodeLLDB, and DevEco Device Tool are listed in **INSTALLED**. +4. Open Visual Studio Code, click the ![](figures/en-us_image_0000001174350651.png) button on the left, and check whether C/C++, CodeLLDB, and DevEco Device Tool are listed in **INSTALLED**. >![](public_sys-resources/icon-note.gif) **NOTE:** >If the C/C++ and CodeLLDB plug-ins fail to be installed, DevEco Device Tool cannot run properly. To solve the issue, see [Installing the C/C++ and CodeLLDB Plug-ins Offline](https://device.harmonyos.com/en/docs/ide/user-guides/offline_plugin_install-0000001074376846). - ![](figures/en-us_image_0000001142802505.png) + ![](figures/en-us_image_0000001174270727.png) diff --git a/en/device-dev/quick-start/wlan-connection.md b/en/device-dev/quick-start/wlan-connection.md index cc0192a6873b1b66a3224c224b63dab3aabb06ef..6869012b733851e1555efbf1cce23ea5c51f7317 100644 --- a/en/device-dev/quick-start/wlan-connection.md +++ b/en/device-dev/quick-start/wlan-connection.md @@ -1,4 +1,4 @@ -# WLAN Connection +# WLAN Connection - [Building](#section191121332125319) - [Burning Images](#section19458165166) @@ -10,7 +10,7 @@ This example shows how to connect the WLAN module to the gateway using attention This section describes how to perform the WLAN module building on a Linux server. -If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/tool-acquisition.md). If the Linux environment is installed using a software package, perform the following steps: +If the Linux environment is installed using Docker, perform the building by referring to [Using Docker to Prepare the Build Environment](../get-code/docker-environment.md). If the Linux environment is installed using a software package, perform the following steps: 1. Open the HUAWEI DevEco Device Tool and choose **View** \> **Terminal**. @@ -63,39 +63,39 @@ If the Linux environment is installed using Docker, perform the building by refe You can use the DevEco tool to perform the image burning of the Hi3861 WLAN module. For details about how to use the tool, see [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). -1. Connect the PC and the target development board through the USB port. For details, please refer to [Introduction to the Hi3861 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_wifi_start_des-0000001050168548). +1. Connect the PC and the target development board through the USB port. For details, please refer to [Introduction to the Hi3861 Development Board](https://device.harmonyos.com/en/docs/start/introduce/oem_minitinier_des_3861-0000001105041324). 2. Open Device Manager, then check and record the serial port number corresponding to the development board. >![](public_sys-resources/icon-note.gif) **NOTE:** - >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3861 Series Development Boards](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3861-drivers-0000001058153433). + >If the serial port number is not displayed correctly, follow the steps described in [Installing the Serial Port Driver on the Hi3861 Series Development Boards](https://device.harmonyos.com/en/docs/ide/user-guides/hi3861-drivers-0000001058153433). - ![](figures/en-us_image_0000001073388838.png) + ![](figures/en-us_image_0000001128311118.png) 3. Open DevEco Device Tool and go to **Projects** \> **Settings**. - ![](figures/en-us_image_0000001078404538.png) + ![](figures/en-us_image_0000001128311116.png) 4. On the **Partition Configuration** tab page, modify the settings. In general cases, you can leave the fields at their default settings. 5. On the **hi3861** tab page, set the programming options. - - **upload\_port**: Select the serial port number obtained in step [2](#en-us_topic_0000001056563976_li848662117291). - - **upload\_protocol**: Select the programming protocol **burn-serial**. - - **upload\_partitions**: Select the file to be programmed. **hi3861\_app** is selected by default. + - **upload\_port**: Select the serial port number obtained in [2](#en-us_topic_0000001056563976_li848662117291). + - **upload\_protocol**: Select the burning protocol **burn-serial**. + - **upload\_partitions**: Select the file to be burned. **hi3861\_app** is selected by default. - ![](figures/en-us_image_0000001078244328.png) + ![](figures/en-us_image_0000001128470922.png) 6. When you finish modifying, click **Save** in the upper right corner. 7. Open the project file. In the DevEco Device Tool window, go to **PROJECT TASKS** \> **hi3861** \> **Upload** to start programming. - ![](figures/en-us_image_0000001163569275.png) + ![](figures/en-us_image_0000001174270749.png) 8. When the following information is displayed, press the RST button on the development board to restart it. - ![](figures/en-us_image_0000001074285712.png) + ![](figures/en-us_image_0000001174270751.png) -9. Start programming. When the following message is displayed, it indicates that the programming is successful. +9. Start burning. When the following message is displayed, the burning is successful. - ![](figures/en-us_image_0000001074445364.png) + ![](figures/en-us_image_0000001174350669.png) ## Connecting WLAN Module to the Internet. diff --git a/en/device-dev/subsystems/Readme-EN.md b/en/device-dev/subsystems/Readme-EN.md index 9c21a040f361f15efc66c5fb965c8fff8de6532b..88e792a04740b935dedc3a7ddbbb1810da26c371 100644 --- a/en/device-dev/subsystems/Readme-EN.md +++ b/en/device-dev/subsystems/Readme-EN.md @@ -2,17 +2,15 @@ - [Compilation and Building](compilation-and-building.md) - [Building Guidelines for Mini and Small Systems](building-guidelines-for-mini-and-small-systems.md) - - [Compilation and Building Overview](compilation-and-building-overview.md) - - [Compilation and Building Guidelines](compilation-and-building-guidelines.md) - - [Compilation and Building FAQ](compilation-and-building-faq.md) + - [Compilation and Building](compilation-and-building-0.md) - [Building Guidelines for the Standard System](building-guidelines-for-the-standard-system.md) - - [Compilation and Building Overview](compilation-and-building-overview-0.md) - - [Compilation and Building Guidelines](compilation-and-building-guidelines-1.md) + - [Compilation and Building Overview](compilation-and-building-overview.md) + - [Compilation and Building Guidelines](compilation-and-building-guidelines.md) - [Distributed Remote Startup](distributed-remote-startup.md) - [Graphics](graphics.md) - - [Graphics](graphics-2.md) + - [Graphics](graphics-1.md) - [Development Guidelines on Container Components](development-guidelines-on-container-components.md) - [Development Guidelines on Layout Container Components](development-guidelines-on-layout-container-components.md) - [Development Guidelines on Common Components](development-guidelines-on-common-components.md) @@ -26,7 +24,7 @@ - [Development Guidelines on Previewing](development-guidelines-on-previewing.md) - [Audio/Video](audio-video.md) - - [Overview](overview-3.md) + - [Overview](overview-2.md) - [Development Guidelines on Media Playback](development-guidelines-on-media-playback.md) - [Development Guidelines on Media Recording](development-guidelines-on-media-recording.md) @@ -59,21 +57,20 @@ - [Sensors Usage Example](sensors-usage-example.md) - [Application Framework](application-framework.md) - - [Overview](overview-4.md) + - [Overview](overview-3.md) - [Setting Up a Development Environment](setting-up-a-development-environment.md) - - [Development Guidelines](development-guidelines-5.md) + - [Development Guidelines](development-guidelines-4.md) - [Development Example](development-example.md) - [OTA Upgrade](ota-upgrade.md) - [Security](security.md) - - [Overview](overview-9.md) + - [Overview](overview-5.md) - [Development Guidelines on Application Signature Verification](development-guidelines-on-application-signature-verification.md) - [Development Guidelines on Application Permission Management](development-guidelines-on-application-permission-management.md) - [Development Guidelines on IPC Authentication](development-guidelines-on-ipc-authentication.md) - - [Development Guidelines on Trusted Device Group Management](development-guidelines-on-trusted-device-group-management.md) - [Startup](startup.md) - - [Startup](startup-10.md) + - [Startup](startup-6.md) - [init Module](init-module.md) - [appspawn Module](appspawn-module.md) - [bootstrap Module](bootstrap-module.md) @@ -83,7 +80,7 @@ - [Testing](testing.md) - [DFX](dfx.md) - - [DFX](dfx-11.md) + - [DFX](dfx-7.md) - [Development Guidelines on HiLog ](development-guidelines-on-hilog.md) - [Development Guidelines on HiLog\_Lite](development-guidelines-on-hilog_lite.md) - [Development Guidelines on HiSysEvent](development-guidelines-on-hisysevent.md) @@ -91,6 +88,7 @@ - [R&D Tools](r-d-tools.md) - [bytrace Usage Guidelines](bytrace-usage-guidelines.md) - [hdc\_std Usage Guidelines](hdc_std-usage-guidelines.md) + - [hdc\_std FAQs](hdc_std-faqs.md) - [XTS](xts.md) diff --git a/en/device-dev/subsystems/application-framework.md b/en/device-dev/subsystems/application-framework.md index d58ed3003a09c0d1e1194097353e454d85afa061..c4973fc34d4cf0058bb54a3de6e3b25b667ef282 100644 --- a/en/device-dev/subsystems/application-framework.md +++ b/en/device-dev/subsystems/application-framework.md @@ -1,10 +1,10 @@ # Application Framework -- **[Overview](overview-4.md)** +- **[Overview](overview-3.md)** - **[Setting Up a Development Environment](setting-up-a-development-environment.md)** -- **[Development Guidelines](development-guidelines-5.md)** +- **[Development Guidelines](development-guidelines-4.md)** - **[Development Example](development-example.md)** diff --git a/en/device-dev/subsystems/audio-video.md b/en/device-dev/subsystems/audio-video.md index 16e2f5b0835dbade41d9c722ab0ff5de90d93b1f..7942eeb78ebe8c14f38f1076dd5006f81f308625 100644 --- a/en/device-dev/subsystems/audio-video.md +++ b/en/device-dev/subsystems/audio-video.md @@ -1,6 +1,6 @@ # Audio/Video -- **[Overview](overview-3.md)** +- **[Overview](overview-2.md)** - **[Development Guidelines on Media Playback](development-guidelines-on-media-playback.md)** diff --git a/en/device-dev/subsystems/building-guidelines-for-mini-and-small-systems.md b/en/device-dev/subsystems/building-guidelines-for-mini-and-small-systems.md index d19baae14741babb44e57557e6b94a6e47401d91..cd4f2e3ca87186a59b38cb3136de9eefcc89fb12 100644 --- a/en/device-dev/subsystems/building-guidelines-for-mini-and-small-systems.md +++ b/en/device-dev/subsystems/building-guidelines-for-mini-and-small-systems.md @@ -1,9 +1,5 @@ # Building Guidelines for Mini and Small Systems -- **[Compilation and Building Overview](compilation-and-building-overview.md)** - -- **[Compilation and Building Guidelines](compilation-and-building-guidelines.md)** - -- **[Compilation and Building FAQ](compilation-and-building-faq.md)** +- **[Compilation and Building](compilation-and-building-0.md)** diff --git a/en/device-dev/subsystems/building-guidelines-for-the-standard-system.md b/en/device-dev/subsystems/building-guidelines-for-the-standard-system.md index bbc92d83896d1912837d2d34b0791a4e47e46004..9e40510e3ec30ac188d72e70130423f6081fe204 100644 --- a/en/device-dev/subsystems/building-guidelines-for-the-standard-system.md +++ b/en/device-dev/subsystems/building-guidelines-for-the-standard-system.md @@ -1,7 +1,7 @@ # Building Guidelines for the Standard System -- **[Compilation and Building Overview](compilation-and-building-overview-0.md)** +- **[Compilation and Building Overview](compilation-and-building-overview.md)** -- **[Compilation and Building Guidelines](compilation-and-building-guidelines-1.md)** +- **[Compilation and Building Guidelines](compilation-and-building-guidelines.md)** diff --git a/en/device-dev/subsystems/compilation-and-building-0.md b/en/device-dev/subsystems/compilation-and-building-0.md new file mode 100644 index 0000000000000000000000000000000000000000..b5236f69f98fab5ed637c306aa61d6039a79bcd0 --- /dev/null +++ b/en/device-dev/subsystems/compilation-and-building-0.md @@ -0,0 +1,998 @@ +# Compilation and Building + +- [Overview](#section10958256161119) + - [Basic Concepts](#section1732301411128) + - [Directory Structure](#section1588744014121) + - [Build Process](#section15761735134) + +- [Configuration Rules](#section2345183962710) + - [Module](#section142532518308) + - [Chipset](#section121501451143710) + - [Product](#section134549283435) + +- [Usage Guidelines](#section13754457192211) + - [Prerequisites](#section31651120233) + - [Using hb](#section1133304172313) + - [Adding a Module](#section167110415315) + - [Adding a Chipset Solution](#section1474718565412) + - [Adding a Product Solution](#section1097623294220) + +- [Troubleshooting](#section19909721104319) + - [Invalid -- w Option](#section138233464318) + - [Library ncurses Not Found](#section151033911442) + - [mcopy not Found](#section19811838104418) + - [No riscv File or Directory](#section03111118451) + - [No Crypto](#section69981127125013) + - [Unexpected Operator](#section967617530505) + + +## Overview + +The Compilation and Building subsystem is a build framework that supports module-based OpenHarmony development using Generate Ninja \(GN\) and Ninja. You can use this subsystem to: + +- Assemble modules for a product and build the product. + +- Build chipset source code independently. +- Build a single module independently. + +### Basic Concepts + +Learn the following concepts before you start compilation and building: + +- Subsystem + + A subsystem is a logical concept. It consists of one or more modules. OpenHarmony is designed with a layered architecture, which consists of the kernel layer, system service layer, framework layer, and application layer from bottom to top. System functions are developed by the level of system, subsystem, and module. In a multi-device deployment scenario, you can customize subsystems and modules as required. + + +- Module + + A module is a reusable, configurable, and tailorable function unit. Each module has an independent directory, and multiple modules can be developed concurrently and built and tested independently. + +- **GN** + + Generate Ninja \(GN\) is used to generate Ninja files. + +- **Ninja** + + Ninja is a small high-speed build system. + +- **hb** + + hb is a command line tool for OpenHarmony to execute build commands. + + +### Directory Structure + +``` +build/lite +├── components # Module description file +├── figures # Figures in the readme file +├── hb # hb pip installation package +├── make_rootfs # Script used to create the file system image +├── config # Build configuration +│ ├── component # Module-related template definition +│ ├── kernel # Kernel-related build configuration +│ └── subsystem # Subsystem build configuration +├── platform # ld script +├── testfwk # Test build framework +└── toolchain # Build toolchain configuration, which contains the compiler directories, build options, and linking options +``` + +### **Build Process** + +[Figure 1](#fig9744112715161) shows the build process. + +**Figure 1** Build process +![](figures/build-process.jpg "build-process") + +1. Use **hb set **to set the OpenHarmony source code directory and the product to build. +2. Use **hb build** to build the product, development board, or module. The procedure is as follows: + - Read the **config.gni** file of the development board selected. The file contains the build toolchain, linking commands, and build options. + - Run the **gn gen** command to read the product configuration and generate the **out** directory and **ninja** files for the solution. + - Run **ninja -C out/board/product** to start the build. + - Package the build result, set the file attributes and permissions, and create a file system image. + + +## Configuration Rules + +To ensure that the chipset and product solutions are pluggable and decoupled from OpenHarmony, the paths, directory trees, and configuration of modules, chipset solutions, and product solutions must comply with the following rules: + +### **Module** + +The source code directory for a module is named in the _\{Domain\}/\{Subsystem\}/\{Module\}_ format. The module directory tree is as follows: + +>![](public_sys-resources/icon-caution.gif) **CAUTION:** +>Define module attributes, such as the name, source code directory, function description, mandatory or not, build targets, RAM, ROM, build outputs, adapted kernels, configurable features, and dependencies, in the JSON file of the subsystem in the **build/lite/components** directory. When adding a module, add its definition to the JSON file of the corresponding subsystem. The module configured for a product must have been defined in a subsystem. Otherwise, the verification will fail. + +``` +component +├── interfaces +│ ├── innerkits # APIs exposed internally among modules +│ └── kits # App APIs provided for app developers +├── frameworks # Framework implementation +├── services # Service implementation +└── BUILD.gn # Build script +``` + +The following example shows how to define attributes of the sensor module of the pan-sensor subsystem: + +``` +{ + "components": [ + { + "component": "sensor_lite", # Module name + "description": "Sensor services", # Brief description of the module + "optional": "true", # Whether the module is mandatory for the system + "dirs": [ # Source code directory of the module + "base/sensors/sensor_lite" + ], + "targets": [ # Build entry of the module + "//base/sensors/sensor_lite/services:sensor_service" + ], + "rom": "92KB", # Module ROM + "ram": "~200KB", # Module RAM (estimated) + "output": [ "libsensor_frameworks.so" ], # Module build outputs + "adapted_kernel": [ "liteos_a" ], # Adapted kernel for the module + "features": [], # Configurable features of the module + "deps": { + "components": [ # Other modules on which the module depends + "samgr_lite", + "ipc_lite" + + ], + "third_party": [ # Open-source third-party software on which the module depends + "bounds_checking_function" + ] + } + } + ] +} +``` + +Observe the following rules when building the **BUILD.gn** module: + +- The build target name must be the same as the module name. +- Define the configurable features in the **BUILD.gn** file of the module. Name the configurable features in the **ohos\_**\{_subsystem_\}**\_**\{_module_\}**\_**\{_feature_\} format. Define the features in module description and configure them in the **config.json** file. +- Define macros in the **OHOS\_**\{_SUBSYSTEM_\}**\_**\{_MODULE_\}**\_**\{_FEATURE_\} format. + + >![](public_sys-resources/icon-note.gif) **NOTE:** + >GN is used as the build script language for modules. For details about how to use GN, see the [GN Quick Start Guide](https://gn.googlesource.com/gn/+/master/docs/quick_start.md). In GN, a module is a build target, which can be a static library, a dynamic library, an executable file, or a group. + + +The following example shows how to build the **foundation/graphic/ui/BUILD.gn** file for a graphics UI module: + +``` + # Declare the configurable features of the module + declare_args() { + enable_ohos_graphic_ui_animator = false # Animation switch + ohos_ohos_graphic_ui_font = "vector" # Configurable font type, which can be vector or bitmap + } + + # Basic module functions + shared_library("base") { + sources = [ + ...... + ] + include_dirs = [ + ...... + ] + } + + # Build only when the animator is enabled + if(enable_ohos_graphic_ui_animator ) { + shared_library("animator") { + sources = [ + ...... + ] + include_dirs = [ + ...... + ] + deps = [ :base ] + } + } + ...... + # It is recommended that the target name be the same as the module name, which can be an executable .bin file, shared_library (.so file), static_library (.a file), or a group. + executable("ui") { + deps = [ + ":base" + ] + + # The animator feature is configured by the product. + if(enable_ohos_graphic_ui_animator ) { + deps += [ + "animator" + ] + } + } +``` + +### **Chipset** + +- The chipset solution is a complete solution based on a development board. The solution includes the drivers, API adaptation, and SDK. +- The chipset solution is a special module, whose source code directory is named in the _**device**/\{Chipset solution vendor\}/\{Development board\}_ format. +- The chipset solution module is built by default based on the development board selected by the product. + +The chipset solution directory tree is as follows: + +``` +device +└── company # Chipset solution vendor + └── board # Name of the development board + ├── BUILD.gn # Build script + ├── hals # Southbound APIs for OS adaptation + ├── linux # Linux kernel version (optional) + │ └── config.gni # Build options for the Linux version + └── liteos_a # LiteOS kernel version (optional) + └── config.gni # Build options for the LiteOS Cortex-A version +``` + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The **config.gni** file contains build-related configurations of the development board. The parameters in the file are globally visible to the system and can be used to build all OS modules during the build process. + +The **config.gni** file contains the following key parameters: + +``` +kernel_type: kernel used by the development board, for example, liteos_a, liteos_m, or linux. +kernel_version: kernel version used by the development board, for example, 4.19. +board_cpu: CPU of the development board, for example, cortex-a7 or riscv32. +board_arch: chipset architecture of the development board, for example, armv7-a or rv32imac. +board_toolchain: name of the customized build toolchain used by the development board, for example, gcc-arm-none-eabi. If this field is not specified, ohos-clang will be used by default. +board_toolchain_prefix: prefix of the build toolchain, for example, gcc-arm-none-eabi. +board_toolchain_type: build toolchain type, for example, gcc or clang. Currently, only GCC and clang are supported. +board_cflags: build options of the .c file configured for the development board. +board_cxx_flags: build options of the .cpp file configured for the development board. +board_ld_flags: link options configured for the development board. +``` + +### **Product** + +The product solution is a complete product based on a development board. It includes the OS adaptation, module assembly configuration, startup configuration, and file system configuration. The source code directory of a product solution is named in the **vendor**/\{_Product solution vendor_\}/\{_Product name_\} format. A product solution is also a special module. + +The product solution directory tree is as follows: + +``` +vendor +└── company # Product solution vendor + ├── product # Product name + │ ├── init_configs + │ │ ├── etc # Startup configuration of the init process (only required for the Linux kernel) + │ │ └── init.cfg # System service startup configuration + │ ├── hals # OS adaptation + │ ├── BUILD.gn # Product build script + │ └── config.json # Product configuration file + │ └── fs.yml # File system packaging configuration + └── ...... +``` + +>![](public_sys-resources/icon-caution.gif) **CAUTION:** +>Create directories and files based on the preceding rules for new products. The Compilation and Building subsystem scans the configured products based on the rules. + +The key directories and files are described as follows: + +1. **vendor/company/product/init\_configs/etc** + + This folder contains the **rcS**, **S**_xxx_, and **fstab** scripts. The **init** process runs the **rcS**, **fstab**, and **S**_00_-_xxx_ scripts in sequence before starting system services. The **S**_xxx_ script contains content related to the development board and product. It is used to create device nodes and directories, scan device nodes, and change file permissions. These scripts are copied from the **BUILD.gn** file to the **out** directory of the product as required and packaged into the **rootfs** image. + +2. **vendor/company/product/init\_configs/init.cfg** + + This file is the configuration file for the **init** process to start services. Currently, the following commands are supported: + + - **start**: starts a service. + - **mkdir**: creates a folder. + - **chmod**: changes the permission on a specified directory or file. + - **chown**: changes the owner group of a specified directory or file. + - **mount**: mounts a device. + + The fields in the file are described as follows: + + ``` + { + "jobs" : [{ # Job array. A job corresponds to a command set. Jobs are executed in the following sequence: pre-init > init > post-init. + "name" : "pre-init", + "cmds" : [ + "mkdir /storage/data", # Create a directory. + "chmod 0755 /storage/data", # Change the permission, which is in 0xxx format, for example, 0755. + "mkdir /storage/data/log", + "chmod 0755 /storage/data/log", + "chown 4 4 /storage/data/log", # Change the owner group. The first number indicates the UID, and the second indicates the GID. + ...... + "mount vfat /dev/mmcblock0 /sdcard rw, umask=000" # The command is in the mount [File system type][source] [target] [flags] [data] format. + # Currently, flags can only be nodev, noexec, nosuid, or rdonly. + ] + }, { + "name" : "init", + "cmds" : [ # Start services based on the sequence of the cmds array. + "start shell", # Note that there is only one space between start and the service name. + ...... + "start service1" + ] + }, { + "name" : "post-init", # Job that is finally executed. Operations performed after the init process is started, for example, mounting a device after the driver initialization. + "cmds" : [] + } + ], + "services" : [{ # Service array. A service corresponds to a process. + "name" : "shell", # Service name + "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"], # Full path of the executable file. It must start with "path". + "uid" : 0, # Process UID, which must be the same as that in the binary file. + "gid" : 0, # Process GID, which must be the same as that in the binary file. + "once" : 0, # Whether the process is a one-off process. 1: The proces is a one-off process. The init process does not restart it after the process exits. 0: The process is not a one-off process. The init process restarts it if the process exits. + "importance" : 0, # Whether the process is a key process. 1: The process is a key process. If it exits, the init process restarts the board. 0: The process is not a key process. If it exits, the init process does not restart the board. + "caps" : [4294967295] + }, + ...... + ] + } + ``` + +3. **vendor/company/product/init\_configs/hals** + + This file stores the content related to OS adaptation of the product. For details about APIs for implementing OS adaptation, see the readme file of each module. + +4. **vendor/company/product/config.json** + + The **config.json** file is the main entry for the build and contains configurations of the development board, OS modules, and kernel. + + The following example shows the **config.json** file of the IP camera developed based on the hispark\_taurus development board: + + ``` + { + "product_name": "ipcamera", # Product name + "ohos_version": "OpenHarmony 1.0", # OS version + "device_company": "hisilicon", # Chipset vendor + "board": "hispark_taurus", # Name of the development board + "kernel_type": "liteos_a", # Kernel type + "kernel_version": "3.0.0", # Kernel version + "subsystems": [ + { + "subsystem": "aafwk", # Subsystem + "components": [ + { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] } # Module and its features + ] + }, + { + ...... + } + ...... + More subsystems and modules + } + } + ``` + +5. **vendor/company/product/fs.yml** + + This file packages the build result to create a configuration file system image, for example, **rootfs.img** \(user-space root file system\) and **userfs.img** \(readable and writable file\). It consists of multiple lists, and each list corresponds to a file system. The fields are described as follows: + + ``` + fs_dir_name: (Mandatory) declares the name of the file system, for example, rootfs or userfs. + fs_dirs: (Optional) configures the mapping between the file directory in the out directory and the system file directory. Each file directory corresponds to a list. + source_dir: (Optional) specifies the target file directory in the out directory. If this field is missing, an empty directory will be created in the file system based on target_dir. + target_dir: (Mandatory) specifies the corresponding file directory in the file system. + ignore_files: (Optional) declares ignored files during the copy operation. + dir_mode: (Optional) specifies the file directory permission, which is set to 755 by default. + file_mode: (Optional) declares permissions of all files in the directory, which is set to 555 by default. + fs_filemode: (Optional) configures files that require special permissions. Each file corresponds to a list. + file_dir: (Mandatory) specifies the detailed file path in the file system. + file_mode: (Mandatory) declares file permissions. + fs_symlink: (Optional) configures the soft link of the file system. + fs_make_cmd: (Mandatory) creates the file system script. The script provided by the OS is stored in the build/lite/make_rootfs directory. Linux, LiteOS, ext4, jffs2, and vfat are supported. Chipset vendors can also customize the script as required. + fs_attr: (Optional) dynamically adjusts the file system based on configuration items. + ``` + + The **fs\_symlink** and **fs\_make\_cmd** fields support the following variables: + + - $\{root\_path\} + + Code root directory, which corresponds to **$\{ohos\_root\_path\}** of GN + + - $\{out\_path\} + + **out** directory of the product, which corresponds to **$\{root\_out\_dir\}** of GN + + - $\{fs\_dir\} + + File system directory, which consists of the following variables + + - $\{root\_path\} + - $\{fs\_dir\_name\} + + + >![](public_sys-resources/icon-note.gif) **NOTE:** + >**fs.yml** is optional and does not need to be configured for devices without a file system. + +6. **vendor/company/product/BUILD.gn** + + This file is the entry for building the source code of the solution vendor and copying the startup configuration file. The **BUILD.gn** file in the corresponding product directory will be built by default if a product is selected. The following example shows how to build the **BUILD.gn** file of a product: + + ``` + group("product") { # The target name must be the same as the product name (level-3 directory name under the product directory). + deps = [] + # Copy the init configuration. + deps += [ "init_configs" ] + # Others + ...... + } + ``` + + +## Usage Guidelines + +### Prerequisites + +The development environment has GN, Ninja, Python 3.7.4 or later, and hb available. For details about installation methods, see [Basic OS Environment Setup](../quick-start/environment-setup.md). + +### Using hb + +**hb** is a command line tool for OpenHarmony to execute build commands. Common hb commands are described as follows: + +**hb set** + +``` +hb set -h +usage: hb set [-h] [-root [ROOT_PATH]] [-p] + +optional arguments: + -h, --help show this help message and exit + -root [ROOT_PATH], --root_path [ROOT_PATH] + Set OHOS root path + -p, --product Set OHOS board and kernel +``` + +- **hb set** \(without argument\): starts the default setting process. +- **hb set -root** _dir_: sets the root directory of the code. +- **hb set -p**: sets the product to build. + +**hb env** + +Displays the current configuration. + +``` +hb env +[OHOS INFO] root path: xxx +[OHOS INFO] board: hispark_taurus +[OHOS INFO] kernel: liteos +[OHOS INFO] product: ipcamera +[OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera +[OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 +``` + +**hb build** + +``` +hb build -h +usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] + [--dmverity] [--tee] [-p PRODUCT] [-f] [-n] + [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch] + [component [component ...]] + +positional arguments: + component name of the component + +optional arguments: + -h, --help show this help message and exit + -b BUILD_TYPE, --build_type BUILD_TYPE + release or debug version + -c COMPILER, --compiler COMPILER + specify compiler + -t [TEST [TEST ...]], --test [TEST [TEST ...]] + compile test suit + --dmverity Enable dmverity + --tee Enable tee + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: camera@huawei + -f, --full full code compilation + -n, --ndk compile ndk + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target + -v, --verbose show all command lines while building + -shs, --sign_haps_by_server + sign haps by server + --patch apply product patch before compiling + + --dmverity Enable dmverity + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: ipcamera@hisilcon + -f, --full full code compilation + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target +``` + +- **hb build** \(without argument\): builds the code based on the configured code directory, product, and options. The **-f** option deletes all products to be built, which is equivalent to running **hb clean** and **hb build**. +- **hb build** _\{module\_name\}_: builds a product module separately based on the development board and kernel set for the product, for example, **hb build kv\_store**. +- **hb build -p ipcamera@hisilicon**: skips the **set** step and builds the product directly. +- You can run **hb build** in **device/device\_company/board** to select the kernel and start the build based on the current development board and the selected kernel to generate an image that contains the kernel and driver only. + +**hb clean** + +You can run **hb clean** to clear the build result of the product in the **out** directory and retain the **args.gn** and **build.log** files only. To clear files in a specified directory, add the directory parameter to the command, for example, **hb clean out/xxx/xxx**. + +``` +hb clean +usage: hb clean [-h] [out_path] + +positional arguments: + out_path clean a specified path. + +optional arguments: + -h, --help show this help message and exit +``` + +### Adding a Module + +To add a module, determine the subsystem to which the module belongs and the module name, and then perform the following steps: + +1. Add the module build script after the source code development is complete. + + The following example adds the **BUILD.gn** script \(stored in the **applications/sample/hello\_world** directory\) to build the **hello\_world** module \(as an executable file\). + + ``` + executable("hello_world") { + include_dirs = [ + "include", + ] + sources = [ + "src/hello_world.c" + ] + } + ``` + + The above script is used to build **hello\_world** that can run on OpenHarmony. + + To build the preceding module separately, select a product via the **hb set** command and run the **-T** command. + + ``` + hb build -f -T //applications/sample/hello_world + ``` + + After the module functions are verified on the development board, perform steps [2 to 4](#li11471037297) to configure the module to the product. + +2. Add module description. + + The module description is stored in the **build/lite/components** directory. New modules must be added to the JSON file of the corresponding subsystem. The module description must contain the following fields: + + - **module**: name of the module + - **description**: brief description of the module + - **optional**: whether the module is optional + - **dirs**: source code directory of the module + - **targets**: module build entry + + For example, to add the **hello\_world** module to the application subsystem, add the **hello\_world** object to the **applications.json** file. + + ``` + { + "components": [ + { + "component": "hello_world", + "description": "Hello world.", + "optional": "true", + "dirs": [ + "applications/sample/hello_world" + ], + "targets": [ + "//applications/sample/hello_world" + ] + }, + ... + ] + } + ``` + +3. Configure the module for the product. + + The **config.json** file is stored in the **vendor/company/product/** directory. The file must contain the product name, OpenHarmony version, device vendor, development board, kernel type, kernel version, and the subsystem and module to configure. The following example adds the **hello\_world** module to the **my\_product.json** configuration file: + + ``` + { + "product_name": "hello_world_test", + "ohos_version": "OpenHarmony 1.0", + "device_company": "hisilicon", + "board": "hispark_taurus", + "kernel_type": "liteos_a", + "kernel_version": "1.0.0", + "subsystems": [ + { + "subsystem": "applications", + "components": [ + { "component": "hello_world", "features":[] } + ] + }, + ... + ] + } + ``` + +4. Build the product. + + 1. Run the **hb set** command in the root code directory and select the product. + + 2. Run the **hb build** command. + + +### Adding a Chipset Solution + +The following uses the RTL8720 development board provided by Realtek as an example. To a chipset solution, perform the following steps: + +1. Create a directory for the chipset solution. + + To create a directory based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](#section1625463413327), run the following command in the root code directory: + + ``` + mkdir -p device/realtek/rtl8720 + ``` + +2. Create a directory for kernel adaptation and build the **config.gni** file of the development board. + + For example, to adapt the LiteOS Cortex-M kernel to the RTL8720 development board, configure the **device/realtek/rtl8720/liteos\_a/config.gni** file as follows: + + ``` + # Kernel type, e.g. "linux", "liteos_a", "liteos_m". + kernel_type = "liteos_a" + + # Kernel version. + kernel_version = "3.0.0" + + # Board CPU type, e.g. "cortex-a7", "riscv32". + board_cpu = "real-m300" + + # Board arch, e.g. "armv7-a", "rv32imac". + board_arch = "" + + # Toolchain name used for system compiling. + # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. + # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. + board_toolchain = "gcc-arm-none-eabi" + + # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. + board_toolchain_path = + rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", + root_build_dir) + + # Compiler prefix. + board_toolchain_prefix = "gcc-arm-none-eabi-" + + # Compiler type, "gcc" or "clang". + board_toolchain_type = "gcc" + + # Board related common compile flags. + board_cflags = [] + board_cxx_flags = [] + board_ld_flags = [] + ``` + +3. Build the script. + + Create the **BUILD.gn** file in the development board directory. The target name must be the same as that of the development board. The content in the **device/realtek/rtl8720/BUILD.gn** file is configured as follows: + + ``` + group("rtl8720") { # The target can be shared_library, static_library, or an executable file. + # Content + ...... + } + ``` + +4. Build the chipset solution. + + Run the **hb build** command in the development board directory to start the build. + + +### Adding a Product Solution + +You can use the Compilation and Building subsystem to customize product solutions by assembling chipset solutions and modules. The procedure is as follows: + +1. Create a product directory. + + The following uses the Wi-Fi IoT module on the RTL8720 development board as an example. Run the following command in the root code directory to create a product directory based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](#section1625463413327): + + ``` + mkdir -p vendor/my_company/wifiiot + ``` + +2. Assemble the product. + + Create the **config.json** file in the product directory. The **vendor/my\_company/wifiiot/config.json** file is as follows: + + ``` + { + "product_name": "wifiiot", # Product name + "ohos_version": "OpenHarmony 1.0", # OS version + "device_company": "realtek", # Name of the chipset solution vendor + "board": "rtl8720", # Name of the development board + "kernel_type": "liteos_m", # Kernel type + "kernel_version": "3.0.0", # Kernel version + "subsystems": [ + { + "subsystem": "kernel", # Subsystem + "components": [ + { "component": "liteos_m", "features":[] } # Module and its features + ] + }, + ... + { + More subsystems and modules + } + ] + } + ``` + + Before the build, the Compilation and Building subsystem checks the validity of fields, including **device\_company**, **board**, **kernel\_type**, **kernel\_version**, **subsystem**, and **component**. The **device\_company**, **board**, **kernel\_type**, and **kernel\_version** fields must match the current chipset solution, and **subsystem** and **component** must match the module description in the **build/lite/components** file. + +3. Implement adaptation to OS APIs. + + Create the **hals** directory in the product directory and store the source code as well as the build script for OS adaptation in this directory. + +4. Configure the system service. + + Create the **init\_configs** directory in the product directory and then the **init.cfg** file in the newly created directory. Configure the system service to be started. + +5. \(Optional\) Configure the init process only for the Linux kernel. + + Create the **etc** directory in the **init\_configs** directory, and then the **init.d** folder and the **fstab** file in the newly created directory. Then, create the **rcS** and **S**_xxx_ files in the **init.d** file and edit them based on product requirements. + +6. \(Optional\) Configure the file system image only for the development board that supports the file system. + + Create the **fs.yml** file in the product directory and configure it as required. A typical **fs.yml** file is as follows: + + ``` + - + fs_dir_name: rootfs # Image name + fs_dirs: + - + # Copy the files in the out/my_board/my_product/bin directory to the rootfs/bin directory and ignore the .bin files related to testing. + source_dir: bin + target_dir: bin + ignore_files: + - Test.bin + - TestSuite.bin + - + # Copy the files in the out/my_board/my_product/libs directory to the rootfs/lib directory, ignore all .a files, and set the file permissions to 644 and folder permissions 755. + source_dir: libs + target_dir: lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: usr/lib + target_dir: usr/lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: config + target_dir: etc + - + source_dir: system + target_dir: system + - + source_dir: sbin + target_dir: sbin + - + source_dir: usr/bin + target_dir: usr/bin + - + source_dir: usr/sbin + target_dir: usr/sbin + - + # Create an empty proc directory. + target_dir: proc + - + target_dir: mnt + - + target_dir: opt + - + target_dir: tmp + - + target_dir: var + - + target_dir: sys + - + source_dir: etc + target_dir: etc + - + source_dir: vendor + target_dir: vendor + - + target_dir: storage + + fs_filemode: + - + file_dir: lib/ld-uClibc-0.9.33.2.so + file_mode: 555 + - + file_dir: lib/ld-2.24.so + file_mode: 555 + - + file_dir: etc/init.cfg + file_mode: 400 + fs_symlink: + - + # Create the soft link ld-musl-arm.so.1 -> libc.so in the rootfs/lib directory. + source: libc.so + link_name: ${fs_dir}/lib/ld-musl-arm.so.1 + - + source: mksh + link_name: ${fs_dir}/bin/sh + - + source: mksh + link_name: ${fs_dir}/bin/shell + fs_make_cmd: + # Create an ext4 image for the rootfs directory using the script. + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + - + fs_dir_name: userfs + fs_dirs: + - + source_dir: storage/etc + target_dir: etc + - + source_dir: data + target_dir: data + fs_make_cmd: + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + + ``` + +7. \(Optional\) Configure patches if the product and modules need to be patched. + + Create the **patch.yml** file in the product directory and configure it as required. A typical **patch.yml** file is as follows: + + ``` + # Directory in which the patch is to be installed + foundation/communication/dsoftbus: + # Directory in which the patch is stored + - foundation/communication/dsoftbus/1.patch + - foundation/communication/dsoftbus/2.patch + third_party/wpa_supplicant: + - third_party/wpa_supplicant/1.patch + - third_party/wpa_supplicant/2.patch + - third_party/wpa_supplicant/3.patch + ... + ``` + + If you add **--patch** when running the **hb build** command, the patch file can be added to the specified directory before the build. + + ``` + hb build -f --patch + ``` + +8. Build the script. + + Create the **BUILD.gn** file in the product directory and write the script. The following **BUILD.gn** file uses the Wi-Fi IoT module in [1](#li1970321162111) as an example: + + ``` + group("wifiiot") { # The target name must be the same as the product name. + deps = [] + # Copy the init configuration. + deps += [ "init_configs" ] + # Build the hals directory. + deps += [ "hals" ] + # Others + ...... + } + ``` + +9. Build the product. + + Run the **hb set** command in the code root directory, select the new product as prompted, and run the **hb build** command. + + +## Troubleshooting + +### Invalid -- w Option + +- **Symptom** + + The build fails, and "usr/sbin/ninja: invalid option -- w" is displayed. + +- **Cause** + + The Ninja version in the build environment is outdated and does not support the **--w** option. + +- **Solution** + + Uninstall Ninja and GN and follow the instructions provided in [Acquiring Tools](../get-code/tool-acquisition.md) to install Ninja and GN of the required version. + + +### Library ncurses Not Found + +- **Symptom** + + The build fails, and "/usr/bin/ld: cannot find -lncurses" is displayed. + +- **Cause** + + The ncurses library is not installed. + +- **Solution** + + ``` + sudo apt-get install lib32ncurses5-dev + ``` + + +### mcopy not Found + +- **Symptom** + + The build fails, and "line 77: mcopy: command not found" is displayed. + +- **Cause** + + mcopy is not installed. + +- **Solution** + + ``` + ​sudo apt-get install dosfstools mtools + ``` + + +### No riscv File or Directory + +- **Symptom** + + The build fails, and the following information is displayed: + + riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory. + +- **Cause** + + Permission is required to access files in the **riscv** compiler directory. + +- **Solution** + + Run the following command to query the directory where **gcc\_riscv32** is located: + + ``` + which riscv32-unknown-elf-gcc + ``` + + Run the **chmod** command to change the directory permission to **755**. + + +### No Crypto + +- **Symptom** + + The build fails, and "No module named 'Crypto'" is displayed. + +- **Cause** + + Crypto is not installed in Python 3. + +- **Solution** + 1. Run the following command to query the Python version: + + ``` + python3 --version + ``` + + 2. Ensure that Python 3.7 or later is installed, and then run the following command to install pycryptodome: + + ``` + sudo pip3 install pycryptodome + ``` + + + +### Unexpected Operator + +- **Symptom** + + The build fails, and "xx.sh \[: xx unexpected operator" is displayed. + +- **Cause** + + The build environment is shell, not bash. + +- **Solution** + + ``` + sudo rm -rf /bin/sh + sudo ln -s /bin/bash /bin/sh + ``` + + diff --git a/en/device-dev/subsystems/compilation-and-building-faq.md b/en/device-dev/subsystems/compilation-and-building-faq.md deleted file mode 100644 index 7c90a77cafe15b19f2bdcfbbc9d976158b83be9c..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-faq.md +++ /dev/null @@ -1,121 +0,0 @@ -# Compilation and Building FAQ - -- [Invalid -- w option](#section1019152312222) -- [Ncurses library not found](#section21449422618) -- [Mcopy not found](#section12477184992615) -- [No riscv file or directory](#section178451337202716) -- [No Crypto](#section1241481172819) -- [Unexpected operator](#section3691222152919) - -## Invalid -- w option - -- **Problem** - - The compilation fails, and **usr/sbin/ninja: invalid option -- w** is displayed. - -- **Cause** - - The Ninja version in the compilation environment is outdated and does not support the **--w** option. - -- **Solution** - - Uninstall Ninja and GN and follow the instructions provided in [Acquiring Tools](../get-code/tool-acquisition.md) to obtain the provided compilation toolchain. - - -## Ncurses library not found - -- **Problem** - - The compilation fails, and **/usr/bin/ld: cannot find -lncurses** is displayed. - -- **Cause** - - The ncurses library is not installed. - -- **Solution** - - ``` - sudo apt-get install lib32ncurses5-dev - ``` - - -## Mcopy not found - -- **Problem** - - The compilation fails, and **line 77: mcopy: command not found** is displayed. - -- **Cause** - - Mcopy is not installed. - -- **Solution** - - ``` - ​sudo apt-get install dosfstools mtools - ``` - - -## No riscv file or directory - -- **Problem** - - The compilation fails, and the following information is displayed: **riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory**. - -- **Cause** - - Permission is required to access files in the **riscv** compiler path. - -- **Solution** - 1. Run the following command to query the directory where **gcc\_riscv32** is located: - - ``` - which riscv32-unknown-elf-gcc - ``` - - 2. Run the **chmod** command to change the directory permission to **755**. - - -## No Crypto - -- **Problem** - - The compilation fails, and **No module named'Crypto loaded** is displayed. - -- **Cause** - - Crypto is not installed in Python 3. - -- **Solution** - 1. Run the following command to query the Python version: - - ``` - python3 --version - ``` - - 2. Ensure that Python 3.7 or later is installed, and then run the following command to install pycryptodome: - - ``` - sudo pip3 install pycryptodome - ``` - - - -## Unexpected operator - -- **Problem** - - The compilation fails, and **xx.sh \[: xx unexpected operator** is displayed. - -- **Cause** - - The compilation environment is shell instead of bash. - -- **Solution** - - ``` - sudo rm -rf /bin/sh - sudo ln -s /bin/bash /bin/sh - ``` - - diff --git a/en/device-dev/subsystems/compilation-and-building-guidelines-1.md b/en/device-dev/subsystems/compilation-and-building-guidelines-1.md deleted file mode 100644 index eddc2c96aaefe399e0c46c7d47eb3810ab59f67a..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-guidelines-1.md +++ /dev/null @@ -1,174 +0,0 @@ -# Compilation and Building Guidelines - -- [Directory Structure](#section56731811102915) -- [Building](#section1069873833818) - - [Build Command](#section2740182614395) - -- [How to Develop](#section4207112818418) - -## Directory Structure - -``` -/build # Primary directory -├── config # Build configuration items -├── core -│ └── gn # Build entry configuration -├── loader # Loader of module configuration, which also generates a template for the module -├── ohos # Configuration of the process for building and packaging OpenHarmony -│ ├── kits # Build and packaging templates and processing flow for kits -│ ├── ndk # NDK template and processing flow -│ ├── notice # Notice template and processing flow -│ ├── packages # Distribution packaging template and processing flow -│ ├── sa_profile # SA template and processing flow -│ ├── sdk # SDK template and processing flow, which contains the module configuration in the SDK -│ └── testfwk # Processing flow related to the test -├── scripts # Build-related Python script -├── templates # C/C++ build templates -└── toolchain # Toolchain configuration -``` - -## Building - -### Build Command - -- Run the following command in the root directory of the source code to build the full distribution: - - ``` - ./build.sh --product-name {product_name} - ``` - - **product\_name** indicates the product supported by the current distribution, for example, Hi3516D V300. - - The image generated after build is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - -- The build command supports the following options: - - ``` - --product-name # (Mandatory) Name of the product to build, for example, Hi3516D V300 - --build-target # (Optional) One or more build targets - --gn-args # (Optional) One or more gn parameters - --ccache # (Optional) Use of Ccache for build. This option takes effect only when Ccache is installed on the local PC. - ``` - - -## How to Develop - -1. Add a module. - - The following steps use a custom module as an example to describe how to build the module, including build a library, an executable file, and a configuration file. - - The example module **partA** consists of **feature1**, **feature2**, and **feature3**. The target of **feature1** is a dynamic library, that of **feature2** is an executable file, and that of **feature3** is an etc configuration file. - - Add **partA** to a subsystem, for example, **subsystem\_examples** \(defined in the **test/examples/** directory\). - - The complete directory structure of **partA** is as follows: - - ``` - test/examples/partA - ├── feature1 - │ ├── BUILD.gn - │ ├── include - │ │ └── helloworld1.h - │ └── src - │ └── helloworld1.cpp - ├── feature2 - │ ├── BUILD.gn - │ ├── include - │ │ └── helloworld2.h - │ └── src - │ └── helloworld2.cpp - └── feature3 - ├── BUILD.gn - └── src - └── config.conf - ``` - - Example 1: GN script \(**test/examples/partA/feature1/BUILD.gn**\) for building a dynamic library - - ``` - config("helloworld_lib_config") { - include_dirs = [ "include" ] - } - - ohos_shared_library("helloworld_lib") { - sources = [ - "include/helloworld1.h", - "src/helloworld1.cpp", - ] - public_configs = [ ":helloworld_lib_config" ] - part_name = "partA" - } - ``` - - Example 2: GN script \(**test/examples/partA/feature2/BUILD.gn**\) for building an executable file - - ``` - ohos_executable("helloworld_bin") { - sources = [ - "src/helloworld2.cpp" - ] - include_dirs = [ "include" ] - deps = [ # Dependent submodule - "../feature1:helloworld_lib" - ] - external_deps = [ "partB:module1" ] # (Optional) If there is a cross-module dependency, the format is "module name: submodule name" - install_enable = true # By default, the executable file is not installed. You need to set this parameter to true for installation. - part_name = "partA" - } - ``` - - Example 3: GN script \(**test/examples/partA/feature3/BUILD.gn**\) for building the etc configuration file \(submodule\). - - ``` - ohos_prebuilt_etc("feature3_etc") { - source = "src/config.conf" - relative_install_dir = "init" # (Optional) Directory for installing the submodule, which is relative to the default installation directory (/system/etc) - part_name = "partA" - } - ``` - - Example 4: Adding the module configuration file **test/examples/ohos.build** to the **ohos.build** file of this subsystem. Each subsystem has an **ohos.build** file in its root directory. - - ``` - "partA": { - "module_list": [ - "//test/examples/partA/feature1:helloworld_lib", - "//test/examples/partA/feature2:helloworld_bin", - "//test/examples/partA/feature3:feature3_etc", - ], - "inner_kits": [ - - ], - "system_kits": [ - - ], - "test_list": [ - - ] - } - ``` - - The declaration of a module contains the following parts: - - - **module\_list**: submodule list of the module - - **inner\_kits**: APIs for other modules that depend on this module through **external\_deps** - - **system\_kits**: APIs for developers - - **test\_list**: test cases for the submodules of the module - -2. Add the module to the product configuration file. - - Add **"subsystem\_examples:partA"** to the configuration file **productdefine/common/products/\{product-name\}.json** to build and package **partA** into the distribution. - -3. Build the module, including the library, executable file, and etc configuration file. - - For example, run the following command to build Hi3516D V300: - - ``` - ./build.sh --product-name Hi3516DV300 --ccache - ``` - -4. Obtain the build result. - - Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - - diff --git a/en/device-dev/subsystems/compilation-and-building-guidelines.md b/en/device-dev/subsystems/compilation-and-building-guidelines.md index e89b07bebaaba173dafd27affe843b42d4e0e3f2..eddc2c96aaefe399e0c46c7d47eb3810ab59f67a 100644 --- a/en/device-dev/subsystems/compilation-and-building-guidelines.md +++ b/en/device-dev/subsystems/compilation-and-building-guidelines.md @@ -1,430 +1,174 @@ -# Compilation and Building Guidelines +# Compilation and Building Guidelines -- [Prerequisites](#section13333171022312) -- [How to Use the hb Command Line Tool](#section477242204612) -- [Adding a Module](#section4207112818418) -- [Adding a Chipset Solution](#section2737141421917) -- [Adding a Product Solution](#section720881917199) +- [Directory Structure](#section56731811102915) +- [Building](#section1069873833818) + - [Build Command](#section2740182614395) -## Prerequisites +- [How to Develop](#section4207112818418) -Ensure that the development environment has GN, Ninja, Python 3.7.4 or later, and hb commands. For details about installation methods, see [Basic OS Environment Setup](../quick-start/environment-setup.md). +## Directory Structure -## How to Use the hb Command Line Tool +``` +/build # Primary directory +├── config # Build configuration items +├── core +│ └── gn # Build entry configuration +├── loader # Loader of module configuration, which also generates a template for the module +├── ohos # Configuration of the process for building and packaging OpenHarmony +│ ├── kits # Build and packaging templates and processing flow for kits +│ ├── ndk # NDK template and processing flow +│ ├── notice # Notice template and processing flow +│ ├── packages # Distribution packaging template and processing flow +│ ├── sa_profile # SA template and processing flow +│ ├── sdk # SDK template and processing flow, which contains the module configuration in the SDK +│ └── testfwk # Processing flow related to the test +├── scripts # Build-related Python script +├── templates # C/C++ build templates +└── toolchain # Toolchain configuration +``` -hb is a command line tool for OpenHarmony to execute build commands. Common hb commands are described as follows: +## Building -1. **hb set** +### Build Command - ``` - hb set -h - usage: hb set [-h] [-root [ROOT_PATH]] [-p] - - optional arguments: - -h, --help show this help message and exit - -root [ROOT_PATH], --root_path [ROOT_PATH] - Set OHOS root path - -p, --product Set OHOS board and kernel - ``` - - - If you run **hb set** with no argument, the default setting process starts. - - You can run **hb set -root** _dir_ to set the root directory of the source code. - - **hb set -p** is used to set the product to build. - -2. **hb env** - - View the current configuration. - - ``` - hb env - [OHOS INFO] root path: xxx - [OHOS INFO] board: hispark_taurus - [OHOS INFO] kernel: liteos - [OHOS INFO] product: ipcamera - [OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera - [OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 - ``` - -3. **hb build** +- Run the following command in the root directory of the source code to build the full distribution: ``` - hb build -h - usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] - [--dmverity] [-p PRODUCT] [-f] [-n] - [component [component ...]] - - positional arguments: - component name of the component - - optional arguments: - -h, --help show this help message and exit - -b BUILD_TYPE, --build_type BUILD_TYPE - release or debug version - -t [TEST [TEST ...]], --test [TEST [TEST ...]] - compile test suit - --dmverity Enable dmverity - -p PRODUCT, --product PRODUCT - build a specified product with - {product_name}@{company}, eg: ipcamera@hisilcon - -f, --full full code compilation - -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] - Compile single target + ./build.sh --product-name {product_name} ``` - - If you run **hb build** with no argument, the previously configured code directory, product, and options are used for the build. The **-f** option will delete all products to be built, which is equivalent to running **hb clean** and **hb build**. - - You can run **hb build** _\{module\_name\}_ to build product modules separately based on the development board and kernel set for the product, for example, **hb build kv\_store**. - - You can run **hb build -p ipcamera@hisilicon** to skip the setting step and compile the product directly. - - You can run **hb build** in **device/device\_company/board** to select the kernel and start the build based on the current development board and the selected kernel to generate an image that contains the kernel and driver only. + **product\_name** indicates the product supported by the current distribution, for example, Hi3516D V300. -4. **hb clean** + The image generated after build is stored in the **out/ohos-arm-release/packages/phone/images/** directory. - Clear the build result of the product in the **out** directory, and retain the **args.gn** and **build.log** files only. To clear files in a specified directory, add the directory parameter to the command, for example, **hb clean out/xxx/xxx**. +- The build command supports the following options: ``` - hb clean - usage: hb clean [-h] [out_path] - - positional arguments: - out_path clean a specified path. - - optional arguments: - -h, --help show this help message and exit + --product-name # (Mandatory) Name of the product to build, for example, Hi3516D V300 + --build-target # (Optional) One or more build targets + --gn-args # (Optional) One or more gn parameters + --ccache # (Optional) Use of Ccache for build. This option takes effect only when Ccache is installed on the local PC. ``` -## Adding a Module - -To add a module, determine the subsystem to which the module belongs and the module name, and then perform the following steps: +## How to Develop -1. Add the module build script after the source code development is complete. +1. Add a module. - The following example adds the **BUILD.gn** script \(stored in the **applications/sample/hello\_world** directory\) to build the **hello\_world** module \(as an executable file\). + The following steps use a custom module as an example to describe how to build the module, including build a library, an executable file, and a configuration file. - ``` - executable("hello_world") { - include_dirs = [ - "include", - ] - sources = [ - "src/hello_world.c" - ] - } - ``` + The example module **partA** consists of **feature1**, **feature2**, and **feature3**. The target of **feature1** is a dynamic library, that of **feature2** is an executable file, and that of **feature3** is an etc configuration file. - The added script is used to build **hello\_world** that can run on OpenHarmony. + Add **partA** to a subsystem, for example, **subsystem\_examples** \(defined in the **test/examples/** directory\). - To build the preceding module separately, select a product via the **hb set** command and run the **-T** command. + The complete directory structure of **partA** is as follows: ``` - hb build -f -T //applications/sample/hello_world + test/examples/partA + ├── feature1 + │ ├── BUILD.gn + │ ├── include + │ │ └── helloworld1.h + │ └── src + │ └── helloworld1.cpp + ├── feature2 + │ ├── BUILD.gn + │ ├── include + │ │ └── helloworld2.h + │ └── src + │ └── helloworld2.cpp + └── feature3 + ├── BUILD.gn + └── src + └── config.conf ``` - After the module functions are verified based on the development board, perform steps 2 to 5 to configure the module for the product. - -2. Add the module description. - - The module description is stored in the **build/lite/components** directory. New modules must be added to the JSON file of the corresponding subsystem. A module description must contain the following fields: - - - **module**: name of the module - - **description**: brief description of the module - - **optional**: whether the module is optional - - **dirs**: source code directory of the module - - **targets**: module build entry - - For example, to add the **hello\_world** module to the application subsystem, add the **hello\_world** object to the **applications.json** file. + Example 1: GN script \(**test/examples/partA/feature1/BUILD.gn**\) for building a dynamic library ``` - { - "components": [ - { - "component": "hello_world", - "description": "Hello world.", - "optional": "true", - "dirs": [ - "applications/sample/hello_world" - ], - "targets": [ - "//applications/sample/hello_world" - ] - }, - ... - ] + config("helloworld_lib_config") { + include_dirs = [ "include" ] + } + + ohos_shared_library("helloworld_lib") { + sources = [ + "include/helloworld1.h", + "src/helloworld1.cpp", + ] + public_configs = [ ":helloworld_lib_config" ] + part_name = "partA" } ``` -3. Configure the module for the product. - - The **config.json** file is stored in the **vendor/company/product/** directory. The file must contain the product name, OpenHarmony version, device vendor, development board, kernel type, kernel version, and the subsystem and module to configure. The following example adds the **hello\_world** module to the **my\_product.json** configuration file: + Example 2: GN script \(**test/examples/partA/feature2/BUILD.gn**\) for building an executable file ``` - { - "product_name": "hello_world_test", - "ohos_version": "OpenHarmony 1.0", - "device_company": "hisilicon", - "board": "hispark_taurus", - "kernel_type": "liteos_a", - "kernel_version": "1.0.0", - "subsystems": [ - { - "subsystem": "applications", - "components": [ - { "component": "hello_world", "features":[] } - ] - }, - ... - ] + ohos_executable("helloworld_bin") { + sources = [ + "src/helloworld2.cpp" + ] + include_dirs = [ "include" ] + deps = [ # Dependent submodule + "../feature1:helloworld_lib" + ] + external_deps = [ "partB:module1" ] # (Optional) If there is a cross-module dependency, the format is "module name: submodule name" + install_enable = true # By default, the executable file is not installed. You need to set this parameter to true for installation. + part_name = "partA" } ``` -4. Build the product. - - 1. Run the **hb set** command in the root code directory to select the corresponding product. - - 2. Run the **hb build** command. - - -## Adding a Chipset Solution - -The Compilation and Building subsystem allows you to add a chipset solution. Detailed operations are as follows: - -1. Create a directory for the chipset solution. - - Taking the RTL8720 development board of chipset provider Realtek for example, you need to run the following command in the root code directory to create a directory for the chipset solution based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](compilation-and-building-overview.md#section1625463413327). + Example 3: GN script \(**test/examples/partA/feature3/BUILD.gn**\) for building the etc configuration file \(submodule\). ``` - mkdir -p device/realtek/rtl8720 + ohos_prebuilt_etc("feature3_etc") { + source = "src/config.conf" + relative_install_dir = "init" # (Optional) Directory for installing the submodule, which is relative to the default installation directory (/system/etc) + part_name = "partA" + } ``` -2. Create a directory for kernel adaptation and build the **config.gni** file of the development board. - - The following example adapts the LiteOS Cortex-M kernel to the RTL8720 development board of Realtek. The **device/realtek/rtl8720/liteos\_a/config.gni** file is configured as follows: + Example 4: Adding the module configuration file **test/examples/ohos.build** to the **ohos.build** file of this subsystem. Each subsystem has an **ohos.build** file in its root directory. ``` - # Kernel type, e.g. "linux", "liteos_a", "liteos_m". - kernel_type = "liteos_a" - - # Kernel version. - kernel_version = "3.0.0" - - # Board CPU type, e.g. "cortex-a7", "riscv32". - board_cpu = "real-m300" - - # Board arch, e.g. "armv7-a", "rv32imac". - board_arch = "" + "partA": { + "module_list": [ + "//test/examples/partA/feature1:helloworld_lib", + "//test/examples/partA/feature2:helloworld_bin", + "//test/examples/partA/feature3:feature3_etc", + ], + "inner_kits": [ - # Toolchain name used for system compiling. - # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. - # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. - board_toolchain = "gcc-arm-none-eabi" + ], + "system_kits": [ - # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. - board_toolchain_path = - rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", - root_build_dir) + ], + "test_list": [ - # Compiler prefix. - board_toolchain_prefix = "gcc-arm-none-eabi-" - - # Compiler type, "gcc" or "clang". - board_toolchain_type = "gcc" - - # Board related common compile flags. - board_cflags = [] - board_cxx_flags = [] - board_ld_flags = [] - ``` - -3. Build the script. - - Create the **BUILD.gn** file in the development board directory. The target name must be the same as that of the development board. Taking the RTL8720 development board of Realtek as an example, the content in the **device/realtek/rtl8720/BUILD.gn** file is configured as follows: - - ``` - group("rtl8720") { # The target can be shared_library, static_library, or an executable file. - # Content - ...... - } - ``` - -4. Build the chipset solution. - - Run the **hb build** command in the development board directory to start the build. - - -## Adding a Product Solution - -The Compilation and Building subsystem supports flexible assembly of chipset solutions and modules to customize desired product solutions. The operation procedure is as follows: - -1. Create a product directory. - - Taking the Wi-Fi IoT module based on the RTL8720 development board as an example, you need to run the following command in the root code directory to create a product directory based on [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](compilation-and-building-overview.md#section1625463413327). - - ``` - mkdir -p vendor/my_company/wifiiot - ``` - -2. Assemble the product. - - Create the **config.json** file in the product directory. Taking the Wi-Fi IoT module as an example, the **vendor/my\_company/wifiiot/config.json** file is as follows: - - ``` - { - "product_name": "wifiiot", # Product name - "ohos_version": "OpenHarmony 1.0", # In-use OS version - "device_company": "realtek", # Name of the chipset solution vendor - "board": "rtl8720", # Name of the development board - "kernel_type": "liteos_m", # Selected kernel type - "kernel_version": "3.0.0", # Selected kernel version - "subsystems": [ - { - "subsystem": "kernel", # Selected subsystem - "components": [ - { "component": "liteos_m", "features":[] } # Selected module and its features - ] - }, - ... - { - More subsystems and modules - } ] - } + } ``` - Before the build, the Compilation and Building subsystem will check the validity of fields, including **device\_company**, **board**, **kernel\_type**, **kernel\_version**, **subsystem**, and **component**. The first four fields and the latter two fields must match the current chipset solution and the module description in the **build/lite/components** file, respectively. - -3. Implement adaptation of OS APIs. + The declaration of a module contains the following parts: - Create the **hals** directory in the product directory and store the source code as well as the build script for OS adaptation in this directory. + - **module\_list**: submodule list of the module + - **inner\_kits**: APIs for other modules that depend on this module through **external\_deps** + - **system\_kits**: APIs for developers + - **test\_list**: test cases for the submodules of the module -4. Configure the system service. +2. Add the module to the product configuration file. - Create the **init\_configs** directory in the product directory and then the **init.cfg** file in the newly created directory. You can configure the system service to be started on demand. + Add **"subsystem\_examples:partA"** to the configuration file **productdefine/common/products/\{product-name\}.json** to build and package **partA** into the distribution. -5. Configure the init process \(only for the Linux kernel\). +3. Build the module, including the library, executable file, and etc configuration file. - You need to create the **etc** directory in the **init\_configs** directory, and then the **init.d** folder as well as the **fstab** file in the newly created directory. In addition, you need to create the **rcS** and **Sxxx** files in the **init.d** file and edit them based on product requirements. - -6. Configure the file system image \(required only for the development board that supports the file system\). - - Create the **fs.yml** file in the product directory and configure it as required. A typical **fs.yml** file is configured as follows: + For example, run the following command to build Hi3516D V300: ``` - - - fs_dir_name: rootfs # Image name - fs_dirs: - - - # Copy the files in the out/my_board/my_product/bin directory to the rootfs/bin directory and ignore the .bin files related to testing. - source_dir: bin - target_dir: bin - ignore_files: - - Test.bin - - TestSuite.bin - - - # Copy the files in the out/my_board/my_product/libs directory to the rootfs/lib directory, ignore all .a files, and set the permissions on the files and folders to 644 and 755, respectively. - source_dir: libs - target_dir: lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: usr/lib - target_dir: usr/lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: config - target_dir: etc - - - source_dir: system - target_dir: system - - - source_dir: sbin - target_dir: sbin - - - source_dir: usr/bin - target_dir: usr/bin - - - source_dir: usr/sbin - target_dir: usr/sbin - - - # Create an empty proc directory. - target_dir: proc - - - target_dir: mnt - - - target_dir: opt - - - target_dir: tmp - - - target_dir: var - - - target_dir: sys - - - source_dir: etc - target_dir: etc - - - source_dir: vendor - target_dir: vendor - - - target_dir: storage - - fs_filemode: - - - file_dir: lib/ld-uClibc-0.9.33.2.so - file_mode: 555 - - - file_dir: lib/ld-2.24.so - file_mode: 555 - - - file_dir: etc/init.cfg - file_mode: 400 - fs_symlink: - - - # Create the soft link ld-musl-arm.so.1 -> libc.so in the rootfs/lib directory. - source: libc.so - link_name: ${fs_dir}/lib/ld-musl-arm.so.1 - - - source: mksh - link_name: ${fs_dir}/bin/sh - - - source: mksh - link_name: ${fs_dir}/bin/shell - fs_make_cmd: - # Create an ext4 image for the rootfs directory using the script. - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - - - fs_dir_name: userfs - fs_dirs: - - - source_dir: storage/etc - target_dir: etc - - - source_dir: data - target_dir: data - fs_make_cmd: - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - ``` - -7. Build the script. - - Create the **BUILD.gn** file in the product directory and build the script based on your requirements. Taking the Wi-Fi IoT module in step 1 as an example, the **BUILD.gn** is configured as follows: - - ``` - group("wifiiot") { # The target name must be the same as the product name. - deps = [] - # Copy the init configuration. - deps += [ "init_configs" ] - # Build the hals directory. - deps += [ "hals" ] - # Others - ...... - } + ./build.sh --product-name Hi3516DV300 --ccache ``` -8. Build the product. +4. Obtain the build result. - Run the **hb set** command in the root code directory to select the new product as prompted, and then run the **hb build** command to start the build. + Files generated during the build are stored in the **out/ohos-arm-release/** directory, and the generated image is stored in the **out/ohos-arm-release/packages/phone/images/** directory. diff --git a/en/device-dev/subsystems/compilation-and-building-overview-0.md b/en/device-dev/subsystems/compilation-and-building-overview-0.md deleted file mode 100644 index de4d2beab9d8c3f91f9d1ff841af68e9311b0fb6..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/compilation-and-building-overview-0.md +++ /dev/null @@ -1,60 +0,0 @@ -# Compilation and Building Overview - -- [Basic Concepts](#section175012297491) -- [Working Principles](#section193961322175011) -- [Limitations and Constraints](#section2029921310472) - -The compilation and building subsystem provides a framework based on Generate Ninja \(GN\) and Ninja. This subsystem allows you to: - -- Build products based on different chipset platforms, for example, Hi3516D V300. - -- Package capabilities required by a product by assembling modules based on the product configuration. - -## Basic Concepts - -It is considered best practice to learn the following basic concepts before you start building: - -- **Platform** - - A platform is a combination of development boards and kernels. - - Supported subsystems and modules vary according to the platform. - -- **Subsystems** - - OpenHarmony is designed with a layered architecture, which from bottom to top consists of the kernel layer, system service layer, framework layer, and application layer. System functions are expanded by levels, from system to subsystem, and further to module. In a multi-device deployment scenario, unnecessary subsystems and modules can be excluded from the system as required. A subsystem is a logical concept and is a flexible combination of functions. - -- **Module** - - A module is a reusable software binary unit that contains source code, configuration files, resource files, and build scripts. A module can be built independently, integrated in binary mode, and then tested independently. - -- **GN** - - GN is short for Generate Ninja, which is used to generate Ninja files. - -- **Ninja** - - Ninja is a small high-speed build system. - - -## Working Principles - -The process to build OpenHarmony is as follows: - -- Parsing commands: Parse the name of the product to build and load related configurations. -- Running GN: Configure toolchains and global options based on the parsed product name and compilation type. -- Running Ninja: Start building and generate a product distribution. - -## Limitations and Constraints - -- You must download the source code using method 3 described in [Source Code Acquisition](../get-code/source-code-acquisition.md). -- The build environment must be Ubuntu 18.04 or later. -- You must install the software package required for build. - - The installation command is as follows: - - ``` - sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 - ``` - - diff --git a/en/device-dev/subsystems/compilation-and-building-overview.md b/en/device-dev/subsystems/compilation-and-building-overview.md index 8cf7a6a1c1459288b1430f022740ef3a229663dd..de4d2beab9d8c3f91f9d1ff841af68e9311b0fb6 100644 --- a/en/device-dev/subsystems/compilation-and-building-overview.md +++ b/en/device-dev/subsystems/compilation-and-building-overview.md @@ -1,132 +1,60 @@ -# Compilation and Building Overview +# Compilation and Building Overview - [Basic Concepts](#section175012297491) -- [Usage Guidelines](#section193961322175011) +- [Working Principles](#section193961322175011) - [Limitations and Constraints](#section2029921310472) -The compilation and building subsystem is a building framework based on Generate Ninja \(GN\) and Ninja, which supports component-based OpenHarmony development. This subsystem can be used to: +The compilation and building subsystem provides a framework based on Generate Ninja \(GN\) and Ninja. This subsystem allows you to: -- Build existing products. +- Build products based on different chipset platforms, for example, Hi3516D V300. -- Build chipset source code independently. -- Build a single component independently. +- Package capabilities required by a product by assembling modules based on the product configuration. ## Basic Concepts -It is considered best practice to learn the following basic concepts before you start development and building: +It is considered best practice to learn the following basic concepts before you start building: -- **Component** +- **Platform** - A component is a reusable software unit that can contain source code, configuration files, resource files, and compilation scripts. + A platform is a combination of development boards and kernels. -- **GN** - - GN is short for Generate Ninja, which is used to generate Ninja files. - -- **Ninja** - - Ninja is a small high-speed building system. - - -## Usage Guidelines - -1. **Building Process** + Supported subsystems and modules vary according to the platform. - [Figure 1](#fig9744112715161) shows the building process. +- **Subsystems** - **Figure 1** Building process - ![](figures/building-process.jpg "building-process") + OpenHarmony is designed with a layered architecture, which from bottom to top consists of the kernel layer, system service layer, framework layer, and application layer. System functions are expanded by levels, from system to subsystem, and further to module. In a multi-device deployment scenario, unnecessary subsystems and modules can be excluded from the system as required. A subsystem is a logical concept and is a flexible combination of functions. - 1. **hb set**: Set the OpenHarmony source code directory and the product to build. - 2. **hb build**: Build the product, development board, or component. The process to build the solution is as follows: - - **Reading configuration**: Read the development board configuration, which covers the toolchain, linking commands, and compilation options. - - **Running gn**: Run the **gn gen** command to read the product configuration \(related to the development board, kernel, and system components\) and generate the **out** directory and **ninja** files for the solution. - - **Running Ninja**: Run **ninja -C out/company/product** to start compilation. - - **Packaging**: Package the compilation result to create a file system image. +- **Module** + A module is a reusable software binary unit that contains source code, configuration files, resource files, and build scripts. A module can be built independently, integrated in binary mode, and then tested independently. -2. **Building Commands** - - 1. **hb set** - - ``` - hb set -h - usage: hb set [-h] [-root [ROOT_PATH]] [-p] - - optional arguments: - -h, --help show this help message and exit - -root [ROOT_PATH], --root_path [ROOT_PATH] - Set OHOS root path - -p, --product Set OHOS board and kernel - ``` +- **GN** - - If you run **hb set** with no argument, the default setting process starts. - - You can run **hb set -root** _dir_ to set the root directory of the source code. - - **hb set -p** is used to set the product to compile. + GN is short for Generate Ninja, which is used to generate Ninja files. - 2. **hb env** +- **Ninja** - View the current configuration. + Ninja is a small high-speed build system. - ``` - hb env - [OHOS INFO] root path: xxx - [OHOS INFO] board: hispark_taurus - [OHOS INFO] kernel: liteos - [OHOS INFO] product: ipcamera - [OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera - [OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 - ``` - 3. **hb build** +## Working Principles - ``` - hb build -h - usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] - [--dmverity] [-p PRODUCT] [-f] [-n] - [component [component ...]] - - positional arguments: - component name of the component - - optional arguments: - -h, --help show this help message and exit - -b BUILD_TYPE, --build_type BUILD_TYPE - release or debug version - -c COMPILER, --compiler COMPILER - specify compiler - -t [TEST [TEST ...]], --test [TEST [TEST ...]] - compile test suite - --dmverity Enable dmverity - -p PRODUCT, --product PRODUCT - build a specified product with - {product_name}@{company}, eg: ipcamera@hisilcon - -f, --full full code compilation - ``` +The process to build OpenHarmony is as follows: - - If you run **hb build** with no argument, the previously configured code directory, product, and options are used for the compilation. The **-f** option will delete all products to be compiled, which is equivalent to running **hb clean** and **hb build**. - - You can run **hb build** _\{component\_name\}_ to compile product components separately based on the development board and kernel set for the product, for example, **hb build kv\_store**. - - You can run **hb build -p ipcamera@hisilicon** to skip the setting step and compile the product directly. - - You can run **hb build** in **device/device\_company/board** to select the kernel and start compilation based on the current development board and the selected kernel to generate an image that contains the kernel and driver only. +- Parsing commands: Parse the name of the product to build and load related configurations. +- Running GN: Configure toolchains and global options based on the parsed product name and compilation type. +- Running Ninja: Start building and generate a product distribution. - 4. **hb clean** +## Limitations and Constraints - Clear the compilation result of the product in the **out** directory, and retain the **args.gn** and **build.log** files only. To clear files in a specified directory, add the directory parameter to the command, for example, **hb clean** _xxx_**/out/**_xxx_. +- You must download the source code using method 3 described in [Source Code Acquisition](../get-code/source-code-acquisition.md). +- The build environment must be Ubuntu 18.04 or later. +- You must install the software package required for build. + The installation command is as follows: ``` - hb clean - usage: hb clean [-h] [out_path] - - positional arguments: - out_path clean a specified path. - - optional arguments: - -h, --help show this help message and exit + sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 ``` -## Limitations and Constraints - -Ensure that the development environment has GN and Ninja, Python 3.7.4 and later, and hb commands. You must download the complete code before you start. - diff --git a/en/device-dev/subsystems/development-guidelines-5.md b/en/device-dev/subsystems/development-guidelines-4.md similarity index 100% rename from en/device-dev/subsystems/development-guidelines-5.md rename to en/device-dev/subsystems/development-guidelines-4.md diff --git a/en/device-dev/subsystems/development-guidelines-on-photographing.md b/en/device-dev/subsystems/development-guidelines-on-photographing.md index 23f92734097a2c318c8701f8c30983b88100b7bc..d35bed7457c70bc19d6c66cdbca1267b7da37aec 100644 --- a/en/device-dev/subsystems/development-guidelines-on-photographing.md +++ b/en/device-dev/subsystems/development-guidelines-on-photographing.md @@ -385,6 +385,7 @@ None Surface *surface = Surface::CreateSurface(); if (surface == nullptr) { delete fc; + return; } surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ fc->AddSurface(*surface); diff --git a/en/device-dev/subsystems/development-guidelines-on-trusted-device-group-management.md b/en/device-dev/subsystems/development-guidelines-on-trusted-device-group-management.md deleted file mode 100644 index 91c4013935b5b3b8ce3cea7997dbeae25f7ac67d..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/development-guidelines-on-trusted-device-group-management.md +++ /dev/null @@ -1,264 +0,0 @@ -# Development Guidelines on Trusted Device Group Management - -- [When to Use](#section18502174174019) -- [Available APIs](#section1633115419401) -- [How to Develop](#section17516229192313) -- [Debugging and Verification](#section427316292411) - -## When to Use - -When a distributed service needs to exploit the secure communication channel provided by the distributed virtual bus for different devices, it can use the trusted device group management component to create groups of trusted devices. Distributed applications can establish and use secure, trusted relationships between devices based on the authentication capabilities for devices using different HUAWEI IDs, such as PIN code, QR code, and OneHop, and the capabilities for grouped devices using the same HUAWEI ID. For a device on which you have not logged in using your HUAWEI ID, you can enter the PIN code or scan the QR code to obtain the connection and PIN code information of the device. Then you can create a group of trusted devices and add this device to the group. If other applications have created and shared their groups of trusted devices, or have logged in using the same HUAWEI ID as yours, you can call APIs to query and use the groups. - -## Available APIs - -The following tables list the innerkits APIs provided by trusted device group management. These APIs are intended for system applications only. - -**Table 1** Java APIs provided by trusted device group management - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

public static DeviceGroupManager getInstance(Abilityability, StringappID, IHichainGroupCallbackcallbackHandler)

-

Obtains a DeviceGroupManager instance and registers a listener.

-

int createGroup(String appId, String groupName, int groupType, String groupInfo)

-

Creates a group of trusted devices.

-

public int deleteGroup(String gourpId)

-

Deletes a group of trusted devices.

-

public String getLocalConnectInfo()

-

Obtains the network connection information of the local device.

-

int addMemberToGroup(String appId, long requestId, String addParams, String connectParams, int groupType)

-

Adds a member to a specified group.

-

int deleteMemberFromGroup(String appId, long requestId, String deleteParams, String connectParams)

-

Deletes a member from a specified group.

-

int cancelRequest(long requestId)

-

Cancels an ongoing request, for example, adding or deleting a member.

-

List<String> listJoinedGroups(int groupType)

-

Obtains a list of groups of a specified type to which the current device has been added.

-

List<String> listTrustedDevices(String groupId)

-

Obtains a list of devices in a specified group.

-

boolean isDeviceInGroup(String groupId, String deviceId)

-

Checks whether a specified device has been added to the given group.

-

List<String> getGroupInfo(String queryParams)

-

Obtains a list of information about the groups that match the input parameters.

-

int setFriendsList(String groupId, List<String> friendsList)

-

Adds a friend list to a specified group.

-

List<String> getFriendsList(String groupId)

-

Obtains the friend list of a specified group.

-

int registerGroupNotice(String groupId, IHichainGroupChangeListener groupChangeListener)

-

Registers a listener for changes to a specified group.

-

int revokeGroupNotice(String groupId)

-

Revokes the listener for changes to a specified group.

-
- -**Table 2** C++ APIs provided by trusted device group management for internal applications to query group information using SA - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

DeviceAuthProxy()

-

Obtains a DeviceAuthProxy instance.

-

~DeviceAuthProxy()

-

A destructor used to delete the DeviceAuthProxy instance.

-

static int CheckAccessToGroup(const std::string &groupId, const std::string &pkgName);

-

Checks whether an application with a specified bundle name can access a specified group.

-

static int CheckAccessToDevice(const std::string &connDeviceId, const std::string &pkgName);

-

Checks whether an application with a specified bundle name can access the group that contains a specified device.

-

static std::vector<std::string> GetRelatedGroupInfo(const std::string &connDeviceId);

-

Obtains information about all the groups that contain both the local device and the device with a specified ID.

-
- -## How to Develop - -To develop trusted device group management, first obtain a management instance \(a callback to obtain group operation results is registered during the process\). Then you can use the instance to add or delete members, set a friend list for a group, and perform related query operations. - -**Scenario 1**: Create a group. - -``` -private HwDeviceGroupManager hwDeviceGroupManager; -... -private HichainGroupCallback groupCallbackByA = new HichainGroupCallback() { - @Override public void onFinish(long requestId, GroupOperation operationCode, String returnData) { - - } - @Override public void onError(long requestId, GroupOperation operationCode, int errorCode, String errorReturn) { - - } - @Override public String onRequest(long requestId, GroupOperation operationCode, String reqParams) { - JSONObject onRequestJson = generateConfirmation(REQUEST_ACCEPTED); - return onRequestJson.toString(); - } -}; -... -Optional context = convertAbilityToContext(mAbility); -Context ctxt = context.get(); -hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA); -int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO); -``` - -1. Declare the private member variable of the **HwDeviceGroupManager** instance. - - ``` - private HwDeviceGroupManager hwDeviceGroupManager; - ``` - -2. Create a callback for group management operations. - - ``` - private HichainGroupCallback groupCallbackByA = new HichainGroupCallback(); - ``` - -3. Obtain a **HwDeviceGroupManager** instance. \(In distributed scenarios, the same application on different devices must use the same **APP\_ID**.\) - - ``` - hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA); - ``` - -4. Call the **createGroup** function to create a group. If **0** is returned, the creation request is submitted successfully. - - ``` - int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO); - ``` - -5. After the group is created, **onFinish** is called. In this callback, the value of **operationCode** is **OperationCode.CREATE**, indicating a group creation operation. **returnData** is in JSON format and contains the **groupId** field, indicating the ID of the created group. - -**Scenario 2**: Add an authenticated device \(member\) to a group so that you can initiate trusted, encrypted connections to the device through the distributed virtual bus. - -``` -deviceGroupManager = DeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback); -private static final String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}"; -private static final String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}"; -private static final int GROUP_TYPE = 256; -int result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE); -``` - -1. Obtain an **HwDeviceGroupManager** instance. - - ``` - deviceGroupManager = HwDeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback); - ``` - -2. Set network connection parameters for the member to add \(in JSON format\), which are network parameters supported by the distributed virtual bus, such as **WIFI\_IP**, **WIFI\_PORT**, **BLR\_MAC**, and **DEVICE\_ID**. For details about the parameters, see the distributed virtual bus development guidelines. - - ``` - String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}"; - ``` - -3. Set parameters for the member to add \(in JSON format\), including the group ID, name, and whether the member is an administrator. If the member is invited to add a group, the value of **isAdmin** is **true**; otherwise, the value of **isAdmin** is **false**. - - ``` - String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}"; - ``` - -4. Set the type of the target group to **256**, indicating a P2P group. - - ``` - private static final int GROUP_TYPE = 256; - ``` - -5. Set **generateConfirmation** of the **onRequest** function in **HichainGroupCallback**. **PIN\_CODE** indicates the PIN code, which is input by users on the UI of the service. \(In a distributed communication, two devices must use the same PIN code.\) - - ``` - private JSONObject generateConfirmation(int confirmation) { - JSONObject jsonObject = new JSONObject(); - try { jsonObject.put("pinCode", PIN_CODE); - jsonObject.put("confirmation", confirmation); - } catch (JSONException e) { - LogUtil.error(TAG, "" + e.getMessage()); - } - return jsonObject; - } - ``` - -6. Call the **addMemberToGroup** function to add the member to the group. - - ``` - result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE); - ``` - -7. Check whether **HichainGroupCallback.onFinish** is called \(**operationCode** is **OperationCode.JOIN**\). If it is called, the member is added successfully. -8. Call APIs of the distributed virtual bus to create secure sessions between devices. - -## Debugging and Verification - -1. Develop an application with OpenHarmony. - -2. Develop an application by following the development guidelines. - -3. Create a group. If the **onFinish** callback is invoked, the group is created successfully. - -4. Deploy the same application on two devices, A and B. - -5. Transmit the connection parameters of device B to device A through a QR code. - -6. In the application on device A, create group1 and call the API to add device B to group1. If **HichainGroupCallback.onFinish** is called, device B is successfully added to group1. - diff --git a/en/device-dev/subsystems/dfx-11.md b/en/device-dev/subsystems/dfx-7.md similarity index 92% rename from en/device-dev/subsystems/dfx-11.md rename to en/device-dev/subsystems/dfx-7.md index faf8b0d8fa8e4c39a1548d7a7e77b6eb6906bd95..b7bfac023a5bf84628ceb40723a9ed2e62dbb892 100644 --- a/en/device-dev/subsystems/dfx-11.md +++ b/en/device-dev/subsystems/dfx-7.md @@ -6,7 +6,7 @@ The DFX subsystem provides the following functions: -- HiLog: Implements the logging function. It is applicable to Mini-System Devices \(reference memory ≥ 128 KB\), Small-System Devices \(reference memory ≥ 1 MB\), and Standard-System Devices \(reference memory ≥ 128 MB\). +- HiLog: Implements the logging function. It is applicable to Mini-System Devices \(reference memory ≥ 128 KB\) and Small-System Devices \(reference memory ≥ 1 MB\) as well as Standard-System Devices \(reference memory ≥ 128 MB\). - HiSysEvent: Implements system event logging. It is applicable to Standard-System Devices \(reference memory ≥ 128 MB\). diff --git a/en/device-dev/subsystems/dfx.md b/en/device-dev/subsystems/dfx.md index 241303cae97af3db18251e836e22ca628efba17c..c4ffcc54fdf46737c0b3d3363302d22e0990ab22 100644 --- a/en/device-dev/subsystems/dfx.md +++ b/en/device-dev/subsystems/dfx.md @@ -1,6 +1,6 @@ # DFX -- **[DFX](dfx-11.md)** +- **[DFX](dfx-7.md)** - **[Development Guidelines on HiLog](development-guidelines-on-hilog.md)** diff --git a/en/device-dev/subsystems/figures/build-process.jpg b/en/device-dev/subsystems/figures/build-process.jpg index c8d58bc3d172524c78e3c45455622d081429529c..a48ea734509526b3ed0fe85b7c4a98b0a2a9c4f0 100644 Binary files a/en/device-dev/subsystems/figures/build-process.jpg and b/en/device-dev/subsystems/figures/build-process.jpg differ diff --git a/en/device-dev/subsystems/figures/building-process.jpg b/en/device-dev/subsystems/figures/building-process.jpg deleted file mode 100644 index c8d58bc3d172524c78e3c45455622d081429529c..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/figures/building-process.jpg and /dev/null differ diff --git a/en/device-dev/subsystems/figures/ril-adapter.png b/en/device-dev/subsystems/figures/ril-adapter.png deleted file mode 100644 index 51d8a0668a19b26071873247a5cf1f483d9044e5..0000000000000000000000000000000000000000 Binary files a/en/device-dev/subsystems/figures/ril-adapter.png and /dev/null differ diff --git "a/en/device-dev/subsystems/figures/\345\216\273\347\224\265.png" "b/en/device-dev/subsystems/figures/\345\216\273\347\224\265.png" deleted file mode 100644 index fd53e705cde494b3b5a7a5e2c923a9b5ac07aa4f..0000000000000000000000000000000000000000 Binary files "a/en/device-dev/subsystems/figures/\345\216\273\347\224\265.png" and /dev/null differ diff --git "a/en/device-dev/subsystems/figures/\346\235\245\347\224\265.png" "b/en/device-dev/subsystems/figures/\346\235\245\347\224\265.png" deleted file mode 100644 index 9b27f13794e395cb6b05ec588f96bc938288ec01..0000000000000000000000000000000000000000 Binary files "a/en/device-dev/subsystems/figures/\346\235\245\347\224\265.png" and /dev/null differ diff --git a/en/device-dev/subsystems/graphics-2.md b/en/device-dev/subsystems/graphics-1.md similarity index 100% rename from en/device-dev/subsystems/graphics-2.md rename to en/device-dev/subsystems/graphics-1.md diff --git a/en/device-dev/subsystems/graphics.md b/en/device-dev/subsystems/graphics.md index 254f1e0fa0022f821ba9ecb5f8f88846a868bfe7..db3332445d4a69852fb1d709531774f719344cbe 100644 --- a/en/device-dev/subsystems/graphics.md +++ b/en/device-dev/subsystems/graphics.md @@ -1,6 +1,6 @@ # Graphics -- **[Graphics](graphics-2.md)** +- **[Graphics](graphics-1.md)** - **[Development Guidelines on Container Components](development-guidelines-on-container-components.md)** diff --git a/en/device-dev/subsystems/overview-2.md b/en/device-dev/subsystems/overview-2.md new file mode 100644 index 0000000000000000000000000000000000000000..98b5b4ad048a507a0a4fe21297b86ca6b158995d --- /dev/null +++ b/en/device-dev/subsystems/overview-2.md @@ -0,0 +1,81 @@ +# Overview + +- [Basic Concepts](#section967213571204) +- [Encoding and Decoding](#section1582020483111) + +OpenHarmony multimedia services help you to develop for audio and video playback and recording. + +- The media playback module facilitates the development of audio and video playback, including media file and stream playback, volume control, and playback progress control. +- The media recording module supports the development of audio and video recording and provides functions to set the size of captured video, encoding bit rate, encoder type, video frame rate, audio sampling rate, and output file format. + +## Basic Concepts + +It is considered good practice that you understand the following concepts before starting development: + +- Streaming media technology + + The streaming media technology refers to a process to encode continuous video and audio data and store the data on a network server. A viewer can watch and listen to the video and audio during download with no need to wait for the completion of download. + + +- Video frame rate + + The frame rate is used to measure the number of displayed frames, which is the number of images transmitted per second. The more frames per second \(FPS\), the smoother the video. + +- Bit rate + + Bit rate is the number of bits transmitted per unit of time. The commonly used unit is kbit/s. + +- Sampling rate + + The sampling rate is the number of samples per second taken from continuous signals to form discrete signals. The unit is hertz \(Hz\). + + +## Encoding and Decoding + +Available audio and video encoding and decoding capabilities vary depending on device types. The following table lists supported specifications for available development boards. + +**Table 1** Encoding and decoding specifications for different development boards + + + + + + + + + + + + + + + + + + + + + + + + +

Device Type

+

Development Board

+

Decoding

+

Encoding

+

Cameras with a screen

+

Hi3516

+
  • Audio: The MPEG-4 AAC Profile (AAC LC), mono and dual channels, and the MPEG-4 (.mp4 and .m4a) container format are supported.
  • Video: The H.265 (HEVC) and H.264 (AVC) (for streams encoded using a chip of the same type) and the MPEG-4 (.mp4) container format are supported.
+
  • Audio: AAC-LC encoding, mono and dual channels, and the MPEG-4 (.mp4) container format are supported.
  • Video: H.264 and H.265 encoding and the MPEG-4 (.mp4) container format are supported.
+

Cameras without a screen

+

Hi3518

+
  • Audio: The MPEG-4 AAC Profile (AAC LC), mono and dual channels, and the MPEG-4 (.mp4 and .m4a) container format are supported.
  • Video: none
+
  • Audio: AAC-LC encoding, mono and dual channels, and the MPEG-4 (.mp4) container format are supported.
  • Video: H.264 and H.265 encoding and the MPEG-4 (.mp4) container format are supported.
+

WLAN connecting devices

+

Hi3861

+

N/A

+

N/A

+
+ +For details about the encoding and decoding specifications of Hi3516 and Hi3518, refer to their documentation. + diff --git a/en/device-dev/subsystems/overview-3.md b/en/device-dev/subsystems/overview-3.md index 98b5b4ad048a507a0a4fe21297b86ca6b158995d..be32c8ebf46f3db9ab43c7a48fc0556250a04b7b 100644 --- a/en/device-dev/subsystems/overview-3.md +++ b/en/device-dev/subsystems/overview-3.md @@ -1,81 +1,148 @@ -# Overview +# Overview -- [Basic Concepts](#section967213571204) -- [Encoding and Decoding](#section1582020483111) +- [Basic Concepts](#section72601941194812) +- [Ability Management Framework](#section14633111813374) +- [Bundle Management Framework](#section1341146154412) +- [Working Principles](#section94302021112717) +- [Limitations and Constraints](#section89534912527) -OpenHarmony multimedia services help you to develop for audio and video playback and recording. +The application framework is provided by OpenHarmony for you to develop OpenHarmony applications. It consists of two modules: ability management framework \(also called the ability framework\) and bundle management framework. -- The media playback module facilitates the development of audio and video playback, including media file and stream playback, volume control, and playback progress control. -- The media recording module supports the development of audio and video recording and provides functions to set the size of captured video, encoding bit rate, encoder type, video frame rate, audio sampling rate, and output file format. +## Basic Concepts -## Basic Concepts +This section describes some basic concepts for you to better understand the OpenHarmony application framework before you start development. -It is considered good practice that you understand the following concepts before starting development: +## Ability Management Framework -- Streaming media technology +The ability management framework manages running status of OpenHarmony applications. - The streaming media technology refers to a process to encode continuous video and audio data and store the data on a network server. A viewer can watch and listen to the video and audio during download with no need to wait for the completion of download. +**Figure 1** Architecture of the ability management framework +![](figures/architecture-of-the-ability-management-framework.png "architecture-of-the-ability-management-framework") +- **Ability** is the minimum unit for the system to schedule applications. It is a component that can implement an independent functionality. An application can contain one or more **Ability** instances. There are two types of templates that you can use to create an **Ability** instance: Page and Service. + - An **Ability using the Page template** \(Page ability for short\) provides a UI for interacting with users. -- Video frame rate + - An **Ability using the Service template** does not have a UI and is used for running background tasks. - The frame rate is used to measure the number of displayed frames, which is the number of images transmitted per second. The more frames per second \(FPS\), the smoother the video. -- Bit rate - Bit rate is the number of bits transmitted per unit of time. The commonly used unit is kbit/s. +- An **AbilitySlice** represents a single screen and its control logic. It is specific to Page abilities. A Page ability may contain one ability slice or multiple ability slices that provide highly relevant capabilities. -- Sampling rate + **Figure 2** Relationship between a Page ability and its ability slices + ![](figures/relationship-between-a-page-ability-and-its-ability-slices.png "relationship-between-a-page-ability-and-its-ability-slices") - The sampling rate is the number of samples per second taken from continuous signals to form discrete signals. The unit is hertz \(Hz\). +- **Lifecycle** is a general term for all states of an ability, including **INITIAL**, **INACTIVE**, **ACTIVE**, and **BACKGROUND**. + **Figure 3** Lifecycle state transition of a Page ability + -## Encoding and Decoding + ![](figures/图片1.png) -Available audio and video encoding and decoding capabilities vary depending on device types. The following table lists supported specifications for available development boards. + - **OnStart\(\)** + + This callback is invoked when the system first creates the Page ability. After this callback is executed, the Page ability enters the **INACTIVE** state. This callback is triggered only once in the entire lifecycle of each Page ability. You must override this callback and set the default ability slice to be displayed. + + - **OnActive\(\)** + + This callback is invoked when the Page ability in the **INACTIVE** state enters the foreground. After this callback is executed, the Page ability enters the **ACTIVE** state, in which it becomes interactive. The Page ability will stay in this state unless it loses focus upon a certain event, for example, when the user touches the Back button or navigates to another Page ability. + + When such an event occurs, the Page ability returns to the **INACTIVE** state, and the system invokes the **OnInactive\(\)** callback. The Page ability may move to the **ACTIVE** state again, and the system will then invoke the **OnActive\(\)** callback again. You should implement both **OnActive\(\)** and **OnInactive\(\)** for a Page ability and use **OnActive\(\)** to obtain the resources released in **OnInactive\(\)**. + + - **OnInactive\(\)** + + This callback is invoked when the Page ability loses focus, and the Page ability then becomes **INACTIVE**. You can implement the behavior to perform after the Page ability loses focus. + + - **OnBackground\(\)** + + This callback is invoked based on the system resource status when the Page ability becomes invisible to the user. After this callback is executed, the Page ability enters the **BACKGROUND** state. You should release the resources that are no longer needed after the Page ability becomes invisible or perform time-consuming save operations in this callback. + + - **OnForeground\(\)** + + A Page ability in the **BACKGROUND** state still resides in memory. When the Page ability returns to the foreground \(for example, when the user navigates to this Page ability again\), the system first calls **OnForeground\(\)** to switch the Page ability to the **INACTIVE** state, and then calls **OnActive\(\)** to make it **ACTIVE**. You should use the **OnForeground\(\)** callback to reclaim the resources released in **OnBackground\(\)**. Currently, the **OnForeground\(\)** callback is unavailable to lite devices. + + - **OnStop\(\)** + + This callback is invoked when the system is destroying a Page ability due to one of the following possible causes: + + - The user explicitly closes the Page ability using a system management feature, for example, the task manager. + - The user behavior, for example, exiting an application, triggers the **TerminateAbility\(\)** function on the Page ability. + - The system needs to temporarily destroy the Page ability and re-create it due to configuration changes. + - The system automatically destroys a Page ability in the **BACKGROUND** state due to resource management purposes. + + +- **AbilityKit** is a development kit provided by the ability management framework. You can use this kit to develop applications based on the **Ability** component. There are two types of applications developed based on the **Ability** component: JS Ability developed using the JavaScript language and Native Ability developed using the C/C++ language. The JS application development framework encapsulates JavaScript UI components on the basis of the AbilityKit and is used to help you quickly develop JS Ability-based applications. +- **AbilityLoader** is used to register and load **Ability** classes. After creating an **Ability** class, you should first call the registration API defined in **AbilityLoader** to register the **Ability** class name with the ability management framework so that this **Ability** can be instantiated when being started. + +- **AbilityManager** enables inter-process communication \(IPC\) between the AbilityKit and the Ability Manager Service. + +- **EventHandler** is provided by the AbilityKit to enable inter-thread communication between abilities. + +- The **Ability Manager Service** is a system service used to coordinate the running relationships and lifecycle states of **Ability** instances. It consists of the following modules: + + - The service startup module starts and registers the Ability Manager Service. + - The service interface management module manages external capabilities provided by the Ability Manager Service. + - The process management module starts and destroys processes where **Ability** instances are running, and maintains the process information. + - The ability stack management module maintains the presentation sequence of abilities in the stack. + - The lifecycle scheduling module changes an ability to a particular state based on the current operation of the system. + - The connection management module manages connections to Service abilities. + +- **AppSpawn** is a system service used to create the process for running an ability. This service has high permissions. It sets permissions for **Ability** instances and pre-loads some common modules to accelerate application startup. + + +## Bundle Management Framework + +The bundle management framework is provided by OpenHarmony for you to manage application bundles. + +**Figure 4** Architecture of the bundle management framework +![](figures/architecture-of-the-bundle-management-framework.png "architecture-of-the-bundle-management-framework") + +- **BundleKit** includes external APIs provided by the Bundle Manager Service, including the APIs for application installation and uninstallation, bundle information query, and bundle state change listeners. +- The **bundle scanning sub-module** parses pre-installed or installed bundles on the local device and extracts information from them for the bundle management module to manage and make the information persistent for storage. +- The **bundle installation sub-module** installs, uninstalls, and updates a bundle. The **bundle installation service** is an independent process that communicates with the Bundle Manager Service through IPC. It is used to create or delete installation directories and has high permissions. + +- The **bundle management sub-module** manages information related to application bundles and stores persistent bundle information. + +- The **bundle security management sub-module** verifies signatures, and grants and manages permissions. + + +## Working Principles + +The Ability Manager Service and Bundle Manager Service are the core modules of the ability management framework and bundle management framework, respectively. The two system-level services are registered and discovered by using the system service framework SAMgr, and they are used by manage abilities and bundles for other processes. The Ability Manager Service and Bundle Manager Service are provided as open APIs in the AbilityKit and BundleKit. + +**Figure 5** Startup of the Ability Manager Service and Bundle Manager Service +![](figures/startup-of-the-ability-manager-service-and-bundle-manager-service.png "startup-of-the-ability-manager-service-and-bundle-manager-service") + +OpenHarmony applications can be installed and started after the two services are started. + +**Figure 6** Application startup process +![](figures/application-startup-process.png "application-startup-process") + +The home screen is the first OpenHarmony application started by the Ability Manager Service. After the home screen is started, the user can touch any installed OpenHarmony application on the home screen to start the particular application. The figure above shows the interaction process of starting an installed application from the home screen. + +As shown in the figure, the Ability Manager Service is responsible for displaying or hiding an ability, and the Bundle Manager Service is responsible for storing and querying ability information. + +## Limitations and Constraints + +- Language version + + - C++ 11 or later + + +- The specifications of the application framework vary depending on the System-on-a-Chip \(SoC\) and underlying OS capabilities. + + - Cortex-M RAM and ROM + + - RAM: greater than 20 KB \(recommended\) + + - ROM: greater than 300 KB \(for the JS application development framework and related subsystems, such as UIKit and engine\) + + + - Cortex-A RAM and ROM + + - RAM: greater than 2 MB \(recommended\) + + - ROM: greater than 2 MB \(for the JS application development framework and related subsystems, such as UIKit and engine\) -**Table 1** Encoding and decoding specifications for different development boards - - - - - - - - - - - - - - - - - - - - - - - -

Device Type

-

Development Board

-

Decoding

-

Encoding

-

Cameras with a screen

-

Hi3516

-
  • Audio: The MPEG-4 AAC Profile (AAC LC), mono and dual channels, and the MPEG-4 (.mp4 and .m4a) container format are supported.
  • Video: The H.265 (HEVC) and H.264 (AVC) (for streams encoded using a chip of the same type) and the MPEG-4 (.mp4) container format are supported.
-
  • Audio: AAC-LC encoding, mono and dual channels, and the MPEG-4 (.mp4) container format are supported.
  • Video: H.264 and H.265 encoding and the MPEG-4 (.mp4) container format are supported.
-

Cameras without a screen

-

Hi3518

-
  • Audio: The MPEG-4 AAC Profile (AAC LC), mono and dual channels, and the MPEG-4 (.mp4 and .m4a) container format are supported.
  • Video: none
-
  • Audio: AAC-LC encoding, mono and dual channels, and the MPEG-4 (.mp4) container format are supported.
  • Video: H.264 and H.265 encoding and the MPEG-4 (.mp4) container format are supported.
-

WLAN connecting devices

-

Hi3861

-

N/A

-

N/A

-
-For details about the encoding and decoding specifications of Hi3516 and Hi3518, refer to their documentation. diff --git a/en/device-dev/subsystems/overview-4.md b/en/device-dev/subsystems/overview-4.md deleted file mode 100644 index be32c8ebf46f3db9ab43c7a48fc0556250a04b7b..0000000000000000000000000000000000000000 --- a/en/device-dev/subsystems/overview-4.md +++ /dev/null @@ -1,148 +0,0 @@ -# Overview - -- [Basic Concepts](#section72601941194812) -- [Ability Management Framework](#section14633111813374) -- [Bundle Management Framework](#section1341146154412) -- [Working Principles](#section94302021112717) -- [Limitations and Constraints](#section89534912527) - -The application framework is provided by OpenHarmony for you to develop OpenHarmony applications. It consists of two modules: ability management framework \(also called the ability framework\) and bundle management framework. - -## Basic Concepts - -This section describes some basic concepts for you to better understand the OpenHarmony application framework before you start development. - -## Ability Management Framework - -The ability management framework manages running status of OpenHarmony applications. - -**Figure 1** Architecture of the ability management framework -![](figures/architecture-of-the-ability-management-framework.png "architecture-of-the-ability-management-framework") - -- **Ability** is the minimum unit for the system to schedule applications. It is a component that can implement an independent functionality. An application can contain one or more **Ability** instances. There are two types of templates that you can use to create an **Ability** instance: Page and Service. - - An **Ability using the Page template** \(Page ability for short\) provides a UI for interacting with users. - - - An **Ability using the Service template** does not have a UI and is used for running background tasks. - - - -- An **AbilitySlice** represents a single screen and its control logic. It is specific to Page abilities. A Page ability may contain one ability slice or multiple ability slices that provide highly relevant capabilities. - - **Figure 2** Relationship between a Page ability and its ability slices - ![](figures/relationship-between-a-page-ability-and-its-ability-slices.png "relationship-between-a-page-ability-and-its-ability-slices") - -- **Lifecycle** is a general term for all states of an ability, including **INITIAL**, **INACTIVE**, **ACTIVE**, and **BACKGROUND**. - - **Figure 3** Lifecycle state transition of a Page ability - - - ![](figures/图片1.png) - - - **OnStart\(\)** - - This callback is invoked when the system first creates the Page ability. After this callback is executed, the Page ability enters the **INACTIVE** state. This callback is triggered only once in the entire lifecycle of each Page ability. You must override this callback and set the default ability slice to be displayed. - - - **OnActive\(\)** - - This callback is invoked when the Page ability in the **INACTIVE** state enters the foreground. After this callback is executed, the Page ability enters the **ACTIVE** state, in which it becomes interactive. The Page ability will stay in this state unless it loses focus upon a certain event, for example, when the user touches the Back button or navigates to another Page ability. - - When such an event occurs, the Page ability returns to the **INACTIVE** state, and the system invokes the **OnInactive\(\)** callback. The Page ability may move to the **ACTIVE** state again, and the system will then invoke the **OnActive\(\)** callback again. You should implement both **OnActive\(\)** and **OnInactive\(\)** for a Page ability and use **OnActive\(\)** to obtain the resources released in **OnInactive\(\)**. - - - **OnInactive\(\)** - - This callback is invoked when the Page ability loses focus, and the Page ability then becomes **INACTIVE**. You can implement the behavior to perform after the Page ability loses focus. - - - **OnBackground\(\)** - - This callback is invoked based on the system resource status when the Page ability becomes invisible to the user. After this callback is executed, the Page ability enters the **BACKGROUND** state. You should release the resources that are no longer needed after the Page ability becomes invisible or perform time-consuming save operations in this callback. - - - **OnForeground\(\)** - - A Page ability in the **BACKGROUND** state still resides in memory. When the Page ability returns to the foreground \(for example, when the user navigates to this Page ability again\), the system first calls **OnForeground\(\)** to switch the Page ability to the **INACTIVE** state, and then calls **OnActive\(\)** to make it **ACTIVE**. You should use the **OnForeground\(\)** callback to reclaim the resources released in **OnBackground\(\)**. Currently, the **OnForeground\(\)** callback is unavailable to lite devices. - - - **OnStop\(\)** - - This callback is invoked when the system is destroying a Page ability due to one of the following possible causes: - - - The user explicitly closes the Page ability using a system management feature, for example, the task manager. - - The user behavior, for example, exiting an application, triggers the **TerminateAbility\(\)** function on the Page ability. - - The system needs to temporarily destroy the Page ability and re-create it due to configuration changes. - - The system automatically destroys a Page ability in the **BACKGROUND** state due to resource management purposes. - - -- **AbilityKit** is a development kit provided by the ability management framework. You can use this kit to develop applications based on the **Ability** component. There are two types of applications developed based on the **Ability** component: JS Ability developed using the JavaScript language and Native Ability developed using the C/C++ language. The JS application development framework encapsulates JavaScript UI components on the basis of the AbilityKit and is used to help you quickly develop JS Ability-based applications. -- **AbilityLoader** is used to register and load **Ability** classes. After creating an **Ability** class, you should first call the registration API defined in **AbilityLoader** to register the **Ability** class name with the ability management framework so that this **Ability** can be instantiated when being started. - -- **AbilityManager** enables inter-process communication \(IPC\) between the AbilityKit and the Ability Manager Service. - -- **EventHandler** is provided by the AbilityKit to enable inter-thread communication between abilities. - -- The **Ability Manager Service** is a system service used to coordinate the running relationships and lifecycle states of **Ability** instances. It consists of the following modules: - - - The service startup module starts and registers the Ability Manager Service. - - The service interface management module manages external capabilities provided by the Ability Manager Service. - - The process management module starts and destroys processes where **Ability** instances are running, and maintains the process information. - - The ability stack management module maintains the presentation sequence of abilities in the stack. - - The lifecycle scheduling module changes an ability to a particular state based on the current operation of the system. - - The connection management module manages connections to Service abilities. - -- **AppSpawn** is a system service used to create the process for running an ability. This service has high permissions. It sets permissions for **Ability** instances and pre-loads some common modules to accelerate application startup. - - -## Bundle Management Framework - -The bundle management framework is provided by OpenHarmony for you to manage application bundles. - -**Figure 4** Architecture of the bundle management framework -![](figures/architecture-of-the-bundle-management-framework.png "architecture-of-the-bundle-management-framework") - -- **BundleKit** includes external APIs provided by the Bundle Manager Service, including the APIs for application installation and uninstallation, bundle information query, and bundle state change listeners. -- The **bundle scanning sub-module** parses pre-installed or installed bundles on the local device and extracts information from them for the bundle management module to manage and make the information persistent for storage. -- The **bundle installation sub-module** installs, uninstalls, and updates a bundle. The **bundle installation service** is an independent process that communicates with the Bundle Manager Service through IPC. It is used to create or delete installation directories and has high permissions. - -- The **bundle management sub-module** manages information related to application bundles and stores persistent bundle information. - -- The **bundle security management sub-module** verifies signatures, and grants and manages permissions. - - -## Working Principles - -The Ability Manager Service and Bundle Manager Service are the core modules of the ability management framework and bundle management framework, respectively. The two system-level services are registered and discovered by using the system service framework SAMgr, and they are used by manage abilities and bundles for other processes. The Ability Manager Service and Bundle Manager Service are provided as open APIs in the AbilityKit and BundleKit. - -**Figure 5** Startup of the Ability Manager Service and Bundle Manager Service -![](figures/startup-of-the-ability-manager-service-and-bundle-manager-service.png "startup-of-the-ability-manager-service-and-bundle-manager-service") - -OpenHarmony applications can be installed and started after the two services are started. - -**Figure 6** Application startup process -![](figures/application-startup-process.png "application-startup-process") - -The home screen is the first OpenHarmony application started by the Ability Manager Service. After the home screen is started, the user can touch any installed OpenHarmony application on the home screen to start the particular application. The figure above shows the interaction process of starting an installed application from the home screen. - -As shown in the figure, the Ability Manager Service is responsible for displaying or hiding an ability, and the Bundle Manager Service is responsible for storing and querying ability information. - -## Limitations and Constraints - -- Language version - - - C++ 11 or later - - -- The specifications of the application framework vary depending on the System-on-a-Chip \(SoC\) and underlying OS capabilities. - - - Cortex-M RAM and ROM - - - RAM: greater than 20 KB \(recommended\) - - - ROM: greater than 300 KB \(for the JS application development framework and related subsystems, such as UIKit and engine\) - - - - Cortex-A RAM and ROM - - - RAM: greater than 2 MB \(recommended\) - - - ROM: greater than 2 MB \(for the JS application development framework and related subsystems, such as UIKit and engine\) - - - - diff --git a/en/device-dev/subsystems/overview-9.md b/en/device-dev/subsystems/overview-5.md similarity index 100% rename from en/device-dev/subsystems/overview-9.md rename to en/device-dev/subsystems/overview-5.md diff --git a/en/device-dev/subsystems/overview.md b/en/device-dev/subsystems/overview.md index af871180f3042797494129e8a9a80e36e62a1ca7..dd3d44a6a412a87dad271137b77557eb4e7171dd 100644 --- a/en/device-dev/subsystems/overview.md +++ b/en/device-dev/subsystems/overview.md @@ -90,7 +90,7 @@ It is considered good practice that you understand the following concepts before Similarly, you can create a surface, implement consumer logic for it, and transfer it to the **Camera** instance. For example, transmit video streams over the network or save captured frame data as an image file. - The graphics module also obtains stream resources from the camera module through surfaces. For details, see development guidelines on [Graphic](graphics-2.md). + The graphics module also obtains stream resources from the camera module through surfaces. For details, see development guidelines on [Graphic](graphics-1.md). - Camera running process 1. Creating a camera diff --git a/en/device-dev/subsystems/plug-in.md b/en/device-dev/subsystems/plug-in.md index 2a743f9dc6982779298802ff108d40fd27f0c5c6..70c27a3f371bb5214c842cece220807addaed08b 100644 --- a/en/device-dev/subsystems/plug-in.md +++ b/en/device-dev/subsystems/plug-in.md @@ -117,6 +117,8 @@ Algorithm plug-in APIs including **Prepare**, **SyncProcess**, **AsyncProcess +For the data structure of **ConfigInfo**, **ClientInfo**, **AlgorithmInfo**, and **DataInfo**, see [Table 2](sdk.md#table22154317482) in the SDK development guidelines. + The **Request** and **Response** classes define the requests and responses used for communication between the AI engine server and algorithm plug-ins. A request encapsulates the request content and input data of the caller. The plug-in returns the calculation result to the AI engine server through a response. [Table 3](#table16273647125120) describes the attributes of the **Request** class. diff --git a/en/device-dev/subsystems/sdk.md b/en/device-dev/subsystems/sdk.md index 5cc0b855635d383e046ae6c117a8d28428406da3..119cbc1e84f7f4c04e58f682a535759ddff30b6f 100644 --- a/en/device-dev/subsystems/sdk.md +++ b/en/device-dev/subsystems/sdk.md @@ -126,8 +126,6 @@ The function of the SDK header file is implemented by mapping SDK API calls to c

long long clientVersion: Indicates client version number. This parameter is not used currently.

int clientId: Indicates the client ID.

int sessionId: Indicates the session ID.

-

uid_t serverUid: Indicates the server UID.

-

uid_t clientUid: Indicates the client UID.

int extendLen: Indicates the length of the extended information (extendMsg).

unsigned char *extendMsg: Indicates the body of the extended information.

diff --git a/en/device-dev/subsystems/security.md b/en/device-dev/subsystems/security.md index e69ec0072cf44c6314e688ce37d3a25bbe8df412..adc524ff7a08f0600470efb08bee7a096364f240 100644 --- a/en/device-dev/subsystems/security.md +++ b/en/device-dev/subsystems/security.md @@ -1,6 +1,6 @@ # Security -- **[Overview](overview-9.md)** +- **[Overview](overview-5.md)** - **[Development Guidelines on Application Signature Verification](development-guidelines-on-application-signature-verification.md)** @@ -8,6 +8,4 @@ - **[Development Guidelines on IPC Authentication](development-guidelines-on-ipc-authentication.md)** -- **[Development Guidelines on Trusted Device Group Management](development-guidelines-on-trusted-device-group-management.md)** - diff --git a/en/device-dev/subsystems/startup-10.md b/en/device-dev/subsystems/startup-6.md similarity index 100% rename from en/device-dev/subsystems/startup-10.md rename to en/device-dev/subsystems/startup-6.md diff --git a/en/device-dev/subsystems/startup.md b/en/device-dev/subsystems/startup.md index 5a2025350a8b09b4a2afd74af17e2dc4894efa53..7f8f4f3e5e9b0dfcc87ea25c5cdd6378c04e8d1a 100644 --- a/en/device-dev/subsystems/startup.md +++ b/en/device-dev/subsystems/startup.md @@ -1,6 +1,6 @@ # Startup -- **[Startup](startup-10.md)** +- **[Startup](startup-6.md)** - **[init Module](init-module.md)** diff --git a/en/device-dev/subsystems/xts.md b/en/device-dev/subsystems/xts.md index 24396f880e05a6ed78dfcb41c8a78660ad469317..c4957d70f0ebf8fb52cf3a662ba9f75eecb5d834 100644 --- a/en/device-dev/subsystems/xts.md +++ b/en/device-dev/subsystems/xts.md @@ -456,6 +456,7 @@ The HCPPTest framework is enhanced and adapted based on the open-source framewor ] cflags = [ "-Wno-error" ] } + ``` 4. Add build options to the **BUILD.gn** file in the **acts** directory. diff --git a/en/readme.md b/en/readme.md index 6f5507767fb638dc4a82b16d8c40da15bc4bf0af..ef5b8c15a2391147b29899652fc8eea697efe8a6 100644 --- a/en/readme.md +++ b/en/readme.md @@ -1,77 +1,81 @@ -# WELCOME TO OPENHARMONY +# Overview + This project stores OpenHarmony documentation, including the quick start guide, development guides, and API reference. We appreciate your contribution to the OpenHarmony documentation. -## Motivation -Traditional OSs are limited to a specific type of device, while OpenHarmony provides distributed features that are compatible with a wide range of different devices. The first version supports devices with 128 KB to 128 MB of memory. Join us as we keep updating OpenHarmony versions. -For device developers, OpenHarmony utilizes a component-based design to tailor its features to better suit specific devices, based on each device's capabilities and service characteristics. OpenHarmony can run on devices with limited resources and wearables with hundreds of KB of memory, as well as more powerful devices, such as smart home cameras and dashcams with hundreds of MB of memory. - -[中文版本](../zh-cn/readme.md) - -## Device Development - Documentation Directory Structure -- [Overview](device-dev/quick-start/overview.md) -- [Getting Started](device-dev/quick-start/Readme-EN.md) -- [Source Code Acquisition/Tool Acquisition](device-dev/get-code/Readme-EN.md) -- [Kernel Usage Guidelines](device-dev/kernel/Readme-EN.md) -- [Driver Usage Guidelines](device-dev/driver/Readme-EN.md) -- [Subsystem Development Guidelines](device-dev/subsystems/Readme-EN.md) - - [Compilation and Building](device-dev/subsystems/compilation-and-building.md) - - [Distributed Remote Startup](device-dev/subsystems/distributed-remote-startup.md) - - [Graphics](device-dev/subsystems/graphics.md) - - [Multimedia](device-dev/subsystems/multimedia.md) - - [Utils](device-dev/subsystems/utils.md) - - [AI Framework](device-dev/subsystems/ai-framework.md) - - [Sensors](device-dev/subsystems/sensors.md) - - [Application Framework](device-dev/subsystems/application-framework.md) - - [OTA Upgrade](device-dev/subsystems/ota-upgrade.md) - - [Security](device-dev/subsystems/security.md) - - [Startup](device-dev/subsystems/startup.md) - - [Testing](device-dev/subsystems/testing.md) - - [DFX](device-dev/subsystems/dfx.md) - - [R&D Tools](device-dev/subsystems/r-d-tools.md) - - [X Test Suite](device-dev/subsystems/xts.md) -- [Bundle Development Guidelines](device-dev/bundles/Readme-EN.md) -- [Third-Party Library Porting Guide](device-dev/porting/Readme-EN.md) -- [Device Development Guidelines](device-dev/guide/Readme-EN.md) - - [WLAN-connected Products](device-dev/guide/wlan-connected-products.md) - - [Cameras Without a Screen](device-dev/guide/cameras-without-a-screen.md) - - [Cameras with a Screen](device-dev/guide/cameras-with-a-screen.md) - - [Visual Application Development](device-dev/guide/visual-application-development.md) - - [Development Example for Clock Apps](device-dev/guide/development-example-for-clock-apps.md) - - [Development Example for Platform Drivers](device-dev/guide/development-example-for-platform-drivers.md) - - [Development Example for Peripheral Drivers](device-dev/guide/development-example-for-peripheral-drivers.md) -- [Privacy and Security](device-dev/security/Readme-EN.md) -- [Glossary](device-dev/glossary/glossary.md) - -# Application Development - Documentation Directory Structure - -- [Getting Started](application-dev/quick-start/getting-started.md) -- [UI](application-dev/ui/Readme-EN.md) -- [Media](application-dev/media/Readme-EN.md) -- [Connectivity](application-dev/connectivity/Readme-EN.md) -- [JS Reference](application-dev/js-reference/Readme-EN.md) - -## Start Contributing - -OpenHarmony is an open-source community and encourages everyone in the community to submit patches directly to the project. You can contribute either to the code or documentation. -- [Contributing to the Code](contribute/contributing-code.md) -- [Contributing to the Documentation](contribute/documentation-contribution.md) - -For more details on how to contribute, see [Contributing Documents](contribute). -## Get Source Code and Tools -To download the source code and tools required for the project, click the following links: -- [Source Code Acquisition](device-dev/get-code/source-code-acquisition.md) -- [Tool Acquisition](device-dev/get-code/tool-acquisition.md) - -## Where to Turn for Help -You can subscribe to the mailing list to get constant updates on new features, released road maps, and community activities. For how to subscribe to the mailing list or get any other support, see [Communication in Community](https://gitee.com/openharmony/docs/tree/master/contribute/communication-in-community.md). - -## Code of Conduct -OpenHarmony is committed to providing a welcoming and inspiring community for all. In order to maintain a collaborative environment, we recommend you read and follow the community [Code of Conduct](https://gitee.com/openharmony/docs/blob/master/contribute/code-of-conduct.md). - -## Contributors & Acknowledgements -A great open-source project wouldn't be possible without the hard work of many contributors. We'd like to invite anyone from around the world to participate in this exciting journey, and we're grateful for your time, passion, and efforts! - -## Release -In order to provide new features and bug fixes, the community constantly updates code and provides new releases. - -See [OpenHarmony Release Notes](release-notes/OpenHarmony-Release-Notes.md). \ No newline at end of file +## Contents + +- [OpenHarmony Overview](OpenHarmony-Overview.md) +- Mini and Small System Development Guidelines \(Reference Memory < 128 MB\) + - Device development + - **overview**: [device development overview](device-dev/overview.md) + - **quick-start**: [quick start guide](device-dev/quick-start/Readme-EN.md) \(covering environment setup, source code acquisition, build, and burning\) + - Basic development capabilities + - **Kernel**: [lite kernel](device-dev/kernel/kernel-for-mini-and-small-systems.md) + - **Drivers**: [drivers](device-dev/driver/Readme-EN.md) + - **Subsystems**: [subsystems](device-dev/subsystems/Readme-EN.md) \(such as compilation and building, graphics, DFX, and XTS\) + - **Security**: [privacy and security](device-dev/security/Readme-EN.md) + + - **guide**: [guidelines](device-dev/guide/Readme-EN.md) + - [WLAN-connected products](device-dev/guide/wlan-connected-products.md) \(LED peripheral control and third-party SDK integration\) + - [Screenless cameras](device-dev/guide/cameras-without-a-screen.md) \(camera control\) + - [Cameras with a screen](device-dev/guide/cameras-with-a-screen.md) \(screen and camera control, visual application development\) + + - **porting**: [porting adaptation](device-dev/porting/Readme-EN.md) + - [Third-Party SoC Porting Guide](device-dev/porting/third-party-soc-porting-guide.md) + - [Third-Party Library Porting Guide](device-dev/porting/third-party-library-porting-guide.md) + + - **bundles**: [bundle development](device-dev/bundles/Readme-EN.md) + - [Development Specifications](device-dev/bundles/development-specifications.md) + - [Development Guidelines](device-dev/bundles/development-guidelines.md) + - [HPM User Guide](device-dev/bundles/hpm-user-guide.md) + +- Standard System Development Guidelines \(Reference Memory ≥ 128 MB\) + - Device development + - **overview**: [device development overview](device-dev/overview.md) + - **quick-start**: [quick start guide](device-dev/quick-start/Readme-EN.md) \(covering environment setup, source code acquisition, build, and burning\) + - Basic development capabilities + - **Kernel**: [Linux kernel](device-dev/kernel/Readme-EN.md) + - **Drivers**: [drivers](device-dev/driver/Readme-EN.md) + - **Subsystems**: [subsystems](device-dev/subsystems/Readme-EN.md) \(such as compilation and building, graphics, DFX, and XTS\) + - **Security**: [privacy and security](device-dev/security/Readme-EN.md) + + - **guide**: [guidelines](device-dev/guide/Readme-EN.md) + - [Clock apps](device-dev/guide/development-example-for-clock-apps.md) + - [Platform drivers](device-dev/guide/development-example-for-platform-drivers.md) + - [Peripheral drivers](device-dev/guide/development-example-for-peripheral-drivers.md) + + - **porting**: [porting adaptation](device-dev/porting/Readme-EN.md) + - [Third-Party SoC Porting Guide](device-dev/porting/third-party-soc-porting-guide.md) + - [Third-Party Library Porting Guide](device-dev/porting/third-party-library-porting-guide.md) + + - **bundles**: [bundle development](device-dev/bundles/Readme-EN.md) + - [Development Specifications](device-dev/bundles/development-specifications.md) + - [Development Guidelines](device-dev/bundles/development-guidelines.md) + - [HPM User Guide](device-dev/bundles/hpm-user-guide.md) + + +- App development + - **Overview**: [app development overview](application-dev/application-dev-guide.md) + - **quick-start**: [quick start guide](application-dev/quick-start/Readme-EN.md) + - **ui**: [UI](application-dev/ui/Readme-EN.md) + - **media**: [media](application-dev/media/Readme-EN.md) + - **connectivity**: [networks and connectivity](application-dev/connectivity/Readme-EN.md) + - **js-reference**: [JS reference](application-dev/js-reference/Readme-EN.md) +- **glossary**: [glossary](device-dev/glossary/glossary.md) + +## Version Change History + +For details, see [Release Notes](release-notes/OpenHarmony-Release-Notes.md). + +## Third-Party Open-Source Software and License Notice + +None. + +## How to Contribute + +A great open-source project wouldn't be possible without the hard work of many contributors. We'd like to invite anyone from around the world to [participate](contribute/contribution.md) in this exciting journey, and we're grateful for your time, passion, and efforts! + +You can evaluate available documents, make simple modifications, provide feedback on document quality, and contribute your original content. For details, see [Documentation Contribution](contribute/documentation-contribution.md). + +Excellent contributors will be awarded and the contributions will be publicized in the developer community. + diff --git a/zh-cn/device-dev/driver/GPIO.md b/zh-cn/device-dev/driver/GPIO.md index afffef57ab689bd2220b0cc24b3323089b0e2d52..a5ce55f5d682843ec65e9c5247d2efc832053855 100755 --- a/zh-cn/device-dev/driver/GPIO.md +++ b/zh-cn/device-dev/driver/GPIO.md @@ -1,9 +1,560 @@ -# GPIO +# GPIO -- **[GPIO概述](GPIO概述.md)** +- [概述](#section1635911016188) + - [接口说明](#section17715915181611) -- **[GPIO使用指导](GPIO使用指导.md)** +- [使用指导](#section259614242196) + - [使用流程](#section103477714216) + - [确定GPIO管脚号](#section370083272117) + - [使用API操作GPIO管脚](#section13604050132118) -- **[GPIO使用实例](GPIO使用实例.md)** +- [使用实例](#section25941262111) +## 概述 + +GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。 + +GPIO接口定义了操作GPIO管脚的标准方法集合,包括: + +- 设置管脚方向: 方向可以是输入或者输出\(暂不支持高阻态\) + +- 读写管脚电平值: 电平值可以是低电平或高电平 +- 设置管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式 +- 使能和禁止管脚中断:禁止或使能管脚中断 + +### 接口说明 + +**表 1** GPIO驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

GPIO读写

+

GpioRead

+

读管脚电平值

+

GpioWrite

+

写管脚电平值

+

GPIO配置

+

GpioSetDir

+

设置管脚方向

+

GpioGetDir

+

获取管脚方向

+

GPIO中断设置

+

GpioSetIrq

+

设置管脚对应的中断服务函数

+

GpioUnSetIrq

+

取消管脚对应的中断服务函数

+

GpioEnableIrq

+

使能管脚中断

+

GpioDisableIrq

+

禁止管脚中断

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如[图1](#fig1399416053717)所示。 + +**图 1** GPIO使用流程图 + + +![](figures/zh-cn_image_0000001170187071.png) + +### 确定GPIO管脚号 + +不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。 + +- Hi3516DV300 + + 控制器管理12组GPIO管脚,每组8个。 + + GPIO号 = GPIO组索引 \(0\~11\) \* 每组GPIO管脚数\(8\) + 组内偏移 + + 举例:GPIO10\_3的GPIO号 = 10 \* 8 + 3 = 83 + +- Hi3518EV300 + + 控制器管理10组GPIO管脚,每组10个。 + + GPIO号 = GPIO组索引 \(0\~9\) \* 每组GPIO管脚数\(10\) + 组内偏移 + + 举例:GPIO7\_3的GPIO管脚号 = 7 \* 10 + 3 = 73 + + +### 使用API操作GPIO管脚 + +- 设置GPIO管脚方向 + + 在进行GPIO管脚读写前,需要先通过如下函数设置GPIO管脚方向: + + int32\_t GpioSetDir\(uint16\_t gpio, uint16\_t dir\); + + **表 2** GpioSetDir参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

待设置的GPIO管脚号

+

dir

+

待设置的方向值

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ + +- 读写GPIO管脚 + + 如果要读取一个GPIO管脚电平,通过以下函数完成: + + int32\_t GpioRead\(uint16\_t gpio, uint16\_t \*val\); + + **表 3** GpioRead参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

待读取的GPIO管脚号

+

val

+

接收读取电平值的指针

+

返回值

+

返回值描述

+

0

+

读取成功

+

负数

+

读取失败

+
+ + 如果要向GPIO管脚写入电平值,通过以下函数完成: + + int32\_t GpioWrite\(uint16\_t gpio, uint16\_t val\); + + **表 4** GpioWrite参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

待写入的GPIO管脚号

+

val

+

待写入的电平值

+

返回值

+

返回值描述

+

0

+

写入成功

+

负数

+

写入失败

+
+ + 示例代码: + + ``` + int32_t ret; + uint16_t val; + /* 将3号GPIO管脚配置为输出 */ + ret = GpioSetDir(3, GPIO_DIR_OUT); + if (ret != 0) { + HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); + return; + } + /* 向3号GPIO管脚写入低电平GPIO_VAL_LOW */ + ret = GpioWrite(3, GPIO_VAL_LOW); + if (ret != 0) { + HDF_LOGE("GpioWrite: failed, ret %d\n", ret); + return; + } + /* 将6号GPIO管脚配置为输入 */ + ret = GpioSetDir(6, GPIO_DIR_IN); + if (ret != 0) { + HDF_LOGE("GpioSetDir: failed, ret %d\n", ret); + return; + } + /* 读取6号GPIO管脚的电平值 */ + ret = GpioRead(6, &val); + ``` + + +- 设置GPIO中断 + + 如果要为一个GPIO管脚设置中断响应程序,使用如下函数: + + int32\_t GpioSetIrq\(uint16\_t gpio, uint16\_t mode, GpioIrqFunc func, void \*arg\); + + **表 5** GpioSetIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

mode

+

中断触发模式

+

func

+

中断服务程序

+

arg

+

传递给中断服务程序的入参

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ + >![](public_sys-resources/icon-caution.gif) **注意:** + >同一时间,只能为某个GPIO管脚设置一个中断服务函数,如果重复调用GpioSetIrq函数,则之前设置的中断服务函数会被取代。 + + 当不再需要响应中断服务函数时,使用如下函数取消中断设置: + + int32\_t GpioUnSetIrq\(uint16\_t gpio\); + + **表 6** GpioUnSetIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

返回值

+

返回值描述

+

0

+

取消成功

+

负数

+

取消失败

+
+ + 在中断服务程序设置完成后,还需要先通过如下函数使能GPIO管脚的中断: + + int32\_t GpioEnableIrq\(uint16\_t gpio\); + + **表 7** GpioEnableIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

返回值

+

返回值描述

+

0

+

使能成功

+

负数

+

使能失败

+
+ + >![](public_sys-resources/icon-caution.gif) **注意:** + >必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。 + + 如果要临时屏蔽此中断,可以通过如下函数禁止GPIO管脚中断: + + int32\_t GpioDisableIrq\(uint16\_t gpio\); + + **表 8** GpioDisableIrq参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

gpio

+

GPIO管脚号

+

返回值

+

返回值描述

+

0

+

禁止成功

+

负数

+

禁止失败

+
+ + 示例代码: + + ``` + /* 中断服务函数 + */ + int32_t MyCallBackFunc(uint16_t gpio, void *data) + { + HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); + return 0; + } + + int32_t ret; + /* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */ + ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); + if (ret != 0) { + HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); + return; + } + + /* 使能3号GPIO管脚中断 */ + ret = GpioEnableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); + return; + } + + /* 禁止3号GPIO管脚中断 */ + ret = GpioDisableIrq(3); + if (ret != 0) { + HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); + return; + } + + /* 取消3号GPIO管脚中断服务程序 */ + ret = GpioUnSetIrq(3); + if (ret != 0) { + HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); + return; + } + ``` + + +## 使用实例 + +本实例程序中,我们将测试一个GPIO管脚的中断触发:为管脚设置中断服务函数,触发方式为边沿触发,然后通过交替写高低电平到管脚,产生电平波动,制造触发条件,观察中断服务函数的执行。 + +首先需要选取一个空闲的GPIO管脚,本例程基于Hi3516DV300某开发板,GPIO管脚选择GPIO10\_3,换算成GPIO号为83。 + +读者可以根据自己使用的开发板,参考其原理图,选择一个空闲的GPIO管脚即可。 + +``` +#include "gpio_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +static uint32_t g_irqCnt; + +/* 中断服务函数*/ +static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) +{ + HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); + g_irqCnt++; /* 如果中断服务函数触发执行,则将全局中断计数加1 */ + return GpioDisableIrq(gpio); +} + +/* 测试用例函数 */ +static int32_t TestCaseGpioIrqEdge(void) +{ + int32_t ret; + uint16_t valRead; + uint16_t mode; + uint16_t gpio = 83; /* 待测试的GPIO管脚号 */ + uint32_t timeout; + + /* 将管脚方向设置为输出 */ + ret = GpioSetDir(gpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret); + return ret; + } + + /* 先禁止该管脚中断 */ + ret = GpioDisableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* 为管脚设置中断服务函数,触发模式为上升沿和下降沿共同触发 */ + mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING; + HDF_LOGE("%s: mode:%0x\n", __func__, mode); + ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret); + return ret; + } + + /* 使能此管脚中断 */ + ret = GpioEnableIrq(gpio); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret); + (void)GpioUnSetIrq(gpio); + return ret; + } + + g_irqCnt = 0; /* 清除全局计数器 */ + timeout = 0; /* 等待时间清零 */ + /* 等待此管脚中断服务函数触发,等待超时时间为1000毫秒 */ + while (g_irqCnt <= 0 && timeout < 1000) { + (void)GpioRead(gpio, &valRead); + (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); + HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout); + OsalMDelay(200); /* wait for irq trigger */ + timeout += 200; + } + (void)GpioUnSetIrq(gpio); + return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; +} +``` diff --git "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 86231b7af28d913333f5ee3c7440ce6c7551d4a7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,79 +0,0 @@ -# GPIO使用实例 - -本实例程序中,我们将测试一个GPIO管脚的中断触发:为管脚设置中断服务函数,触发方式为边沿触发,然后通过交替写高低电平到管脚,产生电平波动,制造触发条件,观察中断服务函数的执行。 - -首先需要选取一个空闲的GPIO管脚,本例程基于Hi3516DV300某开发板,GPIO管脚选择GPIO10\_3,换算成GPIO号为83。 - -读者可以根据自己使用的开发板,参考其原理图,选择一个空闲的GPIO管脚即可。 - -``` -#include "gpio_if.h" -#include "hdf_log.h" -#include "osal_irq.h" -#include "osal_time.h" - -static uint32_t g_irqCnt; - -/* 中断服务函数*/ -static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) -{ - HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); - g_irqCnt++; /* 如果中断服务函数触发执行,则将全局中断计数加1 */ - return GpioDisableIrq(gpio); -} - -/* 测试用例函数 */ -static int32_t TestCaseGpioIrqEdge(void) -{ - int32_t ret; - uint16_t valRead; - uint16_t mode; - uint16_t gpio = 83; /* 待测试的GPIO管脚号 */ - uint32_t timeout; - - /* 将管脚方向设置为输出 */ - ret = GpioSetDir(gpio, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret); - return ret; - } - - /* 先禁止该管脚中断 */ - ret = GpioDisableIrq(gpio); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret); - return ret; - } - - /* 为管脚设置中断服务函数,触发模式为上升沿和下降沿共同触发 */ - mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING; - HDF_LOGE("%s: mode:%0x\n", __func__, mode); - ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret); - return ret; - } - - /* 使能此管脚中断 */ - ret = GpioEnableIrq(gpio); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret); - (void)GpioUnSetIrq(gpio); - return ret; - } - - g_irqCnt = 0; /* 清除全局计数器 */ - timeout = 0; /* 等待时间清零 */ - /* 等待此管脚中断服务函数触发,等待超时时间为1000毫秒 */ - while (g_irqCnt <= 0 && timeout < 1000) { - (void)GpioRead(gpio, &valRead); - (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); - HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout); - OsalMDelay(200); /* wait for irq trigger */ - timeout += 200; - } - (void)GpioUnSetIrq(gpio); - return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; -} -``` - diff --git "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 1bc136ee21147a7eca55b507cd96dfa8ab5fe583..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/GPIO\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,395 +0,0 @@ -# GPIO使用指导 - -- [使用流程](#section1583613406410) -- [确定GPIO管脚号](#section135943361443) -- [使用API操作GPIO管脚](#section69151114115315) - -## 使用流程 - -GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如[图1](#fig1399416053717)所示。 - -**图 1** GPIO使用流程图 - - -![](figures/zh-cn_image_0000001057342245.png) - -## 确定GPIO管脚号 - -不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。 - -- Hi3516DV300 - - 控制器管理12组GPIO管脚,每组8个。 - - GPIO号 = GPIO组索引 \(0\~11\) \* 每组GPIO管脚数\(8\) + 组内偏移 - - 举例:GPIO10\_3的GPIO号 = 10 \* 8 + 3 = 83 - -- Hi3518EV300 - - 控制器管理10组GPIO管脚,每组10个。 - - GPIO号 = GPIO组索引 \(0\~9\) \* 每组GPIO管脚数\(10\) + 组内偏移 - - 举例:GPIO7\_3的GPIO管脚号 = 7 \* 10 + 3 = 73 - - -## 使用API操作GPIO管脚 - -- 设置GPIO管脚方向 - - 在进行GPIO管脚读写前,需要先通过如下函数设置GPIO管脚方向: - - int32\_t GpioSetDir\(uint16\_t gpio, uint16\_t dir\); - - **表 1** GpioSetDir参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

待设置的GPIO管脚号

-

dir

-

待设置的方向值

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- -- 读写GPIO管脚 - - 如果要读取一个GPIO管脚电平,通过以下函数完成: - - int32\_t GpioRead\(uint16\_t gpio, uint16\_t \*val\); - - **表 2** GpioRead参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

待读取的GPIO管脚号

-

val

-

接收读取电平值的指针

-

返回值

-

返回值描述

-

0

-

读取成功

-

负数

-

读取失败

-
- - 如果要向GPIO管脚写入电平值,通过以下函数完成: - - int32\_t GpioWrite\(uint16\_t gpio, uint16\_t val\); - - **表 3** GpioWrite参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

待写入的GPIO管脚号

-

val

-

待写入的电平值

-

返回值

-

返回值描述

-

0

-

写入成功

-

负数

-

写入失败

-
- - 示例代码: - - ``` - int32_t ret; - uint16_t val; - /* 将3号GPIO管脚配置为输出 */ - ret = GpioSetDir(3, GPIO_DIR_OUT); - if (ret != 0) { - HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); - return; - } - /* 向3号GPIO管脚写入低电平GPIO_VAL_LOW */ - ret = GpioWrite(3, GPIO_VAL_LOW); - if (ret != 0) { - HDF_LOGE("GpioWrite: failed, ret %d\n", ret); - return; - } - /* 将6号GPIO管脚配置为输入 */ - ret = GpioSetDir(6, GPIO_DIR_IN); - if (ret != 0) { - HDF_LOGE("GpioSetDir: failed, ret %d\n", ret); - return; - } - /* 读取6号GPIO管脚的电平值 */ - ret = GpioRead(6, &val); - ``` - - -- 设置GPIO中断 - - 如果要为一个GPIO管脚设置中断响应程序,使用如下函数: - - int32\_t GpioSetIrq\(uint16\_t gpio, uint16\_t mode, GpioIrqFunc func, void \*arg\); - - **表 4** GpioSetIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

mode

-

中断触发模式

-

func

-

中断服务程序

-

arg

-

传递给中断服务程序的入参

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- - >![](public_sys-resources/icon-caution.gif) **注意:** - >同一时间,只能为某个GPIO管脚设置一个中断服务函数,如果重复调用GpioSetIrq函数,则之前设置的中断服务函数会被取代。 - - 当不再需要响应中断服务函数时,使用如下函数取消中断设置: - - int32\_t GpioUnSetIrq\(uint16\_t gpio\); - - **表 5** GpioUnSetIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

返回值

-

返回值描述

-

0

-

取消成功

-

负数

-

取消失败

-
- - 在中断服务程序设置完成后,还需要先通过如下函数使能GPIO管脚的中断: - - int32\_t GpioEnableIrq\(uint16\_t gpio\); - - **表 6** GpioEnableIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

返回值

-

返回值描述

-

0

-

使能成功

-

负数

-

使能失败

-
- - >![](public_sys-resources/icon-caution.gif) **注意:** - >必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。 - - 如果要临时屏蔽此中断,可以通过如下函数禁止GPIO管脚中断: - - int32\_t GpioDisableIrq\(uint16\_t gpio\); - - **表 7** GpioDisableIrq参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

gpio

-

GPIO管脚号

-

返回值

-

返回值描述

-

0

-

禁止成功

-

负数

-

禁止失败

-
- - 示例代码: - - ``` - /* 中断服务函数 - */ - int32_t MyCallBackFunc(uint16_t gpio, void *data) - { - HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); - return 0; - } - - int32_t ret; - /* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */ - ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); - if (ret != 0) { - HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); - return; - } - - /* 使能3号GPIO管脚中断 */ - ret = GpioEnableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); - return; - } - - /* 禁止3号GPIO管脚中断 */ - ret = GpioDisableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); - return; - } - - /* 取消3号GPIO管脚中断服务程序 */ - ret = GpioUnSetIrq(3); - if (ret != 0) { - HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); - return; - } - ``` - - diff --git "a/zh-cn/device-dev/driver/GPIO\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/GPIO\346\246\202\350\277\260.md" deleted file mode 100755 index 1c4bcfc9c060718e31a5dd7bf267513fdb3afb0d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/GPIO\346\246\202\350\277\260.md" +++ /dev/null @@ -1,82 +0,0 @@ -# GPIO概述 - -- [简介](#section15318165672215) -- [接口说明](#section18977142162418) - -## 简介 - -GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。 - -GPIO接口定义了操作GPIO管脚的标准方法集合,包括: - -- 设置管脚方向: 方向可以是输入或者输出\(暂不支持高阻态\) - -- 读写管脚电平值: 电平值可以是低电平或高电平 -- 设置管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式 -- 使能和禁止管脚中断:禁止或使能管脚中断 - -## 接口说明 - -**表 1** GPIO驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

GPIO读写

-

GpioRead

-

读管脚电平值

-

GpioWrite

-

写管脚电平值

-

GPIO配置

-

GpioSetDir

-

设置管脚方向

-

GpioGetDir

-

获取管脚方向

-

GPIO中断设置

-

GpioSetIrq

-

设置管脚对应的中断服务函数

-

GpioUnSetIrq

-

取消管脚对应的中断服务函数

-

GpioEnableIrq

-

使能管脚中断

-

GpioDisableIrq

-

禁止管脚中断

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/I2C.md b/zh-cn/device-dev/driver/I2C.md index 5bc8c5bf3ce065ab72f19260fe0ab8ca622c0cd8..6655c1e6f2ed116957963dc823c336c2a3df7f32 100755 --- a/zh-cn/device-dev/driver/I2C.md +++ b/zh-cn/device-dev/driver/I2C.md @@ -1,9 +1,426 @@ -# I2C +# I2C -- **[I2C概述](I2C概述.md)** +- [概述](#section5361140416) + - [接口说明](#section459052019177) -- **[I2C使用指导](I2C使用指导.md)** +- [使用指导](#section1695201514281) + - [使用流程](#section1338373417288) + - [打开I2C控制器](#section13751110132914) + - [进行I2C通信](#section9202183372916) + - [关闭I2C控制器](#section19481164133018) -- **[I2C使用实例](I2C使用实例.md)** +- [使用实例](#section5302202015300) +## 概述 + +- I2C\(Inter Integrated Circuit\)总线是由Philips公司开发的一种简单、双向二线制同步串行总线。 +- I2C以主从方式工作,通常有一个主设备和一个或者多个从设备,主从设备通过SDA\(SerialData\)串行数据线以及SCL\(SerialClock\)串行时钟线两根线相连,如[图1 ](#fig1135561232714)所示。 + +- I2C数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。数据传输以字节为单位,高位在前,逐个bit进行传输。 +- I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址,当主设备需要和某一个从设备通信时,通过广播的方式,将从设备地址写到总线上,如果某个从设备符合此地址,将会发出应答信号,建立传输。 + +- I2C接口定义了完成I2C传输的通用方法集合,包括: + + - I2C控制器管理: 打开或关闭I2C控制器 + - I2C消息传输:通过消息传输结构体数组进行自定义传输 + + **图 1** I2C物理连线示意图 + ![](figures/I2C物理连线示意图.png "I2C物理连线示意图") + + +### 接口说明 + +**表 1** I2C驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

I2C控制器管理接口

+

I2cOpen

+

打开I2C控制器

+

I2cClose

+

关闭I2C控制器

+

I2c消息传输接口

+

I2cTransfer

+

自定义传输

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用I2C设备的一般流程如[图2](#fig166181128151112)所示。 + +**图 2** I2C设备使用流程图 + + +![](figures/zh-cn_image_0000001123509750.png) + +### 打开I2C控制器 + +在进行I2C通信前,首先要调用I2cOpen打开I2C控制器。 + +DevHandle I2cOpen\(int16\_t number\); + +**表 2** I2cOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

number

+

I2C控制器号

+

返回值

+

返回值描述

+

NULL

+

打开I2C控制器失败

+

设备句柄

+

打开的I2C控制器设备句柄

+
+ +假设系统中存在8个I2C控制器,编号从0到7,那么我们现在获取3号控制器 + +``` +DevHandle i2cHandle = NULL; /* I2C控制器句柄 / + +/* 打开I2C控制器 */ +i2cHandle = I2cOpen(3); +if (i2cHandle == NULL) { + HDF_LOGE("I2cOpen: failed\n"); + return; +} +``` + +### 进行I2C通信 + +消息传输 + +int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\); + +**表 3** I2cTransfer参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2C控制器设备句柄

+

msgs

+

待传输数据的消息结构体数组

+

count

+

消息数组长度

+

返回值

+

返回值描述

+

正整数

+

成功传输的消息结构体数目

+

负数

+

执行失败

+
+ +I2C传输消息类型为I2cMsg,每个传输消息结构体表示一次读或写,通过一个消息数组,可以执行若干次的读写组合操作。 + +``` +int32_t ret; +uint8_t wbuff[2] = { 0x12, 0x13 }; +uint8_t rbuff[2] = { 0 }; +struct I2cMsg msgs[2]; /* 自定义传输的消息结构体数组 */ +msgs[0].buf = wbuff; /* 写入的数据 */ +msgs[0].len = 2; /* 写入数据长度为2 */ +msgs[0].addr = 0x5A; /* 写入设备地址为0x5A */ +msgs[0].flags = 0; /* 传输标记为0,默认为写 */ +msgs[1].buf = rbuff; /* 要读取的数据 */ +msgs[1].len = 2; /* 读取数据长度为2 */ +msgs[1].addr = 0x5A; /* 读取设备地址为0x5A */ +msgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ置位 */ +/* 进行一次自定义传输,传输的消息个数为2 */ +ret = I2cTransfer(i2cHandle, msgs, 2); +if (ret != 2) { + HDF_LOGE("I2cTransfer: failed, ret %d\n", ret); + return; +} +``` + +>![](public_sys-resources/icon-caution.gif) **注意:** +>- I2cMsg结构体中的设备地址不包含读写标志位,读写信息由flags成员变量的读写控制位传递。 +>- 本函数不对消息结构体个数count做限制,其最大个数度由具体I2C控制器决定。 +>- 本函数也不对每个消息结构体中的数据长度做限制,同样由具体I2C控制器决定。 +>- 本函数可能会引起系统休眠,不允许在中断上下文调用 + +### 关闭I2C控制器 + +I2C通信完成之后,需要关闭I2C控制器,关闭函数如下所示: + +void I2cClose\(DevHandle handle\); + +**表 4** I2cClose参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2C控制器设备句柄

+
+ +``` +I2cClose(i2cHandle); /* 关闭I2C控制器 */ +``` + +## 使用实例 + +本例程以操作开发板上的I2C设备为例,详细展示I2C接口的完整使用流程。 + +本例拟对Hi3516DV300某开发板上TouchPad设备进行简单的寄存器读写访问,基本硬件信息如下: + +- SOC:hi3516dv300。 + +- Touch IC:I2C地址为0x38, IC内部寄存器位宽为1字节。 + +- 原理图信息:TouchPad设备挂接在3号I2C控制器下;IC的复位管脚为3号GPIO。 + +本例程首先对Touch IC进行复位操作(开发板上电默认会给TouchIC供电,本例程不考虑供电),然后对其内部寄存器进行随机读写,测试I2C通路是否正常。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>本例程重点在于展示I2C设备访问流程,并验证I2C通路,所以对于设备寄存器读写值不做关注,读写寄存器导致的行为由设备自身决定。 + +示例如下: + +``` +#include "i2c_if.h" /* I2C标准接口头文件 */ +#include "gpio_if.h" /* GPIO标准接口头文件 */ +#include "hdf_log.h" /* 标准日志打印头文件 */ +#include "osal_io.h" /* 标准IO读写接口头文件 */ +#include "osal_time.h" /* 标准延迟&睡眠接口头文件 */ + +/* 定义一个表示TP设备的结构体,存储i2c及gpio相关硬件信息 */ +struct TpI2cDevice { + uint16_t rstGpio; /* 复位管脚 */ + uint16_t busId; /* I2C总线号 */ + uint16_t addr; /* I2C设备地址 */ + uint16_t regLen; /* 寄存器字节宽度 */ + DevHandle i2cHandle; /* I2C控制器句柄 */ +}; + +/* I2C管脚io配置,需要查阅SOC寄存器手册 */ +#define I2C3_DATA_REG_ADDR 0x112f008c /* 3号I2C控制器SDA管脚配置寄存器地址 */ +#define I2C3_CLK_REG_ADDR 0x112f0090 /* 3号I2C控制器SCL管脚配置寄存器地址 */ +#define I2C_REG_CFG 0x5f1 /* 3号I2C控制器SDA及SCL管脚配置值 */ + +static void TpSocIoCfg(void) +{ + /* 将3号I2C控制器对应两个管脚的IO功能设置为I2C */ + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR)); + OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR)); +} + +/* 对TP的复位管脚进行初始化, 拉高维持20ms, 再拉底维持50ms,最后再拉高维持20ms, 完成复位动作 */ +static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice) +{ + int32_t ret; + + /* 设置复位管脚方向为输出 */ + ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret); + return ret; + } + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst low fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(50); + + ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set rst high fail!:%d", __func__, ret); + return ret; + } + OsalMSleep(20); + + return HDF_SUCCESS; +} + +/* 基于I2cTransfer方法封装一个寄存器读写的辅助函数, 通过flag表示读或写 */ +static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen, uint8_t flag) +{ + int index = 0; + unsigned char regBuf[4] = {0}; + struct I2cMsg msgs[2] = {0}; + + /* 单双字节寄存器长度适配 */ + if (tpDevice->regLen == 1) { + regBuf[index++] = regAddr & 0xFF; + } else { + regBuf[index++] = (regAddr >> 8) & 0xFF; + regBuf[index++] = regAddr & 0xFF; + } + + /* 填充I2cMsg消息结构 */ + msgs[0].addr = tpDevice->addr; + msgs[0].flags = 0; /* 标记为0,表示写入 */ + msgs[0].len = tpDevice->regLen; + msgs[0].buf = regBuf; + + msgs[1].addr = tpDevice->addr; + msgs[1].flags = (flag == 1) ? I2C_FLAG_READ : 0; /* 添加读标记位,表示读取 */ + msgs[1].len = dataLen; + msgs[1].buf = regData; + + if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) { + HDF_LOGE("%s: i2c read err", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +/* TP寄存器读函数 */ +static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1); +} + +/* TP寄存器写函数 */ +static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, + unsigned char *regData, unsigned int dataLen) +{ + return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0); +} + +/* I2C例程总入口 */ +static int32_t TestCaseI2c(void) +{ + int32_t i; + int32_t ret; + unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC }; + unsigned char bufRead[7] = {0}; + static struct TpI2cDevice tpDevice; + + /* IO管脚功能配置 */ + TpSocIoCfg(); + + /* TP设备信息初始化 */ + tpDevice.rstGpio = 3; + tpDevice.busId = 3; + tpDevice.addr = 0x38; + tpDevice.regLen = 1; + tpDevice.i2cHandle = NULL; + + /* GPIO管脚初始化 */ + ret = TestCaseGpioInit(&tpDevice); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: gpio init fail!:%d", __func__, ret); + return ret; + } + + /* 打开I2C控制器 */ + tpDevice.i2cHandle = I2cOpen(tpDevice.busId); + if (tpDevice.i2cHandle == NULL) { + HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId); + return -1; + } + + /* 向TP-IC的0xD5寄存器连续写7字节数据 */ + ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + OsalMSleep(10); + + /* 从TP-IC的0xDO寄存器连续读7字节数据 */ + ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); + I2cClose(tpDevice.i2cHandle); + return -1; + } + + HDF_LOGE("%s: tp i2c write&read reg success!", __func__); + for (i = 0; i < 7; i++) { + HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]); + } + + /* 访问完毕关闭I2C控制器 */ + I2cClose(tpDevice.i2cHandle); + return ret; +} +``` diff --git "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index a75da59b1b8b225230df1091d4335afbd8240b1d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,192 +0,0 @@ -# I2C使用实例 - -本例程以操作开发板上的I2C设备为例,详细展示I2C接口的完整使用流程。 - -本例拟对Hi3516DV300某开发板上TouchPad设备进行简单的寄存器读写访问,基本硬件信息如下: - -- SOC:hi3516dv300。 - -- Touch IC:I2C地址为0x38, IC内部寄存器位宽为1字节。 - -- 原理图信息:TouchPad设备挂接在3号I2C控制器下;IC的复位管脚为3号GPIO。 - -本例程首先对Touch IC进行复位操作(开发板上电默认会给TouchIC供电,本例程不考虑供电),然后对其内部寄存器进行随机读写,测试I2C通路是否正常。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->本例程重点在于展示I2C设备访问流程,并验证I2C通路,所以对于设备寄存器读写值不做关注,读写寄存器导致的行为由设备自身决定。 - -示例如下: - -``` -#include "i2c_if.h" /* I2C标准接口头文件 */ -#include "gpio_if.h" /* GPIO标准接口头文件 */ -#include "hdf_log.h" /* 标准日志打印头文件 */ -#include "osal_io.h" /* 标准IO读写接口头文件 */ -#include "osal_time.h" /* 标准延迟&睡眠接口头文件 */ - -/* 定义一个表示TP设备的结构体,存储i2c及gpio相关硬件信息 */ -struct TpI2cDevice { - uint16_t rstGpio; /* 复位管脚 */ - uint16_t busId; /* I2C总线号 */ - uint16_t addr; /* I2C设备地址 */ - uint16_t regLen; /* 寄存器字节宽度 */ - DevHandle i2cHandle; /* I2C控制器句柄 */ -}; - -/* I2C管脚io配置,需要查阅SOC寄存器手册 */ -#define I2C3_DATA_REG_ADDR 0x112f008c /* 3号I2C控制器SDA管脚配置寄存器地址 */ -#define I2C3_CLK_REG_ADDR 0x112f0090 /* 3号I2C控制器SCL管脚配置寄存器地址 */ -#define I2C_REG_CFG 0x5f1 /* 3号I2C控制器SDA及SCL管脚配置值 */ - -static void TpSocIoCfg(void) -{ - /* 将3号I2C控制器对应两个管脚的IO功能设置为I2C */ - OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR)); - OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR)); -} - -/* 对TP的复位管脚进行初始化, 拉高维持20ms, 再拉底维持50ms,最后再拉高维持20ms, 完成复位动作 */ -static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice) -{ - int32_t ret; - - /* 设置复位管脚方向为输出 */ - ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret); - return ret; - } - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(20); - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst low fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(50); - - ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set rst high fail!:%d", __func__, ret); - return ret; - } - OsalMSleep(20); - - return HDF_SUCCESS; -} - -/* 基于I2cTransfer方法封装一个寄存器读写的辅助函数, 通过flag表示读或写 */ -static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen, uint8_t flag) -{ - int index = 0; - unsigned char regBuf[4] = {0}; - struct I2cMsg msgs[2] = {0}; - - /* 单双字节寄存器长度适配 */ - if (tpDevice->regLen == 1) { - regBuf[index++] = regAddr & 0xFF; - } else { - regBuf[index++] = (regAddr >> 8) & 0xFF; - regBuf[index++] = regAddr & 0xFF; - } - - /* 填充I2cMsg消息结构 */ - msgs[0].addr = tpDevice->addr; - msgs[0].flags = 0; /* 标记为0,表示写入 */ - msgs[0].len = tpDevice->regLen; - msgs[0].buf = regBuf; - - msgs[1].addr = tpDevice->addr; - msgs[1].flags = (flag == 1) ? I2C_FLAG_READ : 0; /* 添加读标记位,表示读取 */ - msgs[1].len = dataLen; - msgs[1].buf = regData; - - if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) { - HDF_LOGE("%s: i2c read err", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -/* TP寄存器读函数 */ -static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen) -{ - return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1); -} - -/* TP寄存器写函数 */ -static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr, - unsigned char *regData, unsigned int dataLen) -{ - return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0); -} - -/* I2C例程总入口 */ -static int32_t TestCaseI2c(void) -{ - int32_t i; - int32_t ret; - unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC }; - unsigned char bufRead[7] = {0}; - static struct TpI2cDevice tpDevice; - - /* IO管脚功能配置 */ - TpSocIoCfg(); - - /* TP设备信息初始化 */ - tpDevice.rstGpio = 3; - tpDevice.busId = 3; - tpDevice.addr = 0x38; - tpDevice.regLen = 1; - tpDevice.i2cHandle = NULL; - - /* GPIO管脚初始化 */ - ret = TestCaseGpioInit(&tpDevice); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: gpio init fail!:%d", __func__, ret); - return ret; - } - - /* 打开I2C控制器 */ - tpDevice.i2cHandle = I2cOpen(tpDevice.busId); - if (tpDevice.i2cHandle == NULL) { - HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId); - return -1; - } - - /* 向TP-IC的0xD5寄存器连续写7字节数据 */ - ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret); - I2cClose(tpDevice.i2cHandle); - return -1; - } - OsalMSleep(10); - - /* 从TP-IC的0xDO寄存器连续读7字节数据 */ - ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); - I2cClose(tpDevice.i2cHandle); - return -1; - } - - HDF_LOGE("%s: tp i2c write&read reg success!", __func__); - for (i = 0; i < 7; i++) { - HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]); - } - - /* 访问完毕关闭I2C控制器 */ - I2cClose(tpDevice.i2cHandle); - return ret; -} -``` - diff --git "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 38341ca1d40f1c2572078f2f449e8a37065a9281..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/I2C\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,171 +0,0 @@ -# I2C使用指导 - -- [使用流程](#section333203315215) -- [打开I2C控制器](#section123631358135713) -- [进行I2C通信](#section11091522125812) -- [关闭I2C控制器](#section13519505589) - -## 使用流程 - -使用I2C设备的一般流程如[图1](#fig166181128151112)所示。 - -**图 1** I2C设备使用流程图 - - -![](figures/zh-cn_image_0000001057902344.png) - -## 打开I2C控制器 - -在进行I2C通信前,首先要调用I2cOpen打开I2C控制器。 - -DevHandle I2cOpen\(int16\_t number\); - -**表 1** I2cOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

number

-

I2C控制器号

-

返回值

-

返回值描述

-

NULL

-

打开I2C控制器失败

-

设备句柄

-

打开的I2C控制器设备句柄

-
- -假设系统中存在8个I2C控制器,编号从0到7,那么我们现在获取3号控制器 - -``` -DevHandle i2cHandle = NULL; /* I2C控制器句柄 / - -/* 打开I2C控制器 */ -i2cHandle = I2cOpen(3); -if (i2cHandle == NULL) { - HDF_LOGE("I2cOpen: failed\n"); - return; -} -``` - -## 进行I2C通信 - -消息传输 - -int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\); - -**表 2** I2cTransfer参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

I2C控制器设备句柄

-

msgs

-

待传输数据的消息结构体数组

-

count

-

消息数组长度

-

返回值

-

返回值描述

-

正整数

-

成功传输的消息结构体数目

-

负数

-

执行失败

-
- -I2C传输消息类型为I2cMsg,每个传输消息结构体表示一次读或写,通过一个消息数组,可以执行若干次的读写组合操作。 - -``` -int32_t ret; -uint8_t wbuff[2] = { 0x12, 0x13 }; -uint8_t rbuff[2] = { 0 }; -struct I2cMsg msgs[2]; /* 自定义传输的消息结构体数组 */ -msgs[0].buf = wbuff; /* 写入的数据 */ -msgs[0].len = 2; /* 写入数据长度为2 */ -msgs[0].addr = 0x5A; /* 写入设备地址为0x5A */ -msgs[0].flags = 0; /* 传输标记为0,默认为写 */ -msgs[1].buf = rbuff; /* 要读取的数据 */ -msgs[1].len = 2; /* 读取数据长度为2 */ -msgs[1].addr = 0x5A; /* 读取设备地址为0x5A */ -msgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ置位 */ -/* 进行一次自定义传输,传输的消息个数为2 */ -ret = I2cTransfer(i2cHandle, msgs, 2); -if (ret != 2) { - HDF_LOGE("I2cTransfer: failed, ret %d\n", ret); - return; -} -``` - ->![](public_sys-resources/icon-caution.gif) **注意:** ->- I2cMsg结构体中的设备地址不包含读写标志位,读写信息由flags成员变量的读写控制位传递。 ->- 本函数不对消息结构体个数count做限制,其最大个数度由具体I2C控制器决定。 ->- 本函数也不对每个消息结构体中的数据长度做限制,同样由具体I2C控制器决定。 ->- 本函数可能会引起系统休眠,不允许在中断上下文调用 - -## 关闭I2C控制器 - -I2C通信完成之后,需要关闭2C控制器,关闭函数如下所示: - -void I2cClose\(DevHandle handle\); - -**表 3** I2cClose参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

I2C控制器设备句柄

-
- -``` -I2cClose(i2cHandle); /* 关闭I2C控制器 */ -``` - diff --git "a/zh-cn/device-dev/driver/I2C\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/I2C\346\246\202\350\277\260.md" deleted file mode 100755 index 7961b58a8284049766dc470b862e377d79f1c696..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/I2C\346\246\202\350\277\260.md" +++ /dev/null @@ -1,60 +0,0 @@ -# I2C概述 - -- [简介](#section5361140416) -- [接口说明](#section7606310210) - -## 简介 - -- I2C\(Inter Integrated Circuit\)总线是由Philips公司开发的一种简单、双向二线制同步串行总线。 -- I2C以主从方式工作,通常有一个主设备和一个或者多个从设备,主从设备通过SDA\(SerialData\)串行数据线以及SCL\(SerialClock\)串行时钟线两根线相连,如[图1 ](#fig1135561232714)所示。 - -- I2C数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。数据传输以字节为单位,高位在前,逐个bit进行传输。 -- I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址,当主设备需要和某一个从设备通信时,通过广播的方式,将从设备地址写到总线上,如果某个从设备符合此地址,将会发出应答信号,建立传输。 - -- I2C接口定义了完成I2C传输的通用方法集合,包括: - - - I2C控制器管理: 打开或关闭I2C控制器 - - I2C消息传输:通过消息传输结构体数组进行自定义传输 - - **图 1** I2C物理连线示意图 - ![](figures/I2C物理连线示意图.png "I2C物理连线示意图") - - -## 接口说明 - -**表 1** I2C驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

I2C控制器管理接口

-

I2cOpen

-

打开I2C控制器

-

I2cClose

-

关闭I2C控制器

-

I2c消息传输接口

-

I2cTransfer

-

自定义传输

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/LCD.md b/zh-cn/device-dev/driver/LCD.md index b6352ca83310a7c0f1d6af1d09f47a8450e626db..97075a5a0d8fa5fcf2245525e99754210a575652 100755 --- a/zh-cn/device-dev/driver/LCD.md +++ b/zh-cn/device-dev/driver/LCD.md @@ -1,9 +1,363 @@ -# LCD +# LCD -- **[LCD开发概述](LCD开发概述.md)** +- [概述](#section141575391542) + - [接口说明](#section14711163785519) -- **[LCD开发指导](LCD开发指导.md)** +- [开发指导](#section12394223125615) + - [开发步骤](#section515923045814) -- **[LCD开发实例](LCD开发实例.md)** +- [开发实例](#section7441155155813) +## 概述 + +LCD(Liquid Crystal Display)液晶显示驱动,对LCD进行上电,并通过接口初始化LCD内部寄存器,使LCD正常工作。Display驱动模型基于HDF( Hardware Driver Foundation)[驱动框架](HDF开发概述.md)开发,实现跨OS、跨平台,为LCD硬件提供上下电功能、发送初始化序列功能,使LCD进入正常的工作模式,显示芯片平台侧的图像数据,基于HDF驱动框架的Display驱动模型如[图1](#fig69138814229)。 + +**图 1** 基于HDF驱动框架的Display驱动模型 +![](figures/基于HDF驱动框架的Display驱动模型.png "基于HDF驱动框架的Display驱动模型") + +- **Display驱动模型介绍** + + Display驱动模型主要由平台驱动层、芯片平台适配层、LCD器件驱动层三部分组成。驱动模型基于HDF驱动框架开发,通过Platform层和OSAL层提供的接口,屏蔽内核形态的差异,使得器件驱动可以便利的迁移到不同OS及芯片平台。模型向上对接Display公共hal层,支撑HDI接口的实现,通过Display-HDI(Hardware Display Interface)对图形服务提供各类驱动能力接口。 + + (1)Display平台驱动层:通过HDF提供的IOService数据通道,与公共Hal层对接,集中接收并处理各类上层调用指令; + + (2)SOC平台驱动适配层:借助此SOC适配层,实现Display驱动和SOC侧驱动解耦,主要完成芯片平台相关的参数配置,并传递平台驱动层的调用到器件驱动层; + + (3)LCD器件驱动层:在器件驱动层中,主要实现和器件自身强相关的驱动适配接口,例如发送初始化序列、上下电、背光设置等。 + + 基于Display驱动模型开发LCD驱动,可以借助平台提供的各种能力及接口,较大程度的降低器件驱动的开发周期和难度,提升开发效率。 + + +### 接口说明 + +LCD接口通常可分为MIPI DSI接口、TTL接口和LVDS接口,常用的是MIPI DSI接口和TTL接口,下面对常用的MIPI DSI接口和TTL接口作简要介绍。 + +- MIPI DSI接口 + + **图 2** MIPI DSI接口 + ![](figures/MIPI-DSI接口.png "MIPI-DSI接口") + + MIPI DSI接口是MIPI(移动行业处理器接口)联盟定义的显示接口,主要用于移动终端显示屏接口,接口数据传输遵循MIPI协议,MIPI DSI接口为数据接口,传输图像数据,通常情况下MIPI DSI接口的控制信息以MIPI包形式通过MIPI DSI接口发送到对端IC,不需要额外的外设接口。 + +- TTL接口 + + **图 3** TTL接口 + ![](figures/TTL接口.png "TTL接口") + + TTL(Transistor Transistor Logic)即晶体管-晶体管逻辑,TTL电平信号由TTL器件产生,TTL器件是数字集成电路的一大门类,它采用双极型工艺制造,具有高速度、低功耗和品种多等特点。 + + TTL接口是并行方式传输数据的接口,有数据信号、时钟信号和控制信号(行同步、帧同步、数据有效信号等),在控制信号控制下完成数据传输。通常TTL接口的LCD,内部寄存器读写需要额外的外设接口,比如SPI接口、I2C接口等。 + + +## 开发指导 + +Display驱动模型基于HDF驱动框架、Platform接口及OSAL接口开发,可以做到不区分OS(LiteOS、Linux)和芯片平台(Hi35xx、Hi38xx、V3S等),为LCD器件提供统一的驱动模型。 + +### 开发步骤 + +1. 添加LCD驱动相关的设备描述配置。 +2. 在SOC平台驱动适配层中适配对应的芯片平台驱动。 +3. 添加器件驱动,并在驱动入口函数Init中注册Panel驱动数据,驱动数据接口主要包括如下接口: + - LCD上下电 + + 根据LCD硬件连接,使用Platform接口层提供的GPIO操作接口操作对应LCD管脚,例如复位管脚、IOVCC管脚,上电时序参考LCD供应商提供的SPEC。 + + - 发送初始化序列 + + 根据LCD硬件接口,使用Platform接口层提供的I2C、SPI、MIPI等接口,下载LCD初始化序列,初始化参数序列可以参考LCD供应商提供的SPEC。 + + +4. 根据需求实现HDF框架其他接口,比如Release接口。 +5. 根据需求使用HDF框架可创建其他设备节点,用于业务逻辑或者调试功能。 + +## 开发实例 + +添加设备描述配置: + +``` +/* Display驱动相关的设备描述配置 */ +display :: host { + hostName = "display_host"; + /* Display平台驱动设备描述 */ + device_hdf_disp :: device { + device0 :: deviceNode { + policy = 2; + priority = 200; + permission = 0660; + moduleName = "HDF_DISP"; + serviceName = "hdf_disp"; + } + } + /* SOC适配层驱动设备描述 */ + device_hi35xx_disp :: device { + device0 :: deviceNode { + policy = 0; + priority = 199; + moduleName = "HI351XX_DISP"; + } + } + /* LCD器件驱动设备描述 */ + device_lcd :: device { + device0 :: deviceNode { + policy = 0; + priority = 100; + preload = 0; + moduleName = "LCD_Sample"; + } + device1 :: deviceNode { + policy = 0; + priority = 100; + preload = 2; + moduleName = "LCD_SampleXX"; + } + } +} +``` + +SOC适配层驱动,以Hi35xx系列芯片为例,需要在本层驱动中适配MIPI等和芯片平台相关的配置,示例如下: + +``` +static int32_t MipiDsiInit(struct PanelInfo *info) +{ + int32_t ret; + struct DevHandle *mipiHandle = NULL; + struct MipiCfg cfg; + + mipiHandle = MipiDsiOpen(0); + if (mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + cfg.lane = info->mipi.lane; + cfg.mode = info->mipi.mode; + cfg.format = info->mipi.format; + cfg.burstMode = info->mipi.burstMode; + cfg.timing.xPixels = info->width; + cfg.timing.hsaPixels = info->hsw; + cfg.timing.hbpPixels = info->hbp; + cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; + cfg.timing.vsaLines = info->vsw; + cfg.timing.vbpLines = info->vbp; + cfg.timing.vfpLines = info->vfp; + cfg.timing.ylines = info->height; + /* 0 : no care */ + cfg.timing.edpiCmdSize = 0; + cfg.pixelClk = CalcPixelClk(info); + cfg.phyDataRate = CalcDataRate(info); + /* config mipi device */ + ret = MipiDsiSetCfg(mipiHandle, &cfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); + } + MipiDsiClose(mipiHandle); + HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, + cfg.pixelClk, cfg.phyDataRate); + return ret; +} +``` + +LCD器件驱动示例如下: + +``` +#define RESET_GPIO 5 +#define MIPI_DSI0 0 +#define BLK_PWM1 1 +#define PWM_MAX_PERIOD 100000 +/* backlight setting */ +#define MIN_LEVEL 0 +#define MAX_LEVEL 255 +#define DEFAULT_LEVEL 100 + +#define WIDTH 480 +#define HEIGHT 960 +#define HORIZONTAL_BACK_PORCH 20 +#define HORIZONTAL_FRONT_PORCH 20 +#define HORIZONTAL_SYNC_WIDTH 10 +#define VERTIACL_BACK_PORCH 14 +#define VERTIACL_FRONT_PORCH 16 +#define VERTIACL_SYNC_WIDTH 2 +#define FRAME_RATE 60 + +/* Panel Info结构体结构体 */ +struct PanelInfo { + uint32_t width; + uint32_t height; + uint32_t hbp; + uint32_t hfp; + uint32_t hsw; + uint32_t vbp; + uint32_t vfp; + uint32_t vsw; + uint32_t frameRate; + enum LcdIntfType intfType; + enum IntfSync intfSync; + struct MipiDsiDesc mipi; + struct BlkDesc blk; + struct PwmCfg pwm; +}; + +/* LCD屏的初始化序列 */ +static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; +static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; +static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; +static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; +static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; +static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; +static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; +static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; +static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; +static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; +static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; +static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; +static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; +static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; +static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; +static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; +static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; +static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; +static uint8_t g_payLoad18[] = { + 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, + 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, + 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 +}; +static uint8_t g_payLoad19[] = { 0x11 }; +static uint8_t g_payLoad20[] = { 0x29 }; + +struct DsiCmdDesc g_OnCmd[] = { + { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, + { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, + { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, + { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, + { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, + { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, + { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, + { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, + { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, + { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, + { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, + { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, + { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, + { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, + { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, + { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, + { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, + { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, + { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, + { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, + { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, +}; +static DevHandle g_mipiHandle = NULL; +static DevHandle g_pwmHandle = NULL; + +/* 设置Reset Pin脚状态 */ +static int32_t LcdResetOn(void) +{ + int32_t ret; + ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioSetDir failure, ret:%d", ret); + return HDF_FAILURE; + } + ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); + if (ret != HDF_SUCCESS) { + HDF_LOGE("GpioWrite failure, ret:%d", ret); + return HDF_FAILURE; + } + /* delay 20ms */ + OsalMSleep(20); + return HDF_SUCCESS; +} + +static int32_t SampleInit(void) +{ + /* 获取MIPI DSI设备操作句柄 */ + g_mipiHandle = MipiDsiOpen(MIPI_DSI0); + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: MipiDsiOpen failure", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t SampleOn(void) +{ + int32_t ret; + /* LCD上电序列 */ + ret = LcdResetOn(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: LcdResetOn failure", __func__); + return HDF_FAILURE; + } + if (g_mipiHandle == NULL) { + HDF_LOGE("%s: g_mipiHandle is null", __func__); + return HDF_FAILURE; + } + /* 使用mipi下发初始化序列 */ + int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); + int32_t i; + for (i = 0; i < count; i++) { + ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); + if (ret != HDF_SUCCESS) { + HDF_LOGE("MipiDsiTx failure"); + return HDF_FAILURE; + } + } + /* 将mipi切换到HS模式 */ + MipiDsiSetHsMode(g_mipiHandle); + return HDF_SUCCESS; +} + +/* PanelInfo结构体变量 */ +static struct PanelInfo g_panelInfo = { + .width = WIDTH, /* width */ + .height = HEIGHT, /* height */ + .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ + .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ + .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ + .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ + .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ + .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ + .frameRate = FRAME_RATE, /* frame rate */ + .intfType = MIPI_DSI, /* panel interface type */ + .intfSync = OUTPUT_USER, /* output timming type */ + /* mipi config info */ + .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, + /* backlight config info */ + .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, + .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, +}; + +/* 器件驱动需要适配的基础接口 */ +static struct PanelData g_panelData = { + .info = &g_panelInfo, + .init = SampleInit, + .on = SampleOn, + .off = SampleOff, + .setBacklight = SampleSetBacklight, +}; + +/* 器件驱动入口函数 */ +int32_t SampleEntryInit(struct HdfDeviceObject *object) +{ + HDF_LOGI("%s: enter", __func__); + if (object == NULL) { + HDF_LOGE("%s: param is null!", __func__); + return HDF_FAILURE; + } + /* 器件驱动接口注册,ops提供给平台驱动调用 */ + if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { + HDF_LOGE("%s: PanelDataRegister error!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +struct HdfDriverEntry g_sampleDevEntry = { + .moduleVersion = 1, + .moduleName = "LCD_SAMPLE", + .Init = SampleEntryInit, +}; + +HDF_INIT(g_sampleDevEntry); +``` diff --git "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index 6de19704008c9850cec3a9f79baeddeef0c24401..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,291 +0,0 @@ -# LCD开发实例 - -添加设备描述配置: - -``` -/* Display驱动相关的设备描述配置 */ -display :: host { - hostName = "display_host"; - /* Display平台驱动设备描述 */ - device_hdf_disp :: device { - device0 :: deviceNode { - policy = 2; - priority = 200; - permission = 0660; - moduleName = "HDF_DISP"; - serviceName = "hdf_disp"; - } - } - /* SOC适配层驱动设备描述 */ - device_hi35xx_disp :: device { - device0 :: deviceNode { - policy = 0; - priority = 199; - moduleName = "HI351XX_DISP"; - } - } - /* LCD器件驱动设备描述 */ - device_lcd :: device { - device0 :: deviceNode { - policy = 0; - priority = 100; - preload = 0; - moduleName = "LCD_Sample"; - } - device1 :: deviceNode { - policy = 0; - priority = 100; - preload = 2; - moduleName = "LCD_SampleXX"; - } - } -} -``` - -SOC适配层驱动,以Hi35xx系列芯片为例,需要在本层驱动中适配MIPI等和芯片平台相关的配置,示例如下: - -``` -static int32_t MipiDsiInit(struct PanelInfo *info) -{ - int32_t ret; - struct DevHandle *mipiHandle = NULL; - struct MipiCfg cfg; - - mipiHandle = MipiDsiOpen(0); - if (mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - cfg.lane = info->mipi.lane; - cfg.mode = info->mipi.mode; - cfg.format = info->mipi.format; - cfg.burstMode = info->mipi.burstMode; - cfg.timing.xPixels = info->width; - cfg.timing.hsaPixels = info->hsw; - cfg.timing.hbpPixels = info->hbp; - cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw; - cfg.timing.vsaLines = info->vsw; - cfg.timing.vbpLines = info->vbp; - cfg.timing.vfpLines = info->vfp; - cfg.timing.ylines = info->height; - /* 0 : no care */ - cfg.timing.edpiCmdSize = 0; - cfg.pixelClk = CalcPixelClk(info); - cfg.phyDataRate = CalcDataRate(info); - /* config mipi device */ - ret = MipiDsiSetCfg(mipiHandle, &cfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:MipiDsiSetCfg failure", __func__); - } - MipiDsiClose(mipiHandle); - HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, - cfg.pixelClk, cfg.phyDataRate); - return ret; -} -``` - -LCD器件驱动示例如下: - -``` -#define RESET_GPIO 5 -#define MIPI_DSI0 0 -#define BLK_PWM1 1 -#define PWM_MAX_PERIOD 100000 -/* backlight setting */ -#define MIN_LEVEL 0 -#define MAX_LEVEL 255 -#define DEFAULT_LEVEL 100 - -#define WIDTH 480 -#define HEIGHT 960 -#define HORIZONTAL_BACK_PORCH 20 -#define HORIZONTAL_FRONT_PORCH 20 -#define HORIZONTAL_SYNC_WIDTH 10 -#define VERTIACL_BACK_PORCH 14 -#define VERTIACL_FRONT_PORCH 16 -#define VERTIACL_SYNC_WIDTH 2 -#define FRAME_RATE 60 - -/* Panel Info结构体结构体 */ -struct PanelInfo { - uint32_t width; - uint32_t height; - uint32_t hbp; - uint32_t hfp; - uint32_t hsw; - uint32_t vbp; - uint32_t vfp; - uint32_t vsw; - uint32_t frameRate; - enum LcdIntfType intfType; - enum IntfSync intfSync; - struct MipiDsiDesc mipi; - struct BlkDesc blk; - struct PwmCfg pwm; -}; - -/* LCD屏的初始化序列 */ -static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; -static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 }; -static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; -static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; -static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; -static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; -static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; -static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; -static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; -static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; -static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; -static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; -static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; -static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; -static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; -static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; -static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; -static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; -static uint8_t g_payLoad18[] = { - 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, - 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, - 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 -}; -static uint8_t g_payLoad19[] = { 0x11 }; -static uint8_t g_payLoad20[] = { 0x29 }; - -struct DsiCmdDesc g_OnCmd[] = { - { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, - { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 }, - { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, - { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 }, - { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, - { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, - { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, - { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 }, - { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 }, - { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 }, - { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 }, - { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 }, - { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 }, - { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 }, - { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 }, - { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 }, - { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 }, - { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 }, - { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 }, - { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 }, - { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 }, -}; -static DevHandle g_mipiHandle = NULL; -static DevHandle g_pwmHandle = NULL; - -/* 设置Reset Pin脚状态 */ -static int32_t LcdResetOn(void) -{ - int32_t ret; - ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioSetDir failure, ret:%d", ret); - return HDF_FAILURE; - } - ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("GpioWrite failure, ret:%d", ret); - return HDF_FAILURE; - } - /* delay 20ms */ - OsalMSleep(20); - return HDF_SUCCESS; -} - -static int32_t SampleInit(void) -{ - /* 获取MIPI DSI设备操作句柄 */ - g_mipiHandle = MipiDsiOpen(MIPI_DSI0); - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: MipiDsiOpen failure", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -static int32_t SampleOn(void) -{ - int32_t ret; - /* LCD上电序列 */ - ret = LcdResetOn(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: LcdResetOn failure", __func__); - return HDF_FAILURE; - } - if (g_mipiHandle == NULL) { - HDF_LOGE("%s: g_mipiHandle is null", __func__); - return HDF_FAILURE; - } - /* 使用mipi下发初始化序列 */ - int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); - int32_t i; - for (i = 0; i < count; i++) { - ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i])); - if (ret != HDF_SUCCESS) { - HDF_LOGE("MipiDsiTx failure"); - return HDF_FAILURE; - } - } - /* 将mipi切换到HS模式 */ - MipiDsiSetHsMode(g_mipiHandle); - return HDF_SUCCESS; -} - -/* PanelInfo结构体变量 */ -static struct PanelInfo g_panelInfo = { - .width = WIDTH, /* width */ - .height = HEIGHT, /* height */ - .hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */ - .hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */ - .hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */ - .vbp = VERTIACL_BACK_PORCH, /* vertiacl back porch */ - .vfp = VERTIACL_FRONT_PORCH, /* vertiacl front porch */ - .vsw = VERTIACL_SYNC_WIDTH, /* vertiacl sync width */ - .frameRate = FRAME_RATE, /* frame rate */ - .intfType = MIPI_DSI, /* panel interface type */ - .intfSync = OUTPUT_USER, /* output timming type */ - /* mipi config info */ - .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT }, - /* backlight config info */ - .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, - .pwm = { BLK_PWM1, PWM_MAX_PERIOD }, -}; - -/* 器件驱动需要适配的基础接口 */ -static struct PanelData g_panelData = { - .info = &g_panelInfo, - .init = SampleInit, - .on = SampleOn, - .off = SampleOff, - .setBacklight = SampleSetBacklight, -}; - -/* 器件驱动入口函数 */ -int32_t SampleEntryInit(struct HdfDeviceObject *object) -{ - HDF_LOGI("%s: enter", __func__); - if (object == NULL) { - HDF_LOGE("%s: param is null!", __func__); - return HDF_FAILURE; - } - /* 器件驱动接口注册,ops提供给平台驱动调用 */ - if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) { - HDF_LOGE("%s: PanelDataRegister error!", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -struct HdfDriverEntry g_sampleDevEntry = { - .moduleVersion = 1, - .moduleName = "LCD_SAMPLE", - .Init = SampleEntryInit, -}; - -HDF_INIT(g_sampleDevEntry); -``` - diff --git "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 12161e4cef9752fb16db59f597560828f5af8085..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,23 +0,0 @@ -# LCD开发指导 - -- [开发步骤](#section3904154911218) - -Display驱动模型基于HDF驱动框架、Platform接口及OSAL接口开发,可以做到不区分OS(LiteOS、Linux)和芯片平台(Hi35xx、Hi38xx、V3S等),为LCD器件提供统一的驱动模型。 - -## 开发步骤 - -1. 添加LCD驱动相关的设备描述配置。 -2. 在SOC平台驱动适配层中适配对应的芯片平台驱动。 -3. 添加器件驱动,并在驱动入口函数Init中注册Panel驱动数据,驱动数据接口主要包括如下接口: - - LCD上下电 - - 根据LCD硬件连接,使用Platform接口层提供的GPIO操作接口操作对应LCD管脚,例如复位管脚、IOVCC管脚,上电时序参考LCD供应商提供的SPEC。 - - - 发送初始化序列 - - 根据LCD硬件接口,使用Platform接口层提供的I2C、SPI、MIPI等接口,下载LCD初始化序列,初始化参数序列可以参考LCD供应商提供的SPEC。 - - -4. 根据需求实现HDF框架其他接口,比如Release接口。 -5. 根据需求使用HDF框架可创建其他设备节点,用于业务逻辑或者调试功能。 - diff --git "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index ab5e824934e96eedd766288dbeb33f93d7b38ab2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/LCD\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,46 +0,0 @@ -# LCD开发概述 - -- [简介](#section3781515122118) -- [接口说明](#section20280192712120) - -## 简介 - -LCD(Liquid Crystal Display)液晶显示驱动,对LCD进行上电,并通过接口初始化LCD内部寄存器,使LCD正常工作。Display驱动模型基于HDF( Hardware Driver Foundation)[驱动框架](HDF开发概述.md)开发,实现跨OS、跨平台,为LCD硬件提供上下电功能、发送初始化序列功能,使LCD进入正常的工作模式,显示芯片平台侧的图像数据,基于HDF驱动框架的Display驱动模型如[图1](#fig69138814229)。 - -**图 1** 基于HDF驱动框架的Display驱动模型 -![](figures/基于HDF驱动框架的Display驱动模型.png "基于HDF驱动框架的Display驱动模型") - -- **Display驱动模型介绍** - - Display驱动模型主要由平台驱动层、芯片平台适配层、LCD器件驱动层三部分组成。驱动模型基于HDF驱动框架开发,通过Platform层和OSAL层提供的接口,屏蔽内核形态的差异,使得器件驱动可以便利的迁移到不同OS及芯片平台。模型向上对接Display公共hal层,支撑HDI接口的实现,通过Display-HDI(Hardware Display Interface)对图形服务提供各类驱动能力接口。 - - (1)Display平台驱动层:通过HDF提供的IOService数据通道,与公共Hal层对接,集中接收并处理各类上层调用指令; - - (2)SOC平台驱动适配层:借助此SOC适配层,实现Display驱动和SOC侧驱动解耦,主要完成芯片平台相关的参数配置,并传递平台驱动层的调用到器件驱动层; - - (3)LCD器件驱动层:在器件驱动层中,主要实现和器件自身强相关的驱动适配接口,例如发送初始化序列、上下电、背光设置等。 - - 基于Display驱动模型开发LCD驱动,可以借助平台提供的各种能力及接口,较大程度的降低器件驱动的开发周期和难度,提升开发效率。 - - -## 接口说明 - -LCD接口通常可分为MIPI DSI接口、TTL接口和LVDS接口,常用的是MIPI DSI接口和TTL接口,下面对常用的MIPI DSI接口和TTL接口作简要介绍。 - -- MIPI DSI接口 - - **图 2** MIPI DSI接口 - ![](figures/MIPI-DSI接口.png "MIPI-DSI接口") - - MIPI DSI接口是MIPI(移动行业处理器接口)联盟定义的显示接口,主要用于移动终端显示屏接口,接口数据传输遵循MIPI协议,MIPI DSI接口为数据接口,传输图像数据,通常情况下MIPI DSI接口的控制信息以MIPI包形式通过MIPI DSI接口发送到对端IC,不需要额外的外设接口。 - -- TTL接口 - - **图 3** TTL接口 - ![](figures/TTL接口.png "TTL接口") - - TTL(Transistor Transistor Logic)即晶体管-晶体管逻辑,TTL电平信号由TTL器件产生,TTL器件是数字集成电路的一大门类,它采用双极型工艺制造,具有高速度、低功耗和品种多等特点。 - - TTL接口是并行方式传输数据的接口,有数据信号、时钟信号和控制信号(行同步、帧同步、数据有效信号等),在控制信号控制下完成数据传输。通常TTL接口的LCD,内部寄存器读写需要额外的外设接口,比如SPI接口、I2C接口等。 - - diff --git a/zh-cn/device-dev/driver/MIPI-DSI.md b/zh-cn/device-dev/driver/MIPI-DSI.md index 2dcbddcdd053fdc85e2b8478b690d79dfe41909d..ae9363290a0c8ea71dbc5b5517602bb826ac1fdc 100755 --- a/zh-cn/device-dev/driver/MIPI-DSI.md +++ b/zh-cn/device-dev/driver/MIPI-DSI.md @@ -1,9 +1,554 @@ -# MIPI DSI +# MIPI DSI -- **[MIPI DSI概述](MIPI-DSI概述.md)** +- [概述](#section16806142183217) + - [接口说明](#section129611916132011) -- **[MIPI DSI使用指导](MIPI-DSI使用指导.md)** +- [使用指导](#section037231715335) + - [使用流程](#section49299119344) + - [获取MIPI-DSI操作句柄](#section5126155683811) + - [MIPI-DSI相应配置](#section201164274344) + - [发送/回读控制指令](#section199401342173415) + - [释放MIPI-DSI操作句柄](#section161011610357) -- **[MIPI DSI使用实例](MIPI-DSI使用实例.md)** +- [使用实例](#section17470126123520) +## 概述 + +- DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface \(MIPI\) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设\(通常是LCD或者类似的显示设备\),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。 + +- MIPI-DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。 +- 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。 + + **图 1** DSI发送、接收接口 + ![](figures/DSI发送-接收接口.png "DSI发送-接收接口") + + +### 接口说明 + +**表 1** MIPI-DSI API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

设置/获取当前MIPI-DSI相关配置

+

MipiDsiSetCfg

+

设置MIPI-DSI相关配置

+

MipiDsiGetCfg

+

获取当前MIPI-DSI相关配置

+

获取/释放MIPI-DSI操作句柄

+

MipiDsiOpen

+

获取MIPI-DSI操作句柄

+

MipiDsiClose

+

释放MIPI-DSI操作句柄

+

设置MIPI-DSI进入Low power模式/High speed模式

+

MipiDsiSetLpMode

+

设置MIPI-DSI进入Low power模式

+

MipiDsiSetHsMode

+

设置MIPI-DSI进入High speed模式

+

MIPI-DSI发送/回读指令

+

MipiDsiTx

+

MIPI-DSI发送相应指令的接口

+

MipiDsiRx

+

MIPI-DSI按期望长度回读的接口

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用 + +## 使用指导 + +### 使用流程 + +使用MIPI-DSI的一般流程如[图2](#fig99821771782)所示。 + +**图 2** MIPI-DSI使用流程图 + + +![](figures/zh-cn_image_0000001123514210.png) + +### 获取MIPI-DSI操作句柄 + +在进行MIPI-DSI进行通信前,首先要调用MipiDsiOpen获取操作句柄,该函数会返回指定通道ID的操作句柄。 + +DevHandle MipiDsiOpen\(uint8\_t id\); + +**表 2** MipiDsiOpen的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

id

+

MIPI DSI通道ID

+

返回值

+

返回值描述

+

NULL

+

获取失败

+

设备句柄

+

获取到指令通道的操作句柄, 类型为DevHandle

+
+ +假设系统中的MIPI-DSI通道为0,获取该通道操作句柄的示例如下: + +``` +DevHandle mipiDsiHandle = NULL; /* 设备句柄 */ +chnId = 0; /* MIPI-DSI通道ID */ + +/* 获取操作句柄 */ +mipiDsiHandle = MipiDsiOpen(chnId); +if (mipiDsiHandle == NULL) { + HDF_LOGE("MipiDsiOpen: failed\n"); + return; +} +``` + +### MIPI-DSI相应配置 + +- 写入MIPI-DSI配置 + +int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\); + +**表 3** MipiDsiSetCfg的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cfg

+

MIPI-DSI相应配置buf 指针

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ +``` +int32_t ret; +struct MipiCfg cfg = {0}; + +/* 当前对接的屏幕配置如下 */ +cfg.lane = DSI_4_LANES; +cfg.mode = DSI_CMD_MODE; +cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; +cfg.format = FORMAT_RGB_24_BIT; +cfg.pixelClk = 174; +cfg.phyDataRate = 384; +cfg.timingInfo.hsaPixels = 50; +cfg.timingInfo.hbpPixels = 55; +cfg.timingInfo.hlinePixels = 1200; +cfg.timingInfo.yResLines = 1800; +cfg.timingInfo.vbpLines = 33; +cfg.timingInfo.vsaLines = 76; +cfg.timingInfo.vfpLines = 120; +cfg.timingInfo.xResPixels = 1342; +/* 写入配置数据 */ +ret = MipiDsiSetCfg(g_handle, &cfg); +if (ret != 0) { + HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); + return -1; +} +``` + +- 获取当前MIPI-DSI的配置 + +int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); + +**表 4** MipiDsiGetCfg的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cfg

+

MIPI-DSI相应配置buf 指针

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +struct MipiCfg cfg; +memset(&cfg, 0, sizeof(struct MipiCfg)); +ret = MipiDsiGetCfg(g_handle, &cfg); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); + return HDF_FAILURE; +} +``` + +### 发送/回读控制指令 + +- 发送指令 + +int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); + +**表 5** MipiDsiTx的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cmd

+

需要发送的指令数据指针

+

返回值

+

返回值描述

+

0

+

发送成功

+

负数

+

发送失败

+
+ +``` +int32_t ret; +struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); +if (cmd == NULL) { + return HDF_FAILURE; +} +cmd->dtype = DTYPE_DCS_WRITE; +cmd->dlen = 1; +cmd->payload = OsalMemCalloc(sizeof(uint8_t)); +if (cmd->payload == NULL) { + HdfFree(cmd); + return HDF_FAILURE; +} +*(cmd->payload) = DTYPE_GEN_LWRITE; +MipiDsiSetLpMode(mipiHandle); +ret = MipiDsiTx(mipiHandle, cmd); +MipiDsiSetHsMode(mipiHandle); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret); + HdfFree(cmd->payload); + HdfFree(cmd); + return HDF_FAILURE; +} +HdfFree(cmd->payload); +HdfFree(cmd); +``` + +- 回读指令 + +int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); + +**表 6** MipiDsiRx的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

操作句柄

+

cmd

+

需要回读的指令数据指针

+

readLen

+

期望回读的数据长度

+

out

+

回读的数据buf指针

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +uint8_t readVal = 0; + +struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); +if (cmdRead == NULL) { + return HDF_FAILURE; +} +cmdRead->dtype = DTYPE_DCS_READ; +cmdRead->dlen = 1; +cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); +if (cmdRead->payload == NULL) { + HdfFree(cmdRead); + return HDF_FAILURE; +} +*(cmdRead->payload) = DDIC_REG_STATUS; +MipiDsiSetLpMode(g_handle); +ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); +MipiDsiSetHsMode(g_handle); +if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + return HDF_FAILURE; +} +HdfFree(cmdRead->payload); +HdfFree(cmdRead); +``` + +### 释放MIPI-DSI操作句柄 + +MIPI-DSI使用完成之后,需要释放操作句柄,释放句柄的函数如下所示: + +void MipiDsiClose\(DevHandle handle\); + +该函数会释放掉由MipiDsiOpen申请的资源。 + +**表 7** MipiDsiClose的参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

MIPI-DSI操作句柄

+
+ +``` +MipiDsiClose(mipiHandle); /* 释放掉MIPI-DSI操作句柄 */ +``` + +## 使用实例 + +MIPI-DSI完整的使用示例如下所示: + +``` +#include "hdf.h" +#include "mipi_dsi_if.h" + +void PalMipiDsiTestSample(void) +{ + uint8_t chnId; + int32_t ret; + DevHandle handle = NULL; + + /* 设备通道编号 */ + chnId = 0; + /* 获取操作句柄 */ + handle = MipiDsiOpen(chnId); + if (handle == NULL) { + HDF_LOGE("MipiDsiOpen: failed!\n"); + return; + } + /* 配置相应参数 */ + struct MipiCfg cfg = {0}; + cfg.lane = DSI_4_LANES; + cfg.mode = DSI_CMD_MODE; + cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; + cfg.format = FORMAT_RGB_24_BIT; + cfg.pixelClk = 174; + cfg.phyDataRate = 384; + cfg.timingInfo.hsaPixels = 50; + cfg.timingInfo.hbpPixels = 55; + cfg.timingInfo.hlinePixels = 1200; + cfg.timingInfo.yResLines = 1800; + cfg.timingInfo.vbpLines = 33; + cfg.timingInfo.vsaLines = 76; + cfg.timingInfo.vfpLines = 120; + cfg.timingInfo.xResPixels = 1342; + /* 写入配置数据 */ + ret = MipiDsiSetCfg(g_handle, &cfg); + if (ret != 0) { + HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); + return; + } + /* 发送PANEL初始化指令 */ + struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmd == NULL) { + return; + } + cmd->dtype = DTYPE_DCS_WRITE; + cmd->dlen = 1; + cmd->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmd->payload == NULL) { + HdfFree(cmd); + return; + } + *(cmd->payload) = DTYPE_GEN_LWRITE; + MipiDsiSetLpMode(mipiHandle); + ret = MipiDsiTx(mipiHandle, cmd); + MipiDsiSetHsMode(mipiHandle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret); + HdfFree(cmd->payload); + HdfFree(cmd); + return; + } + HdfFree(cmd->payload); + HdfFree(cmd); + /* 回读panel状态寄存器 */ + uint8_t readVal = 0; + struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); + if (cmdRead == NULL) { + return; + } + cmdRead->dtype = DTYPE_DCS_READ; + cmdRead->dlen = 1; + cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); + if (cmdRead->payload == NULL) { + HdfFree(cmdRead); + return; + } + *(cmdRead->payload) = DDIC_REG_STATUS; + MipiDsiSetLpMode(g_handle); + ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); + MipiDsiSetHsMode(g_handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + return; + } + HdfFree(cmdRead->payload); + HdfFree(cmdRead); + /* 释放MIPI DSI设备句柄 */ + MipiDsiClose(handle); +} +``` diff --git "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 77e9242f30b175fee1f855d9516d3e407aa2a8fa..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,98 +0,0 @@ -# MIPI DSI使用实例 - -MIPI-DSI完整的使用示例如下所示: - -``` -#include "hdf.h" -#include "mipi_dsi_if.h" - -void PalMipiDsiTestSample(void) -{ - uint8_t chnId; - int32_t ret; - DevHandle handle = NULL; - - /* 设备通道编号 */ - chnId = 0; - /* 获取操作句柄 */ - handle = MipiDsiOpen(chnId); - if (handle == NULL) { - HDF_LOGE("MipiDsiOpen: failed!\n"); - return; - } - /* 配置相应参数 */ - struct MipiCfg cfg = {0}; - cfg.lane = DSI_4_LANES; - cfg.mode = DSI_CMD_MODE; - cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; - cfg.format = FORMAT_RGB_24_BIT; - cfg.pixelClk = 174; - cfg.phyDataRate = 384; - cfg.timingInfo.hsaPixels = 50; - cfg.timingInfo.hbpPixels = 55; - cfg.timingInfo.hlinePixels = 1200; - cfg.timingInfo.yResLines = 1800; - cfg.timingInfo.vbpLines = 33; - cfg.timingInfo.vsaLines = 76; - cfg.timingInfo.vfpLines = 120; - cfg.timingInfo.xResPixels = 1342; - /* 写入配置数据 */ - ret = MipiDsiSetCfg(g_handle, &cfg); - if (ret != 0) { - HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); - return; - } - /* 发送PANEL初始化指令 */ - struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); - if (cmd == NULL) { - return; - } - cmd->dtype = DTYPE_DCS_WRITE; - cmd->dlen = 1; - cmd->payload = OsalMemCalloc(sizeof(uint8_t)); - if (cmd->payload == NULL) { - HdfFree(cmd); - return; - } - *(cmd->payload) = DTYPE_GEN_LWRITE; - MipiDsiSetLpMode(mipiHandle); - ret = MipiDsiTx(mipiHandle, cmd); - MipiDsiSetHsMode(mipiHandle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret); - HdfFree(cmd->payload); - HdfFree(cmd); - return; - } - HdfFree(cmd->payload); - HdfFree(cmd); - /* 回读panel状态寄存器 */ - uint8_t readVal = 0; - struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); - if (cmdRead == NULL) { - return; - } - cmdRead->dtype = DTYPE_DCS_READ; - cmdRead->dlen = 1; - cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); - if (cmdRead->payload == NULL) { - HdfFree(cmdRead); - return; - } - *(cmdRead->payload) = DDIC_REG_STATUS; - MipiDsiSetLpMode(g_handle); - ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); - MipiDsiSetHsMode(g_handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - return; - } - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - /* 释放MIPI DSI设备句柄 */ - MipiDsiClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 58603da99a1536aebce4f61f049e5bc960d0114f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/MIPI-DSI\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,365 +0,0 @@ -# MIPI DSI使用指导 - -- [使用流程](#section8982671284) -- [获取MIPI-DSI操作句柄](#section57982569176) -- [MIPI-DSI相应配置](#section5935410201815) -- [发送/回读控制指令](#section611661316194) -- [释放MIPI-DSI操作句柄](#section217313211199) - -## 使用流程 - -使用MIPI-DSI的一般流程如[图1](#fig99821771782)所示。 - -**图 1** MIPI-DSI使用流程图 - - -![](figures/zh-cn_image_0000001072553354.png) - -## 获取MIPI-DSI操作句柄 - -在进行MIPI-DSI进行通信前,首先要调用MipiDsiOpen获取操作句柄,该函数会返回指定通道ID的操作句柄。 - -DevHandle MipiDsiOpen\(uint8\_t id\); - -**表 1** MipiDsiOpen的参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

id

-

MIPI DSI通道ID

-

返回值

-

返回值描述

-

NULL

-

获取失败

-

设备句柄

-

获取到指令通道的操作句柄, 类型为DevHandle

-
- -假设系统中的MIPI-DSI通道为0,获取该通道操作句柄的示例如下: - -``` -DevHandle mipiDsiHandle = NULL; /* 设备句柄 */ -chnId = 0; /* MIPI-DSI通道ID */ - -/* 获取操作句柄 */ -mipiDsiHandle = MipiDsiOpen(chnId); -if (mipiDsiHandle == NULL) { - HDF_LOGE("MipiDsiOpen: failed\n"); - return; -} -``` - -## MIPI-DSI相应配置 - -- 写入MIPI-DSI配置 - -int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\); - -**表 2** MipiDsiSetCfg的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cfg

-

MIPI-DSI相应配置buf 指针

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- -``` -int32_t ret; -struct MipiCfg cfg = {0}; - -/* 当前对接的屏幕配置如下 */ -cfg.lane = DSI_4_LANES; -cfg.mode = DSI_CMD_MODE; -cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS; -cfg.format = FORMAT_RGB_24_BIT; -cfg.pixelClk = 174; -cfg.phyDataRate = 384; -cfg.timingInfo.hsaPixels = 50; -cfg.timingInfo.hbpPixels = 55; -cfg.timingInfo.hlinePixels = 1200; -cfg.timingInfo.yResLines = 1800; -cfg.timingInfo.vbpLines = 33; -cfg.timingInfo.vsaLines = 76; -cfg.timingInfo.vfpLines = 120; -cfg.timingInfo.xResPixels = 1342; -/* 写入配置数据 */ -ret = MipiDsiSetCfg(g_handle, &cfg); -if (ret != 0) { - HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); - return -1; -} -``` - -- 获取当前MIPI-DSI的配置 - -int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); - -**表 3** MipiDsiGetCfg的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cfg

-

MIPI-DSI相应配置buf 指针

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -struct MipiCfg cfg; -memset(&cfg, 0, sizeof(struct MipiCfg)); -ret = MipiDsiGetCfg(g_handle, &cfg); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); - return HDF_FAILURE; -} -``` - -## 发送/回读控制指令 - -- 发送指令 - -int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); - -**表 4** MipiDsiTx的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cmd

-

需要发送的指令数据指针

-

返回值

-

返回值描述

-

0

-

发送成功

-

负数

-

发送失败

-
- -``` -int32_t ret; -struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); -if (cmd == NULL) { - return HDF_FAILURE; -} -cmd->dtype = DTYPE_DCS_WRITE; -cmd->dlen = 1; -cmd->payload = OsalMemCalloc(sizeof(uint8_t)); -if (cmd->payload == NULL) { - HdfFree(cmd); - return HDF_FAILURE; -} -*(cmd->payload) = DTYPE_GEN_LWRITE; -MipiDsiSetLpMode(mipiHandle); -ret = MipiDsiTx(mipiHandle, cmd); -MipiDsiSetHsMode(mipiHandle); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret); - HdfFree(cmd->payload); - HdfFree(cmd); - return HDF_FAILURE; -} -HdfFree(cmd->payload); -HdfFree(cmd); -``` - -- 回读指令 - -int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); - -**表 5** MipiDsiRx的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

操作句柄

-

cmd

-

需要回读的指令数据指针

-

readLen

-

期望回读的数据长度

-

out

-

回读的数据buf指针

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -uint8_t readVal = 0; - -struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); -if (cmdRead == NULL) { - return HDF_FAILURE; -} -cmdRead->dtype = DTYPE_DCS_READ; -cmdRead->dlen = 1; -cmdRead->payload = OsalMemCalloc(sizeof(uint8_t)); -if (cmdRead->payload == NULL) { - HdfFree(cmdRead); - return HDF_FAILURE; -} -*(cmdRead->payload) = DDIC_REG_STATUS; -MipiDsiSetLpMode(g_handle); -ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); -MipiDsiSetHsMode(g_handle); -if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); - HdfFree(cmdRead->payload); - HdfFree(cmdRead); - return HDF_FAILURE; -} -HdfFree(cmdRead->payload); -HdfFree(cmdRead); -``` - -## 释放MIPI-DSI操作句柄 - -MIPI-DSI使用完成之后,需要释放操作句柄,释放句柄的函数如下所示: - -void MipiDsiClose\(DevHandle handle\); - -该函数会释放掉由MipiDsiOpen申请的资源。 - -**表 6** MipiDsiClose的参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

MIPI-DSI操作句柄

-
- -``` -MipiDsiClose(mipiHandle); /* 释放掉MIPI-DSI操作句柄 */ -``` - diff --git "a/zh-cn/device-dev/driver/MIPI-DSI\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/MIPI-DSI\346\246\202\350\277\260.md" deleted file mode 100755 index 5af73287eb9f6d46a3ec9f7fb5ca2e3d0668ce1b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/MIPI-DSI\346\246\202\350\277\260.md" +++ /dev/null @@ -1,84 +0,0 @@ -# MIPI DSI概述 - -- [简介](#section1369320102013) -- [接口说明](#section6577545192317) - -## 简介 - -- DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface \(MIPI\) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设\(通常是LCD或者类似的显示设备\),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。 - -- MIPI-DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。 - - 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。 - - **图 1** DSI发送、接收接口 - ![](figures/DSI发送-接收接口.png "DSI发送-接收接口") - - - -## 接口说明 - -**表 1** MIPI-DSI API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

设置/获取当前MIPI-DSI相关配置

-

MipiDsiSetCfg

-

设置MIPI-DSI相关配置

-

MipiDsiGetCfg

-

获取当前MIPI-DSI相关配置

-

获取/释放MIPI-DSI操作句柄

-

MipiDsiOpen

-

获取MIPI-DSI操作句柄

-

MipiDsiClose

-

释放MIPI-DSI操作句柄

-

设置MIPI-DSI进入Low power模式/High speed模式

-

MipiDsiSetLpMode

-

设置MIPI-DSI进入Low power模式

-

MipiDsiSetHsMode

-

设置MIPI-DSI进入High speed模式

-

MIPI-DSI发送/回读指令

-

MipiDsiTx

-

MIPI-DSI发送相应指令的接口

-

MipiDsiRx

-

MIPI-DSI按期望长度回读的接口

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用 - diff --git a/zh-cn/device-dev/driver/RTC.md b/zh-cn/device-dev/driver/RTC.md index de745a39f9bbe657f60ac09e4dcfac7bd225b829..ea85e74184425b5c02a9d304d1d87c4875aeaeac 100755 --- a/zh-cn/device-dev/driver/RTC.md +++ b/zh-cn/device-dev/driver/RTC.md @@ -1,9 +1,944 @@ -# RTC +# RTC -- **[RTC概述](RTC概述.md)** +- [概述](#section104842041574) + - [接口说明](#section3373340142215) -- **[RTC使用指导](RTC使用指导.md)** +- [使用指导](#section20636145604113) + - [使用流程](#section16919828134215) + - [创建RTC设备句柄](#section1131212144310) + - [销毁RTC设备句柄](#section10744117144314) + - [注册RTC定时报警回调函数](#section14839440184320) + - [操作RTC](#section161927578433) -- **[RTC使用实例](RTC使用实例.md)** +- [使用实例](#section1186111020456) +## 概述 + +RTC\(real-time clock\)为操作系统中的实时时钟设备,为操作系统提供精准的实时时间和定时报警功能。当设备下电后,通过外置电池供电,RTC继续记录操作系统时间;设备上电后,RTC提供实时时钟给操作系统,确保断电后系统时间的连续性。 + +### 接口说明 + +**表 1** RTC设备API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

RTC句柄操作

+

RtcOpen

+

获取RTC设备驱动句柄

+

RtcClose

+

释放RTC设备驱动句柄

+

RTC时间操作接口

+

RtcReadTime

+

读RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

RtcWriteTime

+

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

RTC报警操作接口

+

RtcReadAlarm

+

读RTC报警时间信息

+

RtcWriteAlarm

+

写RTC报警时间信息

+

RtcRegisterAlarmCallback

+

注册报警超时回调函数

+

RtcAlarmInterruptEnable

+

使能/去使能RTC报警中断

+

RTC配置操作

+

RtcGetFreq

+

读RTC外接晶振频率

+

RtcSetFreq

+

配置RTC外接晶振频率

+

RtcReset

+

RTC复位

+

读写用户定义寄存器

+

RtcReadReg

+

读用户自定义寄存器

+

RtcWriteReg

+

写用户自定义寄存器

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +在操作系统启动过程中,驱动管理模块根据配置文件加载RTC驱动,RTC驱动会检测RTC器件并初始化驱动。 + +使用RTC设备的一般流程如[图1](#fig166181128151112)所示。 + +**图 1** RTC设备使用流程图 + + +![](figures/zh-cn_image_0000001123675706.png) + +### 创建RTC设备句柄 + +RTC驱动加载成功后,驱动开发者使用驱动框架提供的查询接口并调用RTC设备驱动接口。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>当前操作系统支持一个RTC设备。 + +DevHandle RtcOpen\(void\); + +**表 2** RtcOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

void

+

NA

+

返回值

+

返回值描述

+

handle

+

操作成功返回 指针类型

+

NULL

+

操作失败

+
+ +``` +DevHandle handle = NULL; + +/* 获取RTC句柄 */ +handle = RtcOpen(); +if (handle == NULL) { + /* 错误处理 */ +} +``` + +### 销毁RTC设备句柄 + +销毁RTC设备句柄,系统释放对应的资源。 + +void RtcClose\(DevHandle handle\); + +**表 3** RtcClose参数描述 + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+
+ +``` +/* 销毁RTC句柄 */ +RtcClose(handle); +``` + +### 注册RTC定时报警回调函数 + +系统启动后需要注册RTC定时报警回调函数,报警超时后触发回调函数。 + +int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\); + +**表 4** RtcRegisterAlarmCallback参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

cb

+

定时报警回调函数

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +注册RTC\_ALARM\_INDEX\_A的定时报警处理函数, 示例如下: + +``` +/* 用户注册RTC定时报警回调函数的方法 */ +int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) +{ + if (alarmIndex == RTC_ALARM_INDEX_A) { + /* 报警A的处理 */ + } else if (alarmIndex == RTC_ALARM_INDEX_B) { + /* 报警B的处理 */ + } else { + /* 错误处理 */ + } + return 0; +} +int32_t ret; +/* 注册报警A的定时回调函数 */ +ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); +if (ret != 0) { + /* 错误处理 */ +} +``` + +### 操作RTC + +- 读取RTC时间。 + +系统从RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒,则可以通过以下函数完成: + +int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\); + +**表 5** RtcReadTime参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

time

+

RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +struct RtcTime tm; + +/* 系统从RTC读取时间信息 */ +ret = RtcReadTime(handle, &tm); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置RTC时间 + +设置RTC时间,则可以通过以下函数完成: + +int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\); + +**表 6** RtcWriteTime参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

time

+

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 + +``` +int32_t ret; +struct RtcTime tm; + +/* 设置RTC时间为 UTC 2020/01/01 00:59:00 .000 */ +tm.year = 2020; +tm.month = 01; +tm.day = 01; +tm.hour= 00; +tm.minute = 59; +tm.second = 00; +tm.millisecond = 0; +/* 写RTC时间信息 */ +ret = RtcWriteTime(handle, &tm); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 读取RTC报警时间 + +如果需要读取定时报警时间,则可以通过以下函数完成: + +int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); + +**表 7** RtcReadAlarm参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

time

+

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +struct RtcTime alarmTime; + +/* 读RTC_ALARM_INDEX_A索引的RTC定时报警时间信息 */ +ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置RTC报警时间 + +根据报警索引设置RTC报警时间,通过以下函数完成: + +int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); + +**表 8** RtcWriteAlarm参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

time

+

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 + +``` +int32_t ret; +struct RtcTime alarmTime; + +/* 设置RTC报警时间为2020/01/01 00:59:59 .000 */ +alarmTime.year = 2020; +alarmTime.month = 01; +alarmTime.day = 01; +alarmTime.hour = 00; +alarmTime.minute = 59; +alarmTime.second = 59; +alarmTime.millisecond = 0; +/* 设置RTC_ALARM_INDEX_A索引的定时报警时间 */ +ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置定时报警中断使能或去使能 + +在启动报警操作前,需要先设置报警中断使能,报警超时后会触发告警回调函数,可以通过以下函数完成: + +int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\); + +**表 9** RtcAlarmInterruptEnable参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

alarmIndex

+

报警索引

+

enable

+

RTC报警中断配置,1:使能,0:去使能

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; + +/* 设置RTC报警中断使能 */ +ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 读取RTC外频 + +读取RTC外接晶体振荡频率,可以通过以下函数完成: + +int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\); + +**表 10** RtcGetFreq参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

freq

+

RTC的外接晶体振荡频率,单位(HZ)

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint32_t freq = 0; + +/* 读取RTC外接晶体振荡频率 */ +ret = RtcGetFreq(handle, &freq); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 配置RTC外频 + +配置RTC外接晶体振荡频率,可以通过以下函数完成: + +int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\); + +**表 11** RtcSetFreq参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

freq

+

RTC的外接晶体振荡频率,单位(HZ)

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint32_t freq = 32768; /* 32768 Hz */ + +/* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ +ret = RtcSetFreq(handle, freq); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 复位RTC + +复位RTC,复位RTC后各配置寄存器恢复默认值,可以通过以下函数完成: + +int32\_t RtcReset\(DevHandle handle\); + +**表 12** RtcReset参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; + +/* 复位RTC,复位RTC后各配置寄存器恢复默认值 */ +ret = RtcReset(handle); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 读取RTC自定义寄存器配置 + +按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: + +int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\); + +**表 13** RtcReadReg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

usrDefIndex

+

用户定义的寄存器对应索引

+

value

+

寄存器值

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义的第一个寄存器*/ +uint8_t value = 0; + +/* 按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值 */ +ret = RtcReadReg(handle, usrDefIndex, &value); +if (ret != 0) { + /* 错误处理 */ +} +``` + +- 设置RTC自定义寄存器配置 + +按照用户定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: + +int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\); + +**表 14** RtcWriteReg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

RTC设备句柄

+

usrDefIndex

+

用户定义的寄存器对应索引

+

value

+

寄存器值

+

返回值

+

返回值描述

+

0

+

操作成功

+

负数

+

操作失败

+
+ +``` +int32_t ret; +uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义第一个寄存器*/ +uint8_t value = 0x10; + +/* 按照用户的定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值 */ +ret = RtcWriteReg(handle, usrDefIndex, value); +if (ret != 0) { + /* 错误处理 */ +} +``` + +## 使用实例 + +本实例提供RTC接口的完整使用流程: + +1. 系统启动,驱动管理模块会识别系统当前的RTC器件; +2. 驱动管理模块完成RTC设备的初始化和设备创建; +3. 用户通过不同API,对该RTC设备进行对应的操作; +4. 关闭RTC设备,释放设备资源。 + +示例如下: + +``` +#include "rtc_if.h" +int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) +{ + if (alarmIndex == RTC_ALARM_INDEX_A) { + /* 报警A的处理 */ + printf("RTC Alarm A callback function\n\r"); + } else if (alarmIndex == RTC_ALARM_INDEX_B) { + /* 报警B的处理 */ + printf("RTC Alarm B callback function\n\r"); + } else { + /* 错误处理 */ + } + return 0; +} + +void RtcTestSample(void) +{ + int32_t ret; + struct RtcTime tm; + struct RtcTime alarmTime; + uint32_t freq; + DevHandle handle = NULL; + + /* 获取RTC设备句柄 */ + handle = RtcOpen(); + if (handle == NULL) { + /* 错误处理 */ + } + /* 注册报警A的定时回调函数 */ + ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ + freq = 32768; /* 32768 Hz */ + ret = RtcSetFreq(handle, freq); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC报警中断使能 */ + ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC时间为2020/01/01 00:00:10 .990 */ + tm.year = 2020; + tm.month = 01; + tm.day = 01; + tm.hour= 0; + tm.minute = 0; + tm.second = 10; + tm.millisecond = 990; + /* 写RTC时间信息 */ + ret = RtcWriteTime(handle, &tm); + if (ret != 0) { + /* 错误处理 */ + } + /* 设置RTC报警时间为2020/01/01 00:00:30 .100 */ + alarmTime.year = 2020; + alarmTime.month = 01; + alarmTime.day = 01; + alarmTime.hour = 0; + alarmTime.minute = 0; + alarmTime.second = 30; + alarmTime.millisecond = 100; + /* 设置RTC_ALARM_INDEX_A索引定时报警时间信息, 定时时间到后会打印"RTC Alarm A callback function" */ + ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); + if (ret != 0) { + /* 错误处理 */ + } + + /* 读取RTC实时时间 */ + ret = RtcReadTime(handle, &tm); + if (ret != 0) { + /* 错误处理 */ + } + sleep(5) + printf("RTC read time:\n\r"); + printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", + tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); + /* 销毁RTC设备句柄 */ + RtcClose(handle); +} +``` diff --git "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index d413efda41b8fbc48a7f5c6b8837dbc8aef2c480..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,97 +0,0 @@ -# RTC使用实例 - -本实例提供RTC接口的完整使用流程: - -1. 系统启动,驱动管理模块会识别系统当前的RTC器件; -2. 驱动管理模块完成RTC设备的初始化和设备创建; -3. 用户通过不同API,对该RTC设备进行对应的操作; -4. 关闭RTC设备,释放设备资源。 - -示例如下: - -``` -#include "rtc_if.h" -int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) -{ - if (alarmIndex == RTC_ALARM_INDEX_A) { - /* 报警A的处理 */ - printf("RTC Alarm A callback function\n\r"); - } else if (alarmIndex == RTC_ALARM_INDEX_B) { - /* 报警B的处理 */ - printf("RTC Alarm B callback function\n\r"); - } else { - /* 错误处理 */ - } - return 0; -} - -void RtcTestSample(void) -{ - int32_t ret; - struct RtcTime tm; - struct RtcTime alarmTime; - uint32_t freq; - DevHandle handle = NULL; - - /* 获取RTC设备句柄 */ - handle = RtcOpen(); - if (handle == NULL) { - /* 错误处理 */ - } - /* 注册报警A的定时回调函数 */ - ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ - freq = 32768; /* 32768 Hz */ - ret = RtcSetFreq(handle, freq); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC报警中断使能 */ - ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC时间为2020/01/01 00:00:10 .990 */ - tm.year = 2020; - tm.month = 01; - tm.day = 01; - tm.hour= 0; - tm.minute = 0; - tm.second = 10; - tm.millisecond = 990; - /* 写RTC时间信息 */ - ret = RtcWriteTime(handle, &tm); - if (ret != 0) { - /* 错误处理 */ - } - /* 设置RTC报警时间为2020/01/01 00:00:30 .100 */ - alarmTime.year = 2020; - alarmTime.month = 01; - alarmTime.day = 01; - alarmTime.hour = 0; - alarmTime.minute = 0; - alarmTime.second = 30; - alarmTime.millisecond = 100; - /* 设置RTC_ALARM_INDEX_A索引定时报警时间信息, 定时时间到后会打印"RTC Alarm A callback function" */ - ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); - if (ret != 0) { - /* 错误处理 */ - } - - /* 读取RTC实时时间 */ - ret = RtcReadTime(handle, &tm); - if (ret != 0) { - /* 错误处理 */ - } - sleep(5) - printf("RTC read time:\n\r"); - printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", - tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); - /* 销毁RTC设备句柄 */ - RtcClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 45065165bd233fa2a09b4f8843b40c2325786823..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/RTC\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,741 +0,0 @@ -# RTC使用指导 - -- [使用流程](#section620515765714) -- [创建RTC设备句柄](#section0702183665711) -- [销毁RTC设备句柄](#section639962619542) -- [注册RTC定时报警回调函数](#section123631358135713) -- [操作RTC](#section11091522125812) - -## 使用流程 - -在操作系统启动过程中,驱动管理模块根据配置文件加载RTC驱动,RTC驱动会检测RTC器件并初始化驱动。 - -使用RTC设备的一般流程如[图1](#fig166181128151112)所示。 - -**图 1** RTC设备使用流程图 - - -![](figures/zh-cn_image_0000001054728498.png) - -## 创建RTC设备句柄 - -RTC驱动加载成功后,驱动开发者使用驱动框架提供的查询接口并调用RTC设备驱动接口。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前操作系统支持一个RTC设备。 - -DevHandle RtcOpen\(void\); - -**表 1** RtcOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

void

-

NA

-

返回值

-

返回值描述

-

handle

-

操作成功返回 指针类型

-

NULL

-

操作失败

-
- -``` -DevHandle handle = NULL; - -/* 获取RTC句柄 */ -handle = RtcOpen(); -if (handle == NULL) { - /* 错误处理 */ -} -``` - -## 销毁RTC设备句柄 - -销毁RTC设备句柄,系统释放对应的资源。 - -void RtcClose\(DevHandle handle\); - -**表 2** RtcClose参数描述 - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-
- -``` -/* 销毁RTC句柄 */ -RtcClose(handle); -``` - -## 注册RTC定时报警回调函数 - -系统启动后需要注册RTC定时报警回调函数,报警超时后触发回调函数。 - -int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\); - -**表 3** RtcRegisterAlarmCallback参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

cb

-

定时报警回调函数

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -注册RTC\_ALARM\_INDEX\_A的定时报警处理函数, 示例如下: - -``` -/* 用户注册RTC定时报警回调函数的方法 */ -int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) -{ - if (alarmIndex == RTC_ALARM_INDEX_A) { - /* 报警A的处理 */ - } else if (alarmIndex == RTC_ALARM_INDEX_B) { - /* 报警B的处理 */ - } else { - /* 错误处理 */ - } - return 0; -} -int32_t ret; -/* 注册报警A的定时回调函数 */ -ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); -if (ret != 0) { - /* 错误处理 */ -} -``` - -## 操作RTC - -- 读取RTC时间。 - -系统从RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒,则可以通过以下函数完成: - -int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\); - -**表 4** RtcReadTime参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

time

-

RTC读取时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -struct RtcTime tm; - -/* 系统从RTC读取时间信息 */ -ret = RtcReadTime(handle, &tm); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置RTC时间 - -设置RTC时间,则可以通过以下函数完成: - -int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\); - -**表 5** RtcWriteTime参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

time

-

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 - -``` -int32_t ret; -struct RtcTime tm; - -/* 设置RTC时间为 UTC 2020/01/01 00:59:00 .000 */ -tm.year = 2020; -tm.month = 01; -tm.day = 01; -tm.hour= 00; -tm.minute = 59; -tm.second = 00; -tm.millisecond = 0; -/* 写RTC时间信息 */ -ret = RtcWriteTime(handle, &tm); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 读取RTC报警时间 - -如果需要读取定时报警时间,则可以通过以下函数完成: - -int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); - -**表 6** RtcReadAlarm参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

time

-

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -struct RtcTime alarmTime; - -/* 读RTC_ALARM_INDEX_A索引的RTC定时报警时间信息 */ -ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置RTC报警时间 - -根据报警索引设置RTC报警时间,通过以下函数完成: - -int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); - -**表 7** RtcWriteAlarm参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

time

-

RTC报警时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->RTC起始时间为UTC 1970/01/01 Thursday 00:00:00,年的最大取值按照用户器件手册要求计算配置,星期不用配置。 - -``` -int32_t ret; -struct RtcTime alarmTime; - -/* 设置RTC报警时间为2020/01/01 00:59:59 .000 */ -alarmTime.year = 2020; -alarmTime.month = 01; -alarmTime.day = 01; -alarmTime.hour = 00; -alarmTime.minute = 59; -alarmTime.second = 59; -alarmTime.millisecond = 0; -/* 设置RTC_ALARM_INDEX_A索引的定时报警时间 */ -ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置定时报警中断使能或去使能 - -在启动报警操作前,需要先设置报警中断使能,报警超时后会触发告警回调函数,可以通过以下函数完成: - -int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\); - -**表 8** RtcAlarmInterruptEnable参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

alarmIndex

-

报警索引

-

enable

-

RTC报警中断配置,1:使能,0:去使能

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; - -/* 设置RTC报警中断使能 */ -ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 读取RTC外频 - -读取RTC外接晶体振荡频率,可以通过以下函数完成: - -int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\); - -**表 9** RtcGetFreq参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

freq

-

RTC的外接晶体振荡频率,单位(HZ)

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint32_t freq = 0; - -/* 读取RTC外接晶体振荡频率 */ -ret = RtcGetFreq(handle, &freq); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 配置RTC外频 - -配置RTC外接晶体振荡频率,可以通过以下函数完成: - -int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\); - -**表 10** RtcSetFreq参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

freq

-

RTC的外接晶体振荡频率,单位(HZ)

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint32_t freq = 32768; /* 32768 Hz */ - -/* 设置RTC外接晶体振荡频率,注意按照器件手册要求配置RTC外频 */ -ret = RtcSetFreq(handle, freq); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 复位RTC - -复位RTC,复位RTC后各配置寄存器恢复默认值,可以通过以下函数完成: - -int32\_t RtcReset\(DevHandle handle\); - -**表 11** RtcReset参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; - -/* 复位RTC,复位RTC后各配置寄存器恢复默认值 */ -ret = RtcReset(handle); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 读取RTC自定义寄存器配置 - -按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: - -int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\); - -**表 12** RtcReadReg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

usrDefIndex

-

用户定义的寄存器对应索引

-

value

-

寄存器值

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义的第一个寄存器*/ -uint8_t value = 0; - -/* 按照用户定义的寄存器索引,读取对应的寄存器配置,一个索引对应一字节的配置值 */ -ret = RtcReadReg(handle, usrDefIndex, &value); -if (ret != 0) { - /* 错误处理 */ -} -``` - -- 设置RTC自定义寄存器配置 - -按照用户定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值,通过以下函数完成: - -int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\); - -**表 13** RtcWriteReg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

RTC设备句柄

-

usrDefIndex

-

用户定义的寄存器对应索引

-

value

-

寄存器值

-

返回值

-

返回值描述

-

0

-

操作成功

-

负数

-

操作失败

-
- -``` -int32_t ret; -uint8_t usrDefIndex = 0; /* 定义0索引对应用户定义第一个寄存器*/ -uint8_t value = 0x10; - -/* 按照用户的定义的寄存器索引,设置对应的寄存器配置,一个索引对应一字节的配置值 */ -ret = RtcWriteReg(handle, usrDefIndex, value); -if (ret != 0) { - /* 错误处理 */ -} -``` - diff --git "a/zh-cn/device-dev/driver/RTC\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/RTC\346\246\202\350\277\260.md" deleted file mode 100755 index 19b903394cd28f79241b90a90db46a81f1d82529..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/RTC\346\246\202\350\277\260.md" +++ /dev/null @@ -1,103 +0,0 @@ -# RTC概述 - -- [简介](#section104842041574) -- [接口说明](#section16892932155715) - -## 简介 - -RTC\(real-time clock\)为操作系统中的实时时钟设备,为操作系统提供精准的实时时间和定时报警功能。当设备下电后,通过外置电池供电,RTC继续记录操作系统时间;设备上电后,RTC提供实时时钟给操作系统,确保断电后系统时间的连续性。 - -## 接口说明 - -**表 1** RTC设备API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

RTC句柄操作

-

RtcOpen

-

获取RTC设备驱动句柄

-

RtcClose

-

释放RTC设备驱动句柄

-

RTC时间操作接口

-

RtcReadTime

-

读RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

RtcWriteTime

-

写RTC时间信息,包括年、月、星期、日、时、分、秒、毫秒

-

RTC报警操作接口

-

RtcReadAlarm

-

读RTC报警时间信息

-

RtcWriteAlarm

-

写RTC报警时间信息

-

RtcRegisterAlarmCallback

-

注册报警超时回调函数

-

RtcAlarmInterruptEnable

-

使能/去使能RTC报警中断

-

RTC配置操作

-

RtcGetFreq

-

读RTC外接晶振频率

-

RtcSetFreq

-

配置RTC外接晶振频率

-

RtcReset

-

RTC复位

-

读写用户定义寄存器

-

RtcReadReg

-

读用户自定义寄存器

-

RtcWriteReg

-

写用户自定义寄存器

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/Readme-CN.md b/zh-cn/device-dev/driver/Readme-CN.md index f86ff0362ebca8304d36ae274a125ce7bd8e22bc..c4960d522fa5595f74388a08024d6608ad6ee098 100755 --- a/zh-cn/device-dev/driver/Readme-CN.md +++ b/zh-cn/device-dev/driver/Readme-CN.md @@ -8,66 +8,19 @@ - [配置管理](配置管理.md) - [HDF开发实例](HDF开发实例.md) -- [驱动平台](驱动平台.md) +- [平台驱动](平台驱动.md) - [GPIO](GPIO.md) - - [GPIO概述](GPIO概述.md) - - [GPIO使用指导](GPIO使用指导.md) - - [GPIO使用实例](GPIO使用实例.md) - - [I2C](I2C.md) - - [I2C概述](I2C概述.md) - - [I2C使用指导](I2C使用指导.md) - - [I2C使用实例](I2C使用实例.md) - - [RTC](RTC.md) - - [RTC概述](RTC概述.md) - - [RTC使用指导](RTC使用指导.md) - - [RTC使用实例](RTC使用实例.md) - - [SDIO](SDIO.md) - - [SDIO概述](SDIO概述.md) - - [SDIO使用指导](SDIO使用指导.md) - - [SDIO使用实例](SDIO使用实例.md) - - [SPI](SPI.md) - - [SPI概述](SPI概述.md) - - [SPI使用指导](SPI使用指导.md) - - [SPI使用实例](SPI使用实例.md) - - [UART](UART.md) - - [UART概述](UART概述.md) - - [UART使用指导](UART使用指导.md) - - [UART使用实例](UART使用实例.md) - - [WATCHDOG](WATCHDOG.md) - - [看门狗概述](看门狗概述.md) - - [看门狗使用指导](看门狗使用指导.md) - - [看门狗使用实例](看门狗使用实例.md) - - [MIPI DSI](MIPI-DSI.md) - - [MIPI DSI概述](MIPI-DSI概述.md) - - [MIPI DSI使用指导](MIPI-DSI使用指导.md) - - [MIPI DSI使用实例](MIPI-DSI使用实例.md) - [外设](外设.md) - [LCD](LCD.md) - - [LCD开发概述](LCD开发概述.md) - - [LCD开发指导](LCD开发指导.md) - - [LCD开发实例](LCD开发实例.md) - - [TOUCHSCREEN](TOUCHSCREEN.md) - - [Touchscreen开发概述](Touchscreen开发概述.md) - - [Touchscreen开发指导](Touchscreen开发指导.md) - - [Touchscreen开发实例](Touchscreen开发实例.md) - - [SENSOR](SENSOR.md) - - [传感器驱动开发概述](传感器驱动开发概述.md) - - [传感器驱动开发指导](传感器驱动开发指导.md) - - [传感器驱动开发实例](传感器驱动开发实例.md) - - [传感器驱动测试指导](传感器驱动测试指导.md) - - [WLAN](WLAN.md) - - [WLAN开发概述](WLAN开发概述.md) - - [WLAN开发指导](WLAN开发指导.md) - - [WLAN开发实例](WLAN开发实例.md) diff --git a/zh-cn/device-dev/driver/SDIO.md b/zh-cn/device-dev/driver/SDIO.md index 192dd216b5df44ef51ede3e7ac9dab09eaca828a..482037c6ff6da5590edc094387ac72b94bac7d8a 100755 --- a/zh-cn/device-dev/driver/SDIO.md +++ b/zh-cn/device-dev/driver/SDIO.md @@ -1,9 +1,1068 @@ -# SDIO +# SDIO -- **[SDIO概述](SDIO概述.md)** +- [概述](#section1155271783811) + - [接口说明](#section08064247248) -- **[SDIO使用指导](SDIO使用指导.md)** +- [使用指导](#section1878939192515) + - [使用流程](#section1490685512255) + - [打开SDIO控制器](#section10782428132616) + - [独占HOST](#section11263172312715) + - [使能SDIO设备](#section17861486271) + - [注册SDIO中断](#section521213262286) + - [进行SDIO通信](#section85661522153420) + - [释放SDIO中断](#section1683449352) + - [去使能SDIO设备](#section15379324143611) + - [释放HOST](#section536018263713) + - [关闭SDIO控制器](#section4752739183716) -- **[SDIO使用实例](SDIO使用实例.md)** +- [使用实例](#section376910122382) +## 概述 + +- SDIO是安全数字输入输出接口(Secure Digital Input and Output)的缩写,是从SD内存卡接口的基础上演化出来的一种外设接口。SDIO接口兼容以前的SD内存卡,并且可以连接支持SDIO接口的设备。 +- SDIO的应用比较广泛,目前,有许多手机都支持SDIO功能,并且很多SDIO外设也被开发出来,使得手机外接外设更加容易。常见的SDIO外设有WLAN、GPS、CAMERA、蓝牙等。 +- SDIO总线有两端,其中一端是主机端(HOST),另一端是设备端(DEVICE)。所有的通信都是由HOST端发出命令开始的,在DEVICE端只要能解析HOST的命令,就可以同HOST进行通信了。SDIO的HOST可以连接多个DEVICE,如下图所示: + + - CLK信号:HOST给DEVICE的时钟信号。 + - VDD信号:电源信号。 + - VSS信号:Ground信号。 + - D0-3信号:4条数据线,其中,DAT1信号线复用为中断线,在1BIT模式下DAT0用来传输数据,在4BIT模式下DAT0-DAT3用来传输数据。 + - CMD信号:用于HOST发送命令和DEVICE回复响应。 + + **图 1** SDIO的HOST-DEVICE连接示意图 + + + ![](figures/zh-cn_image_0000001054280608.png) + +- SDIO接口定义了操作SDIO的通用方法集合,包括打开/关闭SDIO控制器、独占/释放HOST、使能/去使能设备、申请/释放中断、读写、获取/设置公共信息等。 + +### 接口说明 + +**表 1** SDIO驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

SDIO设备打开/关闭接口

+

SdioOpen

+

打开指定总线号的SDIO控制器

+

SdioClose

+

关闭SDIO控制器

+

SDIO读写接口

+

SdioReadBytes

+

从指定地址开始,增量读取指定长度的数据

+

SdioWriteBytes

+

从指定地址开始,增量写入指定长度的数据

+

SdioReadBytesFromFixedAddr

+

从固定地址读取指定长度的数据

+

SdioWriteBytesToFixedAddr

+

向固定地址写入指定长度的数据

+

SdioReadBytesFromFunc0

+

从SDIO function 0的指定地址空间读取指定长度的数据

+

SdioWriteBytesToFunc0

+

向SDIO function 0的指定地址空间写入指定长度的数据

+

SDIO设置块大小接口

+

SdioSetBlockSize

+

设置块的大小

+

SDIO获取/设置公共信息接口

+

SdioGetCommonInfo

+

获取公共信息

+

SdioSetCommonInfo

+

设置公共信息

+

SDIO刷新数据接口

+

SdioFlushData

+

刷新数据

+

SDIO独占/释放HOST接口

+

SdioClaimHost

+

独占Host

+

SdioReleaseHost

+

释放Host

+

SDIO使能/去使能功能设备接口

+

SdioEnableFunc

+

使能SDIO功能设备

+

SdioDisableFunc

+

去使能SDIO功能设备

+

SDIO申请/释放中断接口

+

SdioClaimIrq

+

申请中断

+

SdioReleaseIrq

+

释放中断

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,目前只支持在内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用SDIO的一般流程如[图2](#fig1343742311264)所示。 + +**图 2** SDIO使用流程图 + + +![](figures/zh-cn_image_0000001123540984.png) + +### 打开SDIO控制器 + +在使用SDIO进行通信前,首先要调用SdioOpen获取SDIO控制器的设备句柄,该函数会返回指定总线号的SDIO控制器的设备句柄。 + +DevHandle SdioOpen\(int16\_t mmcBusNum, struct SdioFunctionConfig \*config\); + +**表 2** SdioOpen函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

mmcBusNum

+

总线号

+

config

+

SDIO功能配置信息

+

返回值

+

返回值描述

+

NULL

+

获取SDIO控制器的设备句柄失败

+

设备句柄

+

SDIO控制器的设备句柄

+
+ +打开SDIO控制器的示例如下: + +``` +DevHandle handle = NULL; +struct SdioFunctionConfig config; +config.funcNr = 1; +config.vendorId = 0x123; +config.deviceId = 0x456; +/* 打开总线号为1的SDIO控制器 */ +handle = SdioOpen(1, &config); +if (handle == NULL) { + HDF_LOGE("SdioOpen: failed!\n"); +} +``` + +### 独占HOST + +获取到SDIO控制器的设备句柄之后,需要先独占HOST才能进行SDIO后续的一系列操作,独占HOST函数如下所示: + +void SdioClaimHost\(DevHandle handle\); + +**表 3** SdioClaimHost函数的参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+
+ +独占HOST示例如下: + +``` +SdioClaimHost(handle); /* 独占HOST */ +``` + +### 使能SDIO设备 + +在访问寄存器之前,需要先使能SDIO设备,使能SDIO设备的函数如下所示: + +int32\_t SdioEnableFunc\(DevHandle handle\); + +**表 4** SdioEnableFunc函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

返回值

+

返回值描述

+

0

+

SDIO使能成功

+

负数

+

SDIO使能失败

+
+ +使能SDIO设备的示例如下: + +``` +int32_t ret; +/* 使能SDIO设备 */ +ret = SdioEnableFunc(handle); +if (ret != 0) { + HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); +} +``` + +### 注册SDIO中断 + +在通信之前,还需要注册SDIO中断,注册SDIO中断函数如下图所示: + +int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\); + +**表 5** SdioClaimIrq函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

handler

+

中断服务函数指针

+

返回值

+

返回值描述

+

0

+

注册中断成功

+

负数

+

注册中断失败

+
+ +注册SDIO中的示例如下: + +``` +/* 中断服务函数需要根据各自平台的情况去实现 */ +static void SdioIrqFunc(void *data) +{ + if (data == NULL) { + HDF_LOGE("SdioIrqFunc: data is NULL.\n"); + return; + } + /* 需要开发者自行添加具体实现 */ +} + +int32_t ret; +/* 注册SDIO中断 */ +ret = SdioClaimIrq(handle, SdioIrqFunc); +if (ret != 0) { + HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); +} +``` + +### 进行SDIO通信 + +- 向SDIO设备增量写入指定长度的数据 + +对应的接口函数如下所示: + +int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 6** SdioWriteBytes函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

待写入数据的指针

+

addr

+

待写入数据的起始地址

+

size

+

待写入数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO写数据成功

+

负数

+

SDIO写数据失败

+
+ +向SDIO设备增量写入指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t wbuff[] = {1,2,3,4,5}; +uint32_t addr = 0x100 + 0x09; +/* 向SDIO设备起始地址0x109,增量写入5个字节的数据 */ +ret = SdioWriteBytes(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0])); +if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); +} +``` + +- 从SDIO设备增量读取指定长度的数据 + +对应的接口函数如下所示: + +int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 7** SdioReadBytes函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

接收读取数据的指针

+

addr

+

待读取数据的起始地址

+

size

+

待读取数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO读数据成功

+

负数

+

SDIO读数据失败

+
+ +从SDIO设备增量读取指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t rbuff[5] = {0}; +uint32_t addr = 0x100 + 0x09; +/* 从SDIO设备起始地址0x109,增量读取5个字节的数据 */ +ret = SdioReadBytes(handle, rbuff, addr, 5); +if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); +} +``` + +- 向SDIO设备的固定地址写入指定长度的数据 + + 对应的接口函数如下所示: + + int32\_t SdioWriteBytesToFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); + + **表 8** SdioWriteBytesToFixedAddr函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

待写入数据的指针

+

addr

+

待写入数据的固定地址

+

size

+

待写入数据的长度

+

scatterLen

+

集散表的长度。如果该字段不为0,则data为集散表类型。

+

返回值

+

返回值描述

+

0

+

SDIO写数据成功

+

负数

+

SDIO写数据失败

+
+ + 向SDIO设备的固定地址写入指定长度的数据的示例如下: + + ``` + int32_t ret; + uint8_t wbuff[] = {1,2,3,4,5}; + uint32_t addr = 0x100 + 0x09; + /* 向SDIO设备固定地址0x109写入5个字节的数据 */ + ret = SdioWriteBytesToFixedAddr(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0]), 0); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); + } + ``` + +- 从SDIO设备的固定地址读取指定长度的数据 + + 对应的接口函数如下所示: + + int32\_t SdioReadBytesFromFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); + + **表 9** SdioReadBytesFromFixedAddr函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

接收读取数据的指针

+

addr

+

待读取数据的起始地址

+

size

+

待读取数据的长度

+

scatterLen

+

集散表的长度。如果该字段不为0,则data为集散表类型。

+

返回值

+

返回值描述

+

0

+

SDIO读数据成功

+

负数

+

SDIO读数据失败

+
+ + 从SDIO设备的固定地址读取指定长度的数据的示例如下: + + ``` + int32_t ret; + uint8_t rbuff[5] = {0}; + uint32_t addr = 0x100 + 0x09; + /* 从SDIO设备固定地址0x109中读取5个字节的数据 */ + ret = SdioReadBytesFromFixedAddr(handle, rbuff, addr, 5, 0); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); + } + ``` + + +- 向SDIO function 0的指定地址空间写入指定长度的数据 + +当前只支持写入一个字节的数据,对应的接口函数如下所示: + +int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 10** SdioWriteBytesToFunc0函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

待写入数据的指针

+

addr

+

待写入数据的起始地址

+

size

+

待写入数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO写数据成功

+

负数

+

SDIO写数据失败

+
+ +向SDIO function 0的指定地址空间写入指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t wbuff = 1; +/* 向SDIO function 0地址0x2中写入1字节的数据 */ +ret = SdioWriteBytesToFunc0(handle, &wbuff, 0x2, 1); +if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); +} +``` + +- 从SDIO function 0的指定地址空间读取指定长度的数据 + +当前只支持读取一个字节的数据,对应的接口函数如下所示: + +int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); + +**表 11** SdioReadBytesFromFunc0函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

data

+

接收读取数据的指针

+

addr

+

待读取数据的起始地址

+

size

+

待读取数据的长度

+

返回值

+

返回值描述

+

0

+

SDIO读数据成功

+

负数

+

SDIO读数据失败

+
+ +从SDIO function 0的指定地址空间读取指定长度的数据的示例如下: + +``` +int32_t ret; +uint8_t rbuff; +/* 从SDIO function 0设备地址0x2中读取1字节的数据 */ +ret = SdioReadBytesFromFunc0(handle, &rbuff, 0x2, 1); +if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); +} +``` + +### 释放SDIO中断 + +通信完成之后,需要释放SDIO中断,函数如下所示: + +int32\_t SdioReleaseIrq\(DevHandle handle\); + +**表 12** SdioReleaseIrq函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

返回值

+

返回值描述

+

0

+

释放SDIO中断成功

+

负数

+

释放SDIO中断失败

+
+ +释放SDIO中断的示例如下: + +``` +int32_t ret; +/* 释放SDIO中断 */ +ret = SdioReleaseIrq(handle); +if (ret != 0) { + HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); +} +``` + +### 去使能SDIO设备 + +通信完成之后,还需要去使能SDIO设备,函数如下所示: + +int32\_t SdioDisableFunc\(DevHandle handle\); + +**表 13** SdioDisableFunc函数的参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+

返回值

+

返回值描述

+

0

+

去使能SDIO设备成功

+

负数

+

去使能SDIO设备失败

+
+ +去使能SDIO设备的示例如下: + +``` +int32_t ret; +/* 去使能SDIO设备 */ +ret = SdioDisableFunc(handle); +if (ret != 0) { + HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); +} +``` + +### 释放HOST + +通信完成之后,还需要释放去HOST,函数如下所示: + +void SdioReleaseHost\(DevHandle handle\); + +**表 14** SdioReleaseHost函数的参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+
+ +释放HOST的示例如下: + +``` +SdioReleaseHost(handle); /* 释放HOST */ +``` + +### 关闭SDIO控制器 + +SDIO通信完成之后,最后需要关闭SDIO控制器,函数如下所示: + +void SdioClose\(DevHandle handle\); + +该函数会释放掉申请的资源。 + +**表 15** SdioClose函数的参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SDIO控制器的设备句柄

+
+ +关闭SDIO控制器的示例如下: + +``` +SdioClose(handle); /* 关闭SDIO控制器 */ +``` + +## 使用实例 + +SDIO设备完整的使用示例如下所示,首先打开总线号为1的SDIO控制器,然后独占HOST、使能设备、注册中断,接着进行SDIO通信(读写等),通信完成之后,释放中断、去使能设备、释放HOST,最后关闭SDIO控制器。 + +``` +#include "hdf_log.h" +#include "sdio_if.h" + +#define TEST_FUNC_NUM 1 /* 本测试用例中,使用编号为1的I/O function */ +#define TEST_FBR_BASE_ADDR 0x100 /* 编号为1的I/O function的FBR基地址 */ +#define TEST_ADDR_OFFSET 9 /* 本测试用例中,需要读写的寄存器的地址偏移 */ +#define TEST_DATA_LEN 3 /* 本测试用例中,读写数据的长度 */ +#define TEST_BLOCKSIZE 2 /* 本测试用例中,数据块的大小,单位字节 */ + +/* 中断服务函数,需要根据各自平台的情况去实现 */ +static void SdioIrqFunc(void *data) +{ + if (data == NULL) { + HDF_LOGE("SdioIrqFunc: data is NULL.\n"); + return; + } + /* 需要开发者自行添加具体的实现 */ +} + +void SdioTestSample(void) +{ + int32_t ret; + DevHandle handle = NULL; + uint8_t data[TEST_DATA_LEN] = {0}; + struct SdioFunctionConfig config = {1, 0x123, 0x456}; + uint8_t val; + uint32_t addr; + + /* 打开总线号为1的SDIO设备 */ + handle = SdioOpen(1, &config); + if (handle == NULL) { + HDF_LOGE("SdioOpen: failed!\n"); + return; + } + /* 独占HOST */ + SdioClaimHost(handle); + /* 使能SDIO设备 */ + ret = SdioEnableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); + goto ENABLE_ERR; + } + /* 注册中断 */ + ret = SdioClaimIrq(handle, SdioIrqFunc); + if (ret != 0) { + HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); + goto CLAIM_IRQ_ERR; + } + /* 设置块大小为2字节 */ + ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE); + if (ret != 0) { + HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO设备增量地址读取3字节的数据 */ + addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET; + ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO设备增量地址写入3字节的数据 */ + ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO设备读取1字节的数据 */ + ret = SdioReadBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO设备写入1字节的数据 */ + ret = SdioWriteBytes(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO设备固定地址读取3字节的数据 */ + ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO设备固定地址写入1字节的数据 */ + ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 从SDIO function 0读取1字节的数据 */ + addr = 0x02; + ret = SdioReadBytesFromFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } + /* 向SDIO function 0写入1字节的数据 */ + ret = SdioWriteBytesToFunc0(handle, &val, addr, 1); + if (ret != 0) { + HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); + goto COMM_ERR; + } +COMM_ERR: + /* 释放中断 */ + ret = SdioReleaseIrq(handle); + if (ret != 0) { + HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); + } +CLAIM_IRQ_ERR: + /* 去使能SDIO设备 */ + ret = SdioDisableFunc(handle); + if (ret != 0) { + HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); + } +ENABLE_ERR: + /* 释放HOST */ + SdioReleaseHost(handle); + /* 关闭SDIO设备 */ + SdioClose(handle); +} +``` diff --git "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 18ddb74593b5ea69a427ecd03e8a41394daae174..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,129 +0,0 @@ -# SDIO使用实例 - -SDIO设备完整的使用示例如下所示,首先打开总线号为1的SDIO控制器,然后独占HOST、使能设备、注册中断,接着进行SDIO通信(读写等),通信完成之后,释放中断、去使能设备、释放HOST,最后关闭SDIO控制器。 - -``` -#include "hdf_log.h" -#include "sdio_if.h" - -#define TEST_FUNC_NUM 1 /* 本测试用例中,使用编号为1的I/O function */ -#define TEST_FBR_BASE_ADDR 0x100 /* 编号为1的I/O function的FBR基地址 */ -#define TEST_ADDR_OFFSET 9 /* 本测试用例中,需要读写的寄存器的地址偏移 */ -#define TEST_DATA_LEN 3 /* 本测试用例中,读写数据的长度 */ -#define TEST_BLOCKSIZE 2 /* 本测试用例中,数据块的大小,单位字节 */ - -/* 中断服务函数,需要根据各自平台的情况去实现 */ -static void SdioIrqFunc(void *data) -{ - if (data == NULL) { - HDF_LOGE("SdioIrqFunc: data is NULL.\n"); - return; - } - /* 需要开发者自行添加具体的实现 */ -} - -void SdioTestSample(void) -{ - int32_t ret; - DevHandle handle = NULL; - uint8_t data[TEST_DATA_LEN] = {0}; - struct SdioFunctionConfig config = {1, 0x123, 0x456}; - uint8_t val; - uint32_t addr; - - /* 打开总线号为1的SDIO设备 */ - handle = SdioOpen(1, &config); - if (handle == NULL) { - HDF_LOGE("SdioOpen: failed!\n"); - return; - } - /* 独占HOST */ - SdioClaimHost(handle); - /* 使能SDIO设备 */ - ret = SdioEnableFunc(handle); - if (ret != 0) { - HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); - goto ENABLE_ERR; - } - /* 注册中断 */ - ret = SdioClaimIrq(handle, SdioIrqFunc); - if (ret != 0) { - HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); - goto CLAIM_IRQ_ERR; - } - /* 设置块大小为2字节 */ - ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE); - if (ret != 0) { - HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO设备增量地址读取3字节的数据 */ - addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET; - ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN); - if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO设备增量地址写入3字节的数据 */ - ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN); - if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO设备读取1字节的数据 */ - ret = SdioReadBytes(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO设备写入1字节的数据 */ - ret = SdioWriteBytes(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO设备固定地址读取3字节的数据 */ - ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO设备固定地址写入1字节的数据 */ - ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 从SDIO function 0读取1字节的数据 */ - addr = 0x02; - ret = SdioReadBytesFromFunc0(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); - goto COMM_ERR; - } - /* 向SDIO function 0写入1字节的数据 */ - ret = SdioWriteBytesToFunc0(handle, &val, addr, 1); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); - goto COMM_ERR; - } -COMM_ERR: - /* 释放中断 */ - ret = SdioReleaseIrq(handle); - if (ret != 0) { - HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); - } -CLAIM_IRQ_ERR: - /* 去使能SDIO设备 */ - ret = SdioDisableFunc(handle); - if (ret != 0) { - HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); - } -ENABLE_ERR: - /* 释放HOST */ - SdioReleaseHost(handle); - /* 关闭SDIO设备 */ - SdioClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index fd65e6de6adcef6ef307018c850ca1cb513d3b1f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SDIO\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,787 +0,0 @@ -# SDIO使用指导 - -- [使用流程](#section1962415610383) -- [打开SDIO控制器](#section814751015461) -- [独占HOST](#section49274582455) -- [使能SDIO设备](#section1431520410489) -- [注册SDIO中断](#section3662781537) -- [进行SDIO通信](#section391941913484) -- [释放SDIO中断](#section56205204481) -- [去使能SDIO设备](#section181181621124815) -- [释放HOST](#section657117215486) -- [关闭SDIO控制器](#section1898172114818) - -## 使用流程 - -使用SDIO的一般流程如[图1](SPI使用指导.md#fig23885455594)所示。 - -**图 1** SDIO使用流程图 - - -![](figures/zh-cn_image_0000001054440624.png) - -## 打开SDIO控制器 - -在使用SDIO进行通信前,首先要调用SdioOpen获取SDIO控制器的设备句柄,该函数会返回指定总线号的SDIO控制器的设备句柄。 - -DevHandle SdioOpen\(int16\_t mmcBusNum, struct SdioFunctionConfig \*config\); - -**表 1** SdioOpen函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

mmcBusNum

-

总线号

-

config

-

SDIO功能配置信息

-

返回值

-

返回值描述

-

NULL

-

获取SDIO控制器的设备句柄失败

-

设备句柄

-

SDIO控制器的设备句柄

-
- -打开SDIO控制器的示例如下: - -``` -DevHandle handle = NULL; -struct SdioFunctionConfig config; -config.funcNr = 1; -config.vendorId = 0x123; -config.deviceId = 0x456; -/* 打开总线号为1的SDIO控制器 */ -handle = SdioOpen(1, &config); -if (handle == NULL) { - HDF_LOGE("SdioOpen: failed!\n"); -} -``` - -## 独占HOST - -获取到SDIO控制器的设备句柄之后,需要先独占HOST才能进行SDIO后续的一系列操作,独占HOST函数如下所示: - -void SdioClaimHost\(DevHandle handle\); - -**表 2** SdioClaimHost函数的参数描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-
- -独占HOST示例如下: - -``` -SdioClaimHost(handle); /* 独占HOST */ -``` - -## 使能SDIO设备 - -在访问寄存器之前,需要先使能SDIO设备,使能SDIO设备的函数如下所示: - -int32\_t SdioEnableFunc\(DevHandle handle\); - -**表 3** SdioEnableFunc函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

返回值

-

返回值描述

-

0

-

SDIO使能成功

-

负数

-

SDIO使能失败

-
- -使能SDIO设备的示例如下: - -``` -int32_t ret; -/* 使能SDIO设备 */ -ret = SdioEnableFunc(handle); -if (ret != 0) { - HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret); -} -``` - -## 注册SDIO中断 - -在通信之前,还需要注册SDIO中断,注册SDIO中断函数如下图所示: - -int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\); - -**表 4** SdioClaimIrq函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

handler

-

中断服务函数指针

-

返回值

-

返回值描述

-

0

-

注册中断成功

-

负数

-

注册中断失败

-
- -注册SDIO中的示例如下: - -``` -/* 中断服务函数需要根据各自平台的情况去实现 */ -static void SdioIrqFunc(void *data) -{ - if (data == NULL) { - HDF_LOGE("SdioIrqFunc: data is NULL.\n"); - return; - } - /* 需要开发者自行添加具体实现 */ -} - -int32_t ret; -/* 注册SDIO中断 */ -ret = SdioClaimIrq(handle, SdioIrqFunc); -if (ret != 0) { - HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret); -} -``` - -## 进行SDIO通信 - -- 向SDIO设备增量写入指定长度的数据 - -对应的接口函数如下所示: - -int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 5** SdioWriteBytes函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

待写入数据的指针

-

addr

-

待写入数据的起始地址

-

size

-

待写入数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO写数据成功

-

负数

-

SDIO写数据失败

-
- -向SDIO设备增量写入指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t wbuff[] = {1,2,3,4,5}; -uint32_t addr = 0x100 + 0x09; -/* 向SDIO设备起始地址0x109,增量写入5个字节的数据 */ -ret = SdioWriteBytes(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0])); -if (ret != 0) { - HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret); -} -``` - -- 从SDIO设备增量读取指定长度的数据 - -对应的接口函数如下所示: - -int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 6** SdioReadBytes函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

接收读取数据的指针

-

addr

-

待读取数据的起始地址

-

size

-

待读取数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO读数据成功

-

负数

-

SDIO读数据失败

-
- -从SDIO设备增量读取指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t rbuff[5] = {0}; -uint32_t addr = 0x100 + 0x09; -/* 从SDIO设备起始地址0x109,增量读取5个字节的数据 */ -ret = SdioReadBytes(handle, rbuff, addr, 5); -if (ret != 0) { - HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret); -} -``` - -- 向SDIO设备的固定地址写入指定长度的数据 - - 对应的接口函数如下所示: - - int32\_t SdioWriteBytesToFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); - - **表 7** SdioWriteBytesToFixedAddr函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

待写入数据的指针

-

addr

-

待写入数据的固定地址

-

size

-

待写入数据的长度

-

scatterLen

-

集散表的长度。如果该字段不为0,则data为集散表类型。

-

返回值

-

返回值描述

-

0

-

SDIO写数据成功

-

负数

-

SDIO写数据失败

-
- - 向SDIO设备的固定地址写入指定长度的数据的示例如下: - - ``` - int32_t ret; - uint8_t wbuff[] = {1,2,3,4,5}; - uint32_t addr = 0x100 + 0x09; - /* 向SDIO设备固定地址0x109写入5个字节的数据 */ - ret = SdioWriteBytesToFixedAddr(handle, wbuff, addr, sizeof(wbuff) / sizeof(wbuff[0]), 0); - if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret); - } - ``` - -- 从SDIO设备的固定地址读取指定长度的数据 - - 对应的接口函数如下所示: - - int32\_t SdioReadBytesFromFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\); - - **表 8** SdioReadBytesFromFixedAddr函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

接收读取数据的指针

-

addr

-

待读取数据的起始地址

-

size

-

待读取数据的长度

-

scatterLen

-

集散表的长度。如果该字段不为0,则data为集散表类型。

-

返回值

-

返回值描述

-

0

-

SDIO读数据成功

-

负数

-

SDIO读数据失败

-
- - 从SDIO设备的固定地址读取指定长度的数据的示例如下: - - ``` - int32_t ret; - uint8_t rbuff[5] = {0}; - uint32_t addr = 0x100 + 0x09; - /* 从SDIO设备固定地址0x109中读取5个字节的数据 */ - ret = SdioReadBytesFromFixedAddr(handle, rbuff, addr, 5, 0); - if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret); - } - ``` - - -- 向SDIO function 0的指定地址空间写入指定长度的数据 - -当前只支持写入一个字节的数据,对应的接口函数如下所示: - -int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 9** SdioWriteBytesToFunc0函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

待写入数据的指针

-

addr

-

待写入数据的起始地址

-

size

-

待写入数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO写数据成功

-

负数

-

SDIO写数据失败

-
- -向SDIO function 0的指定地址空间写入指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t wbuff = 1; -/* 向SDIO function 0地址0x2中写入1字节的数据 */ -ret = SdioWriteBytesToFunc0(handle, &wbuff, 0x2, 1); -if (ret != 0) { - HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret); -} -``` - -- 从SDIO function 0的指定地址空间读取指定长度的数据 - -当前只支持读取一个字节的数据,对应的接口函数如下所示: - -int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\); - -**表 10** SdioReadBytesFromFunc0函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

data

-

接收读取数据的指针

-

addr

-

待读取数据的起始地址

-

size

-

待读取数据的长度

-

返回值

-

返回值描述

-

0

-

SDIO读数据成功

-

负数

-

SDIO读数据失败

-
- -从SDIO function 0的指定地址空间读取指定长度的数据的示例如下: - -``` -int32_t ret; -uint8_t rbuff; -/* 从SDIO function 0设备地址0x2中读取1字节的数据 */ -ret = SdioReadBytesFromFunc0(handle, &rbuff, 0x2, 1); -if (ret != 0) { - HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret); -} -``` - -## 释放SDIO中断 - -通信完成之后,需要释放SDIO中断,函数如下所示: - -int32\_t SdioReleaseIrq\(DevHandle handle\); - -**表 11** SdioReleaseIrq函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

返回值

-

返回值描述

-

0

-

释放SDIO中断成功

-

负数

-

释放SDIO中断失败

-
- -释放SDIO中断的示例如下: - -``` -int32_t ret; -/* 释放SDIO中断 */ -ret = SdioReleaseIrq(handle); -if (ret != 0) { - HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret); -} -``` - -## 去使能SDIO设备 - -通信完成之后,还需要去使能SDIO设备,函数如下所示: - -int32\_t SdioDisableFunc\(DevHandle handle\); - -**表 12** SdioDisableFunc函数的参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-

返回值

-

返回值描述

-

0

-

去使能SDIO设备成功

-

负数

-

去使能SDIO设备失败

-
- -去使能SDIO设备的示例如下: - -``` -int32_t ret; -/* 去使能SDIO设备 */ -ret = SdioDisableFunc(handle); -if (ret != 0) { - HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret); -} -``` - -## 释放HOST - -通信完成之后,还需要释放去HOST,函数如下所示: - -void SdioReleaseHost\(DevHandle handle\); - -**表 13** SdioReleaseHost函数的参数描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-
- -释放HOST的示例如下: - -``` -SdioReleaseHost(handle); /* 释放HOST */ -``` - -## 关闭SDIO控制器 - -SDIO通信完成之后,最后需要关闭SDIO控制器,函数如下所示: - -void SdioClose\(DevHandle handle\); - -该函数会释放掉申请的资源。 - -**表 14** SdioClose函数的参数描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SDIO控制器的设备句柄

-
- -关闭SDIO控制器的示例如下: - -``` -SdioClose(handle); /* 关闭SDIO控制器 */ -``` - diff --git "a/zh-cn/device-dev/driver/SDIO\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/SDIO\346\246\202\350\277\260.md" deleted file mode 100755 index 69b74874472f27c6f3d737e8383f80708ae654a7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SDIO\346\246\202\350\277\260.md" +++ /dev/null @@ -1,149 +0,0 @@ -# SDIO概述 - -- [简介](#section1155271783811) -- [接口说明](#section10204143763819) - -## 简介 - -- SDIO是安全数字输入输出接口(Secure Digital Input and Output)的缩写,是从SD内存卡接口的基础上演化出来的一种外设接口。SDIO接口兼容以前的SD内存卡,并且可以连接支持SDIO接口的设备。 -- SDIO的应用比较广泛,目前,有许多手机都支持SDIO功能,并且很多SDIO外设也被开发出来,使得手机外接外设更加容易。常见的SDIO外设有WLAN、GPS、CAMERA、蓝牙等。 -- SDIO总线有两端,其中一端是主机端(HOST),另一端是设备端(DEVICE)。所有的通信都是由HOST端发出命令开始的,在DEVICE端只要能解析HOST的命令,就可以同HOST进行通信了。SDIO的HOST可以连接多个DEVICE,如下图所示: - - - CLK信号:HOST给DEVICE的时钟信号。 - - VDD信号:电源信号。 - - VSS信号:Ground信号。 - - D0-3信号:4条数据线,其中,DAT1信号线复用为中断线,在1BIT模式下DAT0用来传输数据,在4BIT模式下DAT0-DAT3用来传输数据。 - - CMD信号:用于HOST发送命令和DEVICE回复响应。 - - **图 1** SDIO的HOST-DEVICE连接示意图 - - - ![](figures/zh-cn_image_0000001054280608.png) - -- SDIO接口定义了操作SDIO的通用方法集合,包括打开/关闭SDIO控制器、独占/释放HOST、使能/去使能设备、申请/释放中断、读写、获取/设置公共信息等。 - -## 接口说明 - -**表 1** SDIO驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

SDIO设备打开/关闭接口

-

SdioOpen

-

打开指定总线号的SDIO控制器

-

SdioClose

-

关闭SDIO控制器

-

SDIO读写接口

-

SdioReadBytes

-

从指定地址开始,增量读取指定长度的数据

-

SdioWriteBytes

-

从指定地址开始,增量写入指定长度的数据

-

SdioReadBytesFromFixedAddr

-

从固定地址读取指定长度的数据

-

SdioWriteBytesToFixedAddr

-

向固定地址写入指定长度的数据

-

SdioReadBytesFromFunc0

-

从SDIO function 0的指定地址空间读取指定长度的数据

-

SdioWriteBytesToFunc0

-

向SDIO function 0的指定地址空间写入指定长度的数据

-

SDIO设置块大小接口

-

SdioSetBlockSize

-

设置块的大小

-

SDIO获取/设置公共信息接口

-

SdioGetCommonInfo

-

获取公共信息

-

SdioSetCommonInfo

-

设置公共信息

-

SDIO刷新数据接口

-

SdioFlushData

-

刷新数据

-

SDIO独占/释放HOST接口

-

SdioClaimHost

-

独占Host

-

SdioReleaseHost

-

释放Host

-

SDIO使能/去使能功能设备接口

-

SdioEnableFunc

-

使能SDIO功能设备

-

SdioDisableFunc

-

去使能SDIO功能设备

-

SDIO申请/释放中断接口

-

SdioClaimIrq

-

申请中断

-

SdioReleaseIrq

-

释放中断

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,目前只支持在内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/SENSOR.md b/zh-cn/device-dev/driver/SENSOR.md index 5907809028cf4b2f14cf484c96adbd8c25a57db2..956f7307bbb0d12677d581ce310cce1b898c7260 100755 --- a/zh-cn/device-dev/driver/SENSOR.md +++ b/zh-cn/device-dev/driver/SENSOR.md @@ -1,11 +1,929 @@ -# SENSOR +# SENSOR -- **[传感器驱动开发概述](传感器驱动开发概述.md)** +- [概述](#section3634112111) + - [接口说明](#section188213414114) -- **[传感器驱动开发指导](传感器驱动开发指导.md)** +- [开发指导](#section1140943382) + - [开发步骤](#section7893102915819) -- **[传感器驱动开发实例](传感器驱动开发实例.md)** +- [开发实例](#section257750691) +- [测试指导](#section106021256121219) -- **[传感器驱动测试指导](传感器驱动测试指导.md)** +## 概述 +Sensor(传感器)驱动模块为上层Sensor服务系统提供稳定的Sensor基础能力API,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置等功能;基于HDF(**H**ardware **D**river **F**oundation)驱动框架开发的Sensor驱动模型,实现跨操作系统迁移,器件差异配置等功能。Sensor驱动模型如下图1所示: + +**图 1** Sensor驱动模型图 +![](figures/Sensor驱动模型图.png "Sensor驱动模型图") + +Sensor驱动模型对外开放的API接口能力如下: + +- 提供Sensor HDI(**H**ardware **D**river **I**nterface)能力接口,简化服务开发。 +- 提供Sensor驱动模型能力接口:依赖HDF驱动框架实现Sensor器件驱动的注册,加载,去注册,器件探测等能力,提供同一类型Sensor器件驱动归一接口, 寄存器配置解析操作接口,总线访问抽象接口,平台抽象接口。 +- 提供开发者实现的能力接口:依赖HDF驱动框架的HCS\(**H**DF **C**onfiguration **S**ource\)配置管理,根据同类型Sensor差异化配置,实现Sensor器件参数序列化配置和器件部分操作接口,简化Sensor器件驱动开发。 + +### 接口说明 + +Sensor驱动模型对HDI开放的API接口功能,参考表1。 + +**表 1** Sensor驱动模型对外API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

功能描述

+

查询操作

+

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

+

获取系统中注册的所有传感器信息,一种类型传感器信息包括传感器名字、设备厂商、固件版本号、硬件版本号、传感器类型编号、传感器标识、最大量程、精度、功耗。

+

配置操作

+

int32_t Enable(int32_t sensorId)

+

使能一种传感器设备,只有数据订阅者使能传感器后,才能获取订阅的传感器数据。

+

int32_t Disable(int32_t sensorId)

+

去使能一种传感器设备。

+

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

+

设置一种传感器的数据采样间隔和数据上报间隔。

+

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

+

设置一种传感器的工作模式,不同的工作模式,上报数据方式不同。

+

int32_t SetOption(int32_t sensorId, uint32_t option)

+

设置一种传感器量程,精度等可选配置。

+

数据订阅操作

+

int32_t Register(RecordDataCallback cb)

+

订阅者注册传感器数据回调函数,系统会将获取到的传感器数据上报给订阅者。

+

int32_t Unregister(void)

+

订阅者去注册传感器数据回调函数。

+

接口实例

+

const struct SensorInterface *NewSensorInterfaceInstance(void)

+

创建传感器接口实例。

+

int32_t FreeSensorInterfaceInstance(void)

+

释放传感器接口实例。

+
+ +Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无需实现,直接使用,参考表2: + +**表 2** Sensor驱动模型对驱动开发者开放的功能接口列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

功能描述

+

设备管理操作接口

+

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

+

添加当前类型的传感器设备到传感器设备管理。

+

int32_t DeleteSensorDevice(int32_t sensorId)

+

删除传感器设备管理里指定的传感器设备。

+

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

+

上报指定类型传感器的数据到用户侧。

+

Sensor抽象总线和平台操作接口

+

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

+

按照配置的总线方式,读取传感器寄存器配置数据。

+

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

+

按照配置的总线方式,传感器配置数据写入寄存器。

+

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

+

创建指定传感器的定时线程,用于传感器数据上报处理。

+

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

+

销毁传感器创建的定时线程。

+

通用配置操作接口

+

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

+

根据传感器总线类型信息,下发寄存器分组配置。

+

配置解析操作接口

+

+

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

+

根据传感器设备HCS资源配置,获取传感器信息,总线配置信息,属性配置等基本配置信息,并初始化对应的基本配置数据结构体。

+

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

+

根据传感器设备HCS资源配置,解析寄存器分组信息,并初始化配置数据结构体。

+

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

+

释放传感器配置数据结构体里分配的资源。

+

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

+

获取传感器总线句柄信息。

+

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

+

释放传感器句柄信息。

+
+ +Sensor驱动模型要求驱动开发者实现的接口功能,参考表3 + +**表 3** Sensor驱动模型要求驱动开发者实现的接口列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

功能描述

+

基本功能操作

+

int32_t init(void)

+

传感器器设备探测成功后,需要对传感器器设备初始化配置。

+

int32_t GetInfo(struct SensorBasicInfo *info)

+

从传感器器设备的HCS配置里,获取当前传感器设备的基本信息。

+

int32_t Enable(void)

+

根据当前传感器器设备的HCS配置,下发传感器设备使能操作组的寄存器配置。

+

int32_t Disable(void)

+

根据当前传感器器设备的HCS配置,下发传感器设备去使能操作组的寄存器配置。

+

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

+

根据数据采样率和数据上报间隔,配置当前传感器设备的数据上报线程处理时间。

+

int32_t SetMode(int32_t mode)

+

配置当前传感器设备数据上报方式。

+

int32_t SetOption(uint32_t option)

+

根据可选配置,下发量程,精度等寄存器配置。

+

void ReadSensorData(void)

+

实现传感器的数据读取函数。

+
+ +接口实现参考[SENSOR](#section257750691)章节。 + +## 开发指导 + +Sensor驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同Sensor器件提供统一的驱动模型。本篇开发指导以加速度计传感器为例,介绍传感器驱动开发。 + +### 开发步骤 + +1. 加速度计传感器驱动注册。HDF驱动框架会提供统一的驱动管理模型,通过加速计传感器模块配置信息,识别并加载对应模块驱动。 +2. 加速度计传感器驱动初始化和去初始化。HDF驱动框架通过init入口函数,依次启动传感器设备驱动加载和分配传感器设备数据配置资源。HDF驱动框架通过release函数,释放驱动加载的资源和配置。 +3. 加速度计传感器寄存器组配置解析。不同类型传感器需要在hcs里配置器件对应的HCS配置文件,然后再设备驱动启动过程中探测器件是否在位,然后加载对应的配置文件,生成配置的结构体对象。 +4. 加速度计传感器驱动操作接口实现。实现各个类型传感器归一化驱动接口,如init,GetInfo,Enable,Disable,SetBatch,SetMode,SetOption,ReadSensorData等函数,完成传感器驱动配置下发和数据上报功能。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>传感器驱动模型已经提供一部分能力集,包括驱动设备管理能力,抽象总线和平台操作接口能力,通用配置操作接口能力,配置解析操作接口能力,接口参考[表2](#table1156812588320)。需要开发人员实现部分有:1、传感器部分操作接口([表3](#table1083014911336));2、传感器HCS差异化数据配置;3、驱动基本功能验证。 + +## 开发实例 + +基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](驱动开发.md)。加速度传感器选择通讯接口方式为I2C,厂家选择博世BMI160加速度传感器。 + +1. 加速度计传感器驱动入口注册 + +- 加速度计传感器驱动入口函数实现 + +``` +/* 注册加速度计传感器入口数据结构体对象 */ +struct HdfDriverEntry g_sensorAccelDevEntry = { + .moduleVersion = 1, /* 加速度计传感器模块版本号 */ + .moduleName = "HDF_SENSOR_ACCEL", /* 加速度计传感器模块名,要与device_info.hcs文件里的加速度计moduleName字段值一样*/ + .Bind = BindAccelDriver, /* 加速度计传感器绑定函数 */ + .Init = InitAccelDriver, /* 加速度计传感器初始化函数 */ + .Release = ReleaseAccelDriver, /* 加速度计传感器资源释放函数 */ +}; + +/* 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 */ +HDF_INIT(g_sensorAccelDevEntry); +``` + +- 加速度计传感器设备配置描述 + +加速度传感器模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](配置管理.md)介绍。 + +``` +/* 加速度计传感器设备HCS配置 */ +device_sensor_accel :: device { + device0 :: deviceNode { + policy = 1; /* policy字段是驱动服务发布的策略 */ + priority = 105; /* 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */ + preload = 2; /* 驱动按需加载字段,0表示加载,2表示不加载 */ + permission = 0664; /* 驱动创建设备节点权限 */ + moduleName = "HDF_SENSOR_ACCEL"; /* 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */ + serviceName = "sensor_accel"; /* 驱动对外发布服务的名称,必须唯一 */ + deviceMatchAttr = "hdf_sensor_accel_driver"; /* 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 */ + } +} +``` + +1. 加速度计传感器驱动初始化和去初始化 + +- 初始化入口函数init + +``` +/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */ +int32_t BindAccelDriver(struct HdfDeviceObject *device) +{ + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + + static struct IDeviceIoService service = { + .object = {0}, + .Dispatch = DispatchAccel, + }; + device->service = &service; + + return HDF_SUCCESS; +} +/*在探测到器件在位后,需要调用RegisterAccelChipOps注册差异化适配函数*/ +int32_t RegisterAccelChipOps(struct AccelOpsCall *ops) +{ + struct AccelDrvData *drvData = NULL; + + CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); + + drvData = AccelGetDrvData(); + drvData->ops.Init = ops->Init; + drvData->ops.ReadData = ops->ReadData; + return HDF_SUCCESS; +} +/* 挂载加速度计传感器驱动归一化的接口函数 */ +static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo) +{ + struct AccelDrvData *drvData = AccelGetDrvData(); + + (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); + deviceInfo->ops.GetInfo = SetAccelInfo; + deviceInfo->ops.Enable = SetAccelEnable; + deviceInfo->ops.Disable = SetAccelDisable; + deviceInfo->ops.SetBatch = SetAccelBatch; + deviceInfo->ops.SetMode = SetAccelMode; + deviceInfo->ops.SetOption = SetAccelOption; + + if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), + &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) { + HDF_LOGE("%s: copy sensor info failed", __func__); + return HDF_FAILURE; + } + /* 传感器类型标识可以在数据HCS配置文件里面配置,也可以在此处 */ + drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER; + drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER; + + return HDF_SUCCESS; +} +/* 传感器寄存器初始化操作 */ +static int32_t InitAccelAfterConfig(void) +{ + struct SensorDeviceInfo deviceInfo; + + if (InitAccelConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel config failed", __func__); + return HDF_FAILURE; + } + + if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: init accel ops failed", __func__); + return HDF_FAILURE; + } + + if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: add accel device failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} +/*通过器件探测函数,挂载器件差异化函数接口*/ +static int32_t DetectAccelChip(void) +{ + int32_t num; + int32_t ret; + int32_t loop; + struct AccelDrvData *drvData = AccelGetDrvData(); + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]); + for (loop = 0; loop < num; ++loop) { + if (g_accelDetectIfList[loop].DetectChip != NULL) { + ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg); + if (ret == HDF_SUCCESS) { + drvData->detectFlag = true; + break; + } + } + } + + if (loop == num) { + HDF_LOGE("%s: detect accel device failed", __func__); + drvData->detectFlag = false; + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +/* 加速度计传感器驱动初始化入口函数,主要功能为对传感器私有数据的结构体对象进行初始化,传感器HCS数据配置对象空间分配,传感器HCS数据配置初始化入口函数调用,传感器设备探测是否在位功能,传感器数据上报定时器创建,传感器归一化接口挂载,传感器设备注册功能 */ +int32_t InitAccelDriver(struct HdfDeviceObject *device) +{ + /* 获取传感器私有数据结构体对象 */ + struct AccelDrvData *drvData = AccelGetDrvData(); + + /* 同类型传感器不同厂家设备探测时,判断此类型传感器是否已经在位,若已经在位,无需再继续探测,直接返回 */ + if (drvData->detectFlag) { + HDF_LOGE("%s: accel sensor have detected", __func__); + return HDF_SUCCESS; + } + + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + /* 分配存放传感器数据配置的私有结构体数据对象,需要在驱动释放时释放分配的资源空间 */ + drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg)); + if (drvData->accelCfg == NULL) { + HDF_LOGE("%s: malloc sensor config data failed", __func__); + return HDF_FAILURE; + } + + drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; + /* 初始化传感器配置数据主要是解析传感器通讯总线配置类型信息,传感器基本信息,传感器属性信息,传感器是否在位信息,寄存器分组信息 */ + if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: get sensor base config failed", __func__); + goto Base_CONFIG_EXIT; + } + + if (DetectAccelChip() != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor detect device no exist", __func__); + goto DETECT_CHIP_EXIT; + } + drvData->detectFlag = true; + if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: detect sensor device failed", __func__); + goto REG_CONFIG_EXIT; + } + + if (InitAccelAfterConfig() != HDF_SUCCESS) { + HDF_LOGE("%s: init accel after config failed", __func__); + goto INIT_EXIT; + } + + HDF_LOGI("%s: init accel driver success", __func__); + return HDF_SUCCESS; + +INIT_EXIT: + DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); +REG_CONFIG_EXIT: + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); +DETECT_CHIP_EXIT: + drvData->detectFlag = false; +BASE_CONFIG_EXIT: + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + return HDF_FAILURE; +} + +/* 释放驱动初始化时分配的资源 */ +void ReleaseAccelDriver(struct HdfDeviceObject *device) +{ + (void)device; + struct AccelDrvData *drvData = NULL; + + drvData = AccelGetDrvData(); + (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus); + (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); + drvData->detectFlag = false; + + if (drvData->accelCfg != NULL) { + drvData->accelCfg->root = NULL; + drvData->accelCfg->regCfgGroup = NULL; + ReleaseSensorAllRegConfig(drvData->accelCfg); + (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + } + + drvData->initStatus = false; +} +``` + +1. 加速度计传感器寄存器组配置信息 + +加速度计传感器数据配置只需要按照模板配置即可,基于模板配置的解析功能已经在**InitSensorConfigData**函数完成,只需初始化时调用即可。如果有新增配置项,需要同步修改此函数。 + +``` +加速度传感器数据配置模板(accel_config.hcs) +root { + sensorAccelConfig { + accelChipConfig { + /* 传感器设备信息模板 */ + template sensorInfo { + sensorName = "accelerometer"; /* 加速度计名字,字符最大长度16字节 */ + vendorName = "borsh_bmi160"; /* 传感器设备厂商,字符最大长度16字节 */ + firmwareVersion = "1.0"; /* 传感器固件版本号,默认1.0,字符最大长度16字节 */ + hardwareVersion = "1.0"; /* 传感器硬件版本号,默认1.0,字符最大长度16字节 */ + sensorTypeId = 1; /* 传感器类型编号,详见{@link SensorTypeTag} */ + sensorId = 1; /* 传感器的标识号,有传感器驱动开发者定义,推荐用{@link SensorTypeTag}枚举 */ + maxRange = 8; /* 传感器的最大量程,根据开发者需要配置 */ + precision = 0; /* 传感器的精度,与上报数据配合使用,上报数据结构体{@link SensorEvents } */ + power = 230; /* 传感器的功耗 */ + } + /* 传感器使用的总线类型和配置信息模板 */ + template sensorBusConfig { + busType = 0; /* 0:i2c 1:spi */ + busNum = 6; /* 芯片上分配给传感器的器件号 */ + busAddr = 0; /* 芯片上分配给传感器的地址 */ + regWidth = 1; /* 传感器寄存器地址宽度 */ + regBigEndian = 0; /* 传感器寄存器大小端 */ + } + /* 传感器设备属性模板 */ + template sensorAttr { + chipName = ""; /* 传感器芯片名字 */ + chipIdRegister = 0xf; /* 传感器在位检测寄存器地址 */ + chipIdValue = 0xd1; /* 校验传感器在位检测寄存器值 */ + } + } + } +} + +/* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */ +root { + sensorAccelConfig { + accel_bmi160_chip_config : accelChipConfig { + match_attr = "hdf_sensor_accel_driver"; /* 需要和加速度传感器设备配置match_attr字段保持一致 */ + accelInfo :: sensorInfo { + vendorName = "borsh_bmi160"; + sensorTypeId = 1; + sensorId = 1; + } + accelBusConfig :: sensorBusConfig { + busType = 0; /* i2c通讯方式 */ + busNum = 6; + busAddr = 0x68; + regWidth = 1; /* 1字节位宽 */ + } + accelAttr :: sensorAttr { + chipName = "bmi160"; + chipIdRegister = 0x00; + chipIdValue = 0xd1; + } + accelRegConfig { + /* regAddr: 寄存器地址 + value: 寄存器值 + mask: 寄存器值的掩码 + len: 寄存器值的数据长度(字节) + delay: 配置寄存器延时(ms) + opsType:操作类型 0-无 1-读 2-写 3-读并检查 4-位更新 + calType: 计算类型 0-无 1-写 2-取反 3-异或 4-左移 5-右移 + shiftNum: 移动位数 + debug: 调试开关,0-调试关闭 1-调试打开 + save: 保存数据开关,0-不保存数据 1-保存数据 + */ + /* 传感器寄存器操作分组,按照分组进行有序配置 */ + /* 寄存器地址, 寄存器值, 寄存器值的掩码, 寄存器值的数据长度, 配置寄存器延时, 操作类型, 计算类型, 移动位数, 调试开关, 保存开关 */ + /* 初始化寄存器组 */ + initSeqConfig = [ + 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + /* 使能寄存器组 */ + enableSeqConfig = [ + 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0, + 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0, + 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0 + ]; + /* 去使能寄存器组 */ + disableSeqConfig = [ + 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 + ]; + } + } + } +} +``` + +1. 加速度计传感器驱动操作接口实现 + +开发者需要根据每种类型的传感器实现归一化接口。 + +``` +/* 不使用函数暂时置空 */ +static int32_t SetAccelInfo(struct SensorBasicInfo *info) +{ + (void)info; + + return HDF_ERR_NOT_SUPPORT; +} +/* 下发使能寄存器组的配置 */ +static int32_t SetAccelEnable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_RUNNING; + + return HDF_SUCCESS; +} +/* 下发去使能寄存器组的配置 */ +static int32_t SetAccelDisable(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); + + ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel sensor disable config failed", __func__); + return HDF_FAILURE; + } + + drvData->threadStatus = SENSOR_THREAD_STOPPED; + + return HDF_SUCCESS; +} +/* 配置传感器采样率和数据上报间隔 */ +static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval) +{ + (void)interval; + + struct AccelDrvData *drvData = AccelGetDrvData(); + drvData->interval = samplingInterval; + + return HDF_SUCCESS; +} +/* 设置传感器工作模式,当前支持实时模式 */ +static int32_t SetAccelMode(int32_t mode) +{ + return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE; +} +/* 设置传感器可选配置 */ +static int32_t SetAccelOption(uint32_t option) +{ + (void)option; + return HDF_ERR_NOT_SUPPORT; +} +``` + +- 差异化处理接口 + + ``` + /* 器件探测时,如果探测成功,则注册差异化处理函数到accel驱动模型里 */ + int32_t DetectAccelBim160Chip(struct SensorCfgData *data) + { + int32_t ret; + struct AccelOpsCall ops; + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + + if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) { + return HDF_SUCCESS; + } + ret = InitAccelPreConfig(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: init BMI160 bus mux config", __func__); + return HDF_FAILURE; + } + if (DetectSensorDevice(data) != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* 差异化处理函数 */ + ops.Init = InitBmi160; + ops.ReadData = ReadBmi160Data; + ret = RegisterAccelChipOps(&ops); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: register BMI160 accel failed", __func__); + (void)ReleaseSensorBusHandle(&data->busCfg); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* 初始化处理函数 */ + static int32_t InitBmi160(struct SensorCfgData *data) + { + int32_t ret; + + CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: bmi160 sensor init config failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + /* 数据处理函数 */ + int32_t ReadBmi160Data(struct SensorCfgData *data) + { + int32_t ret; + struct AccelData rawData = { 0, 0, 0 }; + int32_t tmp[ACCEL_AXIS_NUM]; + struct SensorReportEvent event; + + (void)memset_s(&event, sizeof(event), 0, sizeof(event)); + + ret = ReadBmi160RawData(data, &rawData, &event.timestamp); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + event.sensorId = SENSOR_TAG_ACCELEROMETER; + event.option = 0; + event.mode = SENSOR_WORK_MODE_REALTIME; + + rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G; + rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G; + rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G; + + tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; + + event.dataLen = sizeof(tmp); + event.data = (uint8_t *)&tmp; + ret = ReportSensorEvent(&event); + return ret; + } + ``` + +- 数据处理函数 + +创建传感器定时器,按照配置的采样率定时采样,并上报给数据订阅者。 + +``` +/* 传感器定时工作线程 */ +static int32_t ReadAccelDataThreadWorker(void *arg) +{ + (void)arg; + int64_t interval; + struct AccelDrvData *drvData = AccelGetDrvData(); + + drvData->threadStatus = SENSOR_THREAD_START; + while (true) { + if (drvData->threadStatus == SENSOR_THREAD_RUNNING) { + if (drvData->ops.ReadData != NULL) { + (void)drvData->ops.ReadData(drvData->accelCfg); + } + interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT)); + OsalMSleep(interval); + } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) { + break; + } else { + OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT); + } + + if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) { + continue; + } + } + + return HDF_SUCCESS; +} +/* 创建传感器定时器和器件初始化 */ +static int32_t InitAccelConfig(void) +{ + int32_t ret; + struct AccelDrvData *drvData = AccelGetDrvData(); + + if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) { + HDF_LOGE("%s: accel thread have created", __func__); + return HDF_SUCCESS; + } + + ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + + CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM); + + ret = drvData->ops.Init(drvData->accelCfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: accel create thread failed", __func__); + drvData->threadStatus = SENSOR_THREAD_NONE; + return HDF_FAILURE; + } + drvData->initStatus = true; + return HDF_SUCCESS; +} +``` + +- 主要的数据结构 + +``` +/* 传感器转换单位*/ +#define SENSOR_CONVERT_UNIT 1000 +#define SENSOR_1K_UNIT 1024 +/* 传感器2g对应灵敏度转换值 */ +#define BMI160_ACC_SENSITIVITY_2G 61 +/* 传感器数据采样寄存器地址 */ +#define BMI160_ACCEL_X_LSB_ADDR 0X12 +#define BMI160_ACCEL_X_MSB_ADDR 0X13 +#define BMI160_ACCEL_Y_LSB_ADDR 0X14 +#define BMI160_ACCEL_Y_MSB_ADDR 0X15 +#define BMI160_ACCEL_Z_LSB_ADDR 0X16 +#define BMI160_ACCEL_Z_MSB_ADDR 0X17 +/* 传感器数据维度 */ +enum AccelAxisNum { + ACCEL_X_AXIS = 0, + ACCEL_Y_AXIS = 1, + ACCEL_Z_AXIS = 2, + ACCEL_AXIS_NUM = 3, +}; +/* 传感器每个维度值 */ +struct AccelData { + int32_t x; + int32_t y; + int32_t z; +}; +/* 传感器私有数据结构体 */ +struct AccelDrvData { + bool detectFlag; + uint8_t threadStatus; + uint8_t initStatus; + int64_t interval; + struct SensorCfgData *accelCfg; + struct OsalThread thread; + struct AccelOpsCall ops; +}; +/* 差异化适配函数 */ +struct AccelOpsCall { + int32_t (*Init)(struct SensorCfgData *data); + int32_t (*ReadData)(struct SensorCfgData *data); +}; +``` + +## 测试指导 + +驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 + +``` +/* 标识是否上报传感器数据 */ +static int32_t g_sensorDataFlag = 0; +/* 保持获取的传感器接口实例地址 */ +static const struct SensorInterface *g_sensorDev = nullptr; + +/* 订阅者注册数据上报函数 */ +static int SensorTestDataCallback(struct SensorEvents *event) +{ + if (event == nullptr) { + return -1; + } + float *data = (float*)event->data; + printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, + event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); + if (*data > 1e-5) { + g_sensorDataFlag = 1; + } + return 0; +} +/* 用例执行前,初始化传感器接口实例 */ +void HdfSensorTest::SetUpTestCase() +{ + g_sensorDev = NewSensorInterfaceInstance(); + if (g_sensorDev == nullptr) { + printf("test sensorHdi get Module instace failed\n\r"); + } +} +/* 用例资源释放 */ +void HdfSensorTest::TearDownTestCase() +{ + if (g_sensorDev != nullptr) { + FreeSensorInterfaceInstance(); + g_sensorDev = nullptr; + } +} +/* 传感器驱动测试验证 */ +HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) +{ + int32_t sensorInterval = 1000000000; /* 数据采样率单位纳秒 */ + int32_t pollTime = 5; /* 数据采样时间单位秒 */ + int32_t accelSensorId = 1; /* 加速度传感器类型标识为1 */ + int32_t count = 0; + int ret; + struct SensorInformation *sensorInfo = nullptr; + + ret = g_sensorDev->Register(SensorTestDataCallback) + EXPECT_EQ(SENSOR_NULL_PTR, ret); + + ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); + EXPECT_EQ(0, ret); + if (sensorInfo == nullptr) { + EXPECT_NE(nullptr, sensorInfo); + return; + } + /* 打印获取的传感器列表 */ + for (int i = 0; i < count; i++) { + printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); + } + ret = g_sensorDev->Enable(accelSensorId); + EXPECT_EQ(0, ret); + g_sensorDataFlag = 0; + + ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); + EXPECT_EQ(0, ret); + /* 在时间pollTime内,观察输出打印数据 */ + OsalSleep(pollTime); + EXPECT_EQ(1, g_sensorDataFlag); + + ret = g_sensorDev->Disable(accelSensorId); + g_sensorDataFlag = 0; + EXPECT_EQ(0, ret); + + ret = g_sensorDev->Unregister(); + EXPECT_EQ(0, ret); +} +``` diff --git a/zh-cn/device-dev/driver/SPI.md b/zh-cn/device-dev/driver/SPI.md index 394692a78397c81a270b1cc0e5e944c4837336ab..52ef61ad5b6c8bdf7ca1092a2f6bbb4b450626f9 100755 --- a/zh-cn/device-dev/driver/SPI.md +++ b/zh-cn/device-dev/driver/SPI.md @@ -1,9 +1,566 @@ -# SPI +# SPI -- **[SPI概述](SPI概述.md)** +- [概述](#section193356154511) + - [接口说明](#section232141411476) -- **[SPI使用指导](SPI使用指导.md)** +- [使用指导](#section71363452477) + - [使用流程](#section32846814820) + - [获取SPI设备句柄](#section1927265711481) + - [获取SPI设备属性](#section541133418493) + - [配置SPI设备属性](#section7870106145010) + - [进行SPI通信](#section13324155195013) + - [销毁SPI设备句柄](#section19661632135117) -- **[SPI使用实例](SPI使用实例.md)** +- [使用实例](#section06541058155120) +## 概述 + +- SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线。 +- SPI是由Motorola公司开发,用于在主设备和从设备之间进行通信,常用于与闪存、实时时钟、传感器以及模数转换器等进行通信。 +- SPI以主从方式工作,通常有一个主设备和一个或者多个从设备。主设备和从设备之间一般用4根线相连,它们分别是: + - SCLK – 时钟信号,由主设备产生; + - MOSI – 主设备数据输出,从设备数据输入; + - MISO – 主设备数据输入,从设备数据输出; + - CS – 片选,从设备使能信号,由主设备控制。 + + +- 一个主设备和两个从设备的连接示意图如[图1](#fig15227181812587)所示,Device A和Device B共享主设备的SCLK、MISO和MOSI三根引脚,Device A的片选CS0连接主设备的CS0,Device B的片选CS1连接主设备的CS1。 + +**图 1** SPI主从设备连接示意图。 + + +![](figures/zh-cn_image_0000001123742254.png) + +- SPI通信通常由主设备发起,通过以下步骤完成一次通信: + +1. 通过CS选中要通信的从设备,在任意时刻,一个主设备上最多只能有一个从设备被选中。 +2. 通过SCLK给选中的从设备提供时钟信号。 +3. 基于SCLK时钟信号,主设备数据通过MOSI发送给从设备,同时通过MISO接收从设备发送的数据,完成通信。 + +- 根据SCLK时钟信号的CPOL(Clock Polarity,时钟极性)和CPHA(Clock Phase,时钟相位)的不同组合,SPI有以下四种工作模式: + - CPOL=0,CPHA=0 时钟信号idle状态为低电平,第一个时钟边沿采样数据。 + - CPOL=0,CPHA=1 时钟信号idle状态为低电平,第二个时钟边沿采样数据。 + - CPOL=1,CPHA=0 时钟信号idle状态为高电平,第一个时钟边沿采样数据。 + - CPOL=1,CPHA=1 时钟信号idle状态为高电平,第二个时钟边沿采样数据。 + + +- SPI接口定义了操作SPI设备的通用方法集合,包括: + - SPI设备句柄获取和释放。 + - SPI读写: 从SPI设备读取或写入指定长度数据。 + - SPI自定义传输:通过消息传输结构体执行任意读写组合过程。 + - SPI设备配置:获取和设置SPI设备属性。 + + +>![](public_sys-resources/icon-note.gif) **说明:** +>当前只支持主机模式,不支持从机模式。 + +### 接口说明 + +**表 1** SPI驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

SPI设备句柄获取释放接口

+

SpiOpen

+

获取SPI设备句柄

+

SpiClose

+

释放SPI设备句柄

+

SPI读写接口

+

SpiRead

+

读取指定长度的数据

+

SpiWrite

+

写入指定长度的数据

+

SpiTransfer

+

SPI数据传输接口

+

SPI设备配置接口

+

+

SpiSetCfg

+

根据指定参数,配置SPI设备

+

SpiGetCfg

+

获取SPI设备配置参数

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用SPI的一般流程如[图2](#fig23885455594)所示。 + +**图 2** SPI使用流程图 + + +![](figures/zh-cn_image_0000001123703482.png) + +### 获取SPI设备句柄 + +在使用SPI进行通信时,首先要调用SpiOpen获取SPI设备句柄,该函数会返回指定总线号和片选号的SPI设备句柄。 + +DevHandle SpiOpen\(const struct SpiDevInfo \*info\); + +**表 2** SpiOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

info

+

SPI设备描述符

+

返回值

+

返回值描述

+

NULL

+

获取SPI设备句柄失败

+

设备句柄

+

对应的SPI设备句柄

+
+ +假设系统中的SPI设备总线号为0,片选号为0,获取该SPI设备句柄的示例如下: + +``` +struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ +DevHandle spiHandle = NULL; /* SPI设备句柄 */ +spiDevinfo.busNum = 0; /* SPI设备总线号 */ +spiDevinfo.csNum = 0; /* SPI设备片选号 */ + +/* 获取SPI设备句柄 */ +spiHandle = SpiOpen(&spiDevinfo); +if (spiHandle == NULL) { + HDF_LOGE("SpiOpen: failed\n"); + return; +} +``` + +### 获取SPI设备属性 + +在获取到SPI设备句柄之后,需要配置SPI设备属性。配置SPI设备属性之前,可以先获取SPI设备属性,获取SPI设备属性的函数如下所示: + +int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\); + +**表 3** SpiGetCfg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

cfg

+

SPI设备配置参数

+

返回值

+

返回值描述

+

0

+

获取配置成功

+

负数

+

获取配置失败

+
+ +``` +int32_t ret; +struct SpiCfg cfg = {0}; /* SPI配置信息*/ +ret = SpiGetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ +if (ret != 0) { + HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); +} +``` + +### 配置SPI设备属性 + +在获取到SPI设备句柄之后,需要配置SPI设备属性,配置SPI设备属性的函数如下所示: + +int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\); + +**表 4** SpiSetCfg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

cfg

+

SPI设备配置参数

+

返回值

+

返回值描述

+

0

+

配置成功

+

负数

+

配置失败

+
+ +``` +int32_t ret; +struct SpiCfg cfg = {0}; /* SPI配置信息*/ +cfg.mode = SPI_MODE_LOOP; /* 以回环模式进行通信 */ +cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* 以轮询的方式进行通信 */ +cfg.maxSpeedHz = 115200; /* 最大传输频率 */ +cfg.bitsPerWord = 8; /* 读写位宽为8个比特 */ +ret = SpiSetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ +if (ret != 0) { + HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); +} +``` + +### 进行SPI通信 + +- 向SPI设备写入指定长度的数据 + +如果只向SPI设备写一次数据,则可以通过以下函数完成: + +int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); + +**表 5** SpiWrite参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

buf

+

待写入数据的指针

+

len

+

待写入的数据长度

+

返回值

+

返回值描述

+

0

+

写入成功

+

负数

+

写入失败

+
+ +``` +int32_t ret; +uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78}; +/* 向SPI设备写入指定长度的数据 */ +ret = SpiWrite(spiHandle, wbuff, 4); +if (ret != 0) { + HDF_LOGE("SpiWrite: failed, ret %d\n", ret); +} +``` + +- 从SPI设备读取指定长度的数据 + +如果只读取一次数据,则可以通过以下函数完成: + +int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); + +**表 6** SpiRead参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

buf

+

待读取数据的指针

+

len

+

待读取的数据长度

+

返回值

+

返回值描述

+

0

+

读取成功

+

负数

+

读取失败

+
+ +``` +int32_t ret; +uint8_t rbuff[4] = {0}; +/* 从SPI设备读取指定长度的数据 */ +ret = SpiRead(spiHandle, rbuff, 4); +if (ret != 0) { + HDF_LOGE("SpiRead: failed, ret %d\n", ret); +} +``` + +- 自定义传输 + +如果需要发起一次自定义传输,则可以通过以下函数完成: + +int32\_t SpiTransfer\(DevHandle handle, struct SpiMsg \*msgs, uint32\_t count\); + +**表 7** SpiTransfer参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+

msgs

+

待传输数据的数组

+

count

+

msgs数组长度

+

返回值

+

返回值描述

+

0

+

执行成功

+

负数

+

执行失败

+
+ +``` +int32_t ret; +uint8_t wbuff[1] = {0x12}; +uint8_t rbuff[1] = {0}; +struct SpiMsg msg; /* 自定义传输的消息*/ +msg.wbuf = wbuff; /* 写入的数据 */ +msg.rbuf = rbuff; /* 读取的数据 */ +msg.len = 1; /* 读取、写入数据的长度都是1 */ +msg.csChange = 1; /* 进行下一次传输前关闭片选 */ +msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ +msg.speed = 115200; /* 本次传输的速度 */ +/* 进行一次自定义传输,传输的msg个数为1 */ +ret = SpiTransfer(spiHandle, &msg, 1); +if (ret != 0) { + HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); +} +``` + +### 销毁SPI设备句柄 + +SPI通信完成之后,需要销毁SPI设备句柄,销毁SPI设备句柄的函数如下所示: + +void SpiClose\(DevHandle handle\); + +该函数会释放掉申请的资源。 + +**表 8** SpiClose参数描述 + + + + + + + + + +

参数

+

参数描述

+

handle

+

SPI设备句柄

+
+ +``` +SpiClose(spiHandle); /* 销毁SPI设备句柄 */ +``` + +## 使用实例 + +SPI设备完整的使用示例如下所示,首先获取SPI设备句柄,然后配置SPI设备属性,接着调用读写接口进行数据传输,最后销毁SPI设备句柄。 + +``` +#include "hdf_log.h" +#include "spi_if.h" + +void SpiTestSample(void) +{ + int32_t ret; + struct SpiCfg cfg; /* SPI配置信息 */ + struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ + DevHandle spiHandle = NULL; /* SPI设备句柄 */ + struct SpiMsg msg; /* 自定义传输的消息 */ + uint8_t rbuff[4] = { 0 }; + uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; + uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; + + spiDevinfo.busNum = 0; /* SPI设备总线号 */ + spiDevinfo.csNum = 0; /* SPI设备片选号 */ + spiHandle = SpiOpen(&spiDevinfo); /* 根据spiDevinfo获取SPI设备句柄 */ + if (spiHandle == NULL) { + HDF_LOGE("SpiOpen: failed\n"); + return; + } + /* 获取SPI设备属性 */ + ret = SpiGetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); + goto err; + } + cfg.maxSpeedHz = 115200; /* 将最大时钟频率改为115200 */ + cfg.bitsPerWord = 8; /* 传输位宽改为8比特 */ + /* 配置SPI设备属性 */ + ret = SpiSetCfg(spiHandle, &cfg); + if (ret != 0) { + HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); + goto err; + } + /* 向SPI设备写入指定长度的数据 */ + ret = SpiWrite(spiHandle, wbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiWrite: failed, ret %d\n", ret); + goto err; + } + /* 从SPI设备读取指定长度的数据 */ + ret = SpiRead(spiHandle, rbuff, 4); + if (ret != 0) { + HDF_LOGE("SpiRead: failed, ret %d\n", ret); + goto err; + } + msg.wbuf = wbuff2; /* 写入的数据 */ + msg.rbuf = rbuff; /* 读取的数据 */ + msg.len = 4; /* 读取写入数据的长度为4 */ + msg.csChange = 1; /* 进行下一次传输前关闭片选 */ + msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ + msg.speed = 115200; /* 本次传输的速度 */ + /* 进行一次自定义传输,传输的msg个数为1 */ + ret = SpiTransfer(spiHandle, &msg, 1); + if (ret != 0) { + HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); + goto err; + } +err: + /* 销毁SPI设备句柄 */ + SpiClose(spiHandle); +} +``` diff --git "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index 4c3a6280301b448fad37b861d0028fd737ef2f82..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,70 +0,0 @@ -# SPI使用实例 - -SPI设备完整的使用示例如下所示,首先获取SPI设备句柄,然后配置SPI设备属性,接着调用读写接口进行数据传输,最后销毁SPI设备句柄。 - -``` -#include "hdf_log.h" -#include "spi_if.h" - -void SpiTestSample(void) -{ - int32_t ret; - struct SpiCfg cfg; /* SPI配置信息 */ - struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ - DevHandle spiHandle = NULL; /* SPI设备句柄 */ - struct SpiMsg msg; /* 自定义传输的消息 */ - uint8_t rbuff[4] = { 0 }; - uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; - uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; - - spiDevinfo.busNum = 0; /* SPI设备总线号 */ - spiDevinfo.csNum = 0; /* SPI设备片选号 */ - spiHandle = SpiOpen(&spiDevinfo); /* 根据spiDevinfo获取SPI设备句柄 */ - if (spiHandle == NULL) { - HDF_LOGE("SpiOpen: failed\n"); - return; - } - /* 获取SPI设备属性 */ - ret = SpiGetCfg(spiHandle, &cfg); - if (ret != 0) { - HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); - goto err; - } - cfg.maxSpeedHz = 115200; /* 将最大时钟频率改为115200 */ - cfg.bitsPerWord = 8; /* 传输位宽改为8比特 */ - /* 配置SPI设备属性 */ - ret = SpiSetCfg(spiHandle, &cfg); - if (ret != 0) { - HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); - goto err; - } - /* 向SPI设备写入指定长度的数据 */ - ret = SpiWrite(spiHandle, wbuff, 4); - if (ret != 0) { - HDF_LOGE("SpiWrite: failed, ret %d\n", ret); - goto err; - } - /* 从SPI设备读取指定长度的数据 */ - ret = SpiRead(spiHandle, rbuff, 4); - if (ret != 0) { - HDF_LOGE("SpiRead: failed, ret %d\n", ret); - goto err; - } - msg.wbuf = wbuff2; /* 写入的数据 */ - msg.rbuf = rbuff; /* 读取的数据 */ - msg.len = 4; /* 读取写入数据的长度为4 */ - msg.csChange = 1; /* 进行下一次传输前关闭片选 */ - msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ - msg.speed = 115200; /* 本次传输的速度 */ - /* 进行一次自定义传输,传输的msg个数为1 */ - ret = SpiTransfer(spiHandle, &msg, 1); - if (ret != 0) { - HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); - goto err; - } -err: - /* 销毁SPI设备句柄 */ - SpiClose(spiHandle); -} -``` - diff --git "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 58698a9460cefc157fd27f41bfb3978a1547fdfc..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SPI\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,386 +0,0 @@ -# SPI使用指导 - -- [使用流程](#section691514116412) -- [获取SPI设备句柄](#section12372204616215) -- [获取SPI设备属性](#section17121446171311) -- [配置SPI设备属性](#section97691946634) -- [进行SPI通信](#section197116254416) -- [销毁SPI设备句柄](#section117661819108) - -## 使用流程 - -使用SPI的一般流程如[图1](#fig23885455594)所示。 - -**图 1** SPI使用流程图 - - -![](figures/zh-cn_image_0000001054726248.png) - -## 获取SPI设备句柄 - -在使用SPI进行通信时,首先要调用SpiOpen获取SPI设备句柄,该函数会返回指定总线号和片选号的SPI设备句柄。 - -DevHandle SpiOpen\(const struct SpiDevInfo \*info\); - -**表 1** SpiOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

info

-

SPI设备描述符

-

返回值

-

返回值描述

-

NULL

-

获取SPI设备句柄失败

-

设备句柄

-

对应的SPI设备句柄

-
- -假设系统中的SPI设备总线号为0,片选号为0,获取该SPI设备句柄的示例如下: - -``` -struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */ -DevHandle spiHandle = NULL; /* SPI设备句柄 */ -spiDevinfo.busNum = 0; /* SPI设备总线号 */ -spiDevinfo.csNum = 0; /* SPI设备片选号 */ - -/* 获取SPI设备句柄 */ -spiHandle = SpiOpen(&spiDevinfo); -if (spiHandle == NULL) { - HDF_LOGE("SpiOpen: failed\n"); - return; -} -``` - -## 获取SPI设备属性 - -在获取到SPI设备句柄之后,需要配置SPI设备属性。配置SPI设备属性之前,可以先获取SPI设备属性,获取SPI设备属性的函数如下所示: - -int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\); - -**表 2** SpiGetCfg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

cfg

-

SPI设备配置参数

-

返回值

-

返回值描述

-

0

-

获取配置成功

-

负数

-

获取配置失败

-
- -``` -int32_t ret; -struct SpiCfg cfg = {0}; /* SPI配置信息*/ -ret = SpiGetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ -if (ret != 0) { - HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); -} -``` - -## 配置SPI设备属性 - -在获取到SPI设备句柄之后,需要配置SPI设备属性,配置SPI设备属性的函数如下所示: - -int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\); - -**表 3** SpiSetCfg参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

cfg

-

SPI设备配置参数

-

返回值

-

返回值描述

-

0

-

配置成功

-

负数

-

配置失败

-
- -``` -int32_t ret; -struct SpiCfg cfg = {0}; /* SPI配置信息*/ -cfg.mode = SPI_MODE_LOOP; /* 以回环模式进行通信 */ -cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* 以轮询的方式进行通信 */ -cfg.maxSpeedHz = 115200; /* 最大传输频率 */ -cfg.bitsPerWord = 8; /* 读写位宽为8个比特 */ -ret = SpiSetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ -if (ret != 0) { - HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); -} -``` - -## 进行SPI通信 - -- 向SPI设备写入指定长度的数据 - -如果只向SPI设备写一次数据,则可以通过以下函数完成: - -int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); - -**表 4** SpiWrite参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

buf

-

待写入数据的指针

-

len

-

待写入的数据长度

-

返回值

-

返回值描述

-

0

-

写入成功

-

负数

-

写入失败

-
- -``` -int32_t ret; -uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78}; -/* 向SPI设备写入指定长度的数据 */ -ret = SpiWrite(spiHandle, wbuff, 4); -if (ret != 0) { - HDF_LOGE("SpiWrite: failed, ret %d\n", ret); -} -``` - -- 从SPI设备读取指定长度的数据 - -如果只读取一次数据,则可以通过以下函数完成: - -int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\); - -**表 5** SpiRead参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

buf

-

待读取数据的指针

-

len

-

待读取的数据长度

-

返回值

-

返回值描述

-

0

-

读取成功

-

负数

-

读取失败

-
- -``` -int32_t ret; -uint8_t rbuff[4] = {0}; -/* 从SPI设备读取指定长度的数据 */ -ret = SpiRead(spiHandle, rbuff, 4); -if (ret != 0) { - HDF_LOGE("SpiRead: failed, ret %d\n", ret); -} -``` - -- 自定义传输 - -如果需要发起一次自定义传输,则可以通过以下函数完成: - -int32\_t SpiTransfer\(DevHandle handle, struct SpiMsg \*msgs, uint32\_t count\); - -**表 6** SpiTransfer参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-

msgs

-

待传输数据的数组

-

count

-

msgs数组长度

-

返回值

-

返回值描述

-

0

-

执行成功

-

负数

-

执行失败

-
- -``` -int32_t ret; -uint8_t wbuff[1] = {0x12}; -uint8_t rbuff[1] = {0}; -struct SpiMsg msg; /* 自定义传输的消息*/ -msg.wbuf = wbuff; /* 写入的数据 */ -msg.rbuf = rbuff; /* 读取的数据 */ -msg.len = 1; /* 读取、写入数据的长度都是1 */ -msg.csChange = 1; /* 进行下一次传输前关闭片选 */ -msg.delayUs = 0; /* 进行下一次传输前不进行延时 */ -msg.speed = 115200; /* 本次传输的速度 */ -/* 进行一次自定义传输,传输的msg个数为1 */ -ret = SpiTransfer(spiHandle, &msg, 1); -if (ret != 0) { - HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); -} -``` - -## 销毁SPI设备句柄 - -SPI通信完成之后,需要销毁SPI设备句柄,销毁SPI设备句柄的函数如下所示: - -void SpiClose\(DevHandle handle\); - -该函数会释放掉申请的资源。 - -**表 7** SpiClose参数描述 - - - - - - - - - -

参数

-

参数描述

-

handle

-

SPI设备句柄

-
- -``` -SpiClose(spiHandle); /* 销毁SPI设备句柄 */ -``` - diff --git "a/zh-cn/device-dev/driver/SPI\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/SPI\346\246\202\350\277\260.md" deleted file mode 100755 index 3d3567489af059b7a5f56b8e072bdab95e190eab..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/SPI\346\246\202\350\277\260.md" +++ /dev/null @@ -1,107 +0,0 @@ -# SPI概述 - -- [简介](#section9202632114011) -- [接口说明](#section1859594134119) - -## 简介 - -- SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线。 -- SPI是由Motorola公司开发,用于在主设备和从设备之间进行通信,常用于与闪存、实时时钟、传感器以及模数转换器等进行通信。 -- SPI以主从方式工作,通常有一个主设备和一个或者多个从设备。主设备和从设备之间一般用4根线相连,它们分别是: - - SCLK – 时钟信号,由主设备产生; - - MOSI – 主设备数据输出,从设备数据输入; - - MISO – 主设备数据输入,从设备数据输出; - - CS – 片选,从设备使能信号,由主设备控制。 - - -- 一个主设备和两个从设备的连接示意图如[图1](#fig15227181812587)所示,Device A和Device B共享主设备的SCLK、MISO和MOSI三根引脚,Device A的片选CS0连接主设备的CS0,Device B的片选CS1连接主设备的CS1。 - -**图 1** SPI主从设备连接示意图。 - - -![](figures/zh-cn_image_0000001054142582.png) - -- SPI通信通常由主设备发起,通过以下步骤完成一次通信: - -1. 通过CS选中要通信的从设备,在任意时刻,一个主设备上最多只能有一个从设备被选中。 -2. 通过SCLK给选中的从设备提供时钟信号。 -3. 基于SCLK时钟信号,主设备数据通过MOSI发送给从设备,同时通过MISO接收从设备发送的数据,完成通信。 - -- 根据SCLK时钟信号的CPOL(Clock Polarity,时钟极性)和CPHA(Clock Phase,时钟相位)的不同组合,SPI有以下四种工作模式: - - CPOL=0,CPHA=0 时钟信号idle状态为低电平,第一个时钟边沿采样数据。 - - CPOL=0,CPHA=1 时钟信号idle状态为低电平,第二个时钟边沿采样数据。 - - CPOL=1,CPHA=0 时钟信号idle状态为高电平,第一个时钟边沿采样数据。 - - CPOL=1,CPHA=1 时钟信号idle状态为高电平,第二个时钟边沿采样数据。 - - -- SPI接口定义了操作SPI设备的通用方法集合,包括: - - SPI设备句柄获取和释放。 - - SPI读写: 从SPI设备读取或写入指定长度数据。 - - SPI自定义传输:通过消息传输结构体执行任意读写组合过程。 - - SPI设备配置:获取和设置SPI设备属性。 - - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前只支持主机模式,不支持从机模式。 - -## 接口说明 - -**表 1** SPI驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

SPI设备句柄获取释放接口

-

SpiOpen

-

获取SPI设备句柄

-

SpiClose

-

释放SPI设备句柄

-

SPI读写接口

-

SpiRead

-

读取指定长度的数据

-

SpiWrite

-

写入指定长度的数据

-

SpiTransfer

-

SPI数据传输接口

-

SPI设备配置接口

-

-

SpiSetCfg

-

根据指定参数,配置SPI设备

-

SpiGetCfg

-

获取SPI设备配置参数

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/TOUCHSCREEN.md b/zh-cn/device-dev/driver/TOUCHSCREEN.md index ce5156c848cb3b1ae5403caeb17ae4d9714baadb..f49a1fb198110bdadbf07f0ef048a66bf25efc94 100755 --- a/zh-cn/device-dev/driver/TOUCHSCREEN.md +++ b/zh-cn/device-dev/driver/TOUCHSCREEN.md @@ -1,9 +1,410 @@ -# TOUCHSCREEN +# TOUCHSCREEN -- **[Touchscreen开发概述](Touchscreen开发概述.md)** +- [概述](#section175431838101617) + - [接口说明](#section17667171301711) -- **[Touchscreen开发指导](Touchscreen开发指导.md)** +- [开发指导](#section65745222184) + - [开发步骤](#section865734181916) -- **[Touchscreen开发实例](Touchscreen开发实例.md)** +- [开发实例](#section263714411191) + - [设备描述配置](#section18249155619195) + - [板级配置及器件私有配置](#section3571192072014) + - [添加器件驱动](#section6356758162015) +## 概述 + +- **Touchscreen驱动主要任务** + + Touchscreen驱动用于驱动触摸屏使其正常工作,该驱动主要完成如下工作:对触摸屏驱动IC进行上电、配置硬件管脚并初始化其状态、注册中断、配置通信接口(I2C或SPI)、设定input相关配置、下载及更新固件等操作。 + + +- **Touchscreen驱动层次说明** + + 本节主要介绍基于input驱动模型开发touchscreen器件驱动,其整体的框架模型如[图1](#fig6251184817261)。 + + Input驱动模型基于HDF驱动框架、PLATFORM接口、OSAL接口进行开发,向上对接规范化的驱动接口HDI(Hardware Driver Interface)层,通过Input-HDI层对外提供硬件能力,即上层input service可以通过HDI接口层获取相应的驱动能力,进而操控touchscreen等输入设备。 + + +**图 1** 基于HDF驱动框架的input驱动模型 +![](figures/基于HDF驱动框架的input驱动模型.png "基于HDF驱动框架的input驱动模型") + +- **Input驱动模型介绍** + + Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。器件产生的数据借助平台数据通道能力从内核传递到用户态,驱动模型通过配置文件适配不同器件及硬件平台,提高开发者的器件驱动开发效率。如下部分为模型各部分的说明: + + (1)input设备管理:为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; + + (2)input平台驱动:指各类input设备的公共抽象驱动(例如触摸屏的公共驱动),负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; + + (3)input器件驱动:指各器件厂家的差异化驱动,通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; + + (4)input数据通道:提供一套通用的数据上报通道,各类别的input设备驱动均可用此通道上报input事件; + + (5)input配置解析:负责对input设备的板级配置及器件私有配置进行解析及管理。 + + +- **基于HDF驱动框架开发器件驱动的优势** + + 在HDF(Hardware Driver Foundation)[驱动管理框架](驱动开发.md)的基础上,input驱动模型调用OSAL接口层和Platfom接口层提供的基础接口进行开发,包括bus通信接口、操作系统原生接口(memory、lock、thread、timer等)。由于OSAL接口和Platform接口屏蔽了芯片平台差异,所以基于input驱动模型实现的touchscreen驱动可以进行跨平台、跨OS迁移,以便逐步实现驱动的一次开发,多端部署。 + + +### 接口说明 + +Touchscreen器件的硬件接口相对简单,根据PIN脚的属性,可以简单分为如下三类: + +- 电源接口 +- IO控制接口 +- 通信接口 + +**图 2** Touchscreen器件常用管脚 +![](figures/Touchscreen器件常用管脚.png "Touchscreen器件常用管脚") + +如上图所示的三类接口,分别做简要说明如下: + +1. **电源接口** + - LDO\_1P8:1.8v数字电路 + - LDO\_3P3:3.3v模拟电路 + + 通常情况下,touchscreen驱动IC和LCD驱动IC是相互分离的,这种情况下,touchscreen驱动IC一般同时需要1.8v和3.3v两路供电。随着芯片演进,业内已有touchscreen驱动IC和LCD驱动IC集成在一颗IC中的芯片案例,对touchscreen而言,只需要关注1.8v供电即可,其内部需要的3.3v电源,会在驱动IC内部从LCD的VSP电源(典型值5.5V)中分出来。 + + +2. **IO控制接口** + - Reset:reset管脚,用于在系统休眠、唤醒时,由主机侧对驱动IC进行复位操作。 + - INT:中断管脚,需要在驱动初始化时,配置为输入上拉状态。在驱动IC检测到外部触摸信号后,通过操作中断管脚来触发中断,器件驱动则会在中断处理函数中进行报点数据读取等操作。 + +3. **通信接口** + - I2C:由于touchscreen的报点数据量相对较少,所以一般选用I2C方式传输数据。I2C的具体协议及对应操作接口,可以参考Platform接口层中的[“I2C”使用指南](I2C.md#section1695201514281)。 + - SPI:部分厂商,由于需要传递的数据不止报点坐标,而是需要获取基础容值,数据量较大,所以会选用SPI通信方式。SPI的具体协议及对应操作接口,可以参考Platform接口层中的[“SPI” 使用指南](SPI.md#section71363452477)。 + + +## 开发指导 + +Input驱动模型是基于HDF框架、Platform接口和OSAL接口开发,不区分操作系统和芯片平台,为touchscreen等输入器件提供统一的驱动开发架构。 + +- 如下以touchscreen器件驱动为例,说明input驱动模型的完整加载流程: + + (1)设备描述配置:由开发者参考已有模板进行设备描述配置,包括驱动加载顺序、板级硬件信息、器件私有数据信息等。 + + (2)加载input设备管理驱动:input设备管理驱动由HDF驱动加载,完成设备manager的创建并对其初始化。 + + (3)加载平台驱动:平台驱动由HDF框架加载,主要完成板级配置解析及硬件初始化,并提供器件注册接口。 + + (4)加载器件驱动:器件驱动也由HDF框架加载,完成器件设备的实例化,包括器件私有配置解析和平台预留的差异化接口适配。 + + (5)器件设备向平台驱动注册:将实例化的器件设备向平台驱动注册,实现设备和驱动的绑定,并完成中断注册、上下电等器件初始化工作。 + + (6)input设备注册:在器件初始化完成后,实例化input设备,并将其注册到input manager进行管理。 + + +### 开发步骤 + +1. 设备描述配置 + + 目前Input驱动基于HDF驱动框架编写,驱动的加载启动由HDF驱动管理框架统一处理。首先需要在对应的配置文件中,将驱动信息注册进去,如是否加载、加载优先级,此后HDF驱动框架会逐一启动注册过的驱动模块。驱动的相关配置请参考[HDF驱动框架配置指导](驱动开发.md#section1969312275533)。 + +2. 板级配置及Touchscreen器件私有配置 + + 配置对应的IO管脚功能,例如对单板上为touchscreen设计预留的I2C Pin脚,需设置对应的寄存器,使其选择I2C的通信功能。 + +3. 实现器件差异化适配接口 + + 根据硬件单板设计的通信接口,使用Platform接口层提供的管脚操作接口配置对应的复位管脚、中断管脚以及电源操作,对于GPIO的操作,可参考[GPIO操作接口指导](GPIO.md#section259614242196) + + +## 开发实例 + +本实例提供touchscreen驱动开发示例,并简要对具体关键点进行开发说明。 + +### 设备描述配置 + +如下配置主要包含input驱动模型各模块层级信息,具体原理可参考[HDF驱动开发指南](驱动开发.md),HDF框架依据该配置信息实现对Input模型各模块的依次加载等。 + +``` +input :: host { + hostName = "input_host"; + priority = 100; + device_input_manager :: device { + device0 :: deviceNode { + policy = 2; // 向外发布服务 + priority = 100; // 加载优先级,在input模块内,manager模块优先级应为最高 + preload = 0; // 加载该驱动 0:加载 1:不加载 + permission = 0660; + moduleName = "HDF_INPUT_MANAGER"; + serviceName = "input_dev_manager"; + deviceMatchAttr = ""; + } + } + device_hdf_touch :: device { + device0 :: deviceNode { + policy = 2; + priority = 120; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH"; + serviceName = "event1"; + deviceMatchAttr = "touch_device1"; + } + } + + device_touch_chip :: device { + device0 :: deviceNode { + policy = 0; + priority = 130; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH_SAMPLE"; + serviceName = "hdf_touch_sample_service"; + deviceMatchAttr = "zsj_sample_5p5"; + } + } +} +``` + +### 板级配置及器件私有配置 + +如下配置包含板级硬件配置及器件私有数据配置,实际业务开发时,可根据具体需求增删及修改如下配置文件信息。 + +``` +root { + input_config { + touchConfig { + touch0 { + boardConfig { + match_attr = "touch_device1"; + inputAttr { + inputType = 0; // 0代表触摸屏 + solutionX = 480; + solutionY = 960; + devName = "main_touch"; // 设备名称 + } + busConfig { + busType = 0; // 0代表I2C + busNum = 6; + clkGpio = 86; + dataGpio = 87; + i2cClkIomux = [0x114f0048, 0x403]; // i2c_clk对应pin的寄存器配置 + i2cDataIomux = [0x114f004c, 0x403]; // i2c_data对应pin的寄存器配置 + } + pinConfig { + rstGpio = 3; + intGpio = 4; + rstRegCfg = [0x112f0094, 0x400]; // reset对应pin的寄存器配置 + intRegCfg = [0x112f0098, 0x400]; // interrupt对应pin的寄存器配置 + } + powerConfig { + vccType = 2; // 1代表LDO、2代表GPIO、3代表PMIC + vccNum = 20; // GPIO号为20 + vccValue = 1800; // 电压幅值为1800mV + vciType = 1; + vciNum = 12; + vciValue = 3300; + } + featureConfig { + capacitanceTest = 0; + gestureMode = 0; + gloverMOde = 0; + coverMode = 0; + chargerMode = 0; + knuckleMode = 0; + } + } + chipConfig { + template touchChip { + match_attr = ""; + chipName = "sample"; + vendorName = "zsj"; + chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 + busType = 0; + deviceAddr = 0x5D; + irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 + maxSpeed = 400; + chipVersion = 0; + powerSequence { + /* 上电时序的配置含义说明: + [类型, 状态, 方向 , 延时] + 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 + 0代表下电或拉低,1代表上电或拉高,2代表无操作 + 0代表输入方向,1代表输出方向,2代表无操作 + 代表延时多少毫秒, 例如20代表延时20ms + */ + powerOnSeq = [4, 0, 1, 0, + 3, 0, 1, 10, + 3, 1, 2, 60, + 4, 2, 0, 0]; + suspendSeq = [3, 0, 2, 10]; + resumeSeq = [3, 1, 2, 10]; + powerOffSeq = [3, 0, 2, 10, + 1, 0, 2, 20]; + } + } + chip0 :: touchChip { + match_attr = "zsj_sample_5p5"; + chipInfo = "ZIDN45100"; + chipVersion = 0; + } + } + } + } + } +} +``` + +### 添加器件驱动 + +在器件驱动中,主要实现了平台预留的差异化接口,以器件数据获取及解析进行示例说明。具体开发过程,需要根据实际使用的单板及器件进行适配。 + +``` +/* 将从器件中读取到的报点数据解析为坐标 */ +static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) +{ + int32_t resX = device->driver->boardCfg->attr.resolutionX; + int32_t resY = device->driver->boardCfg->attr.resolutionY; + + for (int32_t i = 0; i < pointNum; i++) { + frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].valid = true; + } +} +/* 从器件中获取报点数据 */ +static int32_t ChipDataHandle(ChipDevice *device) +{ + int32_t ret; + uint8_t touchStatus = 0; + uint8_t pointNum; + uint8_t buf[GT_POINT_SIZE * MAX_SUPPORT_POINT] = {0}; + InputI2cClient *i2cClient = &device->driver->i2cClient; + uint8_t reg[GT_ADDR_LEN] = {0}; + FrameData *frame = &device->driver->frameData; + reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; + ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); + if (ret < 0 || touchStatus == GT_EVENT_INVALID) { + return HDF_FAILURE; + } + OsalMutexLock(&device->driver->mutex); + (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData)); + if (touchStatus == GT_EVENT_UP) { + frame->realPointNum = 0; + frame->definedEvent = TOUCH_UP; + goto exit; + } + reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; + pointNum = touchStatus & GT_FINGER_NUM_MASK; + if (pointNum <= 0 || pointNum > MAX_SUPPORT_POINT) { + HDF_LOGE("%s: pointNum is invalid, %d", __func__, pointNum); + (void)ChipCleanBuffer(i2cClient); + OsalMutexUnlock(&device->driver->mutex); + return HDF_FAILURE; + } + frame->realPointNum = pointNum; + frame->definedEvent = TOUCH_DOWN; + /* 从寄存器中读取报点值 */ + (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); + /* 解析报点值 */ + ParsePointData(device, frame, buf, pointNum); +exit: + OsalMutexUnlock(&device->driver->mutex); + if (ChipCleanBuffer(i2cClient) != HDF_SUCCESS) { + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static struct TouchChipOps g_sampleChipOps = { + .Init = ChipInit, + .Detect = ChipDetect, + .Resume = ChipResume, + .Suspend = ChipSuspend, + .DataHandle = ChipDataHandle, +}; + +static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device) +{ + TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg)); + if (chipCfg == NULL) { + HDF_LOGE("%s: instance chip config failed", __func__); + return NULL; + } + (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg)); + /* 解析器件私有配置 */ + if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) { + HDF_LOGE("%s: parse chip config failed", __func__); + OsalMemFree(chipCfg); + chipCfg = NULL; + } + return chipCfg; +} + +static ChipDevice *ChipDeviceInstance(void) +{ + ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice)); + if (chipDev == NULL) { + HDF_LOGE("%s: instance chip device failed", __func__); + return NULL; + } + (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice)); + return chipDev; +} + +static void FreeChipConfig(TouchChipCfg *config) +{ + if (config->pwrSeq.pwrOn.buf != NULL) { + OsalMemFree(config->pwrSeq.pwrOn.buf); + } + if (config->pwrSeq.pwrOff.buf != NULL) { + OsalMemFree(config->pwrSeq.pwrOff.buf); + } + OsalMemFree(config); +} + +static int32_t HdfSampleChipInit(struct HdfDeviceObject *device) +{ + TouchChipCfg *chipCfg = NULL; + ChipDevice *chipDev = NULL; + HDF_LOGE("%s: enter", __func__); + if (device == NULL) { + return HDF_ERR_INVALID_PARAM; + } + /* 器件私有配置解析 */ + chipCfg = ChipConfigInstance(device); + if (chipCfg == NULL) { + return HDF_ERR_MALLOC_FAIL; + } + /* 器件设备实例化 */ + chipDev = ChipDeviceInstance(); + if (chipDev == NULL) { + goto freeCfg; + } + chipDev->chipCfg = chipCfg; + chipDev->ops = &g_sampleChipOps; + chipDev->chipName = chipCfg->chipName; + chipDev->vendorName = chipCfg->vendorName; + + /* 器件设备注册到平台驱动 */ + if (RegisterChipDevice(chipDev) != HDF_SUCCESS) { + goto freeDev; + } + HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName); + return HDF_SUCCESS; + +freeDev: + OsalMemFree(chipDev); +freeCfg: + FreeChipConfig(chipCfg); + return HDF_FAILURE; +} + +struct HdfDriverEntry g_touchSampleChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_SAMPLE", + .Init = HdfSampleChipInit, +}; + +HDF_INIT(g_touchSampleChipEntry); +``` + diff --git "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index a298d618c1547f7c66c6213a42563b3896ac80b2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,300 +0,0 @@ -# Touchscreen开发实例 - -- [设备描述配置](#section85281142102317) -- [板级配置及器件私有配置](#section189081946192410) -- [添加器件驱动](#section19856687253) - -本实例提供touchscreen驱动开发示例,并简要对具体关键点进行开发说明。 - -## 设备描述配置 - -如下配置主要包含input驱动模型各模块层级信息,具体原理可参考[HDF驱动开发指南](驱动开发.md),HDF框架依据该配置信息实现对Input模型各模块的依次加载等。 - -``` -input :: host { - hostName = "input_host"; - priority = 100; - device_input_manager :: device { - device0 :: deviceNode { - policy = 2; // 向外发布服务 - priority = 100; // 加载优先级,在input模块内,manager模块优先级应为最高 - preload = 0; // 加载该驱动 0:加载 1:不加载 - permission = 0660; - moduleName = "HDF_INPUT_MANAGER"; - serviceName = "input_dev_manager"; - deviceMatchAttr = ""; - } - } - device_hdf_touch :: device { - device0 :: deviceNode { - policy = 2; - priority = 120; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH"; - serviceName = "event1"; - deviceMatchAttr = "touch_device1"; - } - } - - device_touch_chip :: device { - device0 :: deviceNode { - policy = 0; - priority = 130; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH_SAMPLE"; - serviceName = "hdf_touch_sample_service"; - deviceMatchAttr = "zsj_sample_5p5"; - } - } -} -``` - -## 板级配置及器件私有配置 - -如下配置包含板级硬件配置及器件私有数据配置,实际业务开发时,可根据具体需求增删及修改如下配置文件信息。 - -``` -root { - input_config { - touchConfig { - touch0 { - boardConfig { - match_attr = "touch_device1"; - inputAttr { - inputType = 0; // 0代表触摸屏 - solutionX = 480; - solutionY = 960; - devName = "main_touch"; // 设备名称 - } - busConfig { - busType = 0; // 0代表I2C - busNum = 6; - clkGpio = 86; - dataGpio = 87; - i2cClkIomux = [0x114f0048, 0x403]; // i2c_clk对应pin的寄存器配置 - i2cDataIomux = [0x114f004c, 0x403]; // i2c_data对应pin的寄存器配置 - } - pinConfig { - rstGpio = 3; - intGpio = 4; - rstRegCfg = [0x112f0094, 0x400]; // reset对应pin的寄存器配置 - intRegCfg = [0x112f0098, 0x400]; // interrupt对应pin的寄存器配置 - } - powerConfig { - vccType = 2; // 1代表LDO、2代表GPIO、3代表PMIC - vccNum = 20; // GPIO号为20 - vccValue = 1800; // 电压幅值为1800mV - vciType = 1; - vciNum = 12; - vciValue = 3300; - } - featureConfig { - capacitanceTest = 0; - gestureMode = 0; - gloverMOde = 0; - coverMode = 0; - chargerMode = 0; - knuckleMode = 0; - } - } - chipConfig { - template touchChip { - match_attr = ""; - chipName = "sample"; - vendorName = "zsj"; - chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 - busType = 0; - deviceAddr = 0x5D; - irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 - maxSpeed = 400; - chipVersion = 0; - powerSequence { - /* 上电时序的配置含义说明: - [类型, 状态, 方向 , 延时] - 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 - 0代表下电或拉低,1代表上电或拉高,2代表无操作 - 0代表输入方向,1代表输出方向,2代表无操作 - 代表延时多少毫秒, 例如20代表延时20ms - */ - powerOnSeq = [4, 0, 1, 0, - 3, 0, 1, 10, - 3, 1, 2, 60, - 4, 2, 0, 0]; - suspendSeq = [3, 0, 2, 10]; - resumeSeq = [3, 1, 2, 10]; - powerOffSeq = [3, 0, 2, 10, - 1, 0, 2, 20]; - } - } - chip0 :: touchChip { - match_attr = "zsj_sample_5p5"; - chipInfo = "ZIDN45100"; - chipVersion = 0; - } - } - } - } - } -} -``` - -## 添加器件驱动 - -在器件驱动中,主要实现了平台预留的差异化接口,以器件数据获取及解析进行示例说明。具体开发过程,需要根据实际使用的单板及器件进行适配。 - -``` -/* 将从器件中读取到的报点数据解析为坐标 */ -static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) -{ - int32_t resX = device->driver->boardCfg->attr.resolutionX; - int32_t resY = device->driver->boardCfg->attr.resolutionY; - - for (int32_t i = 0; i < pointNum; i++) { - frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].valid = true; - } -} -/* 从器件中获取报点数据 */ -static int32_t ChipDataHandle(ChipDevice *device) -{ - int32_t ret; - uint8_t touchStatus = 0; - uint8_t pointNum; - uint8_t buf[GT_POINT_SIZE * MAX_SUPPORT_POINT] = {0}; - InputI2cClient *i2cClient = &device->driver->i2cClient; - uint8_t reg[GT_ADDR_LEN] = {0}; - FrameData *frame = &device->driver->frameData; - reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; - ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); - if (ret < 0 || touchStatus == GT_EVENT_INVALID) { - return HDF_FAILURE; - } - OsalMutexLock(&device->driver->mutex); - (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData)); - if (touchStatus == GT_EVENT_UP) { - frame->realPointNum = 0; - frame->definedEvent = TOUCH_UP; - goto exit; - } - reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; - pointNum = touchStatus & GT_FINGER_NUM_MASK; - if (pointNum <= 0 || pointNum > MAX_SUPPORT_POINT) { - HDF_LOGE("%s: pointNum is invalid, %d", __func__, pointNum); - (void)ChipCleanBuffer(i2cClient); - OsalMutexUnlock(&device->driver->mutex); - return HDF_FAILURE; - } - frame->realPointNum = pointNum; - frame->definedEvent = TOUCH_DOWN; - /* 从寄存器中读取报点值 */ - (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); - /* 解析报点值 */ - ParsePointData(device, frame, buf, pointNum); -exit: - OsalMutexUnlock(&device->driver->mutex); - if (ChipCleanBuffer(i2cClient) != HDF_SUCCESS) { - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -static struct TouchChipOps g_sampleChipOps = { - .Init = ChipInit, - .Detect = ChipDetect, - .Resume = ChipResume, - .Suspend = ChipSuspend, - .DataHandle = ChipDataHandle, -}; - -static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device) -{ - TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg)); - if (chipCfg == NULL) { - HDF_LOGE("%s: instance chip config failed", __func__); - return NULL; - } - (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg)); - /* 解析器件私有配置 */ - if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: parse chip config failed", __func__); - OsalMemFree(chipCfg); - chipCfg = NULL; - } - return chipCfg; -} - -static ChipDevice *ChipDeviceInstance(void) -{ - ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice)); - if (chipDev == NULL) { - HDF_LOGE("%s: instance chip device failed", __func__); - return NULL; - } - (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice)); - return chipDev; -} - -static void FreeChipConfig(TouchChipCfg *config) -{ - if (config->pwrSeq.pwrOn.buf != NULL) { - OsalMemFree(config->pwrSeq.pwrOn.buf); - } - if (config->pwrSeq.pwrOff.buf != NULL) { - OsalMemFree(config->pwrSeq.pwrOff.buf); - } - OsalMemFree(config); -} - -static int32_t HdfSampleChipInit(struct HdfDeviceObject *device) -{ - TouchChipCfg *chipCfg = NULL; - ChipDevice *chipDev = NULL; - HDF_LOGE("%s: enter", __func__); - if (device == NULL) { - return HDF_ERR_INVALID_PARAM; - } - /* 器件私有配置解析 */ - chipCfg = ChipConfigInstance(device); - if (chipCfg == NULL) { - return HDF_ERR_MALLOC_FAIL; - } - /* 器件设备实例化 */ - chipDev = ChipDeviceInstance(); - if (chipDev == NULL) { - goto freeCfg; - } - chipDev->chipCfg = chipCfg; - chipDev->ops = &g_sampleChipOps; - chipDev->chipName = chipCfg->chipName; - chipDev->vendorName = chipCfg->vendorName; - - /* 器件设备注册到平台驱动 */ - if (RegisterChipDevice(chipDev) != HDF_SUCCESS) { - goto freeDev; - } - HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName); - return HDF_SUCCESS; - -freeDev: - OsalMemFree(chipDev); -freeCfg: - FreeChipConfig(chipCfg); - return HDF_FAILURE; -} - -struct HdfDriverEntry g_touchSampleChipEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH_SAMPLE", - .Init = HdfSampleChipInit, -}; - -HDF_INIT(g_touchSampleChipEntry); -``` - diff --git "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 09dc518533e0397fd75711d33a582a7520c5af39..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,36 +0,0 @@ -# Touchscreen开发指导 - -- [开发步骤](#section1255740132616) - -Input驱动模型是基于HDF框架、Platform接口和OSAL接口开发,不区分操作系统和芯片平台,为touchscreen等输入器件提供统一的驱动开发架构。 - -- 如下以touchscreen器件驱动为例,说明input驱动模型的完整加载流程: - - (1)设备描述配置:由开发者参考已有模板进行设备描述配置,包括驱动加载顺序、板级硬件信息、器件私有数据信息等。 - - (2)加载input设备管理驱动:input设备管理驱动由HDF驱动加载,完成设备manager的创建并对其初始化。 - - (3)加载平台驱动:平台驱动由HDF框架加载,主要完成板级配置解析及硬件初始化,并提供器件注册接口。 - - (4)加载器件驱动:器件驱动也由HDF框架加载,完成器件设备的实例化,包括器件私有配置解析和平台预留的差异化接口适配。 - - (5)器件设备向平台驱动注册:将实例化的器件设备向平台驱动注册,实现设备和驱动的绑定,并完成中断注册、上下电等器件初始化工作。 - - (6)input设备注册:在器件初始化完成后,实例化input设备,并将其注册到input manager进行管理。 - - -## 开发步骤 - -1. 设备描述配置 - - 目前Input驱动基于HDF驱动框架编写,驱动的加载启动由HDF驱动管理框架统一处理。首先需要在对应的配置文件中,将驱动信息注册进去,如是否加载、加载优先级,此后HDF驱动框架会逐一启动注册过的驱动模块。驱动的相关配置请参考[HDF驱动框架配置指导](驱动开发.md#section1969312275533)。 - -2. 板级配置及Touchscreen器件私有配置 - - 配置对应的IO管脚功能,例如对单板上为touchscreen设计预留的I2C Pin脚,需设置对应的寄存器,使其选择I2C的通信功能。 - -3. 实现器件差异化适配接口 - - 根据硬件单板设计的通信接口,使用Platform接口层提供的管脚操作接口配置对应的复位管脚、中断管脚以及电源操作,对于GPIO的操作,可参考[GPIO操作接口指导](GPIO使用指导.md) - - diff --git "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index b6456936b0195199ef6f29d12e690492892bbda0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/Touchscreen\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,71 +0,0 @@ -# Touchscreen开发概述 - -- [简介](#section124332411260) -- [接口说明](#section10542625172618) - -## 简介 - -- **Touchscreen驱动主要任务** - - Touchscreen驱动用于驱动触摸屏使其正常工作,该驱动主要完成如下工作:对触摸屏驱动IC进行上电、配置硬件管脚并初始化其状态、注册中断、配置通信接口(I2C或SPI)、设定input相关配置、下载及更新固件等操作。 - - -- **Touchscreen驱动层次说明** - - 本节主要介绍基于input驱动模型开发touchscreen器件驱动,其整体的框架模型如[图1](#fig6251184817261)。 - - Input驱动模型基于HDF驱动框架、PLATFORM接口、OSAL接口进行开发,向上对接规范化的驱动接口HDI(Hardware Driver Interface)层,通过Input-HDI层对外提供硬件能力,即上层input service可以通过HDI接口层获取相应的驱动能力,进而操控touchscreen等输入设备。 - - -**图 1** 基于HDF驱动框架的input驱动模型 -![](figures/基于HDF驱动框架的input驱动模型.png "基于HDF驱动框架的input驱动模型") - -- **Input驱动模型介绍** - - Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。器件产生的数据借助平台数据通道能力从内核传递到用户态,驱动模型通过配置文件适配不同器件及硬件平台,提高开发者的器件驱动开发效率。如下部分为模型各部分的说明: - - (1)input设备管理:为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; - - (2)input平台驱动:指各类input设备的公共抽象驱动(例如触摸屏的公共驱动),负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; - - (3)input器件驱动:指各器件厂家的差异化驱动,通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; - - (4)input数据通道:提供一套通用的数据上报通道,各类别的input设备驱动均可用此通道上报input事件; - - (5)input配置解析:负责对input设备的板级配置及器件私有配置进行解析及管理。 - - -- **基于HDF驱动框架开发器件驱动的优势** - - 在HDF(Hardware Driver Foundation)[驱动管理框架](驱动开发.md)的基础上,input驱动模型调用OSAL接口层和Platfom接口层提供的基础接口进行开发,包括bus通信接口、操作系统原生接口(memory、lock、thread、timer等)。由于OSAL接口和Platform接口屏蔽了芯片平台差异,所以基于input驱动模型实现的touchscreen驱动可以进行跨平台、跨OS迁移,以便逐步实现驱动的一次开发,多端部署。 - - -## 接口说明 - -Touchscreen器件的硬件接口相对简单,根据PIN脚的属性,可以简单分为如下三类: - -- 电源接口 -- IO控制接口 -- 通信接口 - -**图 2** Touchscreen器件常用管脚 -![](figures/Touchscreen器件常用管脚.png "Touchscreen器件常用管脚") - -如上图所示的三类接口,分别做简要说明如下: - -1. **电源接口** - - LDO\_1P8:1.8v数字电路 - - LDO\_3P3:3.3v模拟电路 - - 通常情况下,touchscreen驱动IC和LCD驱动IC是相互分离的,这种情况下,touchscreen驱动IC一般同时需要1.8v和3.3v两路供电。随着芯片演进,业内已有touchscreen驱动IC和LCD驱动IC集成在一颗IC中的芯片案例,对touchscreen而言,只需要关注1.8v供电即可,其内部需要的3.3v电源,会在驱动IC内部从LCD的VSP电源(典型值5.5V)中分出来。 - - -2. **IO控制接口** - - Reset:reset管脚,用于在系统休眠、唤醒时,由主机侧对驱动IC进行复位操作。 - - INT:中断管脚,需要在驱动初始化时,配置为输入上拉状态。在驱动IC检测到外部触摸信号后,通过操作中断管脚来触发中断,器件驱动则会在中断处理函数中进行报点数据读取等操作。 - -3. **通信接口** - - I2C:由于touchscreen的报点数据量相对较少,所以一般选用I2C方式传输数据。I2C的具体协议及对应操作接口,可以参考Platform接口层中的[“I2C”使用指南](I2C使用指导.md)。 - - SPI:部分厂商,由于需要传递的数据不止报点坐标,而是需要获取基础容值,数据量较大,所以会选用SPI通信方式。SPI的具体协议及对应操作接口,可以参考Platform接口层中的[“SPI” 使用指南](SPI使用指导.md)。 - - diff --git a/zh-cn/device-dev/driver/UART.md b/zh-cn/device-dev/driver/UART.md index 5d81f12e15f43bdf7e3302bc33cf1dddd524b4e9..feb048b58800db30b173691f6eea19fcecab5a67 100755 --- a/zh-cn/device-dev/driver/UART.md +++ b/zh-cn/device-dev/driver/UART.md @@ -1,9 +1,682 @@ -# UART +# UART -- **[UART概述](UART概述.md)** +- [概述](#section833012453535) + - [接口说明](#section1680292311549) -- **[UART使用指导](UART使用指导.md)** +- [使用指导](#section12779050105412) + - [使用流程](#section1858116395510) + - [获取UART设备句柄](#section124512065617) + - [UART设置波特率](#section86881004579) + - [UART获取波特率](#section897032965712) + - [UART设置设备属性](#section129141884588) + - [UART获取设备属性](#section18689637165812) + - [设置UART传输模式](#section72713435918) + - [向UART设备写入指定长度的数据](#section128001736155919) + - [从UART设备中读取指定长度的数据](#section92851601604) + - [销毁UART设备句柄](#section1477410521406) -- **[UART使用实例](UART使用实例.md)** +- [使用实例](#section35404241311) +## 概述 + +- UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)的缩写,是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 +- UART应用比较广泛,常用于输出打印信息,也可以外接各种模块,如GPS、蓝牙等。 +- 两个UART设备的连接示意图如下,UART与其他模块一般用2线(图1)或4线(图2)相连,它们分别是: + - TX:发送数据端,和对端的RX相连; + - RX:接收数据端,和对端的TX相连; + - RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连; + - CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连; + + **图 1** 2线UART设备连接示意图 + + + ![](figures/zh-cn_image_0000001170262141.png) + + **图 2** 4线UART设备连接示意图 + + + ![](figures/zh-cn_image_0000001123582482.png) + + +- UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。 +- UART接口定义了操作UART端口的通用方法集合,包括获取、释放设备句柄、读写数据、获取和设置波特率、获取和设置设备属性。 + +### 接口说明 + +**表 1** UART驱动API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

UART获取/释放设备句柄

+

+

UartOpen

+

UART获取设备句柄

+

UartClose

+

UART释放设备句柄

+

UART读写接口

+

+

UartRead

+

从UART设备中读取指定长度的数据

+

UartWrite

+

向UART设备中写入指定长度的数据

+

UART获取/设置波特率接口

+

UartGetBaud

+

UART获取波特率

+

UartSetBaud

+

UART设置波特率

+

UART获取/设置设备属性

+

+

UartGetAttribute

+

UART获取设备属性

+

UartSetAttribute

+

UART设置设备属性

+

UART设置传输模式

+

UartSetTransMode

+

UART设置传输模式

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用UART的一般流程如[图3](#fig1852173020185)所示。 + +**图 3** UART使用流程图 + + +![](figures/zh-cn_image_0000001170227689.png) + +### 获取UART设备句柄 + +在使用UART进行通信时,首先要调用UartOpen获取UART设备句柄,该函数会返回指定端口号的UART设备句柄。 + +DevHandle UartOpen\(uint32\_t port\); + +**表 2** UartOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

port

+

UART设备号

+

返回值

+

返回值描述

+

NULL

+

获取UART设备句柄失败

+

设备句柄

+

UART设备句柄

+
+ +假设系统中的UART端口号为3,获取该UART设备句柄的示例如下: + +``` +DevHandle handle = NULL; /* UART设备句柄 */ +uint32_t port = 3; /* UART设备端口号 */ +handle = UartOpen(port); +if (handle == NULL) { + HDF_LOGE("UartOpen: failed!\n"); + return; +} +``` + +### UART设置波特率 + +在通信之前,需要设置UART的波特率,设置波特率的函数如下所示: + +int32\_t UartSetBaud\(DevHandle handle, uint32\_t baudRate\); + +**表 3** UartSetBaud参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

baudRate

+

待设置的波特率值

+

返回值

+

返回值描述

+

0

+

UART设置波特率成功

+

负数

+

UART设置波特率失败

+
+ +假设需要设置的UART波特率为9600,设置波特率的实例如下: + +``` +int32_t ret; +/* 设置UART波特率 */ +ret = UartSetBaud(handle, 9600); +if (ret != 0) { + HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); +} +``` + +### UART获取波特率 + +设置UART的波特率后,可以通过获取波特率接口来查看UART当前的波特率,获取波特率的函数如下所示: + +int32\_t UartGetBaud\(DevHandle handle, uint32\_t \*baudRate\); + +**表 4** UartGetBaud参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

baudRate

+

接收波特率值的指针

+

返回值

+

返回值描述

+

0

+

UART获取波特率成功

+

负数

+

UART获取波特率失败

+
+ +获取波特率的实例如下: + +``` +int32_t ret; +uint32_t baudRate; +/* 获取UART波特率 */ +ret = UartGetBaud(handle, &baudRate); +if (ret != 0) { + HDF_LOGE("UartGetBaud: failed, ret %d\n", ret); +} +``` + +### UART设置设备属性 + +在通信之前,需要设置UART的设备属性,设置设备属性的函数如下图所示: + +int32\_t UartSetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); + +**表 5** UartSetAttribute参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

attribute

+

待设置的设备属性

+

返回值

+

返回值描述

+

0

+

UART设置设备属性成功

+

负数

+

UART设置设备属性失败

+
+ +设置UART的设备属性的实例如下: + +``` +int32_t ret; +struct UartAttribute attribute; +attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ +attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ +attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ +attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ +attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ +attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ +attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ +/* 设置UART设备属性 */ +ret = UartSetAttribute(handle, &attribute); +if (ret != 0) { + HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); +} +``` + +### UART获取设备属性 + +设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性,获取设备属性的函数如下图所示: + +int32\_t UartGetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); + +**表 6** UartGetAttribute参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

attribute

+

接收UART设备属性的指针

+

返回值

+

返回值描述

+

0

+

UART获取设备属性成功

+

负数

+

UART获取设备属性失败

+
+ +获取UART的设备属性的实例如下: + +``` +int32_t ret; +struct UartAttribute attribute; +/* 获取UART设备属性 */ +ret = UartGetAttribute(handle, &attribute); +if (ret != 0) { + HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret); +} +``` + +### 设置UART传输模式 + +在通信之前,需要设置UART的传输模式,设置传输模式的函数如下图所示: + +int32\_t UartSetTransMode\(DevHandle handle, enum UartTransMode mode\); + +**表 7** UartSetTransMode参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

mode

+

待设置的传输模式,

+

返回值

+

返回值描述

+

0

+

UART设置传输模式成功

+

负数

+

UART设置传输模式失败

+
+ +假设需要设置的UART传输模式为UART\_MODE\_RD\_BLOCK,设置传输模式的实例如下: + +``` +int32_t ret; +/* 设置UART传输模式 */ +ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); +if (ret != 0) { + HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); +} +``` + +### 向UART设备写入指定长度的数据 + +对应的接口函数如下所示: + +int32\_t UartWrite\(DevHandle handle, uint8\_t \*data, uint32\_t size\); + +**表 8** UartWrite参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

data

+

待写入数据的指针

+

size

+

待写入数据的长度

+

返回值

+

返回值描述

+

0

+

UART写数据成功

+

负数

+

UART写数据失败

+
+ +写入指定长度数据的实例如下: + +``` +int32_t ret; +uint8_t wbuff[5] = {1, 2, 3, 4, 5}; +/* 向UART设备写入指定长度的数据 */ +ret = UartWrite(handle, wbuff, 5); +if (ret != 0) { + HDF_LOGE("UartWrite: failed, ret %d\n", ret); +} +``` + +### 从UART设备中读取指定长度的数据 + +对应的接口函数如下所示: + +int32\_t UartRead\(DevHandle handle, uint8\_t \*data, uint32\_t size\); + +**表 9** UartRead参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+

data

+

接收读取数据的指针

+

size

+

待读取数据的长度

+

返回值

+

返回值描述

+

非负数

+

UART读取到的数据长度

+

负数

+

UART读取数据失败

+
+ +读取指定长度数据的实例如下: + +``` +int32_t ret; +uint8_t rbuff[5] = {0}; +/* 从UART设备读取指定长度的数据 */ +ret = UartRead(handle, rbuff, 5); +if (ret < 0) { + HDF_LOGE("UartRead: failed, ret %d\n", ret); +} +``` + +>![](public_sys-resources/icon-caution.gif) **注意:** +>UART返回值为非负值,表示UART读取成功。若返回值等于0,表示UART无有效数据可以读取。若返回值大于0,表示实际读取到的数据长度,该长度小于或等于传入的参数size的大小,并且不超过当前正在使用的UART控制器规定的最大单次读取数据长度的值。 + +### 销毁UART设备句柄 + +UART通信完成之后,需要销毁UART设备句柄,函数如下所示: + +void UartClose\(DevHandle handle\); + +该函数会释放申请的资源。 + +**表 10** UartClose参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

UART设备句柄

+
+ +销毁UART设备句柄的实例如下: + +``` +UartClose(handle); /* 销毁UART设备句柄 * +``` + +## 使用实例 + +UART设备完整的使用示例如下所示,首先获取UART设备句柄,接着设置波特率、设备属性和传输模式,之后进行UART通信,最后销毁UART设备句柄。 + +``` +#include "hdf_log.h" +#include "uart_if.h" + +void UartTestSample(void) +{ + int32_t ret; + uint32_t port; + DevHandle handle = NULL; + uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; + uint8_t rbuff[5] = { 0 }; + struct UartAttribute attribute; + attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ + attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ + attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ + attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ + attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ + attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ + attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ + /* UART设备端口号,要填写实际平台上的端口号 */ + port = 1; + /* 获取UART设备句柄 */ + handle = UartOpen(port); + if (handle == NULL) { + HDF_LOGE("UartOpen: failed!\n"); + return; + } + /* 设置UART波特率为9600 */ + ret = UartSetBaud(handle, 9600); + if (ret != 0) { + HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); + goto _ERR; + } + /* 设置UART设备属性 */ + ret = UartSetAttribute(handle, &attribute); + if (ret != 0) { + HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); + goto _ERR; + } + /* 设置UART传输模式为非阻塞模式 */ + ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); + if (ret != 0) { + HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); + goto _ERR; + } + /* 向UART设备写入5字节的数据 */ + ret = UartWrite(handle, wbuff, 5); + if (ret != 0) { + HDF_LOGE("UartWrite: failed, ret %d\n", ret); + goto _ERR; + } + /* 从UART设备读取5字节的数据 */ + ret = UartRead(handle, rbuff, 5); + if (ret < 0) { + HDF_LOGE("UartRead: failed, ret %d\n", ret); + goto _ERR; + } +_ERR: + /* 销毁UART设备句柄 */ + UartClose(handle); +} +``` diff --git "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index d049e3d021843a422c3e11b1fde5a10b57393070..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,67 +0,0 @@ -# UART使用实例 - -UART设备完整的使用示例如下所示,首先获取UART设备句柄,接着设置波特率、设备属性和传输模式,之后进行UART通信,最后销毁UART设备句柄。 - -``` -#include "hdf_log.h" -#include "uart_if.h" - -void UartTestSample(void) -{ - int32_t ret; - uint32_t port; - DevHandle handle = NULL; - uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; - uint8_t rbuff[5] = { 0 }; - struct UartAttribute attribute; - attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ - attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ - attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ - attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ - attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ - attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ - attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ - /* UART设备端口号,要填写实际平台上的端口号 */ - port = 1; - /* 获取UART设备句柄 */ - handle = UartOpen(port); - if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); - return; - } - /* 设置UART波特率为9600 */ - ret = UartSetBaud(handle, 9600); - if (ret != 0) { - HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); - goto _ERR; - } - /* 设置UART设备属性 */ - ret = UartSetAttribute(handle, &attribute); - if (ret != 0) { - HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); - goto _ERR; - } - /* 设置UART传输模式为非阻塞模式 */ - ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); - if (ret != 0) { - HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); - goto _ERR; - } - /* 向UART设备写入5字节的数据 */ - ret = UartWrite(handle, wbuff, 5); - if (ret != 0) { - HDF_LOGE("UartWrite: failed, ret %d\n", ret); - goto _ERR; - } - /* 从UART设备读取5字节的数据 */ - ret = UartRead(handle, rbuff, 5); - if (ret < 0) { - HDF_LOGE("UartRead: failed, ret %d\n", ret); - goto _ERR; - } -_ERR: - /* 销毁UART设备句柄 */ - UartClose(handle); -} -``` - diff --git "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 1d1ee50a8c13e37c506350820c71a5a7b4893d7f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/UART\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,506 +0,0 @@ -# UART使用指导 - -- [使用流程](#section47784125013) -- [获取UART设备句柄](#section146445153110) -- [UART设置波特率](#section1862705516339) -- [UART获取波特率](#section1263651563414) -- [UART设置设备属性](#section1770091483814) -- [UART获取设备属性](#section117543316384) -- [设置UART传输模式](#section187233112369) -- [向UART设备写入指定长度的数据](#section82416423368) -- [从UART设备中读取指定长度的数据](#section192177171373) -- [销毁UART设备句柄](#section63131236354) - -## 使用流程 - -使用UART的一般流程如[图1](#p58686354483)所示。 - -**图 1** UART使用流程图 - - -![](figures/zh-cn_image_0000001054006983.png) - -## 获取UART设备句柄 - -在使用UART进行通信时,首先要调用UartOpen获取UART设备句柄,该函数会返回指定端口号的UART设备句柄。 - -DevHandle UartOpen\(uint32\_t port\); - -**表 1** UartOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

port

-

UART设备号

-

返回值

-

返回值描述

-

NULL

-

获取UART设备句柄失败

-

设备句柄

-

UART设备句柄

-
- -假设系统中的UART端口号为3,获取该UART设备句柄的示例如下: - -``` -DevHandle handle = NULL; /* UART设备句柄 */ -uint32_t port = 3; /* UART设备端口号 */ -handle = UartOpen(port); -if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); - return; -} -``` - -## UART设置波特率 - -在通信之前,需要设置UART的波特率,设置波特率的函数如下所示: - -int32\_t UartSetBaud\(DevHandle handle, uint32\_t baudRate\); - -**表 2** UartSetBaud参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

baudRate

-

待设置的波特率值

-

返回值

-

返回值描述

-

0

-

UART设置波特率成功

-

负数

-

UART设置波特率失败

-
- -假设需要设置的UART波特率为9600,设置波特率的实例如下: - -``` -int32_t ret; -/* 设置UART波特率 */ -ret = UartSetBaud(handle, 9600); -if (ret != 0) { - HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); -} -``` - -## UART获取波特率 - -设置UART的波特率后,可以通过获取波特率接口来查看UART当前的波特率,获取波特率的函数如下所示: - -int32\_t UartGetBaud\(DevHandle handle, uint32\_t \*baudRate\); - -**表 3** UartGetBaud参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

baudRate

-

接收波特率值的指针

-

返回值

-

返回值描述

-

0

-

UART获取波特率成功

-

负数

-

UART获取波特率失败

-
- -获取波特率的实例如下: - -``` -int32_t ret; -uint32_t baudRate; -/* 获取UART波特率 */ -ret = UartGetBaud(handle, &baudRate); -if (ret != 0) { - HDF_LOGE("UartGetBaud: failed, ret %d\n", ret); -} -``` - -## UART设置设备属性 - -在通信之前,需要设置UART的设备属性,设置设备属性的函数如下图所示: - -int32\_t UartSetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); - -**表 4** UartSetAttribute参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

attribute

-

待设置的设备属性

-

返回值

-

返回值描述

-

0

-

UART设置设备属性成功

-

负数

-

UART设置设备属性失败

-
- -设置UART的设备属性的实例如下: - -``` -int32_t ret; -struct UartAttribute attribute; -attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ -attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ -attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ -attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ -attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ -attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ -attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ -/* 设置UART设备属性 */ -ret = UartSetAttribute(handle, &attribute); -if (ret != 0) { - HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); -} -``` - -## UART获取设备属性 - -设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性,获取设备属性的函数如下图所示: - -int32\_t UartGetAttribute\(DevHandle handle, struct UartAttribute \*attribute\); - -**表 5** UartGetAttribute参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

attribute

-

接收UART设备属性的指针

-

返回值

-

返回值描述

-

0

-

UART获取设备属性成功

-

负数

-

UART获取设备属性失败

-
- -获取UART的设备属性的实例如下: - -``` -int32_t ret; -struct UartAttribute attribute; -/* 获取UART设备属性 */ -ret = UartGetAttribute(handle, &attribute); -if (ret != 0) { - HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret); -} -``` - -## 设置UART传输模式 - -在通信之前,需要设置UART的传输模式,设置传输模式的函数如下图所示: - -int32\_t UartSetTransMode\(DevHandle handle, enum UartTransMode mode\); - -**表 6** UartSetTransMode参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

mode

-

待设置的传输模式,

-

返回值

-

返回值描述

-

0

-

UART设置传输模式成功

-

负数

-

UART设置传输模式失败

-
- -假设需要设置的UART传输模式为UART\_MODE\_RD\_BLOCK,设置传输模式的实例如下: - -``` -int32_t ret; -/* 设置UART传输模式 */ -ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); -if (ret != 0) { - HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); -} -``` - -## 向UART设备写入指定长度的数据 - -对应的接口函数如下所示: - -int32\_t UartWrite\(DevHandle handle, uint8\_t \*data, uint32\_t size\); - -**表 7** UartWrite参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

data

-

待写入数据的指针

-

size

-

待写入数据的长度

-

返回值

-

返回值描述

-

0

-

UART写数据成功

-

负数

-

UART写数据失败

-
- -写入指定长度数据的实例如下: - -``` -int32_t ret; -uint8_t wbuff[5] = {1, 2, 3, 4, 5}; -/* 向UART设备写入指定长度的数据 */ -ret = UartWrite(handle, wbuff, 5); -if (ret != 0) { - HDF_LOGE("UartWrite: failed, ret %d\n", ret); -} -``` - -## 从UART设备中读取指定长度的数据 - -对应的接口函数如下所示: - -int32\_t UartRead\(DevHandle handle, uint8\_t \*data, uint32\_t size\); - -**表 8** UartRead参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-

data

-

接收读取数据的指针

-

size

-

待读取数据的长度

-

返回值

-

返回值描述

-

非负数

-

UART读取到的数据长度

-

负数

-

UART读取数据失败

-
- -读取指定长度数据的实例如下: - -``` -int32_t ret; -uint8_t rbuff[5] = {0}; -/* 从UART设备读取指定长度的数据 */ -ret = UartRead(handle, rbuff, 5); -if (ret < 0) { - HDF_LOGE("UartRead: failed, ret %d\n", ret); -} -``` - ->![](public_sys-resources/icon-caution.gif) **注意:** ->UART返回值为非负值,表示UART读取成功。若返回值等于0,表示UART无有效数据可以读取。若返回值大于0,表示实际读取到的数据长度,该长度小于或等于传入的参数size的大小,并且不超过当前正在使用的UART控制器规定的最大单次读取数据长度的值。 - -## 销毁UART设备句柄 - -UART通信完成之后,需要销毁UART设备句柄,函数如下所示: - -void UartClose\(DevHandle handle\); - -该函数会释放申请的资源。 - -**表 9** UartClose参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

UART设备句柄

-
- -销毁UART设备句柄的实例如下: - -``` -UartClose(handle); /* 销毁UART设备句柄 * -``` - diff --git "a/zh-cn/device-dev/driver/UART\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/UART\346\246\202\350\277\260.md" deleted file mode 100755 index 2f295bddd98e43a9ff8670b0b5b44943243e6574..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/UART\346\246\202\350\277\260.md" +++ /dev/null @@ -1,106 +0,0 @@ -# UART概述 - -- [简介](#section14770623164917) -- [接口说明](#section149505462492) - -## 简介 - -- UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)的缩写,是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 -- UART应用比较广泛,常用于输出打印信息,也可以外接各种模块,如GPS、蓝牙等。 -- 两个UART设备的连接示意图如下,UART与其他模块一般用2线(图1)或4线(图2)相连,它们分别是: - - TX:发送数据端,和对端的RX相连; - - RX:接收数据端,和对端的TX相连; - - RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连; - - CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连; - - **图 1** 2线UART设备连接示意图 - - - ![](figures/zh-cn_image_0000001053926237.png) - - **图 2** 4线UART设备连接示意图 - - - ![](figures/zh-cn_image_0000001054007499.png) - - -- UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。 -- UART接口定义了操作UART端口的通用方法集合,包括获取、释放设备句柄、读写数据、获取和设置波特率、获取和设置设备属性。 - -## 接口说明 - -**表 1** UART驱动API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

UART获取/释放设备句柄

-

-

UartOpen

-

UART获取设备句柄

-

UartClose

-

UART释放设备句柄

-

UART读写接口

-

-

UartRead

-

从UART设备中读取指定长度的数据

-

UartWrite

-

向UART设备中写入指定长度的数据

-

UART获取/设置波特率接口

-

UartGetBaud

-

UART获取波特率

-

UartSetBaud

-

UART设置波特率

-

UART获取/设置设备属性

-

-

UartGetAttribute

-

UART获取设备属性

-

UartSetAttribute

-

UART设置设备属性

-

UART设置传输模式

-

UartSetTransMode

-

UART设置传输模式

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git a/zh-cn/device-dev/driver/WATCHDOG.md b/zh-cn/device-dev/driver/WATCHDOG.md index 0d7afef9e34e797337223f629833ac288a532914..f3721de176fd86032eaa4addbc9874c3fd42761d 100755 --- a/zh-cn/device-dev/driver/WATCHDOG.md +++ b/zh-cn/device-dev/driver/WATCHDOG.md @@ -1,9 +1,557 @@ -# WATCHDOG +# WATCHDOG -- **[看门狗概述](看门狗概述.md)** +- [概述](#section14918241977) + - [接口说明](#section20177131219818) -- **[看门狗使用指导](看门狗使用指导.md)** +- [使用指导](#section10103184312813) + - [使用流程](#section10181195910815) + - [打开看门狗设备](#section66089201107) + - [获取看门狗状态](#section786624341011) + - [设置超时时间](#section182386137111) + - [获取超时时间](#section1883310371114) + - [启动看门狗](#section82501405123) + - [喂狗](#section3547530101211) + - [停止看门狗](#section944595841217) + - [关闭看门狗设备](#section96561824121311) -- **[看门狗使用实例](看门狗使用实例.md)** +- [使用实例](#section1724514523135) +## 概述 + +看门狗(watchdog),又叫看门狗计时器(watchdog timer),是一种硬件的计时设备,当系统的主程序发生某些错误时,导致未及时清除看门狗计时器的计时值,这时看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。 + +### 接口说明 + +**表 1** 看门狗 API接口功能介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

打开/关闭看门狗

+

WatchdogOpen

+

打开看门狗设备

+

WatchdogClose

+

关闭看门狗设备

+

启动/停止看门狗

+

WatchdogStart

+

启动看门狗

+

WatchdogStop

+

停止看门狗

+

设置/获取超时时间

+

WatchdogSetTimeout

+

设置看门狗超时时间

+

WatchdogGetTimeout

+

获取看门狗超时时间

+

获取看门狗状态

+

WatchdogGetStatus

+

获取看门狗状态

+

清除看门狗定时器

+

WatchdogFeed

+

清除看门狗定时器(喂狗)

+
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>本文涉及看门狗的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用看门狗的一般流程如[图1](#fig19134125410189)所示。 + +**图 1** 看门狗使用流程图 + + +![](figures/zh-cn_image_0000001170229891.png) + +### 打开看门狗设备 + +在操作看门狗之前,需要使用WatchdogOpen打开一个看门狗设备,一个系统可能有多个看门狗,通过ID号来打开指定的看门狗设备: + +int32\_t WatchdogOpen\(int16\_t wdtId\); + +**表 2** WatchdogOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

wdtId

+

看门狗设备号

+

返回值

+

返回值描述

+

NULL

+

打开失败

+

DevHandle类型指针

+

看门狗设备句柄

+
+ +``` +DevHandle handle = NULL; +handle = WatchdogOpen(0); /* 打开0号看门狗设备 */ +if (handle == NULL) { + HDF_LOGE("WatchdogOpen: failed, ret %d\n", ret); + return; +} +``` + +### 获取看门狗状态 + +int32\_t WatchdogGetStatus\(DevHandle handle, int32\_t \*status\); + +**表 3** WatchdogGetStatus参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

status

+

获取到的启动状态指针

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +int32_t status; +/* 获取Watchdog启动状态 */ +ret = WatchdogGetStatus(handle, &status); +if (ret != 0) { + HDF_LOGE("WatchdogGetStatus: failed, ret %d\n", ret); + return; +} +``` + +### 设置超时时间 + +int32\_t WatchdogSetTimeout\(PalHandle \*handle, uint32\_t seconds\); + +**表 4** WatchdogSetTimeout参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

seconds

+

超时时间,单位为秒

+

返回值

+

返回值描述

+

0

+

设置成功

+

负数

+

设置失败

+
+ +``` +int32_t ret; +uint32_t timeOut = 60; +/* 设置超时时间,单位:秒 */ +ret = WatchdogSetTimeout(handle, timeOut); +if (ret != 0) { + HDF_LOGE("WatchdogSetTimeout: failed, ret %d\n", ret); + return; +} +``` + +### 获取超时时间 + +int32\_t WatchdogGetTimeout\(PalHandle \*handle, uint32\_t \*seconds\); + +**表 5** WatchdogGetTimeout参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

seconds

+

接收超时时间的指针,单位为秒

+

返回值

+

返回值描述

+

0

+

获取成功

+

负数

+

获取失败

+
+ +``` +int32_t ret; +uint32_t timeOut; +/* 获取超时时间,单位:秒 */ +ret = WatchdogGetTimeout(handle, &timeOut); +if (ret != 0) { + HDF_LOGE("WatchdogGetTimeout: failed, ret %d\n", ret); + return; +} +``` + +### 启动看门狗 + +int32\_t WatchdogStart\(DevHandle handle\); + +**表 6** WatchdogStart参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

返回值

+

返回值描述

+

0

+

启动成功

+

负数

+

启动失败

+
+ +``` +int32_t ret; +/* 启动看门狗 */ +ret = WatchdogStart(handle); +if (ret != 0) { + HDF_LOGE("WatchdogStart: failed, ret %d\n", ret); + return; +} +``` + +### 喂狗 + +int32\_t WatchdogFeed\(DevHandle handle\); + +**表 7** WatchdogFeed参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

返回值

+

返回值描述

+

0

+

喂狗成功

+

负数

+

喂狗失败

+
+ +``` +int32_t ret; +/* 喂狗 */ +ret = WatchdogFeed(handle); +if (ret != 0) { + HDF_LOGE("WatchdogFeed: failed, ret %d\n", ret); + return; +} +``` + +### 停止看门狗 + +int32\_t WatchdogStop\(DevHandle handle\); + +**表 8** WatchdogStop参数和返回值描述 + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+

返回值

+

返回值描述

+

0

+

停止成功

+

负数

+

停止失败

+
+ +``` +int32_t ret; +/* 停止看门狗 */ +ret = WatchdogStop(handle); +if (ret != 0) { + HDF_LOGE("WatchdogStop: failed, ret %d\n", ret); + return; +} +``` + +### 关闭看门狗设备 + +当操作完毕时,使用WatchdogClose关闭打开的设备句柄: + +void WatchdogClose\(DevHandle handle\); + +**表 9** WatchdogClose参数和返回值描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

看门狗设备句柄

+
+ +``` +/* 关闭看门狗 */ +ret = WatchdogClose(handle); +``` + +## 使用实例 + +本例程提供看门狗的完整使用流程。 + +在本例程中,我们打开一个看门狗设备,设置超时时间并启动计时: + +- 首先定期喂狗,即按时清除看门狗定时器,确保系统不会因定时器超时而复位。 +- 接着再停止喂狗,观察定时器到期后系统是否发生复位行为。 + +示例如下: + +``` +#include "watchdog_if.h" +#include "hdf_log.h" +#include "osal_irq.h" +#include "osal_time.h" + +#define WATCHDOG_TEST_TIMEOUT 2 +#define WATCHDOG_TEST_FEED_TIME 6 + +static int32_t TestCaseWatchdog(void) +{ + int32_t i; + int32_t ret; + uint32_t timeout; + DevHandle handle = NULL; + + /* 打开0号看门狗设备 */ + handle = WatchdogOpen(0); + if (handle == NULL) { + HDF_LOGE("Open watchdog fail!"); + return -1; + } + + /* 设置超时时间 */ + ret = WatchdogSetTimeout(handle, WATCHDOG_TEST_TIMEOUT); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* 回读设置的超时时间值 */ + ret = WatchdogGetTimeout(handle, &timeout); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); + + /* 启动看门狗,开始计时 */ + ret = WatchdogStart(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + + /* 每隔1S喂狗一次 */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); + ret = WatchdogFeed(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); + WatchdogClose(handle); + return ret; + } + OsalSleep(1); + } + /* 由于喂狗间隔小于超时时间,系统不会发生复位,此日志可以正常打印 */ + HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); + + /* 接下来持续不喂狗,使得看门狗计时器超时 */ + for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { + HDF_LOGE("%s: watiting dog buck %d times... \n", __func__, i); + OsalSleep(1); + } + + /* 当不喂狗时间到达之前设定的超时时间的时候,系统会发生复位,理论上观察不到此日志的打印 */ + HDF_LOGE("%s: dog has't buck!!! \n", __func__, i); + WatchdogClose(handle); + return -1; +} +``` diff --git a/zh-cn/device-dev/driver/WLAN.md b/zh-cn/device-dev/driver/WLAN.md index af39a0d3a2bed463178b7cc278c21373c91ef9f1..5f02b83d0f67e26cbce00893a56488a203ca74f3 100755 --- a/zh-cn/device-dev/driver/WLAN.md +++ b/zh-cn/device-dev/driver/WLAN.md @@ -1,9 +1,622 @@ -# WLAN +# WLAN -- **[WLAN开发概述](WLAN开发概述.md)** +- [概述](#section729758162218) + - [WLAN驱动接口架构](#section178022416377) + - [接口说明](#section149681312202415) -- **[WLAN开发指导](WLAN开发指导.md)** +- [开发指导](#section15957746172412) + - [开发步骤](#section11776186132513) -- **[WLAN开发实例](WLAN开发实例.md)** +- [开发实例](#section1395253612512) +## 概述 + +WLAN是基于HDF(Hardware Driver Foundation)驱动框架开发的模块,该模块可实现跨操作系统迁移,自适应器件差异,模块化拼装编译等功能。各WLAN厂商驱动开发人员可根据WLAN模块提供的向下统一接口适配各自的驱动代码,实现如下能力:建立/关闭WLAN热点、扫描、关联WLAN热点等;对HDI层向上提供能力如下:设置MAC地址、设置发射功率、获取设备的MAC地址等。[WLAN模块框架图](#fig967034316227)如下: + +**图 1** WLAN框架 + + +![](figures/zh-cn_image_0000001170383063.png) + +### WLAN驱动接口架构 + +WLAN模块有三部分对外开放的API接口,如[下图2](#fig15016395217)所示: + +1. 对HDI层提供的能力接口。 + +2. 驱动直接调用WLAN模块能力接口。 + +3. 提供给各厂商实现的能力接口。 + +**图 2** WLAN模块开放能力分布图 + + +![](figures/接口分布图4.png) + +### 接口说明 + +WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。提供的部分接口说明如[表1](#table1521573319472)所示: + +**表 1** 可直接调用的接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口名称

+

功能描述

+

wifi_module.h

+

+

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

+

基于HDF开发WLAN驱动时,创建一个WifiModule。

+

void WifiModuleDelete(struct WifiModule *module);

+

基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。

+

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

+

基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。

+

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

+

基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。

+

wifi_mac80211_ops.h

+

int32_t (*startAp)(NetDevice *netDev);

+

启动AP。

+

int32_t (*stopAp)(NetDevice *netDev);

+

停止AP。

+

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

+

开始关联。

+

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

+

取消关联。

+

hdf_netbuf.h

+

static inline void NetBufQueueInit(struct NetBufQueue *q);

+

初始化NetBuf队列。

+

struct NetBuf *NetBufAlloc(uint32_t size);

+

申请NetBuf。

+

void NetBufFree(struct NetBuf *nb);

+

释放NetBuf。

+

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

+

lwip的pbuf转换为NetBuf。

+

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

+

NetBuf转换为lwip的pbuf。

+
+ +同时WLAN驱动模块也提供了需要驱动开发人员实现的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如[表2](#table74613501475)所示: + +**表 2** 需要开发人员实现的接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口名称

+

功能描述

+

net_device.h

+

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

+

初始化NetDevice。

+

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

+

获取NetDevice的状态。

+

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

+

设置Mac地址。

+

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

+

注销NetDevice。

+

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

+

打开NetDevice。

+

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

+

关闭NetDevice。

+
+ +WLAN驱动模块对HDI层提供的能力接口,主要功能有:创建/销毁 IWiFi对象、设置MAC地址等。提供的部分接口说明如[表3](#table141076311618)所示: + +**表 3** HAL层对外接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口名称

+

功能描述

+

wifi_hal.h

+

+

int32_t WifiConstruct(struct IWiFi **wifiInstance);

+

创建IWiFi对象,提供IWiFi基本能力。

+

int32_t WifiDestruct(struct IWiFi **wifiInstance);

+

销毁IWiFi对象。

+

int32_t (*start)(struct IWiFi *);

+

创建HAL和驱动之间的通道及获取驱动支持的网卡信息。

+

int32_t (*stop)(struct IWiFi *);

+

销毁通道。

+

wifi_hal_base_feature.h

+

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

+

获取特性的类型。

+

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

+

设置MAC地址。

+

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

+

获取设备持久化的MAC地址。

+

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

+

设置发射功率。

+
+ +## 开发指导 + +WLAN驱动基于HDF框架和PLATFORM框架开发,不区分OS和芯片平台,为不同厂商的WLAN模组提供统一的驱动模型,各WLAN模组厂商根据如下指导适配WLAN驱动框架。 + +### 开发步骤 + +1. 通过wifi\_config.hcs文件,配置硬件参数:module\(不同feature\),芯片等。 +2. 解析配置文件, 生成全量配置的结构体对象。 +3. Module初始化,创建Module。 +4. 挂接chip,初始化chip。 +5. 总线初始化。 +6. 上层wpa业务挂接。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>以上驱动框架适配步骤一部分已经提供(详细见开发实例),待开发人员实现的部分有:1、根据硬件,修改配置参数;2、适配挂接chip;3、测试自验证。 + +## 开发实例 + +本例程提供WLAN模块初始化过程的完整使用流程。示例如下(以hi3881WLAN芯片为例): + +1、根据硬件,修改配置参数。 + +``` +/* 根据硬件参数,通过wlan_platform.hcs配置相关参数,以下是WLAN平台配置的示例 */ +hisi :& deviceList { + device0 :: deviceInst { + deviceInstId = 0; + powers { + power0 { + powerSeqDelay = 0; /* 电源序列延时 */ + powerType = 1; /* 电源类型:0--总是打开;1--GPIO */ + gpioId = 1; /* GPIO管脚号 */ + activeLevel=1; /* 有效电平:0--低;1--高 */ + } + power1 { + powerSeqDelay = 0; /* 电源序列延时 */ + powerType = 0; /* 电源类型:0--总是打开;1--GPIO */ + } + } + reset { + resetType = 0; /* 复位类型:0--不管理;1--GPIO */ + gpioId = 2; /* GPIO管脚号 */ + activeLevel=1; /* 有效电平:0--低;1--高 */ + resetHoldTime = 30; /* 复位配置后的等待时间(ms) */ + } + bootUpTimeout = 30; /* 启动超时时间(ms) */ + bus { + busType = 0; /* 总线类型:0-sdio */ + busId = 2; /* 总线号 */ + funcNum = [1]; /* SDIO功能号 */ + timeout = 1000; /* 读/写数据的超时时间 */ + blockSize = 512; /* 读/写数据的块大小 */ + } + } +} +/* 每一块芯片添加配置文件wlan_chip_<芯片名>.hcs(如:wlan_chip_hi3881.hcs),配置相关参数。以下是hi3881的配置示例 */ +root { + wlan_config { + hi3881 :& chipList { + chipHi3881 :: chipInst { + match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */ + chipName = "hi3881"; /* WLAN芯片的名称 */ + sdio { + vendorId = 0x0296; /* 厂商Id */ + deviceId = [0x5347]; /* 设备Id */ + } + } + } + } +} +``` + +2、适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化 + +``` +/* WLAN初始化挂接流程 */ +#include "hdf_device_desc.h" +#include "hdf_wifi_product.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "hdf_wlan_chipdriver_manager.h" +#include "securec.h" +#include "wifi_module.h" +#include "hi_wifi_api.h" +#include "hi_types_base.h" + +#define HDF_LOG_TAG Hi3881Driver + +/* WLAN芯片的初始化和去初始化函数 */ +int32_t InitHi3881Chip(struct HdfWlanDevice *device); +int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); +/* WLAN芯片驱动的初始化和去初始化函数 */ +int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); +int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); + +/* 初始化mac80211与芯片侧的函数挂接 */ +hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); + +static const char* const HI3881_DRIVER_NAME = "hisi"; + +/* WLAN芯片驱动挂接以及mac80211与芯片侧的函数挂接 */ +static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) +{ + struct HdfChipDriver *specificDriver = NULL; + if (device == NULL) { + HDF_LOGE("%s fail : channel is NULL", __func__); + return NULL; + } + (void)device; + (void)ifIndex; + specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); + if (specificDriver == NULL) { + HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); + return NULL; + } + if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { + HDF_LOGE("%s fail: memset_s fail!", __func__); + OsalMemFree(specificDriver); + return NULL; + } + + if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { + HDF_LOGE("%s fail : strcpy_s fail", __func__); + OsalMemFree(specificDriver); + return NULL; + } + specificDriver->init = Hi3881Init; + specificDriver->deinit = Hi3881Deinit; + + HiMac80211Init(specificDriver); + + return specificDriver; +} + +/* 释放WLAN芯片驱动 */ +static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) +{ + if (chipDriver == NULL) { + return; + } + if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { + HDF_LOGE("%s:Not my driver!", __func__); + return; + } + OsalMemFree(chipDriver); +} + +static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { + (void)factory; + return 1; +} + +/* WLAN芯片相关函数的注册 */ +static int32_t HDFWlanRegHisiDriverFactory(void) +{ + static struct HdfChipDriverFactory tmpFactory = { 0 }; + struct HdfChipDriverManager *driverMgr = NULL; + driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + tmpFactory.driverName = HI3881_DRIVER_NAME; + tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; + tmpFactory.InitChip = InitHi3881Chip; + tmpFactory.DeinitChip = DeinitHi3881Chip; + tmpFactory.Build = BuildHi3881Driver; + tmpFactory.Release = ReleaseHi3881Driver; + tmpFactory.ReleaseFactory = NULL; + if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) +{ + (void)device; + return HDFWlanRegHisiDriverFactory(); +} + +struct HdfDriverEntry g_hdfHisiChipEntry = { + .moduleVersion = 1, + .Init = HdfWlanHisiChipDriverInit, + .moduleName = "HDF_WLAN_CHIPS" +}; + +HDF_INIT(g_hdfHisiChipEntry); +``` + +``` +#include "hdf_wifi_product.h" +#include "hi_wifi_api.h" +#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) +#include "oal_thread.h" +#include "osal_time.h" +#endif +#include "wifi_mac80211_ops.h" +#include "wal_cfg80211.h" +#include "net_adpater.h" +#include "hdf_wlan_utils.h" + +#define HDF_LOG_TAG Hi3881Driver + +/* WLAN芯片的初始化函数 */ +int32_t InitHi3881Chip(struct HdfWlanDevice *device) +{ + uint8_t maxPortCount = 1; + int32_t ret = HI_SUCCESS; + uint8_t maxRetryCount = 2; + if (device == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HI_FAIL; + } + + do { + if (ret != HI_SUCCESS) { + if (device->reset != NULL && device->reset->Reset != NULL) { + device->reset->Reset(device->reset); + } + HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); + } + ret = hi_wifi_init(maxPortCount); + } while (ret != 0 && --maxRetryCount > 0); + + if (ret != 0) { + HDF_LOGE("%s:Init hi3881 driver failed!", __func__); + return ret; + } + return HI_SUCCESS; +} + +/* WLAN芯片的去初始化函数 */ +int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) +{ + (void)device; + int32_t ret = hi_wifi_deinit(); + if (ret != 0) { + HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); + } + return ret; +} + +/* WLAN芯片驱动的初始化函数 */ +int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + HDF_LOGI("%s: start...", __func__); + hi_u16 mode = wal_get_vap_mode(); + int32_t ret; + nl80211_iftype_uint8 type; + (void)chipDriver; + + if (mode >= WAL_WIFI_MODE_BUTT) { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + + if (mode == WAL_WIFI_MODE_STA) { + type = NL80211_IFTYPE_STATION; + } else if (mode == WAL_WIFI_MODE_AP) { + type = NL80211_IFTYPE_AP; + } else { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + + ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); + if (ret != HI_SUCCESS) { + oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); + } + return ret; +} + +/* WLAN芯片驱动的去初始化函数 */ +int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + (void)chipDriver; + int32_t ret = wal_deinit_drv_wlan_netdev(netDevice); + if (ret != HDF_SUCCESS) { + return ret; + } + return ReleasePlatformNetDevice(netDevice); +} +``` + +3、在芯片侧初始化过程中调用netdev的init和add接口进行初始化netdev,并挂接netdev的一些函数指针 + +``` +hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len) +{ + oal_net_device_stru *netdev = HI_NULL; + + ...... + /* 初始化网络设备,获取对应的实例。*/ + netdev = NetDeviceInit(ifname, *len, LITE_OS); + oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); + ret = wal_init_netif(type, netdev, wdev); + + ...... + + return HI_SUCCESS; +} +/* 挂接netdev的一些函数指针,详细挂接函数{@link NetDeviceInterFace} */ +oal_net_device_ops_stru g_wal_net_dev_ops = +{ + .getStats = wal_netdev_get_stats, + .open = wal_netdev_open, + .stop = wal_netdev_stop, + .xmit = hmac_bridge_vap_xmit, + .ioctl = wal_net_device_ioctl, + .changeMtu = oal_net_device_change_mtu, + .init = oal_net_device_init, + .deInit = oal_net_free_netdev, +#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) + .selectQueue = wal_netdev_select_queue, +#endif + .setMacAddr = wal_netdev_set_mac_addr, +#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) + .netifNotify = HI_NULL, +#endif + .specialEtherTypeProcess = SpecialEtherTypeProcess, +}; + +hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) +{ + /* 添加网络设备到协议栈 */ + hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); + + ...... + + return HI_SUCCESS; +} +``` + +4、WifiMac80211Ops中的函数挂接实现。 + +``` +/* 挂接mac80211的一些函数指针 */ + +/* 驱动需要实现的MAC层基本能力的控制接口 */ +static struct HdfMac80211BaseOps g_baseOps = { + .SetMode = WalSetMode, + .AddKey = WalAddKey, + .DelKey = WalDelKey, + .SetDefaultKey = WalSetDefaultKey, + .GetDeviceMacAddr = WalGetDeviceMacAddr, + .SetMacAddr = WalSetMacAddr, + .SetTxPower = WalSetTxPower, + .GetValidFreqsWithBand = WalGetValidFreqsWithBand, + .GetHwCapability = WalGetHwCapability +}; + +/* 驱动需要实现的MAC层STA能力的控制接口 */ +static struct HdfMac80211STAOps g_staOps = { + .Connect = WalConnect, + .Disconnect = WalDisconnect, + .StartScan = WalStartScan, + .AbortScan = WalAbortScan, + .SetScanningMacAddress = WalSetScanningMacAddress, +}; + +/* 驱动需要实现的MAC层AP能力的控制接口 */ +static struct HdfMac80211APOps g_apOps = { + .ConfigAp = WalConfigAp, + .StartAp = WalStartAp, + .StopAp = WalStopAp, + .ConfigBeacon = WalChangeBeacon, + .DelStation = WalDelStation, + .SetCountryCode = WalSetCountryCode, + .GetAssociatedStasCount = WalGetAssociatedStasCount, + .GetAssociatedStasInfo = WalGetAssociatedStasInfo +}; + +/* 初始化mac80211与芯片侧的函数挂接 */ +hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) +{ + if (chipDriver == NULL) { + oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__); + return; + } + chipDriver->ops = &g_baseOps; + chipDriver->staOps = &g_staOps; + chipDriver->apOps = &g_apOps; +} +``` diff --git "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index bc558cb653344f4a82333d7c4ccdcc73815db838..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,372 +0,0 @@ -# WLAN开发实例 - -本例程提供WLAN模块初始化过程的完整使用流程。示例如下(以hi3881WLAN芯片为例): - -1、根据硬件,修改配置参数 - -``` -/* 根据硬件参数,通过wlan_platform.hcs配置相关参数,以下是WLAN平台配置的示例 */ -hisi :& deviceList { - device0 :: deviceInst { - deviceInstId = 0; - powers { - power0 { - powerSeqDelay = 0; /* 电源序列延时 */ - powerType = 1; /* 电源类型:0--总是打开;1--GPIO */ - gpioId = 1; /* GPIO管脚号 */ - activeLevel=1; /* 有效电平:0--低;1--高 */ - } - power1 { - powerSeqDelay = 0; /* 电源序列延时 */ - powerType = 0; /* 电源类型:0--总是打开;1--GPIO */ - } - } - reset { - resetType = 0; /* 复位类型:0--不管理;1--GPIO */ - gpioId = 2; /* GPIO管脚号 */ - activeLevel=1; /* 有效电平:0--低;1--高 */ - resetHoldTime = 30; /* 复位配置后的等待时间(ms) */ - } - bootUpTimeout = 30; /* 启动超时时间(ms) */ - bus { - busType = 0; /* 总线类型:0-sdio */ - busId = 2; /* 总线号 */ - funcNum = [1]; /* SDIO功能号 */ - timeout = 1000; /* 读/写数据的超时时间 */ - blockSize = 512; /* 读/写数据的块大小 */ - } - } -} -/* 每一块芯片添加配置文件wlan_chip_<芯片名>.hcs(如:wlan_chip_hi3881.hcs),配置相关参数。以下是hi3881的配置示例 */ -root { - wlan_config { - hi3881 :& chipList { - chipHi3881 :: chipInst { - match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */ - chipName = "hi3881"; /* WLAN芯片的名称 */ - sdio { - vendorId = 0x0296; /* 厂商Id */ - deviceId = [0x5347]; /* 设备Id */ - } - } - } - } -} -``` - -2、适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化 - -``` -/* WLAN初始化挂接流程 */ -#include "hdf_device_desc.h" -#include "hdf_wifi_product.h" -#include "hdf_log.h" -#include "osal_mem.h" -#include "hdf_wlan_chipdriver_manager.h" -#include "securec.h" -#include "wifi_module.h" -#include "hi_wifi_api.h" -#include "hi_types_base.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* WLAN芯片的初始化和去初始化函数 */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device); -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); -/* WLAN芯片驱动的初始化和去初始化函数 */ -int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); -int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); - -/* 初始化mac80211与芯片侧的函数挂接 */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); - -static const char* const HI3881_DRIVER_NAME = "hisi"; - -/* WLAN芯片驱动挂接以及mac80211与芯片侧的函数挂接 */ -static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) -{ - struct HdfChipDriver *specificDriver = NULL; - if (device == NULL) { - HDF_LOGE("%s fail : channel is NULL", __func__); - return NULL; - } - (void)device; - (void)ifIndex; - specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); - if (specificDriver == NULL) { - HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); - return NULL; - } - if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { - HDF_LOGE("%s fail: memset_s fail!", __func__); - OsalMemFree(specificDriver); - return NULL; - } - - if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { - HDF_LOGE("%s fail : strcpy_s fail", __func__); - OsalMemFree(specificDriver); - return NULL; - } - specificDriver->init = Hi3881Init; - specificDriver->deinit = Hi3881Deinit; - - HiMac80211Init(specificDriver); - - return specificDriver; -} - -/* 释放WLAN芯片驱动 */ -static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - return; - } - if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { - HDF_LOGE("%s:Not my driver!", __func__); - return; - } - OsalMemFree(chipDriver); -} - -static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { - (void)factory; - return 1; -} - -/* WLAN芯片相关函数的注册 */ -static int32_t HDFWlanRegHisiDriverFactory(void) -{ - static struct HdfChipDriverFactory tmpFactory = { 0 }; - struct HdfChipDriverManager *driverMgr = NULL; - driverMgr = HdfWlanGetChipDriverMgr(); - if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; - } - tmpFactory.driverName = HI3881_DRIVER_NAME; - tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; - tmpFactory.InitChip = InitHi3881Chip; - tmpFactory.DeinitChip = DeinitHi3881Chip; - tmpFactory.Build = BuildHi3881Driver; - tmpFactory.Release = ReleaseHi3881Driver; - tmpFactory.ReleaseFactory = NULL; - if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} - -static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) -{ - (void)device; - return HDFWlanRegHisiDriverFactory(); -} - -struct HdfDriverEntry g_hdfHisiChipEntry = { - .moduleVersion = 1, - .Init = HdfWlanHisiChipDriverInit, - .moduleName = "HDF_WLAN_CHIPS" -}; - -HDF_INIT(g_hdfHisiChipEntry); -``` - -``` -#include "hdf_wifi_product.h" -#include "hi_wifi_api.h" -#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) -#include "oal_thread.h" -#include "osal_time.h" -#endif -#include "wifi_mac80211_ops.h" -#include "wal_cfg80211.h" -#include "net_adpater.h" -#include "hdf_wlan_utils.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* WLAN芯片的初始化函数 */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device) -{ - uint8_t maxPortCount = 1; - int32_t ret = HI_SUCCESS; - uint8_t maxRetryCount = 2; - if (device == NULL) { - HDF_LOGE("%s:NULL ptr!", __func__); - return HI_FAIL; - } - - do { - if (ret != HI_SUCCESS) { - if (device->reset != NULL && device->reset->Reset != NULL) { - device->reset->Reset(device->reset); - } - HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); - } - ret = hi_wifi_init(maxPortCount); - } while (ret != 0 && --maxRetryCount > 0); - - if (ret != 0) { - HDF_LOGE("%s:Init hi3881 driver failed!", __func__); - return ret; - } - return HI_SUCCESS; -} - -/* WLAN芯片的去初始化函数 */ -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) -{ - (void)device; - int32_t ret = hi_wifi_deinit(); - if (ret != 0) { - HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); - } - return ret; -} - -/* WLAN芯片驱动的初始化函数 */ -int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - HDF_LOGI("%s: start...", __func__); - hi_u16 mode = wal_get_vap_mode(); - int32_t ret; - nl80211_iftype_uint8 type; - (void)chipDriver; - - if (mode >= WAL_WIFI_MODE_BUTT) { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; - } - - if (mode == WAL_WIFI_MODE_STA) { - type = NL80211_IFTYPE_STATION; - } else if (mode == WAL_WIFI_MODE_AP) { - type = NL80211_IFTYPE_AP; - } else { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; - } - - ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); - if (ret != HI_SUCCESS) { - oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); - } - return ret; -} - -/* WLAN芯片驱动的去初始化函数 */ -int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - (void)chipDriver; - int32_t ret = wal_deinit_drv_wlan_netdev(netDevice); - if (ret != HDF_SUCCESS) { - return ret; - } - return ReleasePlatformNetDevice(netDevice); -} -``` - -3、在芯片侧初始化过程中调用netdev的init和add接口进行初始化netdev,并挂接netdev的一些函数指针 - -``` -hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len) -{ - oal_net_device_stru *netdev = HI_NULL; - - ...... - /* 初始化网络设备,获取对应的实例。*/ - netdev = NetDeviceInit(ifname, *len, LITE_OS); - oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); - ret = wal_init_netif(type, netdev, wdev); - - ...... - - return HI_SUCCESS; -} -/* 挂接netdev的一些函数指针,详细挂接函数{@link NetDeviceInterFace} */ -oal_net_device_ops_stru g_wal_net_dev_ops = -{ - .getStats = wal_netdev_get_stats, - .open = wal_netdev_open, - .stop = wal_netdev_stop, - .xmit = hmac_bridge_vap_xmit, - .ioctl = wal_net_device_ioctl, - .changeMtu = oal_net_device_change_mtu, - .init = oal_net_device_init, - .deInit = oal_net_free_netdev, -#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) - .selectQueue = wal_netdev_select_queue, -#endif - .setMacAddr = wal_netdev_set_mac_addr, -#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) - .netifNotify = HI_NULL, -#endif - .specialEtherTypeProcess = SpecialEtherTypeProcess, -}; - -hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) -{ - /* 添加网络设备到协议栈 */ - hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); - - ...... - - return HI_SUCCESS; -} -``` - -4、WifiMac80211Ops中的函数挂接实现 - -``` -/* 挂接mac80211的一些函数指针 */ - -/* 驱动需要实现的MAC层基本能力的控制接口 */ -static struct HdfMac80211BaseOps g_baseOps = { - .SetMode = WalSetMode, - .AddKey = WalAddKey, - .DelKey = WalDelKey, - .SetDefaultKey = WalSetDefaultKey, - .GetDeviceMacAddr = WalGetDeviceMacAddr, - .SetMacAddr = WalSetMacAddr, - .SetTxPower = WalSetTxPower, - .GetValidFreqsWithBand = WalGetValidFreqsWithBand, - .GetHwCapability = WalGetHwCapability -}; - -/* 驱动需要实现的MAC层STA能力的控制接口 */ -static struct HdfMac80211STAOps g_staOps = { - .Connect = WalConnect, - .Disconnect = WalDisconnect, - .StartScan = WalStartScan, - .AbortScan = WalAbortScan, - .SetScanningMacAddress = WalSetScanningMacAddress, -}; - -/* 驱动需要实现的MAC层AP能力的控制接口 */ -static struct HdfMac80211APOps g_apOps = { - .ConfigAp = WalConfigAp, - .StartAp = WalStartAp, - .StopAp = WalStopAp, - .ConfigBeacon = WalChangeBeacon, - .DelStation = WalDelStation, - .SetCountryCode = WalSetCountryCode, - .GetAssociatedStasCount = WalGetAssociatedStasCount, - .GetAssociatedStasInfo = WalGetAssociatedStasInfo -}; - -/* 初始化mac80211与芯片侧的函数挂接 */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__); - return; - } - chipDriver->ops = &g_baseOps; - chipDriver->staOps = &g_staOps; - chipDriver->apOps = &g_apOps; -} -``` - diff --git "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 1a5d63663ab7c28d50b8ddd19db7d339b1248472..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,18 +0,0 @@ -# WLAN开发指导 - -- [开发步骤](#section96091936185820) - -WLAN驱动基于HDF框架和PLATFORM框架开发,不区分OS和芯片平台,为不同厂商的WLAN模组提供统一的驱动模型,各WLAN模组厂商根据如下指导适配WLAN驱动框架。 - -## 开发步骤 - -1. 通过wifi\_config.hcs文件,配置硬件参数:module\(不同feature\),芯片等。 -2. 解析配置文件, 生成全量配置的结构体对象。 -3. Module初始化,创建Module。 -4. 挂接chip,初始化chip。 -5. 总线初始化。 -6. 上层wpa业务挂接。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->以上驱动框架适配步骤一部分已经提供(详细见开发实例),待开发人员实现的部分有:1、根据硬件,修改配置参数;2、适配挂接chip;3、测试自验证。 - diff --git "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index 869ee1da51d3e2ac53a46eaebef489ab55428c7e..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/WLAN\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,229 +0,0 @@ -# WLAN开发概述 - -- [简介](#section23087361515) -- [WLAN驱动接口架构](#section1533192516212) -- [接口说明](#section87491484213) - -## 简介 - -WLAN是基于HDF(Hardware Driver Foundation)驱动框架开发的模块,该模块可实现跨操作系统迁移,自适应器件差异,模块化拼装编译等功能。各WLAN厂商驱动开发人员可根据WLAN模块提供的向下统一接口适配各自的驱动代码,实现如下能力:建立/关闭WLAN热点、扫描、关联WLAN热点等;对HDI层向上提供能力如下:设置MAC地址、设置发射功率、获取设备的MAC地址等。[WLAN模块框架图](#fig967034316227)如下: - -**图 1** WLAN框架 - - -![](figures/zh-cn_image_0000001055299108.png) - -## WLAN驱动接口架构 - -WLAN模块有三部分对外开放的API接口,如[下图2](#fig15016395217)所示: - -1. 对HDI层提供的能力接口。 - -2. 驱动直接调用WLAN模块能力接口。 - -3. 提供给各厂商实现的能力接口。 - -**图 2** WLAN模块开放能力分布图 - - -![](figures/接口分布图4.png) - -## 接口说明 - -WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。提供的部分接口说明如[表1](#table1521573319472)所示: - -**表 1** 可直接调用的接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口名称

-

功能描述

-

wifi_module.h

-

-

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

-

基于HDF开发WLAN驱动时,创建一个WifiModule。

-

void WifiModuleDelete(struct WifiModule *module);

-

基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。

-

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

-

基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。

-

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

-

基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。

-

wifi_mac80211_ops.h

-

int32_t (*startAp)(NetDevice *netDev);

-

启动AP。

-

int32_t (*stopAp)(NetDevice *netDev);

-

停止AP。

-

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

-

开始关联。

-

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

-

取消关联。

-

hdf_netbuf.h

-

static inline void NetBufQueueInit(struct NetBufQueue *q);

-

初始化NetBuf队列。

-

struct NetBuf *NetBufAlloc(uint32_t size);

-

申请NetBuf。

-

void NetBufFree(struct NetBuf *nb);

-

释放NetBuf。

-

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

-

lwip的pbuf转换为NetBuf。

-

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

-

NetBuf转换为lwip的pbuf。

-
- -同时WLAN驱动模块也提供了需要驱动开发人员实现的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如[表2](#table74613501475)所示: - -**表 2** 需要开发人员实现的接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口名称

-

功能描述

-

net_device.h

-

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

-

初始化NetDevice。

-

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

-

获取NetDevice的状态。

-

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

-

设置Mac地址。

-

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

-

注销NetDevice。

-

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

-

打开NetDevice。

-

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

-

关闭NetDevice。

-
- -WLAN驱动模块对HDI层提供的能力接口,主要功能有:创建/销毁 IWiFi对象、设置MAC地址等。提供的部分接口说明如[表3](#table141076311618)所示: - -**表 3** HAL层对外接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

头文件

-

接口名称

-

功能描述

-

wifi_hal.h

-

-

int32_t WifiConstruct(struct IWiFi **wifiInstance);

-

创建IWiFi对象,提供IWiFi基本能力。

-

int32_t WifiDestruct(struct IWiFi **wifiInstance);

-

销毁IWiFi对象。

-

int32_t (*start)(struct IWiFi *);

-

创建HAL和驱动之间的通道及获取驱动支持的网卡信息。

-

int32_t (*stop)(struct IWiFi *);

-

销毁通道。

-

wifi_hal_base_feature.h

-

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

-

获取特性的类型。

-

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

-

设置MAC地址。

-

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

-

获取设备持久化的MAC地址。

-

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

-

设置发射功率。

-
- diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001057902344.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001123509750.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001057902344.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001123509750.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001072553354.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001123514210.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001072553354.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001123514210.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054440624.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001123540984.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054440624.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001123540984.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054007499.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001123582482.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054007499.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001123582482.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054728498.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001123675706.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054728498.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001123675706.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054726248.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001123703482.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054726248.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001123703482.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054142582.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001123742254.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054142582.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001123742254.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001057342245.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001170187071.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001057342245.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001170187071.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001054006983.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001170227689.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001054006983.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001170227689.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001057622716.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001170229891.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001057622716.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001170229891.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001053926237.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001170262141.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001053926237.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001170262141.png diff --git a/zh-cn/device-dev/driver/figures/zh-cn_image_0000001055299108.png b/zh-cn/device-dev/driver/figures/zh-cn_image_0000001170383063.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/driver/figures/zh-cn_image_0000001055299108.png rename to zh-cn/device-dev/driver/figures/zh-cn_image_0000001170383063.png diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\345\256\236\344\276\213.md" deleted file mode 100755 index 2222c0fde7eae0be2288c10291da6172cf688401..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\345\256\236\344\276\213.md" +++ /dev/null @@ -1,583 +0,0 @@ -# 传感器驱动开发实例 - -基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](驱动开发.md)。加速度传感器选择通讯接口方式为I2C,厂家选择博世BMI160加速度传感器。 - -1. 加速度计传感器驱动入口注册 - -- 加速度计传感器驱动入口函数实现 - -``` -/* 注册加速度计传感器入口数据结构体对象 */ -struct HdfDriverEntry g_sensorAccelDevEntry = { - .moduleVersion = 1, /* 加速度计传感器模块版本号 */ - .moduleName = "HDF_SENSOR_ACCEL", /* 加速度计传感器模块名,要与device_info.hcs文件里的加速度计moduleName字段值一样*/ - .Bind = BindAccelDriver, /* 加速度计传感器绑定函数 */ - .Init = InitAccelDriver, /* 加速度计传感器初始化函数 */ - .Release = ReleaseAccelDriver, /* 加速度计传感器资源释放函数 */ -}; - -/* 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 */ -HDF_INIT(g_sensorAccelDevEntry); -``` - -- 加速度计传感器设备配置描述 - -加速度传感器模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](配置管理.md)介绍。 - -``` -/* 加速度计传感器设备HCS配置 */ -device_sensor_accel :: device { - device0 :: deviceNode { - policy = 1; /* policy字段是驱动服务发布的策略 */ - priority = 105; /* 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */ - preload = 2; /* 驱动按需加载字段,0表示加载,2表示不加载 */ - permission = 0664; /* 驱动创建设备节点权限 */ - moduleName = "HDF_SENSOR_ACCEL"; /* 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */ - serviceName = "sensor_accel"; /* 驱动对外发布服务的名称,必须唯一 */ - deviceMatchAttr = "hdf_sensor_accel_driver"; /* 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 */ - } -} -``` - -1. 加速度计传感器驱动初始化和去初始化 - -- 初始化入口函数init - -``` -/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */ -int32_t BindAccelDriver(struct HdfDeviceObject *device) -{ - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - - static struct IDeviceIoService service = { - .object = {0}, - .Dispatch = DispatchAccel, - }; - device->service = &service; - - return HDF_SUCCESS; -} -/*在探测到器件在位后,需要调用RegisterAccelChipOps注册差异化适配函数*/ -int32_t RegisterAccelChipOps(struct AccelOpsCall *ops) -{ - struct AccelDrvData *drvData = NULL; - - CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM); - - drvData = AccelGetDrvData(); - drvData->ops.Init = ops->Init; - drvData->ops.ReadData = ops->ReadData; - return HDF_SUCCESS; -} -/* 挂载加速度计传感器驱动归一化的接口函数 */ -static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo) -{ - struct AccelDrvData *drvData = AccelGetDrvData(); - - (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); - deviceInfo->ops.GetInfo = SetAccelInfo; - deviceInfo->ops.Enable = SetAccelEnable; - deviceInfo->ops.Disable = SetAccelDisable; - deviceInfo->ops.SetBatch = SetAccelBatch; - deviceInfo->ops.SetMode = SetAccelMode; - deviceInfo->ops.SetOption = SetAccelOption; - - if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), - &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) { - HDF_LOGE("%s: copy sensor info failed", __func__); - return HDF_FAILURE; - } - /* 传感器类型标识可以在数据HCS配置文件里面配置,也可以在此处 */ - drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER; - drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER; - - return HDF_SUCCESS; -} -/* 传感器寄存器初始化操作 */ -static int32_t InitAccelAfterConfig(void) -{ - struct SensorDeviceInfo deviceInfo; - - if (InitAccelConfig() != HDF_SUCCESS) { - HDF_LOGE("%s: init accel config failed", __func__); - return HDF_FAILURE; - } - - if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: init accel ops failed", __func__); - return HDF_FAILURE; - } - - if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: add accel device failed", __func__); - return HDF_FAILURE; - } - - return HDF_SUCCESS; -} -/*通过器件探测函数,挂载器件差异化函数接口*/ -static int32_t DetectAccelChip(void) -{ - int32_t num; - int32_t ret; - int32_t loop; - struct AccelDrvData *drvData = AccelGetDrvData(); - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - - num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]); - for (loop = 0; loop < num; ++loop) { - if (g_accelDetectIfList[loop].DetectChip != NULL) { - ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg); - if (ret == HDF_SUCCESS) { - drvData->detectFlag = true; - break; - } - } - } - - if (loop == num) { - HDF_LOGE("%s: detect accel device failed", __func__); - drvData->detectFlag = false; - return HDF_FAILURE; - } - return HDF_SUCCESS; -} -/* 加速度计传感器驱动初始化入口函数,主要功能为对传感器私有数据的结构体对象进行初始化,传感器HCS数据配置对象空间分配,传感器HCS数据配置初始化入口函数调用,传感器设备探测是否在位功能,传感器数据上报定时器创建,传感器归一化接口挂载,传感器设备注册功能 */ -int32_t InitAccelDriver(struct HdfDeviceObject *device) -{ - /* 获取传感器私有数据结构体对象 */ - struct AccelDrvData *drvData = AccelGetDrvData(); - - /* 同类型传感器不同厂家设备探测时,判断此类型传感器是否已经在位,若已经在位,无需再继续探测,直接返回 */ - if (drvData->detectFlag) { - HDF_LOGE("%s: accel sensor have detected", __func__); - return HDF_SUCCESS; - } - - CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - /* 分配存放传感器数据配置的私有结构体数据对象,需要在驱动释放时释放分配的资源空间 */ - drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg)); - if (drvData->accelCfg == NULL) { - HDF_LOGE("%s: malloc sensor config data failed", __func__); - return HDF_FAILURE; - } - - drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; - /* 初始化传感器配置数据主要是解析传感器通讯总线配置类型信息,传感器基本信息,传感器属性信息,传感器是否在位信息,寄存器分组信息 */ - if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: get sensor base config failed", __func__); - goto Base_CONFIG_EXIT; - } - - if (DetectAccelChip() != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor detect device no exist", __func__); - goto DETECT_CHIP_EXIT; - } - drvData->detectFlag = true; - if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) { - HDF_LOGE("%s: detect sensor device failed", __func__); - goto REG_CONFIG_EXIT; - } - - if (InitAccelAfterConfig() != HDF_SUCCESS) { - HDF_LOGE("%s: init accel after config failed", __func__); - goto INIT_EXIT; - } - - HDF_LOGI("%s: init accel driver success", __func__); - return HDF_SUCCESS; - -INIT_EXIT: - DestroySensorThread(&drvData->thread, &drvData->threadStatus); - (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); -REG_CONFIG_EXIT: - ReleaseSensorAllRegConfig(drvData->accelCfg); - (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); -DETECT_CHIP_EXIT: - drvData->detectFlag = false; -BASE_CONFIG_EXIT: - drvData->accelCfg->root = NULL; - drvData->accelCfg->regCfgGroup = NULL; - OsalMemFree(drvData->accelCfg); - drvData->accelCfg = NULL; - return HDF_FAILURE; -} - -/* 释放驱动初始化时分配的资源 */ -void ReleaseAccelDriver(struct HdfDeviceObject *device) -{ - (void)device; - struct AccelDrvData *drvData = NULL; - - drvData = AccelGetDrvData(); - (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus); - (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER); - drvData->detectFlag = false; - - if (drvData->accelCfg != NULL) { - drvData->accelCfg->root = NULL; - drvData->accelCfg->regCfgGroup = NULL; - ReleaseSensorAllRegConfig(drvData->accelCfg); - (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg); - OsalMemFree(drvData->accelCfg); - drvData->accelCfg = NULL; - } - - drvData->initStatus = false; -} -``` - -1. 加速度计传感器寄存器组配置信息 - -加速度计传感器数据配置只需要按照模板配置即可,基于模板配置的解析功能已经在**InitSensorConfigData**函数完成,只需初始化时调用即可。如果有新增配置项,需要同步修改此函数。 - -``` -加速度传感器数据配置模板(accel_config.hcs) -root { - sensorAccelConfig { - accelChipConfig { - /* 传感器设备信息模板 */ - template sensorInfo { - sensorName = "accelerometer"; /* 加速度计名字,字符最大长度16字节 */ - vendorName = "borsh_bmi160"; /* 传感器设备厂商,字符最大长度16字节 */ - firmwareVersion = "1.0"; /* 传感器固件版本号,默认1.0,字符最大长度16字节 */ - hardwareVersion = "1.0"; /* 传感器硬件版本号,默认1.0,字符最大长度16字节 */ - sensorTypeId = 1; /* 传感器类型编号,详见{@link SensorTypeTag} */ - sensorId = 1; /* 传感器的标识号,有传感器驱动开发者定义,推荐用{@link SensorTypeTag}枚举 */ - maxRange = 8; /* 传感器的最大量程,根据开发者需要配置 */ - precision = 0; /* 传感器的精度,与上报数据配合使用,上报数据结构体{@link SensorEvents } */ - power = 230; /* 传感器的功耗 */ - } - /* 传感器使用的总线类型和配置信息模板 */ - template sensorBusConfig { - busType = 0; /* 0:i2c 1:spi */ - busNum = 6; /* 芯片上分配给传感器的器件号 */ - busAddr = 0; /* 芯片上分配给传感器的地址 */ - regWidth = 1; /* 传感器寄存器地址宽度 */ - regBigEndian = 0; /* 传感器寄存器大小端 */ - } - /* 传感器设备属性模板 */ - template sensorAttr { - chipName = ""; /* 传感器芯片名字 */ - chipIdRegister = 0xf; /* 传感器在位检测寄存器地址 */ - chipIdValue = 0xd1; /* 校验传感器在位检测寄存器值 */ - } - } - } -} - -/* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */ -root { - sensorAccelConfig { - accel_bmi160_chip_config : accelChipConfig { - match_attr = "hdf_sensor_accel_driver"; /* 需要和加速度传感器设备配置match_attr字段保持一致 */ - accelInfo :: sensorInfo { - vendorName = "borsh_bmi160"; - sensorTypeId = 1; - sensorId = 1; - } - accelBusConfig :: sensorBusConfig { - busType = 0; /* i2c通讯方式 */ - busNum = 6; - busAddr = 0x68; - regWidth = 1; /* 1字节位宽 */ - } - accelAttr :: sensorAttr { - chipName = "bmi160"; - chipIdRegister = 0x00; - chipIdValue = 0xd1; - } - accelRegConfig { - /* regAddr: 寄存器地址 - value: 寄存器值 - mask: 寄存器值的掩码 - len: 寄存器值的数据长度(字节) - delay: 配置寄存器延时(ms) - opsType:操作类型 0-无 1-读 2-写 3-读并检查 4-位更新 - calType: 计算类型 0-无 1-写 2-取反 3-异或 4-左移 5-右移 - shiftNum: 移动位数 - debug: 调试开关,0-调试关闭 1-调试打开 - save: 保存数据开关,0-不保存数据 1-保存数据 - */ - /* 传感器寄存器操作分组,按照分组进行有序配置 */ - /* 寄存器地址, 寄存器值, 寄存器值的掩码, 寄存器值的数据长度, 配置寄存器延时, 操作类型, 计算类型, 移动位数, 调试开关, 保存开关 */ - /* 初始化寄存器组 */ - initSeqConfig = [ - 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0, - 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 - ]; - /* 使能寄存器组 */ - enableSeqConfig = [ - 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0, - 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0, - 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0 - ]; - /* 去使能寄存器组 */ - disableSeqConfig = [ - 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0 - ]; - } - } - } -} -``` - -1. 加速度计传感器驱动操作接口实现 - -开发者需要根据每种类型的传感器实现归一化接口。 - -``` -/* 不使用函数暂时置空 */ -static int32_t SetAccelInfo(struct SensorBasicInfo *info) -{ - (void)info; - - return HDF_ERR_NOT_SUPPORT; -} -/* 下发使能寄存器组的配置 */ -static int32_t SetAccelEnable(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor disable config failed", __func__); - return HDF_FAILURE; - } - - drvData->threadStatus = SENSOR_THREAD_RUNNING; - - return HDF_SUCCESS; -} -/* 下发去使能寄存器组的配置 */ -static int32_t SetAccelDisable(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM); - - ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel sensor disable config failed", __func__); - return HDF_FAILURE; - } - - drvData->threadStatus = SENSOR_THREAD_STOPPED; - - return HDF_SUCCESS; -} -/* 配置传感器采样率和数据上报间隔 */ -static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval) -{ - (void)interval; - - struct AccelDrvData *drvData = AccelGetDrvData(); - drvData->interval = samplingInterval; - - return HDF_SUCCESS; -} -/* 设置传感器工作模式,当前支持实时模式 */ -static int32_t SetAccelMode(int32_t mode) -{ - return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE; -} -/* 设置传感器可选配置 */ -static int32_t SetAccelOption(uint32_t option) -{ - (void)option; - return HDF_ERR_NOT_SUPPORT; -} -``` - -- 差异化处理接口 - - ``` - /* 器件探测时,如果探测成功,则注册差异化处理函数到accel驱动模型里 */ - int32_t DetectAccelBim160Chip(struct SensorCfgData *data) - { - int32_t ret; - struct AccelOpsCall ops; - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - - if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) { - return HDF_SUCCESS; - } - ret = InitAccelPreConfig(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: init BMI160 bus mux config", __func__); - return HDF_FAILURE; - } - if (DetectSensorDevice(data) != HDF_SUCCESS) { - return HDF_FAILURE; - } - - /* 差异化处理函数 */ - ops.Init = InitBmi160; - ops.ReadData = ReadBmi160Data; - ret = RegisterAccelChipOps(&ops); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: register BMI160 accel failed", __func__); - (void)ReleaseSensorBusHandle(&data->busCfg); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - /* 初始化处理函数 */ - static int32_t InitBmi160(struct SensorCfgData *data) - { - int32_t ret; - - CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); - ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: bmi160 sensor init config failed", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; - } - /* 数据处理函数 */ - int32_t ReadBmi160Data(struct SensorCfgData *data) - { - int32_t ret; - struct AccelData rawData = { 0, 0, 0 }; - int32_t tmp[ACCEL_AXIS_NUM]; - struct SensorReportEvent event; - - (void)memset_s(&event, sizeof(event), 0, sizeof(event)); - - ret = ReadBmi160RawData(data, &rawData, &event.timestamp); - if (ret != HDF_SUCCESS) { - return HDF_FAILURE; - } - - event.sensorId = SENSOR_TAG_ACCELEROMETER; - event.option = 0; - event.mode = SENSOR_WORK_MODE_REALTIME; - - rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G; - rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G; - rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G; - - tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT; - - event.dataLen = sizeof(tmp); - event.data = (uint8_t *)&tmp; - ret = ReportSensorEvent(&event); - return ret; - } - ``` - -- 数据处理函数 - -创建传感器定时器,按照配置的采样率定时采样,并上报给数据订阅者。 - -``` -/* 传感器定时工作线程 */ -static int32_t ReadAccelDataThreadWorker(void *arg) -{ - (void)arg; - int64_t interval; - struct AccelDrvData *drvData = AccelGetDrvData(); - - drvData->threadStatus = SENSOR_THREAD_START; - while (true) { - if (drvData->threadStatus == SENSOR_THREAD_RUNNING) { - if (drvData->ops.ReadData != NULL) { - (void)drvData->ops.ReadData(drvData->accelCfg); - } - interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT)); - OsalMSleep(interval); - } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) { - break; - } else { - OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT); - } - - if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) { - continue; - } - } - - return HDF_SUCCESS; -} -/* 创建传感器定时器和器件初始化 */ -static int32_t InitAccelConfig(void) -{ - int32_t ret; - struct AccelDrvData *drvData = AccelGetDrvData(); - - if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) { - HDF_LOGE("%s: accel thread have created", __func__); - return HDF_SUCCESS; - } - - ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel create thread failed", __func__); - drvData->threadStatus = SENSOR_THREAD_NONE; - return HDF_FAILURE; - } - - CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM); - - ret = drvData->ops.Init(drvData->accelCfg); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: accel create thread failed", __func__); - drvData->threadStatus = SENSOR_THREAD_NONE; - return HDF_FAILURE; - } - drvData->initStatus = true; - return HDF_SUCCESS; -} -``` - -- 主要的数据结构 - -``` -/* 传感器转换单位*/ -#define SENSOR_CONVERT_UNIT 1000 -#define SENSOR_1K_UNIT 1024 -/* 传感器2g对应灵敏度转换值 */ -#define BMI160_ACC_SENSITIVITY_2G 61 -/* 传感器数据采样寄存器地址 */ -#define BMI160_ACCEL_X_LSB_ADDR 0X12 -#define BMI160_ACCEL_X_MSB_ADDR 0X13 -#define BMI160_ACCEL_Y_LSB_ADDR 0X14 -#define BMI160_ACCEL_Y_MSB_ADDR 0X15 -#define BMI160_ACCEL_Z_LSB_ADDR 0X16 -#define BMI160_ACCEL_Z_MSB_ADDR 0X17 -/* 传感器数据维度 */ -enum AccelAxisNum { - ACCEL_X_AXIS = 0, - ACCEL_Y_AXIS = 1, - ACCEL_Z_AXIS = 2, - ACCEL_AXIS_NUM = 3, -}; -/* 传感器每个维度值 */ -struct AccelData { - int32_t x; - int32_t y; - int32_t z; -}; -/* 传感器私有数据结构体 */ -struct AccelDrvData { - bool detectFlag; - uint8_t threadStatus; - uint8_t initStatus; - int64_t interval; - struct SensorCfgData *accelCfg; - struct OsalThread thread; - struct AccelOpsCall ops; -}; -/* 差异化适配函数 */ -struct AccelOpsCall { - int32_t (*Init)(struct SensorCfgData *data); - int32_t (*ReadData)(struct SensorCfgData *data); -}; -``` - diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index a544f96506316543a7c9444cc156b80d2f366e7c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,16 +0,0 @@ -# 传感器驱动开发指导 - -- [开发步骤](#section18816105182315) - -Sensor驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同Sensor器件提供统一的驱动模型。本篇开发指导以加速度计传感器为例,介绍传感器驱动开发。 - -## 开发步骤 - -1. 加速度计传感器驱动注册。HDF驱动框架会提供统一的驱动管理模型,通过加速计传感器模块配置信息,识别并加载对应模块驱动。 -2. 加速度计传感器驱动初始化和去初始化。HDF驱动框架通过init入口函数,依次启动传感器设备驱动加载和分配传感器设备数据配置资源。HDF驱动框架通过release函数,释放驱动加载的资源和配置。 -3. 加速度计传感器寄存器组配置解析。不同类型传感器需要在hcs里配置器件对应的HCS配置文件,然后再设备驱动启动过程中探测器件是否在位,然后加载对应的配置文件,生成配置的结构体对象。 -4. 加速度计传感器驱动操作接口实现。实现各个类型传感器归一化驱动接口,如init,GetInfo,Enable,Disable,SetBatch,SetMode,SetOption,ReadSensorData等函数,完成传感器驱动配置下发和数据上报功能。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->传感器驱动模型已经提供一部分能力集,包括驱动设备管理能力,抽象总线和平台操作接口能力,通用配置操作接口能力,配置解析操作接口能力,接口参考[表2](传感器驱动开发概述.md#table1156812588320)。需要开发人员实现部分有:1、传感器部分操作接口([表3](传感器驱动开发概述.md#table1083014911336));2、传感器HCS差异化数据配置;3、驱动基本功能验证。 - diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\246\202\350\277\260.md" deleted file mode 100755 index 6319a9086c6c8754c6a8d36cf9abc7827d24e20b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\345\274\200\345\217\221\346\246\202\350\277\260.md" +++ /dev/null @@ -1,244 +0,0 @@ -# 传感器驱动开发概述 - -- [简介](#section667413271505) -- [接口说明](#section7255104114110) - -## 简介 - -Sensor(传感器)驱动模块为上层Sensor服务系统提供稳定的Sensor基础能力API,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置等功能;基于HDF(**H**ardware **D**river **F**oundation)驱动框架开发的Sensor驱动模型,实现跨操作系统迁移,器件差异配置等功能。Sensor驱动模型如下图1所示: - -**图 1** Sensor驱动模型图 -![](figures/Sensor驱动模型图.png "Sensor驱动模型图") - -Sensor驱动模型对外开放的API接口能力如下: - -- 提供Sensor HDI(**H**ardware **D**river **I**nterface)能力接口,简化服务开发。 -- 提供Sensor驱动模型能力接口:依赖HDF驱动框架实现Sensor器件驱动的注册,加载,去注册,器件探测等能力,提供同一类型Sensor器件驱动归一接口, 寄存器配置解析操作接口,总线访问抽象接口,平台抽象接口。 -- 提供开发者实现的能力接口:依赖HDF驱动框架的HCS\(**H**DF **C**onfiguration **S**ource\)配置管理,根据同类型Sensor差异化配置,实现Sensor器件参数序列化配置和器件部分操作接口,简化Sensor器件驱动开发。 - -## 接口说明 - -Sensor驱动模型对HDI开放的API接口功能,参考表1。 - -**表 1** Sensor驱动模型对外API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

功能描述

-

查询操作

-

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

-

获取系统中注册的所有传感器信息,一种类型传感器信息包括传感器名字、设备厂商、固件版本号、硬件版本号、传感器类型编号、传感器标识、最大量程、精度、功耗。

-

配置操作

-

int32_t Enable(int32_t sensorId)

-

使能一种传感器设备,只有数据订阅者使能传感器后,才能获取订阅的传感器数据。

-

int32_t Disable(int32_t sensorId)

-

去使能一种传感器设备。

-

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

-

设置一种传感器的数据采样间隔和数据上报间隔。

-

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

-

设置一种传感器的工作模式,不同的工作模式,上报数据方式不同。

-

int32_t SetOption(int32_t sensorId, uint32_t option)

-

设置一种传感器量程,精度等可选配置。

-

数据订阅操作

-

int32_t Register(RecordDataCallback cb)

-

订阅者注册传感器数据回调函数,系统会将获取到的传感器数据上报给订阅者。

-

int32_t Unregister(void)

-

订阅者去注册传感器数据回调函数。

-

接口实例

-

const struct SensorInterface *NewSensorInterfaceInstance(void)

-

创建传感器接口实例。

-

int32_t FreeSensorInterfaceInstance(void)

-

释放传感器接口实例。

-
- -Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无需实现,直接使用,参考表2: - -**表 2** Sensor驱动模型对驱动开发者开放的功能接口列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

功能描述

-

设备管理操作接口

-

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

-

添加当前类型的传感器设备到传感器设备管理。

-

int32_t DeleteSensorDevice(int32_t sensorId)

-

删除传感器设备管理里指定的传感器设备。

-

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

-

上报指定类型传感器的数据到用户侧。

-

Sensor抽象总线和平台操作接口

-

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

-

按照配置的总线方式,读取传感器寄存器配置数据。

-

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

-

按照配置的总线方式,传感器配置数据写入寄存器。

-

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

-

创建指定传感器的定时线程,用于传感器数据上报处理。

-

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

-

销毁传感器创建的定时线程。

-

通用配置操作接口

-

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

-

根据传感器总线类型信息,下发寄存器分组配置。

-

配置解析操作接口

-

-

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

-

根据传感器设备HCS资源配置,获取传感器信息,总线配置信息,属性配置等基本配置信息,并初始化对应的基本配置数据结构体。

-

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

-

根据传感器设备HCS资源配置,解析寄存器分组信息,并初始化配置数据结构体。

-

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

-

释放传感器配置数据结构体里分配的资源。

-

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

-

获取传感器总线句柄信息。

-

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

-

释放传感器句柄信息。

-
- -Sensor驱动模型要求驱动开发者实现的接口功能,参考表3 - -**表 3** Sensor驱动模型要求驱动开发者实现的接口列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

功能描述

-

基本功能操作

-

int32_t init(void)

-

传感器器设备探测成功后,需要对传感器器设备初始化配置。

-

int32_t GetInfo(struct SensorBasicInfo *info)

-

从传感器器设备的HCS配置里,获取当前传感器设备的基本信息。

-

int32_t Enable(void)

-

根据当前传感器器设备的HCS配置,下发传感器设备使能操作组的寄存器配置。

-

int32_t Disable(void)

-

根据当前传感器器设备的HCS配置,下发传感器设备去使能操作组的寄存器配置。

-

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

-

根据数据采样率和数据上报间隔,配置当前传感器设备的数据上报线程处理时间。

-

int32_t SetMode(int32_t mode)

-

配置当前传感器设备数据上报方式。

-

int32_t SetOption(uint32_t option)

-

根据可选配置,下发量程,精度等寄存器配置。

-

void ReadSensorData(void)

-

实现传感器的数据读取函数。

-
- -接口实现参考[SENSOR](传感器驱动开发实例.md)章节。 - diff --git "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\346\265\213\350\257\225\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\346\265\213\350\257\225\346\214\207\345\257\274.md" deleted file mode 100755 index 7bf51251601d13df14cc81398af44c826228f2d9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\344\274\240\346\204\237\345\231\250\351\251\261\345\212\250\346\265\213\350\257\225\346\214\207\345\257\274.md" +++ /dev/null @@ -1,82 +0,0 @@ -# 传感器驱动测试指导 - -驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 - -``` -/* 标识是否上报传感器数据 */ -static int32_t g_sensorDataFlag = 0; -/* 保持获取的传感器接口实例地址 */ -static const struct SensorInterface *g_sensorDev = nullptr; - -/* 订阅者注册数据上报函数 */ -static int SensorTestDataCallback(struct SensorEvents *event) -{ - if (event == nullptr) { - return -1; - } - float *data = (float*)event->data; - printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp, - event->sensorId, (*data), *(data + 1), *(data + g_axisZ)); - if (*data > 1e-5) { - g_sensorDataFlag = 1; - } - return 0; -} -/* 用例执行前,初始化传感器接口实例 */ -void HdfSensorTest::SetUpTestCase() -{ - g_sensorDev = NewSensorInterfaceInstance(); - if (g_sensorDev == nullptr) { - printf("test sensorHdi get Module instace failed\n\r"); - } -} -/* 用例资源释放 */ -void HdfSensorTest::TearDownTestCase() -{ - if (g_sensorDev != nullptr) { - FreeSensorInterfaceInstance(); - g_sensorDev = nullptr; - } -} -/* 传感器驱动测试验证 */ -HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0) -{ - int32_t sensorInterval = 1000000000; /* 数据采样率单位纳秒 */ - int32_t pollTime = 5; /* 数据采样时间单位秒 */ - int32_t accelSensorId = 1; /* 加速度传感器类型标识为1 */ - int32_t count = 0; - int ret; - struct SensorInformation *sensorInfo = nullptr; - - ret = g_sensorDev->Register(SensorTestDataCallback) - EXPECT_EQ(SENSOR_NULL_PTR, ret); - - ret = g_sensorDev->GetAllSensors(&sensorInfo, &count); - EXPECT_EQ(0, ret); - if (sensorInfo == nullptr) { - EXPECT_NE(nullptr, sensorInfo); - return; - } - /* 打印获取的传感器列表 */ - for (int i = 0; i < count; i++) { - printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName); - } - ret = g_sensorDev->Enable(accelSensorId); - EXPECT_EQ(0, ret); - g_sensorDataFlag = 0; - - ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime); - EXPECT_EQ(0, ret); - /* 在时间pollTime内,观察输出打印数据 */ - OsalSleep(pollTime); - EXPECT_EQ(1, g_sensorDataFlag); - - ret = g_sensorDev->Disable(accelSensorId); - g_sensorDataFlag = 0; - EXPECT_EQ(0, ret); - - ret = g_sensorDev->Unregister(); - EXPECT_EQ(0, ret); -} -``` - diff --git "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\271\263\345\217\260.md" "b/zh-cn/device-dev/driver/\345\271\263\345\217\260\351\251\261\345\212\250.md" old mode 100755 new mode 100644 similarity index 79% rename from "zh-cn/device-dev/driver/\351\251\261\345\212\250\345\271\263\345\217\260.md" rename to "zh-cn/device-dev/driver/\345\271\263\345\217\260\351\251\261\345\212\250.md" index 7d5a5437f750b6c60b8b249c40c5ae1c6ab0d30b..3f7f75b5eb0d0fc9b334f9c7afe8c21174bff85a --- "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\271\263\345\217\260.md" +++ "b/zh-cn/device-dev/driver/\345\271\263\345\217\260\351\251\261\345\212\250.md" @@ -1,4 +1,4 @@ -# 驱动平台 +# 平台驱动 - **[GPIO](GPIO.md)** diff --git "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\345\256\236\344\276\213.md" deleted file mode 100755 index b8d64e53b754037b4ec6335e683f32bfbd1b6a34..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\345\256\236\344\276\213.md" +++ /dev/null @@ -1,86 +0,0 @@ -# 看门狗使用实例 - -本例程提供看门狗的完整使用流程。 - -在本例程中,我们打开一个看门狗设备,设置超时时间并启动计时: - -- 首先定期喂狗,即按时清除看门狗定时器,确保系统不会因定时器超时而复位。 -- 接着再停止喂狗,观察定时器到期后系统是否发生复位行为。 - -示例如下: - -``` -#include "watchdog_if.h" -#include "hdf_log.h" -#include "osal_irq.h" -#include "osal_time.h" - -#define WATCHDOG_TEST_TIMEOUT 2 -#define WATCHDOG_TEST_FEED_TIME 6 - -static int32_t TestCaseWatchdog(void) -{ - int32_t i; - int32_t ret; - uint32_t timeout; - DevHandle handle = NULL; - - /* 打开0号看门狗设备 */ - handle = WatchdogOpen(0); - if (handle == NULL) { - HDF_LOGE("Open watchdog fail!"); - return -1; - } - - /* 设置超时时间 */ - ret = WatchdogSetTimeout(handle, WATCHDOG_TEST_TIMEOUT); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: set timeout fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - - /* 回读设置的超时时间值 */ - ret = WatchdogGetTimeout(handle, &timeout); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); - - /* 启动看门狗,开始计时 */ - ret = WatchdogStart(handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - - /* 每隔1S喂狗一次 */ - for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { - HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); - ret = WatchdogFeed(handle); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); - WatchdogClose(handle); - return ret; - } - OsalSleep(1); - } - /* 由于喂狗间隔小于超时时间,系统不会发生复位,此日志可以正常打印 */ - HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); - - /* 接下来持续不喂狗,使得看门狗计时器超时 */ - for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { - HDF_LOGE("%s: watiting dog buck %d times... \n", __func__, i); - OsalSleep(1); - } - - /* 当不喂狗时间到达之前设定的超时时间的时候,系统会发生复位,理论上观察不到此日志的打印 */ - HDF_LOGE("%s: dog has't buck!!! \n", __func__, i); - WatchdogClose(handle); - return -1; -} -``` - diff --git "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index b8fd5753d462e8fd80df1f64d6d757d385d3998f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,391 +0,0 @@ -# 看门狗使用指导 - -- [使用流程](#section0719414187) -- [打开看门狗设备](#section198171379261) -- [获取看门狗状态](#section206592910275) -- [设置超时时间](#section19605128182714) -- [获取超时时间](#section11111516208) -- [启动看门狗](#section141174192814) -- [喂狗](#section179101435113910) -- [停止看门狗](#section15282123192816) -- [关闭看门狗设备](#section7857850173411) - -## 使用流程 - -使用看门狗的一般流程如[图1](#fig19134125410189)所示。 - -**图 1** 看门狗使用流程图 - - -![](figures/zh-cn_image_0000001057622716.png) - -## 打开看门狗设备 - -在操作看门狗之前,需要使用WatchdogOpen打开一个看门狗设备,一个系统可能有多个看门狗,通过ID号来打开指定的看门狗设备: - -int32\_t WatchdogOpen\(int16\_t wdtId\); - -**表 1** WatchdogOpen参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

wdtId

-

看门狗设备号

-

返回值

-

返回值描述

-

NULL

-

打开失败

-

DevHandle类型指针

-

看门狗设备句柄

-
- -``` -DevHandle handle = NULL; -handle = WatchdogOpen(0); /* 打开0号看门狗设备 */ -if (handle == NULL) { - HDF_LOGE("WatchdogOpen: failed, ret %d\n", ret); - return; -} -``` - -## 获取看门狗状态 - -int32\_t WatchdogGetStatus\(DevHandle handle, int32\_t \*status\); - -**表 2** WatchdogGetStatus参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

status

-

获取到的启动状态指针

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -int32_t status; -/* 获取Watchdog启动状态 */ -ret = WatchdogGetStatus(handle, &status); -if (ret != 0) { - HDF_LOGE("WatchdogGetStatus: failed, ret %d\n", ret); - return; -} -``` - -## 设置超时时间 - -int32\_t WatchdogSetTimeout\(PalHandle \*handle, uint32\_t seconds\); - -**表 3** WatchdogSetTimeout参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

seconds

-

超时时间,单位为秒

-

返回值

-

返回值描述

-

0

-

设置成功

-

负数

-

设置失败

-
- -``` -int32_t ret; -uint32_t timeOut = 60; -/* 设置超时时间,单位:秒 */ -ret = WatchdogSetTimeout(handle, timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogSetTimeout: failed, ret %d\n", ret); - return; -} -``` - -## 获取超时时间 - -int32\_t WatchdogGetTimeout\(PalHandle \*handle, uint32\_t \*seconds\); - -**表 4** WatchdogGetTimeout参数和返回值描述 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

seconds

-

接收超时时间的指针,单位为秒

-

返回值

-

返回值描述

-

0

-

获取成功

-

负数

-

获取失败

-
- -``` -int32_t ret; -uint32_t timeOut; -/* 获取超时时间,单位:秒 */ -ret = WatchdogGetTimeout(handle, &timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogGetTimeout: failed, ret %d\n", ret); - return; -} -``` - -## 启动看门狗 - -int32\_t WatchdogStart\(DevHandle handle\); - -**表 5** WatchdogStart参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

返回值

-

返回值描述

-

0

-

启动成功

-

负数

-

启动失败

-
- -``` -int32_t ret; -/* 启动看门狗 */ -ret = WatchdogStart(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStart: failed, ret %d\n", ret); - return; -} -``` - -## 喂狗 - -int32\_t WatchdogFeed\(DevHandle handle\); - -**表 6** WatchdogFeed参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

返回值

-

返回值描述

-

0

-

喂狗成功

-

负数

-

喂狗失败

-
- -``` -int32_t ret; -/* 喂狗 */ -ret = WatchdogFeed(handle); -if (ret != 0) { - HDF_LOGE("WatchdogFeed: failed, ret %d\n", ret); - return; -} -``` - -## 停止看门狗 - -int32\_t WatchdogStop\(DevHandle handle\); - -**表 7** WatchdogStop参数和返回值描述 - - - - - - - - - - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-

返回值

-

返回值描述

-

0

-

停止成功

-

负数

-

停止失败

-
- -``` -int32_t ret; -/* 停止看门狗 */ -ret = WatchdogStop(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStop: failed, ret %d\n", ret); - return; -} - -``` - -## 关闭看门狗设备 - -当操作完毕时,使用WatchdogClose关闭打开的设备句柄: - -void WatchdogClose\(DevHandle handle\); - -**表 8** WatchdogClose参数和返回值描述 - - - - - - - - - - -

参数

-

参数描述

-

handle

-

看门狗设备句柄

-
- -``` -/* 关闭看门狗 */ -ret = WatchdogClose(handle); -``` - diff --git "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\346\246\202\350\277\260.md" "b/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\346\246\202\350\277\260.md" deleted file mode 100755 index 467e21ba08ef672247327cd100b8c2db7e4f9a01..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/driver/\347\234\213\351\227\250\347\213\227\346\246\202\350\277\260.md" +++ /dev/null @@ -1,78 +0,0 @@ -# 看门狗概述 - -- [简介](#section3579126111816) -- [接口说明](#section17429111981812) - -## 简介 - -看门狗(watchdog),又叫看门狗计时器(watchdog timer),是一种硬件的计时设备,当系统的主程序发生某些错误时,导致未及时清除看门狗计时器的计时值,这时看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。 - -## 接口说明 - -**表 1** 看门狗 API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

打开/关闭看门狗

-

WatchdogOpen

-

打开看门狗设备

-

WatchdogClose

-

关闭看门狗设备

-

启动/停止看门狗

-

WatchdogStart

-

启动看门狗

-

WatchdogStop

-

停止看门狗

-

设置/获取超时时间

-

WatchdogSetTimeout

-

设置看门狗超时时间

-

WatchdogGetTimeout

-

获取看门狗超时时间

-

获取看门狗状态

-

WatchdogGetStatus

-

获取看门狗状态

-

清除看门狗定时器

-

WatchdogFeed

-

清除看门狗定时器(喂狗)

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->本文涉及看门狗的所有接口,仅限内核态使用,不支持在用户态使用。 - diff --git "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\274\200\345\217\221.md" "b/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\274\200\345\217\221.md" index e35139db59ca7df253ee0134e5afb379d596e300..001ce6dd7a58b2f9f3bda3304f213152ed54fc37 100755 --- "a/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\274\200\345\217\221.md" +++ "b/zh-cn/device-dev/driver/\351\251\261\345\212\250\345\274\200\345\217\221.md" @@ -5,9 +5,9 @@ ## 驱动模型介绍 -HDF框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个host里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个node,HDF框架管理驱动模型如下图所示: +HDF框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个host里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个node,HDF驱动模型如下图所示: -**图 1** HDF框架管理驱动模型 +**图 1** HDF驱动模型 ![](figures/zh-cn_image_0000001054564784.png) diff --git "a/zh-cn/device-dev/get-code/Docker\347\274\226\350\257\221\347\216\257\345\242\203.md" "b/zh-cn/device-dev/get-code/Docker\347\274\226\350\257\221\347\216\257\345\242\203.md" new file mode 100644 index 0000000000000000000000000000000000000000..c15f1861f152e8616fc86c629472fdef6a0df991 --- /dev/null +++ "b/zh-cn/device-dev/get-code/Docker\347\274\226\350\257\221\347\216\257\345\242\203.md" @@ -0,0 +1,313 @@ +# Docker编译环境 + +- [Docker环境介绍](#section107932281315) +- [环境准备](#section7337134183512) +- [独立Docker环境](#section2858536103611) + - [搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section319412277287) + - [编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section631485163615) + - [搭建Docker环境-标准系统类设备(参考内存≥128MB)](#section13585262391) + - [编译源码-标准系统类设备(参考内存≥128MB)](#section193711513406) + +- [基于HPM的Docker环境](#section485713518337) + - [搭建Docker环境](#section3295842510) + - [获取及编译源码](#section69141039143518) + + +## Docker环境介绍 + +OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下: + +- 独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。 +- 基于HPM的Docker环境:适用于使用HPM工具进行发行版编译的场景。 + +**表 1** Docker镜像介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Docker环境

+

系统类型

+

运行平台

+

Docker镜像仓库

+

标签

+

独立 Docker环境

+

轻量和小型系统

+

Ubuntu/Windows

+

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

+

0.0.5

+

标准系统

+

Ubuntu

+

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

+

0.0.1

+

HPM Docker环境

+

轻量和小型系统

+

Ubuntu/Windows

+

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

+

0.0.3

+
+ +## 环境准备 + +在使用docker环境前需要先完成以下操作: + +1. 安装Docker,Docker安装请参考[官方指导](https://docs.docker.com/engine/install/)。 +2. 获取OpenHarmony源码,请参考[获取源码](源码获取.md)。 + + >![](public_sys-resources/icon-note.gif) **说明:** + >HPM Docker环境无需单独获取源码。 + + +## 独立Docker环境 + +OpenHarmony的Docker镜像托管在[HuaweiCloud SWR](https://console.huaweicloud.com/swr/?region=cn-south-1#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage)上。开发者可以通过该镜像在很大程度上简化编译前的环境配置。下文将介绍具体使用步骤。 + +### 搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) + +**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** + +1. 获取Docker镜像。 + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + +2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ubuntu下执行: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + windows下执行(假设源码目录为D:\\OpenHarmony): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +**方式二:通过Dockerfile 构建本地Docker镜像进行构建** + +1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 + + ``` + cd docs/docker + ./build.sh + ``` + +3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ubuntu下执行: + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + windows下执行(假设源码目录为D:\\OpenHarmony): + + ``` + docker run -it -v D:\OpenHarmony:/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 + ``` + + +### 编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) + +通过如下编译脚本启动轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)的编译。下文以Hi3516平台为例说明具体编译步骤。 + +设置编译路径,选择当前路径。 + +``` +hb set + . +``` + +**图 1** 设置编译界面 + + +![](figures/zh-cn_image_0000001101413884.png) + +>![](public_sys-resources/icon-note.gif) **说明:** +>当前开发板平台和编译界面的对应关系如下: +>- Hi3861:wifiiot\_hispark\_pegasus@hisilicon +>- Hi3516:ipcamera\_hispark\_taurus@hisilicon +>- Hi3518:ipcamera\_hispark\_aries@hisilicon + +1. 选择ipcamera\_hispark\_taurus@hisilicon并回车。 +2. 执行编译。 + + ``` + hb build -f + ``` + +3. 查看编译结果。 + + 编译结果文件生成在out/hispark\_taurus/ipcamera\_hispark\_taurus目录下。 + + +### 搭建Docker环境-标准系统类设备(参考内存≥128MB) + +**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** + +1. 获取Docker镜像。 + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**方式二:通过Dockerfile 构建本地Docker镜像进行构建** + +1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +### 编译源码-标准系统类设备(参考内存≥128MB) + +1. 在源码的根目录执行预处理脚本。 + + ``` + ../scripts/prepare.sh + ``` + +2. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 + + ``` + ./build.sh --product-name {product_name} + ``` + + \{product\_name\}为当前版本支持的平台。比如:Hi3516DV300等。 + + 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 + + +>![](public_sys-resources/icon-note.gif) **说明:** +>退出Docker执行exit命令即可。 + +## 基于HPM的Docker环境 + +docker\_dist是一个[HPM](https://hpm.harmonyos.com/)系统中的模板组件,能够帮助用户快速初始化HPM工程,利用docker镜像来快速编译OpenHarmony发行版,在很大程度上简化了编译前的环境配置。开发者在配置好Ubuntu和[hpm-cli](https://device.harmonyos.com/cn/docs/develop/bundles/oem_bundle_guide_prepare-0000001050129846)开发环境后,可以通过以下步骤来使用我们提供的Docker环境。 + +### 搭建Docker环境 + +1. 初始化安装模板。在任意工作目录中执行以下命令。 + + ``` + hpm init -t @ohos/docker_dist + ``` + +2. 修改publishAs。 + + 因为获取到的是模板类型的包,要把包的类型改为需要的类型。 在当前目录下打开bundle.json文件,把"publishAs"字段的值由"template"改为"distribution"。 + + +### 获取及编译源码 + +执行编译。自动安装docker只能在Ubuntu环境下执行,如果其他环境,需要用户自行安装docker,然后拉取镜像,执行编译。 + +- **自动安装docker(Ubuntu环境)** + + 以下命令可以帮助用户自动安装docker, 拉取镜像,并且在容器中开始运行对应解决方案的拉取和编译。 + + **方式一:** + + 命令后接参数指定解决方案,格式如下: + + ``` + hpm run docker solution={product} + ``` + + \{product\}为需编译的解决方案,如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus。 + + **方式二:** + + 设置环境变量来选择解决方案,再执行编译命令。 + + 1. 选择解决方案。 + + ``` + export solution={product} + ``` + + \{product\}为需编译的解决方案,如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus。 + + 2. 获取源码及执行编译。 + + ``` + hpm run docker + ``` + + + 以上两种方式以@ohos/hispark\_taurus为例,执行成功结果如下: + + ``` + ...... + ohos ipcamera_hispark_taurus build success! + @ohos/hispark_taurus: distribution building completed. + ``` + + +- **自行安装docker(非Ubuntu环境)** + + 自行安装docker相关操作如下: + + ``` + # 拉取镜像 + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# linux环境下的编译 + hpm run distWithDocker solution={product} + # windows下的编译,需要配置gitbash + hpm config set shellPath "gitbash路径" + hpm run distWithDocker solution={product} + ``` + + diff --git a/zh-cn/device-dev/get-code/IDE.md b/zh-cn/device-dev/get-code/IDE.md new file mode 100644 index 0000000000000000000000000000000000000000..144b67418be2f44e4a5854bdb799be24b4142b7a --- /dev/null +++ b/zh-cn/device-dev/get-code/IDE.md @@ -0,0 +1,17 @@ +# IDE + +- [获取设备开发工具(HUAWEI DevEco Device Tool)](#section2452141120244) +- [获取应用开发工具(HUAWEI DevEco Studio)](#section0904101019258) + +## 获取设备开发工具(HUAWEI DevEco Device Tool) + +HUAWEI DevEco Device Tool是OpenHarmony面向智能设备开发者提供的一站式集成开发环境,支持OpenHarmony的组件按需定制,支持代码编辑、编译、烧录、调试等功能,支持C/C++语言,以插件的形式部署在Visual Studio Code上。具体可参见[获取工具](https://device.harmonyos.com/cn/ide)和[工具使用指南](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905)**。** + +Huawei DevEco Device Tool支持 OpenHarmony设备开发的演进路标如下: + +![](figures/3.png) + +## 获取应用开发工具(HUAWEI DevEco Studio) + +HUAWEI DevEco Studio(以下简称DevEco Studio)是面向华为终端全场景多设备的一站式集成开发环境(IDE),为开发者提供工程模板创建、开发、编译、调试、发布等E2E的OpenHarmony应用开发服务。通过使用DevEco Studio,开发者可以更高效的开发具备OpenHarmony分布式能力的应用,进而提升创新效率。具体可参见[获取工具](https://developer.harmonyos.com/cn/develop/deveco-studio)和[工具使用指南](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)。 + diff --git a/zh-cn/device-dev/get-code/Readme-CN.md b/zh-cn/device-dev/get-code/Readme-CN.md index c2c5315d396f419a71b74bc8d1747c7400eb820d..a2dbbc91bbebb45f6609d07ca87191ed509e3ab4 100755 --- a/zh-cn/device-dev/get-code/Readme-CN.md +++ b/zh-cn/device-dev/get-code/Readme-CN.md @@ -2,4 +2,6 @@ - [源码获取](源码获取.md) - [获取工具](获取工具.md) + - [Docker编译环境](Docker编译环境.md) + - [IDE](IDE.md) diff --git "a/zh-cn/device-dev/get-code/\346\272\220\347\240\201\350\216\267\345\217\226.md" "b/zh-cn/device-dev/get-code/\346\272\220\347\240\201\350\216\267\345\217\226.md" index 538997e441bc9467ed12a3ea81bed44e8abf49d7..87b5557365b48eaaf0c0a251c1f7e8318945be44 100755 --- "a/zh-cn/device-dev/get-code/\346\272\220\347\240\201\350\216\267\345\217\226.md" +++ "b/zh-cn/device-dev/get-code/\346\272\220\347\240\201\350\216\267\345\217\226.md" @@ -26,11 +26,10 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ## 源码获取概述 -本文档将介绍如何获取OpenHarmony源码并说明OpenHarmony的源码目录结构。OpenHarmony的代码以[组件](../bundles/概述.md)的形式开放,开发者可以通过如下其中一种方式获取: +本文档将介绍如何获取OpenHarmony源码并说明OpenHarmony的源码目录结构。OpenHarmony的代码以[组件](../bundles/组件开发规范.md)的形式开放,开发者可以通过如下其中一种方式获取: - **获取方式1**:从代码仓库获取。通过repo或git工具从代码仓库中下载,此方式可获取最新代码。 - **获取方式2**:通过HPM包管理器获取。在[HPM](https://hpm.harmonyos.com)网站,查找满足需求的开源发行版,直接下载(或者定制后下载),再通过hpm-cli命令工具将所需的组件及工具链下载、安装到本地。 -- **获取方式3**:从镜像站点下载归档后的发行版压缩文件。如果要获取旧版本的源码,也可通过此方式获取,此方式下载速度较快。 ## 获取方式1:从代码仓库获取 @@ -62,7 +61,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 4. 安装码云repo工具,可以执行如下命令。 ``` - curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/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 ``` @@ -107,7 +106,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 repo forall -c 'git lfs pull' ``` -- **OpenHarmony** 其他版本源码获取方式请参考版本[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md)。 +- OpenHarmony其他版本源码获取方式请参考版本[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md)。 ## 获取方式2:从HPM获取 @@ -194,7 +193,7 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 为了获得更好的下载性能,您可以选择从以下站点的镜像库获取源码或者对应的解决方案。 >![](public_sys-resources/icon-note.gif) **说明:** ->- 本部分只提供**OpenHarmony** Master最新版本和LTS最新版本的源码获取方式, 其他版本源码获取方式以及具体版本信息请参考[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md) +>- 本部分只提供OpenHarmony Master最新版本和LTS最新版本的源码获取方式, 其他版本源码获取方式以及具体版本信息请参考[Release-Notes](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-Release-Notes.md) >- 当前Master 1.0版本已经不再维护。 **表 1** 源码获取路径 diff --git "a/zh-cn/device-dev/get-code/\350\216\267\345\217\226\345\267\245\345\205\267.md" "b/zh-cn/device-dev/get-code/\350\216\267\345\217\226\345\267\245\345\205\267.md" index 13556b48039b7b1149c2be8113f886d20729fb04..eeb55c7156473c57f088d2bce54464b13fd8ca92 100755 --- "a/zh-cn/device-dev/get-code/\350\216\267\345\217\226\345\267\245\345\205\267.md" +++ "b/zh-cn/device-dev/get-code/\350\216\267\345\217\226\345\267\245\345\205\267.md" @@ -1,283 +1,7 @@ -# 获取工具 +# 获取工具 -- [Docker环境获取方式](#section107932281315) -- [基于HPM的Docker环境](#section485713518337) - - [搭建Docker环境](#section18957202218355) - - [编译源码](#section69141039143518) +- **[Docker编译环境](Docker编译环境.md)** -- [独立Docker环境](#section2858536103611) - - [搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section319412277287) - - [编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)](#section631485163615) - - [搭建Docker环境-标准系统类设备(参考内存≥128MB)](#section13585262391) - - [编译源码-标准系统类设备(参考内存≥128MB)](#section193711513406) +- **[IDE](IDE.md)** -- [获取设备开发工具(HUAWEI DevEco Device Tool)](#section2452141120244) -- [获取应用开发工具(HUAWEI DevEco Studio)](#section0904101019258) - -## Docker环境获取方式 - -OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下: - -- 基于HPM的Docker环境:适用于使用HPM工具进行发行版编译的场景。 -- 独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。 - - 独立Docker环境目前容器化构建选项支持情况如下: - - **表 1** Docker镜像介绍 - - - - - - - - - - - - - - - - -

Docker镜像仓库

-

标签

-

说明

-

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

-

0.0.5

-

已经预安装OpenHarmony版本的编译环境,支持轻量系统类设备(参考内存≥128KB)小型系统类设备(参考内存≥1MB)的版本构建。

-

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

-

0.0.1

-

已经预安装OpenHarmony版本的编译环境,支持标准系统类设备(参考内存≥128MB)的版本构建。

-
- - >![](public_sys-resources/icon-note.gif) **说明:** - >Docker安装请参考[官方指导](https://docs.docker.com/engine/install/ubuntu/)。 - - -## 基于HPM的Docker环境 - -docker\_dist是一个[HPM](https://hpm.harmonyos.com/)系统中的模板组件,能够帮助用户快速初始化HPM工程,利用docker镜像来快速编译OpenHarmony发行版,在很大程度上简化了编译前的环境配置。开发者在配置好Ubuntu和[hpm-cli](https://device.harmonyos.com/cn/docs/develop/bundles/oem_bundle_guide_prepare-0000001050129846)开发环境后,可以通过以下步骤来使用我们提供的Docker环境。 - -### 搭建Docker环境 - -1. 初始化安装模板。在任意工作目录中执行以下命令。 - - ``` - hpm init -t @ohos/docker_dist - ``` - -2. 修改publishAs。 - - 因为获取到的是模板类型的包,要把包的类型改为需要的类型。 在当前目录下打开bundle.json文件,把"publishAs"字段的值由"template"改为"distribution"。 - - -### 编译源码 - -执行编译。自动安装docker只能在Ubuntu环境下执行,如果其他环境,需要用户自行安装docker,然后拉取镜像,执行编译。 - -- **自动安装docker(Ubuntu环境)** - - 以下命令可以帮助用户自动安装docker, 拉取镜像,并且在容器中开始运行对应解决方案的拉取和编译。 - - 方式一: - - 命令后接参数指定解决方案,格式如下: - - ``` - hpm run docker solution={product} - ``` - - \{product\}为需编译的解决方案如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus - - 方式二: - - 设置环境变量来选择解决方案,再执行编译命令 - - 1、选择解决方案 - - ``` - export solution={product} - ``` - - \{product\}为需编译的解决方案如:@ohos/hispark\_taurus、@ohos/hispark\_aries、@ohos/hispark\_pegasus - - 2、执行编译 - - ``` - hpm run docker - ``` - - 以上两种方式以@ohos/hispark\_taurus为例,执行成功结果如下: - - ``` - ...... - ohos ipcamera_hispark_taurus build success! - @ohos/hispark_taurus: distribution building completed. - ``` - - -- **自行安装docker(非Ubuntu环境)** - - 自行安装docker相关操作如下: - - ``` - # 拉取镜像 - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.3# linux环境下的编译 - hpm run distWithDocker solution={product} - # windows下的编译,需要配置gitbash - hpm config set shellPath "gitbash路径" - hpm run distWithDocker solution={product} - ``` - - -## 独立Docker环境 - -OpenHarmony的Docker镜像托管在[HuaweiCloud SWR](https://console.huaweicloud.com/swr/?region=cn-south-1#/app/warehouse/warehouseMangeDetail/goldensir/openharmony-docker/openharmony-docker?type=ownImage)上。开发者可以通过该镜像在很大程度上简化编译前的环境配置。开发者在配置好开发环境后,通过以下步骤来使用Docker环境。本Docker支持Ubuntu/Windows平台,下文将以Ubuntu系统为例进行使用介绍。 - -### 搭建Docker环境-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) - -**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** - -1. 获取Docker镜像。 - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:0.0.5 - ``` - -2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ``` - 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 openharmony-docker:0.0.5 - ``` - - -### 编译源码-轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB) - -通过如下编译脚本启动轻量系统类设备(参考内存≥128KB)和小型系统类设备(参考内存≥1MB)的编译。下文以Hi3516平台为例说明具体编译步骤。 - -设置编译路径,选择当前路径。 - -``` -hb set - . -``` - -**图 1** 设置编译界面 - - -![](figures/zh-cn_image_0000001101413884.png) - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前开发板平台和编译界面的对应关系如下: ->- Hi3861:wifiiot\_hispark\_pegasus@hisilicon ->- Hi3516:ipcamera\_hispark\_taurus@hisilicon ->- Hi3518:ipcamera\_hispark\_aries@hisilicon - -1. 选择ipcamera\_hispark\_taurus@hisilicon并回车。 -2. 执行编译。 - - ``` - hb build -f - ``` - -3. 查看编译结果。 - - 编译结果文件生成在out/hispark\_taurus/ipcamera\_hispark\_taurus目录下。 - - -### 搭建Docker环境-标准系统类设备(参考内存≥128MB) - -**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** - -1. 获取Docker镜像。 - - ``` - docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - -2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ``` - docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 - ``` - - -**方式二:通过Dockerfile 构建本地Docker镜像进行构建** - -1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 - - ``` - git clone https://gitee.com/openharmony/docs.git - ``` - -2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 - - ``` - cd docs/docker/standard - ./build.sh - ``` - -3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 - - ``` - docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 - ``` - - -### 编译源码-标准系统类设备(参考内存≥128MB) - -1. 在源码的根目录执行预处理脚本。 - - ``` - ../scripts/prepare.sh - ``` - -2. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 - - ``` - ./build.sh --product-name {product_name} - ``` - - \{product\_name\}为当前版本支持的平台。比如:Hi3516DV300等。 - - 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 - - ->![](public_sys-resources/icon-note.gif) **说明:** ->退出Docker执行exit命令即可。 - -## 获取设备开发工具(HUAWEI DevEco Device Tool) - -HUAWEI DevEco Device Tool是OpenHarmony面向智能设备开发者提供的一站式集成开发环境,支持OpenHarmony的组件按需定制,支持代码编辑、编译、烧录、调试等功能,支持C/C++语言,以插件的形式部署在Visual Studio Code上。具体可参见[获取工具](https://device.harmonyos.com/cn/ide)和[工具使用指南](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905)**。** - -Huawei DevEco Device Tool支持 OpenHarmony设备开发的演进路标如下: - -![](figures/3.png) - -## 获取应用开发工具(HUAWEI DevEco Studio) - -HUAWEI DevEco Studio(以下简称DevEco Studio)是面向华为终端全场景多设备的一站式集成开发环境(IDE),为开发者提供工程模板创建、开发、编译、调试、发布等E2E的OpenHarmony应用开发服务。通过使用DevEco Studio,开发者可以更高效的开发具备OpenHarmony分布式能力的应用,进而提升创新效率。具体可参见[获取工具](https://developer.harmonyos.com/cn/develop/deveco-studio)和[工具使用指南](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)。 diff --git "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\345\267\245\344\275\234\346\265\201\347\250\213\350\247\243\346\236\220.md" "b/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\345\267\245\344\275\234\346\265\201\347\250\213\350\247\243\346\236\220.md" deleted file mode 100644 index 90604006df166670190abe945a505eb3e81408b2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\345\267\245\344\275\234\346\265\201\347\250\213\350\247\243\346\236\220.md" +++ /dev/null @@ -1,18 +0,0 @@ -# Input模型工作流程解析 - -为了让开发者更清晰的了解Input模型工作流程,本节将对input模型加载的关键流程代码进行说明。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本章节为Input模型工作流程说明,开发者无需进行开发。 - -- **[私有配置信息解析](私有配置信息解析.md)** - -- **[管理驱动层初始化及注册驱动至HDF框架](管理驱动层初始化及注册驱动至HDF框架.md)** - -- **[公共驱动层初始化及注册驱动至HDF框架](公共驱动层初始化及注册驱动至HDF框架.md)** - -- **[器件驱动层初始化及注册驱动至HDF框架](器件驱动层初始化及注册驱动至HDF框架.md)** - -- **[具体调用逻辑串联函数](具体调用逻辑串联函数.md)** - - diff --git "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\347\256\200\344\273\213.md" "b/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\347\256\200\344\273\213.md" deleted file mode 100644 index 2ad3264215219982f95f0ebd29fd39bc2b480e71..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/Input\346\250\241\345\236\213\347\256\200\344\273\213.md" +++ /dev/null @@ -1,12 +0,0 @@ -# Input模型简介 - -Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。其中: - -- 设备管理层:主要为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; -- 公共驱动层:负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; -- 器件驱动层:通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; - -此外,Input模型预先实现了数据通道以及设备配置信息解析等函数。 - -关于Input模型的详细介绍请参考《[Touchscreen开发概述](../driver/Touchscreen开发概述.md)》。 - diff --git "a/zh-cn/device-dev/guide/LED\345\244\226\350\256\276\346\216\247\345\210\266.md" "b/zh-cn/device-dev/guide/LED\345\244\226\350\256\276\346\216\247\345\210\266.md" index fc94423bf4b226c2284c93a126c88618ba864537..d75a3eb4e0128bb10ea46656f4d39b4c0df1471c 100755 --- "a/zh-cn/device-dev/guide/LED\345\244\226\350\256\276\346\216\247\345\210\266.md" +++ "b/zh-cn/device-dev/guide/LED\345\244\226\350\256\276\346\216\247\345\210\266.md" @@ -1,9 +1,110 @@ -# LED外设控制 +# LED外设控制 -- **[概述](概述.md)** +- [概述](#section14639174516337) +- [开发](#section13857170163412) +- [验证](#section1949121910344) -- **[开发](开发.md)** +## 概述 -- **[验证](验证.md)** +OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力,包含I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。本文介绍如何通过调用OpenHarmony的NDK接口,实现对GPIO控制,达到LED闪烁的效果。其他的IOT外设控制,开发者可根据API指导文档完成,此处不逐一介绍。 +## 开发 + +1. 请先完成[《Hi3861快速入门》](../quick-start/Hi3861开发板介绍.md)。 + + LED控制参考示例存放于applications/sample/wifi-iot/app/iothardware/led\_example.c文件中。 + +2. 实现IOT外设控制,首先需要通过查阅原理图明确接线关系。经过查阅,hispark pegasus的LED与芯片的9号管脚相连。 + + ``` + #define LED_TEST_GPIO 9 + ``` + + >![](public_sys-resources/icon-note.gif) **说明:** + >开发板原理图,请开发者联系Hi3861购买渠道客服获取。 + +3. 使用GPIO前,需要完成GPIO管脚初始化,明确管脚用途,并创建任务,使LED周期性亮灭,达到闪烁的效果。 + + ``` + static void LedExampleEntry(void) + { + osThreadAttr_t attr; + + /* 管脚初始化 */ + IoTGpioInit(LED_TEST_GPIO); + /* 配置9号管脚为输出方向 */ + IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT); + + attr.name = "LedTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = LED_TASK_STACK_SIZE; + attr.priority = LED_TASK_PRIO; + + /* 启动任务 */ + if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) { + printf("[LedExample] Falied to create LedTask!\n"); + } + } + ``` + +4. 在循环任务中通过周期性亮灭形式实现LED闪烁。 + + ``` + static void *LedTask(const char *arg) + { + (void)arg; + while (1) { + switch (g_ledState) { + case LED_ON: + IoTGpioSetOutputVal(LED_TEST_GPIO, 1); + usleep(LED_INTERVAL_TIME_US); + break; + case LED_OFF: + IoTGpioSetOutputVal(LED_TEST_GPIO, 0); + usleep(LED_INTERVAL_TIME_US); + break; + case LED_SPARK: + IoTGpioSetOutputVal(LED_TEST_GPIO, 0); + usleep(LED_INTERVAL_TIME_US); + IoTGpioSetOutputVal(LED_TEST_GPIO, 1); + usleep(LED_INTERVAL_TIME_US); + break; + default: + usleep(LED_INTERVAL_TIME_US); + break; + } + } + return NULL; + } + ``` + +5. 在代码最下方,使用OpenHarmony启动恢复模块接口SYS\_RUN\(\)启动业务。(SYS\_RUN定义在ohos\_init.h文件中) + + ``` + SYS_RUN(LedExampleEntry); + ``` + +6. 修改applications/sample/wifi-iot/app/BUILD.gn文件,使led\_example.c参与编译。 + + ``` + import("//build/lite/config/component/lite_component.gni") + lite_component("app") { + features = [ + "iothardware:led_example" + ] + } + ``` + + +## 验证 + +编译过程请参考《[Hi3861快速入门-源码编译](../quick-start/运行Hello-World.md)》,烧录过程请参考《[Hi3861快速入门-镜像烧录](../quick-start/WLAN联网.md)》。 + +完成以上两步后,按下RST键复位模组,可发现LED在周期性闪烁,与预期相符,验证完毕。 + +**图 1** LED闪烁图 +![](figures/LED闪烁图.gif "LED闪烁图") diff --git a/zh-cn/device-dev/guide/Readme-CN.md b/zh-cn/device-dev/guide/Readme-CN.md index 6afa218aca591d6e446fe35e60821022c6a5459b..82ca22606a0cedb62b29984603e5ef48f5302e58 100755 --- a/zh-cn/device-dev/guide/Readme-CN.md +++ b/zh-cn/device-dev/guide/Readme-CN.md @@ -1,16 +1,12 @@ -# 开发示例 +# 设备开发 - [WLAN连接类产品](WLAN连接类产品.md) - [LED外设控制](LED外设控制.md) - - [概述](概述.md) - - [开发](开发.md) - - [验证](验证.md) - - [集成三方SDK](集成三方SDK.md) - [无屏摄像头类产品](无屏摄像头类产品.md) - [摄像头控制](摄像头控制.md) - - [概述](概述-0.md) + - [概述](概述.md) - [示例开发](示例开发.md) - [拍照开发指导](拍照开发指导.md) - [录像开发指导](录像开发指导.md) @@ -19,16 +15,16 @@ - [带屏摄像头类产品](带屏摄像头类产品.md) - [屏幕和摄像头控制](屏幕和摄像头控制.md) - - [概述](概述-1.md) - - [示例开发](示例开发-2.md) - - [拍照开发指导](拍照开发指导-3.md) - - [录像开发指导](录像开发指导-4.md) + - [概述](概述-0.md) + - [示例开发](示例开发-1.md) + - [拍照开发指导](拍照开发指导-2.md) + - [录像开发指导](录像开发指导-3.md) - [预览开发指导](预览开发指导.md) - - [应用实例](应用实例-5.md) + - [应用实例](应用实例-4.md) - [视觉应用开发](视觉应用开发.md) - - [概述](概述-6.md) + - [概述](概述-5.md) - [开发准备](开发准备.md) - [添加页面](添加页面.md) - [开发首页](开发首页.md) @@ -37,38 +33,7 @@ - [真机运行](真机运行.md) - [常见问题](常见问题.md) -- [时钟应用开发示例](时钟应用开发示例.md) - - [概述](概述-7.md) - - [开发准备](开发准备-8.md) - - [开发步骤](开发步骤.md) - - [签名打包](签名打包.md) - - [真机运行](真机运行-9.md) - +- [时钟应用开发指导](时钟应用开发指导.md) - [平台驱动开发示例](平台驱动开发示例.md) - - [概述](概述-10.md) - - [环境准备](环境准备.md) - - [开发](开发-11.md) - - [编译及烧录](编译及烧录.md) - - [外设驱动开发示例](外设驱动开发示例.md) - - [概述](概述-12.md) - - [硬件资源介绍](硬件资源介绍.md) - - [Input模型简介](Input模型简介.md) - - - [环境搭建](环境搭建.md) - - [TouchScreen器件驱动开发](TouchScreen器件驱动开发.md) - - [配置设备描述信息](配置设备描述信息.md) - - [配置Touchscreen器件信息](配置Touchscreen器件信息.md) - - [适配器件私有驱动](适配器件私有驱动.md) - - - [编译及烧录](编译及烧录-13.md) - - [调试验证](调试验证.md) - - [开机日志分析](开机日志分析.md) - - - [Input模型工作流程解析](Input模型工作流程解析.md) - - [私有配置信息解析](私有配置信息解析.md) - - [管理驱动层初始化及注册驱动至HDF框架](管理驱动层初始化及注册驱动至HDF框架.md) - - [公共驱动层初始化及注册驱动至HDF框架](公共驱动层初始化及注册驱动至HDF框架.md) - - [器件驱动层初始化及注册驱动至HDF框架](器件驱动层初始化及注册驱动至HDF框架.md) - - [具体调用逻辑串联函数](具体调用逻辑串联函数.md) diff --git "a/zh-cn/device-dev/guide/TouchScreen\345\231\250\344\273\266\351\251\261\345\212\250\345\274\200\345\217\221.md" "b/zh-cn/device-dev/guide/TouchScreen\345\231\250\344\273\266\351\251\261\345\212\250\345\274\200\345\217\221.md" deleted file mode 100644 index ef2d3835fa3e16bf4f94ec4d40017dba3cafd5b0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/TouchScreen\345\231\250\344\273\266\351\251\261\345\212\250\345\274\200\345\217\221.md" +++ /dev/null @@ -1,17 +0,0 @@ -# TouchScreen器件驱动开发 - -基于Input模型适配一款触摸屏IC需要完成的工作有: - -1.配置设备描述信息。驱动注册到HDF框架所需要的设备驱动描述信息,如驱动是否加载以及加载次序等; - -2.配置器件私有信息、平台硬件信息。器件私有信息包括上下电时序等,平台硬件信息包括器件连接主板的GPIO端口信息等。 - -3.适配器件私有驱动。 Input模型对Input设备开发流程进行了抽象,开发者只需要适配器件驱动层,无需改动管理驱动层以及公共驱动层。 - -- **[配置设备描述信息](配置设备描述信息.md)** - -- **[配置Touchscreen器件信息](配置Touchscreen器件信息.md)** - -- **[适配器件私有驱动](适配器件私有驱动.md)** - - diff --git a/zh-cn/device-dev/guide/figures/zh-cn_image_0000001161922745.png b/zh-cn/device-dev/guide/figures/zh-cn_image_0000001169991055.png similarity index 100% rename from zh-cn/device-dev/guide/figures/zh-cn_image_0000001161922745.png rename to zh-cn/device-dev/guide/figures/zh-cn_image_0000001169991055.png diff --git "a/zh-cn/device-dev/guide/\345\205\254\345\205\261\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" "b/zh-cn/device-dev/guide/\345\205\254\345\205\261\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" deleted file mode 100644 index 31de19a1b135135ed4b6481331284bdb35200aee..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\205\254\345\205\261\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" +++ /dev/null @@ -1,35 +0,0 @@ -# 公共驱动层初始化及注册驱动至HDF框架 - -示例代码路径:./drivers/framework/model/input/driver/hdf\_touch.c - -``` -static int32_t HdfTouchDriverProbe(struct HdfDeviceObject *device) -{ - ... - /* 板级信息结构体内存申请及hcs配置信息解析 */ - boardCfg = BoardConfigInstance(device); - ... - /* 公共驱动结构体内存申请 */ - touchDriver = TouchDriverInstance(); - ... - /* 依据解析出的板级信息进行公共资源初始化,如IIC初始化 */ - ret = TouchDriverInit(touchDriver, boardCfg); - if (ret == HDF_SUCCESS) { - ... - /* 添加驱动至公共驱动层驱动管理链表,当设备与驱动进行绑定时使用该链表进行查询 */ - AddTouchDriver(touchDriver); - ... - } - ... -} -struct HdfDriverEntry g_hdfTouchEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH", - .Bind = HdfTouchDriverBind, - .Init = HdfTouchDriverProbe, - .Release = HdfTouchDriverRelease, -}; - -HDF_INIT(g_hdfTouchEntry); //驱动注册入口 -``` - diff --git "a/zh-cn/device-dev/guide/\345\205\267\344\275\223\350\260\203\347\224\250\351\200\273\350\276\221\344\270\262\350\201\224\345\207\275\346\225\260.md" "b/zh-cn/device-dev/guide/\345\205\267\344\275\223\350\260\203\347\224\250\351\200\273\350\276\221\344\270\262\350\201\224\345\207\275\346\225\260.md" deleted file mode 100644 index 9fc526d2109ecffd5cec6f672a85e5f8f6b173f0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\205\267\344\275\223\350\260\203\347\224\250\351\200\273\350\276\221\344\270\262\350\201\224\345\207\275\346\225\260.md" +++ /dev/null @@ -1,40 +0,0 @@ -# 具体调用逻辑串联函数 - -Input模型管理层驱动init函数初始化了设备管理链表,公共驱动层初始化函数完成了相关结构体的内存申请。器件驱动相关信息通过RegisterChipDevice函数对公共驱动层相关结构体进行信息填充,同时完成了相关硬件信息的初始化(如中断注册等),绑定设备与驱动组成inputDev通过RegisterInputDevice函数向驱动管理层进行注册,在RegisterInputDevice函数中主要实现了将inputDev向设备管理链表的添加等功能。如下所示为两个函数的实现部分: - -``` -//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_touch.c -int32_t RegisterChipDevice(ChipDevice *chipDev) -{ - ... - /* 绑定设备与驱动,从而通过InputDeviceInstance函数创建inputDev */ - DeviceBindDriver(chipDev); - ... - /* 主要包含器件中断注册及中断处理函数,中断处理函数中有数据上报用户态的数据通道 */ - ChipDriverInit(chipDev); - ... - /* 申请内存实例化InputDev */ - inputDev = InputDeviceInstance(chipDev); - ... - /* 将InputDev设备注册至input驱动管理层 */ - RegisterInputDevice(inputDev); - ... -} - -//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_input_device_manager.c -int32_t RegisterInputDevice(InputDevice *inputDev) -{ - ... - /* 申请ID,该ID对于不同input设备唯一 */ - ret = AllocDeviceID(inputDev); - ... - /* 该函数包含了对hid类设备的特殊处理,对于触摸屏驱动,该函数无实质操作; */ - CreateDeviceNode(inputDev); - /* 内核态数据传送至用户态需使用IOService能力,需要申请buffer */ - AllocPackageBuffer(inputDev); - /* 将input设备添加进设备全局管理链表 */ - AddInputDevice(inputDev); - ... -} -``` - diff --git "a/zh-cn/device-dev/guide/\345\231\250\344\273\266\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" "b/zh-cn/device-dev/guide/\345\231\250\344\273\266\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" deleted file mode 100644 index 4cfddfa469ff7d5812667549270c01baf14befe0..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\231\250\344\273\266\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 器件驱动层初始化及注册驱动至HDF框架 - -具体请参考[3.3章节](适配器件私有驱动.md)器件层驱动初始化及注册驱动至HDF框架部分。 - diff --git "a/zh-cn/device-dev/guide/\345\244\226\350\256\276\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/guide/\345\244\226\350\256\276\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" index 8b083827126708b7db7f7d283ed2f34fa392a9ae..d0d50a418f6329ae124c55ff5cb95eed9d67f763 100644 --- "a/zh-cn/device-dev/guide/\345\244\226\350\256\276\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ "b/zh-cn/device-dev/guide/\345\244\226\350\256\276\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" @@ -1,15 +1,483 @@ -# 外设驱动开发示例 +# 外设驱动开发示例 -- **[概述](概述-12.md)** +- [概述](#section86753818426) + - [硬件资源简介](#section123071189431) + - [Input模型简介](#section53684425430) -- **[环境搭建](环境搭建.md)** +- [环境搭建](#section661075474418) +- [TouchScreen器件驱动开发](#section15233162984520) + - [配置设备描述信息](#section16761205604515) + - [配置Touchscreen器件信息](#section156331030144617) + - [适配器件私有驱动](#section17127331595) -- **[TouchScreen器件驱动开发](TouchScreen器件驱动开发.md)** +- [编译及烧录](#section16465031164711) +- [调试验证](#section62577313482) +- [Input模型工作流程解析](#section1578569154917) + - [私有配置信息解析](#section1310113815495) + - [管理驱动层初始化及注册驱动至HDF框架](#section614512119500) + - [公共驱动层初始化及注册驱动至HDF框架](#section16194201755019) + - [器件驱动层初始化及注册驱动至HDF框架](#section1090743312505) + - [具体调用逻辑串联函数](#section81801147529) -- **[编译及烧录](编译及烧录-13.md)** -- **[调试验证](调试验证.md)** +## 概述 -- **[Input模型工作流程解析](Input模型工作流程解析.md)** +本文档将介绍如何基于Hi3516DV300开发板完成基于HDF\_Input模型的触摸屏器件驱动开发,从而使开发者快速入门,进行基于的外设驱动开发。 +### 硬件资源简介 + +Hi3516DV300开发板套件所提供的触摸屏器件IC为GT911,该器件采用标准I2C与主机通信,通过6pin软排线与主板连接。6pin分布以及实物连接图如下图所示: + +![](figures/绘图1.png) + +### Input模型简介 + +Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。其中: + +- 设备管理层:主要为各类输入设备驱动提供input设备的注册、注销接口,同时统一管理input设备列表; +- 公共驱动层:负责对板级硬件进行初始化、硬件中断处理、向manager注册input设备等; +- 器件驱动层:通过适配平台驱动预留的差异化接口,实现器件驱动开发量最小化; + +此外,Input模型预先实现了数据通道以及设备配置信息解析等函数。 + +关于Input模型的详细介绍请参考《[Touchscreen开发概述](../driver/Touchscreen.md)》。 + +## 环境搭建 + +环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/标准系统入门.md)。 + +>![](public_sys-resources/icon-notice.gif) **须知:** +>本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 + +## TouchScreen器件驱动开发 + +基于Input模型适配一款触摸屏IC需要完成的具体工作见下。 + +### 配置设备描述信息 + +驱动注册到HDF框架所需要的设备驱动描述信息,如驱动是否加载以及加载次序等。 + +配置文件路径:./drivers/adapter/khdf/linux/hcs/device\_info/device\_info.hcs + +device\_info.hcs中的信息主要提供给HDF框架使用,包含了Input模型各层驱动注册到HDF框架所必需的信息,开发者无特殊场景需求无需改动。各驱动层私有配置信息通过“deviceMatchAttr”字段与input\_config.hcs中的“match\_attr”相关内容进行匹配。 + +配置文件中与input模块相关的内容如下所示,相关字段的详细含义可以参考《[驱动配置](../driver/驱动开发.md)》: + +``` +input :: host { + hostName = "input_host"; + priority = 100; + device_input_manager :: device { // Input管理层设备描述信息 + device0 :: deviceNode { + policy = 2; // 向内核用户态均发布服务 + priority = 100; // input管理层驱动优先级默认为100 + preload = 0; // 加载该驱动 + permission = 0660; // 驱动创建设备节点权限 + moduleName = "HDF_INPUT_MANAGER"; // 与驱动入口的moduleName匹配 + serviceName = "hdf_input_host"; // HDF框架生成的节点名 + deviceMatchAttr = ""; // manager目前不需要私有配置,因此为空 + } + } + + device_hdf_touch :: device { // Input公共驱动层设备描述信息 + device0 :: deviceNode { + policy = 2; // 向内核用户态均发布服务 + priority = 120; // input公共驱动优先级默认为120 + preload = 0; // 加载该驱动 + permission = 0660; // 驱动创建设备节点权限 + moduleName = "HDF_TOUCH"; // 与驱动入口的moduleName匹配 + serviceName = "hdf_input_event1"; // HDF框架生成的节点名 + deviceMatchAttr = "touch_device1"; // 与私有配置信息中的“match_attr”字段保持一致 + } + } + + device_touch_chip :: device { // Input器件驱动层信息 + device0 :: deviceNode { + policy = 0; // 向内核用户态均不发布服务 + priority = 130; // input器件驱动优先级默认为130 + preload = 0; // 加载该驱动 + permission = 0660; // 驱动创建设备节点权限 + moduleName = "HDF_TOUCH_GT911"; // 与驱动入口的moduleName匹配 + serviceName = "hdf_touch_gt911_service";// HDF框架生成的节点名 + deviceMatchAttr = "zsj_gt911_5p5"; //与私有配置信息中的“match_attr”字段保持一致 + } + } + } +``` + +该配置文件中需要重点关注的字段有: + +“priority”决定驱动加载顺序; + +“preload”决定驱动是否加载; + +“moduleName ”需要与驱动注册入口处的“moduleName ”字段保持一致; + +“serviceName ”HDF框架依据该字段创建节点名; + +“deviceMatchAttr ”需要与私有配置信息中的“match\_attr”字段保持一致。 + +通过配置设备描述信息,使得HDF框架通过moduleName与注册至驱动入口的代码相匹配,保证了驱动的正常加载,通过priority字段保证了各驱动的加载顺序。 + +### 配置Touchscreen器件信息 + +器件私有信息包括上下电时序等,平台硬件信息包括器件连接主板的GPIO端口信息等。 + +配置文件路径:./drivers/adapter/khdf/linux/hcs/input/input\_config.hcs + +input\_config.hcs中的信息由驱动代码进行读取解析,主要由公共驱动层的私有配置信息及器件驱动层的私有配置信息组成。文件中的配置包含板级硬件信息及器件私有配置信息,实际业务开发时,可根据具体需求增删及修改对应内容。 + +``` +root { + input_config { + touchConfig { + touch0 { // 第一款触摸屏 + boardConfig { // 板级硬件信息 + match_attr = "touch_device1"; // 与设备描述配置信息中公共驱动层私有配置信息的“match_attr”字段保持一致 + inputAttr { + /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */ + inputType = 0; // input类型为touch + solutionX = 480; // 分辨率X信息 + solutionY = 960; // 分辨率Y信息 + devName = "main_touch"; // 设备名称 + } + busConfig { + /* 0:i2c 1:spi */ + busType = 0; // GT911采用I2C通信 + busNum = 6; // 与主机芯片第6路I2C通信 + clkGpio = 86; // 主机芯片SCL管脚 + dataGpio = 87; // 主机芯片SDA管脚 + i2cClkIomux = [0x114f0048, 0x403]; // SCL管脚配置信息 + i2cDataIomux = [0x114f004c, 0x403]; // SDA管脚配置信息 + } + pinConfig { + rstGpio = 3; // 复位管脚连接主机芯片的3号管脚 + intGpio = 4; // 中断管脚连接主机芯片的4号管脚 + rstRegCfg = [0x112f0094, 0x400]; // 复位管脚配置信息 + intRegCfg = [0x112f0098, 0x400]; // 中断管脚配置信息 + } + powerConfig { + /* 0:unused 1:ldo 2:gpio 3:pmic */ + vccType = 2; // GPIO供电 + vccNum = 20; // gpio20 + vccValue = 1800; // 电压幅值为1800mV + vciType = 1; // LDO供电 + vciNum = 12; // ldo12 + vciValue = 3300; // 电压幅值为3300mV + } + + featureConfig { + capacitanceTest = 0; // 容值测试 + gestureMode = 0; // 手势模式 + gloverMode = 0; // 手套模式 + coverMode = 0; // 皮套模式 + chargerMode = 0; // 充电模式 + knuckleMode = 0; // 指关节模式 + } + } + chipConfig { // 器件私有信息配置 + template touchChip { // 模板 + match_attr = ""; + chipName = "gt911"; // 触摸屏IC型号 + vendorName = "zsj"; // 供应商 + chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 + busType = 0; // 0代表I2C,1代表SPI + deviceAddr = 0x5D; // 器件IC通信地址 + irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 + maxSpeed = 400; // 最大通信速率为400Hz + chipVersion = 0; // 触摸屏IC版本号 + powerSequence { + /* 上电时序的配置含义说明: + [类型, 状态, 方向 , 延时] + 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 + 0代表下电或拉低,1代表上电或拉高,2代表无操作 + 0代表输入方向,1代表输出方向,2代表无操作 + 代表延时多少毫秒, 例如20代表延时20ms + */ + powerOnSeq = [4, 0, 1, 0, // 中断管脚配置为输出,且进行拉低 + 3, 0, 1, 10, // 复位管脚配置为输出,且进行拉低,延时10ms + 3, 1, 2, 60, // 复位管脚无操作,且进行拉高,延时60ms + 4, 2, 0, 0]; // 中断管脚配置为输入 + suspendSeq = [3, 0, 2, 10]; // 复位管脚无操作,且进行拉低,延时10ms + resumeSeq = [3, 1, 2, 10]; // 复位管脚无操作,且进行拉高,延时10ms + powerOffSeq = [3, 0, 2, 10, // 复位管脚无操作,且进行拉低,延时10ms + 1, 0, 2, 20]; // 电源正极管脚无操作,且进行拉低,延时20ms + } + } + + chip0 :: touchChip { + match_attr = "zsj_gt911_5p5"; // 与设备描述配置信息中器件私有配置信息的“match_attr”字段保持一致 + chipInfo = "ZIDN45100"; // 产品名+模组编号+芯片编号的组合信息 用于给用户态区分当前器件 + chipVersion = 0; // IC型号的版本 + } + } + } + } + } +} +``` + +示例中“touchConfig”包含了“touch0”,"touch0"包含了“boardConfig”与“chipConfig”;“boardConfig”字段包含了Hi3516DV300板级硬件信息,“chipConfig”包含了触摸屏器件的私有信息,如果需要替换触摸屏器件,重新配置“chipConfig”对应的字段信息即可。同时产品可以配置多款触摸屏,示例中用“touch0”代表了套件中默认的触摸屏的硬件接口以及器件的配置信息,如产品需要配置副屏,可在与“touch0”并列的位置配置“touch1”的信息。 + +### 适配器件私有驱动 + +Input模型对Input设备开发流程进行了抽象,开发者只需要适配器件驱动层,无需改动管理驱动层以及公共驱动层。 + +Input模型由三层驱动组成,开发者适配一款全新触摸屏驱动只需要适配器件驱动层即可,重点实现差异化接口,本小节以代码示例的形式展示开发者需要重点完成的工作。 + +1. 触摸屏器件差异化接口适配 + + 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c + + ``` + static struct TouchChipOps g_gt911ChipOps = { // 器件IC接口 + .Init = ChipInit, // 初始化 + .Detect = ChipDetect, // 器件检测 + .Resume = ChipResume, // 唤醒 + .Suspend = ChipSuspend, // 休眠 + .DataHandle = ChipDataHandle, // 器件数据读取 + .UpdateFirmware = UpdateFirmware, // 固件升级 + }; + + /* 不同触摸屏厂家使用的IC不一样,对应的寄存器操作也不一样,因此器件驱动层代码重点适配差异化接口部分,如下示例代码展示了GT911的数据解析*/ + + static int32_t ChipDataHandle(ChipDevice *device) + { + ... + /* GT911获取坐标之前需先读取状态寄存器 */ + reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; + ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); + if (ret < 0 || touchStatus == GT_EVENT_INVALID) { + return HDF_FAILURE; + } + ... + /* 根据状态寄存器的值读取数据寄存器数据 */ + reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; + reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; + pointNum = touchStatus & GT_FINGER_NUM_MASK; + if (pointNum == 0 || pointNum > MAX_SUPPORT_POINT) { + HDF_LOGE("%s: pointNum is invalid, %u", __func__, pointNum); + (void)ChipCleanBuffer(i2cClient); + OsalMutexUnlock(&device->driver->mutex); + return HDF_FAILURE; + } + frame->realPointNum = pointNum; + frame->definedEvent = TOUCH_DOWN; + (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); + /* 对获取的数据进行解析 */ + ParsePointData(device, frame, buf, pointNum); + ... + } + static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) + { + ... + /* 每个坐标值由两个字节组成,对获取的单字节数据进行拼接得到最终的坐标值 */ + for (i = 0; i < pointNum; i++) { + frame->fingers[i].trackId = buf[GT_POINT_SIZE * i + GT_TRACK_ID]; + frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | + ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); + /* 对解析出来的坐标值进行打印 */ + HDF_LOGD("%s: x = %d, y = %d", __func__, frame->fingers[i].x, frame->fingers[i].y); + } + } + ``` + +2. 器件层驱动初始化及注册驱动至HDF框架 + + 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c + + ``` + static int32_t HdfGoodixChipInit(struct HdfDeviceObject *device) + { + ... + /* 器件配置结构体内存申请、配置信息解析及挂载 */ + chipCfg = ChipConfigInstance(device); + ... + /* 器件实例化 */ + chipDev = ChipDeviceInstance(); + ... + /* 器件信息挂载及器件私有操作挂载 */ + chipDev->chipCfg = chipCfg; + chipDev->ops = &g_gt911ChipOps; + ... + /* 注册器件驱动至平台驱动 */ + RegisterChipDevice(chipDev); + ... + } + struct HdfDriverEntry g_touchGoodixChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_GT911", // 该moduleName与device_info.hcs文件中器件驱动层的moduleName信息相匹配 + .Init = HdfGoodixChipInit, // 器件驱动初始化函数 + }; + HDF_INIT(g_touchGoodixChipEntry); // 注册器件驱动至HDF框架 + ``` + + 器件私有驱动层主要实现了各器件厂商差异较大的部分,如器件休眠唤醒、数据解析以及固件升级等。 + + 至此,基于HDF框架及Input模型的触摸屏驱动适配完成。 + + +## 编译及烧录 + +1. 编辑Makefile文件,添加本示例中的内容: + + 文件路径:./drivers/adapter/khdf/linux/model/input/Makefile + + 添加内容如下: + + ``` + obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \ + $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o + ``` + + 其中touch\_gt911.o为本示例中追加的内容。 + +2. 具体编译及烧录操作请参考[标准系统快速入门编译及烧录章节](../quick-start/标准系统入门.md)。 + +## 调试验证 + +如下所示为开机启动日志部分截取 + +``` +[I/HDF_INPUT_DRV] HdfInputManagerInit: enter // 管理驱动层初始化 +[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // 初始化成功 +[I/osal_cdev] add cdev hdf_input_host success +[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // 公共驱动层初始化 +[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // 初始化成功 +[I/osal_cdev] add cdev hdf_input_event1 success +[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // 器件驱动层初始化 +[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060 +[I/HDF_INPUT_DRV] Product_ID: 911_1060, x_sol = 960, y_sol = 480 +[I/HDF_LOG_TAG] ChipDriverInit: chipDetect succ, ret = 0 +[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch +[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // 初始化成功 +``` + +## Input模型工作流程解析 + +为了让开发者更清晰的了解Input模型工作流程,本节将对input模型加载的关键流程代码进行说明。 + +>![](public_sys-resources/icon-notice.gif) **须知:** +>本章节为Input模型工作流程说明,开发者无需进行开发。 + +### 私有配置信息解析 + +示例代码路径:./drivers/framework/model/input/driver/input\_config\_parser.c + +根据OSAL提供的配置解析函数,可以将hcs文件中各字段含义进行解析,具体请参考input\_config\_parser.c中各函数的实现。如果提供的模板不能满足需求,在hcs文件中添加相应信息后,需要根据添加的字段开发相应的解析函数。 + +``` +static int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode, BoardAttrCfg *attr) +{ + int32_t ret; + ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0); // 获取inputType字段信息,保存在BoardAttrCfg结构体中 + CHECK_PARSER_RET(ret, "GetUint8"); + ... + return HDF_SUCCESS; +} +``` + +### 管理驱动层初始化及注册驱动至HDF框架 + +示例代码路径:./drivers/framework/model/input/driver/hdf\_input\_device\_manager.c + +``` +static int32_t HdfInputManagerInit(struct HdfDeviceObject *device) +{ + /* 分配内存给manager,manager中将存放所有input设备 */ + g_inputManager = InputManagerInstance(); + ... +} +struct HdfDriverEntry g_hdfInputEntry = { + .moduleVersion = 1, + .moduleName = "HDF_INPUT_MANAGER", + .Bind = HdfInputManagerBind, + .Init = HdfInputManagerInit, + .Release = HdfInputManagerRelease, +}; + +HDF_INIT(g_hdfInputEntry); //驱动注册入口 +``` + +### 公共驱动层初始化及注册驱动至HDF框架 + +示例代码路径:./drivers/framework/model/input/driver/hdf\_touch.c + +``` +static int32_t HdfTouchDriverProbe(struct HdfDeviceObject *device) +{ + ... + /* 板级信息结构体内存申请及hcs配置信息解析 */ + boardCfg = BoardConfigInstance(device); + ... + /* 公共驱动结构体内存申请 */ + touchDriver = TouchDriverInstance(); + ... + /* 依据解析出的板级信息进行公共资源初始化,如IIC初始化 */ + ret = TouchDriverInit(touchDriver, boardCfg); + if (ret == HDF_SUCCESS) { + ... + /* 添加驱动至公共驱动层驱动管理链表,当设备与驱动进行绑定时使用该链表进行查询 */ + AddTouchDriver(touchDriver); + ... + } + ... +} +struct HdfDriverEntry g_hdfTouchEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH", + .Bind = HdfTouchDriverBind, + .Init = HdfTouchDriverProbe, + .Release = HdfTouchDriverRelease, +}; + +HDF_INIT(g_hdfTouchEntry); //驱动注册入口 +``` + +### 器件驱动层初始化及注册驱动至HDF框架 + +具体请参考[适配器件私有驱动](#section17127331595)器件层驱动初始化及注册驱动至HDF框架部分。 + +### 具体调用逻辑串联函数 + +Input模型管理层驱动init函数初始化了设备管理链表,公共驱动层初始化函数完成了相关结构体的内存申请。器件驱动相关信息通过RegisterChipDevice函数对公共驱动层相关结构体进行信息填充,同时完成了相关硬件信息的初始化(如中断注册等),绑定设备与驱动组成inputDev通过RegisterInputDevice函数向驱动管理层进行注册,在RegisterInputDevice函数中主要实现了将inputDev向设备管理链表的添加等功能。如下所示为两个函数的实现部分: + +``` +//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_touch.c +int32_t RegisterChipDevice(ChipDevice *chipDev) +{ + ... + /* 绑定设备与驱动,从而通过InputDeviceInstance函数创建inputDev */ + DeviceBindDriver(chipDev); + ... + /* 主要包含器件中断注册及中断处理函数,中断处理函数中有数据上报用户态的数据通道 */ + ChipDriverInit(chipDev); + ... + /* 申请内存实例化InputDev */ + inputDev = InputDeviceInstance(chipDev); + ... + /* 将InputDev设备注册至input驱动管理层 */ + RegisterInputDevice(inputDev); + ... +} + +//函数具体实现代码位置 :./drivers/framework/model/input/driver/hdf_input_device_manager.c +int32_t RegisterInputDevice(InputDevice *inputDev) +{ + ... + /* 申请ID,该ID对于不同input设备唯一 */ + ret = AllocDeviceID(inputDev); + ... + /* 该函数包含了对hid类设备的特殊处理,对于触摸屏驱动,该函数无实质操作; */ + CreateDeviceNode(inputDev); + /* 内核态数据传送至用户态需使用IOService能力,需要申请buffer */ + AllocPackageBuffer(inputDev); + /* 将input设备添加进设备全局管理链表 */ + AddInputDevice(inputDev); + ... +} +``` diff --git "a/zh-cn/device-dev/guide/\345\261\217\345\271\225\345\222\214\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" "b/zh-cn/device-dev/guide/\345\261\217\345\271\225\345\222\214\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" index 7fed33d8a7778766da71be14c1704a1ebb08b0b6..c3267d20ecc5098c234769546719e62eb12d44ce 100755 --- "a/zh-cn/device-dev/guide/\345\261\217\345\271\225\345\222\214\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" +++ "b/zh-cn/device-dev/guide/\345\261\217\345\271\225\345\222\214\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" @@ -1,9 +1,9 @@ # 屏幕和摄像头控制 -- **[概述](概述-1.md)** +- **[概述](概述-0.md)** -- **[示例开发](示例开发-2.md)** +- **[示例开发](示例开发-1.md)** -- **[应用实例](应用实例-5.md)** +- **[应用实例](应用实例-4.md)** diff --git "a/zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" "b/zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" deleted file mode 100644 index 24be5472457cc6266e3a7f55040bdc377de2639d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" +++ /dev/null @@ -1,39 +0,0 @@ -# 常见问题 - -- [hdc\_std连接不到设备](#section1221016541119) -- [hdc\_std运行不了](#section219185710311) - -## hdc\_std连接不到设备 - -- **现象描述** - - 执行 "hdc\_std list targets"命令后结果为:\[Empty\] - -- **可能原因和解决方法** - 1. 设备没有被识别: - - 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 - - 2. hdc\_std工作异常: - - 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 - - 如果一直获取不到设备信息,请在任务管理器中查询是否有adb进程,该进程可能会对hdc产生干扰,可以将其杀掉后重复执行上面的步骤。 - - 3. hdc\_std与设备不匹配: - - 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 - - - -## hdc\_std运行不了 - -- **现象描述** - - 点击hdc\_std.exe文件无法运行。 - -- **可能原因和解决方法** - - hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 - - diff --git "a/zh-cn/device-dev/guide/\345\271\263\345\217\260\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/guide/\345\271\263\345\217\260\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" index 5dc1dd07b55fff2f60df94e5d132d3f02dc1db71..c4f80352fcfe86a1067d60f8f00f837176f70f62 100644 --- "a/zh-cn/device-dev/guide/\345\271\263\345\217\260\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ "b/zh-cn/device-dev/guide/\345\271\263\345\217\260\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" @@ -1,11 +1,453 @@ -# 平台驱动开发示例 +# 平台驱动开发示例 -- **[概述](概述-10.md)** +- [概述](#section194201316174215) +- [环境准备](#section6926133918422) +- [开发](#section65801539470) + - [文件说明](#section0708184454414) + - [实例化驱动入口](#section85325864412) + - [设置相关参数](#section8155172019453) + - [添加控制器](#section1335374114452) -- **[环境准备](环境准备.md)** +- [编译及烧录](#section164824754712) -- **[开发](开发-11.md)** +## 概述 -- **[编译及烧录](编译及烧录.md)** +本文档将以I2C驱动为例,介绍如何基于HDF驱动框架完成平台驱动开发。 + +>![](public_sys-resources/icon-caution.gif) **注意:** +>本例仅作为平台驱动开发示例参考,开发者不可直接用于商用集成。 + +HDF驱动框架为常用外围设备提供了标准的驱动框架,驱动开发者只需将驱动适配至HDF驱动框架,即可通过HDF驱动框架提供的接口操作外围设备。 + +本文以I2C为例。其时序流程如[图1](#fig148041484161)所示。 + +**图 1** I2C时序流程图 + + +![](figures/zh-cn_image_0000001169991055.png) + +- User Business:用户业务驱动。 +- i2cManagerEntry:I2C管理器入口,注册I2cManager到HDF驱动框架。 +- I2cManager:I2C管理器,管理I2C控制器。 +- I2cCntlr:I2C控制器。 +- i2cDriverEntry:I2C控制器入口,注册I2cCntlr到HDF驱动框架。 + +## 环境准备 + +环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/标准系统入门.md)。 + +>![](public_sys-resources/icon-notice.gif) **须知:** +>本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 + +## 开发 + +### 文件说明 + +本例中涉及的文件及路径如下表: + +**表 1** 文件说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

说明

+

文件路径

+

操作

+

示例文件

+

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

+

新增文件

+

设备服务文件

+

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

+

+

追加内容

+

+

配置参数文件

+

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

+

编译文件

+

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

+

依赖头文件

+

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

+

作为头文件引用

+

+

核心层头文件

+

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

+

HCS配置入口文件

+

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

+

HCS配置文件总入口

+
+ +>![](public_sys-resources/icon-caution.gif) **注意:** +>本例程涉及的文件路径均作为演示,驱动开发者应根据实际情况确定具体的源文件存放位置。 + +### 实例化驱动入口 + +实例化一个HdfDriverEntry 对象作为驱动入口。驱动入口必须为HdfDriverEntry(在hdf\_device\_desc.h中定义)类型的全局变量,且moduleName要和device\_info.hcs中保持一致。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 + +I2C驱动中没有实现Bind方法,因为I2C控制器由manager管理,而在manager中已经实现了Bind方法,因此I2C驱动中无需再绑定服务。 + +实例化驱动入口的示例代码如下: + +``` +/* 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量 */ +struct HdfDriverEntry g_sampleI2cDriverEntry = { + .moduleVersion = 1, + .Init = SampleI2cInit, + .Release = SampleI2cRelease, + .moduleName = "demo_i2c_driver", +}; +/* 调用HDF_INIT将驱动入口注册到HDF框架中 */ +HDF_INIT(g_sampleI2cDriverEntry); +``` + +### 设置相关参数 + +通过配置device\_info.hcs,并从HCS获取并解析设备的配置参数以确保驱动能够正确加载。 + +1. 添加设备服务节点(必选)。 + + 编辑device\_info.hcs,在device\_i2c :: device下添加驱动设备服务节点,示例如下: + + ``` + root { + device_info { + match_attr = "hdf_manager"; + device_i2c :: device { // i2c设备节点 + device2 :: deviceNode { // i2c驱动的DeviceNode节点 + policy = 0; // policy字段是驱动服务发布的策略 + priority = 55; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "demo_i2c_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 + serviceName = "DEMO_I2C_DRIVER"; // 驱动对外发布服务的名称,必须唯一 + deviceMatchAttr = "demo_i2c_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的 + // match_attr值相等 + } + } + } + } + + ``` + + >![](public_sys-resources/icon-notice.gif) **须知:** + >配置文件中的priority(取值范围为整数0到200)是用来表示host和驱动的优先级,不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高,驱动的priority值相同则不保证加载顺序。 + +2. 添加配置参数(可选)。 + + 有时驱动可能会需要私有配置信息,以确保寄存器的配置可以满足不同产品的需求。如需要私有配置信息,则可以添加一个驱动的配置文件,用来存放一些驱动的默认配置信息,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init(参考[驱动开发](../driver/驱动开发.md))传递给驱动。驱动开发者可新建配置文件,并在板级驱动hdf.hcs中引用新建的配置文件,本例中直接在原有的配置文件i2c\_config.hcs内添加配置参数。 + + 本例中编辑i2c\_config.hcs,添加配置参数: + + ``` + root { + platform { + i2c_config_demo { + match_attr = "demo_i2c_config"; // 该字段的值必须和device_info.hcs中的deviceMatchAttr值一致 + + template i2c_controller { // 参数模板 + bus = 0; + reg_pbase = 0x120b0000; + reg_size = 0xd1; + } + + controller_demo_0 :: i2c_controller { // 两个I2C示例控制器 + bus = 8; + } + controller_demo_1 :: i2c_controller { + bus = 9; + } + } + } + } + ``` + + match\_attr字段必须与device\_info.hcs中的deviceMatch\_Attr保持一致,在此文件中配置驱动需要的参数,通过match\_attr可匹配至对应的驱动,该驱动即可在Bind或Init中调用DeviceResourceGetIfaceInstance\(\)函数获取这些配置参数。 + + 若配置文件为新文件,则需要在板级配置入口文件hdf.hcs中引用该配置文件,例如: + + ``` + #include "device_info/device_info.hcs" + #include "i2c/i2c_config.hcs" + ``` + + 由于本例中在原有的i2c\_config.hcs内添加配置参数,没有新建配置文件,因此无需再将i2c\_config.hcs添加至板级配置入口文件中。 + +3. 驱动从HCS获取配置参数。 + + 在本例中,驱动需要通过HCS获取寄存器物理基地址、寄存器大小、总线号等参数,从而对控制器进行正确配置。 + + ``` + /* 从HCS获取配置参数 */ + static int32_t SampleI2cReadDrs(struct SampleI2cCntlr *sampleCntlr, const struct DeviceResourceNode *node) + { + int32_t ret; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { // 确保GetUint32方法可用 + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return HDF_FAILURE; + } + + ret = drsOps->GetUint32(node, "reg_pbase", &sampleCntlr->regBasePhy, 0); // 从HCS读取物理基地址reg_pbase + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regBase fail!", __func__); + return ret; + } + + ret = drsOps->GetUint16(node, "reg_size", &sampleCntlr->regSize, 0); // 从HCS读取寄存器大小reg_size + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regsize fail!", __func__); + return ret; + } + + ret = drsOps->GetUint16(node, "bus", (uint16_t *)&sampleCntlr->bus, 0); // 从HCS读取总线号bus + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read bus fail!", __func__); + return ret; + } + + return HDF_SUCCESS; + } + ``` + + +### 添加控制器 + +初始化控制器硬件,并调用核心层接口完成向核心层添加、删除设备,以及钩子函数的实现等。 + +1. 定义结构体,实现钩子函数并赋值至函数指针。 + + I2cMethod结构体在i2c\_core.h中定义,其中通过函数指针的方式定义了I2C需要实现的方法,transfer方法为用于传输的钩子函数,在驱动中需要做具体实现并对函数指针赋值。 + + 示例代码如下: + + ``` + /* 自定义设备结构体,继承父类I2cCntlr */ + struct SampleI2cCntlr { + struct I2cCntlr cntlr; + OsalSpinlock spin; + volatile unsigned char *regBase; + uint16_t regSize; + int16_t bus; + uint32_t regBasePhy; + }; + + /* 消息结构体,继承父类I2cMsg */ + struct SampleTransferData { + struct I2cMsg *msgs; + int16_t index; + int16_t count; + }; + /* 钩子函数实现 */ + static int32_t SampleI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count) + { + int32_t ret = HDF_SUCCESS; + struct SampleI2cCntlr *sampleCntlr = NULL; + struct SampleTransferData td; + + if (cntlr == NULL || cntlr->priv == NULL) { + HDF_LOGE("SampleI2cTransfer: cntlr lor sampleCntlr is null!"); + return HDF_ERR_INVALID_OBJECT; + } + sampleCntlr = (struct SampleI2cCntlr *)cntlr; + + if (msgs == NULL || count <= 0) { + HDF_LOGE("SampleI2cTransfer: err parms! count:%d", count); + return HDF_ERR_INVALID_PARAM; + } + td.msgs = msgs; + td.count = count; + td.index = 0; + + HDF_LOGE("Successfully transmitted!"); // 表示此处传输成功 + + td.index = count; // 经过处理,最后实际发送msg个数等于count,返回已发送个数,此句代替已省略的处理过程 + return (td.index > 0) ? td.index : ret; + } + /* 钩子函数赋值 */ + static struct I2cMethod g_method = { + .transfer = SampleI2cTransfer, + }; + ``` + +2. 编写驱动初始化函数。 + + 本例中使用SampleI2cInit作为驱动初始化函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Init,以供HDF驱动框架调用从而达到初始化驱动的目的。该函数中需要对从HCS获取的配置参数进行解析,并按照这些参数创建控制器。示例如下: + + ``` + /* 解析参数,申请内存并创建控制器 */ + static int32_t SampleI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) + { + int32_t ret; + struct SampleI2cCntlr *sampleCntlr = NULL; + (void)device; + + sampleCntlr = (struct SampleI2cCntlr *)OsalMemCalloc(sizeof(*sampleCntlr)); + if (sampleCntlr == NULL) { + HDF_LOGE("%s: malloc sampleCntlr fail!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + ret = SampleI2cReadDrs(sampleCntlr, node); // 从HCS获取配置参数 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read drs fail! ret:%d", __func__, ret); + goto __ERR__; + } + + sampleCntlr->regBase = OsalIoRemap(sampleCntlr->regBasePhy, sampleCntlr->regSize); + if (sampleCntlr->regBase == NULL) { + HDF_LOGE("%s: ioremap regBase fail!", __func__); + ret = HDF_ERR_IO; + goto __ERR__; + } + + HDF_LOGE("The controller has been initialized!"); // 表示此处省略的控制器初始化操作已经成功 + + sampleCntlr->cntlr.priv = (void *)node; + sampleCntlr->cntlr.busId = sampleCntlr->bus; + sampleCntlr->cntlr.ops = &g_method; + (void)OsalSpinInit(&sampleCntlr->spin); // 初始化自旋锁 + ret = I2cCntlrAdd(&sampleCntlr->cntlr); // 向核心层添加控制器 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: add i2c controller fail:%d!", __func__, ret); + goto __ERR__; + } + + return HDF_SUCCESS; + __ERR__: // 错误处理 + if (sampleCntlr != NULL) { + if (sampleCntlr->regBase != NULL) { + OsalIoUnmap((void *)sampleCntlr->regBase); // 取消地址映射 + sampleCntlr->regBase = NULL; + } + OsalMemFree(sampleCntlr); // 释放内存 + sampleCntlr = NULL; + } + return ret; + } + /* 驱动入口初始化函数 */ + static int32_t SampleI2cInit(struct HdfDeviceObject *device) + { + int32_t ret; + const struct DeviceResourceNode *childNode = NULL; + + HDF_LOGE("%s: Enter", __func__); + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is NULL", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + ret = HDF_SUCCESS; + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + ret = SampleI2cParseAndInit(device, childNode); // 调用解析参数和创建控制器的函数 + if (ret != HDF_SUCCESS) { + break; + } + } + return ret; + } + ``` + +3. 编写驱动释放函数。 + + 本例中使用SampleI2cRelease作为驱动释放函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,将调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。示例如下: + + ``` + /* 删除控制器函数 */ + static void SampleI2cRemoveByNode(const struct DeviceResourceNode *node) + { + int32_t ret; + int16_t bus; + struct I2cCntlr *cntlr = NULL; + struct SampleI2cCntlr *sampleCntlr = NULL; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return; + } + + ret = drsOps->GetUint16(node, "bus", (uint16_t *)&bus, 0); // 从HCS获取I2C总线号 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read bus fail!", __func__); + return; + } + + cntlr = I2cCntlrGet(bus); + if (cntlr != NULL && cntlr->priv == node) { // 根据I2C总线号删除控制器 + I2cCntlrPut(cntlr); + I2cCntlrRemove(cntlr); + sampleCntlr = (struct SampleI2cCntlr *)cntlr; + OsalIoUnmap((void *)sampleCntlr->regBase); + OsalMemFree(sampleCntlr); + } + return; + } + /* 释放资源 */ + static void SampleI2cRelease(struct HdfDeviceObject *device) + { + const struct DeviceResourceNode *childNode = NULL; + + HDF_LOGI("%s: enter", __func__); + + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is NULL", __func__); + return; + } + + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + SampleI2cRemoveByNode(childNode); // 调用删除控制器函数 + } + } + ``` + + +## 编译及烧录 + +1. 编辑Makefile,添加源文件: + + ``` + include drivers/hdf/khdf/platform/platform.mk + + obj-y += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_core.o \ + $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_if.o \ + ./i2c_adapter.o \ + ./i2c_sample.o + ``` + + "./i2c\_sample.o"为本示例中在Makefile中追加的内容。 + +2. 编译及烧录。 + + 具体操作请参考[标准系统快速入门编译及烧录章节](../quick-start/标准系统入门.md)。 diff --git "a/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213-5.md" "b/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213-4.md" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213-5.md" rename to "zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213-4.md" diff --git "a/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213.md" "b/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213.md" index 21cb165165fec20314a38415096eb0959a94869d..5d9fe71891c8f2e2cc5baa03db945da09c7b2ce5 100755 --- "a/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213.md" +++ "b/zh-cn/device-dev/guide/\345\272\224\347\224\250\345\256\236\344\276\213.md" @@ -5,7 +5,7 @@ 修改applications/sample/camera/media/BUILD.gn中的output\_dir。 - 修改前:output\_dir = "$root\_out\_dir/dev\_tools" - - 修改后:output\_dir = "$root\_out\_d_i_r/" + - 修改后:output\_dir = "$root\_out\_dir/" 重新执行源码仓编译并烧写入单板后,可在单板bin目录下找到camera\_sample文件。 diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221-11.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221-11.md" deleted file mode 100644 index a7dedada78968ebaaf7e6f721e9ec4d7cf41994c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221-11.md" +++ /dev/null @@ -1,396 +0,0 @@ -# 开发 - -- [实例化驱动入口](#section6586911816) -- [设置相关参数](#section114323217503) -- [添加控制器](#section115187812516) - -平台驱动开发包含以下几步: - -1. 实例化驱动入口: 实例化一个HdfDriverEntry 对象作为驱动入口。 -2. 设置相关参数:通过配置device\_info.hcs,并从HCS获取并解析设备的配置参数以确保驱动能够正确加载。 -3. 添加控制器:初始化控制器硬件,并调用核心层接口完成向核心层添加、删除设备,以及钩子函数的实现等。 - -本例中涉及的文件及路径如下表: - -**表 1** 文件说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

说明

-

文件路径

-

操作

-

示例文件

-

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

-

新增文件

-

设备服务文件

-

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

-

-

追加内容

-

-

配置参数文件

-

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

-

编译文件

-

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

-

依赖头文件

-

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

-

作为头文件引用

-

-

核心层头文件

-

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

-

HCS配置入口文件

-

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

-

HCS配置文件总入口

-
- ->![](public_sys-resources/icon-caution.gif) **注意:** ->本例程涉及的文件路径均作为演示,驱动开发者应根据实际情况确定具体的源文件存放位置。 - -## 实例化驱动入口 - -驱动入口必须为HdfDriverEntry(在hdf\_device\_desc.h中定义)类型的全局变量,且moduleName要和device\_info.hcs中保持一致。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - -I2C驱动中没有实现Bind方法,因为I2C控制器由manager管理,而在manager中已经实现了Bind方法,因此I2C驱动中无需再绑定服务。 - -实例化驱动入口的示例代码如下: - -``` -/* 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量 */ -struct HdfDriverEntry g_sampleI2cDriverEntry = { - .moduleVersion = 1, - .Init = SampleI2cInit, - .Release = SampleI2cRelease, - .moduleName = "demo_i2c_driver", -}; -/* 调用HDF_INIT将驱动入口注册到HDF框架中 */ -HDF_INIT(g_sampleI2cDriverEntry); -``` - -## 设置相关参数 - -1. 添加设备服务节点(必选)。 - - 编辑device\_info.hcs,在device\_i2c :: device下添加驱动设备服务节点,示例如下: - - ``` - root { - device_info { - match_attr = "hdf_manager"; - device_i2c :: device { // i2c设备节点 - device2 :: deviceNode { // i2c驱动的DeviceNode节点 - policy = 0; // policy字段是驱动服务发布的策略 - priority = 55; // 驱动启动优先级 - permission = 0644; // 驱动创建设备节点权限 - moduleName = "demo_i2c_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 - serviceName = "DEMO_I2C_DRIVER"; // 驱动对外发布服务的名称,必须唯一 - deviceMatchAttr = "demo_i2c_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的 - // match_attr值相等 - } - } - } - } - - ``` - - >![](public_sys-resources/icon-notice.gif) **须知:** - >配置文件中的priority(取值范围为整数0到200)是用来表示host和驱动的优先级,不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高,驱动的priority值相同则不保证加载顺序。 - -2. 添加配置参数(可选)。 - - 有时驱动可能会需要私有配置信息,以确保寄存器的配置可以满足不同产品的需求。如需要私有配置信息,则可以添加一个驱动的配置文件,用来存放一些驱动的默认配置信息,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init(参考[驱动开发](../driver/驱动开发.md))传递给驱动。驱动开发者可新建配置文件,并在板级驱动hdf.hcs中引用新建的配置文件,本例中直接在原有的配置文件i2c\_config.hcs内添加配置参数。 - - 本例中编辑i2c\_config.hcs,添加配置参数: - - ``` - root { - platform { - i2c_config_demo { - match_attr = "demo_i2c_config"; // 该字段的值必须和device_info.hcs中的deviceMatchAttr值一致 - - template i2c_controller { // 参数模板 - bus = 0; - reg_pbase = 0x120b0000; - reg_size = 0xd1; - } - - controller_demo_0 :: i2c_controller { // 两个I2C示例控制器 - bus = 8; - } - controller_demo_1 :: i2c_controller { - bus = 9; - } - } - } - } - ``` - - match\_attr字段必须与device\_info.hcs中的deviceMatch\_Attr保持一致,在此文件中配置驱动需要的参数,通过match\_attr可匹配至对应的驱动,该驱动即可在Bind或Init中调用DeviceResourceGetIfaceInstance\(\)函数获取这些配置参数。 - - 若配置文件为新文件,则需要在板级配置入口文件hdf.hcs中引用该配置文件,例如: - - ``` - #include "device_info/device_info.hcs" - #include "i2c/i2c_config.hcs" - ``` - - 由于本例中在原有的i2c\_config.hcs内添加配置参数,没有新建配置文件,因此无需再将i2c\_config.hcs添加至板级配置入口文件中。 - -3. 驱动从HCS获取配置参数。 - - 在本例中,驱动需要通过HCS获取寄存器物理基地址、寄存器大小、总线号等参数,从而对控制器进行正确配置。 - - ``` - /* 从HCS获取配置参数 */ - static int32_t SampleI2cReadDrs(struct SampleI2cCntlr *sampleCntlr, const struct DeviceResourceNode *node) - { - int32_t ret; - struct DeviceResourceIface *drsOps = NULL; - - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL) { // 确保GetUint32方法可用 - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return HDF_FAILURE; - } - - ret = drsOps->GetUint32(node, "reg_pbase", &sampleCntlr->regBasePhy, 0); // 从HCS读取物理基地址reg_pbase - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regBase fail!", __func__); - return ret; - } - - ret = drsOps->GetUint16(node, "reg_size", &sampleCntlr->regSize, 0); // 从HCS读取寄存器大小reg_size - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regsize fail!", __func__); - return ret; - } - - ret = drsOps->GetUint16(node, "bus", (uint16_t *)&sampleCntlr->bus, 0); // 从HCS读取总线号bus - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read bus fail!", __func__); - return ret; - } - - return HDF_SUCCESS; - } - ``` - - -## 添加控制器 - -1. 定义结构体,实现钩子函数并赋值至函数指针。 - - I2cMethod结构体在i2c\_core.h中定义,其中通过函数指针的方式定义了I2C需要实现的方法,transfer方法为用于传输的钩子函数,在驱动中需要做具体实现并对函数指针赋值。 - - 示例代码如下: - - ``` - /* 自定义设备结构体,继承父类I2cCntlr */ - struct SampleI2cCntlr { - struct I2cCntlr cntlr; - OsalSpinlock spin; - volatile unsigned char *regBase; - uint16_t regSize; - int16_t bus; - uint32_t regBasePhy; - }; - - /* 消息结构体,继承父类I2cMsg */ - struct SampleTransferData { - struct I2cMsg *msgs; - int16_t index; - int16_t count; - }; - /* 钩子函数实现 */ - static int32_t SampleI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count) - { - int32_t ret = HDF_SUCCESS; - struct SampleI2cCntlr *sampleCntlr = NULL; - struct SampleTransferData td; - - if (cntlr == NULL || cntlr->priv == NULL) { - HDF_LOGE("SampleI2cTransfer: cntlr lor sampleCntlr is null!"); - return HDF_ERR_INVALID_OBJECT; - } - sampleCntlr = (struct SampleI2cCntlr *)cntlr; - - if (msgs == NULL || count <= 0) { - HDF_LOGE("SampleI2cTransfer: err parms! count:%d", count); - return HDF_ERR_INVALID_PARAM; - } - td.msgs = msgs; - td.count = count; - td.index = 0; - - HDF_LOGE("Successfully transmitted!"); // 表示此处传输成功 - - td.index = count; // 经过处理,最后实际发送msg个数等于count,返回已发送个数,此句代替已省略的处理过程 - return (td.index > 0) ? td.index : ret; - } - /* 钩子函数赋值 */ - static struct I2cMethod g_method = { - .transfer = SampleI2cTransfer, - }; - ``` - -2. 编写驱动初始化函数。 - - 本例中使用SampleI2cInit作为驱动初始化函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Init,以供HDF驱动框架调用从而达到初始化驱动的目的。该函数中需要对从HCS获取的配置参数进行解析,并按照这些参数创建控制器。示例如下: - - ``` - /* 解析参数,申请内存并创建控制器 */ - static int32_t SampleI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) - { - int32_t ret; - struct SampleI2cCntlr *sampleCntlr = NULL; - (void)device; - - sampleCntlr = (struct SampleI2cCntlr *)OsalMemCalloc(sizeof(*sampleCntlr)); - if (sampleCntlr == NULL) { - HDF_LOGE("%s: malloc sampleCntlr fail!", __func__); - return HDF_ERR_MALLOC_FAIL; - } - - ret = SampleI2cReadDrs(sampleCntlr, node); // 从HCS获取配置参数 - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read drs fail! ret:%d", __func__, ret); - goto __ERR__; - } - - sampleCntlr->regBase = OsalIoRemap(sampleCntlr->regBasePhy, sampleCntlr->regSize); - if (sampleCntlr->regBase == NULL) { - HDF_LOGE("%s: ioremap regBase fail!", __func__); - ret = HDF_ERR_IO; - goto __ERR__; - } - - HDF_LOGE("The controller has been initialized!"); // 表示此处省略的控制器初始化操作已经成功 - - sampleCntlr->cntlr.priv = (void *)node; - sampleCntlr->cntlr.busId = sampleCntlr->bus; - sampleCntlr->cntlr.ops = &g_method; - (void)OsalSpinInit(&sampleCntlr->spin); // 初始化自旋锁 - ret = I2cCntlrAdd(&sampleCntlr->cntlr); // 向核心层添加控制器 - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: add i2c controller fail:%d!", __func__, ret); - goto __ERR__; - } - - return HDF_SUCCESS; - __ERR__: // 错误处理 - if (sampleCntlr != NULL) { - if (sampleCntlr->regBase != NULL) { - OsalIoUnmap((void *)sampleCntlr->regBase); // 取消地址映射 - sampleCntlr->regBase = NULL; - } - OsalMemFree(sampleCntlr); // 释放内存 - sampleCntlr = NULL; - } - return ret; - } - /* 驱动入口初始化函数 */ - static int32_t SampleI2cInit(struct HdfDeviceObject *device) - { - int32_t ret; - const struct DeviceResourceNode *childNode = NULL; - - HDF_LOGE("%s: Enter", __func__); - if (device == NULL || device->property == NULL) { - HDF_LOGE("%s: device or property is NULL", __func__); - return HDF_ERR_INVALID_OBJECT; - } - - ret = HDF_SUCCESS; - DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { - ret = SampleI2cParseAndInit(device, childNode); // 调用解析参数和创建控制器的函数 - if (ret != HDF_SUCCESS) { - break; - } - } - return ret; - } - ``` - -3. 编写驱动释放函数。 - - 本例中使用SampleI2cRelease作为驱动释放函数的函数名(函数名称可由驱动开发者确定),该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,将调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。示例如下: - - ``` - /* 删除控制器函数 */ - static void SampleI2cRemoveByNode(const struct DeviceResourceNode *node) - { - int32_t ret; - int16_t bus; - struct I2cCntlr *cntlr = NULL; - struct SampleI2cCntlr *sampleCntlr = NULL; - struct DeviceResourceIface *drsOps = NULL; - - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL) { - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return; - } - - ret = drsOps->GetUint16(node, "bus", (uint16_t *)&bus, 0); // 从HCS获取I2C总线号 - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read bus fail!", __func__); - return; - } - - cntlr = I2cCntlrGet(bus); - if (cntlr != NULL && cntlr->priv == node) { // 根据I2C总线号删除控制器 - I2cCntlrPut(cntlr); - I2cCntlrRemove(cntlr); - sampleCntlr = (struct SampleI2cCntlr *)cntlr; - OsalIoUnmap((void *)sampleCntlr->regBase); - OsalMemFree(sampleCntlr); - } - return; - } - /* 释放资源 */ - static void SampleI2cRelease(struct HdfDeviceObject *device) - { - const struct DeviceResourceNode *childNode = NULL; - - HDF_LOGI("%s: enter", __func__); - - if (device == NULL || device->property == NULL) { - HDF_LOGE("%s: device or property is NULL", __func__); - return; - } - - DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { - SampleI2cRemoveByNode(childNode); // 调用删除控制器函数 - } - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221.md" deleted file mode 100755 index 18b3247aefef1bb7d1c24a961900349325110ad6..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221.md" +++ /dev/null @@ -1,91 +0,0 @@ -# 开发 - -1. 请先完成[《Hi3861快速入门》](../quick-start/Hi3861开发板介绍.md)。 - - LED控制参考示例存放于applications/sample/wifi-iot/app/iothardware/led\_example.c文件中。 - -2. 实现IOT外设控制,首先需要通过查阅原理图明确接线关系。经过查阅,hispark pegasus的LED与芯片的9号管脚相连。 - - ``` - #define LED_TEST_GPIO 9 - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - >开发板原理图,请开发者联系Hi3861购买渠道客服获取。 - -3. 使用GPIO前,需要完成GPIO管脚初始化,明确管脚用途,并创建任务,使LED周期性亮灭,达到闪烁的效果。 - - ``` - static void LedExampleEntry(void) - { - osThreadAttr_t attr; - - /* 管脚初始化 */ - IoTGpioInit(LED_TEST_GPIO); - /* 配置9号管脚为输出方向 */ - IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT); - - attr.name = "LedTask"; - attr.attr_bits = 0U; - attr.cb_mem = NULL; - attr.cb_size = 0U; - attr.stack_mem = NULL; - attr.stack_size = LED_TASK_STACK_SIZE; - attr.priority = LED_TASK_PRIO; - - /* 启动任务 */ - if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) { - printf("[LedExample] Falied to create LedTask!\n"); - } - } - ``` - -4. 在循环任务中通过周期性亮灭形式实现LED闪烁。 - - ``` - static void *LedTask(const char *arg) - { - (void)arg; - while (1) { - switch (g_ledState) { - case LED_ON: - IoTGpioSetOutputVal(LED_TEST_GPIO, 1); - usleep(LED_INTERVAL_TIME_US); - break; - case LED_OFF: - IoTGpioSetOutputVal(LED_TEST_GPIO, 0); - usleep(LED_INTERVAL_TIME_US); - break; - case LED_SPARK: - IoTGpioSetOutputVal(LED_TEST_GPIO, 0); - usleep(LED_INTERVAL_TIME_US); - IoTGpioSetOutputVal(LED_TEST_GPIO, 1); - usleep(LED_INTERVAL_TIME_US); - break; - default: - usleep(LED_INTERVAL_TIME_US); - break; - } - } - return NULL; - } - ``` - -5. 在代码最下方,使用OpenHarmony启动恢复模块接口SYS\_RUN\(\)启动业务。(SYS\_RUN定义在ohos\_init.h文件中) - - ``` - SYS_RUN(LedExampleEntry); - ``` - -6. 修改applications/sample/wifi-iot/app/BUILD.gn文件,使led\_example.c参与编译。 - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("app") { - features = [ - "iothardware:led_example" - ] - } - ``` - - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207-8.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207-8.md" deleted file mode 100755 index 52eed11deb14636b5a5cf069cf7fc7dbc62196e1..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\345\207\206\345\244\207-8.md" +++ /dev/null @@ -1,8 +0,0 @@ -# 开发准备 - -- [准备开发环境和创建工程](#section1912530122716) - -## 准备开发环境和创建工程 - -首先需要下载和配置DevEco Studio,具体操作请参考[DevEco Studio 使用指南](../../application-dev/quick-start/DevEco-Studio(OpenHarmony)使用指南.md)。 - diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\351\246\226\351\241\265.md" "b/zh-cn/device-dev/guide/\345\274\200\345\217\221\351\246\226\351\241\265.md" index c80d70f94f323a6a705bb2b1dd1c5823eb490b7d..7c93aefcb11cadee6c812e90353fbed9abc9247e 100755 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\351\246\226\351\241\265.md" +++ "b/zh-cn/device-dev/guide/\345\274\200\345\217\221\351\246\226\351\241\265.md" @@ -2,7 +2,7 @@ 应用首页主要展示城市的空气质量概况。首页总共有两屏(可以根据需求设置多屏),每屏显示一个城市的空气质量信息:主要包括AQI指数、城市名称、污染物指数、更新时间和信息来源等数据。 -从第一章节中的[显示效果图](概述-6.md#fig18250512195914)分析可知,首页由三部分组成: +从第一章节中的[显示效果图](概述-5.md#fig18250512195914)分析可知,首页由三部分组成: - 标题栏:位于页面正上方,位置固定,包括应用退出按钮和页面标题。 - 信息栏:主要展示城市的空气信息指标等内容;该页面根据用户需求可设置多屏,且能循环滑动。 diff --git "a/zh-cn/device-dev/guide/\345\274\200\346\234\272\346\227\245\345\277\227\345\210\206\346\236\220.md" "b/zh-cn/device-dev/guide/\345\274\200\346\234\272\346\227\245\345\277\227\345\210\206\346\236\220.md" deleted file mode 100644 index 469d6a3566fe136c2bb59993abde4b12551e4c03..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\345\274\200\346\234\272\346\227\245\345\277\227\345\210\206\346\236\220.md" +++ /dev/null @@ -1,19 +0,0 @@ -# 开机日志分析 - -如下所示为开机启动日志部分截取 - -``` -[I/HDF_INPUT_DRV] HdfInputManagerInit: enter // 管理驱动层初始化 -[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ // 初始化成功 -[I/osal_cdev] add cdev hdf_input_host success -[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter // 公共驱动层初始化 -[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ // 初始化成功 -[I/osal_cdev] add cdev hdf_input_event1 success -[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter // 器件驱动层初始化 -[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060 -[I/HDF_INPUT_DRV] Product_ID: 911_1060, x_sol = 960, y_sol = 480 -[I/HDF_LOG_TAG] ChipDriverInit: chipDetect succ, ret = 0 -[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch -[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911 // 初始化成功 -``` - diff --git "a/zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274-4.md" "b/zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274-3.md" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274-4.md" rename to "zh-cn/device-dev/guide/\345\275\225\345\203\217\345\274\200\345\217\221\346\214\207\345\257\274-3.md" diff --git "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-3.md" "b/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-2.md" old mode 100755 new mode 100644 similarity index 99% rename from "zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-3.md" rename to "zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-2.md" index 83e445c0ed119ba040d2544e9793831a2cd2b05b..0cae9c359bf6c5b036a4f947635d7c2ca289b65a --- "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-3.md" +++ "b/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274-2.md" @@ -385,6 +385,7 @@ Surface *surface = Surface::CreateSurface(); if (surface == nullptr) { delete fc; + return; } surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ fc->AddSurface(*surface); diff --git "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" index e59c365a5c6fe2e58a8333157758418d1508175c..31edc27814baddb754614c87ca0225979ef408ff 100755 --- "a/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ "b/zh-cn/device-dev/guide/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" @@ -385,6 +385,7 @@ Surface *surface = Surface::CreateSurface(); if (surface == nullptr) { delete fc; + return; } surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ fc->AddSurface(*surface); diff --git "a/zh-cn/device-dev/guide/\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" "b/zh-cn/device-dev/guide/\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" index 65f7df79807efc4e7fb9d33879b707e1d6ec1ce3..760e3d563de2f60ddd315d553df3b324d4450f22 100755 --- "a/zh-cn/device-dev/guide/\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" +++ "b/zh-cn/device-dev/guide/\346\221\204\345\203\217\345\244\264\346\216\247\345\210\266.md" @@ -1,6 +1,6 @@ # 摄像头控制 -- **[概述](概述-0.md)** +- **[概述](概述.md)** - **[示例开发](示例开发.md)** diff --git "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\346\255\245\351\252\244.md" "b/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\346\214\207\345\257\274.md" similarity index 42% rename from "zh-cn/device-dev/guide/\345\274\200\345\217\221\346\255\245\351\252\244.md" rename to "zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\346\214\207\345\257\274.md" index ae738663fd4e90e5df3427c9a46dcb6755054fba..56df9a0d92ae4be7094f7049ff6ce481e3bf6591 100644 --- "a/zh-cn/device-dev/guide/\345\274\200\345\217\221\346\255\245\351\252\244.md" +++ "b/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\346\214\207\345\257\274.md" @@ -1,8 +1,35 @@ -# 开发步骤 +# 时钟应用开发指导 + +- [概述](#section11522349121115) +- [开发准备](#section6592121861218) +- [开发步骤](#section19901741111312) +- [签名打包](#section10601181101516) +- [真机运行](#section092721731511) +- [常见问题](#section1122413460153) + - [hdc\_std连接不到设备](#section1922725151614) + - [hdc\_std运行不了](#section15657547131615) + + +## 概述 + +本文将介绍如何快速搭建基于OpenHarmony标准系统(Hi3516DV300开发板)的应用开发环境,并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过[本链接](https://gitee.com/openharmony/app_samples/tree/master/common/Clock)获取。 + +时钟App是一款显示实时时间的应用,显示效果如下图所示: + +**图 1** 时钟应用显示效果图 + + +![](figures/Clock.png) + +## 开发准备 + +首先需要下载和配置DevEco Studio,具体操作请参考[DevEco Studio 使用指南](../../application-dev/quick-start/DevEco-Studio(OpenHarmony)使用指南.md)。 + +## 开发步骤 应用的功能是通过表盘和数字显示实时时间。 -从第一章节中的[显示效果图](概述-7.md#fig7763172132019)分析可知,页面由两个部分组成: +从[显示效果图](时钟应用开发指导.md#fig7763172132019)分析可知,页面由两个部分组成: - 表盘栏:主要展示一个动态的钟表,且钟表指针能准确转动。 - 数字时间栏:主要以数字形式显示当前时间。 @@ -133,98 +160,173 @@ ``` 4. 所有组件设置样式、动画效果和数据动态绑定,完整代码如下所示: - - **index.hml文件** + ``` +
+ + + + + + + {{ hour }}:{{ minute }}:{{ second }} +
+ ``` + + + - **index.css文件** + + ``` + .container { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + } + + .stack { + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 50%; + } + + .digit-clock { + font-size: 58px; + width: 100%; + margin-top: 0px; + text-align: center; + } + + .clock-bg { + width: 80%; + height: 80%; + object-fit: scale-down; + } + + .clock-hand { + width: 25%; + height: 65%; + object-fit: contain; + } + ``` + + + - **index.js:** + + js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:定时获取系统时间。 + + ``` + export default { + timer: undefined, + data: { + hour: 0, + minute: 0, + second: 0 + }, + onInit() { + this.updateTime() + this.timer = setInterval(this.updateTime, 1000) + }, + updateTime: function () { + var nowTime = new Date() + this.hour = nowTime.getHours() + this.minute = nowTime.getMinutes() + this.second = nowTime.getSeconds() + if (this.hour < 10) { + this.hour = '0' + this.hour + } + if (this.minute < 10) { + this.minute = '0' + this.minute + } + if (this.second < 10) { + this.second = '0' + this.second + } + }, + onDestroy() { + clearInterval(this.timer); + } + } + ``` + + + +## 签名打包 + +代码编写完成后,在真机设备上运行应用,需要先对应用进行签名,然后再进行打包,具体操作请参考[签名打包指导](../../application-dev/quick-start/配置OpenHarmony应用签名信息.md)。 + +## 真机运行 + +应用签名打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony系统烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[标准系统Hi3516快速入门](../quick-start/标准系统入门.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载应用。 + +1. 从开发者工具代码仓路径中获取hdc客户端。 + ``` -
- - - - - - - {{ hour }}:{{ minute }}:{{ second }} -
+ developtools/hdc_standard/prebuilt/windows/hdc_std.exe ``` - - **index.css文件** + 修改名称为hdc.exe,并将工具路径加入系统环境path变量中。 + +2. 启动cmd命令窗口,执行以下命令,推送hap应用包到设备目录下并安装。 ``` - .container { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - } - - .stack { - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - height: 50%; - } - - .digit-clock { - font-size: 58px; - width: 100%; - margin-top: 0px; - text-align: center; - } - - .clock-bg { - width: 80%; - height: 80%; - object-fit: scale-down; - } - - .clock-hand { - width: 25%; - height: 65%; - object-fit: contain; - } + hdc smode + hdc target mount + hdc file send clock.hap /data/clock.hap + hdc shell chmod 666 /data/clock.hap + hdc shell bm install -p /data/clock.hap ``` - - **index.js:** +3. 启动应用。执行以下命令,其中ohos.samples.clock为应用包名,MainAbility为应用启动的Ability。 - js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:定时获取系统时间。 + ``` + hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock + ``` + +4. 卸载应用(可选)。执行以下命令,其中ohos.samples.clock为应用包名。 ``` - export default { - timer: undefined, - data: { - hour: 0, - minute: 0, - second: 0 - }, - onInit() { - this.updateTime() - this.timer = setInterval(this.updateTime, 1000) - }, - updateTime: function () { - var nowTime = new Date() - this.hour = nowTime.getHours() - this.minute = nowTime.getMinutes() - this.second = nowTime.getSeconds() - if (this.hour < 10) { - this.hour = '0' + this.hour - } - if (this.minute < 10) { - this.minute = '0' + this.minute - } - if (this.second < 10) { - this.second = '0' + this.second - } - }, - onDestroy() { - clearInterval(this.timer); - } - } + hdc shell bm uninstall -n ohos.samples.clock ``` +## 常见问题 + +### hdc\_std连接不到设备 + +- **现象描述** + + 执行 "hdc\_std list targets"命令后结果为:\[Empty\] + +- **可能原因和解决方法** + 1. 设备没有被识别: + + 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 + + 2. hdc\_std工作异常: + + 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 + + 3. hdc\_std与设备不匹配: + + 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 + + + +### hdc\_std运行不了 + +- **现象描述** + + 点击hdc\_std.exe文件无法运行。 + +- **可能原因和解决方法** + + hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 + + diff --git "a/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\347\244\272\344\276\213.md" deleted file mode 100644 index 3cbff6960f629645fc6f4cca541d7e0dcbee0722..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\227\266\351\222\237\345\272\224\347\224\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 时钟应用开发示例 - -- **[概述](概述-7.md)** - -- **[开发准备](开发准备-8.md)** - -- **[开发步骤](开发步骤.md)** - -- **[签名打包](签名打包.md)** - -- **[真机运行](真机运行-9.md)** - -- **[常见问题](常见问题-10.md)** - - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-0.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-0.md" index e3d5da250e043ac86136b0d8ad5a220f946fefc2..ad74728ebf00a8828271f5e5b466978df3c06dcf 100755 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-0.md" +++ "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-0.md" @@ -1,10 +1,10 @@ -# 概述 +# 概述 -本文档将介绍如何基于IoT Camera开发板,利用开发套件中自带的摄像头,完成拍照、录像功能。 +本文档将介绍如何基于IoT Camera开发板(Hi3516DV300),利用其摄像头和屏幕,完成拍照、录像和视频预览功能。 -开发者可通过执行示例应用,对开发板的外设控制有了更深入了解后,可使用开发板完成摄像头等设备。 +通过本文档,开发者能够对OpenHarmony的摄像控制有更深入的了解,可参照本例尝试完成“智能猫眼”、“智能后视镜”、“智能带屏音箱”等设备的开发。 -若开发者想先查看示例效果,请进入[应用实例](应用实例.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 +若开发者想先查看示例效果,请进入[应用实例](应用实例-4.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 -相机开发基本概念可参考:[相机开发概述](../subsystems/相机开发概述.md)。 +相机应用开发的基本概念请参考:[相机开发概述](../subsystems/相机开发概述.md)。 diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-1.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-1.md" deleted file mode 100755 index f265cdb276c1d92bf06280ad54ba3fb5f210f46d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-1.md" +++ /dev/null @@ -1,10 +0,0 @@ -# 概述 - -本文档将介绍如何基于IoT Camera开发板(Hi3516DV300),利用其摄像头和屏幕,完成拍照、录像和视频预览功能。 - -通过本文档,开发者能够对OpenHarmony的摄像控制有更深入的了解,可参照本例尝试完成“智能猫眼”、“智能后视镜”、“智能带屏音箱”等设备的开发。 - -若开发者想先查看示例效果,请进入[应用实例](应用实例-5.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 - -相机应用开发的基本概念请参考:[相机开发概述](../subsystems/相机开发概述.md)。 - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-10.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-10.md" deleted file mode 100644 index 16734e3f17205895f57f82921da60c53d475f77a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-10.md" +++ /dev/null @@ -1,26 +0,0 @@ -# 概述 - -- [场景介绍](#section191543223549) - -本文档将以I2C驱动为例,介绍如何基于HDF驱动框架完成平台驱动开发。 - ->![](public_sys-resources/icon-caution.gif) **注意:** ->本例仅作为平台驱动开发示例参考,开发者不可直接用于商用集成。 - -## 场景介绍 - -HDF驱动框架为常用外围设备提供了标准的驱动框架,驱动开发者只需将驱动适配至HDF驱动框架,即可通过HDF驱动框架提供的接口操作外围设备。 - -本文以I2C为例。其时序流程如[图1](#fig148041484161)所示。 - -**图 1** I2C时序流程图 - - -![](figures/zh-cn_image_0000001161922745.png) - -- User Business:用户业务驱动。 -- i2cManagerEntry:I2C管理器入口,注册I2cManager到HDF驱动框架。 -- I2cManager:I2C管理器,管理I2C控制器。 -- I2cCntlr:I2C控制器。 -- i2cDriverEntry:I2C控制器入口,注册I2cCntlr到HDF驱动框架。 - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-12.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-12.md" deleted file mode 100644 index 0606b801b5eb33741f1c9cb78d67edf52318712a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-12.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 概述 - -本文档将介绍如何基于Hi3516DV300开发板完成基于HDF\_Input模型的触摸屏器件驱动开发,从而使开发者快速入门,进行基于的外设驱动开发。 - -- **[硬件资源介绍](硬件资源介绍.md)** - -- **[Input模型简介](Input模型简介.md)** - - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-6.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-5.md" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/guide/\346\246\202\350\277\260-6.md" rename to "zh-cn/device-dev/guide/\346\246\202\350\277\260-5.md" diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-7.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260-7.md" deleted file mode 100755 index e032aa00bcccc4972464e760e165742db5ffdf61..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260-7.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 概述 - -- [效果展示](#section3997224182313) - -本文将介绍如何快速搭建基于OpenHarmony标准系统(Hi3516DV300开发板)的应用开发环境,并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过[本链接](https://gitee.com/openharmony/app_samples/tree/master/common/Clock)获取。 - -## 效果展示 - -时钟App是一款显示实时时间的应用,显示效果如下图所示: - -**图 1** 时钟应用显示效果图 - - -![](figures/Clock.png) - diff --git "a/zh-cn/device-dev/guide/\346\246\202\350\277\260.md" "b/zh-cn/device-dev/guide/\346\246\202\350\277\260.md" index 875da92ed1dd39a87faab8a658718423a7ce9d1f..e3d5da250e043ac86136b0d8ad5a220f946fefc2 100755 --- "a/zh-cn/device-dev/guide/\346\246\202\350\277\260.md" +++ "b/zh-cn/device-dev/guide/\346\246\202\350\277\260.md" @@ -1,4 +1,10 @@ -# 概述 +# 概述 -OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力,包含I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。本文介绍如何通过调用OpenHarmony的NDK接口,实现对GPIO控制,达到LED闪烁的效果。其他的IOT外设控制,开发者可根据API指导文档完成,此处不逐一介绍。 +本文档将介绍如何基于IoT Camera开发板,利用开发套件中自带的摄像头,完成拍照、录像功能。 + +开发者可通过执行示例应用,对开发板的外设控制有了更深入了解后,可使用开发板完成摄像头等设备。 + +若开发者想先查看示例效果,请进入[应用实例](应用实例.md)。如需自定义应用行为,可参考下节“示例开发”对示例代码进行修改。 + +相机开发基本概念可参考:[相机开发概述](../subsystems/相机开发概述.md)。 diff --git "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/zh-cn/device-dev/guide/\347\216\257\345\242\203\345\207\206\345\244\207.md" deleted file mode 100644 index c6ae1a18427ed3bdec92f853ac9d49905d4901a5..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\345\207\206\345\244\207.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 环境准备 - -环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/标准系统入门.md)。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 - diff --git "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\346\220\255\345\273\272.md" "b/zh-cn/device-dev/guide/\347\216\257\345\242\203\346\220\255\345\273\272.md" deleted file mode 100644 index 381ddaa88c0c7136b378691ceae0f1594d54aec7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\216\257\345\242\203\346\220\255\345\273\272.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 环境搭建 - -环境准备具体操作请参考[标准系统基础环境搭建](../quick-start/标准系统入门.md)。 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本示例针对OpenHarmony轻量系统、小型系统、标准系统都适用,本文以标准系统为例。其他系统的开发者可参考对应系统的指导文档进行环境搭建。 - diff --git "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214-9.md" "b/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214-9.md" deleted file mode 100644 index 30bb3b0801d1ea859f8e3a64d956fbeb91f0e381..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214-9.md" +++ /dev/null @@ -1,35 +0,0 @@ -# 真机运行 - -应用签名打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony系统烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[标准系统Hi3516快速入门](../quick-start/标准系统入门.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载应用。 - -1. 从开发者工具代码仓路径中获取hdc客户端。 - - ``` - developtools/hdc_standard/prebuilt/windows/hdc_std.exe - ``` - - 修改名称为hdc.exe,并将工具路径加入系统环境path变量中。 - -2. 启动cmd命令窗口,执行以下命令,推送hap应用包到设备目录下并安装。 - - ``` - hdc smode - hdc target mount - hdc file send clock.hap /data/clock.hap - hdc shell chmod 666 /data/clock.hap - hdc shell bm install -p /data/clock.hap - ``` - -3. 启动应用。执行以下命令,其中ohos.samples.clock为应用包名,MainAbility为应用启动的Ability。 - - ``` - hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock - ``` - -4. 卸载应用(可选)。执行以下命令,其中ohos.samples.clock为应用包名。 - - ``` - hdc shell bm uninstall -n ohos.samples.clock - ``` - - diff --git "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214.md" "b/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214.md" index 973019fcce8af2d9c0fde13a096d5c4067df3e6d..660830bd6651d65d45402eab94c88a3bb3750e02 100755 --- "a/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214.md" +++ "b/zh-cn/device-dev/guide/\347\234\237\346\234\272\350\277\220\350\241\214.md" @@ -1,6 +1,6 @@ # 真机运行 -应用编译打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/tool_install-0000001050164976),然后将OpenHarmony烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[Hi3516快速入门](../quick-start/Hi3516开发板介绍.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载三方应用。 +应用编译打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[Hi3516快速入门](../quick-start/Hi3516开发板介绍.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载三方应用。 1. 将IDE编译的未签名应用安装包和安装工具(镜像文件生成目录中的dev\_tools)放在sdcard中,将sdcard插入开发板卡槽。 2. 应用安装默认要校验签名,需要执行以下命令,关闭签名校验。 diff --git "a/zh-cn/device-dev/guide/\347\241\254\344\273\266\350\265\204\346\272\220\344\273\213\347\273\215.md" "b/zh-cn/device-dev/guide/\347\241\254\344\273\266\350\265\204\346\272\220\344\273\213\347\273\215.md" deleted file mode 100644 index 18b33bd5af0271b644fe30b8585e3f6be22a3b55..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\241\254\344\273\266\350\265\204\346\272\220\344\273\213\347\273\215.md" +++ /dev/null @@ -1,6 +0,0 @@ -# 硬件资源介绍 - -Hi3516DV300开发板套件所提供的触摸屏器件IC为GT911,该器件采用标准I2C与主机通信,通过6pin软排线与主板连接。6pin分布以及实物连接图如下图所示: - -![](figures/绘图1.png) - diff --git "a/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-2.md" "b/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-1.md" old mode 100755 new mode 100644 similarity index 51% rename from "zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-2.md" rename to "zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-1.md" index eb01bec406aeb05019daeeb14148eaf702bfc598..e2e6a3452de769747e08e6a384e7aaac0d48b046 --- "a/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-2.md" +++ "b/zh-cn/device-dev/guide/\347\244\272\344\276\213\345\274\200\345\217\221-1.md" @@ -1,8 +1,8 @@ # 示例开发 -- **[拍照开发指导](拍照开发指导-3.md)** +- **[拍照开发指导](拍照开发指导-2.md)** -- **[录像开发指导](录像开发指导-4.md)** +- **[录像开发指导](录像开发指导-3.md)** - **[预览开发指导](预览开发指导.md)** diff --git "a/zh-cn/device-dev/guide/\347\247\201\346\234\211\351\205\215\347\275\256\344\277\241\346\201\257\350\247\243\346\236\220.md" "b/zh-cn/device-dev/guide/\347\247\201\346\234\211\351\205\215\347\275\256\344\277\241\346\201\257\350\247\243\346\236\220.md" deleted file mode 100644 index a472a6dfdfba6d50c291b37dcc1718f56dabaaed..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\247\201\346\234\211\351\205\215\347\275\256\344\277\241\346\201\257\350\247\243\346\236\220.md" +++ /dev/null @@ -1,17 +0,0 @@ -# 私有配置信息解析 - -示例代码路径:./drivers/framework/model/input/driver/input\_config\_parser.c - -根据OSAL提供的配置解析函数,可以将hcs文件中各字段含义进行解析,具体请参考input\_config\_parser.c中各函数的实现。如果提供的模板不能满足需求,在hcs文件中添加相应信息后,需要根据添加的字段开发相应的解析函数。 - -``` -static int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode, BoardAttrCfg *attr) -{ - int32_t ret; - ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0); // 获取inputType字段信息,保存在BoardAttrCfg结构体中 - CHECK_PARSER_RET(ret, "GetUint8"); - ... - return HDF_SUCCESS; -} -``` - diff --git "a/zh-cn/device-dev/guide/\347\255\276\345\220\215\346\211\223\345\214\205.md" "b/zh-cn/device-dev/guide/\347\255\276\345\220\215\346\211\223\345\214\205.md" deleted file mode 100644 index a6fd6f965525ad87ae4b3be7b1987a97ddc0fa39..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\255\276\345\220\215\346\211\223\345\214\205.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 签名打包 - -代码编写完成后,在真机设备上运行应用,需要先对应用进行签名,然后再进行打包,具体操作请参考[签名打包指导](../../application-dev/quick-start/配置OpenHarmony应用签名信息.md)。 - diff --git "a/zh-cn/device-dev/guide/\347\256\241\347\220\206\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" "b/zh-cn/device-dev/guide/\347\256\241\347\220\206\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" deleted file mode 100644 index 73b05bf0b039741952505f3c30c5440a28c1e25b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\256\241\347\220\206\351\251\261\345\212\250\345\261\202\345\210\235\345\247\213\345\214\226\345\217\212\346\263\250\345\206\214\351\251\261\345\212\250\350\207\263HDF\346\241\206\346\236\266.md" +++ /dev/null @@ -1,22 +0,0 @@ -# 管理驱动层初始化及注册驱动至HDF框架 - -示例代码路径:./drivers/framework/model/input/driver/hdf\_input\_device\_manager.c - -``` -static int32_t HdfInputManagerInit(struct HdfDeviceObject *device) -{ - /* 分配内存给manager,manager中将存放所有input设备 */ - g_inputManager = InputManagerInstance(); - ... -} -struct HdfDriverEntry g_hdfInputEntry = { - .moduleVersion = 1, - .moduleName = "HDF_INPUT_MANAGER", - .Bind = HdfInputManagerBind, - .Init = HdfInputManagerInit, - .Release = HdfInputManagerRelease, -}; - -HDF_INIT(g_hdfInputEntry); //驱动注册入口 -``` - diff --git "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225-13.md" "b/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225-13.md" deleted file mode 100644 index 587404009f050d03eeb8b95d221ea1beb2f3e062..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225-13.md" +++ /dev/null @@ -1,17 +0,0 @@ -# 编译及烧录 - -1. 编辑Makefile文件,添加本示例中的内容: - - 文件路径:./drivers/adapter/khdf/linux/model/input/Makefile - - 添加内容如下: - - ``` - obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \ - $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o - ``` - - 其中touch\_gt911.o为本示例中追加的内容。 - -2. 具体编译及烧录操作请参考[标准系统快速入门编译及烧录章节](../quick-start/标准系统入门.md)。 - diff --git "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225.md" "b/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225.md" deleted file mode 100644 index 92d839390d5dcacac6fdc98cb576d3e6312a0c69..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\347\274\226\350\257\221\345\217\212\347\203\247\345\275\225.md" +++ /dev/null @@ -1,20 +0,0 @@ -# 编译及烧录 - -1. 编辑Makefile,添加源文件: - - ``` - include drivers/hdf/khdf/platform/platform.mk - - obj-y += $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_core.o \ - $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/i2c_if.o \ - ./i2c_adapter.o \ - ./i2c_sample.o - ``` - - "./i2c\_sample.o"为本示例中在Makefile中追加的内容。 - -2. 编译及烧录。 - - 具体操作请参考[标准系统快速入门编译及烧录章节](../quick-start/标准系统入门.md)。 - - diff --git "a/zh-cn/device-dev/guide/\350\247\206\350\247\211\345\272\224\347\224\250\345\274\200\345\217\221.md" "b/zh-cn/device-dev/guide/\350\247\206\350\247\211\345\272\224\347\224\250\345\274\200\345\217\221.md" index b4a8975ab2b1883c7e69e324500c9fc516bb9b7e..dd98c6ebbc448ca3b80c308d7230c7c3fd94dbad 100755 --- "a/zh-cn/device-dev/guide/\350\247\206\350\247\211\345\272\224\347\224\250\345\274\200\345\217\221.md" +++ "b/zh-cn/device-dev/guide/\350\247\206\350\247\211\345\272\224\347\224\250\345\274\200\345\217\221.md" @@ -1,6 +1,6 @@ # 视觉应用开发 -- **[概述](概述-6.md)** +- **[概述](概述-5.md)** - **[开发准备](开发准备.md)** diff --git "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\346\211\223\345\214\205.md" "b/zh-cn/device-dev/guide/\350\260\203\350\257\225\346\211\223\345\214\205.md" index 5015bd5755d4a5750aeeac6e699c6d8070dc9827..30505bcb3ebf9e4daf0bb1d6adb2b544f19209be 100755 --- "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\346\211\223\345\214\205.md" +++ "b/zh-cn/device-dev/guide/\350\260\203\350\257\225\346\211\223\345\214\205.md" @@ -1,4 +1,4 @@ # 调试打包 -代码编写完成后,可以进行调试和打包;应用调试及打包方法可以参考[《DevEco Studio使用指南》](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)的[应用调测](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/debug_overview-0000001053822404)和[编译构建](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201)章节。IPCamera应用暂时不支持签名模式,所以需要将应用发布为未签名的应用安装包。 +代码编写完成后,可以进行调试和打包;应用调试及打包方法可以参考[《DevEco Studio使用指南》](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)的[应用调测](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404)和[编译构建](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201)章节。IPCamera应用暂时不支持签名模式,所以需要将应用发布为未签名的应用安装包。 diff --git "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\351\252\214\350\257\201.md" "b/zh-cn/device-dev/guide/\350\260\203\350\257\225\351\252\214\350\257\201.md" deleted file mode 100644 index f339b20a630cc498481d71394a3f46225e537dfa..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\350\260\203\350\257\225\351\252\214\350\257\201.md" +++ /dev/null @@ -1,5 +0,0 @@ -# 调试验证 - -- **[开机日志分析](开机日志分析.md)** - - diff --git "a/zh-cn/device-dev/guide/\351\200\202\351\205\215\345\231\250\344\273\266\347\247\201\346\234\211\351\251\261\345\212\250.md" "b/zh-cn/device-dev/guide/\351\200\202\351\205\215\345\231\250\344\273\266\347\247\201\346\234\211\351\251\261\345\212\250.md" deleted file mode 100644 index b719de9bacbb19722563054b8aafa6584550bf1c..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\200\202\351\205\215\345\231\250\344\273\266\347\247\201\346\234\211\351\251\261\345\212\250.md" +++ /dev/null @@ -1,99 +0,0 @@ -# 适配器件私有驱动 - -Input模型由三层驱动组成,开发者适配一款全新触摸屏驱动只需要适配器件驱动层即可,重点实现差异化接口,本小节以代码示例的形式展示开发者需要重点完成的工作。 - -1. 触摸屏器件差异化接口适配 - - 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c - - ``` - static struct TouchChipOps g_gt911ChipOps = { // 器件IC接口 - .Init = ChipInit, // 初始化 - .Detect = ChipDetect, // 器件检测 - .Resume = ChipResume, // 唤醒 - .Suspend = ChipSuspend, // 休眠 - .DataHandle = ChipDataHandle, // 器件数据读取 - .UpdateFirmware = UpdateFirmware, // 固件升级 - }; - - /* 不同触摸屏厂家使用的IC不一样,对应的寄存器操作也不一样,因此器件驱动层代码重点适配差异化接口部分,如下示例代码展示了GT911的数据解析*/ - - static int32_t ChipDataHandle(ChipDevice *device) - { - ... - /* GT911获取坐标之前需先读取状态寄存器 */ - reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK; - ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1); - if (ret < 0 || touchStatus == GT_EVENT_INVALID) { - return HDF_FAILURE; - } - ... - /* 根据状态寄存器的值读取数据寄存器数据 */ - reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; - reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK; - pointNum = touchStatus & GT_FINGER_NUM_MASK; - if (pointNum == 0 || pointNum > MAX_SUPPORT_POINT) { - HDF_LOGE("%s: pointNum is invalid, %u", __func__, pointNum); - (void)ChipCleanBuffer(i2cClient); - OsalMutexUnlock(&device->driver->mutex); - return HDF_FAILURE; - } - frame->realPointNum = pointNum; - frame->definedEvent = TOUCH_DOWN; - (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum); - /* 对获取的数据进行解析 */ - ParsePointData(device, frame, buf, pointNum); - ... - } - static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum) - { - ... - /* 每个坐标值由两个字节组成,对获取的单字节数据进行拼接得到最终的坐标值 */ - for (i = 0; i < pointNum; i++) { - frame->fingers[i].trackId = buf[GT_POINT_SIZE * i + GT_TRACK_ID]; - frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) | - ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET); - /* 对解析出来的坐标值进行打印 */ - HDF_LOGD("%s: x = %d, y = %d", __func__, frame->fingers[i].x, frame->fingers[i].y); - } - } - ``` - -2. 器件层驱动初始化及注册驱动至HDF框架 - - 示例代码路径:./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c - - ``` - static int32_t HdfGoodixChipInit(struct HdfDeviceObject *device) - { - ... - /* 器件配置结构体内存申请、配置信息解析及挂载 */ - chipCfg = ChipConfigInstance(device); - ... - /* 器件实例化 */ - chipDev = ChipDeviceInstance(); - ... - /* 器件信息挂载及器件私有操作挂载 */ - chipDev->chipCfg = chipCfg; - chipDev->ops = &g_gt911ChipOps; - ... - /* 注册器件驱动至平台驱动 */ - RegisterChipDevice(chipDev); - ... - } - struct HdfDriverEntry g_touchGoodixChipEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH_GT911", // 该moduleName与device_info.hcs文件中器件驱动层的moduleName信息相匹配 - .Init = HdfGoodixChipInit, // 器件驱动初始化函数 - }; - HDF_INIT(g_touchGoodixChipEntry); // 注册器件驱动至HDF框架 - ``` - - 器件私有驱动层主要实现了各器件厂商差异较大的部分,如器件休眠唤醒、数据解析以及固件升级等。 - - 至此,基于HDF框架及Input模型的触摸屏驱动适配完成。 - - diff --git "a/zh-cn/device-dev/guide/\351\205\215\347\275\256Touchscreen\345\231\250\344\273\266\344\277\241\346\201\257.md" "b/zh-cn/device-dev/guide/\351\205\215\347\275\256Touchscreen\345\231\250\344\273\266\344\277\241\346\201\257.md" deleted file mode 100644 index a56381458292b83a64324abba06a4a7301d7a25f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\205\215\347\275\256Touchscreen\345\231\250\344\273\266\344\277\241\346\201\257.md" +++ /dev/null @@ -1,98 +0,0 @@ -# 配置Touchscreen器件信息 - -配置文件路径:./drivers/adapter/khdf/linux/hcs/input/input\_config.hcs - -input\_config.hcs中的信息由驱动代码进行读取解析,主要由公共驱动层的私有配置信息及器件驱动层的私有配置信息组成。文件中的配置包含板级硬件信息及器件私有配置信息,实际业务开发时,可根据具体需求增删及修改对应内容。 - -``` -root { - input_config { - touchConfig { - touch0 { // 第一款触摸屏 - boardConfig { // 板级硬件信息 - match_attr = "touch_device1"; // 与设备描述配置信息中公共驱动层私有配置信息的“match_attr”字段保持一致 - inputAttr { - /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */ - inputType = 0; // input类型为touch - solutionX = 480; // 分辨率X信息 - solutionY = 960; // 分辨率Y信息 - devName = "main_touch"; // 设备名称 - } - busConfig { - /* 0:i2c 1:spi */ - busType = 0; // GT911采用I2C通信 - busNum = 6; // 与主机芯片第6路I2C通信 - clkGpio = 86; // 主机芯片SCL管脚 - dataGpio = 87; // 主机芯片SDA管脚 - i2cClkIomux = [0x114f0048, 0x403]; // SCL管脚配置信息 - i2cDataIomux = [0x114f004c, 0x403]; // SDA管脚配置信息 - } - pinConfig { - rstGpio = 3; // 复位管脚连接主机芯片的3号管脚 - intGpio = 4; // 中断管脚连接主机芯片的4号管脚 - rstRegCfg = [0x112f0094, 0x400]; // 复位管脚配置信息 - intRegCfg = [0x112f0098, 0x400]; // 中断管脚配置信息 - } - powerConfig { - /* 0:unused 1:ldo 2:gpio 3:pmic */ - vccType = 2; // GPIO供电 - vccNum = 20; // gpio20 - vccValue = 1800; // 电压幅值为1800mV - vciType = 1; // LDO供电 - vciNum = 12; // ldo12 - vciValue = 3300; // 电压幅值为3300mV - } - - featureConfig { - capacitanceTest = 0; // 容值测试 - gestureMode = 0; // 手势模式 - gloverMode = 0; // 手套模式 - coverMode = 0; // 皮套模式 - chargerMode = 0; // 充电模式 - knuckleMode = 0; // 指关节模式 - } - } - chipConfig { // 器件私有信息配置 - template touchChip { // 模板 - match_attr = ""; - chipName = "gt911"; // 触摸屏IC型号 - vendorName = "zsj"; // 供应商 - chipInfo = "AAAA11222"; // 1~4字符代表产品名,5~6字符代表IC型号,7~9字符代表模型型号 - busType = 0; // 0代表I2C,1代表SPI - deviceAddr = 0x5D; // 器件IC通信地址 - irqFlag = 2; // 1代表上升沿触发,2代表下降沿触发,4代表高电平触发,8代表低电平触发 - maxSpeed = 400; // 最大通信速率为400Hz - chipVersion = 0; // 触摸屏IC版本号 - powerSequence { - /* 上电时序的配置含义说明: - [类型, 状态, 方向 , 延时] - 0代表空,1代表vcc电源(1.8V),2代表VCI电源(3.3V),3代表复位管脚,4代表中断管脚 - 0代表下电或拉低,1代表上电或拉高,2代表无操作 - 0代表输入方向,1代表输出方向,2代表无操作 - 代表延时多少毫秒, 例如20代表延时20ms - */ - powerOnSeq = [4, 0, 1, 0, // 中断管脚配置为输出,且进行拉低 - 3, 0, 1, 10, // 复位管脚配置为输出,且进行拉低,延时10ms - 3, 1, 2, 60, // 复位管脚无操作,且进行拉高,延时60ms - 4, 2, 0, 0]; // 中断管脚配置为输入 - suspendSeq = [3, 0, 2, 10]; // 复位管脚无操作,且进行拉低,延时10ms - resumeSeq = [3, 1, 2, 10]; // 复位管脚无操作,且进行拉高,延时10ms - powerOffSeq = [3, 0, 2, 10, // 复位管脚无操作,且进行拉低,延时10ms - 1, 0, 2, 20]; // 电源正极管脚无操作,且进行拉低,延时20ms - } - } - - chip0 :: touchChip { - match_attr = "zsj_gt911_5p5"; // 与设备描述配置信息中器件私有配置信息的“match_attr”字段保持一致 - chipInfo = "ZIDN45100"; // 产品名+模组编号+芯片编号的组合信息 用于给用户态区分当前器件 - chipVersion = 0; // IC型号的版本 - } - } - } - } - } -} -``` - -示例中“touchConfig”包含了“touch0”,"touch0"包含了“boardConfig”与“chipConfig”;“boardConfig”字段包含了Hi3516DV300板级硬件信息,“chipConfig”包含了触摸屏器件的私有信息,如果需要替换触摸屏器件,重新配置“chipConfig”对应的字段信息即可。同时产品可以配置多款触摸屏,示例中用“touch0”代表了套件中默认的触摸屏的硬件接口以及器件的配置信息,如产品需要配置副屏,可在与“touch0”并列的位置配置“touch1”的信息。 - diff --git "a/zh-cn/device-dev/guide/\351\205\215\347\275\256\350\256\276\345\244\207\346\217\217\350\277\260\344\277\241\346\201\257.md" "b/zh-cn/device-dev/guide/\351\205\215\347\275\256\350\256\276\345\244\207\346\217\217\350\277\260\344\277\241\346\201\257.md" deleted file mode 100644 index 4183826a4fa9d0afa0ce01ff2ead4d3c1a0dac70..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\205\215\347\275\256\350\256\276\345\244\207\346\217\217\350\277\260\344\277\241\346\201\257.md" +++ /dev/null @@ -1,64 +0,0 @@ -# 配置设备描述信息 - -配置文件路径:./drivers/adapter/khdf/linux/hcs/device\_info/device\_info.hcs - -device\_info.hcs中的信息主要提供给HDF框架使用,包含了Input模型各层驱动注册到HDF框架所必需的信息,开发者无特殊场景需求无需改动。各驱动层私有配置信息通过“deviceMatchAttr”字段与input\_config.hcs中的“match\_attr”相关内容进行匹配。 - -配置文件中与input模块相关的内容如下所示,相关字段的详细含义可以参考《[驱动配置](../driver/驱动开发.md)》: - -``` -input :: host { - hostName = "input_host"; - priority = 100; - device_input_manager :: device { // Input管理层设备描述信息 - device0 :: deviceNode { - policy = 2; // 向内核用户态均发布服务 - priority = 100; // input管理层驱动优先级默认为100 - preload = 0; // 加载该驱动 - permission = 0660; // 驱动创建设备节点权限 - moduleName = "HDF_INPUT_MANAGER"; // 与驱动入口的moduleName匹配 - serviceName = "hdf_input_host"; // HDF框架生成的节点名 - deviceMatchAttr = ""; // manager目前不需要私有配置,因此为空 - } - } - - device_hdf_touch :: device { // Input公共驱动层设备描述信息 - device0 :: deviceNode { - policy = 2; // 向内核用户态均发布服务 - priority = 120; // input公共驱动优先级默认为120 - preload = 0; // 加载该驱动 - permission = 0660; // 驱动创建设备节点权限 - moduleName = "HDF_TOUCH"; // 与驱动入口的moduleName匹配 - serviceName = "hdf_input_event1"; // HDF框架生成的节点名 - deviceMatchAttr = "touch_device1"; // 与私有配置信息中的“match_attr”字段保持一致 - } - } - - device_touch_chip :: device { // Input器件驱动层信息 - device0 :: deviceNode { - policy = 0; // 向内核用户态均不发布服务 - priority = 130; // input器件驱动优先级默认为130 - preload = 0; // 加载该驱动 - permission = 0660; // 驱动创建设备节点权限 - moduleName = "HDF_TOUCH_GT911"; // 与驱动入口的moduleName匹配 - serviceName = "hdf_touch_gt911_service";// HDF框架生成的节点名 - deviceMatchAttr = "zsj_gt911_5p5"; //与私有配置信息中的“match_attr”字段保持一致 - } - } - } -``` - -该配置文件中需要重点关注的字段有: - -“priority”决定驱动加载顺序; - -“preload”决定驱动是否加载; - -“moduleName ”需要与驱动注册入口处的“moduleName ”字段保持一致; - -“serviceName ”HDF框架依据该字段创建节点名; - -“deviceMatchAttr ”需要与私有配置信息中的“match\_attr”字段保持一致。 - -通过配置设备描述信息,使得HDF框架通过moduleName与注册至驱动入口的代码相匹配,保证了驱动的正常加载,通过priority字段保证了各驱动的加载顺序。 - diff --git "a/zh-cn/device-dev/guide/\351\252\214\350\257\201.md" "b/zh-cn/device-dev/guide/\351\252\214\350\257\201.md" deleted file mode 100755 index e9be36acdfb301de6902f16081f4e792cdebe00d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/guide/\351\252\214\350\257\201.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 验证 - -编译过程请参考《[Hi3861快速入门-源码编译](../quick-start/运行Hello-World.md)》,烧录过程请参考《[Hi3861快速入门-镜像烧录](../quick-start/WLAN联网.md)》。 - -完成以上两步后,按下RST键复位模组,可发现LED在周期性闪烁,与预期相符,验证完毕。 - -**图 1** LED闪烁图 -![](figures/LED闪烁图.gif "LED闪烁图") - diff --git a/zh-cn/device-dev/kernel/FAT-20.md b/zh-cn/device-dev/kernel/FAT-21.md similarity index 100% rename from zh-cn/device-dev/kernel/FAT-20.md rename to zh-cn/device-dev/kernel/FAT-21.md diff --git a/zh-cn/device-dev/kernel/LittleFS.md b/zh-cn/device-dev/kernel/LittleFS.md index 1f8ad2cec85fe0c0b5c45076a705e5f12045fa8c..9b852560fb4cae38a2231c1867263b06c082d74e 100644 --- a/zh-cn/device-dev/kernel/LittleFS.md +++ b/zh-cn/device-dev/kernel/LittleFS.md @@ -1,7 +1,7 @@ # LittleFS -- **[基本概念](基本概念-21.md)** +- **[基本概念](基本概念-22.md)** -- **[开发指导](开发指导-22.md)** +- **[开发指导](开发指导-23.md)** diff --git a/zh-cn/device-dev/kernel/Readme-CN.md b/zh-cn/device-dev/kernel/Readme-CN.md index 8b5a59ad1b9f2ddb7beb2c0424b72dd5bc53d432..83fb18bf9460f021e77eca3345e129d00d0d81b5 100755 --- a/zh-cn/device-dev/kernel/Readme-CN.md +++ b/zh-cn/device-dev/kernel/Readme-CN.md @@ -1,7 +1,7 @@ # 内核使用指南 - [轻量和小型系统内核](轻量和小型系统内核.md) - - [轻量系统内核](轻量系统内核.md) + - [小型系统内核](小型系统内核.md) - [基础内核](基础内核.md) - [进程](进程.md) - [线程](线程.md) @@ -87,7 +87,7 @@ - [魔法键使用方法](魔法键使用方法.md) - [用户态异常信息说明](用户态异常信息说明.md) - - [小型系统内核](小型系统内核.md) + - [轻量系统内核](轻量系统内核.md) - [认识LiteOS-M内核](认识LiteOS-M内核.md) - [快速入门](快速入门.md) - [基础内核](基础内核-1.md) @@ -131,15 +131,15 @@ - [扩展组件](扩展组件.md) - [C++支持](C++支持.md) - - [CPUP](CPUP.md) - - [基本概念](基本概念-17.md) - - [开发指导](开发指导-18.md) + - [cpup](cpup-17.md) + - [基本概念](基本概念-18.md) + - [开发指导](开发指导-19.md) - - [文件系统](文件系统-19.md) - - [FAT](FAT-20.md) + - [文件系统](文件系统-20.md) + - [FAT](FAT-21.md) - [LittleFS](LittleFS.md) - - [基本概念](基本概念-21.md) - - [开发指导](开发指导-22.md) + - [基本概念](基本概念-22.md) + - [开发指导](开发指导-23.md) - [内核调测](内核调测.md) - [内存调测](内存调测.md) diff --git a/zh-cn/device-dev/kernel/cpup-17.md b/zh-cn/device-dev/kernel/cpup-17.md new file mode 100644 index 0000000000000000000000000000000000000000..e545d3f8430662299b3bf147bf012326007b4bf7 --- /dev/null +++ b/zh-cn/device-dev/kernel/cpup-17.md @@ -0,0 +1,7 @@ +# cpup + +- **[基本概念](基本概念-18.md)** + +- **[开发指导](开发指导-19.md)** + + diff --git "a/zh-cn/device-dev/kernel/\345\212\250\346\200\201\345\206\205\345\255\230.md" "b/zh-cn/device-dev/kernel/\345\212\250\346\200\201\345\206\205\345\255\230.md" index 31361e2a8b00a51d535d7243d5b832399a5e1355..05922df9f795ac26bfa94d71858bab47dda9a8de 100644 --- "a/zh-cn/device-dev/kernel/\345\212\250\346\200\201\345\206\205\345\255\230.md" +++ "b/zh-cn/device-dev/kernel/\345\212\250\346\200\201\345\206\205\345\255\230.md" @@ -49,7 +49,7 @@ OpenHarmony LiteOS-M动态内存在TLSF算法的基础上,对区间的划分 OpenHarmony LiteOS-M的动态内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 -**表 1** 静态内存模块接口 +**表 1** 动态内存模块接口

功能分类

diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-17.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-18.md" similarity index 100% rename from "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-17.md" rename to "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-18.md" diff --git "a/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-21.md" "b/zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-22.md" similarity index 100% rename from "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-21.md" rename to "zh-cn/device-dev/kernel/\345\237\272\346\234\254\346\246\202\345\277\265-22.md" diff --git "a/zh-cn/device-dev/kernel/\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" index d24843996311d64f63f2873e2f53b784ee55dd73..631bf65b2fe8ca53c7114ac1767c6f64198f4a93 100644 --- "a/zh-cn/device-dev/kernel/\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" +++ "b/zh-cn/device-dev/kernel/\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" @@ -1,15 +1,11 @@ -# 小型系统内核 +# 小型系统内核 -- **[认识LiteOS-M内核](认识LiteOS-M内核.md)** +- **[基础内核](基础内核.md)** -- **[快速入门](快速入门.md)** +- **[文件系统](文件系统.md)** -- **[基础内核](基础内核-1.md)** +- **[标准库](标准库.md)** -- **[扩展组件](扩展组件.md)** - -- **[内核调测](内核调测.md)** - -- **[附录](附录.md)** +- **[调测](调测.md)** diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-18.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-19.md" similarity index 100% rename from "zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-18.md" rename to "zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-19.md" diff --git "a/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-22.md" "b/zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-23.md" similarity index 100% rename from "zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-22.md" rename to "zh-cn/device-dev/kernel/\345\274\200\345\217\221\346\214\207\345\257\274-23.md" diff --git "a/zh-cn/device-dev/kernel/\346\211\251\345\261\225\347\273\204\344\273\266.md" "b/zh-cn/device-dev/kernel/\346\211\251\345\261\225\347\273\204\344\273\266.md" index dcfc826616e437211372c13a415dcc6b3657ae63..83a675d075500f0797e7bdec25beccd12de5f30a 100644 --- "a/zh-cn/device-dev/kernel/\346\211\251\345\261\225\347\273\204\344\273\266.md" +++ "b/zh-cn/device-dev/kernel/\346\211\251\345\261\225\347\273\204\344\273\266.md" @@ -2,8 +2,8 @@ - **[C++支持](C++支持.md)** -- **[CPUP](CPUP.md)** +- **[cpup](cpup-17.md)** -- **[文件系统](文件系统-19.md)** +- **[文件系统](文件系统-20.md)** diff --git "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-19.md" "b/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-20.md" similarity index 99% rename from "zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-19.md" rename to "zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-20.md" index ba10ab39c51ce9917ccc7a664e4b13c3e7842824..2d702a8406ae2330df855d7269920f6e28abad01 100644 --- "a/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-19.md" +++ "b/zh-cn/device-dev/kernel/\346\226\207\344\273\266\347\263\273\347\273\237-20.md" @@ -197,7 +197,7 @@
-- **[FAT](FAT-20.md)** +- **[FAT](FAT-21.md)** - **[LittleFS](LittleFS.md)** diff --git "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" index 0ae605881ae93ccbe37bda0971479cb69a6be0e8..5f5cb86ffa53972e34169fb3563bce199175a9c1 100644 --- "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" +++ "b/zh-cn/device-dev/kernel/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\345\206\205\346\240\270.md" @@ -1,7 +1,7 @@ # 轻量和小型系统内核 -- **[轻量系统内核](轻量系统内核.md)** - - **[小型系统内核](小型系统内核.md)** +- **[轻量系统内核](轻量系统内核.md)** + diff --git "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\347\263\273\347\273\237\345\206\205\346\240\270.md" "b/zh-cn/device-dev/kernel/\350\275\273\351\207\217\347\263\273\347\273\237\345\206\205\346\240\270.md" index 290c4915bf94adb34bc2804d40268adcfe38fd87..c303a4991e698a32053116fb98f805305a13a847 100644 --- "a/zh-cn/device-dev/kernel/\350\275\273\351\207\217\347\263\273\347\273\237\345\206\205\346\240\270.md" +++ "b/zh-cn/device-dev/kernel/\350\275\273\351\207\217\347\263\273\347\273\237\345\206\205\346\240\270.md" @@ -1,11 +1,15 @@ -# 轻量系统内核 +# 轻量系统内核 -- **[基础内核](基础内核.md)** +- **[认识LiteOS-M内核](认识LiteOS-M内核.md)** -- **[文件系统](文件系统.md)** +- **[快速入门](快速入门.md)** -- **[标准库](标准库.md)** +- **[基础内核](基础内核-1.md)** -- **[调测](调测.md)** +- **[扩展组件](扩展组件.md)** + +- **[内核调测](内核调测.md)** + +- **[附录](附录.md)** diff --git "a/zh-cn/device-dev/porting/CMake\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" "b/zh-cn/device-dev/porting/CMake\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" index bb7404eca3e670115c48f40f4f219347162c5064..7fac8fff75034489bff779d9ee5cf76297335f3b 100755 --- "a/zh-cn/device-dev/porting/CMake\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" +++ "b/zh-cn/device-dev/porting/CMake\346\226\271\345\274\217\347\273\204\347\273\207\347\274\226\350\257\221\347\232\204\345\272\223\347\247\273\346\244\215.md" @@ -227,7 +227,7 @@ CMake方式可通过指定工具链进行交叉编译,修改并编译该库, 1. 搭建OpenHarmony环境 - 以hi3518ev300为例,编译出OpenHarmony镜像,烧写到开发板,参考[开发Hi3518第一个示例程序](https://device.harmonyos.com/cn/docs/start/introduce/oem_camera_start_example-0000001051610926)。 + 以hi3518ev300为例,编译出OpenHarmony镜像,烧写到开发板,参考[开发Hi3518第一个示例程序](https://device.harmonyos.com/cn/docs/start/introduce/oem_development_ex_3518-0000001105528572)。 进入系统如下所示: @@ -306,7 +306,7 @@ CMake方式可通过指定工具链进行交叉编译,修改并编译该库,

将三方库加入工程的gn适配文件

-

openHarmony/third_party/double-conversion/build_thirdpaty.py

+

openHarmony/third_party/double-conversion/build_thirdparty.py

GN调用shell命令脚本文件,由上面GN文件将相关命令传入,实现GN转CMake

diff --git "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277.md" index 28c01f99cccb6b99b4d9673b691af7d1da0bc0b5..1a6f14d262b1474576a3974dff7c57b205f48aaf 100755 --- "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277.md" +++ "b/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277.md" @@ -1,4 +1,4 @@ -# Hi3516开发板 +# Hi3516开发板 - **[安装开发板环境](安装开发板环境-2.md)** diff --git "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" index 3c6ebbc875e4460fe0fb51105aae2fcd5571928a..3e24c43eb01be574c4a48c1d9a6e10d82beeca4e 100755 --- "a/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" +++ "b/zh-cn/device-dev/quick-start/Hi3516\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" @@ -1,4 +1,4 @@ -# Hi3516开发板介绍 +# Hi3516开发板介绍 - [简介](#section26131214194212) - [开发板规格](#section15192203316533) diff --git "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277.md" index c7a3daa41bb69758c22f0820179b0bccbc0eeef3..61807ea64d579d2364ff6c327864f20d8d6aaa6a 100755 --- "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277.md" +++ "b/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277.md" @@ -1,4 +1,4 @@ -# Hi3518开发板 +# Hi3518开发板 - **[安装开发板环境](安装开发板环境-4.md)** diff --git "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" index d072777d4e1d56f4f8c3060e0edcb587f536917d..1f77aeac075607531fb98955ef218dfd00e3c6ae 100755 --- "a/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" +++ "b/zh-cn/device-dev/quick-start/Hi3518\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" @@ -1,4 +1,4 @@ -# Hi3518开发板介绍 +# Hi3518开发板介绍 - [简介](#section14815247616) - [开发板规格](#section765112478446) diff --git "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277.md" index 5fa74713ecf8339f75070e2e112e47c7ae0d8d02..f6c5f5833f16ede72614678ebc0483389d9120f8 100755 --- "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277.md" +++ "b/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277.md" @@ -1,4 +1,4 @@ -# Hi3861开发板 +# Hi3861开发板 - **[安装开发板环境](安装开发板环境.md)** diff --git "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" index 8eb13ecf8baf6e8918989e2755517997bc81f4bb..ac6a21df22f9865ab77ad461ab1805404c595d0b 100755 --- "a/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" +++ "b/zh-cn/device-dev/quick-start/Hi3861\345\274\200\345\217\221\346\235\277\344\273\213\347\273\215.md" @@ -1,4 +1,4 @@ -# Hi3861开发板介绍 +# Hi3861开发板介绍 - [简介](#section19352114194115) - [资源和约束](#section82610215014) @@ -19,7 +19,7 @@ Hi3861 WLAN模组是一片大约2cm\*5cm大小的开发板,是一款高度集 **图 2** Hi3861底板外观图 -![](figures/zh-cn_image_0000001119945810.png) +![](figures/zh-cn_image_0000001174350615.png) - RF电路包括功率放大器PA(Power Amplifier)、低噪声放大器LNA(Low Noise Amplifier)、RF Balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s物理层速率。 - Hi3861 WLAN基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支持IEEE 802.11 b/g/n协议的各种数据速率。 @@ -29,7 +29,7 @@ Hi3861 WLAN模组是一片大约2cm\*5cm大小的开发板,是一款高度集 **图 3** Hi3861功能框图 - ![](figures/zh-cn_image_0000001105524466.png) + ![](figures/zh-cn_image_0000001128311066.png) ## 资源和约束 diff --git a/zh-cn/device-dev/quick-start/Readme-CN.md b/zh-cn/device-dev/quick-start/Readme-CN.md index 90dd84f1a6ac1b95caa0a28881d016960f73828c..69991d66becb3cfef2d8980b923dc38cdd43f790 100644 --- a/zh-cn/device-dev/quick-start/Readme-CN.md +++ b/zh-cn/device-dev/quick-start/Readme-CN.md @@ -1,6 +1,5 @@ # 快速入门 -- [导读](导读.md) - [轻量和小型系统入门](轻量和小型系统入门.md) - [概述](概述.md) - [了解开发板](了解开发板.md) @@ -33,12 +32,10 @@ - [常见问题](常见问题-6.md) - [标准系统入门](标准系统入门.md) - - [概述](概述-7.md) - - [环境搭建](环境搭建.md) - - [概述](概述-8.md) - - [Windows开发环境准备](Windows开发环境准备-9.md) - - [Ubuntu编译环境准备](Ubuntu编译环境准备-10.md) - - [常见问题](常见问题-11.md) - - - [开发步骤](开发步骤-12.md) + - [入门介绍](入门介绍.md) + - [Windows开发环境准备](Windows开发环境准备-7.md) + - [搭建Ubuntu环境及编译(Docker方式)](搭建Ubuntu环境及编译(Docker方式).md) + - [搭建Ubuntu环境及编译(安装包方式)](搭建Ubuntu环境及编译(安装包方式).md) + - [镜像烧录](镜像烧录.md) + - [常见问题](常见问题-8.md) diff --git "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207-10.md" "b/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207-10.md" deleted file mode 100644 index e0b8306a6577e9db5b4415098502b02638dbc741..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207-10.md" +++ /dev/null @@ -1,63 +0,0 @@ -# Ubuntu编译环境准备 - -- [方式一:Docker方式准备Ubuntu编译环境](#section1643363843714) - - [获取标准系统源码](#section58448331029) - - [Docker环境安装使用](#section22916211916) - -- [方式二:安装包方式准备Ubuntu编译环境](#section25961010189) - - [安装依赖工具](#section109262032104819) - - [获取标准系统源码](#section6325556113718) - - [获取prebuilts](#section16453104219209) - - -OpenHarmony为开发者提供了Docker和安装包两种方式来搭建Ubuntu编译环境。接下来将分别针对这两种方式进行介绍。 - -## 方式一:Docker方式准备Ubuntu编译环境 - -OpenHarmony标准系统为开发者提供的Docker环境已经将对应的编译工具链进行了封装,开发者可省略对应工具的安装。具体Docker使用分为如下几步: - -1. 获取标准系统源码。 -2. Docker环境安装使用。 - -### 获取标准系统源码 - -获取[标准系统源码](https://repo.huaweicloud.com/harmonyos/os/2.0/code-2.0-canary.tar.gz)。此处获取的源码为静态打包代码,如想获取码云社区最新源码,请采用[repo方式获取](../get-code/源码获取.md)。 - -### Docker环境安装使用 - -具体Docker环境的安装和使用请参考[Docker环境安装使用指导](../get-code/获取工具.md)。 - -## 方式二:安装包方式准备Ubuntu编译环境 - -安装包方式具体操作分为如下几步: - -1. 安装依赖工具。 -2. 获取标准系统源码。 -3. 获取prebuilts。 - -### 安装依赖工具 - -安装命令如下: - -``` -sudo apt-get install binutils git-core 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 lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 -``` - ->![](public_sys-resources/icon-caution.gif) **注意:** ->以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。如果是Ubuntu18.04以上版本需要安装python2.7 和 python-minimal。 - -### 获取标准系统源码 - -获取[标准系统源码](https://repo.huaweicloud.com/harmonyos/os/2.0/code-2.0-canary.tar.gz)。此处获取的源码为静态打包代码,如想获取码云社区最新源码,请采用[repo方式获取](../get-code/源码获取.md)。 - -### 获取prebuilts - -1. 在源码根目录下执行脚本。 - - ``` - build/prebuilts_download.sh - ``` - - 下载的prebuilts二进制默认存放在与OpenHarmony同目录下的OpenHarmony\_2.0\_canary\_prebuilts下。 - - diff --git "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207-9.md" "b/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207-9.md" deleted file mode 100644 index 57bbca56858890b3f41c5b0b73710a42427f30bb..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207-9.md" +++ /dev/null @@ -1,147 +0,0 @@ -# Ubuntu编译环境准备 - -- [Docker方式准备Ubuntu编译环境](#section1643363843714) - - [获取系统源码](#section58448331029) - - [Docker环境安装使用](#section22916211916) - -- [安装包方式准备Ubuntu编译环境](#section25961010189) - - [安装依赖工具](#section109262032104819) - - [获取标准系统源码](#section6325556113718) - - [获取prebuilts](#section16453104219209) - - [配置NodeJS环境和获取Node\_modules依赖包](#section133741330192119) - - [安装hc-gen工具](#section149281248182116) - - -OpenHarmony为开发者提供了Docker和安装包两种方式来搭建Ubuntu编译环境。接下来将分别针对这两种方式进行介绍。 - -## Docker方式准备Ubuntu编译环境 - -OpenHarmony标准系统为开发者提供的Docker环境已经将对应的编译工具链进行了封装,开发者可省略对应工具的安装。具体Docker使用分为如下几步: - -1. 获取系统源码。 -2. Docker环境安装使用。 - -### 获取系统源码 - -具体获取方式请参考[获取标准系统源码](../get-code/源码获取.md)。 - -### Docker环境安装使用 - -具体Docker环境的安装和使用请参考[Docker环境安装使用指导](../get-code/获取工具.md)。 - -## 安装包方式准备Ubuntu编译环境 - -安装包方式具体操作分为如下几步: - -1. 安装依赖工具。 -2. 获取系统源码。 -3. 获取prebuilts。 -4. 配置NodeJS环境和获取Node\_modules依赖包。 -5. 安装hc-gen工具。 - -### 安装依赖工具 - -安装命令如下: - -``` -sudo apt-get install binutils git-core 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 lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 python2.7 python-minimal -``` - ->![](public_sys-resources/icon-note.gif) **说明:** ->以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。 - -### 获取标准系统源码 - -具体获取方式请参考[获取标准系统源码](../get-code/源码获取.md)。 - -### 获取prebuilts - -1. 切换到OpenHarmony工作目录。 - - ``` - cd OpenHarmony - ``` - -2. 下载脚本。 - - ``` - curl https://gitee.com/landwind/script-tools/raw/master/Shell/OpenHarmony/OpenHarmony_2.0_canary_prebuilts_download.sh >./prebuilts_download.sh - ``` - -3. 下载并解压prebuilts压缩包到指定位置。 - - ``` - bash ./prebuilts_download.sh - ``` - - 二进制默认存放在与OpenHarmony同目录下的OpenHarmony\_2.0\_canary\_prebuilts下,如需修改默认位置,请编辑prebuilts\_download.sh修改bin\_dir值。 - -4. 切换到之前的目录。 - - ``` - cd - - ``` - - -### 配置NodeJS环境和获取Node\_modules依赖包 - -为了编译JS Framework,开发者需要在Linux服务器下载配置NodeJS(注意:步骤中OpenHarmony目录指代当前工程的根目录,可自定义),具体操作如下: - -1. 开发者在Linux服务器下载Nodejs。 - - ``` - mkdir -p OpenHarmony/prebuilts/build-tools/common/nodejs #创建nodejs目录 - cd OpenHarmony/prebuilts/build-tools/common/nodejs #进入nodejs目录 - wget --no-check-certificate https://nodejs.org/download/release/v12.18.4/node-v12.18.4-linux-x64.tar.gz #下载nodejs - tar -zxvf node-v12.18.4-linux-x64.tar.gz #解压nodejs压缩包 - cd - #切换到之前的目录 - ``` - -2. 配置NodeJS环境变量,下载node\_modules包。 - - ``` - cd OpenHarmony/third_party/jsframework #进入jsframework目录 - export PATH=../../prebuilts/build-tools/common/nodejs/node-v12.18.4-linux-x64/bin:${PATH} #设置NodeJS环境变量 - npm install #下载node_modules包 - cd - #切换到之前的目录 - ``` - -3. 把下载的node\_modules包放入OpenHarmony代码的prebuilts/build-tools/common/js-framework目录下。 - - ``` - mkdir -p OpenHarmony/prebuilts/build-tools/common/js-framework #创建js-framework目录 - cp -rp OpenHarmony/third_party/jsframework/node_modules OpenHarmony/prebuilts/build-tools/common/js-framework/ - ``` - - -### 安装hc-gen工具 - -hc-gen用于进行驱动编译,具体安装步骤如下: - -1. 打开Linux编译服务器终端。 -2. [下载hc-gen工具](https://repo.huaweicloud.com/harmonyos/compiler/hc-gen/0.65/linux/hc-gen-0.65-linux.tar)。 -3. 解压hc-gen安装包到Linux服务器\~/hc-gen路径下。 - - ``` - tar -xvf hc-gen-0.65-linux.tar -C ~/ - ``` - -4. 设置环境变量。 - - ``` - vim ~/.bashrc - ``` - - 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - - ``` - export PATH=~/hc-gen:$PATH - ``` - -5. 生效环境变量。 - - ``` - source ~/.bashrc - ``` - - diff --git "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207.md" index 073e04bbc4b85187ff76c587eff29ede9b72e41d..e893fad747ef84ff2ded4922f5208e26070fd097 100755 --- "a/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207.md" +++ "b/zh-cn/device-dev/quick-start/Ubuntu\347\274\226\350\257\221\347\216\257\345\242\203\345\207\206\345\244\207.md" @@ -1,4 +1,4 @@ -# Ubuntu编译环境准备 +# Ubuntu编译环境准备 - [获取软件](#section1897711811517) - [获取源码](#section1545225464016) @@ -24,9 +24,9 @@ 6. 安装hb >![](public_sys-resources/icon-notice.gif) **须知:** ->- 针对Ubuntu编译环境我们提供了对应的Docker,该Docker封装了相关编译工具,选择使用Docker的开发者可跳过此章节。Docker使用可参考[Docker方式获取编译环境](../get-code/获取工具.md)。 +>- 针对Ubuntu编译环境我们提供了对应的Docker,该Docker封装了相关编译工具,选择使用Docker的开发者可跳过此章节。Docker使用可参考[Docker方式获取编译环境](../get-code/Docker编译环境.md)。 >- 通常系统默认安装samba、vim等常用软件,需要做适当适配以支持Linux服务器与Windows工作台之间的文件共享。 ->- 想要详细了解OpenHarmony编译构建模块功能的开发者可参考[编译构建使用指南](../subsystems/编译构建概述.md)。 +>- 想要详细了解OpenHarmony编译构建模块功能的开发者可参考[编译构建使用指南](../subsystems/编译构建.md)。 ## 获取软件 diff --git "a/zh-cn/device-dev/quick-start/WLAN\350\201\224\347\275\221.md" "b/zh-cn/device-dev/quick-start/WLAN\350\201\224\347\275\221.md" index a0cacdf965403e4beff4fcdfa9e57e6a04adbffe..ab20f083f914b8a49bf99109750a3f6dd9cb1e0e 100755 --- "a/zh-cn/device-dev/quick-start/WLAN\350\201\224\347\275\221.md" +++ "b/zh-cn/device-dev/quick-start/WLAN\350\201\224\347\275\221.md" @@ -1,4 +1,4 @@ -# WLAN联网 +# WLAN联网 - [源码编译](#section191121332125319) - [镜像烧录](#section19458165166) @@ -10,7 +10,7 @@ 本节描述如何在Linux服务器上进行WLAN模组版本的编译。 -如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/获取工具.md)的编译操作。如果Linux编译环境通过软件包方式安装,请参考如下步骤。 +如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/Docker编译环境.md)的编译操作。如果Linux编译环境通过软件包方式安装,请参考如下步骤。 1. 打开DevEco Device Tool工具,点击“View \> Terminal”,进入终端界面。 @@ -19,7 +19,7 @@ ![](figures/1.png) - 在终端界面使用ssh命令连接linux服务器,如“ssh _user_@_ipaddr_”。 + 在终端界面使用ssh命令连接linux服务器,如“ssh user@ipaddr”。 **图 2** 终端界面示意图 @@ -63,17 +63,17 @@ Hi3861 WLAN模组的镜像烧录可以通过OpenHarmony IDE工具DevEco完成,工具的基本使用请参考[DevEco Device Tool使用指南](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),烧录过程包含如下步骤。 -1. 请连接好电脑和待烧录开发板,需要连接USB口,具体可参考[Hi3861开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_wifi_start_des-0000001050168548)。 +1. 请连接好电脑和待烧录开发板,需要连接USB口,具体可参考[Hi3861开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3861-0000001105041324)。 2. 打开电脑的设备管理器,查看并记录对应的串口号。 >![](public_sys-resources/icon-note.gif) **说明:** >如果对应的串口异常,请根据[Hi3861系列开发板串口驱动安装](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3861-drivers-0000001058153433)安装USB转串口的驱动程序。 - ![](figures/zh-cn_image_0000001073388838.png) + ![](figures/zh-cn_image_0000001128311118.png) 3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - ![](figures/zh-cn_image_0000001078404538.png) + ![](figures/zh-cn_image_0000001128311116.png) 4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3861系列开发板进行适配,无需单独修改。 5. 在“hi3861”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 @@ -82,20 +82,20 @@ Hi3861 WLAN模组的镜像烧录可以通过OpenHarmony IDE工具DevEco完成, - upload\_protocol:选择烧录协议,固定选择“burn-serial”。 - upload\_partitions:选择待烧录的文件,默认选择hi3861\_app。 - ![](figures/zh-cn_image_0000001078244328.png) + ![](figures/zh-cn_image_0000001128470922.png) 6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 7. 打开工程文件,在DevEco Device Tool界面的“PROJECT TASKS”中,点击hi3861下的**Upload**按钮,启动烧录。 - ![](figures/zh-cn_image_0000001163569275.png) + ![](figures/zh-cn_image_0000001174270749.png) 8. 启动烧录后,显示如下提示信息时,请按开发板上的RST按钮重启开发板。 - ![](figures/zh-cn_image_0000001074285712.png) + ![](figures/zh-cn_image_0000001174270751.png) 9. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 - ![](figures/zh-cn_image_0000001074445364.png) + ![](figures/zh-cn_image_0000001174350669.png) ## WLAN模组联网 diff --git "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-9.md" "b/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-7.md" similarity index 99% rename from "zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-9.md" rename to "zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-7.md" index 1922601478a44f30abab394ab7dde6fca921fea3..e4fd814993e581f8f6bde42142ff206415789de8 100644 --- "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-9.md" +++ "b/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-7.md" @@ -1,4 +1,4 @@ -# Windows开发环境准备 +# Windows开发环境准备 - [获取软件](#zh-cn_topic_0000001058091994_section1483143015558) - [安装Visual Studio Code](#zh-cn_topic_0000001058091994_section71401018163318) diff --git "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-8.md" "b/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-8.md" deleted file mode 100644 index 6cb31af41c0892a7b38dfc3dc84b79d02960271f..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207-8.md" +++ /dev/null @@ -1,183 +0,0 @@ -# Windows开发环境准备 - -- [获取软件](#zh-cn_topic_0000001058091994_section1483143015558) -- [安装Visual Studio Code](#zh-cn_topic_0000001058091994_section71401018163318) -- [安装Python](#zh-cn_topic_0000001058091994_section16266553175320) -- [安装Node.js](#zh-cn_topic_0000001058091994_section5353233124511) -- [安装hpm](#zh-cn_topic_0000001058091994_section173054793610) -- [安装DevEco Device Tool插件](#zh-cn_topic_0000001058091994_section4336315185716) - -系统要求:Windows 10 64位系统。 - -DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展,安装分为如下几步: - -1. 安装Visual Studio Code -2. 安装Python -3. 安装Node.js -4. 安装hpm -5. 安装DevEco Device Tool插件 - -## 获取软件 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

工具名称

-

用途说明

-

版本要求

-

获取渠道

-

Visual Studio Code

-

代码编辑工具

-

V1.53及以上 64位版本。

-

https://code.visualstudio.com/Download

-

Python

-

编译构建工具

-

3.7.4-3.8.x 64位版本

-

https://www.python.org/downloads/

-

Node.js

-

提供npm环境

-

v12.0.0及以上 64位版本

-

https://nodejs.org/zh-cn/download/

-

hpm

-

包管理工具

-

最新版

-

执行如下npm命令进行安装,npm自动下载最新版本

-
npm install -g @ohos/hpm-cli
-

DevEco Device Tool

-

OpenHarmony源码的编译、烧录、调试插件工具

-

v2.2 Beta1

-

https://device.harmonyos.com/cn/ide#download

-

下载前,请使用华为开发者帐号登录,如未注册,请先注册华为开发者帐号

-
- -## 安装Visual Studio Code - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装Visual Studio Code,打开命令行工具,输入**code --version**命令,检查版本号是否为1.53及以上版本;可以正常返回版本号,说明环境变量设置也正确。 - -1. 双击Visual Studio Code软件包进行安装。安装过程中,请勾选“添加到PATH(重启后生效)”。 - - ![](figures/zh-cn_image_0000001057335403.png) - -2. 安装完成后,重启计算机,使Visual Studio Code的环境变量生效。 -3. 打开命令行工具,输入**code --version**命令,可以正常显示版本号说明安装成功。 - -## 安装Python - -1. 双击Python安装包进行安装,勾选“**Add Python xx to PATH**”,然后点击**Install Now**开始安装。 - - ![](figures/zh-cn_image_0000001096154076.png) - -2. 等待安装完成后,点击**Close**。 - - ![](figures/zh-cn_image_0000001142794291.png) - -3. 打开命令行工具,输入python --version,检查安装结果。 - - ![](figures/zh-cn_image_0000001143154485.png) - -4. 在命令行工具中,分别执行如下命令设置pip源,用于后续安装DevEco Device Tool过程中下载依赖的组件包。 - - ``` - pip config set global.trusted-host repo.huaweicloud.com - pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple - pip config set global.timeout 120 - ``` - - -## 安装Node.js - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装Node.js,打开命令行工具,输入**node -v**命令,检查版本号是否为12.0.0及以上版本。 - -1. 点击下载后的软件包进行安装,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。 -2. 重新打开命令行工具,输入“node -v“命令,能正常查询Node.js的版本号,说明Node.js安装成功。 - - ![](figures/zh-cn_image_0000001056814287.png) - - -## 安装hpm - -该方式需先确保**Node.js**安装成功。 - -在安装hpm前,请检查网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问。这种情况下,需要先[设置npm代理](https://device.harmonyos.com/cn/docs/ide/user-guides/npm_proxy-0000001054491032),才能安装hpm。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果已安装hpm,可以执行**npm update -g @ohos/hpm-cli**命令升级hpm至最新版本。 - -1. 建议将npm源配置为国内镜像,例如设置为华为云镜像源。 - - ``` - npm config set registry https://repo.huaweicloud.com/repository/npm/ - ``` - -2. 打开命令行工具,执行如下命令安装最新版本hpm。 - - ``` - npm install -g @ohos/hpm-cli - ``` - - ![](figures/zh-cn_image_0000001073840162.png) - -3. 安装完成后,执行如下命令(V为大写字母)检查hpm安装结果。 - - ``` - hpm -V - ``` - - ![](figures/zh-cn_image_0000001100641602.png) - - -## 安装DevEco Device Tool插件 - -安装DevEco Device Tool插件,**主机的用户名不能包含中文字符**,否则可能导致运行出现错误。 - -DevEco Device Tool正常运行需要依赖于C/C++和CodeLLDB插件,在安装完DevEco Device Tool后,会自动从Visual Studio Code的插件市场安装C/C++和CodeLLDB插件。因此,在安装DevEco Device Tool前,请检查Visual Studio Code的网络连接状态,如果网络不能直接访问Internet,则需要通过代理服务器才可以访问,请先[Visual Studio Code代理设置](https://device.harmonyos.com/cn/docs/ide/user-guides/vscode_proxy-0000001074231144)。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->安装DevEco Device Tool时,请先关闭Visual Studio Code。 - -1. 解压DevEco Device Tool插件压缩包,双击安装包程序进行安装。 -2. 安装过程中,会自动安装DevEco Device Tool所需的依赖文件(如C/C++和CodeLLDB插件)和执行程序。 - - ![](figures/zh-cn_image_0000001072468991.png) - -3. 安装完成后,会自动关闭命令行工具窗口。 -4. 启动Visual Studio Code,点击左侧的![](figures/zh-cn_image_0000001072757874.png)按钮,检查INSTALLED中,是否已成功安装C/C++、CodeLLDB和DevEco Device Tool。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果C/C++和CodeLLDB插件安装不成功,则DevEco Device Tool不能正常运行,解决方法,详细请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/ide/user-guides/offline_plugin_install-0000001074376846)。 - - ![](figures/zh-cn_image_0000001142802505.png) - - diff --git "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207.md" index f70d3cce73f8f5939597d71c7d341d08a2f2a505..cffea83cad92e78f19cdb4222117b2c8c75902f0 100755 --- "a/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207.md" +++ "b/zh-cn/device-dev/quick-start/Windows\345\274\200\345\217\221\347\216\257\345\242\203\345\207\206\345\244\207.md" @@ -1,4 +1,4 @@ -# Windows开发环境准备 +# Windows开发环境准备 - [获取软件](#zh-cn_topic_0000001058091994_section1483143015558) - [安装Visual Studio Code](#zh-cn_topic_0000001058091994_section71401018163318) @@ -86,7 +86,7 @@ DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展 1. 双击Visual Studio Code软件包进行安装。安装过程中,请勾选“添加到PATH(重启后生效)”。 - ![](figures/zh-cn_image_0000001057335403.png) + ![](figures/zh-cn_image_0000001174350653.png) 2. 安装完成后,重启计算机,使Visual Studio Code的环境变量生效。 3. 打开命令行工具,输入**code --version**命令,可以正常显示版本号说明安装成功。 @@ -95,15 +95,15 @@ DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展 1. 双击Python安装包进行安装,勾选“**Add Python 3.8 to PATH**”,然后点击**Install Now**开始安装。 - ![](figures/zh-cn_image_0000001168817327.png) + ![](figures/zh-cn_image_0000001128470908.png) 2. 等待安装完成后,点击**Close**。 - ![](figures/zh-cn_image_0000001142794291.png) + ![](figures/zh-cn_image_0000001128311104.png) 3. 打开命令行工具,输入python --version,检查安装结果。 - ![](figures/zh-cn_image_0000001122419072.png) + ![](figures/zh-cn_image_0000001174350655.png) 4. 在命令行工具中,分别执行如下命令设置pip源,用于后续安装DevEco Device Tool过程中下载依赖的组件包。 @@ -122,7 +122,7 @@ DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展 1. 点击下载后的软件包进行安装,全部按照默认设置点击**Next**,直至**Finish**。安装过程中,Node.js会自动在系统的path环境变量中配置node.exe的目录路径。 2. 重新打开命令行工具,输入“node -v“命令,能正常查询Node.js的版本号,说明Node.js安装成功。 - ![](figures/zh-cn_image_0000001056814287.png) + ![](figures/zh-cn_image_0000001128311096.png) ## 安装hpm @@ -146,7 +146,7 @@ DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展 npm install -g @ohos/hpm-cli ``` - ![](figures/zh-cn_image_0000001073840162.png) + ![](figures/zh-cn_image_0000001128311100.png) 3. 安装完成后,执行如下命令(V为大写字母)检查hpm安装结果。 @@ -154,7 +154,7 @@ DevEco Device Tool以插件方式提供,基于Visual Studio Code进行扩展 hpm -V ``` - ![](figures/zh-cn_image_0000001100641602.png) + ![](figures/zh-cn_image_0000001174270735.png) ## 安装DevEco Device Tool插件 @@ -169,14 +169,14 @@ DevEco Device Tool正常运行需要依赖于C/C++和CodeLLDB插件,在安装 1. 解压DevEco Device Tool插件压缩包,双击安装包程序进行安装。 2. 安装过程中,会自动安装DevEco Device Tool所需的依赖文件(如C/C++和CodeLLDB插件)和执行程序。 - ![](figures/zh-cn_image_0000001072468991.png) + ![](figures/zh-cn_image_0000001128470902.png) 3. 安装完成后,会自动关闭命令行工具窗口。 -4. 启动Visual Studio Code,点击左侧的![](figures/zh-cn_image_0000001072757874.png)按钮,检查INSTALLED中,是否已成功安装C/C++、CodeLLDB和DevEco Device Tool。 +4. 启动Visual Studio Code,点击左侧的![](figures/zh-cn_image_0000001174350651.png)按钮,检查INSTALLED中,是否已成功安装C/C++、CodeLLDB和DevEco Device Tool。 >![](public_sys-resources/icon-note.gif) **说明:** >如果C/C++和CodeLLDB插件安装不成功,则DevEco Device Tool不能正常运行,解决方法,详细请参考:[离线安装C/C++和CodeLLDB插件](https://device.harmonyos.com/cn/docs/ide/user-guides/offline_plugin_install-0000001074376846)。 - ![](figures/zh-cn_image_0000001142802505.png) + ![](figures/zh-cn_image_0000001174270727.png) diff --git a/zh-cn/device-dev/quick-start/figures/1-18.png b/zh-cn/device-dev/quick-start/figures/1-18.png deleted file mode 100644 index 8ed1535a6bc23dc5bd02fbd5a3f1392f46ad8d83..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/1-18.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-16.png b/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-16.png deleted file mode 100644 index 1e7dd2cdb515e871a1c5d34b3332b097bc02351b..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-16.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-17.png b/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-17.png index 5b573a4ddfe89fe25cb1b567736823244fdb9e97..1e7dd2cdb515e871a1c5d34b3332b097bc02351b 100644 Binary files a/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-17.png and b/zh-cn/device-dev/quick-start/figures/2021-01-27_170334-17.png differ diff --git a/zh-cn/device-dev/quick-start/figures/2021-01-27_181047.png b/zh-cn/device-dev/quick-start/figures/2021-01-27_181047.png deleted file mode 100755 index 587ca51a1010c3fefcc79be73ffc5584075551ed..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/2021-01-27_181047.png and /dev/null differ diff --git "a/zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242-16.png" "b/zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242-16.png" new file mode 100644 index 0000000000000000000000000000000000000000..6975fb5fef92e35dec2de84b7e7035a39794bdf4 Binary files /dev/null and "b/zh-cn/device-dev/quick-start/figures/3516\346\255\243\351\235\242-16.png" differ diff --git "a/zh-cn/device-dev/quick-start/figures/3861\350\203\214\351\235\242.png" "b/zh-cn/device-dev/quick-start/figures/3861\350\203\214\351\235\242.png" deleted file mode 100755 index 623a4d9c339512dc78ec15c94013ad535c8b296c..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/quick-start/figures/3861\350\203\214\351\235\242.png" and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001113969536.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001113969536.png deleted file mode 100644 index baac7b26450b8bc195a0db0bb3bb41119c0d9828..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001113969536.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001114129426.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001114129426.png deleted file mode 100644 index c5548cb227bd024b49aa3adba0a20869581448e8..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001114129426.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117168786.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117168786.png deleted file mode 100644 index ecc5d08c03bd361cfc3d2b9691ee6a52807cead6..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117168786.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117621400.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117621400.png new file mode 100644 index 0000000000000000000000000000000000000000..bfb378217e99536cf076deecfb0f0677cb51eef8 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001117621400.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001120802383.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001120802383.png deleted file mode 100755 index 4921a82341b8828a6117343b77f7c92b0d99a2c6..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001120802383.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105524466.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311066.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105524466.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311066.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105216304.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311070.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105216304.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311070.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152176131.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311072.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152176131.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311072.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001096963405.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311090.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001096963405.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311090.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001078089378.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311092.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001078089378.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311092.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073835952.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311094.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073835952.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311094.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311096.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311096.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd7b0a67ce7110774979284e69c462058723756 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311096.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160649343.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311098.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160649343.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311098.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311100.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311100.png new file mode 100644 index 0000000000000000000000000000000000000000..61aec8202ac830a3598ef2c8a413be30c5a742f0 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311100.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311104.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311104.png new file mode 100644 index 0000000000000000000000000000000000000000..773abcd91a0c0ee1d3f5f87218216fc337d8f62f Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311104.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001078404538.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311116.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001078404538.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311116.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001057235392.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311118.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001057235392.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128311118.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001151976061.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470864.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001151976061.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470864.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105376252.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470880.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105376252.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470880.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073057176.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470900.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073057176.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470900.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470902.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470902.png new file mode 100644 index 0000000000000000000000000000000000000000..43e43b52b677660cec4d049784b246aebe1a2434 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470902.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160529355.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470904.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160529355.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470904.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470906.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470906.png new file mode 100644 index 0000000000000000000000000000000000000000..281958fe76a787acc5d0b98f5ea248fa5abf2405 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470906.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470908.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470908.png new file mode 100644 index 0000000000000000000000000000000000000000..8aa65e82be8db2e7de62fca8980d00ae42215d96 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470908.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001078244328.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470922.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001078244328.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001128470922.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160527611.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160527611.png deleted file mode 100644 index 558d3299149a13c444966ef3e3260bf5b0956667..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160527611.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160528243.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160528243.png deleted file mode 100644 index 571af4fc8e53f59f246496ad670cc6b84f4473f3..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160528243.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160649345.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160649345.png deleted file mode 100644 index 1819a2816fa617fa6389646fd6a4b1ab0d97272d..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160649345.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163045527.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163045527.png deleted file mode 100644 index d8ac531b8265f265e2bd25518b212143fc61e4cf..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163045527.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163569081.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163569081.png deleted file mode 100644 index 703476a1e0d68ef903774a53b45e19c0617cb135..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163569081.png and /dev/null differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152056191.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270699.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152056191.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270699.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105216296.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270713.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105216296.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270713.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105056492.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270715.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105056492.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270715.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270727.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270727.png new file mode 100644 index 0000000000000000000000000000000000000000..2609aa029260a137c76c299fead396c07b8c8e45 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270727.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001116405268.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270729.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001116405268.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270729.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163529159.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270731.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163529159.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270731.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270733.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270733.png new file mode 100644 index 0000000000000000000000000000000000000000..72dd05e3ae1eb91156df98cb1915b6264b3bbe5a Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270733.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270735.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270735.png new file mode 100644 index 0000000000000000000000000000000000000000..2710fef9266dde76a9c555bc2edecebd8e3d8d1b Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270735.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152256221.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270737.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152256221.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270737.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001151976069.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270739.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001151976069.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270739.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105376260.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270743.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105376260.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270743.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163569275.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270749.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163569275.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270749.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001074285712.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270751.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001074285712.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174270751.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001119945810.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350615.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001119945810.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350615.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152176139.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350623.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152176139.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350623.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073388838.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350633.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073388838.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350633.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163568181.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350641.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001163568181.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350641.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073242197.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350643.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001073242197.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350643.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160529359.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350647.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001160529359.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350647.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001077956808.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350649.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001077956808.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350649.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350651.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350651.png new file mode 100644 index 0000000000000000000000000000000000000000..686385e096a24ec1906169d2b11f75030c386b9f Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350651.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350653.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350653.png new file mode 100644 index 0000000000000000000000000000000000000000..1e6214d082696dc0727947e6b46f252fff33d92e Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350653.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350655.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350655.png new file mode 100644 index 0000000000000000000000000000000000000000..2f6e93e40bf4abee3c83aebf0c5f3299e51dc630 Binary files /dev/null and b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350655.png differ diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105536118.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350659.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001105536118.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350659.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152256235.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350661.png similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001152256235.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350661.png diff --git a/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001074445364.png b/zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350669.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001074445364.png rename to zh-cn/device-dev/quick-start/figures/zh-cn_image_0000001174350669.png diff --git "a/zh-cn/device-dev/quick-start/figures/\346\240\207\345\207\206\347\216\257\345\242\203\345\277\253\351\200\237\345\205\245\351\227\250\346\265\201\347\250\213.png" "b/zh-cn/device-dev/quick-start/figures/\346\240\207\345\207\206\347\216\257\345\242\203\345\277\253\351\200\237\345\205\245\351\227\250\346\265\201\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..587b414d787f36de3494760e14313e0ff18f896b Binary files /dev/null and "b/zh-cn/device-dev/quick-start/figures/\346\240\207\345\207\206\347\216\257\345\242\203\345\277\253\351\200\237\345\205\245\351\227\250\346\265\201\347\250\213.png" differ diff --git "a/zh-cn/device-dev/quick-start/\344\272\206\350\247\243\345\274\200\345\217\221\346\235\277.md" "b/zh-cn/device-dev/quick-start/\344\272\206\350\247\243\345\274\200\345\217\221\346\235\277.md" index ca0d75e7cae1de7d855b2beb89503df26a6e1173..fae4d8bb46425aee84df037e4e126c480c18bd9d 100755 --- "a/zh-cn/device-dev/quick-start/\344\272\206\350\247\243\345\274\200\345\217\221\346\235\277.md" +++ "b/zh-cn/device-dev/quick-start/\344\272\206\350\247\243\345\274\200\345\217\221\346\235\277.md" @@ -1,4 +1,4 @@ -# 了解开发板 +# 了解开发板 - **[Hi3861开发板介绍](Hi3861开发板介绍.md)** diff --git "a/zh-cn/device-dev/quick-start/\345\205\245\351\227\250\344\273\213\347\273\215.md" "b/zh-cn/device-dev/quick-start/\345\205\245\351\227\250\344\273\213\347\273\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..b01d0c442c2b2448421984cc82d61a4f87fcfca7 --- /dev/null +++ "b/zh-cn/device-dev/quick-start/\345\205\245\351\227\250\344\273\213\347\273\215.md" @@ -0,0 +1,54 @@ +# 入门介绍 + +- [快速入门流程](#section7825218111517) +- [开发板简介](#zh-cn_topic_0000001053666242_section047719215429) +- [开发板规格](#zh-cn_topic_0000001053666242_section15192203316533) + +本文快速掌握OpenHarmony标准系统的环境搭建、编译、烧录、启动等操作。本文将以当前推荐的Hi3516DV300开发板为例进行说明。 + +OpenHarmony标准系统使用Windows环境进行开发,使用Linux环境进行编译,可以使用Docker或安装包方式来搭建Linux编译环境,请根据实际情况自行选择。 + +## 快速入门流程 + +标准环境快速入门过程如下图所示,Linux环境编译请根据实际情况选择docker或安装包其中一种即可。 + +**图 1** 标准环境快速入门流程 +![](figures/标准环境快速入门流程.png "标准环境快速入门流程") + +## 开发板简介 + +Hi3516DV300作为新一代行业专用Smart HD IP摄像机SOC,集成新一代ISP\(Image Signal Processor\)、H.265视频压缩编码器,同时集成高性能NNIE引擎,使得Hi3516DV300在低码率、高画质、智能处理和分析、低功耗等方面引领行业水平。 + +**图 2** Hi3516单板正面外观图 + + +![](figures/3516正面-16.png) + +## 开发板规格 + +**表 1** Hi3516开发板规格清单 + + + + + + + + + + + + + +

规格类型

+

规格清单

+

处理器及内部存储

+
  • Hi3516DV300芯片
  • DDR3 1GB
  • eMMC4.5,8GB容量
+

外部器件

+
  • 以太网口
  • 音频视频
    • 1路语音输入
    • 1路单声道(AC_L)输出,接3W功放(LM4871)
    • MicroHDMI(1路HDMI 1.4)
    +
  • 摄像头
    • 传感器IMX335
    • 镜头M12,焦距4mm,光圈1.8
    +
  • 显示屏
    • LCD连接器(2.35寸)
    • LCD连接器(5.5寸)
    +
  • 外部器件及接口
    • SD卡接口
    • JTAG/I2S 接口
    • ADC接口
    • 舵机接口
    • Grove连接器
    • USB2.0(Type C)
    • 功能按键3个,2个用户自定义按键,1个升级按键
    • LED指示灯,绿灯,红灯
    +
+
+ diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-1.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-1.md" deleted file mode 100644 index 2348c6d97e09b0e333f325bf17ae29b129e59f10..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-1.md" +++ /dev/null @@ -1,151 +0,0 @@ -# 安装开发板环境 - -- [Hi3516工具要求](#section179175261196) - - [硬件要求](#section5840424125014) - - [软件要求](#section965634210501) - -- [安装Linux服务器工具](#section182916865219) - - [将Linux shell改为bash](#section1715027152617) - - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251) - - [安装文件打包工具](#section1969111820270) - - [安装Java 虚拟机环境](#section1692618112713) - - -## Hi3516工具要求 - -### 硬件要求 - -- Hi3516DV300 IoT Camera开发板 -- USB转串口线、网线(Windows工作台通过USB转串口线、网线与Hi3516DV300 开发板连接) - -各硬件连接关系如下图所示。 - -**图 1** 硬件连线图 - - -![](figures/矩形备份-292.png) - -### 软件要求 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section182916865219)章节。 - -Hi3516开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 - -**表 1** Linux服务器开发工具及获取途径 - - - - - - - - - - - - - - - - - - - - - - - - -

开发工具

-

用途

-

获取途径

-

bash

-

命令行处理工具

-

系统配置

-

编译基础软件包(仅ubuntu 20+需要)

-

编译依赖的基础软件包

-

通过互联网获取

-

dosfstools、mtools、mtd-utils

-

文件打包工具

-

通过apt-get install安装

-

Java 虚拟机环境

-

编译、调试和运行Java程序

-

通过apt-get install安装

-
- -## 安装Linux服务器工具 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装LLVM、hc-gen编译工具。 ->- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。 - -### 将Linux shell改为bash - -查看shell是否为bash,在终端运行如下命令 - -``` -ls -l /bin/sh -``` - -如果显示为“/bin/sh -\> bash”则为正常,否则请按以下方式修改: - -**方法一**:在终端运行如下命令,然后选择 no。 - -``` -sudo dpkg-reconfigure dash -``` - -**方法二**:先删除sh,再创建软链接。 - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### 安装编译依赖基础软件(仅Ubuntu 20+需要) - -执行以下命令进行安装: - -``` -sudo apt-get install build-essential && sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install make && sudo apt-get install zlib* && sudo apt-get install libffi-dev -``` - -### 安装文件打包工具 - -1. 打开Linux编译服务器终端。 -2. 运行如下命令,安装dosfstools。 - - ``` - sudo apt-get install dosfstools - ``` - -3. 运行如下命令,安装mtools。 - - ``` - sudo apt-get install mtools - ``` - -4. 运行如下命令,安装mtd-utils。 - - ``` - sudo apt-get install mtd-utils - ``` - - -### 安装Java 虚拟机环境 - -1. 打开Linux编译服务器终端。 -2. 安装Java运行时环境(JRE)。 - - ``` - sudo apt-get install default-jre - ``` - -3. 安装Java sdk开发工具包。 - - ``` - sudo apt-get install default-jdk - ``` - - diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-2.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-2.md" index 21805e2323747ff8d8b72df0474b59f83238898d..3f827074bfd5e4c7c19251d467dece8dedeb4fe2 100644 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-2.md" +++ "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-2.md" @@ -1,4 +1,4 @@ -# 安装开发板环境 +# 安装开发板环境 - [Hi3516工具要求](#section179175261196) - [硬件要求](#section5840424125014) diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-3.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-3.md" deleted file mode 100644 index bf59854a1d551fdbcbb26a8b726653d64d72c5bb..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-3.md" +++ /dev/null @@ -1,156 +0,0 @@ -# 安装开发板环境 - -- [Hi3518环境搭建](#section1724111409282) - - [硬件要求](#section487353718276) - - [软件要求](#section17315193935817) - -- [安装Linux服务器工具](#section8831868501) - - [将Linux shell改为bash](#section1715027152617) - - [安装编译依赖基础软件(仅Ubuntu 20+需要)](#section45512412251) - - [安装文件打包工具](#section1686964015274) - - [安装hc-gen](#section18706403274) - - -## Hi3518环境搭建 - -### 硬件要求 - -- Hi3518EV300 IoT Camera开发板 -- USB转串口线、网线(Windows工作台通过USB转串口线、网线与开发板连接) - - 各硬件连接关系如下图所示。 - - -**图 1** 硬件连线图 -![](figures/硬件连线图-3.png "硬件连线图-3") - -### 软件要求 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->本节描述安装包方式搭建编译环境的操作步骤。如果是Docker方式安装编译环境,请跳过此章节以及下述[安装Linux服务器工具](#section8831868501)章节。 - -Hi3518开发板对Linux服务器通用环境配置需要的工具及其获取途径如下表所示。 - -**表 1** Linux服务器开发工具及获取途径 - - - - - - - - - - - - - - - - - - - - -

开发工具

-

用途

-

获取途径

-

bash

-

命令行处理工具

-

系统配置

-

编译基础软件包(仅ubuntu 20+需要)

-

编译依赖的基础软件包

-

通过互联网获取

-

dosfstools、mtools、mtd-utils

-

文件打包工具

-

通过apt-get install安装

-
- -## 安装Linux服务器工具 - ->![](public_sys-resources/icon-notice.gif) **须知:** ->- 如果通过“HPM组件方式”或“HPM包管理器命令行工具方式”获取源码,不需要安装hc-gen编译工具。 ->- (推荐)如果通过“镜像站点方式”或“代码仓库方式”获取源码,需要安装hc-gen编译工具。安装hc-gen编译工具时,请确保编译工具的环境变量路径唯一。 - -### 将Linux shell改为bash - -查看shell是否为bash,在终端运行如下命令 - -``` -ls -l /bin/sh -``` - -如果显示为“/bin/sh -\> bash”则为正常,否则请按以下方式修改: - -**方法一**:在终端运行如下命令,然后选择 no。 - -``` -sudo dpkg-reconfigure dash -``` - -**方法二**:先删除sh,再创建软链接。 - -``` -sudo rm -rf /bin/sh -sudo ln -s /bin/bash /bin/sh -``` - -### 安装编译依赖基础软件(仅Ubuntu 20+需要) - -执行以下命令进行安装: - -``` -sudo apt-get install build-essential && sudo apt-get install gcc && sudo apt-get install g++ && sudo apt-get install make && sudo apt-get install zlib* && sudo apt-get install libffi-dev -``` - -### 安装文件打包工具 - -1. 打开Linux编译服务器终端。 -2. 运行如下命令,安装dosfstools。 - - ``` - sudo apt-get install dosfstools - ``` - -3. 运行如下命令,安装mtools。 - - ``` - sudo apt-get install mtools - ``` - -4. 运行如下命令,安装mtd-utils。 - - ``` - sudo apt-get install mtd-utils - ``` - - -### 安装hc-gen - -1. 打开Linux编译服务器终端。 -2. [下载hc-gen工具](https://repo.huaweicloud.com/harmonyos/compiler/hc-gen/0.65/linux/hc-gen-0.65-linux.tar)。 -3. 解压hc-gen安装包到Linux服务器\~/hc-gen路径下。 - - ``` - tar -xvf hc-gen-0.65-linux.tar -C ~/ - ``` - -4. 设置环境变量。 - - ``` - vim ~/.bashrc - ``` - - 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。 - - ``` - export PATH=~/hc-gen:$PATH - ``` - -5. 生效环境变量。 - - ``` - source ~/.bashrc - ``` - - diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-4.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-4.md" index fced03de6238573e2e338fd74d7b3618f2481d53..b2bbd778809bfdb9aa3ac3e5104e070cce42eae4 100644 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-4.md" +++ "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203-4.md" @@ -1,4 +1,4 @@ -# 安装开发板环境 +# 安装开发板环境 - [Hi3518环境搭建](#section1724111409282) - [硬件要求](#section487353718276) diff --git "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203.md" "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203.md" index 7bc6e67829cceedac9c8991f9ebfbba0ec0c608e..2bf84d7aab300883ba5e0b44f2c0acb5ad043917 100644 --- "a/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203.md" +++ "b/zh-cn/device-dev/quick-start/\345\256\211\350\243\205\345\274\200\345\217\221\346\235\277\347\216\257\345\242\203.md" @@ -1,4 +1,4 @@ -# 安装开发板环境 +# 安装开发板环境 - [Hi3861工具要求](#section466851916410) - [硬件要求](#section19202111020215) @@ -362,6 +362,6 @@ sudo apt-get install build-essential gcc g++ make zlib* libffi-dev 2. 点击安装包,安装驱动程序。 3. 驱动安装完成后,重新插拔USB接口,串口信息显示如下图所示。 - ![](figures/zh-cn_image_0000001057235392.png) + ![](figures/zh-cn_image_0000001174350633.png) diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-0.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-0.md" deleted file mode 100755 index de74ac1a07c009703075f5ac3e5b067bbd463052..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-0.md" +++ /dev/null @@ -1,292 +0,0 @@ -# 常见问题 - -- [安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”](#section1221016541119) -- [安装python3过程中,提示“-bash: make: command not found”](#section1913477181213) -- [安装python3过程中,提示“zlib not available”](#section108211415131210) -- [安装python3过程中,提示“No module named '\_ctypes'”](#section2062268124) -- [编译构建过程中,提示“No module named 'Crypto'”](#section982315398121) -- [编译构建过程中,提示“No module named 'ecdsa'”](#section102035451216) -- [编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0”](#section4498158162320) -- [编译构建过程中,提示找不到“-lgcc”](#section11181036112615) -- [编译构建过程中,提示找不到“python”](#section1571810194619) -- [安装 kconfiglib时,遇到lsb\_release错误](#section691681635814) - -## 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details - ``` - -- **可能原因** - - 环境中未安装“gcc”。 - -- **解决办法** - - 1、通过命令“apt-get install gcc”在线安装。 - - 2、完成后,重新安装python3。 - - -## 安装python3过程中,提示“-bash: make: command not found” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - -bash: make: command not found - ``` - -- **可能原因** - - 环境中未安装“make”。 - -- **解决办法** - - 1、通过命令“apt-get install make”在线安装。 - - 2、完成后,重新安装python3。 - - -## 安装python3过程中,提示“zlib not available” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - zipimport.ZipImportError: can't decompress data; zlib not avaliable - ``` - -- **可能原因** - - 环境中未安装“zlib”。 - -- **解决办法** - - 方法1:通过命令“apt-get install zlib”在线安装。 - - 方法2:如果软件源中没有该软件,请从“www.zlib.net”下载版本代码,并离线安装。 - - ![](figures/10.png) - - 完成下载后,通过以下命令安装: - - ``` - # tar xvf zlib-1.2.11.tar.gz - # cd zlib-1.2.11 - # ./configure - # make && make install - ``` - - 完成后,重新安装python3。 - - -## 安装python3过程中,提示“No module named '\_ctypes'” - -- **现象描述** - - 安装python3过程中出现以下错误: - - ``` - ModuleNotFoundError:No module named ‘_ctypes’ - ``` - - -- **可能原因** - - 环境中未安装“libffi”和“libffi-devel”。 - - -- **解决办法** - - 1、通过命令“apt-get install libffi\* -y”,在线安装。 - - 2、完成后,重新安装python3。 - - -## 编译构建过程中,提示“No module named 'Crypto'” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - ModuleNotFoundError: No module named 'Crypto' - ``` - - -- **可能原因** - - 环境中未安装“Crypto”。 - - -- **解决办法** - - 方法1:通过命令“pip3 install Crypto”,在线安装。 - - 方法2:离线安装 - - 通过网页[https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files),下载源码。 - - ![](figures/zh-cn_image_0000001151976061.png) - - 将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”。 - - 完成上述安装后,重新构建。 - - -## 编译构建过程中,提示“No module named 'ecdsa'” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - ModuleNotFoundError:No module named 'ecdsa' - ``` - - -- **可能原因** - - 环境中未安装“ecdsa”。 - - -- **解决办法** - - 方法1:通过命令“pip3 install ecdsa”,在线安装。 - - 方法2:离线安装 - - 通过网页[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files),下载安装包。 - - ![](figures/zh-cn_image_0000001152176131.png) - - 将安装包放置Linux服务器中,并安装“pip3 install ecdsa-0.15-py2.py3-none-any.whl”。 - - 完成上述安装后,重新构建。 - - -## 编译构建过程中,提示“Could not find a version that satisfies the requirement six\>=1.9.0” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - Could not find a version that satisfies the requirement six>=1.9.0 - ``` - - -- **可能原因** - - 环境中未安装合适的“six”。 - - -- **解决办法** - - 方法1:通过命令“pip3 install six”,在线安装。 - - 方法2:离线安装 - - 通过网页[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files),下载安装包。 - - ![](figures/zh-cn_image_0000001152056191.png) - - 将源码放置在Linux服务器中,并安装“pip3 install six-1.14.0-py2.py3-none-any.whl”。 - - 完成上述安装后,重新构建。 - - -## 编译构建过程中,提示找不到“-lgcc” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - riscv32-unknown-elf-ld: cannot find -lgcc - ``` - - -- **可能原因** - - 交叉编译器gcc\_riscv32的PATH添加错误,如下,在"bin"后多添加了一个“/”,应该删除。 - - ``` - ~/gcc_riscv32/bin/:/data/toolchain/ - ``` - - -- **解决办法** - - 重新修改gcc\_riscv32的PATH,将多余的“/”删除。 - - ``` - ~/gcc_riscv32/bin:/data/toolchain/ - ``` - - -## 编译构建过程中,提示找不到“python” - -- **现象描述** - - 编译构建过程中出现以下错误: - - ``` - -bash: /usr/bin/python: No such file or directory - ``` - - -- **可能原因**1 - - 没有装python。 - -- **解决办法** - - 请按照 [安装Python环境](../quick-start/Ubuntu编译环境准备.md) - -- **可能原因2** - - ![](figures/zh-cn_image_0000001105376252.png) - -- **解决办法** - - usr/bin目录下没有python软链接,请运行以下命令添加软链接: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - 例: - - ![](figures/zh-cn_image_0000001105216296.png) - - -## 安装 kconfiglib时,遇到lsb\_release错误 - -- **现象描述** - - 安装kconfiglib过程中遇到如下错误打印: - - ``` - subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1. - ``` - -- **可能原因** - - lsb\_release模块基于的python版本与现有python版本不一致 - -- **解决办法** - - 执行"find / -name lsb\_release",找到lsb\_release位置并删除,如:"sudo rm -rf /usr/bin/lsb\_release" - - diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-1.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-1.md" index de74ac1a07c009703075f5ac3e5b067bbd463052..f8e0b7384e225685a08fa51e0cf97264bfe3851e 100644 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-1.md" +++ "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-1.md" @@ -1,4 +1,4 @@ -# 常见问题 +# 常见问题 - [安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”](#section1221016541119) - [安装python3过程中,提示“-bash: make: command not found”](#section1913477181213) @@ -134,7 +134,7 @@ 通过网页[https://pypi.org/project/pycrypto/\#files](https://pypi.org/project/pycrypto/#files),下载源码。 - ![](figures/zh-cn_image_0000001151976061.png) + ![](figures/zh-cn_image_0000001128470864.png) 将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”。 @@ -165,7 +165,7 @@ 通过网页[https://pypi.org/project/ecdsa/\#files](https://pypi.org/project/ecdsa/#files),下载安装包。 - ![](figures/zh-cn_image_0000001152176131.png) + ![](figures/zh-cn_image_0000001128311072.png) 将安装包放置Linux服务器中,并安装“pip3 install ecdsa-0.15-py2.py3-none-any.whl”。 @@ -196,7 +196,7 @@ 通过网页[https://pypi.org/project/six/\#files](https://pypi.org/project/six/#files),下载安装包。 - ![](figures/zh-cn_image_0000001152056191.png) + ![](figures/zh-cn_image_0000001174270699.png) 将源码放置在Linux服务器中,并安装“pip3 install six-1.14.0-py2.py3-none-any.whl”。 @@ -253,7 +253,7 @@ - **可能原因2** - ![](figures/zh-cn_image_0000001105376252.png) + ![](figures/zh-cn_image_0000001128311070.png) - **解决办法** @@ -268,7 +268,7 @@ 例: - ![](figures/zh-cn_image_0000001105216296.png) + ![](figures/zh-cn_image_0000001174350623.png) ## 安装 kconfiglib时,遇到lsb\_release错误 diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" deleted file mode 100644 index 7f7e7a76538ce683098105b3e6bda42bae97df74..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-10.md" +++ /dev/null @@ -1,21 +0,0 @@ -# 常见问题 - -- **现象描述** - - Linux编译服务器终端输入不识别的命令时,提示"ImportError: No module named apt\_pkg" - - -- **可能原因** - - python3 apt安装兼容性问题。 - -- **解决办法** - - 执行如下命令重新安装python3-apt。 - - ``` - sudo apt-get remove python3-apt - sudo apt-get install python3-apt - ``` - - diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-2.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-2.md" deleted file mode 100755 index 1dade41bc1a1fd59f0cd3e366899d314ced4f6a9..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-2.md" +++ /dev/null @@ -1,175 +0,0 @@ -# 常见问题 - -- [烧写选择串口后提示失败](#section627268185113) -- [Windows电脑与单板网络连接失败](#section195391036568) -- [烧写失败](#section571164016565) -- [编译构建过程中,提示找不到“python”](#section1039835245619) -- [串口无回显](#section14871149155911) - -## 烧写选择串口后提示失败 - -- **现象描述** - - 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied。 - - **图 1** 打开串口失败图 - ![](figures/打开串口失败图.png "打开串口失败图") - -- **可能原因** - - 串口已经被占用。 - -- **解决办法** - -1. 按图依次选择下拉框,查找带有serial-xx的终端 - - **图 2** 查找是否存在占用串口的终端 - ![](figures/查找是否存在占用串口的终端.png "查找是否存在占用串口的终端") - -2. 点击标号中的垃圾桶图标,关闭串口。 - - **图 3** 关闭串口终端 - ![](figures/关闭串口终端.png "关闭串口终端") - -3. 重新点击烧写,选择串口并开始烧写程序 - - **图 4** 重新启动烧写任务 - - - ![](figures/changjian1.png) - - -## Windows电脑与单板网络连接失败 - -- **现象描述** - - 点击烧写并选择串口后,无法获取文件。 - - **图 5** 网络不通,单板无法获取文件图 - ![](figures/网络不通-单板无法获取文件图.png "网络不通-单板无法获取文件图") - -- **可能原因** - - 单板网络与Windows电脑不联通。 - - Windows电脑防火墙未允许Visual Studio Code联网。 - -- **解决方法** - -1. 检查网线是否连接。 -2. 点击Windows防火墙。 - - **图 6** 网络防火墙设置图 - ![](figures/网络防火墙设置图.png "网络防火墙设置图") - -3. 点击“允许应用通过防火墙”。 - - **图 7** 防火墙和网络保护界面图 - ![](figures/防火墙和网络保护界面图.png "防火墙和网络保护界面图") - -4. 查找Visual Studio Code应用。 - - **图 8** 查找Visual Studio Code应用图 - ![](figures/查找Visual-Studio-Code应用图.png "查找Visual-Studio-Code应用图") - -5. 勾选Visual Studio Code的专用和公用网络的访问权限。 - - **图 9** 允许Visual Studio Code应用访问网络 - ![](figures/允许Visual-Studio-Code应用访问网络.png "允许Visual-Studio-Code应用访问网络") - - -## 烧写失败 - -- **现象描述** - - 点击烧写并选择串口后,出现无法烧写的情况。 - -- **可能原因** - - 安装IDE插件DevEco后未重启。 - -- **解决方法** - - 重启IDE。 - - -## 编译构建过程中,提示找不到“python” - -- **现象描述** - - ![](figures/zh-cn_image_0000001105056492.png) - - -- **可能原因1** - - 没有装python。 - -- **解决办法** - - 请按照[安装python](../quick-start/Ubuntu编译环境准备.md)。 - -- **可能原因2** - - ![](figures/zh-cn_image_0000001151976069.png) - -- **解决办法** - - usr/bin目录下没有python软链接,请运行以下命令: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - 例: - - ![](figures/zh-cn_image_0000001152176139.png) - - -## 串口无回显 - -- **现象描述** - - 串口显示已连接,重启单板后,回车无任何回显。 - -- **可能原因1** - - 串口连接错误。 - -- **解决办法** - - 修改串口号。 - - 请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行内[步骤1](../quick-start/运行Hello-OHOS.md)修改串口号。 - - -- **可能原因2** - - 单板U-boot被损坏。 - -- **解决办法** - - 烧写U-boot。 - - 若上述步骤依旧无法连接串口,可能由于单板U-boot损坏,按下述步骤烧写U-boot。 - - -1. 获取引导文件U-boot。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >单板的U-boot文件请在开源包中获取: - >Hi3516DV300:device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin - >Hi3518EV300:device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin - -2. 根据USB烧写步骤烧写U-boot文件。 - - 按照[Hi3516系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Hi3518系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3518_upload-0000001057313128)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。 - -3. 烧写完成后,登录串口如下图所示。 - - **图 10** U-boot烧写完成串口显示图 - ![](figures/U-boot烧写完成串口显示图.png "U-boot烧写完成串口显示图") - - diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-3.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-3.md" index 1dade41bc1a1fd59f0cd3e366899d314ced4f6a9..ece72f03517ecd60ca587fcba3c3fab1a5974a47 100644 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-3.md" +++ "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-3.md" @@ -1,4 +1,4 @@ -# 常见问题 +# 常见问题 - [烧写选择串口后提示失败](#section627268185113) - [Windows电脑与单板网络连接失败](#section195391036568) @@ -97,7 +97,7 @@ - **现象描述** - ![](figures/zh-cn_image_0000001105056492.png) + ![](figures/zh-cn_image_0000001174270715.png) - **可能原因1** @@ -110,7 +110,7 @@ - **可能原因2** - ![](figures/zh-cn_image_0000001151976069.png) + ![](figures/zh-cn_image_0000001128470880.png) - **解决办法** @@ -125,7 +125,7 @@ 例: - ![](figures/zh-cn_image_0000001152176139.png) + ![](figures/zh-cn_image_0000001174270713.png) ## 串口无回显 diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-5.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-5.md" deleted file mode 100755 index 1bff88b102de828e19eda72d4a376dcec7ea9a01..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-5.md" +++ /dev/null @@ -1,174 +0,0 @@ -# 常见问题 - -- [烧写选择串口后提示失败](#section1498892119619) -- [Windows电脑与单板网络连接失败](#section8512971816) -- [烧写失败](#section1767804111198) -- [编译构建过程中,提示找不到“python”](#zh-cn_topic_0000001053466255_section1039835245619) -- [串口无回显](#zh-cn_topic_0000001053466255_section14871149155911) - -## 烧写选择串口后提示失败 - -- **现象描述** - - 点击烧写并选择串口后,出现Error: Opening COMxx: Access denied。 - - **图 1** 打开串口失败图 - ![](figures/打开串口失败图-7.png "打开串口失败图-7") - -- **可能原因** - - 串口已经被占用。 - -- **解决办法** - -1. 按图依次选择下拉框,查找带有serial-xx的终端 - - **图 2** 查找是否存在占用串口的终端 - ![](figures/查找是否存在占用串口的终端-8.png "查找是否存在占用串口的终端-8") - -2. 点击标号中的垃圾桶图标,关闭串口。 - - **图 3** 关闭串口终端 - ![](figures/关闭串口终端-9.png "关闭串口终端-9") - -3. 重新点击烧写,选择串口并开始烧写程序 - - **图 4** 重新启动烧写任务 - - - ![](figures/changjian1-10.png) - - -## Windows电脑与单板网络连接失败 - -- **现象描述** - - 点击烧写并选择串口后,无法获取文件。 - - **图 5** 网络不通,单板无法获取文件图 - ![](figures/网络不通-单板无法获取文件图-11.png "网络不通-单板无法获取文件图-11") - -- **可能原因** - - 单板网络与Windows电脑不联通。 - - Windows电脑防火墙未允许Visual Studio Code联网。 - -- **解决方法** - -1. 检查网线是否连接。 -2. 点击Windows防火墙。 - - **图 6** 网络防火墙设置图 - ![](figures/网络防火墙设置图-12.png "网络防火墙设置图-12") - -3. 点击“允许应用通过防火墙”。 - - **图 7** 防火墙和网络保护界面图 - ![](figures/防火墙和网络保护界面图-13.png "防火墙和网络保护界面图-13") - -4. 查找Visual Studio Code应用。 - - **图 8** 查找Visual Studio Code应用图 - ![](figures/查找Visual-Studio-Code应用图-14.png "查找Visual-Studio-Code应用图-14") - -5. 勾选Visual Studio Code的专用和公用网络的访问权限。 - - **图 9** 允许Visual Studio Code应用访问网络 - ![](figures/允许Visual-Studio-Code应用访问网络-15.png "允许Visual-Studio-Code应用访问网络-15") - - -## 烧写失败 - -- **现象描述** - - 点击烧写并选择串口后,出现无法烧写的情况。 - -- **可能原因** - - 安装IDE插件DevEco后未重启。 - -- **解决方法** - - 重启IDE。 - - -## 编译构建过程中,提示找不到“python” - -- **现象描述** - - ![](figures/zh-cn_image_0000001105376260.png) - - -- **可能原因1** - - 没有装python。 - -- **解决办法** - - 请按照[安装python](../quick-start/Ubuntu编译环境准备.md)。 - -- **可能原因2** - - ![](figures/zh-cn_image_0000001105216304.png) - -- **解决办法** - - usr/bin目录下没有python软链接,请运行以下命令: - - ``` - # cd /usr/bin/ - # which python3 - # ln -s /usr/local/bin/python3 python - # python --version - ``` - - 例: - - ![](figures/zh-cn_image_0000001152256235.png) - - -## 串口无回显 - -- **现象描述** - - 串口显示已连接,重启单板后,回车无任何回显。 - -- **可能原因1** - - 串口连接错误。 - -- **解决办法** - - 修改串口号。 - - 请查看设备管理器,确认连接单板的串口与终端中连接串口是否一致,若不一致,请按镜像运行内[步骤1](../quick-start/运行Hello-OHOS.md)修改串口号。 - - -- **可能原因2** - - 单板U-boot被损坏。 - -- **解决办法** - - 烧写U-boot。 - - 若上述步骤依旧无法连接串口,可能由于单板U-boot损坏,按下述步骤烧写U-boot。 - - -1. 获取引导文件U-boot。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >单板的U-boot文件请在开源包中获取: - >Hi3516DV300:device\\hisilicon\\hispark\_taurus\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3516dv300.bin - >Hi3518EV300:device\\hisilicon\\hispark\_aries\\sdk\_liteos\\uboot\\out\\boot\\u-boot-hi3518ev300.bin - -2. 根据USB烧写步骤烧写U-boot文件。 - - 按照[Hi3516系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)/[Hi3518系列USB烧写步骤](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3518_upload-0000001057313128)中描述的USB烧写方法,选择对应单板的U-boot文件进行烧写。 - -3. 烧写完成后,登录串口如下图所示。 - - ![](figures/zh-cn_image_0000001105536118.png) - - diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-6.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-6.md" index 1bff88b102de828e19eda72d4a376dcec7ea9a01..b2dc3ad51268d608a8767e7eaf9256fbc9adfe11 100644 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-6.md" +++ "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-6.md" @@ -1,4 +1,4 @@ -# 常见问题 +# 常见问题 - [烧写选择串口后提示失败](#section1498892119619) - [Windows电脑与单板网络连接失败](#section8512971816) @@ -97,7 +97,7 @@ - **现象描述** - ![](figures/zh-cn_image_0000001105376260.png) + ![](figures/zh-cn_image_0000001174270743.png) - **可能原因1** @@ -110,7 +110,7 @@ - **可能原因2** - ![](figures/zh-cn_image_0000001105216304.png) + ![](figures/zh-cn_image_0000001174270739.png) - **解决办法** @@ -125,7 +125,7 @@ 例: - ![](figures/zh-cn_image_0000001152256235.png) + ![](figures/zh-cn_image_0000001174350661.png) ## 串口无回显 @@ -169,6 +169,6 @@ 3. 烧写完成后,登录串口如下图所示。 - ![](figures/zh-cn_image_0000001105536118.png) + ![](figures/zh-cn_image_0000001174350659.png) diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-11.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-8.md" similarity index 86% rename from "zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-11.md" rename to "zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-8.md" index 7f7e7a76538ce683098105b3e6bda42bae97df74..85c32067b448d53895207caca5feb9217dda9b9b 100644 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-11.md" +++ "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230-8.md" @@ -1,4 +1,4 @@ -# 常见问题 +# 常见问题 - **现象描述** diff --git "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230.md" index 2bb8c5f473aa8b6038dca80d1c1fc94b9ae5a019..91cee989ccdc93b2afeb8690bb939a34b57a2a20 100755 --- "a/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230.md" +++ "b/zh-cn/device-dev/quick-start/\345\270\270\350\247\201\351\227\256\351\242\230.md" @@ -1,4 +1,4 @@ -# 常见问题 +# 常见问题 - [hb 安装过程中出现乱码、段错误](#section411894616119) - [hb 安装过程中提示"cannot import 'sysconfig' from 'distutils'"](#section629417571626) diff --git "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244-11.md" "b/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244-11.md" deleted file mode 100644 index 37b798d84329ebe4a92979fe92ceb5560645b6a5..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244-11.md" +++ /dev/null @@ -1,246 +0,0 @@ -# 开发步骤 - -- [环境搭建](#section1246439101710) -- [编译](#section375234715135) -- [烧录](#section111671738101213) - - [前提条件](#section1458192114718) - - [使用USB烧录](#section18423113662120) - -- [示例开发](#section5600113114323) - -## 环境搭建 - -请参考[搭建标准系统环境](概述-7.md)完成OpenHarmony的系统环境搭建。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果使用三方开发板开发,针对开发板的具体环境要求,以三方开发板的官方指导为准。 - -## 编译 - -使用Docker环境的开发者可参照Docker使用指导进行编译。采用安装包方式的开发者在Linux环境进行如下操作。 - -1. 进入源码根目录,执行如下命令进行版本编译。 - - ``` - ./build.sh --product-name Hi3516DV300 - ``` - - \{product\_name\}为当前版本支持的平台。 - -2. 检查编译结果。编译完成后,log中显示如下: - - ``` - build system image successful. - =====build Hi3516DV300 successful. - ``` - - 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >其他模块化编译操作,可参见[编译构建指导](../subsystems/标准系统编译构建指导.md)。 - - -## 烧录 - -标准系统烧录,在V2.2 Beta1及以上版本支持。 - -Hi3516系列开发板中,只有Hi3516DV300支持烧录标准系统,其烧录方式包括USB烧录、网口烧录和串口烧录三种方式,其中: - -- **Windows系统:支持USB烧录、网口烧录和串口烧录** -- **Linux系统:支持串口烧录和网口烧录。如果采用的是Linux+Windows双系统,也支持USB烧录。** - -同一种烧录方式(如网口烧录),在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前Hi3516DV300开发板支持通过USB、网口、串口三种方式烧录OpenHarmony标准系统。本文以USB方式为例讲解烧录操作,其他两种烧录方式请参照[Hi3516DV300烧录指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)。 - -### 前提条件 - -在DevEco Device Tool中[打开一个工程](https://device.harmonyos.com/cn/docs/ide/user-guides/open_project-0000001071680043),该工程文件夹选择待烧录文件所在文件夹即可。其中开发板类型固定选择Hi3516DV300,Framework选择“Hb”。 - -### 使用USB烧录 - -Hi3516DV300开发板使用USB烧录方式,支持Windows系统。如果采用的是Linux+Windows双系统,Linux系统也支持USB烧录。 - -1. 请连接好电脑和待烧录开发板,以Hi3516DV300为例,需要同时连接串口和USB口,具体可参考[Hi3516开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_camera_start_3516-0000001052670587)。 -2. 打开电脑的设备管理器,查看并记录对应的串口号。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - - ![](figures/zh-cn_image_0000001160529359.png) - -3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - - ![](figures/2021-01-27_170334-16.png) - -4. 在**Partition Configuration**页签中,按照下表内容填写烧录文件信息,包括: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Binary

-

Memory

-

System

-

Address

-

Length

-

Board

-

Type

-

fastboot

-

选择“u-boot-hi3516dv300_emmc.bin”

-

emmc

-

none

-

0x000000

-

0x100000

-

固定选择“hi3516dv300”

-

NA

-

boot

-

选择“uImage”

-

emmc

-

none

-

0x100000

-

0xf00000

-

NA

-

updater

-

选择“updater.img”

-

emmc

-

ext3/4

-

0x1000000

-

0x1400000

-

NA

-

misc

-

空白,不用选择

-

emmc

-

none

-

0x2400000

-

0x100000

-

NA

-

system

-

选择“system.img”

-

emmc

-

ext3/4

-

0x2500000

-

0xceb00000

-

NA

-

vendor

-

选择“vendor.img”

-

emmc

-

ext3/4

-

0xd1000000

-

0x10000000

-

NA

-

userdata

-

选择“userdata.img”

-

emmc

-

ext3/4

-

0xe1000000

-

0x5b800000

-

NA

-
- - ![](figures/zh-cn_image_0000001160527611.png) - -5. 在“hi3516dv300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 - - - upload\_port:选择步骤2中查询的串口号。 - - upload\_protocol:选择烧录协议,固定选择“hiburn-usb”。 - - upload\_partitions:选择待烧录的文件,包括fastboot、boot、updater、misc、system、vendor和userdata。 - - ![](figures/zh-cn_image_0000001160528243.png) - -6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 -7. 打开工程文件,点击![](figures/2021-01-27_170334-17.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击fastboot下的**Erase**按钮,擦除U-Boot。 - - ![](figures/zh-cn_image_0000001163045527.png) - -8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(下电再上电)。 - - ![](figures/zh-cn_image_0000001114129426.png) - -9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。 - - ![](figures/zh-cn_image_0000001113969536.png) - -10. 擦除完成后,点击hi3516dv300下的**Upload**按钮,启动烧录。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果您是第一次在工作台烧录Hi3516/Hi3518系列开发板,可能烧录失败,提示“not find the Devices”,请根据[Hi3516/Hi3518系列开发板USB驱动安装](https://device.harmonyos.com/cn/docs/ide/user-guides/usb_driver-0000001058690393)进行处理后再重新烧录。 - - ![](figures/1-18.png) - -11. 启动烧录后,界面提示如下信息时,表示烧录成功。 - - ![](figures/zh-cn_image_0000001160649343.png) - - -## 示例开发 - -恭喜!您已经完成了OpenHarmony标准系统的快速入门,接下来可[开发一个小示例](../guide/概述-10.md),进一步熟悉OpenHarmony的开发。 - diff --git "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244-12.md" "b/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244-12.md" deleted file mode 100644 index 40cde60fb17a996761f180e09bcb509a339f160a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244-12.md" +++ /dev/null @@ -1,246 +0,0 @@ -# 开发步骤 - -- [环境搭建](#section1246439101710) -- [编译](#section375234715135) -- [烧录](#section111671738101213) - - [前提条件](#section1458192114718) - - [使用USB烧录](#section18423113662120) - -- [示例开发](#section5600113114323) - -## 环境搭建 - -请参考[搭建标准系统环境](概述-8.md)完成OpenHarmony的系统环境搭建。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->如果使用三方开发板开发,针对开发板的具体环境要求,以三方开发板的官方指导为准。 - -## 编译 - -使用Docker环境的开发者可参照Docker使用指导进行编译。采用安装包方式的开发者在Linux环境进行如下操作。 - -1. 进入源码根目录,执行如下命令进行版本编译。 - - ``` - ./build.sh --product-name Hi3516DV300 - ``` - - \{product\_name\}为当前版本支持的平台。 - -2. 检查编译结果。编译完成后,log中显示如下: - - ``` - build system image successful. - =====build Hi3516DV300 successful. - ``` - - 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >其他模块化编译操作,可参见[编译构建指导](../subsystems/标准系统编译构建指导.md)。 - - -## 烧录 - -标准系统烧录,在V2.2 Beta1及以上版本支持。 - -Hi3516系列开发板中,只有Hi3516DV300支持烧录标准系统,其烧录方式包括USB烧录、网口烧录和串口烧录三种方式,其中: - -- **Windows系统:支持USB烧录、网口烧录和串口烧录** -- **Linux系统:支持串口烧录和网口烧录。如果采用的是Linux+Windows双系统,也支持USB烧录。** - -同一种烧录方式(如网口烧录),在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->当前Hi3516DV300开发板支持通过USB、网口、串口三种方式烧录OpenHarmony标准系统。本文以USB方式为例讲解烧录操作,其他两种烧录方式请参照[Hi3516DV300烧录指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)。 - -### 前提条件 - -在DevEco Device Tool中[打开一个工程](https://device.harmonyos.com/cn/docs/ide/user-guides/open_project-0000001071680043),该工程文件夹选择待烧录文件所在文件夹即可。其中开发板类型固定选择Hi3516DV300,Framework选择“Hb”。 - -### 使用USB烧录 - -Hi3516DV300开发板使用USB烧录方式,支持Windows系统。如果采用的是Linux+Windows双系统,Linux系统也支持USB烧录。 - -1. 请连接好电脑和待烧录开发板,以Hi3516DV300为例,需要同时连接串口和USB口,具体可参考[Hi3516开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_camera_start_3516-0000001052670587)。 -2. 打开电脑的设备管理器,查看并记录对应的串口号。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - - ![](figures/zh-cn_image_0000001160529359.png) - -3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - - ![](figures/2021-01-27_170334-16.png) - -4. 在**Partition Configuration**页签中,按照下表内容填写烧录文件信息,包括: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Binary

-

Memory

-

System

-

Address

-

Length

-

Board

-

Type

-

fastboot

-

选择“u-boot-hi3516dv300_emmc.bin”

-

emmc

-

none

-

0x000000

-

0x100000

-

固定选择“hi3516dv300”

-

NA

-

boot

-

选择“uImage”

-

emmc

-

none

-

0x100000

-

0xf00000

-

NA

-

updater

-

选择“updater.img”

-

emmc

-

ext3/4

-

0x1000000

-

0x1400000

-

NA

-

misc

-

空白,不用选择

-

emmc

-

none

-

0x2400000

-

0x100000

-

NA

-

system

-

选择“system.img”

-

emmc

-

ext3/4

-

0x2500000

-

0xceb00000

-

NA

-

vendor

-

选择“vendor.img”

-

emmc

-

ext3/4

-

0xd1000000

-

0x10000000

-

NA

-

userdata

-

选择“userdata.img”

-

emmc

-

ext3/4

-

0xe1000000

-

0x5b800000

-

NA

-
- - ![](figures/zh-cn_image_0000001160527611.png) - -5. 在“hi3516dv300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 - - - upload\_port:选择步骤2中查询的串口号。 - - upload\_protocol:选择烧录协议,固定选择“hiburn-usb”。 - - upload\_partitions:选择待烧录的文件,包括fastboot、boot、updater、misc、system、vendor和userdata。 - - ![](figures/zh-cn_image_0000001160528243.png) - -6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 -7. 打开工程文件,点击![](figures/2021-01-27_170334-17.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击fastboot下的**Erase**按钮,擦除U-Boot。 - - ![](figures/zh-cn_image_0000001163045527.png) - -8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(下电再上电)。 - - ![](figures/zh-cn_image_0000001114129426.png) - -9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。 - - ![](figures/zh-cn_image_0000001113969536.png) - -10. 擦除完成后,点击hi3516dv300下的**Upload**按钮,启动烧录。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果您是第一次在工作台烧录Hi3516/Hi3518系列开发板,可能烧录失败,提示“not find the Devices”,请根据[Hi3516/Hi3518系列开发板USB驱动安装](https://device.harmonyos.com/cn/docs/ide/user-guides/usb_driver-0000001058690393)进行处理后再重新烧录。 - - ![](figures/1-18.png) - -11. 启动烧录后,界面提示如下信息时,表示烧录成功。 - - ![](figures/zh-cn_image_0000001160649343.png) - - -## 示例开发 - -恭喜!您已经完成了OpenHarmony标准系统的快速入门,接下来可[开发一个小示例](../guide/概述-10.md),进一步熟悉OpenHarmony的开发。 - diff --git "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244.md" "b/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244.md" index d9eb08eb1571d36406c81a16e6d0f87808885feb..70e795860fbfacc0dc0c4d9c38c453e7a5a99519 100644 --- "a/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244.md" +++ "b/zh-cn/device-dev/quick-start/\345\274\200\345\217\221\346\255\245\351\252\244.md" @@ -1,4 +1,4 @@ -# 开发步骤 +# 开发步骤 - **[Hi3861开发板](Hi3861开发板.md)** diff --git "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210Docker\346\226\271\345\274\217\357\274\211.md" "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210Docker\346\226\271\345\274\217\357\274\211.md" new file mode 100644 index 0000000000000000000000000000000000000000..2f4c97aa4a72f1a42454c7662ccfc17eab7e17d4 --- /dev/null +++ "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210Docker\346\226\271\345\274\217\357\274\211.md" @@ -0,0 +1,118 @@ +# 搭建Ubuntu环境及编译(Docker方式) + +- [获取标准系统源码](#section8761819202511) + - [前提条件](#section102871547153314) + - [操作步骤](#section429012478331) + +- [获取Docker环境](#section181431248132513) +- [编译](#section92391739152318) + +OpenHarmony标准系统为开发者提供的Docker环境已经将对应的编译工具链进行了封装,开发者可省略对应工具的安装。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>- 在使用Docker前需要先安装Docker,Docker安装请参考[官方指导](https://docs.docker.com/engine/install/ubuntu/)。 +>- Docker方式和安装包方式二选一即可。选择Docker方式的开发者可跳过[安装包方式](搭建Ubuntu环境及编译(安装包方式).md)的内容。 + +## 获取标准系统源码 + +### 前提条件 + +1. 注册码云gitee账号。 +2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 +3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading))并配置用户信息。 + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. 安装码云repo工具,可以执行如下命令。 + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### 操作步骤 + +方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +方式二:通过repo + https 下载。 + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## 获取Docker环境 + +**方式一:从HuaweiCloud SWR上直接获取Docker镜像进行构建:** + +1. 获取Docker镜像。 + + ``` + docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + +2. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.1 + ``` + + +**方式二:通过Dockerfile 构建本地Docker镜像进行构建** + +1. 获取Dockerfile脚本文件,用来构建本地Docker镜像。 + + ``` + git clone https://gitee.com/openharmony/docs.git + ``` + +2. 进入Dockerfile代码目录路径执行Docker镜像构建命令。 + + ``` + cd docs/docker/standard + ./build.sh + ``` + +3. 进入OpenHarmony代码根目录执行如下命令,从而进入Docker构建环境。 + + ``` + docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.1 + ``` + + +## 编译 + +1. 在源码的根目录执行预处理脚本。 + + ``` + ../scripts/prepare.sh + ``` + +2. 通过如下编译脚本启动标准系统类设备(参考内存≥128MB)的编译。 + + ``` + ./build.sh --product-name {product_name} + ``` + + \{product\_name\}为当前版本支持的平台,比如:Hi3516DV300 + + 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 + +3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](镜像烧录.md)。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>退出Docker执行exit命令即可。 + diff --git "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210\345\256\211\350\243\205\345\214\205\346\226\271\345\274\217\357\274\211.md" "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210\345\256\211\350\243\205\345\214\205\346\226\271\345\274\217\357\274\211.md" new file mode 100644 index 0000000000000000000000000000000000000000..258eb324d2b51900114cb2cd9b8b843c7041a679 --- /dev/null +++ "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272Ubuntu\347\216\257\345\242\203\345\217\212\347\274\226\350\257\221\357\274\210\345\256\211\350\243\205\345\214\205\346\226\271\345\274\217\357\274\211.md" @@ -0,0 +1,98 @@ +# 搭建Ubuntu环境及编译(安装包方式) + +- [安装依赖工具](#section18431165519244) +- [获取标准系统源码](#section113751052102517) + - [前提条件](#section102871547153314) + - [操作步骤](#section429012478331) + +- [执行prebuilts](#section0495320152619) +- [编译](#section1664835963517) + +## 安装依赖工具 + +安装命令如下: + +``` +sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip +``` + +>![](public_sys-resources/icon-note.gif) **说明:** +>以上安装命令适用于Ubuntu18.04,其他版本请根据安装包名称采用对应的安装命令。 + +## 获取标准系统源码 + +### 前提条件 + +1. 注册码云gitee账号。 +2. 注册码云SSH公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191)。 +3. 安装[git客户端](http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)和[git-lfs](https://gitee.com/vcs-all-in-one/git-lfs?_from=gitee_search#downloading))并配置用户信息。 + + ``` + git config --global user.name "yourname" + git config --global user.email "your-email-address" + git config --global credential.helper store + ``` + +4. 安装码云repo工具,可以执行如下命令。 + + ``` + curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo #如果没有权限,可下载至其他目录,并将其配置到环境变量中 + chmod a+x /usr/local/bin/repo + pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests + ``` + + +### 操作步骤 + +方式一(推荐):通过repo + ssh 下载(需注册公钥,请参考[码云帮助中心](https://gitee.com/help/articles/4191))。 + +``` +repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +方式二:通过repo + https 下载。 + +``` +repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify +repo sync -c +repo forall -c 'git lfs pull' +``` + +## 执行prebuilts + +在源码根目录下执行脚本,安装编译器及二进制工具。 + +``` +bash build/prebuilts_download.sh +``` + +下载的prebuilts二进制默认存放在与OpenHarmony同目录下的OpenHarmony\_2.0\_canary\_prebuilts下。 + +## 编译 + +在Linux环境进行如下操作: + +1. 进入源码根目录,执行如下命令进行版本编译。 + + ``` + ./build.sh --product-name {product_name} + ``` + + \{product\_name\}为当前版本支持的平台,比如:Hi3516DV300 + +2. 检查编译结果。编译完成后,log中显示如下: + + ``` + build system image successful. + =====build Hi3516DV300 successful. + ``` + + 编译所生成的文件都归档在out/ohos-arm-release/目录下,结果镜像输出在 out/ohos-arm-release/packages/phone/images/ 目录下。 + + >![](public_sys-resources/icon-note.gif) **说明:** + >其他模块化编译操作,可参见[编译构建指导](../subsystems/编译构建子系统-标准系统.md)。 + +3. 编译源码完成,请进行镜像烧录,具体请参见[镜像烧录](镜像烧录.md)。 + diff --git "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272\347\263\273\347\273\237\347\216\257\345\242\203.md" "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272\347\263\273\347\273\237\347\216\257\345\242\203.md" index 8329e7ffd099f57833fa26a714a4a2597583b18f..73a9d50f87e5de08c775137b9864e6f02656872e 100755 --- "a/zh-cn/device-dev/quick-start/\346\220\255\345\273\272\347\263\273\347\273\237\347\216\257\345\242\203.md" +++ "b/zh-cn/device-dev/quick-start/\346\220\255\345\273\272\347\263\273\347\273\237\347\216\257\345\242\203.md" @@ -1,4 +1,4 @@ -# 搭建系统环境 +# 搭建系统环境 - **[概述](概述-0.md)** diff --git "a/zh-cn/device-dev/quick-start/\346\240\207\345\207\206\347\263\273\347\273\237\345\205\245\351\227\250.md" "b/zh-cn/device-dev/quick-start/\346\240\207\345\207\206\347\263\273\347\273\237\345\205\245\351\227\250.md" index 6c5d5731272e16d42afd0fb49e2e856b8bfc0911..0281a27a47be0f03dcb2595968a0377c5e65f554 100755 --- "a/zh-cn/device-dev/quick-start/\346\240\207\345\207\206\347\263\273\347\273\237\345\205\245\351\227\250.md" +++ "b/zh-cn/device-dev/quick-start/\346\240\207\345\207\206\347\263\273\347\273\237\345\205\245\351\227\250.md" @@ -1,9 +1,15 @@ # 标准系统入门 -- **[概述](概述-7.md)** +- **[入门介绍](入门介绍.md)** -- **[环境搭建](环境搭建.md)** +- **[Windows开发环境准备](Windows开发环境准备-7.md)** -- **[开发步骤](开发步骤-12.md)** +- **[搭建Ubuntu环境及编译(Docker方式)](搭建Ubuntu环境及编译(Docker方式).md)** + +- **[搭建Ubuntu环境及编译(安装包方式)](搭建Ubuntu环境及编译(安装包方式).md)** + +- **[镜像烧录](镜像烧录.md)** + +- **[常见问题](常见问题-8.md)** diff --git "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-0.md" "b/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-0.md" index 9438a5709543f609e8be3c31d3b142ad6bedacc3..1ef79df37bfea75bd726e0a20b273f7b8c01fd80 100644 --- "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-0.md" +++ "b/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-0.md" @@ -1,4 +1,4 @@ -# 概述 +# 概述 OpenHarmony可以使用DevEco Device Tool进行开发、编译、烧录、调测等。 diff --git "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-6.md" "b/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-6.md" deleted file mode 100644 index 8551ab5722f57062a695c9bb4e420bb300006355..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-6.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 概述 - -开发者可以通过本文快速掌握OpenHarmony标准系统的环境搭建、编译、烧录、启动等操作。本文将以当前推荐的Hi3516DV300开发板为例进行说明。 - diff --git "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-7.md" "b/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-7.md" deleted file mode 100644 index 8551ab5722f57062a695c9bb4e420bb300006355..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-7.md" +++ /dev/null @@ -1,4 +0,0 @@ -# 概述 - -开发者可以通过本文快速掌握OpenHarmony标准系统的环境搭建、编译、烧录、启动等操作。本文将以当前推荐的Hi3516DV300开发板为例进行说明。 - diff --git "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-8.md" "b/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-8.md" deleted file mode 100644 index 2dfd7a2168d9b8fc7dec01687a1c857ec9eb2282..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260-8.md" +++ /dev/null @@ -1,58 +0,0 @@ -# 概述 - -- [简介](#section18217135811916) -- [环境要求](#section466851916410) - - [硬件要求](#section19682305453) - - [软件要求](#section1595725202314) - - -## 简介 - -OpenHarmony标准系统当前可以使用DevEco Device Tool在Windows平台进行开发和烧录,使用Linux环境进行编译。本文接下来将介绍如何进行对应环境的搭建。 - ->![](public_sys-resources/icon-note.gif) **说明:** ->OpenHarmony标准系统的Windows开发环境准备跟轻量和小型系统的对应操作一致,所以完成轻量和小型系统Windows开发环境准备的开发者可以跳过本文[第2章节](Windows开发环境准备-9.md)。 - -## 环境要求 - -### 硬件要求 - -- Linux服务器 -- Windows工作台(主机电脑) - -### 软件要求 - -**表 1** 开发平台要求 - - - - - - - - - - - - - - - - - - -

平台

-

软件

-

描述

-

备注

-

Linux编译服务器

-

操作系统

-

Ubuntu18.04及以上64位系统版本,Shell使用bash。服务器硬件规格要求见下:

-
  • 硬盘:至少400G
  • CPU:至少8核
  • 内存:至少32G
-

通常系统默认安装samba、vim等常用软件,需要做适当适配以支持Linux文件共享。

-

开发人员可以在Windows工作台中进行程序开发,或者远程登录到Linux服务器进行程序开发。

-

Windows工作台

-

操作系统

-

Windows XP/Windows7/Windows10

-
- diff --git "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260.md" "b/zh-cn/device-dev/quick-start/\346\246\202\350\277\260.md" index 426a8d9fbd55e2545bda64c889619c160e561059..32de2be933c176263c569c82662acf43a574ba93 100644 --- "a/zh-cn/device-dev/quick-start/\346\246\202\350\277\260.md" +++ "b/zh-cn/device-dev/quick-start/\346\246\202\350\277\260.md" @@ -1,4 +1,4 @@ -# 概述 +# 概述 OpenHarmony轻量和小型系统适用于内存较小的IOT设备,本文选取了三款典型开发板:Hi3861 WLAN模组、Hi3516DV300、Hi3518EV300,并基于上述三款开发板进行开发介绍。 diff --git "a/zh-cn/device-dev/quick-start/\347\216\257\345\242\203\346\220\255\345\273\272.md" "b/zh-cn/device-dev/quick-start/\347\216\257\345\242\203\346\220\255\345\273\272.md" deleted file mode 100644 index 299cbb9c175b6842abb2c36091dab1a64049a70d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\347\216\257\345\242\203\346\220\255\345\273\272.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 环境搭建 - -- **[概述](概述-8.md)** - -- **[Windows开发环境准备](Windows开发环境准备-9.md)** - -- **[Ubuntu编译环境准备](Ubuntu编译环境准备-10.md)** - -- **[常见问题](常见问题-11.md)** - - diff --git "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-4.md" "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-4.md" deleted file mode 100755 index 6e33d9e8e9014487b3a4f82893d3ef1e61fa22ef..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-4.md" +++ /dev/null @@ -1,264 +0,0 @@ -# 运行Hello OHOS - -- [新建应用程序](#section1550972416485) -- [编译](#section234175193114) -- [烧录](#section7609155824819) -- [镜像运行](#section17612105814480) -- [下一步学习](#section9712145420182) - -本节指导开发者在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello OHOS!”。 - -## 新建应用程序 - -1. 新建目录及源码 - - 新建**applications/sample/camera/apps/src/helloworld.c**目录及文件,代码如下所示,用户可以自定义修改打印内容(例如:修改OHOS为World)。当前应用程序可支持标准C及C++的代码开发。 - - ``` - #include - - int main(int argc, char **argv) - { - printf("\n************************************************\n"); - printf("\n\t\tHello OHOS!\n"); - printf("\n************************************************\n\n"); - - return 0; - } - ``` - -2. 新建编译组织文件 - - 新建**applications/sample/camera/apps/BUILD.gn**文件,内容如下所示: - - ``` - import("//build/lite/config/component/lite_component.gni") - lite_component("hello-OHOS") { - features = [ ":helloworld" ] - } - executable("helloworld") { - output_name = "helloworld" - sources = [ "src/helloworld.c" ] - include_dirs = [] - defines = [] - cflags_c = [] - ldflags = [] - } - ``` - -3. 添加新组件 - - 修改文件**build/lite/components/applications.json**,添加组件hello\_world\_app的配置,如下所示为applications.json文件片段,"\#\#start\#\#"和"\#\#end\#\#"之间为新增配置("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): - - ``` - { - "components": [ - { - "component": "camera_sample_communication", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/communication" - ], - "targets": [ - "//applications/sample/camera/communication:sample" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##start## - { - "component": "hello_world_app", - "description": "Communication related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/apps" - ], - "targets": [ - "//applications/sample/camera/apps:hello-OHOS" - ], - "rom": "", - "ram": "", - "output": [], - "adapted_kernel": [ "liteos_a" ], - "features": [], - "deps": { - "components": [], - "third_party": [] - } - }, - ##end## - { - "component": "camera_sample_app", - "description": "Camera related samples.", - "optional": "true", - "dirs": [ - "applications/sample/camera/launcher", - "applications/sample/camera/cameraApp", - "applications/sample/camera/setting", - "applications/sample/camera/gallery", - "applications/sample/camera/media" - ], - ``` - -4. 修改单板配置文件 - - 修改文件**vendor/hisilicon/hispark\_aries/config.json**,新增hello\_world\_app组件的条目,如下所示代码片段为applications子系统配置,"\#\#start\#\#"和"\#\#end\#\#"之间为新增条目("\#\#start\#\#"和"\#\#end\#\#"仅用来标识位置,添加完配置后删除这两行): - - ``` - { - "subsystem": "applications", - "components": [ - ##start## - { "component": "hello_world_app", "features":[] }, - ##end## - { "component": "camera_sample_app", "features":[] } - - ] - }, - ``` - - -## 编译 - -如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/获取工具.md)的编译操作。如果Linux编译环境通过软件包方式安装,进入源码根目录,执行如下命令进行编译: - -``` -hb set(设置编译路径) -.(选择当前路径) -选择ipcamera_hispark_aries@hisilicon并回车 -hb build -f(执行编译) -``` - -结果文件生成在out/hispark\_aries/ipcamera\_hispark\_aries目录下。 - -**图 1** 设置图例 -![](figures/设置图例-4.png "设置图例-4") - ->![](public_sys-resources/icon-notice.gif) **须知:** ->Hi3518EV300单板的U-boot文件获取路径:device/hisilicon/hispark\_aries/sdk\_liteos/uboot/out/boot/u-boot-hi3518ev300.bin - -## 烧录 - -Hi3518开发板的代码烧录仅支持USB烧录方式。 - -1. 请连接好电脑和待烧录开发板,以Hi3518EV300为例,需要同时连接串口和USB口,具体可参考[Hi3518开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_camera_start_hi3518-0000001050170473)。 -2. 打开电脑的设备管理器,查看并记录对应的串口号。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - - ![](figures/zh-cn_image_0000001073057176.png) - -3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - - ![](figures/zh-cn_image_0000001077956808.png) - -4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3518系列开发板进行适配,无需单独修改。 -5. 在“hi3518ev300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 - - - upload\_port:选择步骤[2](#zh-cn_topic_0000001057313128_li46411811196)中查询的串口号。 - - upload\_protocol:选择烧录协议,固定选择“hiburn-usb”。 - - upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。 - - ![](figures/zh-cn_image_0000001096963405.png) - -6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 -7. 打开工程文件,点击![](figures/2021-01-27_170334-5.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3518ev300\_fastboot下的**Erase**按钮,擦除U-Boot。 - - ![](figures/2021-01-27_181047.png) - - ![](figures/zh-cn_image_0000001163529159.png) - -8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(下电再上电)。 - - ![](figures/zh-cn_image_0000001078089378.png) - -9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。 - - ![](figures/zh-cn_image_0000001073835952.png) - -10. 擦除完成后,点击hi3518ev300下的**Upload**按钮,启动烧录。 - - ![](figures/zh-cn_image_0000001163568181.png) - -11. 启动烧录后,界面提示如下信息时,表示烧录成功。 - - ![](figures/zh-cn_image_0000001073242197.png) - - -## 镜像运行 - -1. 连接串口。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >若无法连接串口,请参考[常见问题](../quick-start/常见问题-5.md)进行排查。 - - **图 2** 连接串口图 - - - ![](figures/chuankou1-6.png) - - 1. 单击**Monitor**打开串口。 - 2. 连续输入回车直到串口显示"hisilicon"。 - 3. 单板初次启动或修改启动参数,请进入[步骤2](#li9441185382314),否则进入[步骤3](#li6442853122312)。 - -2. (初次烧写必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,可保存执行结果,但U-boot重新烧入,则需要再次执行下述步骤。 - - **表 1** U-boot修改命令 - - - - - - - - - - - - - - - - - - - - - - -

执行命令

-

命令解释

-

setenv bootcmd "sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000";

-

设置bootcmd内容,选择FLASH器件0,读取FLASH起始地址为0x100000,大小为0x600000字节的内容到0x40000000的内存地址,此处0x600000为6MB,与IDE中填写OHOS_Image.bin的文件大小必须相同

-

setenv bootargs "console=ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7M rootsize=8M";

-

表示设置bootargs参数为串口输出,波特率为115200,数据位8,rootfs挂载于FLASH上,文件系统类型为jffs2 rw,以支持可读写JFFS2文件系统。“rootaddr=7M rootsize=8M”处对应填入实际rootfs.img的烧写起始位置与长度,与IDE内所填大小必须相同

-

saveenv

-

表示保存当前配置。

-

reset

-

表示复位单板。

-

pri

-

表示查看显示参数。

-
- - >![](public_sys-resources/icon-notice.gif) **须知:** - >**“go 0x40000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。 - -3. 若启动时显示**"hisilicon \#**字样,请输入**“reset”**指令,等待系统自启动进入系统,系统启动后,显示**“OHOS”**字样,输入**”./bin/helloworld”**并回车,显示成功结果如下图所示。 - - **图 3** 启动成功并执行应用程序图 - ![](figures/启动成功并执行应用程序图.png "启动成功并执行应用程序图") - - -## 下一步学习 - -恭喜您,已完成Hi3518的快速上手!建议您下一步进入[无屏摄像头产品开发](../guide/摄像头控制.md)的学习 。 - diff --git "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-5.md" "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-5.md" index c0146d09136cde8e590603813306b64ed1ec961f..51873c97ac3662e15356d6350e6da77ed10fc7c0 100644 --- "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-5.md" +++ "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS-5.md" @@ -1,4 +1,4 @@ -# 运行Hello OHOS +# 运行Hello OHOS - [新建应用程序](#section1550972416485) - [编译](#section234175193114) @@ -128,7 +128,7 @@ ## 编译 -如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/获取工具.md)的编译操作。如果Linux编译环境通过软件包方式安装,进入源码根目录,执行如下命令进行编译: +如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/Docker编译环境.md)的编译操作。如果Linux编译环境通过软件包方式安装,进入源码根目录,执行如下命令进行编译: ``` hb set(设置编译路径) @@ -149,17 +149,17 @@ hb build -f(执行编译) Hi3518开发板的代码烧录仅支持USB烧录方式。 -1. 请连接好电脑和待烧录开发板,以Hi3518EV300为例,需要同时连接串口和USB口,具体可参考[Hi3518开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_camera_start_hi3518-0000001050170473)。 +1. 请连接好电脑和待烧录开发板,以Hi3518EV300为例,需要同时连接串口和USB口,具体可参考[Hi3518开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3518-0000001105201138)。 2. 打开电脑的设备管理器,查看并记录对应的串口号。 >![](public_sys-resources/icon-note.gif) **说明:** >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - ![](figures/zh-cn_image_0000001073057176.png) + ![](figures/zh-cn_image_0000001128470900.png) 3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 - ![](figures/zh-cn_image_0000001077956808.png) + ![](figures/zh-cn_image_0000001174350649.png) 4. 在“Partition Configuration”页签,设置待烧录文件信息,默认情况下,DevEco Device Tool已针对Hi3518系列开发板进行适配,无需单独修改。 5. 在“hi3518ev300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 @@ -168,28 +168,28 @@ Hi3518开发板的代码烧录仅支持USB烧录方式。 - upload\_protocol:选择烧录协议,固定选择“hiburn-usb”。 - upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。 - ![](figures/zh-cn_image_0000001096963405.png) + ![](figures/zh-cn_image_0000001128311090.png) 6. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 7. 打开工程文件,点击![](figures/2021-01-27_170334-5.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3518ev300\_fastboot下的**Erase**按钮,擦除U-Boot。 - ![](figures/zh-cn_image_0000001163529159.png) + ![](figures/zh-cn_image_0000001174270731.png) 8. 执行**Erase**擦除操作后,显示如下提示信息时,请重启开发板(下电再上电)。 - ![](figures/zh-cn_image_0000001078089378.png) + ![](figures/zh-cn_image_0000001128311092.png) 9. 重新上电后,显示如下信息时,表示擦除U-Boot成功。 - ![](figures/zh-cn_image_0000001073835952.png) + ![](figures/zh-cn_image_0000001128311094.png) 10. 擦除完成后,点击hi3518ev300下的**Upload**按钮,启动烧录。 - ![](figures/zh-cn_image_0000001163568181.png) + ![](figures/zh-cn_image_0000001174350641.png) 11. 启动烧录后,界面提示如下信息时,表示烧录成功。 - ![](figures/zh-cn_image_0000001073242197.png) + ![](figures/zh-cn_image_0000001174350643.png) ## 镜像运行 diff --git "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS.md" "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS.md" index 68de0b2b57b40a4f61aaebfbe2a3ec50870bb9e2..d5f775c64f385feec6cdc67c211ee5978397aca7 100755 --- "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS.md" +++ "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-OHOS.md" @@ -1,4 +1,4 @@ -# 运行Hello OHOS +# 运行Hello OHOS - [新建应用程序](#section204672145202) - [编译](#section1077671315253) @@ -129,7 +129,7 @@ ## 编译 -如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/获取工具.md)的编译操作。如果Linux编译环境通过软件包方式安装,请进入源码根目录,执行如下命令进行编译: +如果Linux编译环境通过Docker方式安装,具体编译过程请参见[Docker方式获取编译环境](../get-code/Docker编译环境.md)的编译操作。如果Linux编译环境通过软件包方式安装,请进入源码根目录,执行如下命令进行编译: ``` hb set(设置编译路径) @@ -150,13 +150,13 @@ hb build -f(执行编译) Hi3516开发板的代码烧录支持USB烧录、网口烧录和串口烧录三种方式。此处仅以网口烧录为例进行说明。 -1. 请连接好电脑和待烧录开发板,以Hi3516DV300为例,需要同时连接串口、网口和电源,具体可参考[Hi3516开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_camera_start_3516-0000001052670587)。 +1. 请连接好电脑和待烧录开发板,以Hi3516DV300为例,需要同时连接串口、网口和电源,具体可参考[Hi3516开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3516-0000001152041033)。 2. 打开电脑的设备管理器,查看并记录对应的串口号。 >![](public_sys-resources/icon-note.gif) **说明:** >如果对应的串口异常,请根据[Hi3516/Hi3518系列开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 - ![](figures/zh-cn_image_0000001114129428.png) + ![](figures/zh-cn_image_0000001174350647.png) 3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 @@ -169,7 +169,7 @@ Hi3516开发板的代码烧录支持USB烧录、网口烧录和串口烧录三 - upload\_protocol:选择烧录协议,固定选择“hiburn-net”。 - upload\_partitions:选择待烧录的文件,默认情况下会同时烧录fastboot、kernel、rootfs和userfs。 - ![](figures/zh-cn_image_0000001160529355.png) + ![](figures/zh-cn_image_0000001128470904.png) 6. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/ide/user-guides/set_ipaddress-0000001141825075)。 7. 设置网口烧录的IP地址信息,设置如下选项: @@ -179,20 +179,20 @@ Hi3516开发板的代码烧录支持USB烧录、网口烧录和串口烧录三 - upload\_net\_client\_gw:设置开发板的网关,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.1 - upload\_net\_client\_ip:设置开发板的IP地址,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.3 - ![](figures/zh-cn_image_0000001117463460.png) + ![](figures/zh-cn_image_0000001174270733.png) 8. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 9. 打开工程文件,点击![](figures/2021-01-27_170334-2.png)图标,打开DevEco Device Tool界面,在“PROJECT TASKS”中,点击hi3516dv300下的**Upload**按钮,启动烧录。 - ![](figures/zh-cn_image_0000001116405268.png) + ![](figures/zh-cn_image_0000001174270729.png) 10. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。 - ![](figures/zh-cn_image_0000001114129432.png) + ![](figures/zh-cn_image_0000001128470906.png) 11. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 - ![](figures/zh-cn_image_0000001113969542.png) + ![](figures/zh-cn_image_0000001128311098.png) ## 镜像运行 diff --git "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-World.md" "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-World.md" index 74887e1fd4aa4672b99a9e4dd23ec41c644c649b..f428ec411ee4fc51d1be00be263867d1f8f8dc74 100755 --- "a/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-World.md" +++ "b/zh-cn/device-dev/quick-start/\350\277\220\350\241\214Hello-World.md" @@ -1,4 +1,4 @@ -# 运行Hello World +# 运行Hello World - [修改源码](#section79601457101015) - [调测验证](#section1621064881419) @@ -137,7 +137,7 @@ Call Stack 6 -- 3f5e24 addr:f78fc 3. 根据以上调用栈信息,可以定位WadRecvCB函数中出现了异常。 - ![](figures/zh-cn_image_0000001152256221.png) + ![](figures/zh-cn_image_0000001174270737.png) 4. 完成代码排查及修改。 diff --git "a/zh-cn/device-dev/quick-start/\351\225\234\345\203\217\347\203\247\345\275\225.md" "b/zh-cn/device-dev/quick-start/\351\225\234\345\203\217\347\203\247\345\275\225.md" new file mode 100644 index 0000000000000000000000000000000000000000..3cdd45fd692253fe9fc9ee2c0bfae17974a87756 --- /dev/null +++ "b/zh-cn/device-dev/quick-start/\351\225\234\345\203\217\347\203\247\345\275\225.md" @@ -0,0 +1,68 @@ +# 镜像烧录 + +- [下一步](#section5600113114323) + +标准系统烧录,在V2.2 Beta1及以上版本支持。 + +Hi3516DV300支持烧录标准系统,其烧录方式包括USB烧录、网口烧录和串口烧录三种方式,其中: + +- **Windows系统:支持网口烧录和串口烧录** +- **Linux系统:支持串口烧录和网口烧录。如果采用的是Linux+Windows双系统,也支持USB烧录。** + +同一种烧录方式(如网口烧录),在Windows和Linux环境下的烧录操作完全一致,区别仅在于DevEco Device Tool环境搭建不同。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>当前Hi3516DV300开发板支持通过网口、USB、串口三种方式烧录OpenHarmony标准系统。本文以网口方式为例讲解烧录操作,其他两种烧录方式请参照[Hi3516DV300烧录指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_upload-0000001052148681)。 + +### 前提条件 + +在DevEco Device Tool中[打开一个工程](https://device.harmonyos.com/cn/docs/ide/user-guides/open_project-0000001071680043),该工程文件夹选择待烧录文件所在文件夹即可。其中开发板类型固定选择Hi3516DV300,Framework选择“Hb”。 + +### 使用网口烧录 + +Hi3516DV300开发板使用网口录方式,支持Windows和Linux系统。 + +1. 请连接好电脑和待烧录开发板,需要同时连接串口、网口和电源,具体可参考[Hi3516DV300开发板介绍](https://device.harmonyos.com/cn/docs/start/introduce/oem_minitinier_des_3516-0000001152041033)。 +2. 打开电脑的设备管理器,查看并记录对应的串口号。 + + >![](public_sys-resources/icon-note.gif) **说明:** + >如果对应的串口异常,请根据[Hi3516DV300/Hi3518EV300开发板串口驱动安装指导](https://device.harmonyos.com/cn/docs/ide/user-guides/hi3516_hi3518-drivers-0000001050743695)安装USB转串口的驱动程序。 + + ![](figures/zh-cn_image_0000001114129428.png) + +3. 打开DevEco Device Tool,在Projects中,点击**Settings**打开工程配置界面。 + + ![](figures/2021-01-27_170334-17.png) + +4. 在“hi3516dv300”页签,设置烧录选项,包括upload\_port、upload\_partitions和upload\_protocol。 + + - upload\_port:选择步骤[2](#zh-cn_topic_0000001056443961_li1050616379507)中查询的串口号。 + - upload\_protocol:选择烧录协议,固定选择“hiburn-net”。 + - upload\_partitions:选择待烧录的文件,包括fastboot、boot、updater、misc、system、vendor和userdata。 + + ![](figures/zh-cn_image_0000001117621400.png) + +5. 检查和设置连接开发板后的网络适配器的IP地址信息,设置方法请参考[设置Hi3516DV300网口烧录的IP地址信息](https://device.harmonyos.com/cn/docs/ide/user-guides/set_ipaddress-0000001141825075)。 +6. 设置网口烧录的IP地址信息,设置如下选项: + + - upload\_net\_server\_ip:选择[6](#zh-cn_topic_0000001056443961.md#li1558813168234)中设置的IP地址信息。例如192.168.1.2 + - upload\_net\_client\_mask:设置开发板的子网掩码,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如255.255.255.0 + - upload\_net\_client\_gw:设置开发板的网关,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.1 + - upload\_net\_client\_ip:设置开发板的IP地址,工具会自动根据选择的upload\_net\_server\_ip进行设置。例如192.168.1.3 + + ![](figures/zh-cn_image_0000001117463460.png) + +7. 所有的配置都修改完成后,在工程配置页签的顶部,点击**Save**进行保存。 +8. 启动烧录后,显示如下提示信息时,请重启开发板(下电再上电)。 + + ![](figures/zh-cn_image_0000001114129432.png) + +9. 重新上电后,启动烧录,界面提示如下信息时,表示烧录成功。 + + ![](figures/zh-cn_image_0000001113969542.png) + + +## 下一步 + +恭喜!您已经完成了OpenHarmony标准系统的快速入门,接下来可[开发一个小示例](../guide/时钟应用开发指导.md),进一步熟悉OpenHarmony的开发。 + diff --git "a/zh-cn/device-dev/quick-start/\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" "b/zh-cn/device-dev/quick-start/\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" index ae2c5d1108fb1ba6469b6fc18543567b2208bb6c..dccca07b7f8417364e019cb1a5ee9484d06a9567 100755 --- "a/zh-cn/device-dev/quick-start/\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" +++ "b/zh-cn/device-dev/quick-start/\351\251\261\345\212\250\345\274\200\345\217\221\347\244\272\344\276\213.md" @@ -1,4 +1,4 @@ -# 驱动开发示例 +# 驱动开发示例 - [驱动程序介绍](#s8efc1952ebfe4d1ea717182e108c29bb) - [编译和烧写](#section660016185110) @@ -439,7 +439,7 @@ 1. 单击**Monitor**打开串口。 2. 连续输入回车直到串口显示"hisilicon"。 - 3. 单板初次启动或修改启动参数,请进入[步骤2](运行Hello-OHOS.md#l5b42e79a33ea4d35982b78a22913b0b1),否则进入[步骤3](运行Hello-OHOS.md#ld26f18828aa44c36bfa36be150e60e49)。 + 3. 单板初次启动或修改启动参数,请进入[步骤2](运行Hello-OHOS.md#zh-cn_topic_0000001151888681_l5b42e79a33ea4d35982b78a22913b0b1),否则进入[步骤3](运行Hello-OHOS.md#zh-cn_topic_0000001151888681_ld26f18828aa44c36bfa36be150e60e49)。 2. (单板初次启动必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,若不修改参数只需执行一次。每次复位单板均会自动进入系统。 diff --git a/zh-cn/device-dev/subsystems/DFX.md b/zh-cn/device-dev/subsystems/DFX.md index e5f00a7203adb883c359ee2b11eb1b56c60d7173..19ebb4af3e1e27ecfd86d3f27e8a0f36fb1f8c24 100755 --- a/zh-cn/device-dev/subsystems/DFX.md +++ b/zh-cn/device-dev/subsystems/DFX.md @@ -8,4 +8,10 @@ - **[HiSysEvent开发指导](HiSysEvent开发指导.md)** +- **[HiSysEvent订阅指导](HiSysEvent订阅指导.md)** + +- **[HiSysEvent查询指导](HiSysEvent查询指导.md)** + +- **[HiSysEvent工具使用指导](HiSysEvent工具使用指导.md)** + diff --git "a/zh-cn/device-dev/subsystems/HiSysEvent\345\267\245\345\205\267\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/HiSysEvent\345\267\245\345\205\267\344\275\277\347\224\250\346\214\207\345\257\274.md" new file mode 100644 index 0000000000000000000000000000000000000000..be8ad760312d39c508b8c17465b51efa1aae8dd2 --- /dev/null +++ "b/zh-cn/device-dev/subsystems/HiSysEvent\345\267\245\345\205\267\344\275\277\347\224\250\346\214\207\345\257\274.md" @@ -0,0 +1,33 @@ +# HiSysEvent工具使用指导 + +- [概述](#section1886702718521) +- [使用指导](#section1210623418527) + +## 概述 + +目前系统预制了hisysevent小工具,用于条件查询系统所有的hisysevent事件。 + +## 使用指导 + +1. hisysevent工具的参数: + + hisysevent \[-r | -l \[-s -e -m \]\] + + -r get real hisysevent log. + + -l -s -e -m + + get history hisysevent log, begin time should not be earlier than end time. + +2. 查询实时hisysevent的命令: + + hisysevent -r + + 当实时hisysevent事件过来的时候,会在控制台上打印一条hisysevent事件。 + +3. 查询历史hisysevent的命令: hisysevent -l -s -e -m + +其中-s和-e分别指定了事件生成的开始时间和结束时间,如果没有-s或者-e,代表查询时间无下限/无上限。 + +-m参数制定了本次查询最多返回的时间条数。 + diff --git "a/zh-cn/device-dev/subsystems/HiSysEvent\346\237\245\350\257\242\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/HiSysEvent\346\237\245\350\257\242\346\214\207\345\257\274.md" new file mode 100644 index 0000000000000000000000000000000000000000..162ee89bef1e5cb627fdc5125e82beae6ab14235 --- /dev/null +++ "b/zh-cn/device-dev/subsystems/HiSysEvent\346\237\245\350\257\242\346\214\207\345\257\274.md" @@ -0,0 +1,109 @@ +# HiSysEvent查询指导 + +- [概述](#section279684125212) +- [接口说明](#section03869128521) +- [开发实例](#section14286111855212) + +## 概述 + +HiSysEvent提供了查询接口,用户查询当前所有的HISysEvent事件。 + +## 接口说明 + +**表 1** HiSysEvent查询接口 + + + + + + + + + + + + + + + + +

接口名

+

描述

+

boolean ISysEventService::QuerySysEvent(in long beginTime, in long endTime, in int maxEvents, in SysEventQueryRule[] rules, in IQuerySysEventCallback callback);

+

接口功能:订阅HiSysEvent事件。

+

输入参数:

+
  • beginTime:事件开始时间。
  • endTime:时间结束事件
  • rules:时间过滤规则
  • callback:查询接口回调对象
+

返回值:

+
  • true:查询成功
  • false:查询失败
+

void IQuerySysEventCallback::OnQuery(in String[] sysEvent, in long[] seq)

+

接口功能:订阅事件查询中的回调。

+

输入参数:

+
  • sysEvent:返回时间集合
  • seq:事件序列集合
+

返回值:无。

+

void IQuerySysEventCallback::OnComplete(in int reason, in int total)

+

接口功能:订阅事件查询完成的回调。

+

输入参数:

+
  • reason:查询结束返回原因,目前默认是0
  • total:本次查询总共返回的事件总数量
+

返回值:无。

+
+ +**表 2** SysEventQueryRule订阅规则对象 + + + + + + + + + + + + + + + + +

属性名称

+

描述

+

uint32_t ruleType

+

规则类型,目前默认是0

+

std::string domain;

+
  • domain:事件所属领域,如果传入的是空字符串,则默认事件领域字段匹配成功
+

std::string eventName

+
  • eventName:事件的名称,如果传入的是空字符串,则默认事件名称字段匹配成功
+
+ +## 开发实例 + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventQueryRule.aidl、IQuerySysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象:在查询过程中,会遍历回调OnQuery\(\)接口;在查询结束后,会回调OnComplete\(\)接口 + + IQuerySysEventCallback::OnQuery\(in String\[\] sysEvent, in long\[\] seq\) + + IQuerySysEventCallback::OnComplete\(in int reason, in int total\) + + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventQueryRule.aidl、IQuerySysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象:在查询过程中,会遍历回调OnQuery\(\)接口;在查询结束后,会回调OnComplete\(\)接口 + + IQuerySysEventCallback::OnQuery\(in String\[\] sysEvent, in long\[\] seq\) + + IQuerySysEventCallback::OnComplete\(in int reason, in int total\) + +2. 编译设置: + +在编译子系统里面,需要依赖libbinder模块 + +aosp\_deps = \[ "shared\_library:libbinder", \] + diff --git "a/zh-cn/device-dev/subsystems/HiSysEvent\350\256\242\351\230\205\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/HiSysEvent\350\256\242\351\230\205\346\214\207\345\257\274.md" new file mode 100644 index 0000000000000000000000000000000000000000..beff2dfaa71be287e98bf1c668b0b59179cd17f8 --- /dev/null +++ "b/zh-cn/device-dev/subsystems/HiSysEvent\350\256\242\351\230\205\346\214\207\345\257\274.md" @@ -0,0 +1,98 @@ +# HiSysEvent订阅指导 + +- [概述](#section315316685112) +- [接口说明](#section0342191810519) +- [开发实例](#section123181432175110) + +## 概述 + +HiSysEvent提供了跨进程订阅机制,用户可以通过注册订阅接口。 + +## 接口说明 + +**表 1** HiSysEvent订阅接口 + + + + + + + + + + + + + +

接口名

+

描述

+

int ISysEventService::AddListener(in SysEventRule[] rules, in ISysEventCallback callback)

+

接口功能:订阅HiSysEvent事件。

+

输入参数:

+
  • rules:事件订阅规则
  • callback:订阅回调对象
+

返回值:

+
  • 0:订阅成功,重复订阅
  • 1:订阅成功,初次订阅
  • 其他返回值:订阅失败
+

void ISysEventCallback::Handle(in String domain, in String eventName, in int eventType, in String eventDetail)

+

接口功能:订阅事件的回调接口。

+

输入参数:

+
  • domain:事件所属领域
  • eventName:事件的名称
  • eventType:事件类型
  • eventDetail:包含事件相关信息的字符串,以json的形式体现
+

返回值:无。

+
+ +**表 2** SysEventRule订阅规则对象 + + + + + + + + + + + + + + + + +

属性名称

+

描述

+

uint32_t ruleType

+

规则类型(匹配范围包括domain以及eventName):

+
  • 1:全字符匹配
  • 2:前缀匹配
  • 3:正则表达式匹配
  • 其他值:无效的匹配方式
+

std::string domain;

+
  • domain:事件所属领域,如果传入的是空字符串,则默认事件领域字段匹配成功
+

std::string eventName

+
  • eventName:事件的名称,如果传入的是空字符串,则默认事件名称字段匹配成功
+
+ +## 开发实例 + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventRule.aidl、ISysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象: + + ISysEventCallback::Handle\(in String domain, in String eventName, in int eventType, in String eventDetail\) + + +1. 源代码开发: + + 引入对应的aidl文件,包括:ISysEventService.aidl、SysEventRule.aidl、ISysEventCallback.aidl。 + + 在相应的业务逻辑里面调用ISysEventService::AddListener\(in SysEventRule\[\] rules, in ISysEventCallback callback\)接口。 + + 实现对应的回调对象: + + ISysEventCallback::Handle\(in String domain, in String eventName, in int eventType, in String eventDetail\) + +2. 编译设置: + +在编译子系统里面,需要依赖libbinder模块 + +aosp\_deps = \[ "shared\_library:libbinder", \] + diff --git "a/zh-cn/device-dev/subsystems/IPC\351\200\232\344\277\241\351\211\264\346\235\203\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/IPC\351\200\232\344\277\241\351\211\264\346\235\203\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index a0c52fc9c75746a7a9da6e4d5d862354f94f30dd..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/IPC\351\200\232\344\277\241\351\211\264\346\235\203\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,139 +0,0 @@ -# IPC通信鉴权开发指导 - -- [场景介绍](#section18502174174019) -- [接口说明](#section1633115419401) -- [开发步骤](#section022611498210) -- [常见问题](#section15729104510271) - -## 场景介绍 - -系统服务通过IPC跨进程方式开放的接口,需要对接口调用者进行鉴权操作。在Samgr中注册的系统服务,可以通过进程间通信的方式暴露接口给其他进程访问,同时需要配置相应的访问策略,当其他进程访问这些接口时,将会触发IPC通信鉴权机制校验访问进程是否拥有权限访问该接口,若无权限,则访问会被拒绝。 - -当开发一个系统服务时,如果需要对外开放某些接口,开发者可以通过IPC通信鉴权组件配置这些接口的访问策略。当其他服务通过IPC方式访问这些接口时,会触发Samgr服务调用IPC通信鉴权组件的接口检查调用者服务是否有权限调用该接口。 - -## 接口说明 - -IPC通信鉴权提供的API,仅供Samgr调用,开发者在开发服务时需要配置对应的访问策略,Samgr会调用如下接口获取和检查调用者是否具有正确的访问权限,提供的API列表如下。 - -**表 1** IPC通信鉴权API接口功能介绍 - - - - - - - - - - - - - -

接口名

-

描述

-

int GetCommunicationStrategy(RegParams params, PolicyTrans **policies, unsigned int *policyNum)

-

服务注册过程中查询调用接口对应的访问策略,仅供Samgr调用

-

int IsCommunicationAllowed(AuthParams params)

-

检查访问主体进程是否有权限调用受访客体进程的接口,仅供Samgr调用

-
- -## 开发步骤 - -本部分以BMS服务通过IPC通信方式对外开放接口为例,讲解如何通过IPC通信鉴权组件配置对应接口的访问策略。这里BMS在Samgr中注册的service为bundlems,为开放的接口注册的Feature为BmsFeature。 - -1. 在源码路径下的头文件base/security/permission/services/permission\_lite/ipc\_auth/include/policy\_preset.h中配置相应的访问策略,访问策略主要有三种类型: - - (1)type为RANGE类型:允许某个特定范围UID的进程访问,需要指定uidMin和uidMax; - - (2)type为FIXED类型:允许指定的几个UID的进程访问,需要指定fixedUid,最多配置8个; - - (3)type为BUNDLENAME类型:只允许特定的应用访问,需要指定bundleName(包名); - - ``` - FeaturePolicy bmsFeature[] = { - { - "BmsFeature", - { - { - .type=FIXED, // 允许指定UID的进程访问的方式 - .fixedUid={2, 3, 8} - }, - { - .type=RANGE, // 允许特定范围内的UID的进程访问的方式 - .uidMin=100, - .uidMax=__INT_MAX__, - }, - } - }, - { - "BmsInnerFeature", - { - { - .type=FIXED, // 允许指定UID的进程访问的方式 - .fixedUid={2, 3, 8} - }, - { - .type=RANGE, - .uidMin=100, - .uidMax=999, - }, - } - }, - }; - ``` - -2. 将步骤1中定义的Feature的策略加配到全局策略中,需要配置feature数量; - - ``` - static PolicySetting g_presetPolicies[] = { - {"permissionms", pmsFeature, 1}, - {"abilityms", amsFeature, 2}, - {"bundlems", bmsFeature, 2}, // 步骤1定义的BMS的feature,数量为2 - {"dtbschedsrv", dmsFeature, 1}, - {"samgr", samgrFeature, 1}, - {"appspawn", appspawnFeature, 1}, - {"WMS", wmsFeature, 1}, - {"bundle_daemon", bdsFeature, 1}, - }; - ``` - -3. 将步骤1中定义的BmsFeature注册到Samgr; - - ``` - const char BMS_SERVICE[] = "bundlems"; - const char BMS_FEATURE[] = "BmsFeature"; - static void Init() - { - SamgrLite *sm = SAMGR_GetInstance(); - if (sm == nullptr) { - return; - } - // 注册服务到Samgr - sm->RegisterFeature(BMS_SERVICE, reinterpret_cast(BundleMsFeature::GetInstance())); - sm->RegisterFeatureApi(BMS_SERVICE, BMS_FEATURE, - GetBmsFeatureApi(reinterpret_cast(BundleMsFeature::GetInstance()))); - HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS feature start success"); - } - APP_FEATURE_INIT(Init); - ``` - - -完成以上开发步骤后,开发者在Samgr注册服务时,Samgr会调用IPC通信鉴权组件的GetCommunicationStrategy接口获取服务的访问策略;当其他服务或应用通过IPC方式访问这些服务时,Samgr会调用IPC通信鉴权组件的IsCommunicationAllowed接口检查调用者服务的权限,如果满足访问策略,则可以访问开发者接口,否则拒绝访问。 - -## 常见问题 - -- 开发新服务后,在Samgr注册失败问题 - - **现象描述** - - 开发完新服务后,在启动时出现服务在Samgr注册失败问题。 - - **可能原因** - - 服务注册过程中,Samgr需要从IPC通信鉴权模块获取该服务的访问策略,但是未在该模块配置该服务的UID。 - - **解决办法** - - 在base/security/permission/services/permission\_lite/ipc\_auth/src/ipc\_auth\_impl.c中配置有效的服务的UID。 - - diff --git a/zh-cn/device-dev/subsystems/Readme-CN.md b/zh-cn/device-dev/subsystems/Readme-CN.md index a1c06756966a069dbf7a6b9c697d6c2fa2cb62c5..613d2a00644ec3ed1e48f47c43b94d7c02cc26d0 100755 --- a/zh-cn/device-dev/subsystems/Readme-CN.md +++ b/zh-cn/device-dev/subsystems/Readme-CN.md @@ -1,14 +1,8 @@ -# 子系统 +# 子系统开发指南 - [编译构建](编译构建.md) - - [轻量和小型系统编译构建指导](轻量和小型系统编译构建指导.md) - - [编译构建概述](编译构建概述.md) - - [编译构建使用指导](编译构建使用指导.md) - - [编译构建常见问题](编译构建常见问题.md) - - - [标准系统编译构建指导](标准系统编译构建指导.md) - - [编译构建概述](编译构建概述-0.md) - - [编译构建使用指导](编译构建使用指导-1.md) + - [编译构建子系统—轻量和小型系统](编译构建子系统-轻量和小型系统.md) + - [编译构建子系统—标准系统](编译构建子系统-标准系统.md) - [分布式远程启动](分布式远程启动.md) - [图形图像](图形图像.md) @@ -60,19 +54,11 @@ - [用户程序框架](用户程序框架.md) - [概述](概述.md) - - [搭建环境](搭建环境-2.md) - - [开发指导](开发指导-3.md) + - [搭建环境](搭建环境-0.md) + - [开发指导](开发指导-1.md) - [开发实例](开发实例.md) - [OTA升级](OTA升级.md) - -- [安全](安全.md) - - [概述](概述-7.md) - - [应用验签开发指导](应用验签开发指导.md) - - [应用权限管理开发指导](应用权限管理开发指导.md) - - [IPC通信鉴权开发指导](IPC通信鉴权开发指导.md) - - [可信设备群组管理开发指导](可信设备群组管理开发指导.md) - - [启动恢复](启动恢复.md) - [启动恢复子系统概述](启动恢复子系统概述.md) - [init启动引导组件](init启动引导组件.md) @@ -88,6 +74,9 @@ - [HiLog开发指导](HiLog开发指导.md) - [HiLog\_Lite开发指导](HiLog_Lite开发指导.md) - [HiSysEvent开发指导](HiSysEvent开发指导.md) + - [HiSysEvent订阅指导](HiSysEvent订阅指导.md) + - [HiSysEvent查询指导](HiSysEvent查询指导.md) + - [HiSysEvent工具使用指导](HiSysEvent工具使用指导.md) - [研发工具链](研发工具链.md) - [bytrace使用指导](bytrace使用指导.md) diff --git "a/zh-cn/device-dev/subsystems/SDK\345\274\200\345\217\221\350\277\207\347\250\213.md" "b/zh-cn/device-dev/subsystems/SDK\345\274\200\345\217\221\350\277\207\347\250\213.md" index 83d933cdb5df36058c1726de5d289c88a9fb2fbb..ed8f624d68c07f4791327fc7b161a793a07e54a8 100755 --- "a/zh-cn/device-dev/subsystems/SDK\345\274\200\345\217\221\350\277\207\347\250\213.md" +++ "b/zh-cn/device-dev/subsystems/SDK\345\274\200\345\217\221\350\277\207\347\250\213.md" @@ -126,8 +126,8 @@ SDK头文件的功能实现是基于对SDK的调用映射到对client的调用

long long clientVersion:客户端设备版本号(当前还未启用);

int clientId:客户端ID;

int sessionId:会话ID;

-

uid_t serverUid:server端UID;

-

uid_t clientUid:client端UID;

+

uid_t serverUid:server端UID;

+

uid_t clientUid:client端UID;

int extendLen:拓展信息(extendMsg)长度;

unsigned char *extendMsg:拓展信息主体;

diff --git "a/zh-cn/device-dev/subsystems/XTS\350\256\244\350\257\201\345\255\220\347\263\273\347\273\237\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/zh-cn/device-dev/subsystems/XTS\350\256\244\350\257\201\345\255\220\347\263\273\347\273\237\345\274\200\345\217\221\346\214\207\345\215\227.md" index b5e511362a0ef107beff73f3fb82f98c8a590487..fd5e4d1da7a25a06392d621eab84f4436fb2559e 100755 --- "a/zh-cn/device-dev/subsystems/XTS\350\256\244\350\257\201\345\255\220\347\263\273\347\273\237\345\274\200\345\217\221\346\214\207\345\215\227.md" +++ "b/zh-cn/device-dev/subsystems/XTS\350\256\244\350\257\201\345\255\220\347\263\273\347\273\237\345\274\200\345\217\221\346\214\207\345\215\227.md" @@ -12,7 +12,10 @@ - [C++语言用例执行指导(适用于小型系统、标准系统用例开发)](#section128222336544) - [JS语言用例开发指导(适用于标准系统)](#section159801435165220) - [JS语言用例编译打包指导(适用于标准系统)](#section445519106559) + - [\#ZH-CN\_TOPIC\_0000001126156429/section191521423950](#section191521423950) +- [全量编译指导(适用于标准系统)](#section1519992743415) +- [全量用例执行指导(适用于小型系统、标准系统)](#section118149111426) ## 简介 @@ -646,3 +649,67 @@ OpenHarmony支持如下几种系统类型: hap包编译请参考[标准系统js应用开发指导](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_overview-0000001055075201)。 +## 全量编译指导(适用于标准系统) + +1. 全量编译 + + **命令**: + + ``` + ./build.sh suite=acts system_size=standard + ``` + + **测试用例输出目录**:out/release/suites/acts/testcases + + **测试框架&用例整体输出目录:**out/release/suites/acts(编译用例时会同步编译测试套执行框架) + + +## 全量用例执行指导(适用于小型系统、标准系统) + +**搭建测试环境** + +Windows工作台下安装python3.7及以上版本,确保工作台和测试设备正常连接。 + +**测试执行目录**(对应编译生成的out/release/suites/acts目录) + +``` +├── testcase # 测试套文件存放目录 +│ └──xxx.hap # 测试套可执行hap文件 +│ └──xxx.json # 测试套对应执行配置文件 +├── tools # 测试框架工具目录 +├── run.bat # window平台测试套启动执行文件 +├── report # 测试报告生成目录 +``` + +**用例执行** + +1. 在Windows工作台上,找到从Linux服务器上拷贝下来的测试套件用例目录,在Windows命令窗口进入对应目录,直接执行acts\\run.bat。 + +1. 界面启动后,输入用例执行指令。 + + - 全量执行 + + ``` + run acts + ``` + + ![](figures/zh-cn_image_0000001119924146.gif) + + + - 模块执行\(具体模块可以查看\\acts\\testcases\\\) + + ``` + run –l ActsSamgrTest + ``` + + ![](figures/zh-cn_image_0000001166643927.jpg) + + + 等待执行完成。 + + +1. 查看测试报告。 + + 进入acts\\reports\\,获取当前的执行记录,打开“summary\_report.html”可以获取到测试报告。 + + diff --git "a/zh-cn/device-dev/subsystems/bytrace\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/bytrace\344\275\277\347\224\250\346\214\207\345\257\274.md" index 3933aebf5e5206f7b3c2aaa1f1a8e3d587e43d33..2c443396aca58e31aa099a8de06db028781c7fdd 100644 --- "a/zh-cn/device-dev/subsystems/bytrace\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ "b/zh-cn/device-dev/subsystems/bytrace\344\275\277\347\224\250\346\214\207\345\257\274.md" @@ -1,18 +1,14 @@ # bytrace使用指导 - [简介](#section11388623181619) -- [命令行开发指导](#section1595564317164) - - [bytrace命令](#section2344125731617) - - [bytrace命令使用举例](#section5402591174) - +- [开发指导](#section1595564317164) +- [使用实例](#section667273201818) ## 简介 bytrace是开发人员用于追踪进程轨迹、分析性能的一种工具,主要对内核ftrace进行了封装和扩展,来支持用户态的打点。通过该工具可以打开想要查看的用户态和内核label(通过下面命令行bytrace -l,查看支持的所有label),然后通过命令行进行抓取trace信息到指定文件中。 -## 命令行开发指导 - -### bytrace命令 +## 开发指导 bytrace当前支持以下命令: @@ -83,7 +79,7 @@ bytrace当前支持以下命令: -### bytrace命令使用举例 +## 使用实例 以下是常用bytrace命令示例,供开发者参考: diff --git a/zh-cn/device-dev/subsystems/figures/RIL-Adapter.png b/zh-cn/device-dev/subsystems/figures/RIL-Adapter.png deleted file mode 100644 index eb3a5f511cb246a0c250a0dc76150b8816f4394b..0000000000000000000000000000000000000000 Binary files a/zh-cn/device-dev/subsystems/figures/RIL-Adapter.png and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/figures/\345\216\273\347\224\265.png" "b/zh-cn/device-dev/subsystems/figures/\345\216\273\347\224\265.png" deleted file mode 100755 index 6d8841ed7cd427e5f3d091f8d3261bc38c297bbf..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/subsystems/figures/\345\216\273\347\224\265.png" and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/figures/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" "b/zh-cn/device-dev/subsystems/figures/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" deleted file mode 100755 index 68b98482855637206e94bbd373623dc182a04474..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/subsystems/figures/\345\256\211\345\205\250\345\255\220\347\263\273\347\273\237.png" and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/figures/\346\235\245\347\224\265.png" "b/zh-cn/device-dev/subsystems/figures/\346\235\245\347\224\265.png" deleted file mode 100644 index f666f21d1575a00e928c99afb29a7aca8c26e641..0000000000000000000000000000000000000000 Binary files "a/zh-cn/device-dev/subsystems/figures/\346\235\245\347\224\265.png" and /dev/null differ diff --git "a/zh-cn/device-dev/subsystems/hdc_std-\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/hdc_std-\344\275\277\347\224\250\346\214\207\345\257\274.md" index d4993fb7b51791ca8bbd5af2aff43cf011ade64a..9b14f7c438af9810ff29a223f284eb0b102d4c85 100644 --- "a/zh-cn/device-dev/subsystems/hdc_std-\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ "b/zh-cn/device-dev/subsystems/hdc_std-\344\275\277\347\224\250\346\214\207\345\257\274.md" @@ -2,13 +2,40 @@ - [环境准备](#section05992022154916) - [注意事项](#section19543134915210) -- [全局option](#section618522925119) -- [查询设备列表](#section174891132104218) +- [全局option相关的命令](#section618522925119) + - [-h/help -v/version](#section51533527212) + - [-t key](#section1180555115159) + +- [查询设备列表的命令](#section174891132104218) + - [list targets\[-v\]](#section12911142313168) + - [服务进程相关命令](#section680531510497) + - [target mount](#section396717571168) + - [smode \[off\]](#section179951621713) + - [kill \[-r\]](#section419144621712) + - [start \[-r\]](#section184811812183) + - [网络相关的命令](#section71176123212) + - [tconn host\[:port\]\[-remove\]](#section191911334206) + - [tmode usb](#section17840182562015) + - [tmode port port-number](#section101113462113) + - [文件相关的命令](#section173133523013) + - [file send local remote](#section126223231307) + - [file recv \[-a\] remote local](#section26966541304) + - [应用相关的命令](#section2072647133819) + - [install \[-r/-d/-g\] package](#section49615195111) + - [uninstall \[-k\] package](#section167618461814) + - [调试相关的命令](#section112861250195015) + - [hilog](#section32171612221) + - [shell \[command\]](#section524235625) + +- [常见问题](#section592920255582) + - [hdc\_std连接不到设备](#section74019384588) + +- [hdc\_std运行不了](#section6825095917) hdc\_std(OpenHarmony Device Connector)是OpenHarmony为开发人员提供的用于调试的命令行工具,通过该工具可以在Windows/Linux等系统上与开发机或者模拟器进行交互。 @@ -28,15 +55,14 @@ hdc\_std(OpenHarmony Device Connector)是OpenHarmony为开发人员提供的 ## 注意事项 -1、使用hdc\_std,如果出现异常,可以尝试通过hdc\_std kill命令杀掉hdc\_std服务,或者通过hdc\_std start -r命令重启服务进程进行解决。 - -2、如果出现hdc\_std list targets获取不到设备信息,通过任务管理器查看是否有hdc.exe进程存在,如果进程存在,可以通过杀掉该进程进行解决。 +- 使用hdc\_std,如果出现异常,可以尝试通过hdc\_std kill命令杀掉hdc\_std服务,或者通过hdc\_std start -r命令重启服务进程进行解决。 +- 如果出现hdc\_std list targets获取不到设备信息,通过任务管理器查看是否有hdc.exe进程存在,如果进程存在,可以通过杀掉该进程进行解决。 -## 全局option +## 全局option相关的命令 全局option涉及以下命令: -- **-h/help -v/version** +### -h/help -v/version 用于显示hdc相关的帮助、版本信息。 @@ -72,7 +98,7 @@ hdc\_std -h / hdc\_std help hdc\_std -v / hdc\_std version -- **-t key** +### -t key 用于连接指定设备标识为key的设备。 @@ -115,11 +141,11 @@ hdc\_std -t _key_ shell (-t后面添加的_key_ 需要替换为上面 >![](public_sys-resources/icon-note.gif) **说明:** >一台开发机可支持多个设备连接,每个设备有其唯一的设备标识,如果通过网络与设备连接,其标识为tcp:port格式,如果通过usb连接则标识为设备sn号。该命令需要跟随具体操作命令。 -## 查询设备列表 +## 查询设备列表的命令 查询设备列表涉及以下命令: -**list targets\[-v\]** +### list targets\[-v\] 显示所有已经连接的目标设备列表 @@ -161,7 +187,7 @@ hdc\_std list targets -v 服务进程涉及以下命令: -- **target mount** +### target mount 以读写模式挂载/system等分区。 @@ -197,7 +223,7 @@ hdc\_std list targets -v hdc\_std target mount -- **smode \[off\]** +### smode \[off\] 授予后台服务进程root权限, 使用off参数取消授权。 @@ -207,7 +233,7 @@ hdc\_std smode hdc\_std smode off -- **kill \[-r\]** +### kill \[-r\] 终止服务进程。 @@ -243,7 +269,7 @@ hdc\_std smode off hdc\_std kill -- **start \[-r\]** +### start \[-r\] 启动服务进程。 @@ -281,7 +307,7 @@ hdc\_std start 网络部分涉及以下命令: -- **tconn _host_\[:_port_\]\[-remove\]** +### tconn _host_\[:_port_\]\[-remove\] 通过【ip地址:端口号】来指定连接的设备 @@ -322,7 +348,7 @@ hdc\_std start hdc\_std tconn 192.168.0.100:8710 -- **tmode usb** +### tmode usb 执行后设备端对应daemon进程重启,并首先选用usb连接方式。 @@ -358,7 +384,7 @@ hdc\_std tconn 192.168.0.100:8710 hdc\_std tmode usb -- **tmode port _port-number_** +### tmode port _port-number_ 执行后设备端对应daemon进程重启,并优先使用网络方式连接设备,如果连接设备再选择usb连接。 @@ -401,7 +427,7 @@ hdc\_std tmode port 8710 文件部分涉及以下命令: -- **file send _local remote_** +### file send _local remote_ 发送文件至远端设备。 @@ -442,7 +468,7 @@ hdc\_std tmode port 8710 hdc\_std file send E:\\a.txt /data/local/tmp/a.txt -- **file recv \[-a\] _remote local_** +### file recv \[-a\] _remote local_ 从远端设备接收文件至本地。 @@ -492,7 +518,7 @@ hdc\_std file recv /data/local/tmp/a.txt ./a.txt 应用部分涉及以下命令: -- **install \[-r/-d/-g\] _package_** +### install \[-r/-d/-g\] _package_ 安装OpenHarmony package。 @@ -543,7 +569,7 @@ hdc\_std file recv /data/local/tmp/a.txt ./a.txt hdc\_std install _hwadmin.hap_ -- **uninstall \[-k\] _package_** +### uninstall \[-k\] _package_ 卸载OpenHarmony应用。 @@ -588,7 +614,7 @@ hdc\_std uninstall _package_ 调试涉及以下命令: -- **hilog** +### hilog 支持抓取log信息。 @@ -622,7 +648,7 @@ hdc\_std uninstall _package_ hdc\_std hilog -- **shell \[_command_\]** +### shell \[_command_\] 远程执行命令或进入交互命令环境。 @@ -656,3 +682,37 @@ hdc\_std hilog hdc\_std shell +## 常见问题 + +### hdc\_std连接不到设备 + +- **现象描述** + + 执行 "hdc\_std list targets"命令后结果为:\[Empty\] + +- **解决方法** + 1. 设备没有被识别: + + 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 + + 2. hdc\_std工作异常: + + 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 + + 3. hdc\_std与设备不匹配: + + 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 + + + +## hdc\_std运行不了 + +- **现象描述** + + 点击hdc\_std.exe文件无法运行。 + +- **解决方法** + + hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 + + diff --git "a/zh-cn/device-dev/subsystems/hdc_std\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/zh-cn/device-dev/subsystems/hdc_std\345\270\270\350\247\201\351\227\256\351\242\230.md" deleted file mode 100644 index 3f83fba3e9943bb252fec4fc273a197c3fcd9ec7..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/hdc_std\345\270\270\350\247\201\351\227\256\351\242\230.md" +++ /dev/null @@ -1,39 +0,0 @@ -# hdc\_std常见问题 - -- [hdc\_std连接不到设备](#section1221016541119) -- [hdc\_std运行不了](#section219185710311) - -## hdc\_std连接不到设备 - -- **现象描述** - - 执行 "hdc\_std list targets"命令后结果为:\[Empty\] - -- **可能原因和解决方法** - 1. 设备没有被识别: - - 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 - - 2. hdc\_std工作异常: - - 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 - - 如果一直获取不到设备信息,请在任务管理器中查询是否有adb进程,该进程可能会对hdc产生干扰,可以将其杀掉后重复执行上面的步骤。 - - 3. hdc\_std与设备不匹配: - - 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 - - - -## hdc\_std运行不了 - -- **现象描述** - - 点击hdc\_std.exe文件无法运行。 - -- **可能原因和解决方法** - - hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 - - diff --git "a/zh-cn/device-dev/subsystems/\345\217\257\344\277\241\350\256\276\345\244\207\347\276\244\347\273\204\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\217\257\344\277\241\350\256\276\345\244\207\347\276\244\347\273\204\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index bf9fb41b5170c999b590ae30bfa2c91e1aaa2d30..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\217\257\344\277\241\350\256\276\345\244\207\347\276\244\347\273\204\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,264 +0,0 @@ -# 可信设备群组管理开发指导 - -- [场景介绍](#section18502174174019) -- [接口说明](#section1633115419401) -- [开发步骤](#section17516229192313) -- [调测验证](#section427316292411) - -## 场景介绍 - -当分布式业务需要利用软总线提供的设备间安全会话通信时,可以使用可信设备群组管理服务在设备间创建可信群组。在OpenHarmony下提供异账号下基于PIN、二维码、碰一碰等设备认证能力和同华为账号群组下的设备认证能力,分布式应用可基于该能力建立和使用设备间的安全可信关系。对于未登录华为账号的设备,可以通过PIN码输入、二维码扫描后获取的设备连接信息和PIN码信息,再通过可信设备群组管理提供的群组创建,群组成员添加,主动建立设备间可信关系;在有其它业务应用已经创建并分享了设备可信群组的情况下或者登录了相同的华为账号后,也可以通过可信设备群组管理提供的查询能力,复用这些可信群组。 - -## 接口说明 - -可信群组管理组件当前提供innerkits接口,仅供系统应用调用,相关接口及功能描述如下: - -**表 1** 群组管理器提供的JAVA API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

public static DeviceGroupManager getInstance(Abilityability, StringappID, IHichainGroupCallbackcallbackHandler)

-

获取群组管理的实例,并注册一个请求的listen回调。

-

int createGroup(String appId, String groupName, int groupType, String groupInfo)

-

创建一个可信群组。

-

public int deleteGroup(String gourpId)

-

删除一个可信群组。

-

public String getLocalConnectInfo()

-

获取本地设备的网络连接信息。

-

int addMemberToGroup(String appId, long requestId, String addParams, String connectParams, int groupType)

-

添加成员到指定群组ID的可信群组。

-

int deleteMemberFromGroup(String appId, long requestId, String deleteParams, String connectParams)

-

从指定群组里删除可信成员。

-

int cancelRequest(long requestId)

-

取消正在进行的请求,如添加成员,删除成员。

-

List<String> listJoinedGroups(int groupType)

-

查询指定群组类型下本设备加入的群组信息列表。

-

List<String> listTrustedDevices(String groupId)

-

查询指定群组里可信设备的信息列表。

-

boolean isDeviceInGroup(String groupId, String deviceId)

-

查询指定设备ID的设备是否加入了指定ID的群组。

-

List<String> getGroupInfo(String queryParams)

-

根据输入参数,查询符合条件的群组的信息列表。

-

int setFriendsList(String groupId, List<String> friendsList)

-

向指定ID的群组,添加群组访问的友元名单

-

List<String> getFriendsList(String groupId)

-

获取指定群组里的友元名单

-

int registerGroupNotice(String groupId, IHichainGroupChangeListener groupChangeListener)

-

注册指定群组发生变化的回调listen

-

int revokeGroupNotice(String groupId)

-

取消对指定群组变化的listen

-
- -**表 2** 群组管理器提供的C++ API,供内部系统应用通过SA查询群组信息; - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

DeviceAuthProxy()

-

获取一个可信群组管理代理的实例。

-

~DeviceAuthProxy()

-

可信群组管理代理的实例的析构函数。

-

static int CheckAccessToGroup(const std::string &groupId, const std::string &pkgName);

-

判断指定包名的应用,是否对指定群组具有访问权限。

-

static int CheckAccessToDevice(const std::string &connDeviceId, const std::string &pkgName);

-

判断指定包名的应用,对指定的设备所加入的群组,是否具有访问权限。

-

static std::vector<std::string> GetRelatedGroupInfo(const std::string &connDeviceId);

-

获取指定ID的设备与本地设备存在可信管理的所有群组的基本信息。

-
- -## 开发步骤 - -群组管理的开发步骤比较简单,大体的流程就是先获取一个实例,获取实例的同时就注册了群组操作结果的通知回调,获取到实例后就可以对群组进行成员的添加、删除和群组的友元设置以及群组的相关的查询操作。 - -**场景一** 创建群组,下面首先以创建群组为例,说明群组管理类的创建以及接口使用方法: - -``` -private HwDeviceGroupManager hwDeviceGroupManager; -... -private HichainGroupCallback groupCallbackByA = new HichainGroupCallback() { - @Override public void onFinish(long requestId, GroupOperation operationCode, String returnData) { - - } - @Override public void onError(long requestId, GroupOperation operationCode, int errorCode, String errorReturn) { - - } - @Override public String onRequest(long requestId, GroupOperation operationCode, String reqParams) { - JSONObject onRequestJson = generateConfirmation(REQUEST_ACCEPTED); - return onRequestJson.toString(); - } -}; -... -Optional context = convertAbilityToContext(mAbility); -Context ctxt = context.get(); -hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA); -int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO); -``` - -1. 在类成员里申明群组管理实例的私有成员变量 - - ``` - private HwDeviceGroupManager hwDeviceGroupManager; - ``` - -2. 创建一个群组管理操作回调; - - ``` - private HichainGroupCallback groupCallbackByA = new HichainGroupCallback(); - ``` - -3. 在构造函数里创建一个群组管理的实例, 在分布式场景中,位于不同设备的同业务应用,应该设置相同的APP\_ID; - - ``` - hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA); - ``` - -4. 调用createGroup创建一个群组,当函数返回为0,在表明创建群组的请求已正确提交; - - ``` - int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO); - ``` - -5. 群组创建成功,会收到一个onFinish的回调,回调函数中operationCode参数为OperationCode.CREATE, 表明是创建群组操作,returnData为Json格式数据,会包含一个“groupId”的字段,返回创建的群组的Id值。 - -**场景二** 添加成员,在创建群组后,我们希望把目标设备经过设备认证加入到群组中,后续就可以通过软总线向目标设备发起可信的加密通信; - -``` -deviceGroupManager = DeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback); -private static final String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}"; -private static final String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}"; -private static final int GROUP_TYPE = 256; -int result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE); -``` - -1. 获取群组管理的实例; - - ``` - deviceGroupManager = HwDeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback); - ``` - -2. 设置添加成员的网络连接参数,为JSON格式,为软总线支持的网络参数字段,包括WIFI\_IP,WIFI\_PORT,BLR\_MAC,DEVICE\_ID等,具体连接参数要求参见软总线; - - ``` - String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}"; - ``` - -3. 设置添加成员的成员信息参数,为JSON格式,包括欲添加的群组ID,群组名,是否是管理员,若是主动邀请对方加入,则isAdmin字段为true,若是主动加入对方群组,则isAdmin为false - - ``` - String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}"; - ``` - -4. 设置欲添加的群组的群组类型为256,即点对点群组; - - ``` - private static final int GROUP_TYPE = 256; - ``` - -5. 在HichainGroupCallback 的onRequest函数,参见场景一列出的generateConfirmation传入指定的参数,其中PIN\_CODE为为PIN码,由上层业务提供界面给用户输入,确保分布式场景两端设置的PIN码一致,后续步骤才能成功; - - ``` - private JSONObject generateConfirmation(int confirmation) { - JSONObject jsonObject = new JSONObject(); - try { jsonObject.put("pinCode", PIN_CODE); - jsonObject.put("confirmation", confirmation); - } catch (JSONException e) { - LogUtil.error(TAG, "" + e.getMessage()); - } - return jsonObject; - } - ``` - -6. 调用群组管理的添加成员接口 - - ``` - result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE); - ``` - -7. 若添加成功,将会收到HichainGroupCallback.onFinish的回调,其中operationCode参数为OperationCode.JOIN -8. 添加成员成功后,业务可以调用软总线请求创建设备间安全会话。 - -## 调测验证 - -1 在OpenHarmony上开发应用App。 - -2 根据开发指导开发,开发应用App。 - -3 执行创建群组操作,如果收到onFinish回调,代表创建群组成功。 - -4 在分布式组网的节点部署相同的App,假设当前部署的有节点A和节点B; - -5 通过上层将节点B的连接参数,通过扫码的方式,传递到节点A, - -6 节点A上App创建一个群组group1,节点A上App调用添加成员接口,将B加入到group1中,若收到HichainGroupCallback.onFinish,表明加入群组成功; - diff --git "a/zh-cn/device-dev/subsystems/\345\256\211\345\205\250.md" "b/zh-cn/device-dev/subsystems/\345\256\211\345\205\250.md" deleted file mode 100755 index 88ce479aa01d95df97297fd45bd3ac17d0d16ff1..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\256\211\345\205\250.md" +++ /dev/null @@ -1,13 +0,0 @@ -# 安全 - -- **[概述](概述-7.md)** - -- **[应用验签开发指导](应用验签开发指导.md)** - -- **[应用权限管理开发指导](应用权限管理开发指导.md)** - -- **[IPC通信鉴权开发指导](IPC通信鉴权开发指导.md)** - -- **[可信设备群组管理开发指导](可信设备群组管理开发指导.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\346\235\203\351\231\220\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\346\235\203\351\231\220\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 127a7f175667a950f8cd2f4e43e3bc738d825519..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\346\235\203\351\231\220\347\256\241\347\220\206\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,228 +0,0 @@ -# 应用权限管理开发指导 - -- [运作机制](#section193961322175011) -- [场景介绍](#section18502174174019) -- [接口说明](#section1633115419401) -- [开发步骤](#section022611498210) - -## 运作机制 - -由于OpenHarmony允许安装三方应用,所以需要对三方应用的敏感权限调用进行管控,具体实现是应用在开发阶段就需要在profile.json中指明此应用在运行过程中可能会调用哪些敏感权限,这些权限包括静态权限和动态权限,静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示获取用户的敏感信息,所以需要在运行时让用户确认才可以调用,授权方式包括系统设置应用手动授权等。除了运行时对应用调用敏感权限进行管控外,还需要利用应用签名管控手段确保应用安装包已经被设备厂商进行了确认。 - -**表 1** OpenHarmony权限列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

OpenHarmony权限

-

授权方式

-

权限说明

-

ohos.permission.LISTEN_BUNDLE_CHANGE

-

system_grant(静态权限)

-

允许该应用获取应用变化消息。

-

ohos.permission.GET_BUNDLE_INFO

-

system_grant(静态权限)

-

允许该应用获取应用信息。

-

ohos.permission.INSTALL_BUNDLE

-

system_grant(静态权限)

-

允许该应用安装应用。

-

ohos.permission.CAMERA

-

user_grant(动态权限)

-

此应用可随时使用相机拍摄照片和录制视频。

-

ohos.permission.MODIFY_AUDIO_SETTINGS

-

system_grant(静态权限)

-

允许该应用修改全局音频设置,例如音量和用于输出的扬声器。

-

ohos.permission.READ_MEDIA

-

user_grant(动态权限)

-

允许该应用读取您的视频收藏。

-

ohos.permission.MICROPHONE

-

user_grant(动态权限)

-

此应用可随时使用麦克风进行录音。

-

ohos.permission.WRITE_MEDIA

-

user_grant(动态权限)

-

允许该应用写入您的音乐收藏。

-

ohos.permission.DISTRIBUTED_DATASYNC

-

user_grant(动态权限)

-

管控分布式数据传输能力。

-

ohos.permission.DISTRIBUTED_VIRTUALDEVICE

-

user_grant(动态权限)

-

允许应用使用分布式虚拟能力

-
- ->![](public_sys-resources/icon-note.gif) **说明:** ->静态权限:应用安装时由系统授予的权限,对应于权限敏感级别的system\_grant ->动态权限:应用在运行过程中需要用户授权的权限,对应于权限敏感级别的user\_grant - -## 场景介绍 - -应用权限是软件用来访问系统资源和使用系统能力的一种通行方式。在涉及用户隐私相关功能和数据的场景,例如:访问个人设备的硬件特性,如摄像头、麦克风,以及读写媒体文件等,OpenHarmony通过应用权限管理组件来保护这些数据以及能力。 - -在系统应用开发过程中,如果应用要使用敏感权限,开发者可以调用应用权限管理组件接口检查待访问权限是否被授权,如果未授权,操作不允许。 - -## 接口说明 - -应用权限管理提供的API接口,当前仅供系统应用和系统服务调用,具体API接口如下。 - -**表 2** 应用权限管理API接口功能介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

int CheckPermission(int uid, const char *permissionName)

-

检查指定UID的应用进程是否具有访问系统服务API的权限

-

int CheckSelfPermission(const char *permissionName)

-

检查调用者是否具有访问系统服务API的权限

-

int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)

-

查询应用申请的所有权限,并检查权限是否被授予

-

int GrantPermission(const char *identifier, const char *permName)

-

将指定权限授予应用程序

-

int RevokePermission(const char *identifier, const char *permName)

-

收回应用程序的指定权限

-

int GrantRuntimePermission(int uid, const char *permissionName)

-

应用运行时动态授予指定权限

-

int RevokeRuntimePermission(int uid, const char *permissionName)

-

应用运行时动态撤销指定权限

-
- -## 开发步骤 - -本部分以包管理器的应用权限开发为例进行讲解。开发过程中,首先需要明确涉及的敏感权限,并在config.json中声明该权限,在安装应用程序时,包管理器会调用应用权限管理组件的接口检查该权限是否被授予,若授予,安装流程正常进行,否则安装失败。 - -1. 在开发过程中,包管理器明确需要安装应用的权限(ohos.permission.INSTALL\_BUNDLE),并在config.json中声明该权限; - - ``` - { - ... - "module": { - "package": "com.huawei.kitframework", - "deviceType": [ - "phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera", "smartVision" - ], - "reqPermissions": [{ - // 声明需要的权限:安装应用程序的权限名 - "name": "ohos.permission.INSTALL_BUNDLE", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - }, - { - "name": "ohos.permission.LISTEN_BUNDLE_CHANGE", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - }, - { - "name": "ohos.permission.GET_BUNDLE_INFO", - "reason": "install bundle", - "usedScene": { - "ability": [ - "KitFramework" - ], - "when": "always" - } - } - ], - ... - } - ``` - -2. 当包管理器开发应用安装功能接口时,会调用权限管理相关接口检查自身是否具有安装应用程序的权限,例如:以安装应用的权限名"ohos.permission.INSTALL\_BUNDLE"作为入参,调用CheckPermission接口检查包管理器是否具有安装应用的权限,如果有权限,安装流程继续执行,否则返回安装失败; - - ``` - constexpr static char PERMISSION_INSTALL_BUNDLE[] = "ohos.permission.INSTALL_BUNDLE"; - - bool Install(const char *hapPath, const InstallParam *installParam, InstallerCallback installerCallback) - { - if ((hapPath == nullptr) || (installerCallback == nullptr) || (installParam == nullptr)) { - HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to nullptr parameters"); - return false; - } - // 检查ohos.permission.INSTALL_BUNDLE权限是否被授予 - if (CheckPermission(0, static_cast(PERMISSION_INSTALL_BUNDLE)) != GRANTED) { - HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to permission denied"); - return false; // 返回安装失败 - } - // 安装流程 - ... - } - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\351\252\214\347\255\276\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\351\252\214\347\255\276\345\274\200\345\217\221\346\214\207\345\257\274.md" deleted file mode 100755 index 8c5e78070f8c6b457d28fa149bcc528bad8a910b..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\272\224\347\224\250\351\252\214\347\255\276\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ /dev/null @@ -1,272 +0,0 @@ -# 应用验签开发指导 - -- [场景介绍](#section18502174174019) -- [验签流程](#section554632717226) -- [接口说明](#section1633115419401) -- [开发步骤(场景一)](#section4207112818418) - - [验签指导](#section11470123816297) - - [生成OpenHarmony自签名应用](#section167151429133312) - - [开发示例](#section174318361353) - -- [开发步骤(场景二)](#section81272563427) - - [验签指导](#section07028210442) - - [开发示例](#section1930711345445) - -- [调测验证](#section427316292411) - -## 场景介绍 - -当需要验证调试应用、发布应用,OpenHarmony自签名应用的完整性是否被破坏时,可以调用验签组件的接口进行验证。如有需要还可通过验签接口获取部分描述文件信息,如appid。对于调试应用,还可通过验签接口验证应用和设备的UDID是否匹配,确保应用安装在了正确的设备上。 - -## 验签流程 - -未经签名的Hap包的压缩方式是ZIP格式,简单分为文件块,中心目录(Central directory)块,中心目录结尾(EOCD,End of central directory record)块。 - -经过签名的Hap包,在文件块,和中心目录块之间,插入了签名块。签名块由文件签名数据块(data sign block)、描述文件签名数据块(profile sign block)和签名头(sign head)组成,如下图所示。 - -**图 1** 经过签名的Hap包结构 - - -![](figures/安全子系统.png) - -整个验签流程,主要分为三部分:整包验签、描述文件签名块验签,以及描述文件内容校验。 - -**整包验签** - -用设备的预置根证书,通过证书链来证明叶子证书本身是可信的,然后用叶子证书的公钥解密出的摘要证明整包是未篡改的。 - -具体操作步骤如下: - -1. 对文件签名数据块中的证书链进行校验,确定其叶子证书是可信的。 -2. 用叶子证书中的公钥对文件签名块进行验签,证明其未被篡改。 -3. 计算并合并文件块,中心目录块和中心目录结尾块的摘要。然后将计算结果,再与签名块中的描述文件签名块的摘要合并,将最终合并的摘要与文件签名块中包含的摘要对比,如果两者相等,则整包验签通过。 - -**描述文件签名块验签** - -首先判断文件签名的签发单位,如果是应用市场签发的发布应用,则无需对描述文件进行验签,直接信任,否则要对其验签。先取出整个描述文件签名块,然后验证证书链,最后用叶子证书对描述文件数据块验签,证明其未被篡改。 - -**描述文件内容校验** - -取出描述文件,并对其内容进行合法性检查。其中若hap包为调试应用,则会比对本机UDID与描述文件中包含的UDID列表,如果本机UDID在描述文件的UDID列表中包含,则验证通过。比较描述文件中包含的证书(如果是应用市场发布应用或OpenHarmony自签名则无需比较),和整包校验时使用的叶子证书,如果相同,认为整个验签流程完成。 - -## 接口说明 - -验签组件当前提供innerkits接口,仅供系统应用调用,相关接口及功能描述如下: - -**表 1** 验签组件API接口功能介绍 - - - - - - - - - - - - - - - - -

接口名

-

描述

-

int APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)

-

主入口函数,输入文件路径,进行验签,并将从描述文件中获取的数据通过verifyRst返回给调用者

-

int APPVERI_SetDebugMode(bool mode)

-

设置测试模式,设置mode为true,则支持基于测试根密钥的证书链校验,设置mode为false,则关闭基于测试根密钥的证书链校验。

-

注:当前没有基于现有测试根密钥的证书,开发者可根据自身需要,替换测试根密钥并进行相关验证。

-

void APPVERI_FreeVerifyRst(VerifyResult *verifyRst)

-

释放verifyRst中申请的内存

-
- -## 开发步骤(场景一) - -### 验签指导 - -对应用市场发布应用、基于应用市场调试证书签发的调试应用、OpenHarmony自签名应用的校验。 - -1. 定义出参结构体变量VerifyResult; - - ``` - VerifyResult verifyResult = {0}; - ``` - -2. 以文件路径及VerifyResult为入参,调用APPVERI\_AppVerify进行文件校验; - - ``` - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - ``` - -3. 判断返回结果,如果校验通过的话,获取VerifyResult中的数据,进行业务处理; - - ``` - signatureInfo.appId = verifyResult.profile.appid; - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - ``` - -4. 调用APPVERI\_FreeVerifyRst,释放VerifyResult中申请的内存。 - - ``` - APPVERI_FreeVerifyRst(&verifyResult); - ``` - - -### 生成OpenHarmony自签名应用 - -如果是OpenHarmony自签名应用的校验,开发者可通过以下方式生成OpenHarmony自签名应用。 - -1. 材料备齐。 - - 生成自签名应用需要的材料有:签名工具、系统应用hap包、系统应用profile文件\(\*.p7b\)、签名证书\(\*.cer\)、签名公私钥对\(\*.jks\)。 - -2. 将所有材料放在同一个目录下,打开shell。 -3. 根据应用、描述文件的实际名称修改指令,并在shell中输入,完成签名。 - - ``` - java -jar hapsigntoolv2.jar sign -mode localjks -privatekey "OpenHarmony Software Signature" -inputFile camera.hap -outputFile signed_camera.hap -signAlg SHA256withECDSA -keystore OpenHarmony.jks -keystorepasswd 123456 -keyaliaspasswd 123456 -profile camera_release.p7b -certpath OpenHarmony.cer -profileSigned 1 - ``` - - 关键字段说明: - - -jar:签名工具,[hapsigntool](https://repo.huaweicloud.com/harmonyos/develop_tools/hapsigntoolv2.jar) - - -mode:本地签名标记位,固定为localjks - - -privatekey:密钥对别名,签名公私钥对的别名为OpenHarmony Software Signature - - -inputFile:待签名应用,通过编译产生 - - -outputFile:签名后应用,最终输出 - - -signAlg:签名算法,当前固定为SHA256withECDSA - - -keystore:公私钥对,使用签名公私钥对,位于开源库security\_services\_app\_verify仓中OpenHarmonyCer目录下,[OpenHarmony.jks](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.jks)。默认密码为123456 ,用户可采用工具\(例如keytool\)更改默认密码 - - -keystorepasswd:公私钥对密码,默认签名公私钥对密码为123456 - - -keyaliaspasswd:公私钥对别名密码,默认签名公私钥对别名密码为123456 - - -profile:描述文件,应用的描述文件位于对应源代码目录中 - - -certpath:使用签名证书,位于开源库security\_services\_app\_verify仓中OpenHarmonyCer目录下,[OpenHarmony.cer](https://gitee.com/openharmony/security_appverify/blob/master/interfaces/innerkits/appverify_lite/OpenHarmonyCer/OpenHarmony.cer) - - -profileSigned:签名块中是否包含描述文件\(profile\)。固定为1(包含) - - -### 开发示例 - -以应用管理框架组件在应用安装时进行验签的实际调用为例: - -``` -uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) -{ - bool mode = ManagerService::GetInstance().IsDebugMode(); - HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); - // 定义结果结构体 - VerifyResult verifyResult = {0}; - // 输入待验签文件路径进行验签 - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - uint8_t errorCode = SwitchErrorCode(ret); - if (errorCode != ERR_OK) { - return errorCode; - } - // 从结果结构体中获取appid - signatureInfo.appId = verifyResult.profile.appid; - // 从结果结构体中获取描述文件中书写的应用名 - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - int32_t restricNum = verifyResult.profile.permission.restricNum; - for (int32_t i = 0; i < restricNum; i++) { - signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); - } - // 释放结果结构体中申请的内存 - APPVERI_FreeVerifyRst(&verifyResult); - return ERR_OK; -} -``` - -## 开发步骤(场景二) - -### 验签指导 - -对采用基于测试根密钥证书签名的应用的校验。 - -1. 调用APPVERI\_SetDebugMode\(true\)开启测试模式; - - ``` - ManagerService::SetDebugMode(true); - ... - uint8_t ManagerService::SetDebugMode(bool enable) - { - int32_t ret = APPVERI_SetDebugMode(enable); - if (ret < 0) { - HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); - return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; - } - isDebugMode_ = enable; - HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); - return ERR_OK; - } - ``` - -2. 同场景一中步骤一至四,定义结构体,校验、释放结构体; -3. 调用APPVERI\_SetDebugMode\(false\)关闭测试模式。 - - ``` - ManagerService::SetDebugMode(false); - ``` - - -### 开发示例 - -完整开发示例如下(在场景一代码示例的基础上进行补充): - -``` -uint8_t ManagerService::SetDebugMode(bool enable) -{ - int32_t ret = APPVERI_SetDebugMode(enable); - if (ret < 0) { - HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed"); - return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR; - } - isDebugMode_ = enable; - HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_); - return ERR_OK; -} -uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo) -{ - // 开启支持测试服务器签名应用验证 - ManagerService::SetDebugMode(true); - bool mode = ManagerService::GetInstance().IsDebugMode(); - HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode); - // 定义结果结构体 - VerifyResult verifyResult = {0}; - // 输入待验签文件路径进行验签 - int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); - uint8_t errorCode = SwitchErrorCode(ret); - if (errorCode != ERR_OK) { - return errorCode; - } - // 从结果结构体中获取appid - signatureInfo.appId = verifyResult.profile.appid; - // 从结果结构体中获取描述文件中书写的应用名 - signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; - int32_t restricNum = verifyResult.profile.permission.restricNum; - for (int32_t i = 0; i < restricNum; i++) { - signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]); - } - // 释放结果结构体中申请的内存 - APPVERI_FreeVerifyRst(&verifyResult); - // 关闭支持测试服务器签名应用验证 - ManagerService::SetDebugMode(false); - return ERR_OK; -} -``` - -## 调测验证 - -1. 选取一个在OpenHarmony上能够正常安装的应用A。 -2. 根据开发指导开发。 -3. 对应用A,采用自开发程序进行验签,验签通过,能获取到appid。即为开发成功。 - diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213-6.md" "b/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213-6.md" deleted file mode 100755 index 39c2377cd403b1b3aaed2c97947c6cea63b4e6dc..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\345\256\236\344\276\213-6.md" +++ /dev/null @@ -1,112 +0,0 @@ -# 开发实例 - -- [去电开发实例](#section286643718507) -- [来电开发实例](#section3205350105014) - -## 去电开发实例 - -去电的调用流程示例如下图所示: - -**图 1** 去电调用流程图 - - -![](figures/去电.png) - -当应用触发去电动作时,RIL Adapter会接收到拨打电话的请求,OnRequest\(\)会根据拨打电话请求ID调用拨打电话的接口。在该接口里会把电话服务传过来的数据封装为对应的AT指令发送到Modem,Modem执行完拨号命令后通过OnRequestResponse\(\)接口把响应结果上报给RIL Adapter。 - -``` -#include -#include -#include -#include -#include "atchannel.h" -#include "at_tok.h" -#include "hdf_log.h" -#include "ril.h" - -static void OnRequest(int request, void *data, size_t datalen, RIL_Token token) -{ - HDF_LOGI("OnRequest request = %{public}d start \n", request); - switch (request) { - case HREQ_CALL_DIAL: - SendDialRequest(data, datalen, token); - break; - …… - default: - break; - } -} - -// 将去电ID和参数转换成对应的AT命令,通过send_at_request发送给Modem -static void SendDialRequest(void *data, size_t datalen __unused, RIL_Token token) -{ - char *atCmd; - const char *clir; - int ret; - DialInfo *pDial; - pDial = (DialInfo *) data; - - if (!strncmp(pDial->address, "*31#", 4)) { - HDF_LOGI("clir suppression"); - clir = "i"; - num = (char *)&(pDial->address[4]); - } else if (!strncmp(pDial->address, "#31#", 4)) { - HDF_LOGI("clir invocation"); - clir = "I"; - num = (char *)&(pDial->address[4]); - } else { - HDF_LOGI("set clir state to default"); - clir = ""; - num = (char *)pDial->number; - } - - asprintf(&atCmd, "ATD%s%s;", pDial->address, clir); - ret = send_at_request(atCmd, NULL); - free(atCmd); - // 命令执行完成后调用该接口,将Modem执行的结果反馈给RIL Adapter - OnRequestResponse(t, RIL_RESULT_SUCCESS, NULL, 0); -} -``` - -## 来电开发实例 - -来电的调用流程示例如下图所示: - -**图 2** 来电调用流程图 - - -![](figures/来电.png) - -Modem设备节点读取线程s\_tid\_read会循环读取Modem上报的消息,当Modem接收到来电时会主动上报来电相关的信息; - -当该线程通过调用OnNotificationResponse\(\)解析到Modem上报的数据是以"+CRING"、"RING"等字符开头时,表示有来电事件,然后通过OnRadioEventNotify\(HNOTI\_CALL\_STATUS, NULL, 0\)上报给RIL Adapter完成来电事件上报。 - -``` -#include -#include "atchannel.h" -#include "at_tok.h" -#include "hdf_log.h" -#include "ril.h" - -bool IsCallStatusUpdated(const char *s) -{ - return (StrBeginWith(s, "+CRING:") - || StrBeginWith(s, "RING") - || StrBeginWith(s, "NO CARRIER") - || StrBeginWith(s, "+CCWA")); -} - -// 将Modem上报数据解析为对应的Modem事件 -static void OnNotificationResponse(const char *s, const char *sms_pdu) -{ - char *line = NULL, *p; - HDF_LOGI("OnNotificationResponse = %{public}s sState = %{public}d", s, sState); - // 解析到以"+CRING:"等字符开头的数据时,转换为来电事件 - if (IsCallStatusUpdated(s)) { - // 通知RIL Adapter有来电事件 - OnRadioEventNotify(HNOTI_CALL_STATUS, NULL, 0); - } - …… -} -``` - diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" "b/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-1.md" similarity index 100% rename from "zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-3.md" rename to "zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-1.md" diff --git "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-5.md" "b/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-5.md" deleted file mode 100755 index cd3f58d79fd22f548f694d86830562b3494428c2..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\345\274\200\345\217\221\346\214\207\345\257\274-5.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 开发指导 - -- **[Modem厂商库集成指导](Modem厂商库集成指导.md)** - -- **[Modem厂商库初始化开发指导](Modem厂商库初始化开发指导.md)** - -- **[Modem业务请求及响应开发指导](Modem业务请求及响应开发指导.md)** - -- **[Modem事件上报开发指导](Modem事件上报开发指导.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" index 2b37619913040891523cba68ded948d628a273f5..0e1ebbfecfc56b1d4eecf483c07c4c646cb85e0b 100755 --- "a/zh-cn/device-dev/subsystems/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" +++ "b/zh-cn/device-dev/subsystems/\346\213\215\347\205\247\345\274\200\345\217\221\346\214\207\345\257\274.md" @@ -385,6 +385,7 @@ Surface *surface = Surface::CreateSurface(); if (surface == nullptr) { delete fc; + return; } surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */ fc->AddSurface(*surface); diff --git "a/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203-2.md" "b/zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203-0.md" old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203-2.md" rename to "zh-cn/device-dev/subsystems/\346\220\255\345\273\272\347\216\257\345\242\203-0.md" diff --git "a/zh-cn/device-dev/subsystems/\346\240\207\345\207\206\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\346\240\207\345\207\206\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" deleted file mode 100644 index 6c6cf033328d93b995af036b0607bb9c31bb37ef..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\240\207\345\207\206\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" +++ /dev/null @@ -1,7 +0,0 @@ -# 标准系统编译构建指导 - -- **[编译构建概述](编译构建概述-0.md)** - -- **[编译构建使用指导](编译构建使用指导-1.md)** - - diff --git "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260-7.md" "b/zh-cn/device-dev/subsystems/\346\246\202\350\277\260-7.md" deleted file mode 100644 index 45d0d3267613ee990ad09557a99fb18a311c5efe..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260-7.md" +++ /dev/null @@ -1,76 +0,0 @@ -# 概述 - -- [基本概念](#section175012297491) -- [约束与限制](#section2029921310472) - -OpenHarmony安全子系统目前提供给开发者的安全能力主要包含应用可信、权限管理、设备可信。涉及以下几个模块: - -- 应用验签 - - 为了确保应用内容的完整性,系统通过应用签名和Profile对应用的来源进行管控,同时对于调试应用,还可通过验签接口验证应用和设备的UDID是否匹配,确保应用安装在了正确的设备上。 - -- 应用权限管理 - - 应用权限是管理应用访问系统资源和使用系统能力的一种通用方式,应用在开发阶段需要在profile.json中指明此应用在运行过程中可能会调用哪些权限,其中静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示涉及到敏感信息,所以需要用户进行动态授权。 - -- IPC通信鉴权 - - 系统服务通过IPC暴露接口给其他进程访问,这些接口需要配置相应的访问策略,当其他进程访问这些接口时,将会触发IPC通信鉴权机制校验访问进程是否拥有权限访问该接口,若无权限,则拒绝访问该接口。 - -- 可信设备群组管理 - - 提供基于群组概念的同华为账号群组、点对点群组(如二维码、碰一碰等)的设备安全可信关系的创建和查询,分布式应用可基于该能力进行设备间的可信认证,然后向分布式软总线请求设备间安全会话。 - - -## 基本概念 - -在进行依赖验签组件的应用开发前,开发者应了解以下基本概念: - -- Samgr - - Samgr\(System Ability M2anager\)系统能力管理,在OpenHarmony上作为一个管理系统能力的模块,详见系统服务框架子系统。 - - -- BMS - - BMS\(Bundle Manager Service\)包管理管理,在OpenHarmony上主要负责应用的安装、卸载和数据管理。 - - -- 描述文件 - - 本文中的描述文件,指HarmonyAppProvision,简称profile。HarmonyAppProvision采用json文件格式进行描述。 - - -- 叶子证书 - - 最终用于为整包或profile签名的证书称为叶子证书,位于数字证书链的最末端。 - - -- 调试应用 - - 指开发者从应用市场申请调试证书与调试描述文件,并以此签名的hap包。 - - -- 待上架应用 - - 指开发者从应用市场申请发布证书与发布描述文件,以此签名,未通过应用市场正式发布的hap包。 - - -- 发布应用 - - 指开发者从应用市场申请发布证书与发布描述文件,以此签名的hap包,上传至应用市场,并由应用市场正式发布的hap包。 - - -- OpenHarmony自签名应用 - - 当开发者自行编译OpenHarmony系统应用后,采用原应用描述文件,以及公开的OpenHarmony公私钥对和证书进行自签名产生的hap包。 - - -## 约束与限制 - -- 仅支持以下三类应用的验签:应用市场调试应用、应用市场发布应用、OpenHarmony自签名应用的验签。 -- 若对应用市场调试应用验签,则本机UDID需要在描述文件包含的UDID列表中。 -- 待上架应用无法验签通过。 -- 验签组件提供的接口都位于security\_interfaces\_innerkits\_app\_verify仓[app\_verify\_pub.h](https://gitee.com/fork_ohos_wj/security_interfaces_innerkits_app_verify/blob/master/app_verify_pub.h)中,仅支持系统应用开发者调用。 -- 可信设备群组管理接口,目前只对系统签名权限才可以使用。 - diff --git "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260.md" "b/zh-cn/device-dev/subsystems/\346\246\202\350\277\260.md" index 63ee16f94ce7de540c47dae8ab52a5aef504889b..3edb13ccbc396b35961edfd5548283fa096cd6bd 100755 --- "a/zh-cn/device-dev/subsystems/\346\246\202\350\277\260.md" +++ "b/zh-cn/device-dev/subsystems/\346\246\202\350\277\260.md" @@ -73,7 +73,7 @@ Ability子系统是管理OpenHarmony应用运行状态的开发框架。 - **AbilityKit**:Ability框架提供给开发者的开发包,开发者基于该开发包可以开发出基于Ability组件的应用。基于Ability组件开发的应用有两种类型:基于Javascript语言开发的Ability(JS Ability)和基于C/C++语言开发的Ability(Native Ability)。JS应用开发框架是开发者开发JS Ability所用到框架,是在AbilityKit基础封装的包含js UI组件的一套方便开发者能够迅速开发Ability应用的框架。 - **AbilityLoader**:负责注册和加载开发者Ability的模块。开发者开发的Ability先要调用AbilityLoader的注册接口注册到框架中,接着Ability启动时会被实例化。 -- **AbilityManager**:负责AbilityKit和Ability管理服务进行IPC的通信。 +- **AbilityManager:**负责AbilityKit和Ability管理服务进行IPC的通信。 - **EventHandler**:AbilityKit提供给开发者的用于在Ability中实现线程间通信的一个模块。 diff --git "a/zh-cn/device-dev/subsystems/\347\224\250\346\210\267\347\250\213\345\272\217\346\241\206\346\236\266.md" "b/zh-cn/device-dev/subsystems/\347\224\250\346\210\267\347\250\213\345\272\217\346\241\206\346\236\266.md" index 14552d89af7b37c90cd9edbbc22f1d2d6c2b0bcb..840c204266911e6cb5771d178004db2f27017f48 100755 --- "a/zh-cn/device-dev/subsystems/\347\224\250\346\210\267\347\250\213\345\272\217\346\241\206\346\236\266.md" +++ "b/zh-cn/device-dev/subsystems/\347\224\250\346\210\267\347\250\213\345\272\217\346\241\206\346\236\266.md" @@ -2,9 +2,9 @@ - **[概述](概述.md)** -- **[搭建环境](搭建环境-2.md)** +- **[搭建环境](搭建环境-0.md)** -- **[开发指导](开发指导-3.md)** +- **[开发指导](开发指导-1.md)** - **[开发实例](开发实例.md)** diff --git "a/zh-cn/device-dev/subsystems/\347\240\224\345\217\221\345\267\245\345\205\267\351\223\276.md" "b/zh-cn/device-dev/subsystems/\347\240\224\345\217\221\345\267\245\345\205\267\351\223\276.md" index 5c490a8cfbdc0458b160ce6b284ecd2582f2faad..71503a41dac0d9b78f5b156bf8c4b6cb5b44f161 100644 --- "a/zh-cn/device-dev/subsystems/\347\240\224\345\217\221\345\267\245\345\205\267\351\223\276.md" +++ "b/zh-cn/device-dev/subsystems/\347\240\224\345\217\221\345\267\245\345\205\267\351\223\276.md" @@ -4,6 +4,4 @@ - **[hdc\_std 使用指导](hdc_std-使用指导.md)** -- **[hdc\_std常见问题](hdc_std常见问题.md)** - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272.md" index b59e4b2a18f9ef3c093e85b47b97126043b59744..fa8f3606d6e71269e60fb925c4ab438fe1524c8f 100755 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272.md" +++ "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272.md" @@ -1,7 +1,7 @@ # 编译构建 -- **[轻量和小型系统编译构建指导](轻量和小型系统编译构建指导.md)** +- **[编译构建子系统—轻量和小型系统](编译构建子系统-轻量和小型系统.md)** -- **[标准系统编译构建指导](标准系统编译构建指导.md)** +- **[编译构建子系统—标准系统](编译构建子系统-标准系统.md)** diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274.md" deleted file mode 100755 index 8d5f276817760d9b28e9bee264507fc2e6c6b533..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274.md" +++ /dev/null @@ -1,431 +0,0 @@ -# 编译构建使用指导 - -- [前提条件](#section13333171022312) -- [hb命令行工具使用](#section477242204612) -- [新增组件](#section4207112818418) -- [新增芯片解决方案](#section2737141421917) -- [新增产品解决方案](#section720881917199) - -## 前提条件 - -开发环境需安装gn、ninja构建工具、python 3.7.4及以上和hb。安装方法请见[搭建系统基础环境](../quick-start/搭建系统环境.md)。 - -## hb命令行工具使用 - -hb是OpenHarmony的命令行工具,用来执行编译命令。以下对hb的常用命令进行说明。 - -1. **hb set** - - ``` - hb set -h - usage: hb set [-h] [-root [ROOT_PATH]] [-p] - - optional arguments: - -h, --help show this help message and exit - -root [ROOT_PATH], --root_path [ROOT_PATH] - Set OHOS root path - -p, --product Set OHOS board and kernel - ``` - - - hb set 后无参数,进入默认设置流程 - - hb set -root dir可直接设置代码根目录 - - hb set -p设置要编译的产品 - -2. **hb env** - - 查看当前设置信息 - - ``` - hb env - [OHOS INFO] root path: xxx - [OHOS INFO] board: hispark_taurus - [OHOS INFO] kernel: liteos - [OHOS INFO] product: ipcamera - [OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera - [OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 - ``` - -3. **hb build** - - ``` - hb build -h - usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] - [--dmverity] [-p PRODUCT] [-f] [-n] - [component [component ...]] - - positional arguments: - component name of the component - - optional arguments: - -h, --help show this help message and exit - -b BUILD_TYPE, --build_type BUILD_TYPE - release or debug version - -t [TEST [TEST ...]], --test [TEST [TEST ...]] - compile test suit - --dmverity Enable dmverity - -p PRODUCT, --product PRODUCT - build a specified product with - {product_name}@{company}, eg: ipcamera@hisilcon - -f, --full full code compilation - -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] - Compile single target - ``` - - - hb build后无参数,会按照设置好的代码路径、产品进行编译,编译选项使用与之前保持一致。-f 选项将删除当前产品所有编译产品,等同于hb clean + hb build. - - hb build \{component\_name\}:基于设置好的产品对应的单板、内核,单独编译组件(e.g.:hb build kv\_store\)。 - - hb build -p ipcamera@hisilicon:免set编译产品,该命令可以跳过set步骤,直接编译产品。 - - 在device/device\_company/board下单独执行hb build会进入内核选择界面,选择完成后会根据当前路径的单板、选择的内核编译出仅包含内核、驱动的镜像。 - -4. **hb clean** - - 清除out目录对应产品的编译产物,仅保留args.gn、build.log。清除指定路径可输入路径参数:hb clean out/board/product,默认将清除当前hb set的产品对应out路径。 - - ``` - hb clean - usage: hb clean [-h] [out_path] - - positional arguments: - out_path clean a specified path. - - optional arguments: - -h, --help show this help message and exit - ``` - - -## 新增组件 - -本小节介绍如何新增一个组件,首先确定组件归属的子系统和组件名称,然后按如下步骤新增: - -1. 源码开发完成后,添加组件编译脚本。 - - 以编译组件hello\_world可执行文件为例,applications/sample/hello\_world/BUILD.gn可以写为: - - ``` - executable("hello_world") { - include_dirs = [ - "include", - ] - sources = [ - "src/hello_world.c" - ] - } - ``` - - 如上编译脚本,可编译出一个可在OpenHarmony上运行的名为hello\_world的可执行文件。 - - 单独编译该组件,hb set任意选择一款产品,然后使用-T选项单独编译组件: - - ``` - hb build -f -T //applications/sample/hello_world - ``` - - 组件在开发板上功能验证完成后,可按步骤2\~5将组件配置到产品中。 - -2. 添加组件描述。 - - 组件描述位于build/lite/components下,新增的组件需加入对应子系统的json文件中。一个组件描述必选的字段有: - - - component:组件名称。 - - description:组件的一句话功能描述。 - - optional:组件是否为系统可选。 - - dirs:组件源码路径。 - - targets:组件编译入口。 - - 以将hello\_world组件加入应用子系统为例,在applications.json中添加hello\_world对象: - - ``` - { - "components": [ - { - "component": "hello_world", - "description": "Hello world.", - "optional": "true", - "dirs": [ - "applications/sample/hello_world" - ], - "targets": [ - "//applications/sample/hello_world" - ] - }, - ... - ] - } - ``` - -3. 将组件配置到产品。 - - 产品的配置文件config.json位于位于vendor/company/product/下,产品配置文件需包含产品名称、OpenHarmony版本号、device厂商、开发板、内核类型、内核版本号,以及配置的子系统和组件。以将hello\_world组件加入产品配置文件my\_product.json中为例,加入hello\_wolrd对象: - - ``` - { - "product_name": "hello_world_test", - "ohos_version": "OpenHarmony 1.0", - "device_company": "hisilicon", - "board": "hispark_taurus", - "kernel_type": "liteos_a", - "kernel_version": "1.0.0", - "subsystems": [ - { - "subsystem": "applications", - "components": [ - { "component": "hello_world", "features":[] } - ] - }, - ... - ] - } - ``` - -4. 编译产品。 - - 1. 代码根目录输入hb set选择对应产品。 - - 2. 执行hb build。 - - -## 新增芯片解决方案 - -编译构建支持添加新的芯片解决方案厂商,具体步骤如下: - -1. 创建芯片解决方案目录。 - - 按照[芯片解决方案配置规则](编译构建概述.md#section1625463413327)创建目录,以芯片厂商realtek的“rtl8720“开发板为例, 在代码根目录执行: - - ``` - mkdir -p device/realtek/rtl8720 - ``` - -2. 创建内核适配目录,并编写开发板编译配置config.gni文件。 - - 以realtek的“rtl8720“开发板的liteos\_m适配为例,device/realtek/rtl8720/liteos\_a/config.gni的内容如下: - - ``` - # Kernel type, e.g. "linux", "liteos_a", "liteos_m". - kernel_type = "liteos_a" - - # Kernel version. - kernel_version = "3.0.0" - - # Board CPU type, e.g. "cortex-a7", "riscv32". - board_cpu = "real-m300" - - # Board arch, e.g. "armv7-a", "rv32imac". - board_arch = "" - - # Toolchain name used for system compiling. - # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. - # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. - board_toolchain = "gcc-arm-none-eabi" - - # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. - board_toolchain_path = - rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", - root_build_dir) - - # Compiler prefix. - board_toolchain_prefix = "gcc-arm-none-eabi-" - - # Compiler type, "gcc" or "clang". - board_toolchain_type = "gcc" - - # Board related common compile flags. - board_cflags = [] - board_cxx_flags = [] - board_ld_flags = [] - ``` - -3. 编写编译脚本。 - - 在开发板目录下创建BUILD.gn,target名称应与开发板名称一致。以realtek的rtl8720开发板为例,device/realtek/rtl8720/BUILD.gn内容可以是: - - ``` - group("rtl8720") { # target类型也可以shared_library, static_library, executable - # 具体内容 - ...... - } - ``` - -4. 编译芯片解决方案。 - - 在开发板目录下执行hb build,即可启动芯片解决方案的编译。 - - -## 新增产品解决方案 - -编译构建支持芯片解决方案和组件的灵活拼装,形成定制化的产品解决方案。具体步骤如下: - -1. 创建产品目录 - - 按照[产品解决方案配置规则](编译构建概述.md#section1625463413327)创建产品目录,以基于“rtl8720“开发板的wifiiot模组为例,在代码根目录执行: - - ``` - mkdir -p vendor/my_company/wifiiot - ``` - -2. 拼装产品 - - 在新建的产品目录下新建config.json文件,以步骤1中的wifiiot为例,vendor/my\_company/wifiiot/config.json可以是: - - ``` - { - "product_name": "wifiiot", # 产品名称 - "ohos_version": "OpenHarmony 1.0", # 使用的OS版本 - "device_company": "realtek", # 芯片解决方案厂商名称 - "board": "rtl8720", # 开发板名称 - "kernel_type": "liteos_m", # 选择的内核类型 - "kernel_version": "3.0.0", # 选择的内核版本 - "subsystems": [ - { - "subsystem": "kernel", # 选择的子系统 - "components": [ - { "component": "liteos_m", "features":[] } # 选择的组件和组件特性 - ] - }, - ... - { - 更多子系统和组件 - } - ] - } - ``` - - 注意:编译构建系统编译前会对device\_company,board,kernel\_type,kernel\_version、subsystem、component字段进行有效性检查,其中device\_company,board,kernel\_type,kernel\_version应与已知的芯片解决方案匹配,subsystem、component应与build/lite/components下的组件描述匹配。 - -3. 适配OS接口 - - 在产品目录下创建hals目录,并将产品解决方案对OS适配的源码和编译脚本放入该目录下。 - -4. 配置系统服务 - - 在产品目录下创建init\_configs目录,并在init\_configs目录下创建init.cfg文件,按需配置要启动的系统服务。 - -5. 配置init进程(仅linux内核需要) - - 在init\_configs目录下创建etc目录,然后在etc下创建init.d文件夹和fstab文件。最后按产品需求在init.d文件下创建并编辑rcS文件和Sxxx文件。 - -6. 配置文件系统镜像(可选,仅支持文件系统的开发板需要) - - 在产品目录下创建fs.yml文件。fs.yml需按产品实际情况配置,一个典型的fs.yml文件如下: - - ``` - - - fs_dir_name: rootfs # 镜像的名称 - fs_dirs: - - - # 将编译生成的out/my_board/my_product/bin目录下的文件拷贝到rootfs/bin中,并忽略测试bin - source_dir: bin - target_dir: bin - ignore_files: - - Test.bin - - TestSuite.bin - - - # 将编译生成的out/my_board/my_product/libs目录下的文件拷贝到rootfs/lib中,忽略所有.a文件,并设置文件和文件夹的权限为644和755 - source_dir: libs - target_dir: lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: usr/lib - target_dir: usr/lib - ignore_files: - - .a - dir_mode: 755 - file_mode: 644 - - - source_dir: config - target_dir: etc - - - source_dir: system - target_dir: system - - - source_dir: sbin - target_dir: sbin - - - source_dir: usr/bin - target_dir: usr/bin - - - source_dir: usr/sbin - target_dir: usr/sbin - - - # 创建一个proc空目录 - target_dir: proc - - - target_dir: mnt - - - target_dir: opt - - - target_dir: tmp - - - target_dir: var - - - target_dir: sys - - - source_dir: etc - target_dir: etc - - - source_dir: vendor - target_dir: vendor - - - target_dir: storage - - fs_filemode: - - - file_dir: lib/ld-uClibc-0.9.33.2.so - file_mode: 555 - - - file_dir: lib/ld-2.24.so - file_mode: 555 - - - file_dir: etc/init.cfg - file_mode: 400 - fs_symlink: - - - # 在rootfs/lib下创建软连接ld-musl-arm.so.1 -> libc.so - source: libc.so - link_name: ${fs_dir}/lib/ld-musl-arm.so.1 - - - source: mksh - link_name: ${fs_dir}/bin/sh - - - source: mksh - link_name: ${fs_dir}/bin/shell - fs_make_cmd: - # 使用脚本将rootfs制作为ext4格式的image - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - - - fs_dir_name: userfs - fs_dirs: - - - source_dir: storage/etc - target_dir: etc - - - source_dir: data - target_dir: data - fs_make_cmd: - - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 - - ``` - -7. 编写编译脚本 - - 在产品目录下创建BUILD.gn文件,按产品实际情况编写脚本。以步骤1中的wifiiot为例,BUILD.gn示例如下: - - ``` - group("wifiiot") { # target名称与产品名一致 - deps = [] - # 拷贝init配置 - deps += [ "init_configs" ] - # 将hals加入编译 - deps += [ "hals" ] - # 其他 - ...... - } - ``` - -8. 编译产品。 - - 在代码根目录执行hb set按提示选择新增的产品,然后执行hb build即可启动编译。 - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274-1.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\255\220\347\263\273\347\273\237-\346\240\207\345\207\206\347\263\273\347\273\237.md" old mode 100755 new mode 100644 similarity index 66% rename from "zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274-1.md" rename to "zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\255\220\347\263\273\347\273\237-\346\240\207\345\207\206\347\263\273\347\273\237.md" index 661ff10cf6bdcb8d16510560214c53e124813a6d..ec1cb9420870543a825e4ab6b34125dca243b0c9 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\344\275\277\347\224\250\346\214\207\345\257\274-1.md" +++ "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\255\220\347\263\273\347\273\237-\346\240\207\345\207\206\347\263\273\347\273\237.md" @@ -1,12 +1,73 @@ -# 编译构建使用指导 +# 编译构建子系统—标准系统 -- [目录结构](#section56731811102915) -- [编译](#section1069873833818) - - [编译命令](#section2740182614395) +- [概述](#section17466112012244) + - [基本概念](#section445513507246) + - [运作机制](#section12541217142510) + - [约束与限制](#section886933762513) -- [开发步骤](#section4207112818418) +- [编译构建使用指导](#section16901215262) + - [目录结构](#section109065332264) + - [编译命令](#section123265539266) + - [开发步骤](#section591084422719) -## 目录结构 + +## 概述 + +编译构建子系统提供了一个基于gn和ninja的编译构建框架。主要提供以下功能: + +- 构建不同芯片平台的产品。如:Hi3516DV300平台。 + +- 根据产品配置可以按照组件组装打包产品需要的能力。 + +### 基本概念 + +在了解编译构建子系统的能力前,应了解如下基本概念: + +- 平台 + + 开发板和内核的组合,不同平台支持的子系统和组件不同。 + +- 子系统 + + OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 \> 子系统 \> 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。子系统是一个逻辑概念,它具体由对应的组件构成。 + +- 组件 + + 对子系统的进一步拆分,可复用的软件单元,它包含源码、配置文件、资源文件和编译脚本;能独立构建,以二进制方式集成,具备独立验证能力的二进制单元。 + +- gn + + Generate ninja的缩写,用于产生ninja文件。 + +- ninja + + ninja是一个专注于速度的小型构建系统。 + + +### 运作机制 + +OpenHarmony侧的编译构建流程主要包括编译命令行解析,调用gn,执行ninja: + +- 命令行解析:解析待编译的产品名称,加载相关配置。 +- 调用gn: 根据命令行解析的产品名称和编译类型,配置编译工具链和全局的编译选项。 +- 执行ninja:启动编译并生成对应的产品版本。 + +### 约束与限制 + +- 需按照[源码获取](../get-code/源码获取.md)指导下载全量源码(采用方式三获取)。 +- 编译环境需要Ubuntu18.04及以上版本。 +- 安装编译所需的程序包。 + + 安装命令: + + ``` + sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 + ``` + + +## 编译构建使用指导 + +### 目录结构 ``` /build # 编译构建主目录 @@ -27,9 +88,7 @@ └── toolchain # 编译工具链配置 ``` -## 编译 - -### 编译命令 +### 编译命令 - 代码根目录下执行全量版本的编译命令: @@ -51,7 +110,7 @@ ``` -## 开发步骤 +### 开发步骤 1. 添加组件。 diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\255\220\347\263\273\347\273\237-\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237.md" old mode 100755 new mode 100644 similarity index 39% rename from "zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260.md" rename to "zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\255\220\347\263\273\347\273\237-\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237.md" index 83423cbe1c9b0d7f4bfd6bae3124b490c43cd6c8..5933ac0bab5e87df9f63b0f74f266bb7c8e080eb --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260.md" +++ "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\255\220\347\263\273\347\273\237-\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237.md" @@ -1,9 +1,32 @@ -# 编译构建概述 +# 编译构建子系统—轻量和小型系统 -- [基本概念](#section175012297491) -- [目录结构](#section3267040205617) -- [构建流程](#section193961322175011) -- [组件、芯片解决方案和产品解决方案配置规则](#section1625463413327) +- [概述](#section10958256161119) + - [基本概念](#section1732301411128) + - [目录结构](#section1588744014121) + - [构建流程](#section15761735134) + +- [配置规则](#section2345183962710) + - [组件](#section142532518308) + - [芯片解决方案](#section121501451143710) + - [产品解决方案](#section134549283435) + +- [使用指导](#section13754457192211) + - [前提条件](#section31651120233) + - [hb工具使用说明](#section1133304172313) + - [新增组件](#section167110415315) + - [新增芯片解决方案](#section1474718565412) + - [新增产品解决方案](#section1097623294220) + +- [常见问题](#section19909721104319) + - [ninja版本问题导致编译失败](#section138233464318) + - [ncurses库缺失导致编译失败](#section151033911442) + - [未安装mcopy导致编译失败](#section19811838104418) + - [权限问题导致编译失败](#section03111118451) + - [未安装Crypto导致编译失败](#section69981127125013) + - [编译环境为shell导致编译失败](#section967617530505) + + +## 概述 一个基于gn和ninja的构建系统,以支持OpenHarmony组件化开发为目标,提供以下基本功能: @@ -12,7 +35,7 @@ - 独立构建芯片解决方案厂商源码。 - 独立构建单个组件。 -## 基本概念 +### 基本概念 在使用编译构建子系统前,应了解如下基本概念: @@ -38,7 +61,7 @@ OpenHarmony的命令行工具,用来执行编译命令。 -## 目录结构 +### 目录结构 ``` build/lite @@ -55,7 +78,7 @@ build/lite └── toolchain # 编译工具链配置,包括:编译器路径、编译选项、链接选项等 ``` -## 构建流程 +### 构建流程 编译构建流程如[图1 ](#fig9744112715161)所示,主要分设置和编译两步: @@ -70,13 +93,16 @@ build/lite - 系统镜像打包:将组件编译产物打包,设置文件属性和权限,制作文件系统镜像。 -## 组件、芯片解决方案和产品解决方案配置规则 +## 配置规则 为了实现芯片解决方案、产品解决方案与OpenHarmony是解耦的、可插拔的,组件、芯片解决方案和产品解决方案的路径、目录树和配置需遵循一定的规则,具体如下: -- **组件** +### **组件** + +组件源码路径命名规则为:**\{领域\}/\{子系统\}/\{组件\}**,组件目录树规则如下: -组件源码路径命名规则为:_\{领域\}/\{子系统\}/\{组件\}_,组件目录树规则如下: +>![](public_sys-resources/icon-caution.gif) **注意:** +>组件的名称、源码路径、功能简介、是否必选、编译目标、RAM、ROM、编译输出、已适配的内核、可配置的特性和依赖等属性定义在build/lite/components目录下对应子系统的json文件中,新增组件时需要在对应子系统json文件中添加相应的组件定义。产品所配置的组件必须在某个子系统中被定义过,否则会校验失败。 ``` component @@ -88,8 +114,6 @@ component └── BUILD.gn # 组件编译脚本 ``` -组件的名称、源码路径、功能简介、是否必选、编译目标、RAM、ROM、编译输出、已适配的内核、可配置的特性和依赖等属性定义在build/lite/components目录下对应子系统的json文件中,新增组件时需要在对应子系统json文件中添加相应的组件定义。产品所配置的组件必须在某个子系统中被定义过,否则会校验失败。 - 以泛sensor子系统的sensor服务组件为例,组件属性定义描述文件字段说明如下: ``` @@ -125,13 +149,15 @@ component } ``` -组件的编译脚本语言为gn,gn的基本用法请见[gn快速入门](https://gn.googlesource.com/gn/+/master/docs/quick_start.md)。组件即为gn定义的编译目标,可以为静态库、动态库、可执行文件或group。组件BUILD.gn的编写建议如下: +组件BUILD.gn的编写建议如下: -1)编译目标名称与组件一致。 +- 编译目标名称与组件一致。 +- 组件对外可配置的特性变量需声明在该组件BUILD.gn中,特性变量命名规则:ohos\_\{subsystem\}\_\{component\}\_\{feature\}。特性在组件描述中也需要同步定义,在产品配置文件config.json中按需配置。 +- 宏定义规则:OHOS\_\{SUBSYSTEM\}\_\{COMPONENT\}\_\{FEATURE\} -2)组件对外可配置的特性变量需声明在该组件BUILD.gn中,特性变量命名规则:ohos\_\{subsystem\}\_\{component\}\_\{feature\}。特性在组件描述中也需要同步定义,在产品配置文件config.json中按需配置。 + >![](public_sys-resources/icon-note.gif) **说明:** + >组件的编译脚本语言为gn,gn的基本用法请见[gn快速入门](https://gn.googlesource.com/gn/+/master/docs/quick_start.md)。组件即为gn定义的编译目标,可以为静态库、动态库、可执行文件或group。 -3)宏定义规则:OHOS\_\{SUBSYSTEM\}\_\{COMPONENT\}\_\{FEATURE\} 以图形的UI组件为例,foundation/graphic/ui/BUILD.gn文件如下: @@ -180,9 +206,13 @@ component } ``` -- **芯片解决方案** +### **芯片解决方案** + +- 芯片解决方案是指基于某款开发板的完整解决方案,包含驱动、设备侧接口适配、开发板sdk等。 +- 芯片解决方案是一个特殊的组件,源码路径规则为:**device/\{芯片解决方案厂商\}/\{开发板\}**。 +- 芯片解决方案组件会随产品选择的开发板默认编译。 -芯片解决方案是指基于某款开发板的完整解决方案,包含驱动、设备侧接口适配、开发板sdk等。芯片解决方案是一个特殊的组件,源码路径规则为:_device/\{芯片解决方案厂商\}/\{开发板\}_。芯片解决方案组件会随产品选择的开发板默认编译。芯片解决方案目录树规则如下: +芯片解决方案目录树规则如下: ``` device @@ -196,7 +226,10 @@ device └── config.gni # liteos_a版本编译配置 ``` -config.gni为开发板编译相关的配置。编译时会采用该配置文件中的参数选择编译相应的OS组件,编译阶段系统全局可见。关键字段介绍如下: +>![](public_sys-resources/icon-note.gif) **说明:** +>config.gni为开发板编译相关的配置,编译时会采用该配置文件中的参数编译所有OS组件,编译阶段系统全局可见。 + +config.gni的关键字段介绍如下: ``` kernel_type: 开发板使用的内核类型,例如:“liteos_a”, “liteos_m”, “linux”。 @@ -211,9 +244,11 @@ board_cxx_flags: 开发板配置的cpp文件编译选项。 board_ld_flags: 开发板配置的链接选项。 ``` -- **产品解决方案** +### **产品解决方案** + +产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、组件拼装配置、启动配置和文件系统配置等。产品解决方案的源码路径规则为:**vendor/\{产品解决方案厂商\}/\{产品名称\}**_。_产品解决方案也是一个特殊的组件。 -产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、组件拼装配置、启动配置和文件系统配置等。源码路径规则为:_vendor/\{产品解决方案厂商\}/\{产品名称\}。_产品解决方案也是一个特殊的组件,目录树规则如下: +产品解决方案的目录树规则如下: ``` vendor @@ -229,25 +264,24 @@ vendor └── ...... ``` -新增产品须按如上的规则创建目录和文件,编译构建系统将按该规则扫描已配置的产品。关键的目录和文件详细介绍如下: +>![](public_sys-resources/icon-caution.gif) **注意:** +>**新增产品须按如上的规则创建目录和文件,编译构建系统将按该规则扫描已配置的产品。** -1. vendor/company/product/init\_configs/etc +关键的目录和文件详细介绍如下: - 该文件夹中包含rcS脚本,Sxxx脚本和fstab脚本,init进程在启动系统服务之前执行这些脚本。执行的流程为“rcS-\>fstab-\>S00-xxx“,Sxxx脚本中的内容与开发板和产品需要有关,主要包括设备节点的创建、创建目录、扫描设备节点、修改文件权限等等。这些文件在产品编译的BUILD.gn中按需拷贝到产品out目录中,最终打包到rootfs镜像中。 - -2. vendor/company/product/init\_configs/init.cfg - - init进程启动服务的配置文件,当前支持解析的命令有: +1. **vendor/company/product/init\_configs/etc** - 1\) start: 启动某个服务 + 该文件夹中包含rcS脚本,Sxxx脚本和fstab脚本。init进程在启动系统服务之前执行这些脚本。执行的流程为“rcS-\>fstab-\>S00-xxx“。Sxxx脚本中的内容与开发板和产品需要有关,主要包括设备节点的创建、创建目录、扫描设备节点、修改文件权限等等。这些文件在产品编译的BUILD.gn中按需拷贝到产品out目录中,最终打包到rootfs镜像中。 - 2\) mkdir: 创建文件夹 +2. **vendor/company/product/init\_configs/init.cfg** - 3)chmod: 修改指定路径/文件的权限 - - 4\) chown: 修改指定路径/文件的属组 + init进程启动服务的配置文件,当前支持解析的命令有: - 5\) mount: 挂载命令 + - start: 启动某个服务 + - mkdir: 创建文件夹 + - chmod: 修改指定路径/文件的权限 + - chown: 修改指定路径/文件的属组 + - mount: 挂载命令 该文件中的各个字段的解释如下: @@ -273,7 +307,7 @@ vendor "start service1" ] }, { - "name" : "post-init", # 最后别执行的job, init进程启动完成后的处理(如驱动初始化后再mount设备) + "name" : "post-init", # 最后执行的job, init进程启动完成后的处理(如驱动初始化后再mount设备) "cmds" : [] } ], @@ -291,13 +325,15 @@ vendor } ``` -3. vendor/company/product/init\_configs/hals +3. **vendor/company/product/init\_configs/hals** 解决方案厂商对OS的适配,需要实现的接口请见各个组件的readme说明文档。 -4. vendor/company/product/config.json +4. **vendor/company/product/config.json** - config.json为编译构建的主入口,包含了开发板、OS组件和内核等配置信息。以基于hispark\_taurus开发板的ipcamera产品为例,配置文件如下: + config.json为编译构建的主入口,包含了开发板、OS组件和内核等配置信息。 + + 以基于hispark\_taurus开发板的ipcamera产品为例,配置文件如下: ``` { @@ -323,7 +359,7 @@ vendor } ``` -5. vendor/company/product/fs.yml +5. **vendor/company/product/fs.yml** 该文件用于配置文件系统镜像制作过程,将编译产物打包成文件系统镜像,比如用户态根文件系统rootfs.img和可读写的userfs.img。它由多个列表组成,每个列表对应一个文件系统。字段说明如下: @@ -364,7 +400,7 @@ vendor >![](public_sys-resources/icon-note.gif) **说明:** >fs.yml是可选的,对于没有文件系统的设备可不配置。 -6. vendor/company/product/BUILD.gn +6. **vendor/company/product/BUILD.gn** 产品编译的入口,主要用于编译解决方案厂商源码和拷贝启动配置文件。如果某个产品被选择为要编译的产品,那么对应产品目录下的BUILD.gn会默认编译。一个典型的产品编译BUILD.gn应该如下: @@ -379,3 +415,582 @@ vendor ``` +## 使用指导 + +### 前提条件 + +开发环境需安装gn、ninja构建工具、python 3.7.4及以上和hb。安装方法请见[搭建系统基础环境](../quick-start/搭建系统环境.md)。 + +### hb工具使用说明 + +hb是OpenHarmony的命令行工具,用来执行编译命令。以下对hb的常用命令进行说明。 + +**hb set** + +``` +hb set -h +usage: hb set [-h] [-root [ROOT_PATH]] [-p] + +optional arguments: + -h, --help show this help message and exit + -root [ROOT_PATH], --root_path [ROOT_PATH] + Set OHOS root path + -p, --product Set OHOS board and kernel +``` + +- hb set 后无参数,进入默认设置流程 +- hb set -root dir可直接设置代码根目录 +- hb set -p设置要编译的产品 + +**hb env** + +查看当前设置信息 + +``` +hb env +[OHOS INFO] root path: xxx +[OHOS INFO] board: hispark_taurus +[OHOS INFO] kernel: liteos +[OHOS INFO] product: ipcamera +[OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera +[OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19 +``` + +**hb build** + +``` +hb build -h +usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]] + [--dmverity] [--tee] [-p PRODUCT] [-f] [-n] + [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch] + [component [component ...]] + +positional arguments: + component name of the component + +optional arguments: + -h, --help show this help message and exit + -b BUILD_TYPE, --build_type BUILD_TYPE + release or debug version + -c COMPILER, --compiler COMPILER + specify compiler + -t [TEST [TEST ...]], --test [TEST [TEST ...]] + compile test suit + --dmverity Enable dmverity + --tee Enable tee + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: camera@huawei + -f, --full full code compilation + -n, --ndk compile ndk + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target + -v, --verbose show all command lines while building + -shs, --sign_haps_by_server + sign haps by server + --patch apply product patch before compiling + + --dmverity Enable dmverity + -p PRODUCT, --product PRODUCT + build a specified product with + {product_name}@{company}, eg: ipcamera@hisilcon + -f, --full full code compilation + -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]] + Compile single target +``` + +- hb build后无参数,会按照设置好的代码路径、产品进行编译,编译选项使用与之前保持一致。-f 选项将删除当前产品所有编译产品,等同于hb clean + hb build. +- hb build \{component\_name\}:基于设置好的产品对应的单板、内核,单独编译组件(e.g.:hb build kv\_store\)。 +- hb build -p ipcamera@hisilicon:免set编译产品,该命令可以跳过set步骤,直接编译产品。 +- 在device/device\_company/board下单独执行hb build会进入内核选择界面,选择完成后会根据当前路径的单板、选择的内核编译出仅包含内核、驱动的镜像。 + +**hb clean** + +清除out目录对应产品的编译产物,仅保留args.gn、build.log。清除指定路径可输入路径参数:hb clean out/board/product,默认将清除当前hb set的产品对应out路径。 + +``` +hb clean +usage: hb clean [-h] [out_path] + +positional arguments: + out_path clean a specified path. + +optional arguments: + -h, --help show this help message and exit +``` + +### 新增组件 + +本小节介绍如何新增一个组件,首先确定组件归属的子系统和组件名称,然后按如下步骤新增: + +1. 源码开发完成后,添加组件编译脚本。 + + 以编译组件hello\_world可执行文件为例,applications/sample/hello\_world/BUILD.gn可以写为: + + ``` + executable("hello_world") { + include_dirs = [ + "include", + ] + sources = [ + "src/hello_world.c" + ] + } + ``` + + 如上编译脚本,可编译出一个可在OpenHarmony上运行的名为hello\_world的可执行文件。 + + 单独编译该组件,hb set任意选择一款产品,然后使用-T选项单独编译组件: + + ``` + hb build -f -T //applications/sample/hello_world + ``` + + 组件在开发板上功能验证完成后,可按[步骤2\~4](#li11471037297)将组件配置到产品中。 + +2. 添加组件描述。 + + 组件描述位于build/lite/components下,新增的组件需加入对应子系统的json文件中。一个组件描述必选的字段有: + + - component:组件名称。 + - description:组件的一句话功能描述。 + - optional:组件是否为系统可选。 + - dirs:组件源码路径。 + - targets:组件编译入口。 + + 以将hello\_world组件加入应用子系统为例,在applications.json中添加hello\_world对象: + + ``` + { + "components": [ + { + "component": "hello_world", + "description": "Hello world.", + "optional": "true", + "dirs": [ + "applications/sample/hello_world" + ], + "targets": [ + "//applications/sample/hello_world" + ] + }, + ... + ] + } + ``` + +3. 将组件配置到产品。 + + 产品的配置文件config.json位于位于vendor/company/product/下,产品配置文件需包含产品名称、OpenHarmony版本号、device厂商、开发板、内核类型、内核版本号,以及配置的子系统和组件。以将hello\_world组件加入产品配置文件my\_product.json中为例,加入hello\_wolrd对象: + + ``` + { + "product_name": "hello_world_test", + "ohos_version": "OpenHarmony 1.0", + "device_company": "hisilicon", + "board": "hispark_taurus", + "kernel_type": "liteos_a", + "kernel_version": "1.0.0", + "subsystems": [ + { + "subsystem": "applications", + "components": [ + { "component": "hello_world", "features":[] } + ] + }, + ... + ] + } + ``` + +4. 编译产品。 + + 1. 代码根目录输入hb set选择对应产品。 + + 2. 执行hb build。 + + +### 新增芯片解决方案 + +编译构建支持添加新的芯片解决方案厂商,具体步骤如下: + +1. 创建芯片解决方案目录。 + + 按照[芯片解决方案配置规则](#section1625463413327)创建目录,以芯片厂商realtek的“rtl8720“开发板为例, 在代码根目录执行: + + ``` + mkdir -p device/realtek/rtl8720 + ``` + +2. 创建内核适配目录,并编写开发板编译配置config.gni文件。 + + 以realtek的“rtl8720“开发板的liteos\_m适配为例,device/realtek/rtl8720/liteos\_a/config.gni的内容如下: + + ``` + # Kernel type, e.g. "linux", "liteos_a", "liteos_m". + kernel_type = "liteos_a" + + # Kernel version. + kernel_version = "3.0.0" + + # Board CPU type, e.g. "cortex-a7", "riscv32". + board_cpu = "real-m300" + + # Board arch, e.g. "armv7-a", "rv32imac". + board_arch = "" + + # Toolchain name used for system compiling. + # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. + # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. + board_toolchain = "gcc-arm-none-eabi" + + # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. + board_toolchain_path = + rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin", + root_build_dir) + + # Compiler prefix. + board_toolchain_prefix = "gcc-arm-none-eabi-" + + # Compiler type, "gcc" or "clang". + board_toolchain_type = "gcc" + + # Board related common compile flags. + board_cflags = [] + board_cxx_flags = [] + board_ld_flags = [] + ``` + +3. 编写编译脚本。 + + 在开发板目录下创建BUILD.gn,target名称应与开发板名称一致。以realtek的rtl8720开发板为例,device/realtek/rtl8720/BUILD.gn内容可以是: + + ``` + group("rtl8720") { # target类型也可以shared_library, static_library, executable + # 具体内容 + ...... + } + ``` + +4. 编译芯片解决方案。 + + 在开发板目录下执行hb build,即可启动芯片解决方案的编译。 + + +### 新增产品解决方案 + +编译构建支持芯片解决方案和组件的灵活拼装,形成定制化的产品解决方案。具体步骤如下: + +1. 创建产品目录 + + 按照[产品解决方案配置规则](#section1625463413327)创建产品目录,以基于“rtl8720“开发板的wifiiot模组为例,在代码根目录执行: + + ``` + mkdir -p vendor/my_company/wifiiot + ``` + +2. 拼装产品 + + 在新建的产品目录下新建config.json文件,以步骤1中的wifiiot为例,vendor/my\_company/wifiiot/config.json可以是: + + ``` + { + "product_name": "wifiiot", # 产品名称 + "ohos_version": "OpenHarmony 1.0", # 使用的OS版本 + "device_company": "realtek", # 芯片解决方案厂商名称 + "board": "rtl8720", # 开发板名称 + "kernel_type": "liteos_m", # 选择的内核类型 + "kernel_version": "3.0.0", # 选择的内核版本 + "subsystems": [ + { + "subsystem": "kernel", # 选择的子系统 + "components": [ + { "component": "liteos_m", "features":[] } # 选择的组件和组件特性 + ] + }, + ... + { + 更多子系统和组件 + } + ] + } + ``` + + 注意:编译构建系统编译前会对device\_company,board,kernel\_type,kernel\_version、subsystem、component字段进行有效性检查,其中device\_company,board,kernel\_type,kernel\_version应与已知的芯片解决方案匹配,subsystem、component应与build/lite/components下的组件描述匹配。 + +3. 适配OS接口 + + 在产品目录下创建hals目录,并将产品解决方案对OS适配的源码和编译脚本放入该目录下。 + +4. 配置系统服务 + + 在产品目录下创建init\_configs目录,并在init\_configs目录下创建init.cfg文件,按需配置要启动的系统服务。 + +5. 配置init进程(仅linux内核需要) + + 在init\_configs目录下创建etc目录,然后在etc下创建init.d文件夹和fstab文件。最后按产品需求在init.d文件下创建并编辑rcS文件和Sxxx文件。 + +6. 配置文件系统镜像(可选,仅支持文件系统的开发板需要) + + 在产品目录下创建fs.yml文件。fs.yml需按产品实际情况配置,一个典型的fs.yml文件如下: + + ``` + - + fs_dir_name: rootfs # 镜像的名称 + fs_dirs: + - + # 将编译生成的out/my_board/my_product/bin目录下的文件拷贝到rootfs/bin中,并忽略测试bin + source_dir: bin + target_dir: bin + ignore_files: + - Test.bin + - TestSuite.bin + - + # 将编译生成的out/my_board/my_product/libs目录下的文件拷贝到rootfs/lib中,忽略所有.a文件,并设置文件和文件夹的权限为644和755 + source_dir: libs + target_dir: lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: usr/lib + target_dir: usr/lib + ignore_files: + - .a + dir_mode: 755 + file_mode: 644 + - + source_dir: config + target_dir: etc + - + source_dir: system + target_dir: system + - + source_dir: sbin + target_dir: sbin + - + source_dir: usr/bin + target_dir: usr/bin + - + source_dir: usr/sbin + target_dir: usr/sbin + - + # 创建一个proc空目录 + target_dir: proc + - + target_dir: mnt + - + target_dir: opt + - + target_dir: tmp + - + target_dir: var + - + target_dir: sys + - + source_dir: etc + target_dir: etc + - + source_dir: vendor + target_dir: vendor + - + target_dir: storage + + fs_filemode: + - + file_dir: lib/ld-uClibc-0.9.33.2.so + file_mode: 555 + - + file_dir: lib/ld-2.24.so + file_mode: 555 + - + file_dir: etc/init.cfg + file_mode: 400 + fs_symlink: + - + # 在rootfs/lib下创建软连接ld-musl-arm.so.1 -> libc.so + source: libc.so + link_name: ${fs_dir}/lib/ld-musl-arm.so.1 + - + source: mksh + link_name: ${fs_dir}/bin/sh + - + source: mksh + link_name: ${fs_dir}/bin/shell + fs_make_cmd: + # 使用脚本将rootfs制作为ext4格式的image + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + - + fs_dir_name: userfs + fs_dirs: + - + source_dir: storage/etc + target_dir: etc + - + source_dir: data + target_dir: data + fs_make_cmd: + - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4 + + ``` + +7. 配置产品Patch(可选,视产品涉及组件是否需要打补丁而定) + + 在产品目录下创建patch.yml文件。patch.yml需按产品实际情况配置,一个典型的patch.yml文件如下: + + ``` + # 需要打patch的路径 + foundation/communication/dsoftbus: + # 该路径下需要打的patch存放路径 + - foundation/communication/dsoftbus/1.patch + - foundation/communication/dsoftbus/2.patch + third_party/wpa_supplicant: + - third_party/wpa_supplicant/1.patch + - third_party/wpa_supplicant/2.patch + - third_party/wpa_supplicant/3.patch + ... + ``` + + 配置完成后,编译时增加--patch参数,即可在产品编译前将配置的Patch文件打到对应目录中,再进行编译: + + ``` + hb build -f --patch + ``` + +8. 编写编译脚本 + + 在产品目录下创建BUILD.gn文件,按产品实际情况编写脚本。以步骤1中的wifiiot为例,BUILD.gn示例如下: + + ``` + group("wifiiot") { # target名称与产品名一致 + deps = [] + # 拷贝init配置 + deps += [ "init_configs" ] + # 将hals加入编译 + deps += [ "hals" ] + # 其他 + ...... + } + ``` + +9. 编译产品。 + + 在代码根目录执行hb set按提示选择新增的产品,然后执行hb build即可启动编译。 + + +## 常见问题 + +### ninja版本问题导致编译失败 + +- **现象描述:** + + 编译失败,提示“usr/sbin/ninja: invalid option -- w”。 + +- **可能原因:** + + 编译环境中ninja版本太低,不支持--w选项。 + +- **解决办法:** + + 卸载环境中ninja和gn,按照HarmonyOS官网[获取工具](../get-code/IDE.md)。 + + +### ncurses库缺失导致编译失败 + +- **现象描述:** + + 编译失败,提示“/usr/bin/ld: cannot find -lncurses”。 + +- **可能原因:** + + 编译环境ncurses库缺失。 + +- **解决办法:** + + ``` + sudo apt-get install lib32ncurses5-dev + ``` + + +### 未安装mcopy导致编译失败 + +- **现象描述:** + + ​编译失败,提示“line 77: mcopy: command not found”。 + +- **可能原因:** + + 编译环境未安装mcopy。 + +- **解决办法:** + + ``` + ​sudo apt-get install dosfstools mtools + ``` + + +### 权限问题导致编译失败 + +- **现象描述:** + + 编译失败,提示“riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory”。 + +- ​**可能原因:** + + 当前用户对riscv编译器路径下的文件访问权限不够。 + +- ​**解决办法:** + + 查询gcc\_riscv32所在目录。 + + ``` + which riscv32-unknown-elf-gcc + ``` + + 使用chmod命令修改目录权限为755。 + + +### 未安装Crypto导致编译失败 + +- **现象描述:** + + 编译失败,提示“No module named 'Crypto'”。 + +- **可能原因:** + + python3未安装Crypto。 + +- **解决办法:** + 1. 查询Python版本号。 + + ``` + python3 --version + ``` + + 2. 需使用python3.7以上版本,然后安装pycryptodome。 + + ``` + sudo pip3 install pycryptodome + ``` + + + +### 编译环境为shell导致编译失败 + +- **现象描述:** + + 编译失败:“xx.sh \[: xx unexpected operator”。 + +- **可能原因:** + + 编译环境shell不是bash。 + +- **解决办法:** + + ``` + sudo rm -rf /bin/sh + sudo ln -s /bin/bash /bin/sh + ``` + + diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\270\270\350\247\201\351\227\256\351\242\230.md" deleted file mode 100755 index ca00b2428542c6024ff6fa79649c5814646cfd28..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\345\270\270\350\247\201\351\227\256\351\242\230.md" +++ /dev/null @@ -1,121 +0,0 @@ -# 编译构建常见问题 - -- [由于ninja版本问题导致编译失败](#section1019152312222) -- [由于ncurses库缺失导致编译失败](#section21449422618) -- [由于未安装mcopy导致编译失败](#section12477184992615) -- [由于权限问题导致编译失败](#section178451337202716) -- [由于未安装Crypto导致编译失败](#section1241481172819) -- [由于编译环境为shell导致编译失败](#section3691222152919) - -## 由于ninja版本问题导致编译失败 - -- **现象描述:** - - 编译失败,提示“usr/sbin/ninja: invalid option -- w”。 - -- **可能原因:** - - 编译环境中ninja版本太低,不支持--w选项。 - -- **解决办法:** - - 卸载环境中ninja和gn,按照HarmonyOS官网[获取工具](../get-code/获取工具.md)。 - - -## 由于ncurses库缺失导致编译失败 - -- **现象描述:** - - 编译失败,提示“/usr/bin/ld: cannot find -lncurses”。 - -- **可能原因:** - - 编译环境ncurses库缺失。 - -- **解决办法:** - - ``` - sudo apt-get install lib32ncurses5-dev - ``` - - -## 由于未安装mcopy导致编译失败 - -- **现象描述:** - - ​编译失败,提示“line 77: mcopy: command not found”。 - -- **可能原因:** - - 编译环境未安装mcopy。 - -- **解决办法:** - - ``` - ​sudo apt-get install dosfstools mtools - ``` - - -## 由于权限问题导致编译失败 - -- **现象描述:** - - 编译失败,提示“riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory”。 - -- ​**可能原因:** - - 当前用户对riscv编译器路径下的文件访问权限不够。 - -- ​**解决办法:** - 1. 查询gcc\_riscv32所在目录。 - - ``` - which riscv32-unknown-elf-gcc - ``` - - 2. 使用chmod命令修改目录权限为755。 - - -## 由于未安装Crypto导致编译失败 - -- **现象描述:** - - 编译失败,提示“No module named 'Crypto'”。 - -- **可能原因:** - - python3未安装Crypto。 - -- **解决办法:** - 1. 查询Python版本号。 - - ``` - python3 --version - ``` - - 2. 需使用python3.7以上版本,然后安装pycryptodome。 - - ``` - sudo pip3 install pycryptodome - ``` - - - -## 由于编译环境为shell导致编译失败 - -- **现象描述:** - - 编译失败:“xx.sh \[: xx unexpected operator”。 - -- **可能原因:** - - 编译环境shell不是bash。 - -- **解决办法:** - - ``` - sudo rm -rf /bin/sh - sudo ln -s /bin/bash /bin/sh - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260-0.md" "b/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260-0.md" deleted file mode 100755 index 1bd7dd28d93785765d46a6c7585280e1fe6d390a..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\347\274\226\350\257\221\346\236\204\345\273\272\346\246\202\350\277\260-0.md" +++ /dev/null @@ -1,58 +0,0 @@ -# 编译构建概述 - -- [基本概念](#section175012297491) -- [运作机制](#section193961322175011) -- [约束与限制](#section2029921310472) - -编译构建子系统提供了一个基于gn和ninja的编译构建框架。主要提供以下功能: - -- 构建不同芯片平台的产品。如:Hi3516DV300平台。 - -- 根据产品配置可以按照组件组装打包产品需要的能力。 - -## 基本概念 - -在了解编译构建子系统的能力前,应了解如下基本概念: - -- 平台 - - 开发板和内核的组合,不同平台支持的子系统和组件不同。 - -- 子系统 - - OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 \> 子系统 \> 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。子系统是一个逻辑概念,它具体由对应的组件构成。 - -- 组件 - - 对子系统的进一步拆分,可复用的软件单元,它包含源码、配置文件、资源文件和编译脚本;能独立构建,以二进制方式集成,具备独立验证能力的二进制单元。 - -- gn - - Generate ninja的缩写,用于产生ninja文件。 - -- ninja - - ninja是一个专注于速度的小型构建系统。 - - -## 运作机制 - -OpenHarmony侧的编译构建流程主要包括编译命令行解析,调用gn,执行ninja: - -- 命令行解析:解析待编译的产品名称,加载相关配置。 -- 调用gn: 根据命令行解析的产品名称和编译类型,配置编译工具链和全局的编译选项。 -- 执行ninja:启动编译并生成对应的产品版本。 - -## 约束与限制 - -- 需按照[源码获取](../get-code/源码获取.md)指导下载全量源码(采用方式三获取)。 -- 编译环境需要Ubuntu18.04及以上版本。 -- 安装编译所需的程序包。 - - 安装命令: - - ``` - sudo apt-get install binutils git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 - ``` - - diff --git "a/zh-cn/device-dev/subsystems/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" "b/zh-cn/device-dev/subsystems/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" deleted file mode 100755 index e85c33895c2a4348209433745b10487457589a5d..0000000000000000000000000000000000000000 --- "a/zh-cn/device-dev/subsystems/\350\275\273\351\207\217\345\222\214\345\260\217\345\236\213\347\263\273\347\273\237\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 轻量和小型系统编译构建指导 - -- **[编译构建概述](编译构建概述.md)** - -- **[编译构建使用指导](编译构建使用指导.md)** - -- **[编译构建常见问题](编译构建常见问题.md)** - - diff --git "a/zh-cn/device-dev/quick-start/\345\257\274\350\257\273.md" "b/zh-cn/device-dev/\345\257\274\350\257\273.md" old mode 100755 new mode 100644 similarity index 83% rename from "zh-cn/device-dev/quick-start/\345\257\274\350\257\273.md" rename to "zh-cn/device-dev/\345\257\274\350\257\273.md" index 95d9b60b723551ddcf8f06602353ecd82d62159a..5927fe29580d014356e247e03a15a17f6a24eafb --- "a/zh-cn/device-dev/quick-start/\345\257\274\350\257\273.md" +++ "b/zh-cn/device-dev/\345\257\274\350\257\273.md" @@ -30,6 +30,9 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按 ## 文档导读 +- [轻量和小型系统开发指导](#table3762949121211) +- [标准系统开发指导](#table17667535516) + **表 1** 轻量和小型系统开发指导(参考内存<128MB) @@ -45,49 +48,49 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按

整体认知OpenHarmony

- +

获取开发资源

准备开发前相关资源

- +

快速入门

快速熟悉OpenHarmony环境搭建、编译、烧录、调测、运行。

-

轻量和小型系统快速入门

+

轻量和小型系统入门

基础能力使用

使用OpenHarmony提供的基础能力

- +

进阶开发

结合系统能力开发智能设备

- +

移植适配

  • 针对特定芯片做移植适配
  • 对三方库进行移植适配
- +

贡献组件

OpenHarmony贡献功能组件

- +

参考

@@ -115,49 +118,49 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按

整体认知OpenHarmony

- +

获取开发资源

准备开发前相关资源

- +

快速入门

快速熟悉OpenHarmony环境搭建、编译、烧录、调测、运行。

-

标准系统快速入门

+

标准系统入门

基础能力使用

使用OpenHarmony提供的基础能力

- +

进阶开发

结合系统能力开发智能设备

- +

移植适配

对三方库进行移植适配

-

三方库移植指导

+

三方库移植指导

贡献组件

OpenHarmony贡献功能组件

- +

参考

diff --git a/zh-cn/readme.md b/zh-cn/readme.md index 78b1dc6acf653695b9ff9f1ec9f38f6a38d19ca2..b2c4e67dca56025dee5fa6caa3a0874b0109b258 100644 --- a/zh-cn/readme.md +++ b/zh-cn/readme.md @@ -7,7 +7,7 @@ - [Openharmony概述](OpenHarmony-Overview_zh.md) - 轻量和小型系统开发指导(参考内存<128MB) - 设备开发 - - overview:[设备开发导读](device-dev/quick-start/导读.md) + - overview:[设备开发导读](device-dev/导读.md) - quick-start:[快速入门](device-dev/quick-start/Readme-CN.md)(搭建环境、获取源码、编译、烧录等) - 开发基础能力 - Kernel:[轻量和小型系统内核](device-dev/kernel/轻量和小型系统内核.md) @@ -31,7 +31,7 @@ - 标准系统开发指导(参考内存≥128MB) - 设备开发 - - overview:[设备开发导读](device-dev/quick-start/导读.md) + - overview:[设备开发导读](device-dev/导读.md) - quick-start:[快速入门](device-dev/quick-start/Readme-CN.md)(搭建环境、获取源码、编译、烧录等) - 开发基础能力 - Kernel:[标准系统内核](device-dev/kernel/标准系统内核.md) @@ -40,7 +40,7 @@ - Security:[隐私与安全](device-dev/security/Readme-CN.md) - guide:[开发示例](device-dev/guide/Readme-CN.md) - - [时钟应用](device-dev/guide/时钟应用开发示例.md) + - [时钟应用](device-dev/guide/时钟应用开发指导.md) - [平台驱动](device-dev/guide/平台驱动开发示例.md) - [外设驱动](device-dev/guide/外设驱动开发示例.md)