“e27ec1f26c451b545d2c9371a6f1cfc4fa6a6066”上不存在“src/git@gitcode.net:taosdata/tdengine.git”
未验证 提交 3a36b79f 编写于 作者: O openharmony_ci 提交者: Gitee

!8112 [翻译完成】#I5J31J

Merge pull request !8112 from Annie_wang/PR7172
...@@ -12,9 +12,9 @@ App permissions are used to protect the following objects: ...@@ -12,9 +12,9 @@ App permissions are used to protect the following objects:
Without the required permissions, an app cannot access or perform operations on the target object. Permissions must be clearly defined for apps. With well-defined app permissions, the system can standardize the behavior of apps and protect user privacy. Before an app accesses the target object, the target object verifies the app's permissions and denies the access if the app does not have required permissions. Without the required permissions, an app cannot access or perform operations on the target object. Permissions must be clearly defined for apps. With well-defined app permissions, the system can standardize the behavior of apps and protect user privacy. Before an app accesses the target object, the target object verifies the app's permissions and denies the access if the app does not have required permissions.
Currently, ATM performs app permission verification based on the token identity (Token ID). A token ID identifies an app. The ATM manages app permissions based on the app's token ID. Currently, ATM verifies app permissions based on the token identity (Token ID). A token ID identifies an app. The ATM manages app permissions based on the app's token ID.
## How to Develop ## Permission Workflow
Determine the permissions required for an app to access data or perform an operation. Declare the required permissions in the app installation package. Determine the permissions required for an app to access data or perform an operation. Declare the required permissions in the app installation package.
...@@ -22,13 +22,13 @@ Determine whether the required permissions need to be authorized by users. If ye ...@@ -22,13 +22,13 @@ Determine whether the required permissions need to be authorized by users. If ye
After the user grants permissions to the app, the app can access the data or perform the operation. After the user grants permissions to the app, the app can access the data or perform the operation.
The figure below shows the process. The figure below shows the permission workflow.
![](figures/figure1.png) ![](figures/figure1.png)
## When to Use ## When to Use
### Scenarios ### Example Scenarios
The following describes two common scenarios. The following describes two common scenarios.
...@@ -62,7 +62,7 @@ Observe the following principles for permission management: ...@@ -62,7 +62,7 @@ Observe the following principles for permission management:
To protect user privacy, ATM defines different permission levels based on the sensitivity of the data involved or the security threat of the ability. To protect user privacy, ATM defines different permission levels based on the sensitivity of the data involved or the security threat of the ability.
### App APL ### App APLs
The ability privilege level (APL) defines the priority of the app permission requested. Apps of different APLs can apply for permissions of different levels. The ability privilege level (APL) defines the priority of the app permission requested. Apps of different APLs can apply for permissions of different levels.
...@@ -76,9 +76,9 @@ The table below describes the APLs. ...@@ -76,9 +76,9 @@ The table below describes the APLs.
By default, apps are of the normal APL. By default, apps are of the normal APL.
For the app of the system_basic or system_core APL, declare the app APL level in the **apl** field in the app's profile, and use the profile signing tool to generate a certificate when developing the app installation package. For details about the signing process, see [Hapsigner Guide](hapsigntool-guidelines.md). For the app of the system_basic or system_core APL, declare the app APL in the **apl** field in the app's profile, and use the profile signing tool to generate a certificate when developing the app installation package. For details about the signing process, see [Hapsigner Guide](hapsigntool-guidelines.md).
### Permission Levels ### Levels of Permissions
The permissions open to apps vary with the permission level. The permission levels include the following in ascending order of seniority. The permissions open to apps vary with the permission level. The permission levels include the following in ascending order of seniority.
...@@ -121,11 +121,11 @@ If the permission required by an app has higher level than the app's APL, you ca ...@@ -121,11 +121,11 @@ If the permission required by an app has higher level than the app's APL, you ca
In addition to the preceding [authorization processes](#authorization-processes), you must declare the ACL. In addition to the preceding [authorization processes](#authorization-processes), you must declare the ACL.
In other words, in addition to declaring the required permissions in the **config.json** file, you must declare the high-level permissions in the app's [profile](accesstoken-guidelines.md#declaring-the-acl). The subsequent steps of authorization are the same. In other words, in addition to declaring the required permissions in the **config.json** file, you must [declare the ACL](accesstoken-guidelines.md#declaring-the-acl) in the app's profile. The subsequent steps of authorization are the same.
**NOTE** **NOTICE**
Declare the target ACL in the **acl** field of the app's profile in the app installation package, and generate a certificate using the profile signing tool. For details about the signing process, see [Hapsigner Guide](hapsigntool-guidelines.md). Declare the target ACL in the **acls** field of the app's profile in the app installation package, and generate a certificate using the profile signing tool. For details about the signing process, see [Hapsigner Guide](hapsigntool-guidelines.md).
## Permission Authorization Modes ## Permission Authorization Modes
...@@ -149,9 +149,7 @@ Permissions can be classified into the following types based on the authorizatio ...@@ -149,9 +149,7 @@ Permissions can be classified into the following types based on the authorizatio
### Authorization Processes ### Authorization Processes
The process for an app obtaining the required permissions varies The process for an app obtaining the required permissions varies depending on the permission authorization mode.
depending on the permission authorization mode.
- For a system_grant permission, you need to [declare the permission](accesstoken-guidelines.md) in the **config.json** file. The permission will be pre-granted when the app is installed. - For a system_grant permission, you need to [declare the permission](accesstoken-guidelines.md) in the **config.json** file. The permission will be pre-granted when the app is installed.
...@@ -165,7 +163,7 @@ The procedure is as follows: ...@@ -165,7 +163,7 @@ The procedure is as follows:
2. Associate the object that requires the permissions in the app with the target permissions. In this way, the user knows the operations to be granted with the specified permissions. 2. Associate the object that requires the permissions in the app with the target permissions. In this way, the user knows the operations to be granted with the specified permissions.
3. Check whether the user has granted the required permissions to the app when the app is running. If yes, the app can access the data or perform the operation. If the user has not granted the permissions to the app, display a dialog box requesting the user authorization when the app attempts to access the data or perform the operation. 3. Check whether the user has granted the required permissions to the app when the app is running. If yes, the app can access the data or perform the operation. If the user has not granted the permissions to the app, display a dialog box requesting the user authorization when the app attempts to access the data.
4. Check the user authorization result. Allow the next step only after the user has granted the permissions to the app. 4. Check the user authorization result. Allow the next step only after the user has granted the permissions to the app.
......
...@@ -52,7 +52,7 @@ The camera module encapsulates camera operations in camera preview, photographin ...@@ -52,7 +52,7 @@ The camera module encapsulates camera operations in camera preview, photographin
| API | Description | | API | Description |
| ------------------------------------------------------------ | ---------------------------- | | ------------------------------------------------------------ | ---------------------------- |
| CamRetCode GetStreamOperator(<br> const OHOS::sptr<IStreamOperatorCallback> &callback,<br> OHOS::sptr<IStreamOperator> &streamOperator) | Obtains the stream controller. | | CamRetCode GetStreamOperator(<br> const OHOS::sptr<IStreamOperatorCallback> &callback,<br> OHOS::sptr<IStreamOperator> &streamOperator) | Obtains the stream controller. |
| CamRetCode UpdateSettings(const std::shared_ptr<CameraSetting> &settingss) | Updates device control parameters. | | CamRetCode UpdateSettings(const std::shared_ptr<CameraSetting> &settings) | Updates device control parameters. |
| CamRetCode SetResultMode(const ResultCallbackMode &mode) | Sets the result callback mode and function.| | CamRetCode SetResultMode(const ResultCallbackMode &mode) | Sets the result callback mode and function.|
| CamRetCode GetEnabledResults(std::vector<MetaType> &results) | Obtains the enabled ResultMeta. | | CamRetCode GetEnabledResults(std::vector<MetaType> &results) | Obtains the enabled ResultMeta. |
| CamRetCode EnableResult(const std::vector<MetaType> &results) | Enables specific ResultMeta. | | CamRetCode EnableResult(const std::vector<MetaType> &results) | Enables specific ResultMeta. |
...@@ -730,7 +730,7 @@ There is a camera demo in the **/drivers/peripheral/camera/hal/init** directory. ...@@ -730,7 +730,7 @@ There is a camera demo in the **/drivers/peripheral/camera/hal/init** directory.
"-o | --offline stream offline test\n" "-o | --offline stream offline test\n"
"-c | --capture capture one picture\n" "-c | --capture capture one picture\n"
"-w | --set WB Set white balance Cloudy\n" "-w | --set WB Set white balance Cloudy\n"
"-v | --video capture Viedeo of 10s\n" "-v | --video capture Video of 10s\n"
"-a | --Set AE Set Auto exposure\n" "-a | --Set AE Set Auto exposure\n"
"-f | --Set Flashlight Set flashlight ON 5s OFF\n" "-f | --Set Flashlight Set flashlight ON 5s OFF\n"
"-q | --quit stop preview and quit this app\n"); "-q | --quit stop preview and quit this app\n");
......
# I3C<a name="1"></a> # I3C
## Introduction
## Overview<a name="section1"></a> ### Function
The Improved Inter-Integrated Circuit (I3C) is a simple and cost-efficient bidirectional 2-wire synchronous serial bus protocol developed by the Mobile Industry Processor Interface (MIPI) Alliance. Improved Inter-Integrated Circuit (I3C) is a simple and cost-efficient two-wire bidirectional synchronous serial bus protocol developed by the Mobile Industry Processor Interface (MIPI) Alliance.
I3C is backward compatible with legacy Inter-Integrated Circuit (I2C). Moreover, it provides the in-band interrupt (IBI) function and supports hot-join of I3C devices. This eliminates the need for adding an extra interrupt line to implement interrupts in I2C. I3C is a two-wire bidirectional serial bus, optimized for multiple sensor target devices and controlled by only one I3C controller at a time. It is backward compatible with Inter-Integrated circuit (I2C) target devices, but features higher speed and lower power consumption. Moreover, I3C supports in-band interrupts (IBIs), hot-joins of target devices, and controller switchover. The IBIs over the serial bus eliminates the need for an extra interrupt line to complete interrupts in I2C. I2C devices, I3C target devices, and the I3C secondary controller can co-exist on the same I3C bus.
The I2C device, I3C slave device, and I3C secondary master device can coexist on the I3C bus.
The I3C APIs provide a set of common functions for I3C transfer, including:
The I3C driver APIs provide a set of common functions for I3C transfer, including:
- Opening and closing an I3C controller - Opening and closing an I3C controller
- Obtaining and setting I3C controller parameters - Obtaining and setting I3C controller parameters
- Performing custom I3C message transfer by using a message array - Performing custom I3C message transfer by using a message array
- Requesting and releasing an IBI - Requesting and releasing an IBI
[Figure 1](#fig1) shows the I3C physical connection. ### Basic Concepts
**Figure 1** I3C physical connection<a name="fig1"></a>
- IBI
When there is no start signal on the serial clock (SCL) line, the I3C target device can pull down the serial data (SDA) line to make the controller send an SCL start signal, which initiates an IBI request. If multiple target devices send interrupt requests at the same time, the I3C controller arbitrates the requests based on the target device addresses. The request with a lower address is responded first.
- Dynamic Address Assignment (DAA)
The I3C controller can dynamically allocate addresses to target devices to avoid address conflicts. Before addresses are allocated, each I3C device connected to a I3C bus must be uniquely identified in either of the following ways:
- The device has an I2C compliant static address that can be used by the host.
- The device has a 48-bit temporary ID.
The host must use a 48-bit temporary ID unless the device has a static IP address.
- Common Command Code (CCC)
All I3C devices support CCC. The CCC can be sent to a specific I3C target device or all I3C target devices.
- Bus Characteristic Register (BCR)
Each I3C device connected to an I3C bus has a read-only BCR, which describes the I3C compliant device's role and capabilities for use in DAA and CCC.
- Device Characteristic Register (DCR)
Each I3C device connected to an I3C bus has a read-only DCR, which describes the I3C compliant device type (such as accelerometers, gyroscope, and others) for use in DAA and DCC.
### Working Principles
In the Hardware Driver Foundation (HDF), the I3C module uses the unified service mode for API adaptation. In this mode, a service is used as the I3C manager to handle external access requests in a unified manner. The unified service mode applies when the system has multiple device objects of the same type, for example, when there are more than 10 I3C controllers. If the independent service mode is used in this case, more device nodes need to be configured and more memory resources will be consumed.
Multiple devices, such as I2C target device, I3C target device, and I3C secondary controller, can be connected to an I3C bus. However, the I3C bus must have only one controller.
**Figure 1** I3C physical connection
![](figures/I3C_physical_connection.png "I3C_physical_connection") ![](figures/I3C_physical_connection.png "I3C_physical_connection")
## Available APIs<a name="section2"></a> ### Constraints
Currently, the I3C module supports only the kernels (LiteOS) of mini and small systems.
## Usage Guidelines
### When to Use
I3C can connect to one or more I3C or I2C target devices. It is used to:
- Communicate with sensors, such as gyroscopes, barometers, and image sensors that support the I3C protocol.
- Communicate with devices with other ports (such as UART serial ports) through software or hardware protocols.
### Available APIs
**Table 1** I3C driver APIs **Table 1** I3C driver APIs
<a name="table1"></a>
| API | Description |
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="18.63%"><p>Category</p> | ------------- | ----------------- |
</th> | I3cOpen | Opens an I3C controller. |
<th class="cellrowborder" valign="top" width="28.03%"><p>API</p> | I3cClose | Closes an I3C controller. |
</th> | I3cTransfer | Performs custom transfer. |
<th class="cellrowborder" valign="top" width="53.339999999999996%"><p>Description</p> | I3cSetConfig | Sets the I3C controller. |
</th> | I3cGetConfig | Obtains the I3C controller configuration. |
</tr> | I3cRequestIbi | Requests an IBI. |
</thead> | I3cFreeIbi | Releases an IBI. |
<tbody><tr><td class="cellrowborder" bgcolor="#ffffff" rowspan="2" valign="top" width="18.63%"><p>I3C controller management</p>
</td> >![](../public_sys-resources/icon-note.gif) **NOTE**<br>
<td class="cellrowborder" valign="top" width="28.03%"><p>I3cOpen</p> >All APIs described in this document can be called only in kernel mode.
</td>
<td class="cellrowborder" valign="top" width="53.339999999999996%">Opens an I3C controller.</p> ### How to Develop
</td>
</tr> The figure below illustrates the use of I3C driver APIs.
<tr><td class="cellrowborder" valign="top"><p>I3cClose</p>
</td> **Figure 2** Process of using I3C driver APIs
<td class="cellrowborder" valign="top"><p>Closes an I3C controller.</p>
</td>
</tr>
<tr><td class="cellrowborder" bgcolor="#ffffff" valign="top" width="18.63%"><p>I3C transfer</p>
</td>
<td class="cellrowborder" valign="top" width="28.03%"><p>I3cTransfer</p>
</td>
<td class="cellrowborder" valign="top" width="53.339999999999996%"><p>Customizes an I3C transfer.</p>
</td>
</tr>
<tr><td class="cellrowborder" bgcolor=ffffff rowspan="2" valign="top" width="18.63%"><p>I3C controller configuration</p>
</td>
<td class="cellrowborder" valign="top" width="28.03%"><p>I3cSetConfig</p>
</td>
<td class="cellrowborder"valign="top" width="53.339999999999996%">Sets an I3C controller.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top"><p>I3cGetConfig</p>
</td>
<td class="cellrowborder" valign="top"><p>Obtains the I3C controller configuration.</p>
</td>
</tr>
<tr><td class="cellrowborder" bgcolor=ffffff rowspan="2" valign="top" width="18.63%"><p>I3C IBI</p>
</td>
<td class="cellrowborder" valign="top" width="28.03%"><p>I3cRequestIbi</p>
</td>
<td class="cellrowborder" valign="top" width="53.339999999999996%">Requests an IBI.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top"><p>I3cFreeIbi</p>
</td>
<td class="cellrowborder" valign="top"><p>Releases an IBI.</p>
</td>
</tr>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE**
>
>All functions described in this document can be called only in the kernel space.
## Usage Guidelines<a name="section3"></a>
### How to Use<a name="section4"></a>
[Figure 2](#fig2) shows how I3C works.
**Figure 2** How I3C works<a name="fig2"></a>
![](figures/I3C_usage_flowchart.png "I3C_usage_flowchart") ![](figures/I3C_usage_flowchart.png "I3C_usage_flowchart")
### Opening an I3C Controller<a name="section5"></a> #### Opening an I3C Controller
Before I3C communication, call **I3cOpen** to open an I3C controller. Before I3C communication, call **I3cOpen()** to open an I3C controller.
```c ```c
DevHandle I3cOpen(int16_t number); DevHandle I3cOpen(int16_t number);
``` ```
**Table 2** Description of I3cOpen **Table 2** Description of I3cOpen
<a name="table2"></a> | Name | Description |
| ---------- | ------------------- |
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="20.66%"><p>Parameter</strong></p> | number | I3C controller number. |
</th> | **Return Value**| **Description** |
<th class="cellrowborder" valign="top" width="79.34%"><p><strong>Description</strong></p> | NULL | The operation failed. |
</th> | Controller handle| The operation is successful. The handle of the I3C controller opened is returned. |
</tr>
</thead> Example: Open I3C controller 1 of the eight I3C controllers numbered from 0 to 7 in the system.
<tbody><tr><td class="cellrowborder" valign="top" width="20.66%"><p>number</p>
</td>
<td class="cellrowborder" valign="top" width="79.34%"><p>I3C controller ID.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="20.66%"><p><strong>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="79.34%"><p><strong>Description</strong></p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="20.66%"><p>NULL</p>
</td>
<td class="cellrowborder" valign="top" width="79.34%"><p>Failed to open the I3C controller.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="20.66%"><p>Controller handle</p>
</td>
<td class="cellrowborder" valign="top" width="79.34%"><p>Handle of the I3C controller opened.</p>
</td>
</tr>
</tbody>
</table>
The following example opens I3C controller 1 of the eight I3C controllers (numbered from 0 to 7) in the system.
```c ```c
DevHandle i3cHandle = NULL; /* I3C controller handle. / DevHandle i3cHandle = NULL; /* I3C controller handle. /
...@@ -147,7 +116,7 @@ if (i3cHandle == NULL) { ...@@ -147,7 +116,7 @@ if (i3cHandle == NULL) {
} }
``` ```
### Performing I3C Communication<a name="section6"></a> #### Performing I3C Communication
Call **I3cTransfer()** to transfer messages. Call **I3cTransfer()** to transfer messages.
```c ```c
...@@ -156,53 +125,18 @@ int32_t I3cTransfer(DevHandle handle, struct I3cMsg *msgs, int16_t count, enum T ...@@ -156,53 +125,18 @@ int32_t I3cTransfer(DevHandle handle, struct I3cMsg *msgs, int16_t count, enum T
**Table 3** Description of I3cTransfer **Table 3** Description of I3cTransfer
<a name="table3"></a>
| Name | Description |
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong> Parameter</strong></p> | ---------- | -------------------------------------------- |
</th> | handle | I3C controller handle. |
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p> | msgs | Pointer to the message array of the data to transfer. |
</th> | count | Length of the message array. |
</tr> | mode | Transmission mode. The value **0** indicates I2C mode, **1** indicates I3C mode, and **2** indicates CCC transmission. |
</thead> | **Return Value**| **Description** |
<tbody><tr><td class="cellrowborder" valign="top" width="50%"><p>handle</p> | Positive integer | The operation is successful. The number of message structures that are successfully transmitted is returned. |
</td> | Negative value | The operation failed. |
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller handle.</p>
</td> The I3C messages are of the I3cMsg type. Each message structure indicates a read or write operation. A message array can be used to perform multiple read or write operations.
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>msgs</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the message structure array of the data to be transmitted.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>count</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Length of the message array.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>mode</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Transmission mode, where the value <b>0</b> indicates the I2C mode, <b>1</b> indicates the I3C mode, and <b>2</b> indicates transmission of the Common Command Code (CCC).
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>Positive integer</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Number of message structures successfully transferred.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>Negative number</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>The operation failed.</p>
</td>
</tr>
</tbody>
</table>
The I3C messages are of the I3cMsg type. Each message structure indicates a read or write operation. A message array is used to perform multiple read or write operations.
```c ```c
int32_t ret; int32_t ret;
...@@ -225,13 +159,14 @@ if (ret != 2) { ...@@ -225,13 +159,14 @@ if (ret != 2) {
} }
``` ```
>![](../public_sys-resources/icon-caution.gif) **Caution** >![](./public_sys-resources/icon-caution.gif) **Caution**<br>
>
>- The device address in the **I3cMsg** structure does not contain the read/write flag bit. The read/write information is passed by the read/write control bit in the member variable **flags**. >- The device address in the **I3cMsg** structure does not contain the read/write flag bit. The read/write information is passed by the read/write control bit in the member variable **flags**.
>- The **I3cTransfer()** function does not limit the number of message structures or the length of data in each message structure. The I3C controller determines these two limits. >- The **I3cTransfer()** function does not limit the number of message structures or the length of data in each message structure. The I3C controller determines these two limits.
>- Using **I3cTransfer()** may cause the system to sleep. Do not call it in the interrupt context. >- Using **I3cTransfer()** may cause the system to sleep. Do not call it in the interrupt context.
### Obtaining the I3C Controller Configuration<a name="section7"></a> #### Obtaining the I3C Controller Configuration
Call **I3cGetConfig()** to obtain the configuration of an I3C controller.
```c ```c
int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config); int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config);
...@@ -239,43 +174,30 @@ int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config); ...@@ -239,43 +174,30 @@ int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config);
**Table 4** Description of I3cGetConfig **Table 4** Description of I3cGetConfig
<a name="table4"></a>
| Name | Description |
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p> | ---------- | -------------- |
</th> | handle | I3C controller handle. |
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p> | config | Pointer to the I3C controller configuration. |
</th> | **Return Value**| **Description**|
</tr> | 0 | The operation is successful. |
</thead> | Negative value | The operation failed. |
<tbody><tr><td class="cellrowborder" valign="top" width="50%"><p>handle</p>
</td> The following is an example of obtaining the I3C controller configuration:
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller handle.</p>
</td> ```c
</tr> struct I3cConfig config;
<tr><td class="cellrowborder" valign="top" width="50%"><p>config</p>
</td> ret = I3cGetConfig(i3cHandle, &config);
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the I3C controller configuration.</p> if (ret != HDF_SUCCESS) {
</td> HDF_LOGE("%s: Get config fail!", __func__);
</tr> return HDF_FAILURE;
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p> }
</td> ```
<td class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</td> #### Setting an I3C Controller
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>0</p> Call **I3cSetConfig()** to set an I3C controller.
</td>
<td class="cellrowborder" valign="top" width="50%"><p>The operation is successful.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>Negative number</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Failed to obtain the I3C controller configuration.</p>
</td>
</tr>
</tbody>
</table>
### Configuring an I3C Controller<a name="section8"></a>
```c ```c
int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config); int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config);
...@@ -283,43 +205,32 @@ int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config); ...@@ -283,43 +205,32 @@ int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config);
**Table 5** Description of I3cSetConfig **Table 5** Description of I3cSetConfig
<a name="table5"></a>
| Name | Description |
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p> | ---------- | -------------- |
</th> | handle | I3C controller handle. |
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p> | config | Pointer to the I3C controller configuration. |
</th> | **Return Value**| **Description**|
</tr> | 0 | The operation is successful. |
</thead> | Negative value | The operation failed. |
<tbody><tr><td class="cellrowborder" valign="top" width="50%"><p>handle</p>
</td> The following is an example of setting an I3C controller:
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller handle.</p>
</td> ```c
</tr> struct I3cConfig config;
<tr><td class="cellrowborder" valign="top" width="50%"><p>config</p>
</td> config->busMode = I3C_BUS_HDR_MODE;
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the I3C controller configuration.</p> config->curMaster = NULL;
</td> ret = I3cSetConfig(i3cHandle, &config);
</tr> if (ret != HDF_SUCCESS) {
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p> HDF_LOGE("%s: Set config fail!", __func__);
</td> return HDF_FAILURE;
<td class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p> }
</td> ```
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>0</p> #### Requesting an IBI
</td>
<td class="cellrowborder" valign="top" width="50%"><p>The operation is successful.</p> Call **I3cRequestIbi()** to request an IBI.
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>Negative number</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Failed to configure the I3C controller.</p>
</td>
</tr>
</tbody>
</table>
### Requesting an IBI<a name="section9"></a>
```c ```c
int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t payload); int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t payload);
...@@ -327,51 +238,18 @@ int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t ...@@ -327,51 +238,18 @@ int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t
**Table 6** Description of I3cRequestIbi **Table 6** Description of I3cRequestIbi
<a name="table6"></a>
| Name | Description |
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p> | ---------- | -------------- |
</th> | handle | I3C controller handle. |
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p> | addr | I3C device address. |
</th> | func | Callback used to return the IBI. |
</tr> | payload | IBI payload. |
</thead> | **Return Value**| **Description**|
<tbody><tr><td class="cellrowborder" valign="top" width="50%"><p>handle</p> | 0 | The operation is successful. |
</td> | Negative value | The operation failed. |
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller handle.</p>
</td> The following is an example:
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>addr</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>I3C device address.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>func</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Callback used to return the IBI.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>payload</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>IBI payload.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</td>
</tr>
<tr><td class="cellrowborder"valign="top" width="50%"><p>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>The operation is successful.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>Negative number</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p> Failed to request the IBI.</p>
</td>
</tr>
</tbody>
</table>
```c ```c
static int32_t TestI3cIbiFunc(DevHandle handle, uint16_t addr, struct I3cIbiData data) static int32_t TestI3cIbiFunc(DevHandle handle, uint16_t addr, struct I3cIbiData data)
...@@ -388,7 +266,7 @@ int32_t I3cTestRequestIbi(void) ...@@ -388,7 +266,7 @@ int32_t I3cTestRequestIbi(void)
DevHandle i3cHandle = NULL; DevHandle i3cHandle = NULL;
int32_t ret; int32_t ret;
/* Open an I3C controller. */ /* Open the I3C controller. */
i3cHandle = I3cOpen(1); i3cHandle = I3cOpen(1);
if (i3cHandle == NULL) { if (i3cHandle == NULL) {
HDF_LOGE("I3cOpen: failed\n"); HDF_LOGE("I3cOpen: failed\n");
...@@ -396,7 +274,7 @@ int32_t I3cTestRequestIbi(void) ...@@ -396,7 +274,7 @@ int32_t I3cTestRequestIbi(void)
} }
ret = I3cRequestIbi(i3cHandle, 0x3F, TestI3cIbiFunc, 16); ret = I3cRequestIbi(i3cHandle, 0x3F, TestI3cIbiFunc, 16);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("%s: Requset IBI failed!", __func__); HDF_LOGE("%s: Request IBI failed!", __func__);
return -1; return -1;
} }
...@@ -407,7 +285,9 @@ int32_t I3cTestRequestIbi(void) ...@@ -407,7 +285,9 @@ int32_t I3cTestRequestIbi(void)
} }
``` ```
### Releasing an IBI<a name="section10"></a> #### Releasing an IBI
Call **I3cFreeIbi()** to release an IBI.
```c ```c
int32_t I3cFreeIbi(DevHandle handle, uint16_t addr); int32_t I3cFreeIbi(DevHandle handle, uint16_t addr);
...@@ -415,47 +295,22 @@ int32_t I3cFreeIbi(DevHandle handle, uint16_t addr); ...@@ -415,47 +295,22 @@ int32_t I3cFreeIbi(DevHandle handle, uint16_t addr);
**Table 7** Description of I3cFreeIbi **Table 7** Description of I3cFreeIbi
<a name="table7"></a>
| Name | Description |
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p> | ---------- | -------------- |
</th> | handle | I3C controller handle. |
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p> | addr | I3C device address. |
</th> | **Return Value**| **Description**|
</tr> | 0 | The operation is successful. |
</thead> | Negative value | The operation failed. |
<tbody><tr><td class="cellrowborder" valign="top" width="50%"><p>handle</p>
</td> The following is an example:
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller handle.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>addr</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>I3C device address.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>The operation is successful.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>Negative number</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Failed to release the IBI.</p>
</td>
</tr>
</tbody>
</table>
```c ```c
I3cFreeIbi(i3cHandle, 0x3F); /* Release an IBI. */ I3cFreeIbi(i3cHandle, 0x3F); /* Release an IBI. */
``` ```
### Closing an I3C controller<a name="section11"></a> #### Closing an I3C Controller
Call **I3cClose()** to close the I3C controller after the communication is complete. Call **I3cClose()** to close the I3C controller after the communication is complete.
```c ```c
...@@ -464,28 +319,18 @@ void I3cClose(DevHandle handle); ...@@ -464,28 +319,18 @@ void I3cClose(DevHandle handle);
**Table 8** Description of I3cClose **Table 8** Description of I3cClose
<a name="table4"></a>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p> Parameter</p> | Name | Description |
</th> | ---------- | -------------- |
<th class="cellrowborder" valign="top" width="50%"><p>Description</p> | handle | I3C controller handle. |
</th>
</tr>
</thead>
<tbody><tr><td class="cellrowborder" valign="top" width="50%"><p>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller handle.</p>
</td>
</tr>
</tbody>
</table>
The following is an example:
```c ```c
I3cClose(i3cHandle); /* Close an I3C controller. */ I3cClose(i3cHandle); /* Close the I3C controller. */
``` ```
## Example<a name="section12""></a> ## Development Example
This following example shows how to use I3C APIs to manage an I3C device on a Hi3516D V300 development board. This following example shows how to use I3C APIs to manage an I3C device on a Hi3516D V300 development board.
...@@ -503,10 +348,9 @@ The sample code is as follows: ...@@ -503,10 +348,9 @@ The sample code is as follows:
```c ```c
#include "i3c_if.h" /* Header file for I3C standard APIs */ #include "i3c_if.h" /* Header file for I3C standard APIs */
#include "i3c_ccc.h" /* Header file for I3C CCC */
#include "hdf_log.h" /* Header file for log APIs */ #include "hdf_log.h" /* Header file for log APIs */
##include "osal_io.h" /* Header file for I/O read and write APIs */ ##include "osal_io.h" /* Header file for I/O read and write APIs */
##include "osal_time.h" /* Header file for delay and sleep APIs */ #include "osal_time.h" /* Header file for delay and sleep APIs */
/* Define a device structure to hold information. */ /* Define a device structure to hold information. */
struct TestI3cDevice { struct TestI3cDevice {
...@@ -516,7 +360,7 @@ struct TestI3cDevice { ...@@ -516,7 +360,7 @@ struct TestI3cDevice {
DevHandle i3cHandle; /* I3C controller handle */ DevHandle i3cHandle; /* I3C controller handle */
}; };
/* Use I3cTransfer to encapsulate a register read/write helper function. Use flag to indicate a read or write operation. */ /* Use I3cTransfer() to encapsulate a register read/write helper function. Use flag to indicate a read or write operation. */
static int TestI3cReadWrite(struct TestI3cDevice *testDevice, unsigned int regAddr, static int TestI3cReadWrite(struct TestI3cDevice *testDevice, unsigned int regAddr,
unsigned char *regData, unsigned int dataLen, uint8_t flag) unsigned char *regData, unsigned int dataLen, uint8_t flag)
{ {
...@@ -539,7 +383,7 @@ static int TestI3cReadWrite(struct TestI3cDevice *testDevice, unsigned int regAd ...@@ -539,7 +383,7 @@ static int TestI3cReadWrite(struct TestI3cDevice *testDevice, unsigned int regAd
msgs[0].buf = regBuf; msgs[0].buf = regBuf;
msgs[1].addr = testDevice->addr; msgs[1].addr = testDevice->addr;
msgs[1].flags = (flag == 1) ? I3C_FLAG_READ: 0; /* Add a read flag bit to read data. */ msgs[1].flags = (flag == 1) ? I3C_FLAG_READ : 0; /* Add the read flag. */
msgs[1].len = dataLen; msgs[1].len = dataLen;
msgs[1].buf = regData; msgs[1].buf = regData;
......
# UART<a name="EN-US_TOPIC_0000001153656474"></a> # UART
## Overview<a name="section1761881586154520"></a>
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. ## Overview
**Figure 1** Independent service mode<a name="fig1474518243468"></a> 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 service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage.
![](figures/independent-service-mode.png "independent-service-mode-14")
## Available APIs<a name="section752964871810"></a> **Figure 1** Independent service mode
![image](figures/independent-service-mode.png)
## Available APIs
**UartHostMethod**:
UartHostMethod
``` ```
struct UartHostMethod { struct UartHostMethod {
...@@ -26,181 +30,57 @@ struct UartHostMethod { ...@@ -26,181 +30,57 @@ struct UartHostMethod {
}; };
``` ```
**Table 1** Callbacks for the members in the UartHostMethod structure **Table 1** Description of the callback functions in UartHostMethod
<a name="table22862114719"></a> | Function| Input Parameter| Output Parameter| Return Value| Description|
<table><thead align="left"><tr id="row5297211471"><th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.1"><p id="p12291121134710"><a name="p12291121134710"></a><a name="p12291121134710"></a>Callback</p> | -------- | -------- | -------- | -------- | -------- |
</th> | Init | **host**: structure pointer to the UART controller at the core layer.| –| HDF_STATUS| Initializes a UART device.|
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.2"><p id="p3291921164712"><a name="p3291921164712"></a><a name="p3291921164712"></a>Input Parameter</p> | Deinit | **host**: structure pointer to the UART controller at the core layer.| –| HDF_STATUS| Deinitializes a UART device.|
</th> | Read | **host**: structure pointer to the UART controller at the core layer.<br>**size**: data size, which is of the uint32_t type.| **data**: pointer to the output data. The value is of the uint8_t type.| HDF_STATUS| Reads data.|
<th class="cellrowborder" valign="top" width="19.98%" id="mcps1.2.6.1.3"><p id="p15291321114718"><a name="p15291321114718"></a><a name="p15291321114718"></a>Output Parameter</p> | Write | **host**: structure pointer to the UART controller at the core layer.<br>**data**: pointer to the input data. The value is of the uint8_t type.<br>**size**: data size, which is of the uint32_t type.| –| HDF_STATUS| Writes data.|
</th> | SetBaud | **host**: structure pointer to the UART controller at the core layer.<br>**baudRate**: pointer to the input baud rate. The value is of the uint32_t type. | –| HDF_STATUS| Sets the baud rate.|
<th class="cellrowborder" valign="top" width="20.02%" id="mcps1.2.6.1.4"><p id="p03092115478"><a name="p03092115478"></a><a name="p03092115478"></a>Return Value</p> | GetBaud | **host**: structure pointer to the UART controller at the core layer.| **baudRate**: pointer to the output baud rate. The value is of the uint32_t type.| HDF_STATUS| Obtains the current baud rate.|
</th> | GetAttribute | **host**: structure pointer to the UART controller at the core layer.| **attribute**: structure pointer to the UART attributes. For details, see **UartAttribute** in **uart_if.h**.| HDF_STATUS| Obtains UART attributes.|
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.5"><p id="p230172113475"><a name="p230172113475"></a><a name="p230172113475"></a>Description</p> | SetAttribute | **host**: structure pointer to the UART controller at the core layer.<br>**attribute**: structure pointer to the UART attributes to set.| –| HDF_STATUS| Sets UART attributes.|
</th> | SetTransMode | **host**: structure pointer to the UART controller at the core layer.<br>**mode**: transfer mode to set. For details, see **UartTransMode** in **uart_if.h**.| –| HDF_STATUS| Sets the UART transfer mode.|
</tr> | PollEvent | **host**: structure pointer to the UART controller at the core layer.<br>**filep**: void pointer to a file.<br>**table**: void pointer to poll_table.| –| HDF_STATUS| Polls for pending events.|
</thead>
<tbody><tr id="row13305217472"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p193012104714"><a name="p193012104714"></a><a name="p193012104714"></a>Init</p>
</td> ## How to Develop
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p53082134713"><a name="p53082134713"></a><a name="p53082134713"></a><strong id="b231216565514"><a name="b231216565514"></a><a name="b231216565514"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p14301121174719"><a name="p14301121174719"></a><a name="p14301121174719"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p83092116473"><a name="p83092116473"></a><a name="p83092116473"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p173032124713"><a name="p173032124713"></a><a name="p173032124713"></a>Initializes the UART device.</p>
</td>
</tr>
<tr id="row530121144713"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p12301215474"><a name="p12301215474"></a><a name="p12301215474"></a>Deinit</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p14301921174718"><a name="p14301921174718"></a><a name="p14301921174718"></a><strong id="b7500154935512"><a name="b7500154935512"></a><a name="b7500154935512"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p143142110477"><a name="p143142110477"></a><a name="p143142110477"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p1531162174719"><a name="p1531162174719"></a><a name="p1531162174719"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p203162110478"><a name="p203162110478"></a><a name="p203162110478"></a>Deinitializes the UART device.</p>
</td>
</tr>
<tr id="row93172118476"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p1231102194712"><a name="p1231102194712"></a><a name="p1231102194712"></a>Read</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p117841019115819"><a name="p117841019115819"></a><a name="p117841019115819"></a><strong id="b8784519205820"><a name="b8784519205820"></a><a name="b8784519205820"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
<p id="p13318214472"><a name="p13318214472"></a><a name="p13318214472"></a><strong id="b76471214185712"><a name="b76471214185712"></a><a name="b76471214185712"></a>size</strong>: data size, which is of the uint32_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p1313213473"><a name="p1313213473"></a><a name="p1313213473"></a><strong id="b1372195311577"><a name="b1372195311577"></a><a name="b1372195311577"></a>data</strong>: uint8_t pointer to the output data.</p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p193110216473"><a name="p193110216473"></a><a name="p193110216473"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p1331102115475"><a name="p1331102115475"></a><a name="p1331102115475"></a>Receives data.</p>
</td>
</tr>
<tr id="row1731102120479"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p731321204711"><a name="p731321204711"></a><a name="p731321204711"></a>Write</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p11377332105815"><a name="p11377332105815"></a><a name="p11377332105815"></a><strong id="b193771532135811"><a name="b193771532135811"></a><a name="b193771532135811"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
<p id="p174031635125817"><a name="p174031635125817"></a><a name="p174031635125817"></a><strong id="b540373505819"><a name="b540373505819"></a><a name="b540373505819"></a>data</strong>: pointer to the input data, which is of the uint8_t type.</p>
<p id="p15311321204719"><a name="p15311321204719"></a><a name="p15311321204719"></a><strong id="b15686191305911"><a name="b15686191305911"></a><a name="b15686191305911"></a>size</strong>: data size, which is of the uint32_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p143142114478"><a name="p143142114478"></a><a name="p143142114478"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p143212110477"><a name="p143212110477"></a><a name="p143212110477"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p123216211477"><a name="p123216211477"></a><a name="p123216211477"></a>Sends data.</p>
</td>
</tr>
<tr id="row73215214478"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p1032112119475"><a name="p1032112119475"></a><a name="p1032112119475"></a>SetBaud</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p863959125812"><a name="p863959125812"></a><a name="p863959125812"></a><strong id="b11631159145818"><a name="b11631159145818"></a><a name="b11631159145818"></a>host</strong>: structure pointer to the UART controller at the core layer. </p>
<p id="p3321521134717"><a name="p3321521134717"></a><a name="p3321521134717"></a><strong id="b16745461412"><a name="b16745461412"></a><a name="b16745461412"></a>baudRate</strong>: pointer to the input baud rate, which is of the uint32_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p18327218478"><a name="p18327218478"></a><a name="p18327218478"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p23242111475"><a name="p23242111475"></a><a name="p23242111475"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p7321521114711"><a name="p7321521114711"></a><a name="p7321521114711"></a>Sets the baud rate.</p>
</td>
</tr>
<tr id="row113252104713"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p9323219476"><a name="p9323219476"></a><a name="p9323219476"></a>GetBaud</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p132821184711"><a name="p132821184711"></a><a name="p132821184711"></a><strong id="b4510164912550"><a name="b4510164912550"></a><a name="b4510164912550"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p63262112477"><a name="p63262112477"></a><a name="p63262112477"></a><strong id="b1097116311227"><a name="b1097116311227"></a><a name="b1097116311227"></a>baudRate</strong>: uint32_t pointer to the output baud rate.</p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p13262174719"><a name="p13262174719"></a><a name="p13262174719"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p163232154717"><a name="p163232154717"></a><a name="p163232154717"></a>Obtains the current baud rate.</p>
</td>
</tr>
<tr id="row2032102118472"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p9331321154714"><a name="p9331321154714"></a><a name="p9331321154714"></a>GetAttribute</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p15331721164715"><a name="p15331721164715"></a><a name="p15331721164715"></a><strong id="b1518144935510"><a name="b1518144935510"></a><a name="b1518144935510"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p23313219472"><a name="p23313219472"></a><a name="p23313219472"></a><strong id="b16392039333"><a name="b16392039333"></a><a name="b16392039333"></a>attribute</strong>: structure pointer to the output attributes. For details, see <strong id="b524111513416"><a name="b524111513416"></a><a name="b524111513416"></a>UartAttribute</strong> in <strong id="b47291920444"><a name="b47291920444"></a><a name="b47291920444"></a>uart_if.h</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p833142115476"><a name="p833142115476"></a><a name="p833142115476"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p63342119476"><a name="p63342119476"></a><a name="p63342119476"></a>Obtains UART attributes.</p>
</td>
</tr>
<tr id="row1133112144717"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p14331421114715"><a name="p14331421114715"></a><a name="p14331421114715"></a>SetAttribute</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p147011110590"><a name="p147011110590"></a><a name="p147011110590"></a><strong id="b070151125915"><a name="b070151125915"></a><a name="b070151125915"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
<p id="p16331210473"><a name="p16331210473"></a><a name="p16331210473"></a><strong id="b1497919522420"><a name="b1497919522420"></a><a name="b1497919522420"></a>attribute</strong>: structure pointer to the input attributes.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p3331721204710"><a name="p3331721204710"></a><a name="p3331721204710"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p03302111471"><a name="p03302111471"></a><a name="p03302111471"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p1933152113478"><a name="p1933152113478"></a><a name="p1933152113478"></a>Sets UART attributes.</p>
</td>
</tr>
<tr id="row834221114716"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p1934821104719"><a name="p1934821104719"></a><a name="p1934821104719"></a>SetTransMode</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1821251985919"><a name="p1821251985919"></a><a name="p1821251985919"></a><strong id="b1121271918594"><a name="b1121271918594"></a><a name="b1121271918594"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
<p id="p1034621104717"><a name="p1034621104717"></a><a name="p1034621104717"></a><strong id="b104767219711"><a name="b104767219711"></a><a name="b104767219711"></a>mode</strong>: transmission mode, which is an enumerated value. For details, see <strong id="b2101455871"><a name="b2101455871"></a><a name="b2101455871"></a>UartTransMode</strong> in <strong id="b99657016815"><a name="b99657016815"></a><a name="b99657016815"></a>uart_if.h</strong>).</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p173442110475"><a name="p173442110475"></a><a name="p173442110475"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p1734721194720"><a name="p1734721194720"></a><a name="p1734721194720"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p15341021194715"><a name="p15341021194715"></a><a name="p15341021194715"></a>Sets the UART transmission mode.</p>
</td>
</tr>
<tr id="row434192119479"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p133442184717"><a name="p133442184717"></a><a name="p133442184717"></a>PollEvent</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p31278367592"><a name="p31278367592"></a><a name="p31278367592"></a><strong id="b1127163625919"><a name="b1127163625919"></a><a name="b1127163625919"></a>host</strong>: structure pointer to the UART controller at the core layer.</p>
<p id="p16654144015591"><a name="p16654144015591"></a><a name="p16654144015591"></a><strong id="b86541440135917"><a name="b86541440135917"></a><a name="b86541440135917"></a>filep</strong>: void pointer to a file.</p>
<p id="p634121104712"><a name="p634121104712"></a><a name="p634121104712"></a><strong id="b163481035141514"><a name="b163481035141514"></a><a name="b163481035141514"></a>table</strong>: void pointer to a poll_table.</p>
</td>
<td class="cellrowborder" valign="top" width="19.98%" headers="mcps1.2.6.1.3 "><p id="p1334142111479"><a name="p1334142111479"></a><a name="p1334142111479"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20.02%" headers="mcps1.2.6.1.4 "><p id="p133472110473"><a name="p133472110473"></a><a name="p133472110473"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p63522174720"><a name="p63522174720"></a><a name="p63522174720"></a>Polls for pending events.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section944397404154520"></a>
The UART module adaptation involves the following steps: The UART module adaptation involves the following steps:
1. Instantiate the driver entry. 1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure. - Instantiate the **HdfDriverEntry** structure.
- Call **HDF\_INIT** to register the **HdfDriverEntry** instance with the HDF. - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files. 2. Configure attribute files.
- Add the **deviceNode** information to the **device\_info.hcs** file. - Add the **deviceNode** information to the **device_info.hcs** file.
- \(Optional\) Add the **uart\_config.hcs** file. - (Optional) Add the **uart_config.hcs** file.
3. Instantiate the UART controller object. 3. Instantiate the UART controller object.
- Initialize **UartHost**. - Initialize **UartHost**.
- Instantiate **UartHostMethod** in the **UartHost** object. - Instantiate **UartHostMethod** in the **UartHost** object.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
> For details about the functions in **UartHostMethod**, see [Available APIs](#available-apis).
>![](../public_sys-resources/icon-note.gif) **NOTE** 4. Debug the driver.<br>
(Optional) For new drivers, verify the basic functions, such as the UART status control and response to interrupts.
>For details, see [Available APIs](#available-apis).
## Development Example
4. Debug the driver. The following uses **uart_hi35xx.c** as an example to present the information required for implementing device functions.
- \(Optional\) For new drivers, verify the basic functions, such as the UART control status and response to interrupts.
1. Instantiate the driver entry.<br/>The driver entry must be a global variable of the **HdfDriverEntry** type (defined in **hdf_device_desc.h**), and the value of **moduleName** must be the same as that in **device_info.hcs**. In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke.
Generally, the HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
## Development Example<a name="section774610224154520"></a> UART driver entry example:
The following uses **uart\_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions.
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type \(defined in **hdf\_device\_desc.h**\), and the value of **moduleName** must be the same as that in **device\_info.hcs**. In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke.
Generally, HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, HDF calls **Release** to release driver resources and exit.
- UART driver entry reference
``` ```
struct HdfDriverEntry g_hdfUartDevice = { struct HdfDriverEntry g_hdfUartDevice = {
.moduleVersion = 1, .moduleVersion = 1,
.moduleName = "HDF_PLATFORM_UART", // (Mandatory) This parameter must be the same as that in the .hcs file. .moduleName = "HDF_PLATFORM_UART", // (Mandatory) The value must be the same as that in the .hcs file.
.Bind = HdfUartDeviceBind, // See the Bind function. .Bind = HdfUartDeviceBind, // See the Bind function.
.Init = HdfUartDeviceInit, // See the Init function. .Init = HdfUartDeviceInit, // See the Init function.
.Release = HdfUartDeviceRelease, //See the Release function. .Release = HdfUartDeviceRelease, //See the Release function.
...@@ -209,11 +89,10 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -209,11 +89,10 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
HDF_INIT(g_hdfUartDevice); HDF_INIT(g_hdfUartDevice);
``` ```
2. Add the **deviceNode** information to the **device\_info.hcs** file and configure the device attributes in the **uart\_config.hcs** file. The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **UartHost** members at the core layer. 2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **uart_config.hcs** file.<br> The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **UartHost** members at the core layer.
In this example, there is only one UART controller. If there are multiple UART controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **uart_config** file for each controller.
- **device_info.hcs** configuration example
In this example, there is only one UART controller. If there are multiple UART controllers, you need to add the **deviceNode** information to the **device\_info** file and add the corresponding device attributes to the **uart\_config** file.
- **device\_info.hcs** configuration reference
``` ```
root { root {
...@@ -224,15 +103,15 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -224,15 +103,15 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
priority = 50; priority = 50;
device_uart :: device { device_uart :: device {
device0 :: deviceNode { device0 :: deviceNode {
policy = 1; // The value 1 indicates that the driver publishes kernel-mode services. The value 2 indicates that the driver publishes user-mode services. policy = 1; // The driver publishes services only for kernel-mode processes.
priority = 40; // Driver startup priority priority = 40; // Driver startup priority.
permission = 0644; // Permission for the driver to create a device node permission = 0644; // Permission for the driver to create a device node.
moduleName = "HDF_PLATFORM_UART"; // Driver name, which must be the same as that of moduleName in the driver entry structure. moduleName = "HDF_PLATFORM_UART"; // Driver name, which must be the same as moduleName in the HdfDriverEntry structure.
serviceName = "HDF_PLATFORM_UART_0";// Unique name of the service published by the driver. The name is in the HDF_PLATFORM_UART_X format. X indicates the UART controller number. serviceName = "HDF_PLATFORM_UART_0";// Unique name of the service published by the driver. The name is in the HDF_PLATFORM_UART_X format. X indicates the UART controller number.
deviceMatchAttr = "hisilicon_hi35xx_uart_0"; // 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. deviceMatchAttr = "hisilicon_hi35xx_uart_0"; // 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.
} }
device1 :: deviceNode { device1 :: deviceNode {
policy = 2; policy = 2; // The driver publishes services for both kernel- and user-mode processes.
permission = 0644; permission = 0644;
priority = 40; priority = 40;
moduleName = "HDF_PLATFORM_UART"; moduleName = "HDF_PLATFORM_UART";
...@@ -246,20 +125,21 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -246,20 +125,21 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
} }
``` ```
- **uart\_config.hcs** configuration reference - **uart_config.hcs** configuration example
``` ```
root { root {
platform { platform {
template uart_controller {// Template configuration. In the template, you can configure the common parameters shared by service nodes. template uart_controller { // Template configuration. In the template, you can configure the common parameters shared by device nodes.
match_attr = ""; match_attr = "";
num = 0; // (Mandatory) Device number num = 0; // (Mandatory) Device number
baudrate = 115200; // (Mandatory) Baud rate. Set the value based on service requirements. baudrate = 115200; // (Mandatory) Baud rate. Set the value based on service requirements.
fifoRxEn = 1; // (Mandatory) Enable the receive of FIFOs. fifoRxEn = 1; // (Mandatory) Enable FIFOs to be received.
fifoTxEn = 1; // (Mandatory) Enable the transmit of FIFOs. fifoTxEn = 1; // (Mandatory) Enable FIFOs to be transferred.
flags = 4; // (Mandatory) Flag signal flags = 4; // (Mandatory) Flag signal.
regPbase = 0x120a0000; // (Mandatory) Used for address mapping. regPbase = 0x120a0000; // (Mandatory) Used for address mapping.
interrupt = 38; // (Mandatory) Interrupt number interrupt = 38; // (Mandatory) Interrupt number.
iomemCount = 0x48; // (Mandatory) Used for address mapping. iomemCount = 0x48; // (Mandatory) Used for address mapping.
} }
controller_0x120a0000 :: uart_controller { controller_0x120a0000 :: uart_controller {
...@@ -273,42 +153,43 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -273,42 +153,43 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
match_attr = "hisilicon_hi35xx_uart_1"; match_attr = "hisilicon_hi35xx_uart_1";
} }
... ...
//(Optional) Add nodes to the device_info.hcs file as required. //(Optional) Add more controller data. The node information must have been added in the device_info.hcs file.
} }
} }
``` ```
3. Initialize the **UartHost** object at the core layer, including initializing the vendor custom structure \(transferring parameters and data\), instantiating **UartHostMethod** \(used to call underlying functions of the driver\) in **UartHost**, and implementing the **HdfDriverEntry** member functions \(**Bind**, **Init**, and **Release**\). 3. Initialize the **UartHost** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **UartHostMethod** in **UartHost** (so that the underlying driver functions can be called).
- Custom structure reference - Defining a custom structure
To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **uart_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number, to the **UartHost** object at the core layer.
To the driver, the custom structure carries parameters and data. The values in the **uart\_config.hcs** file are read by HDF, and the structure members are initialized through **DeviceResourceIface**. Some important values, such as the device number, are also passed to the objects at the core layer.
``` ```
struct UartPl011Port {// Structure related to the API struct UartPl011Port { // Interface structure
int32_t enable; int32_t enable;
unsigned long physBase; // Physical address unsigned long physBase; // Physical address
uint32_t irqNum; // Interrupt number uint32_t irqNum; // Interrupt number
uint32_t defaultBaudrate;// Default baud rate uint32_t defaultBaudrate;// Default baud rate
uint32_t flags; // Flag signal, which is related to the following three macros. uint32_t flags; // Flags related to the following three macros.
#define PL011_FLG_IRQ_REQUESTED (1 << 0) #define PL011_FLG_IRQ_REQUESTED (1 << 0)
#define PL011_FLG_DMA_RX_REQUESTED (1 << 1) #define PL011_FLG_DMA_RX_REQUESTED (1 << 1)
#define PL011_FLG_DMA_TX_REQUESTED (1 << 2) #define PL011_FLG_DMA_TX_REQUESTED (1 << 2)
struct UartDmaTransfer *rxUdt; // DMA transmission struct UartDmaTransfer *rxUdt; // DMA transfer
struct UartDriverData *udd; // See the following description. struct UartDriverData *udd; // The data structure is defined as follows:
}; };
struct UartDriverData {// Structure related to data transmission struct UartDriverData { // Structure related to data transfer
uint32_t num; uint32_t num;
uint32_t baudrate; // Baud rate (configurable) uint32_t baudrate; // Baud rate (configurable)
struct UartAttribute attr; // Transmission attributes, such as the data bit and stop bit struct UartAttribute attr; // Attributes, such as the data bit and stop bit, related to data transfer
struct UartTransfer *rxTransfer; // FIFO structure related to the buffer struct UartTransfer *rxTransfer; // Buffer (FIFO structure)
wait_queue_head_t wait; // Queuing signal related to conditional variables wait_queue_head_t wait; // Queuing signal related to conditional variables
int32_t count; // Data count int32_t count; // Data count
int32_t state; // UART controller status int32_t state; // UART controller state
#define UART_STATE_NOT_OPENED 0 #define UART_STATE_NOT_OPENED 0
#define UART_STATE_OPENING 1 #define UART_STATE_OPENING 1
#define UART_STATE_USEABLE 2 #define UART_STATE_USEABLE 2
#define UART_STATE_SUSPENED 3 #define UART_STATE_SUSPENDED 3
uint32_t flags; // Status flag uint32_t flags; // Status flags
#define UART_FLG_DMA_RX (1 << 0) #define UART_FLG_DMA_RX (1 << 0)
#define UART_FLG_DMA_TX (1 << 1) #define UART_FLG_DMA_TX (1 << 1)
#define UART_FLG_RD_BLOCK (1 << 2) #define UART_FLG_RD_BLOCK (1 << 2)
...@@ -317,21 +198,21 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -317,21 +198,21 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
void *private; // It stores the pointer to the start address of UartPl011Port for easy invocation. void *private; // It stores the pointer to the start address of UartPl011Port for easy invocation.
}; };
// UartHost is the controller structure at the core layer. Its members are assigned with values by using the Init function. // UartHost is the controller structure at the core layer. The Init function assigns values to the members of UartHost.
struct UartHost { struct UartHost {
struct IDeviceIoService service; struct IDeviceIoService service;
struct HdfDeviceObject *device; struct HdfDeviceObject *device;
uint32_t num; uint32_t num;
OsalAtomic atom; OsalAtomic atom;
void *priv; // It stores the pointer to the start address of the vendor's custom structure for invoking the structure. void *priv; // It stores the pointer to the start address of the vendor's custom structure for easy invocation.
struct UartHostMethod *method; // Hook at the core layer. The vendor needs to implement and instantiate its member functions. struct UartHostMethod *method; // Hook at the core layer. You need to implement and instantiate its member functions.
}; };
``` ```
- Instantiating **UartHostMethod** in **UartHost** (other members are initialized by **Bind**)
- Instantiate the callback function structure **UartHostMethod** in **UartHost**. Other members are initialized by using the **Bind** function.
``` ```
// Example in pwm_hi35xx.c: instantiate the hook. // Example in uart_hi35xx.c: instantiate the hook.
struct UartHostMethod g_uartHostMethod = { struct UartHostMethod g_uartHostMethod = {
.Init = Hi35xxInit, .Init = Hi35xxInit,
.Deinit = Hi35xxDeinit, .Deinit = Hi35xxDeinit,
...@@ -346,62 +227,32 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -346,62 +227,32 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
}; };
``` ```
- Bind function - **Bind** function
Input parameters: Input parameter:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return values: Return value:
HDF\_STATUS \(The following table lists some status. For details about other status, see **HDF\_STATUS** in the **//drivers/framework/include/utils/hdf\_base.h** file.\) HDF_STATUS<br/>The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
**Table 2** Input parameters and return values of the Bind function **Table 2** HDF_STATUS
<a name="table69781823185619"></a> | Status| Description|
<table><thead align="left"><tr id="row997916234569"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p99801123205616"><a name="p99801123205616"></a><a name="p99801123205616"></a>Status (Value)</p> | -------- | -------- |
</th> | HDF_ERR_INVALID_OBJECT | Invalid controller object.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p698092355615"><a name="p698092355615"></a><a name="p698092355615"></a>Description</p> | HDF_ERR_MALLOC_FAIL | Failed to allocate memory.|
</th> | HDF_ERR_INVALID_PARAM | Invalid parameter.|
</tr> | HDF_ERR_IO | I/O error.|
</thead> | HDF_SUCCESS | Initialization successful.|
<tbody><tr id="row39803236568"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p8980123175613"><a name="p8980123175613"></a><a name="p8980123175613"></a>HDF_ERR_INVALID_OBJECT</p> | HDF_FAILURE | Initialization failed.|
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p79801423165611"><a name="p79801423165611"></a><a name="p79801423165611"></a>Invalid controller object</p>
</td>
</tr>
<tr id="row3980023165617"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p698011239568"><a name="p698011239568"></a><a name="p698011239568"></a>HDF_ERR_MALLOC_FAIL</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p798082395610"><a name="p798082395610"></a><a name="p798082395610"></a>Failed to allocate memory</p>
</td>
</tr>
<tr id="row10980223165610"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1980172365614"><a name="p1980172365614"></a><a name="p1980172365614"></a>HDF_ERR_INVALID_PARAM</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p14980223145614"><a name="p14980223145614"></a><a name="p14980223145614"></a>Invalid parameter</p>
</td>
</tr>
<tr id="row7980142315612"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p17980152385611"><a name="p17980152385611"></a><a name="p17980152385611"></a>HDF_ERR_IO</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p17980182385611"><a name="p17980182385611"></a><a name="p17980182385611"></a>I/O error</p>
</td>
</tr>
<tr id="row9980122312564"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p10981323155616"><a name="p10981323155616"></a><a name="p10981323155616"></a>HDF_SUCCESS</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p11981423175614"><a name="p11981423175614"></a><a name="p11981423175614"></a>Initialization successful</p>
</td>
</tr>
<tr id="row15981122365618"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p19981122311567"><a name="p19981122311567"></a><a name="p19981122311567"></a>HDF_FAILURE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p199811723105615"><a name="p199811723105615"></a><a name="p199811723105615"></a>Initialization failed</p>
</td>
</tr>
</tbody>
</table>
Function description: Function description:
Initializes the custom structure object and **UartHost**. Initializes the custom structure object and **UartHost**.
``` ```
//uart_hi35xx.c //uart_hi35xx.c
static int32_t HdfUartDeviceBind(struct HdfDeviceObject *device) static int32_t HdfUartDeviceBind(struct HdfDeviceObject *device)
...@@ -409,36 +260,37 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -409,36 +260,37 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
... ...
return (UartHostCreate(device) == NULL)? HDF_FAILURE: HDF_SUCCESS;// (Mandatory) Call UartHostCreate. return (UartHostCreate(device) == NULL)? HDF_FAILURE: HDF_SUCCESS;// (Mandatory) Call UartHostCreate.
} }
// Description of the UartHostCreate function at the core layer in uart_core.c // Description of UartHostCreate() in uart_core.c
struct UartHost *UartHostCreate(struct HdfDeviceObject *device) struct UartHost *UartHostCreate(struct HdfDeviceObject *device)
{ {
struct UartHost *host = NULL; // Create a UartHost. struct UartHost *host = NULL; // Create UartHost.
... ...
host = (struct UartHost *)OsalMemCalloc(sizeof(*host));// Apply for memory. host = (struct UartHost *)OsalMemCalloc(sizeof(*host));// Allocate memory.
... ...
host->device = device; // (Mandatory) Enable conversion between HdfDeviceObject and UartHost. host->device = device; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and UartHost
device->service = &(host->service); // (Mandatory) Enable conversion between HdfDeviceObject and UartHost. device->service = &(host->service; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and UartHost
host->device->service->Dispatch = UartIoDispatch;// Assign a value to the Dispatch method of service. host->device->service->Dispatch = UartIoDispatch;// Assign values to Dispatch of service.
OsalAtomicSet(&host->atom, 0); // Initialize or set atomic data. OsalAtomicSet(&host->atom, 0); // Initialize or set the atomic services.
host->priv = NULL; host->priv = NULL;
host->method = NULL; host->method = NULL;
return host; return host;
} }
``` ```
- Init function - **Init** function
Input parameters: Input parameter:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return values: Return value:
HDF\_STATUS HDF_STATUS
Function description: Function description:
Initializes the custom structure object and **UartHost**, calls the **artAddDev** function at the core layer, and connects to VFS. Initializes the custom structure object and **UartHost**, calls the **artAddDev** function at the core layer, and connects to the VFS.
``` ```
int32_t HdfUartDeviceInit(struct HdfDeviceObject *device) int32_t HdfUartDeviceInit(struct HdfDeviceObject *device)
...@@ -447,38 +299,38 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -447,38 +299,38 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
struct UartHost *host = NULL; struct UartHost *host = NULL;
HDF_LOGI("%s: entry", __func__); HDF_LOGI("%s: entry", __func__);
... ...
host = UartHostFromDevice(device);// Forcibly convert to UartHost by using service. The value is assigned in the Bind function. host = UartHostFromDevice(device);// Forcibly convert to UartHost by using service. The values are assigned by Bind().
... ...
ret = Hi35xxAttach(host, device); // Initialize the UartHost object. ret = Hi35xxAttach(host, device); // Initialize the UartHost object.
... ...
host->method = &g_uartHostMethod; // Connect to the UARTHostMethod instance. host->method = &g_uartHostMethod; // Hook the UartHostMethod instance.
return ret; return ret;
} }
// Complete initialization of the UartHost object. // Initialize UartHost.
static int32_t Hi35xxAttach(struct UartHost *host, struct HdfDeviceObject *device) static int32_t Hi35xxAttach(struct UartHost *host, struct HdfDeviceObject *device)
{ {
int32_t ret; int32_t ret;
// udd and port are structure objects customized by the vendor. The vendor needs to implement related functions as required. // udd and port are customized structure objects. Implement the related functions as required.
struct UartDriverData *udd = NULL; struct UartDriverData *udd = NULL;
struct UartPl011Port *port = NULL; struct UartPl011Port *port = NULL;
... ...
// Steps [1] to [7] assign values to udd and then to the UartHost object at the core layer. // Steps 1 to 7 instantiate and assign values to the udd object, and then assign values to UartHost.
udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd));// [1] udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd));// Step 1
... ...
port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port));// [2] port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port));// Step 2
... ...
udd->ops = Pl011GetOps();// [3] Perform operations, such as starting or stopping a device, setting attributes, and sending data. udd->ops = Pl011GetOps(); // Step 3 Hook the functions for starting or stopping a device, setting attributes, and sending data.
udd->recv = PL011UartRecvNotify;// [4] Connect to the data receiving notification function (conditional lock mechanism). udd->recv = PL011UartRecvNotify;// Step 4 Hook the data receiving notification function (conditional lock mechanism).
udd->count = 0; // [5] udd->count = 0; // Step 5
port->udd = udd; // [6] Enable conversion between UartPl011Port and UartDriverData. port->udd = udd; // Step 6 Enable conversion between UartPl011Port and UartDriverData.
ret = UartGetConfigFromHcs(port, device->property);// (Mandatory) Transfer the attributes of HdfDeviceObject to the vendor custom structure. ret = UartGetConfigFromHcs(port, device->property);// Pass the attributes of HdfDeviceObject to the custom structure.
// The sample code is as follows: // The sample code is as follows:
... ...
udd->private = port; // [7] udd->private = port; // Step 7
host->priv = udd; // (Mandatory) Enable conversion between UartHost and UartDriverData. host->priv = udd; // (Mandatory) Enable conversion between UartHost and UartDriverData.
host->num = udd->num;// (Mandatory) UART device number host->num = udd->num; // (Mandatory) UART device number
UartAddDev(host); // (Mandatory) Function in uart_dev.c at the core layer used to register a character device node with the VFS so that the UART can be accessed in user mode through this virtual file node. UartAddDev(host); // (Mandatory) Function (in uart_dev.c) used to register a character device node to the VFS so that the UART can be accessed through the virtual file node in user mode.
return HDF_SUCCESS; return HDF_SUCCESS;
} }
...@@ -488,7 +340,7 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -488,7 +340,7 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
struct UartDriverData *udd = port->udd; struct UartDriverData *udd = port->udd;
struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
... ...
// Extract the value based on the request parameter and assign the value to the vendor custom structure. // Extract the values based on the request and assign the values to the custom structure.
if (iface->GetUint32(node, "num", &udd->num, 0) != HDF_SUCCESS) { if (iface->GetUint32(node, "num", &udd->num, 0) != HDF_SUCCESS) {
HDF_LOGE("%s: read busNum fail", __func__); HDF_LOGE("%s: read busNum fail", __func__);
return HDF_FAILURE; return HDF_FAILURE;
...@@ -497,20 +349,20 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -497,20 +349,20 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
return 0; return 0;
} }
``` ```
- **Release** function
- Release function Input parameter:
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return values: Return value:
No value is returned.
Function description: Function description:
Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations. Releases the memory and deletes the controller. This function assigns values to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. All forced conversion operations for obtaining the corresponding object can be successful only when **Init()** has the corresponding value assignment operations.
``` ```
void HdfUartDeviceRelease(struct HdfDeviceObject *device) void HdfUartDeviceRelease(struct HdfDeviceObject *device)
...@@ -520,7 +372,7 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -520,7 +372,7 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
host = UartHostFromDevice(device);// Forcibly convert HdfDeviceObject to UartHost by using service. For details about the value assignment, see the Bind function. host = UartHostFromDevice(device);// Forcibly convert HdfDeviceObject to UartHost by using service. For details about the value assignment, see the Bind function.
... ...
if (host->priv != NULL) { if (host->priv != NULL) {
Hi35xxDetach(host); // Memory release function customized by the vendor. For details, see the following description. Hi35xxDetach(host); // Customized memory release function.
} }
UartHostDestroy(host); // Call the function of the core layer to release the host. UartHostDestroy(host); // Call the function of the core layer to release the host.
} }
...@@ -536,15 +388,12 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th ...@@ -536,15 +388,12 @@ The following uses **uart\_hi35xx.c** as an example to present the contents th
port = udd->private;// Convert UartDriverData to UartPl011Port. port = udd->private;// Convert UartDriverData to UartPl011Port.
if (port != NULL) { if (port != NULL) {
if (port->physBase != 0) { if (port->physBase != 0) {
OsalIoUnmap((void *)port->physBase);// Remove address mapping. OsalIoUnmap((void *)port->physBase);// Unmap addresses.
} }
(void)OsalMemFree(port); OsalMemFree(port);
udd->private = NULL; udd->private = NULL;
} }
(void)OsalMemFree(udd);// Release UartDriverData. OsalMemFree(udd);//Release UartDriverData.
host->priv = NULL; host->priv = NULL;
} }
``` ```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册