From 046d368029b15b8c831b59765c7406e91f038d41 Mon Sep 17 00:00:00 2001 From: Annie_wang Date: Thu, 5 May 2022 16:21:06 +0800 Subject: [PATCH] update docs Signed-off-by: Annie_wang --- .../driver/driver-hdf-development.md | 194 +++++----- en/device-dev/driver/driver-hdf-manage.md | 324 ++++++++-------- .../driver/driver-hdf-message-management.md | 355 ++++++++---------- en/device-dev/driver/driver-hdf-overview.md | 26 +- en/device-dev/driver/driver-hdf-sample.md | 41 +- .../driver/driver-hdf-servicemanage.md | 265 ++++++------- .../driver/driver-peripherals-touch-des.md | 6 +- .../driver/driver-platform-adc-develop.md | 2 +- .../driver/driver-platform-dac-develop.md | 2 +- .../driver/driver-platform-i2c-develop.md | 2 +- .../driver/driver-platform-i3c-develop.md | 2 +- .../driver/driver-platform-mipidsi-develop.md | 2 +- .../driver/driver-platform-mmc-develop.md | 2 +- .../driver/driver-platform-pwm-develop.md | 2 +- .../driver/driver-platform-rtc-develop.md | 2 +- .../driver/driver-platform-sdio-develop.md | 2 +- .../driver/driver-platform-uart-develop.md | 8 +- .../driver-platform-watchdog-develop.md | 2 +- 18 files changed, 608 insertions(+), 631 deletions(-) diff --git a/en/device-dev/driver/driver-hdf-development.md b/en/device-dev/driver/driver-hdf-development.md index 192e813d41..b6ffbe9f43 100644 --- a/en/device-dev/driver/driver-hdf-development.md +++ b/en/device-dev/driver/driver-hdf-development.md @@ -3,83 +3,89 @@ ## Driver Model -The Hardware Driver Foundation (HDF) is designed based on the component-based driver model. This model allows refined driver management and standardize driver development and deployment. 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 figure below shows the HDF driver model. +The Hardware Driver Foundation (HDF) is designed upon a component-based driver model. This model enables refined driver management and streamlines driver development and deployment. In the HDF, the same type of device drivers are placed in a host. You can develop and deploy the drivers separately. One driver can have multiple nodes. + +The figure below shows the HDF driver model. **Figure 1** HDF driver model ![](figures/hdf-driver-model.png) -## How to Development +## How to Develop -The HDF-based driver development involves driver implementation and driver configuration. The development procedure is as follows: +The HDF-based driver development involves driver implementation and configuration. The procedure is as follows: -1. Implement a driver. - To implement a driver, compile driver service code and register a driver entry. +1. Implement a driver.
+ Write the driver code and register the driver entry with the HDF. - - Driver service code - - ``` - #include "hdf_device_desc.h" // Header file that describes the APIs provided by the HDF to the driver. - #include "hdf_log.h" // Header file that describes the log APIs provided by the HDF. - - #define HDF_LOG_TAG "sample_driver" // Tag contained in logs. If no tag is not specified, the default HDF_TAG is used. - - // Service capabilities provided by the driver. Bind the service APIs to the HDF. - int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver bind success"); - return 0; - } - - // Initialize the driver service. - int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver Init success"); - return 0; - } - - // Release the driver resources. - void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) - { - HDF_LOGD("Sample driver release success"); - return; - } - ``` + - Writing the driver service code + + The following is an example: + + ``` + #include "hdf_device_desc.h" // Header file that defines the driver development APIs provided by the HDF. + #include "hdf_log.h" // Header file that defines the log APIs provided by the HDF. + + #define HDF_LOG_TAG "sample_driver" // Tag contained in logs. If no tag is not specified, the default HDF_TAG is used. + + // Bind the service interface provided by the driver to the HDF. + int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver bind success"); + return 0; + } + + // Initialize the driver service. + int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver Init success"); + return 0; + } + + // Release the driver resources. + void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) + { + HDF_LOGD("Sample driver release success"); + return; + } + ``` + - Registering the driver entry with the HDF - - ``` - // Define a driver entry object. It must be a global variable of the HdfDriverEntry type (defined in hdf_device_desc.h). - struct HdfDriverEntry g_sampleDriverEntry = { - .moduleVersion = 1, - .moduleName = "sample_driver", - .Bind = HdfSampleDriverBind, - .Init = HdfSampleDriverInit, - .Release = HdfSampleDriverRelease, - }; - - // Call HDF_INIT to register the driver entry with the HDF. 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 resources and exit the driver model. - HDF_INIT(g_sampleDriverEntry); - ``` - -2. Build the driver. - - LiteOS + + + ``` + // Define a driver entry object. It must be a global variable of the HdfDriverEntry type (defined in hdf_device_desc.h). + struct HdfDriverEntry g_sampleDriverEntry = { + .moduleVersion = 1, + .moduleName = "sample_driver", + .Bind = HdfSampleDriverBind, + .Init = HdfSampleDriverInit, + .Release = HdfSampleDriverRelease, + }; + + // Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind() function and then the Init() function. If the Init() function fails to be called, the HDF will call Release() to release driver resources and exit the driver model. + HDF_INIT(g_sampleDriverEntry); + ``` + +2. Build the driver.
+ - LiteOS
Modify **makefile** and **BUILD.gn**. - - makefile: + - **makefile**:
Use the **makefile** template provided by the HDF to compile the driver code. ``` include $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mk # Import the content predefined by the HDF. This operation is mandatory. MODULE_NAME := # File to be generated. - LOCAL_INCLUDE: = # Header file directory of the driver. + LOCAL_INCLUDE: = # Directory of the driver header files. LOCAL_SRCS : = # Source code file of the driver. LOCAL_CFLAGS : = # Custom compilation options. include $(HDF_DRIVER) # Import the makefile template to complete the compilation. ``` - Add the path of the generated file to **hdf_lite.mk** in the **drivers/adapter/khdf/liteos** directory to link the file to the kernel image. The following is an example: + Add the path of the generated file to **hdf_lite.mk** in the **drivers/adapter/khdf/liteos** directory to link the file to the kernel image. ``` @@ -87,7 +93,7 @@ The HDF-based driver development involves driver implementation and driver confi LIB_SUBDIRS += # Directory in which the driver code makefile is located. ``` - - **BUILD.gn**: + - **BUILD.gn**:
Add **BUILD.gn**. The content of **BUILD.gn** is as follows: @@ -98,18 +104,18 @@ The HDF-based driver development involves driver implementation and driver confi module_name = "xxx" hdf_driver(module_name) { sources = [ - "xxx/xxx/xxx.c", # Source code file of the driver + "xxx/xxx/xxx.c", # Source code to compile. ] - public_configs = [ ":public" ] # Configuration applied to dependencies + public_configs = [ ":public" ] # Head file configuration of the dependencies. } - config("public") {# Configuration of the dependencies + config("public") {# Define the head file configuration of the dependencies. include_dirs = [ - "xxx/xxx/xxx", # Directory of the dependency header file. + "xxx/xxx/xxx", # Directory of the dependency header files. ] } ``` - Add the directory where the **BUILD.gn** file of the driver is located to **/drivers/adapter/khdf/liteos/BUILD.gn**. + Add the **BUILD.gn** directory to **/drivers/adapter/khdf/liteos/BUILD.gn**. ``` @@ -120,7 +126,7 @@ The HDF-based driver development involves driver implementation and driver confi ] } ``` - - Linux + - Linux
To define the driver control macro, add the **Kconfig** file to the driver directory **xxx** and add the path of the **Kconfig** file to **drivers/adapter/khdf/linux/Kconfig**. @@ -142,25 +148,25 @@ The HDF-based driver development involves driver implementation and driver confi obj-y += xxx.o ``` -3. Configure the driver. - HDF Configuration Source (HCS) is the source code that describes the configuration of the HDF. For details about the HCS, see [Driver Configuration Management](../driver/driver-hdf-manage.md). +3. Configure the driver.
+ The HDF Configuration Source (HCS) contains the source code of HDF configuration. For details about the HCS, see [Configuration Management](../driver/driver-hdf-manage.md). The driver configuration consists of the driver device description defined by the HDF and the private driver configuration. - - (Mandatory) Driver device description - The information required for the HDF to load drivers comes from the driver device description defined by the HDF. Therefore, the device description must be added to the configuration file **device_info.hcs** defined by the HDF for drivers developed based on the HDF. The following is an example: + - (Mandatory) Setting the driver device description
+ The HDF loads a driver based on the driver device description defined by the HDF. Therefore, the driver device description must be added to the **device_info.hcs** file defined by the HDF. The following is an example: ``` root { device_info { match_attr = "hdf_manager"; - template host { // Host template. If the node (for example, sample_host) uses the default values in the template, the values of the node fields can be omitted. + template host { // Host template. If a node (for example, sample_host) uses the default values in this template, the node fields can be omitted. hostName = ""; priority = 100; - uid = ""; // User ID (UID) of the user-mode process. By default, it is left empty, that is, set to the value defined for hostName, which indicates a common user. - gid = ""; // Group ID (GID) of the user-mode process. By default, it is left empty, that is, set to the value defined for hostName, which indicates a common user group. - caps = [""]]; // Linux capabilities of the user-mode process. It is left empty by default. Set this parameter based on service requirements. + uid = ""; // User ID (UID) of a user-mode process. It is left empty by default. If you do not set the value, this parameter will be set to the value of hostName, which indicates a common user. + gid = ""; // Group ID (GID) of a user-mode process. It is left empty by default. If you do not set the value, this parameter will be set to the value of hostName, which indicates a common user group. + caps = [""]]; // Linux capabilities of a user-mode process. It is left empty by default. Set this parameter based on service requirements. template device { template deviceNode { policy = 0; @@ -174,17 +180,17 @@ The HDF-based driver development involves driver implementation and driver confi } } sample_host :: host{ - hostName = "host0"; // Host name. The host node is used to store a type of drivers. - priority = 100; // Host startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the host loading sequence is random. + hostName = "host0"; // Host name. The host node is used as a container to hold a type of drivers. + priority = 100; // Host startup priority (0-200). A smaller value indicates a higher priority. The default value 100 is recommended. The hosts with the same priority start based on the time when the priority was configured. The host configured first starts first. caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH"]; // Linux capabilities of the user-mode process. device_sample :: device { // Sample device node. device0 :: deviceNode { // DeviceNode of the sample driver. - policy = 1; // Driver service release policy. For details, see the 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 host loading sequence is random. - preload = 0; // On-demand loading of the driver. For details, see "NOTE" at the end of this section. + policy = 1; // Policy for providing the driver service. For details, see Driver Service Management. + priority = 100; // Driver startup priority (0-200). A smaller value indicates a higher priority. The default value 100 is recommended. The drivers with the same priority start based on the time when the priority was configured. The driver configured first starts first. + preload = 0; // The loading mode of the driver is on-demand loading. For details, see "NOTE" at the end of this document. permission = 0664; // Permission for the driver to create a device node. - moduleName = "sample_driver"; // Driver name. The value of this field must be the same as that of moduleName in the HdfDriverEntry structure. - serviceName = "sample_service"; // Name of the service published by the driver. The service name must be unique. + moduleName = "sample_driver"; // Driver name. The value must be the same as that of moduleName in the HdfDriverEntry structure. + serviceName = "sample_service"; // Name of the service provided by the driver. The service name must be unique. deviceMatchAttr = "sample_config"; // Keyword for 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. } } @@ -192,32 +198,36 @@ The HDF-based driver development involves driver implementation and driver confi } } ``` - > ![icon-note.gif](../public_sys-resources/icon-note.gif) **NOTE**
+ ![icon-note.gif](../public_sys-resources/icon-note.gif) **NOTE**
- - **uid**, **gid**, and **caps** are startup configuration for user-mode drivers and do not need to be configured for kernel-mode drivers. + - **uid**, **gid**, and **caps** are startup parameters for user-mode drivers only. - According to the principle of least privilege for processes, **uid** and **gid** do not need to be configured for service modules. In the preceding example, **uid** and **gid** are left empty (granted with the common user rights) for sample_host. - - If you need to set **uid** and **gid** to **system** or **root** due to service requirements, contact security experts for review. - - The process UID is configured in **base/startup/init_lite/services/etc/passwd**, and the process GID is configured in **base/startup/init_lite/services/etc/group**. For details, see [Adding a System Service User Group]( https://gitee.com/openharmony/startup_init_lite/wikis). - - If CAP_DAC_OVERRIDE needs to be configured for a service module, set **caps = ["DAC_OVERRIDE"]** instead of **caps = ["CAP_DAC_OVERRIDE"]**. + - If you need to set **uid** and **gid** to **system** or **root** due to service requirements, contact security experts for review. + - The process UIDs are configured in **base/startup/init_lite/services/etc/passwd**, and the process GIDs are configured in **base/startup/init_lite/services/etc/group**. For details, see [Adding a System Service User Group]( https://gitee.com/openharmony/startup_init_lite/wikis). + - If CAP_DAC_OVERRIDE needs to be configured for a service module, enter **caps = ["DAC_OVERRIDE"]** instead of **caps = ["CAP_DAC_OVERRIDE"]**. - - (Optional) Private configuration information of the driver - If the driver has private configuration, you can add a driver configuration file to set default driver configuration. When loading the driver, the HDF obtains and saves the corresponding configuration in **property** of **HdfDeviceObject**, and passes the configuration to the driver through **Bind()** and **Init()** (see step 1). The following is an example of the driver configuration: + - (Optional) Setting driver private information
+ If the driver has private configuration, add a driver configuration file to set default driver configuration. When loading the driver, the HDF obtains and saves the driver private information in **property** of **HdfDeviceObject**, and passes the information to the driver using **Bind()** and **Init()** (see step 1). + The following is an example of the driver private configuration: + ``` root { SampleDriverConfig { sample_version = 1; sample_bus = "I2C_0"; - match_attr = "sample_config"; // The value of this field must be the same as that of deviceMatchAttr in device_info.hcs. + match_attr = "sample_config"; // The value must be the same as that of deviceMatchAttr in device_info.hcs. } } ``` - - After the configuration, add the configuration file to the board-level configuration entry file **hdf.hcs**. (You can use DevEco to perform on-click configuration. For details, see the description about the driver development suite.) The following is an example: + After the configuration, add the configuration file to the board-level configuration entry file **hdf.hcs**. (You can use DevEco to perform one-click configuration. For details, see the description about the driver development suite.) + + The following is an example: + ``` #include "device_info/device_info.hcs" @@ -225,7 +235,7 @@ The HDF-based driver development involves driver implementation and driver confi ``` -> ![icon-note.gif](../public_sys-resources/icon-note.gif) **NOTE**
+> ![icon-note.gif](../public_sys-resources/icon-note.gif) **NOTE**
> Drivers can be loaded on demand or in sequence. > > - On-demand loading @@ -239,11 +249,11 @@ The HDF-based driver development involves driver implementation and driver confi > } DevicePreload; > ``` > -> If **preload** in the configuration file is set to **0** (**DEVICE_PRELOAD_ENABLE**), the driver is loaded by default during the system boot process. +> If **preload** in the configuration file is set to **0 (DEVICE_PRELOAD_ENABLE)**, the driver is loaded by default during the system boot process. > -> If **preload** is set to **1** (**DEVICE\_PRELOAD\_ENABLE\_STEP2**), the driver is loaded after a quick start is complete if the system supports quick start. If the system does not support quick start, the value **1** has the same meaning as **DEVICE\_PRELOAD\_ENABLE**. +> If **preload** is set to **1 (DEVICE_PRELOAD_ENABLE_STEP2)**, the driver is loaded after a quick start is complete. If the system does not support quick start, the value **1** has the same meaning as **DEVICE_PRELOAD_ENABLE**. > -> If **preload** is set to **2** (**DEVICE\_PRELOAD\_DISABLE**), the driver is dynamically loaded instead of being loaded during the system boot process. When a user-mode process requests the driver service (for details, see [Driver Message Mechanism Management](driver-hdf-message-management.md)), the HDF attempts to dynamically load the driver if the driver service does not exist. +> If **preload** is set to **2 (DEVICE_PRELOAD_DISABLE)** , the driver is dynamically loaded instead of being loaded during the system boot process. When a user-mode process requests the driver service, the HDF attempts to dynamically load the driver if the driver service does not exist. For more details, see [Driver Messaging Mechanism](driver-hdf-message-management.md). > -> - Sequential loading (drivers must be loaded by default) -> In the configuration file, the **priority** field \(value range: 0 to 200\) indicates the priority of the host and driver. For drivers in different hosts, a smaller host priority value indicates a higher driver loading priority; for drivers in the same host, a smaller driver priority value indicates a higher driver loading priority. +> - Sequential loading (**preload** set to **0 (DEVICE_PRELOAD_ENABLE)**)
+> In the configuration file, the **priority** fields (value range: 0 to 200) determines the loading sequence of a host and a driver. For drivers in different hosts, a smaller host priority value indicates a higher driver loading priority; for drivers in the same host, a smaller driver priority value indicates a higher driver loading priority. diff --git a/en/device-dev/driver/driver-hdf-manage.md b/en/device-dev/driver/driver-hdf-manage.md index 7acd765714..abef772fb0 100644 --- a/en/device-dev/driver/driver-hdf-manage.md +++ b/en/device-dev/driver/driver-hdf-manage.md @@ -1,107 +1,72 @@ -# Driver Configuration Management - -## HDF Configuration Overview - -HCS is the source code that describes the configuration of the HDF using key-value pairs. It decouples the configuration code from driver code, thereby facilitating configuration management. - -HDF Configuration Generator \(HC-GEN\) is a tool for converting a configuration file into a file that can be read by the target software. - -- In a low-performance system on a chip \(SoC\), this tool can convert a configuration file into the source code or macro definitions of the configuration tree so that the driver can obtain the configuration by calling the C library code or macro-based APIs. -- In a high-performance SoC, this tool can convert an HCS configuration file into the HDF Configuration Binary \(HCB\) file, allowing the driver to obtain the configuration through the APIs provided by the HDF. - -The following figure shows the typical application scenario of the HCB mode. - -**Figure 1** Configuration process -![](figures/configuration-process.png "configuration-process") - -The HCS is compiled using the HC-GEN tool to generate an HCB file. The HCS Parser module in the HDF recreates a configuration tree using the HCB file. Then, the HDF driver modules obtain the configurations using the API provided by the HCS Paser. - -## Configuration Syntax - -The HCS syntax is described as follows: - -### Keywords - -The keywords listed in the following table below are reserved for HCS configuration files. - -**Table 1** Reserved keywords for HCS configuration files - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Keywords

-

Description

-

Remarks

-

root

-

Configures the root node.

-

-

-

include

-

References other HCS configuration files.

-

-

-

delete

-

Deletes a node or an attribute.

-

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

-

template

-

Defines a template node.

-

-

-

match_attr

-

Marks the node attribute for matching.

-

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

-
- -### Basic Structures - -The HCS configuration file consists of configurations of attributes and nodes. - -**Attributes** - -An attribute, as the minimum configuration unit, is an independent configuration item. Its syntax is as follows: +# Configuration Management -``` - attribute_name = value; -``` -- The value of **attribute\_name** is a case-sensitive string of characters starting with a letter and consisting of letters, digits, and underscores \(\_\). +## HDF Configuration Overview + +HDF Configuration Source (HCS) is the source code that describes the HDF configuration in key-value pairs. It decouples the configuration code from driver code, simplifying configuration management. + +HDF Configuration Generator (HC-GEN) is a tool for converting an HDF configuration file into a file that can be read by the software. + +- In a low-performance system on a chip (SoC), this tool converts an HCS configuration file into the source code or macro definitions of the configuration tree. The driver can obtain the configuration by calling the C library code or macro-based APIs. + +- In a high-performance SoC, this tool converts an HCS configuration file into an HDF Configuration Binary (HCB) file. The driver can obtain the configuration by calling the configuration parsing APIs provided by the HDF. + +The figure below illustrates how an HCB file is used. + + **Figure 1** Process of using an HCB file -- Available formats of **value** are as follows: + ![](figures/HCB-using-process.png) - - A binary, octal, decimal, or hexadecimal integer. For details, see [Data Types](#section177001259134). +The HC-GEN converts the HCS into an HCB file. The HCS Parser module in the HDF rebuilds a configuration tree from the HCB file. The HDF driver obtains the configuration through the configuration read API provided by the HCS Parser. - - A character string. The content should be enclosed in double quotation marks \(" "\). - - A node reference +## Configuration Syntax +The following describes the HCS syntax. -- An attribute key-value pair must end with a semicolon \(;\) and belong to a node. +### Keywords -**Nodes** +The table below describes the keywords used in the HCS syntax. + + **Table 1** Keywords used in HCS syntax + +| Keyword| Description| Remarks| +| -------- | -------- | -------- | +| root | Sets the root node.| - | +| include | References other HCS files.| - | +| delete | Deletes a node or an attribute.| Applicable only to the configuration tree referenced by **include**.| +| template | Defines a template node.| - | +| match_attr | Marks the node attribute for matching.| During configuration parsing, the attribute value can be used to locate the corresponding node.| + + +### Basic Structures + +The HCS has two structures: attribute and node. + +**Attribute** + +An attribute is the minimum, independent configuration unit. The syntax is as follows: + + +``` + attribute_name = value; +``` + +- **attribute_name** is a case-sensitive string of letters, digits, and underscores (_) and must start with a letter or underscore (_). + +- The **value** can be in any of the following formats: + + - A binary, octal, decimal, or hexadecimal integer. For details, see the **Data Types** section. + - String quoted by double quotation marks (""). + - Node reference. + +- An attribute key-value pair must end with a semicolon (;) and belong to a node. + +**Node** + +A node is a set of attributes. The syntax is as follows: -A node is a set of attributes. Its syntax is as follows: ``` node_name { @@ -110,39 +75,40 @@ A node is a set of attributes. Its syntax is as follows: } ``` -- The value of **node\_name** is a case-sensitive string of characters starting with a letter and consisting of letters, digits, and underscores \(\_\). +- **node_name** is a case-sensitive string of letters, digits, and underscores (_) and must start with a letter or underscore (_). -- A semicolon \(;\) is not required after the curly brace \(\}\). +- No semicolon (;) is required after the curly brace ({) or (}). -- The reserved keyword **root** is used to declare the root node of a configuration table. +- The keyword **root** is used to declare the root node of a configuration table. Each configuration table must start with the root node. -- The root node must contain a **module** attribute that uses a string to represent the module to which the configuration belongs. +- The root node must contain a **module** attribute. The value is a string indicating the module to which the configuration belongs. -- The **match\_attr** attribute can be added to a node. Its value is a globally unique character string. During configuration parsing, the query interface can be invoked to query the nodes with the attribute based on the attribute value. +- The **match_attr** attribute can be added to a node. Its value is a globally unique string. During configuration parsing, the **match_attr** attribute can be used to quickly locate the node that contains the attribute. -### Data Types + +### Data Types Attributes automatically use built-in data types, including integer, string, array, and boolean. You do not need to explicitly specify the data type for the attribute values. **Integer** -An integer can be binary, octal, decimal, or hexadecimal. The minimum space is automatically allocated to the integer based on the actual data length. - -- Binary: prefixed with 0b, for example, 0b1010 + An integer can be binary, octal, decimal, or hexadecimal. The minimum space is automatically allocated to the integer based on the actual data length. +- Binary: prefixed with **0b**, for example, **0b1010**. -- Octal: prefixed with 0, for example, 0664 -- Decimal: either signed or unsigned, without a prefix, for example, 1024 or +1024. Negative integers can be read only via signed interfaces. +- Octal: prefixed with **0**, for example, **0664**. -- Hexadecimal: prefixed with 0x, for example, 0xff00 and 0xFF +- Decimal: signed or unsigned, without prefix, for example, **1024** or **+1024**. Negative integers can be read only via signed interfaces. +- Hexadecimal: prefixed with **0x**, for example, **0xff00** and **0xFF**. **String** -A string is enclosed by double quotation marks \(" "\). +A string is enclosed in double quotation marks (""). **Array** -The elements in an array can be integers or strings, but cannot be a combination of both. The combination of **uint32\_t** and **uint64\_t** in an integer array will enable up-casting to **uint64**. The following is an example of an integer array and a string array: +An array can hold either integers or strings, but not a mixture of them. The mixed use of **uint32_t** and **uint64_t** in an integer array will cause typecasting to **uint64**. The following is an example of an integer array and a string array: + ``` attr_foo = [0x01, 0x02, 0x03, 0x04]; @@ -151,53 +117,62 @@ attr_bar = ["hello", "world"]; **Boolean** -A Boolean data type has two possible values: **true** and **false**. +Boolean data type is a form of data with only two possible values: **true** and **false**. + -### Pre-Processing +### Preprocessing **include** -The **include** keyword is used to import other HCS files. The syntax is as follows: +The keyword **include** is used to import other HCS files. The syntax is as follows: + ``` #include "foo.hcs" #include "../bar.hcs" ``` -- The file names must be enclosed by double quotation marks \(" "\). Files in different directories can be referenced using relative paths. The file included must be a valid HCS file. -- In the scenario that multiple HCS files are imported using **include**, if the same nodes exist, the latter node will override the former one, and other nodes are listed in sequence. +- The file name must be enclosed in double quotation marks (""). If the file to be included is in a different directory with the target file, use a relative path. The included file must be a valid HCS file. + +- If multiple HCS files included contain the same nodes, the same nodes will be overridden and other nodes are listed in sequence. -### Comments -Comments can be formatted as follows: +### Comments -- Single-line comment +The following two comment formats are supported: - ``` - // comment - ``` +- Single-line comment -- Multi-line comment + + ``` + // comment + ``` - ``` - /* - comment - */ - ``` +- Multi-line comment - >![](../public_sys-resources/icon-note.gif) **NOTE:** - >Multi-line comments cannot be nested. + + ``` + /* + comment + */ + ``` + > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
+ > Multi-line comments cannot be nested. -### Reference Modifications -You can use the following syntax to modify the content of any other node: +### Reference Modification + +You can reference the content of a node to modify the content of another node. The syntax is as follows: + ``` node :& source_node ``` -This syntax indicates that the node value is a modification of the source\_node value. Example: +In this statement, the content of **node** is referenced to modify the content of **source_node**. + +Example: ``` root { @@ -220,7 +195,8 @@ root { } ``` -The following configuration tree is generated: +The configuration tree generated is as follows: + ``` root { @@ -236,20 +212,26 @@ root { } ``` -In the preceding example, the **foo.foo\_** node changes the value of the referenced **bar.attr** to "**foo**", and the **foo.foo1** node changes the value of the referenced **foo.foo2.attr** to **0x2**. In the generated configuration tree, **foo.foo\_** and **foo.foo1** are not displayed, but their configuration modifications are presented by their referenced nodes. +In this example, the value of **bar.attr** is changed to **foo** by referencing **foo.foo_**, and the value of **foo.foo2.attr** is changed to **0x2** by referencing **foo.foo1**. The **foo.foo_** and **foo.foo1** nodes are used to modify the content of the target nodes, and do not exist in the configuration tree generated. -- A node of the same level can be referenced simply using the node name. A node of a different level must be referenced by the absolute path, and node names are separated using a period \(.\). **root** indicates the root node. The path format is the node path sequence starting with root. For example, **root.foo.bar** is a valid absolute path. -- If multiple modifications are made to the same attribute, only one uncertain modification can take effect, and a warning will be displayed. +- A node of the same level can be referenced simply using the node name. To reference a node of a different level, use the absolute path starting with **root**, and separate the node names using a period (.). **root** indicates the root node. For example, **root.foo.bar**. -### Node Replication +- If multiple modifications are made to the same attribute, only one modification takes effect and a warning will be displayed for you to confirm the result. + + +### Node Replication + +You can replicate a node to define a node with similar content. The syntax is as follows: -The content of a node can be replicated to another node to define the node with similar content. The syntax is as follows: ``` node : source_node ``` -The preceding statement indicates that the attributes of **source\_node** are replicated to **node**. Example: +This statement replicates the attributes of the **source_node** node to define **node**. + +Example: + ``` root { @@ -263,7 +245,8 @@ root { } ``` -The following configuration tree is generated: +The configuration tree generated is as follows: + ``` root { @@ -278,13 +261,17 @@ root { } ``` -In the preceding example, the **bar** node configuration includes both the **attr\_0** and **attr\_1** values. The modification to **attr\_0** in the **bar** node does not affect the **foo** node. +In this example, the **bar** node contains **attr_0** and **attr_1** attributes, and the modification of the **attr_0** attribute in the **bar** node does not affect the **foo** node. + +You do not need to specify the path of the **foo** node if the **foo** node and the **bar** node are of the same level. Otherwise, specify the absolute path of **foo**. For details, see [Reference Modification](referencemodification). + -The path of the **foo** node is not required if the **foo** node and the **bar** node are of the same level. Otherwise, the absolute path must be used. For details, see [Reference Modifications](#section193708571145). +### Delete -### Delete +You can use the keyword **delete** to delete unnecessary nodes or attributes from the base configuration tree imported by using the **include** keyword. The following example includes the configuration in **sample2.hcs** to **sample1.hcs** and deletes the **attribute2** attribute and the **foo_2** node. + +Example: -You can use the keyword **delete** to delete unnecessary nodes or attributes in the base configuration tree imported by the **include** keyword. In the following example, **sample1.hcs** imports the configuration of **sample2.hcs** using **include**, and deletes the **attribute2** attribute and the **foo\_2** node using the **delete** keyword. ``` // sample2.hcs @@ -305,7 +292,8 @@ root { } ``` -The following configuration tree is generated: +The configuration tree generated is as follows: + ``` root { @@ -313,18 +301,23 @@ root { } ``` ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->The **delete** keyword cannot be used in the same HCS file. It is recommended that you delete unnecessary attributes directly from the configuration source code. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
+> The keyword **delete** cannot be used to delete nodes or attributes in the same HCS file. In an HCS file, you can directly delete unnecessary attributes. + + +### Attribute Reference -### Attribute References +You can associate an attribute and a node so that the node can be quickly located when the attribute is read during configuration parsing. The syntax is as follows: -To quickly locate the associated node during configuration parsing, you can use the node as the value of the attribute and read the attribute to find the corresponding node. The syntax is as follows: ``` attribute = &node; ``` -This syntax indicates that the **attribute** value is a reference to **node**. During code parsing, you can quickly locate the node using this attribute. Example: +In this statement, the value of **attribute** is a referenced to the node. During code parsing, you can quickly locate the node based on this **attribute**. + +Example: + ``` node1 { @@ -334,8 +327,10 @@ node2 { attr_1 = &root.node1; } ``` + Or + ``` node2 { node1 { @@ -345,11 +340,15 @@ node2 { } ``` -### Template -The **template** keyword is used to generate nodes with strictly consistent syntax, thereby facilitating the traverse and management of nodes of the same type. +### Template + +The template is used to generate nodes with consistent syntax, thereby facilitating the traverse and management of nodes of the same type. + +If a node is defined using the keyword **template**, its child nodes inherit from the node configuration through the double colon operator (::). The child nodes can modify or add but cannot delete attributes in **template**. The attributes not defined in the child nodes will use the attributes defined in **template** as the default values. + +Example: -If a node is defined using the keyword **template**, its child nodes inherit the node configuration through the double colon operator \(::\). The child nodes can modify but cannot add or delete attributes in **template**. The attributes not defined in the child nodes will use the attributes defined in **template** as the default values. Example: ``` root { @@ -368,7 +367,8 @@ root { } ``` -The following configuration tree is generated: +The configuration tree generated is as follows: + ``` root { @@ -384,15 +384,18 @@ root { } ``` -In the preceding example, the **bar** and **bar\_1** nodes inherit the **foo** node. The structures of the generated configuration tree nodes are the same as that of the **foo** node, but the attribute values are different. +In this example, the **bar** and **bar_1** nodes inherit from the **foo** node. The structure of the generated configuration tree is the same as that of the **foo** node, except that the attribute values are different. -## Configuration Generation -The HC-GEN tool is used to generate configurations. It checks the HCS configuration syntax and converts HCS source files into HCB files. +## **Configuration Generation** -### Introduction to hc-gen +The HC-GEN tool checks the HCS configuration syntax and converts HCS source files into HCB files. + + +### HC-GEN + +HC-GEN options: -Parameter description: ``` Usage: hc-gen [Options] [File] @@ -410,7 +413,8 @@ options: -h show this help message ``` -Generate a **.c** or **.h** configuration file. +Generate a .c or .h configuration file. + ``` hc-gen -o [OutputCFileName] -t [SourceHcsFileName] @@ -418,19 +422,21 @@ hc-gen -o [OutputCFileName] -t [SourceHcsFileName] Generate an HCB file. + ``` hc-gen -o [OutputHcbFileName] -b [SourceHcsFileName] ``` Generate a macro definition file. + ``` hc-gen -o [OutputMacroFileName] -m [SourceHcsFileName] ``` -Compile an **HCB** file to an **HCS** file: +Decompile an HCB file to an HCS file. + ``` hc-gen -o [OutputHcsFileName] -d [SourceHcbFileName] ``` - diff --git a/en/device-dev/driver/driver-hdf-message-management.md b/en/device-dev/driver/driver-hdf-message-management.md index 14faab8e40..65ae4d200d 100644 --- a/en/device-dev/driver/driver-hdf-message-management.md +++ b/en/device-dev/driver/driver-hdf-message-management.md @@ -1,189 +1,166 @@ -# Driver Message Mechanism Management - -## When to Use - -When user-level applications need to interact with kernel-level drivers, the driver message mechanism of the HDF can be used. - -## Available APIs - -The message mechanism provides the following features: - -1. User-level applications send messages to drivers. -2. User-level applications receive events sent by the drivers. - -**Table 1** APIs for the driver message mechanism - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

struct HdfIoService *HdfIoServiceBind(const char *serviceName)

-

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

-

void HdfIoServiceRecycle(struct HdfIoService *service);

-

Releases a specified driver service.

-

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

-

Receives events sent by the drivers.

-

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

-

Sends events.

-
- -## How to Develop - -1. Set the value of the **policy** field in the driver configuration information to **2** \(SERVICE\_POLICY\_CAPACITY, see [Driver Service Management](driver-hdf-servicemanage.md)\). - - ``` - device_sample :: Device { - policy = 2; - ... - } - ``` - -2. The **permission** field in the driver configuration information indicates the permission provided for the driver to create device nodes. The default value is **0666**. You can configure the value of this field based on the actual application scenario of the driver. -3. Implement the **Dispatch** function of the service base member **IDeviceIoService** during service implementation. - - ``` - // Process messages delivered by user-level applications. - int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) - { - HDF_LOGE("sample driver lite A dispatch"); - return 0; - } - int32_t SampleDriverBind(struct HdfDeviceObject *device) - { - HDF_LOGE("test for lite os sample driver A Open!"); - if (device == NULL) { - HDF_LOGE("test for lite os sample driver A Open failed!"); - return -1; - } - static struct ISampleDriverService sampleDriverA = { - .ioService.Dispatch = SampleDriverDispatch, - .ServiceA = SampleDriverServiceA, - .ServiceB = SampleDriverServiceB, - }; - device->service = (struct IDeviceIoService *)(&sampleDriverA); - return 0; - } - ``` - -4. Define the CMD type in the message processing function. - - ``` - #define SAMPLE_WRITE_READ 1 // Read and write operation 1 - ``` - -5. Enable the user-level application to obtain the service interface and send messages to the driver. - - ``` - int SendMsg(const char *testMsg) - { - if (testMsg == NULL) { - HDF_LOGE("test msg is null"); - return -1; - } - struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); - if (serv == NULL) { - HDF_LOGE("fail to get service"); - return -1; - } - struct HdfSBuf *data = HdfSBufObtainDefaultSize(); - if (data == NULL) { - HDF_LOGE("fail to obtain sbuf data"); - return -1; - } - struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); - if (reply == NULL) { - HDF_LOGE("fail to obtain sbuf reply"); - ret = HDF_DEV_ERR_NO_MEMORY; - goto out; - } - if (!HdfSbufWriteString(data, testMsg)) { - HDF_LOGE("fail to write sbuf"); - ret = HDF_FAILURE; - goto out; - } - int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); - if (ret != HDF_SUCCESS) { - HDF_LOGE("fail to send service call"); - goto out; - } - out: - HdfSBufRecycle(data); - HdfSBufRecycle(reply); - HdfIoServiceRecycle(serv); - return ret; - } - ``` - -6. Enable the user-level application to receive messages reported by the driver. - 1. Enable the user-level application to compile the function for processing messages reported by the driver. - - ``` - static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) - { - OsalTimespec time; - OsalGetTime(&time); - HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); - - const char *string = HdfSbufReadString(data); - if (string == NULL) { - HDF_LOGE("fail to read string in event data"); - return -1; - } - HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); - return 0; - } - ``` - - 2. Enable the user-level application to register the function for receiving messages reported by the driver. - - ``` - int RegisterListen() - { - struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); - if (serv == NULL) { - HDF_LOGE("fail to get service"); - return -1; - } - static struct HdfDevEventlistener listener = { - .callBack = OnDevEventReceived, - .priv ="Service0" - }; - if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { - HDF_LOGE("fail to register event listener"); - return -1; - } - ...... - HdfDeviceUnregisterEventListener(serv, &listener); - HdfIoServiceRecycle(serv); - return 0; - } - ``` - - 3. Enable the driver to report events. - - ``` - int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) - { - ... // process api call here - return HdfDeviceSendEvent(deviceObject, cmdCode, data); - } - ``` - - - +# Driver Messaging Mechanism + + +## When to Use + +The HDF messaging mechanism implements the interaction between the user-mode applications and kernel-mode drivers. + + +## Available APIs + +The messaging mechanism allows: + +1. User-mode applications to send messages to drivers. + +2. User-mode applications to receive events from drivers. + + **Table 1** APIs for the driver messaging mechanism + +| API| Description| +| -------- | -------- | +| struct HdfIoService \*HdfIoServiceBind(const char \*serviceName); | Obtains a driver service. The **Dispatch()** method in the driver service obtained sends messages to the driver.| +| void HdfIoServiceRecycle(struct HdfIoService \*service); | Releases a driver service.| +| int HdfDeviceRegisterEventListener(struct HdfIoService \*target, struct HdfDevEventlistener \*listener); | Registers the method for receiving events reported by the driver.| +| int HdfDeviceSendEvent(struct HdfDeviceObject \*deviceObject, uint32_t id, struct HdfSBuf \*data); | Sends events. | + + +## How to Develop + +1. In the driver configuration, set **policy** to **2**. For more details, see [policy](../driver/driver-hdf-servicemanage.md). + + ``` + device_sample :: Device { + policy = 2; + ... + } + ``` + +2. Set the driver permission. By default, the **permission** field is set to **0666**, which allows the driver to create device nodes. You can set this field based on service requirements. + +3. Implement the **Dispatch()** method of **IDeviceIoService**. + + ``` + // Dispatch messages sent from the user-mode application. + int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) + { + HDF_LOGE("sample driver lite A dispatch"); + return 0; + } + int32_t SampleDriverBind(struct HdfDeviceObject *device) + { + HDF_LOGE("test for lite os sample driver A Open!"); + if (device == NULL) { + HDF_LOGE("test for lite os sample driver A Open failed!"); + return -1; + } + static struct ISampleDriverService sampleDriverA = { + .ioService.Dispatch = SampleDriverDispatch, + .ServiceA = SampleDriverServiceA, + .ServiceB = SampleDriverServiceB, + }; + device->service = (struct IDeviceIoService *)(&sampleDriverA); + return 0; + } + ``` + +4. Define the cmd type in the message processing function. + + ``` + #define SAMPLE_WRITE_READ 1 // Read and write operation 1 + ``` + +5. Bind the driver service and the user-mode application to enable messages to be sent to the driver. + + ``` + int SendMsg(const char *testMsg) + { + if (testMsg == NULL) { + HDF_LOGE("test msg is null"); + return -1; + } + struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); + if (serv == NULL) { + HDF_LOGE("fail to get service"); + return -1; + } + struct HdfSBuf *data = HdfSBufObtainDefaultSize(); + if (data == NULL) { + HDF_LOGE("fail to obtain sbuf data"); + return -1; + } + struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); + if (reply == NULL) { + HDF_LOGE("fail to obtain sbuf reply"); + ret = HDF_DEV_ERR_NO_MEMORY; + goto out; + } + if (!HdfSbufWriteString(data, testMsg)) { + HDF_LOGE("fail to write sbuf"); + ret = HDF_FAILURE; + goto out; + } + int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("fail to send service call"); + goto out; + } + out: + HdfSBufRecycle(data); + HdfSBufRecycle(reply); + HdfIoServiceRecycle(serv); + return ret; + } + ``` + +6. Enable the user-mode application to receive messages from the driver. + 1. Enable the driver to report events to the user-mode application. + + ``` + static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) + { + OsalTimespec time; + OsalGetTime(&time); + HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); + + const char *string = HdfSbufReadString(data); + if (string == NULL) { + HDF_LOGE("fail to read string in event data"); + return -1; + } + HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); + return 0; + } + ``` + 2. Register the method for receiving the messages from the driver. + + ``` + int RegisterListen() + { + struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); + if (serv == NULL) { + HDF_LOGE("fail to get service"); + return -1; + } + static struct HdfDevEventlistener listener = { + .callBack = OnDevEventReceived, + .priv ="Service0" + }; + if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { + HDF_LOGE("fail to register event listener"); + return -1; + } + ...... + HdfDeviceUnregisterEventListener(serv, &listener); + HdfIoServiceRecycle(serv); + return 0; + } + ``` + 3. Enable the driver to report events. + + ``` + int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) + { + ... // Process the API call. + return HdfDeviceSendEvent(deviceObject, cmdCode, data); + } + ``` diff --git a/en/device-dev/driver/driver-hdf-overview.md b/en/device-dev/driver/driver-hdf-overview.md index c66ffc4d16..14f93df86d 100644 --- a/en/device-dev/driver/driver-hdf-overview.md +++ b/en/device-dev/driver/driver-hdf-overview.md @@ -1,27 +1,27 @@ -# HDF Overview +# HDF Overview -## Introduction -The Hardware Driver Foundation \(HDF\) provides the following driver framework capabilities: driver loading, driver service management, and driver message mechanism. This unified driver architecture platform is designed to provide a more precise and efficient development environment, where you can perform one-time development and multi-system deployment. +## Introduction -## Driver Loading +The Hardware Driver Foundation (HDF) provides driver framework capabilities including driver loading, driver service management, and driver messaging mechanism. It strives to build a unified driver architecture platform to provide a more precise and efficient development environment, where you can perform one-time development for multi-device deployment. -Both on-demand loading and sequential loading are supported. -- On-demand loading +## Driver Loading - Drivers can be loaded by default during the operating system \(OS\) startup or be loaded dynamically after the OS startup. +The HDF supports the following loading modes: -- Sequential loading +- On-demand loading + The driver is loaded by default during the operating system (OS) boot process or dynamically loaded after OS is started. - Drivers can be loaded based on their priorities during the OS startup. +- Sequential loading + The driver is loaded based on its priority during the OS boot process. -## Driver Service Management +## Driver Service Management -The HDF centrally manages driver services. You can directly obtain a specified driver service by using the API provided by the HDF. +The HDF allows centralized management of driver services. You can obtain a driver service by using the API provided by the HDF. -## Driver Message Mechanism -The HDF provides a unified driver message mechanism, which allows message interactions between user-level applications and kernel-level drivers. +## Driver messaging mechanism +The HDF provides a unified driver messaging mechanism, which allows messages to be exchanged between user-mode applications and kernel-mode drivers. diff --git a/en/device-dev/driver/driver-hdf-sample.md b/en/device-dev/driver/driver-hdf-sample.md index 1c06c77022..93d1e3a03b 100644 --- a/en/device-dev/driver/driver-hdf-sample.md +++ b/en/device-dev/driver/driver-hdf-sample.md @@ -1,13 +1,14 @@ -# HDF Development Example +# HDF Development Example -The following example shows how to add driver configuration, compile the driver code, and implement interaction between the user-state applications and the driver. -## Adding Configuration +The following is a HDF-based driver development example. -Add the driver configuration to the HDF configuration file \(for example, **vendor/hisilicon/xxx/hdf_config/device\_info**\). -Example: +## Adding Driver Configuration +Add the driver configuration to the HDF configuration file, for example, **vendor/hisilicon/xxx/hdf_config/device_info**. + + ``` root { device_info { @@ -44,10 +45,12 @@ root { } ``` -## Compiling the Driver Code -The following is the sample driver code compiled based on HDF (for details, see [Driver Development](driver-hdf-development.md)): +## Writing the Driver Code + +Write the driver code based on the HDF. For more details, see [Driver Development](../driver/driver-hdf-development.md). + ``` #include #include @@ -79,7 +82,7 @@ int32_t HdfSampleDriverDispatch( void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) { - // Release resources here + // Release resources. return; } @@ -116,10 +119,12 @@ struct HdfDriverEntry g_sampleDriverEntry = { HDF_INIT(g_sampleDriverEntry); ``` -## Compiling the Code for Interaction -The following is the sample code compiled based on HDF for interaction between the driver and user-state applications. You can place the code in **drivers/adapter/uhdf** for compilation. For details about the **build.gn** file, see **drivers/framework/sample/platform/uart/dev/build.gn**. +## Implementing Interaction Between the Application and the Driver + +Write the code for interaction between the user-mode application and the driver. Place the code in the **drivers/adapter/uhdf** directory for compilation. For details about **build.gn**, see **drivers/framework/sample/platform/uart/dev/build.gn**. + ``` #include #include @@ -227,9 +232,13 @@ int main() } ``` ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->The code compilation of user-state applications depends on the dynamic libraries **hdf\_core** and **osal** provided by HDF because user-state applications use the message sending interface of HDF. In the GN file, add the following dependencies: ->deps = \[ ->"//drivers/adapter/uhdf/manager:hdf\_core", ->"//drivers/adapter/uhdf/posix:hdf\_posix\_osal", ->\] +> ![icon-note.gif](../public_sys-resources/icon-note.gif) **NOTE**
+> The user-mode application uses the message sending API of the HDF, and the compilation of the user-mode application depends on the dynamic libraries **hdf_core** and **osal** provided by the HDF. Therefore, you need to add the following dependencies to the .gn file: +> +> deps = [ +> +> "//drivers/adapter/uhdf/manager:hdf_core", +> +> "//drivers/adapter/uhdf/posix:hdf_posix_osal", +> +> ] diff --git a/en/device-dev/driver/driver-hdf-servicemanage.md b/en/device-dev/driver/driver-hdf-servicemanage.md index 0e5485bfb8..f9445db98f 100644 --- a/en/device-dev/driver/driver-hdf-servicemanage.md +++ b/en/device-dev/driver/driver-hdf-servicemanage.md @@ -1,162 +1,143 @@ -# Driver Service Management +# Driver Service Management -Driver services are objects of open capabilities provided by the HDF and are managed by the HDF in a unified manner. Using driver service management, you can release and obtain driver services. +Driver services are objects of capabilities provided by HDF driver devices to external systems and are managed by the HDF in a unified manner. Driver service management involves providing and obtaining driver services. -The HDF uses the **policy** field in the configuration file to define policies for drivers to release services externally. The values and meanings of this field are as follows: +The HDF uses the **policy** field in the configuration file to define policies for drivers to provide services externally. The values this field are as follows: + + + ``` typedef enum { /* The driver does not provide services. */ SERVICE_POLICY_NONE = 0, - /* The driver provides services for kernel-space applications. */ + /* The driver provides services only for kernel-mode applications. */ SERVICE_POLICY_PUBLIC = 1, - /* The driver provides services for both kernel- and user-space applications. */ + /* The driver provides services for both kernel- and user-mode applications. */ SERVICE_POLICY_CAPACITY = 2, - /* The driver services are not released externally but can be subscribed to. */ + /** The driver services are not provided externally but can be subscribed to. */ SERVICE_POLICY_FRIENDLY = 3, - /* The driver services are private. They are neither released nor subscribed to. */ + /* The driver private services cannot be provided externally or subscribed to. */ SERVICE_POLICY_PRIVATE = 4, - /* The service policy is incorrect. */ + /** Invalid service policy. */ SERVICE_POLICY_INVALID } ServicePolicy; ``` -## When to Use -The driver service management capability can be used if the driver provides capabilities using APIs. - -## Available APIs - -The table below describes the APIs used for driver service management. - -**Table 1** APIs for driver service management - - - - - - - - - - - - - - - - -

Function

-

Description

-

int32_t (*Bind)(struct HdfDeviceObject *deviceObject);

-

Binds a service interface to the HDF. You need to implement the Bind function.

-

const struct HdfObject *DevSvcManagerClntGetService(const char *svcName);

-

Obtains a specified driver service.

-

int HdfDeviceSubscribeService(

-

struct HdfDeviceObject *deviceObject, const char *serviceName, struct SubscriberCallback callback);

-

Subscribes to a specified driver service.

-
- -## How to Develop - -The development of driver service management includes compiling, binding, obtaining, and subscribing to driver services. The details are as follows: - -1. Release a driver service. - - ``` - Define the driver service structure. - struct ISampleDriverService { - struct IDeviceIoService ioService; // The first member of the service structure must be a member of the IDeviceIoService type. - int32_t (*ServiceA)(void); // The first service interface of the driver. - int32_t (*ServiceB)(uint32_t inputCode); // The second service interface of the driver. The rest can be deduced by analogy. - }; - - Implementation of the driver service interface - int32_t SampleDriverServiceA(void) - { - // You need to implement the service logic. - return 0; - } - - int32_t SampleDriverServiceB(uint32_t inputCode) - { - // You need to implement the service logic. - return 0; - } - ``` - -2. Bind the driver service to the HDF and implement the **Bind** function in the **HdfDriverEntry** structure. - - ``` - int32_t SampleDriverBind(struct HdfDeviceObject *deviceObject) - { - // deviceObject indicates the pointer to the device object created by the HDF for each driver. It is used to store device-related private data and service interfaces. - if (deviceObject == NULL) { - HDF_LOGE("Sample device object is null!"); - return -1; - } - static struct ISampleDriverService sampleDriverA = { - .ServiceA = SampleDriverServiceA, - .ServiceB = SampleDriverServiceB, - }; - deviceObject->service = &sampleDriverA.ioService; - return 0; - } - ``` - -3. Obtain the driver service. - - You can either use the API or subscription mechanism provided by the HDF to obtain the driver service. - - - Using the API - - After the driver is loaded, you can obtain the driver service using the API provided by the HDF, as shown in the following: - - ``` - const struct ISampleDriverService *sampleService = - (const struct ISampleDriverService *)DevSvcManagerClntGetService("sample_driver"); - if (sampleService == NULL) { - return -1; - } - sampleService->ServiceA(); - sampleService->ServiceB(5); - ``` - - - Using the subscription mechanism - - If the kernel mode is unaware of the time for loading drivers \(on the same host\), use the subscription mechanism provided by the HDF to subscribe to the drivers. After the drivers are loaded, the HDF releases the driver services to you. The implementation is as follows: - - ``` - // Subscription callback function. After the subscribed drivers are loaded, the HDF releases the driver services to you using this function. - // object indicates the pointer to the private data of the subscriber, and service indicates the pointer to the subscribed service. - int32_t TestDriverSubCallBack(struct HdfDeviceObject *deviceObject, const struct HdfObject *service) - { - const struct ISampleDriverService *sampleService = - (const struct ISampleDriverService *)service; - if (sampleService == NULL) { - return -1; - } - sampleService->ServiceA(); - sampleService->ServiceB(5); - } - // Implement the subscription process. - int32_t TestDriverInit(struct HdfDeviceObject *deviceObject) - { - if (deviceObject == NULL) { - HDF_LOGE("Test driver init failed, deviceObject is null!"); - return -1; - } - struct SubscriberCallback callBack; - callBack.deviceObject = deviceObject; - callBack.OnServiceConnected = TestDriverSubCallBack; - int32_t ret = HdfDeviceSubscribeService(deviceObject, "sample_driver", callBack); - if (ret != 0) { - HDF_LOGE("Test driver subscribe sample driver failed!"); - } - return ret; - } - ``` +## When to Use +The driver service management capability can be used if the driver provides capabilities using APIs. +## Available APIs + +The table below describes the APIs for driver service management. + + **Table 1** APIs for driver service management + +| API| Description| +| -------- | -------- | +| int32_t (\*Bind)(struct HdfDeviceObject \*deviceObject); | Binds a service API to the HDF. You need to implement the **Bind()** function.| +| const struct HdfObject \*DevSvcManagerClntGetService(const char \*svcName); | Obtains a driver service.| +| int HdfDeviceSubscribeService(
struct HdfDeviceObject \*deviceObject, const char \*serviceName, struct SubscriberCallback callback); | Subscribes to a driver service.| + + +## How to Develop + +The development procedure is as follows: + +1. Define the services to be provided by the driver. + + ``` + Define the driver service structure. + struct ISampleDriverService { + struct IDeviceIoService ioService; // The first member must be of the IDeviceIoService type. + int32_t (*ServiceA)(void); // API of the first driver service. + int32_t (*ServiceB)(uint32_t inputCode); // API of the second driver service. You can add more as required. + }; + + Implement the driver service APIs. + int32_t SampleDriverServiceA(void) + { + // You need to implement the service logic. + return 0; + } + + int32_t SampleDriverServiceB(uint32_t inputCode) + { + // You need to implement the service logic. + return 0; + } + ``` + +2. Bind the driver service to the HDF and implement the **Bind()** function in the **HdfDriverEntry** structure. + + ``` + int32_t SampleDriverBind(struct HdfDeviceObject *deviceObject) + { + // deviceObject is a pointer to the device object created by the HDF for each driver. The device object holds private device data and service APIs. + if (deviceObject == NULL) { + HDF_LOGE("Sample device object is null!"); + return -1; + } + static struct ISampleDriverService sampleDriverA = { + .ServiceA = SampleDriverServiceA, + .ServiceB = SampleDriverServiceB, + }; + deviceObject->service = &sampleDriverA.ioService; + return 0; + } + ``` + +3. Obtain the driver service. + The driver service can be obtained by using the API or subscription mechanism provided by the HDF. + + - Using the API + Use the API provided by the HDF to obtain the driver service if the driver has been loaded. + + + ``` + const struct ISampleDriverService *sampleService = + (const struct ISampleDriverService *)DevSvcManagerClntGetService("sample_driver"); + if (sampleService == NULL) { + return -1; + } + sampleService->ServiceA(); + sampleService->ServiceB(5); + ``` + - Using the subscription mechanism + If the kernel mode is unaware of the time for loading drivers on the same host, use the subscription mechanism provided by the HDF to subscribe to the drivers. After the drivers are loaded, the HDF sends the driver services to the subscriber. The implementation is as follows: + + + ``` + // Callback invoked to return the driver services after the subscribed driver is loaded. + // object is the pointer to the private data of the subscriber, and service is the pointer to the subscribed service object. + int32_t TestDriverSubCallBack(struct HdfDeviceObject *deviceObject, const struct HdfObject *service) + { + const struct ISampleDriverService *sampleService = + (const struct ISampleDriverService *)service; + if (sampleService == NULL) { + return -1; + } + sampleService->ServiceA(); + sampleService->ServiceB(5); + } + // Implement the subscription process. + int32_t TestDriverInit(struct HdfDeviceObject *deviceObject) + { + if (deviceObject == NULL) { + HDF_LOGE("Test driver init failed, deviceObject is null!"); + return -1; + } + struct SubscriberCallback callBack; + callBack.deviceObject = deviceObject; + callBack.OnServiceConnected = TestDriverSubCallBack; + int32_t ret = HdfDeviceSubscribeService(deviceObject, "sample_driver", callBack); + if (ret != 0) { + HDF_LOGE("Test driver subscribe sample driver failed!"); + } + return ret; + } + ``` diff --git a/en/device-dev/driver/driver-peripherals-touch-des.md b/en/device-dev/driver/driver-peripherals-touch-des.md index 15c1892db7..2402d94695 100644 --- a/en/device-dev/driver/driver-peripherals-touch-des.md +++ b/en/device-dev/driver/driver-peripherals-touch-des.md @@ -11,7 +11,7 @@ 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. + 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 Device Interfaces \(HDIs\) for upper-layer input services to control the touchscreen. **Figure 1** Architecture of the input driver model @@ -88,7 +88,7 @@ Perform the following steps: 1. Add the touchscreen driver-related descriptions. - Currently, the input driver is developed based on the HDF and is loaded and started by the HDF. Register the driver information, such as whether to load the driver and the loading priority in the configuration file. Then, the HDF starts the registered driver modules one by one. For details about the driver configuration, see [Driver Development](driver-hdf-development.md#section1969312275533). + Currently, the input driver is developed based on the HDF and is loaded and started by the HDF. Register the driver information, such as whether to load the driver and the loading priority in the configuration file. Then, the HDF starts the registered driver modules one by one. For details about the driver configuration, see [Driver Development](driver-hdf-development.md#how-to-develop). 2. Complete the board-level configuration and private data configuration of the touchscreen. @@ -96,7 +96,7 @@ Perform the following steps: 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](driver-platform-gpio-des.md#section1635911016188). + 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](driver-platform-gpio-des.md#overview). ## Development Example diff --git a/en/device-dev/driver/driver-platform-adc-develop.md b/en/device-dev/driver/driver-platform-adc-develop.md index 36dca8941b..fd48b7f8b7 100644 --- a/en/device-dev/driver/driver-platform-adc-develop.md +++ b/en/device-dev/driver/driver-platform-adc-develop.md @@ -89,7 +89,7 @@ The ADC module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-dac-develop.md b/en/device-dev/driver/driver-platform-dac-develop.md index 11585ba116..902035e732 100644 --- a/en/device-dev/driver/driver-platform-dac-develop.md +++ b/en/device-dev/driver/driver-platform-dac-develop.md @@ -284,7 +284,7 @@ The DAC module adaptation procedure is as follows: ``` ![](../public_sys-resources/icon-note.gif) **NOTE**
- For details about **DacMethod**, see [Available APIs](#section752964871810). + For details about **DacMethod**, see [Available APIs](#available-apis). - **Init** function diff --git a/en/device-dev/driver/driver-platform-i2c-develop.md b/en/device-dev/driver/driver-platform-i2c-develop.md index 4ce103b1f9..c5dddbd42f 100644 --- a/en/device-dev/driver/driver-platform-i2c-develop.md +++ b/en/device-dev/driver/driver-platform-i2c-develop.md @@ -70,7 +70,7 @@ The I2C module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-i3c-develop.md b/en/device-dev/driver/driver-platform-i3c-develop.md index e21de4f0cc..e5b08e2067 100644 --- a/en/device-dev/driver/driver-platform-i3c-develop.md +++ b/en/device-dev/driver/driver-platform-i3c-develop.md @@ -52,7 +52,7 @@ The I3C module adaptation involves the following steps: 3. Instantiate the I3C controller object. - Initialize **I3cCntlr**. - - Instantiate **I3cMethod** in **I3cCntlr**. For details, see [Available APIs](#Available_apis). + - Instantiate **I3cMethod** in **I3cCntlr**. For details, see [Available APIs](#available-apis). 4. Register an interrupt handler. Register an interrupt handler for the controller to implement the device hot-join and in-band interrupt (IBI) features. diff --git a/en/device-dev/driver/driver-platform-mipidsi-develop.md b/en/device-dev/driver/driver-platform-mipidsi-develop.md index 326076cc91..ceb69f730c 100644 --- a/en/device-dev/driver/driver-platform-mipidsi-develop.md +++ b/en/device-dev/driver/driver-platform-mipidsi-develop.md @@ -118,7 +118,7 @@ The MIPI DSI module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-mmc-develop.md b/en/device-dev/driver/driver-platform-mmc-develop.md index 3c9c9cd6d0..7becfa6f23 100644 --- a/en/device-dev/driver/driver-platform-mmc-develop.md +++ b/en/device-dev/driver/driver-platform-mmc-develop.md @@ -209,7 +209,7 @@ The MMC module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-pwm-develop.md b/en/device-dev/driver/driver-platform-pwm-develop.md index 4207b04e5d..269e990a87 100644 --- a/en/device-dev/driver/driver-platform-pwm-develop.md +++ b/en/device-dev/driver/driver-platform-pwm-develop.md @@ -81,7 +81,7 @@ The PWM module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-rtc-develop.md b/en/device-dev/driver/driver-platform-rtc-develop.md index 42d1d4126c..20639f951a 100644 --- a/en/device-dev/driver/driver-platform-rtc-develop.md +++ b/en/device-dev/driver/driver-platform-rtc-develop.md @@ -196,7 +196,7 @@ The RTC module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-sdio-develop.md b/en/device-dev/driver/driver-platform-sdio-develop.md index 330d863572..0f7e41238f 100644 --- a/en/device-dev/driver/driver-platform-sdio-develop.md +++ b/en/device-dev/driver/driver-platform-sdio-develop.md @@ -292,7 +292,7 @@ The SDIO module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-uart-develop.md b/en/device-dev/driver/driver-platform-uart-develop.md index b9592d57cc..bc6d827363 100644 --- a/en/device-dev/driver/driver-platform-uart-develop.md +++ b/en/device-dev/driver/driver-platform-uart-develop.md @@ -1,11 +1,5 @@ # UART -- [Overview](#section1761881586154520) -- [How to Develop](#section944397404154520) - - [UartHostMethod](#section192316441461) - -- [Development Example](#section774610224154520) - ## Overview In the Hardware Driver Foundation \(HDF\), the Universal Asynchronous Receiver/Transmitter \(UART\) uses the independent service mode for API adaptation. In this mode, each device independently publishes a device service to handle external access requests. After receiving an access request from an API, the device manager extracts the parameters in the request to call the internal method of the target device. In the independent service mode, the service management capabilities of the HDF Device Manager can be directly used. However, you need to configure a device node for each device, which increases the memory usage. @@ -186,7 +180,7 @@ The UART module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. diff --git a/en/device-dev/driver/driver-platform-watchdog-develop.md b/en/device-dev/driver/driver-platform-watchdog-develop.md index 1c3d0b5d65..367b2531c4 100644 --- a/en/device-dev/driver/driver-platform-watchdog-develop.md +++ b/en/device-dev/driver/driver-platform-watchdog-develop.md @@ -129,7 +129,7 @@ The Watchdog module adaptation involves the following steps: >![](../public_sys-resources/icon-note.gif) **NOTE** - >For details, see [Available APIs](#availableapis). + >For details, see [Available APIs](#available-apis). 4. Debug the driver. -- GitLab