| Init | **host**: structure pointer to the UART controller at the core layer.| –| HDF_STATUS| Initializes a UART device.|
| Init | **host**: structure pointer to the UART controller at the core layer.| –| HDF_STATUS| Initializes a UART device.|
| Deinit | **host**: structure pointer to the UART controller at the core layer.| –| HDF_STATUS| Deinitializes a UART device.|
| Deinit | **host**: structure pointer to the UART controller at the core layer.| –| HDF_STATUS| Deinitializes a UART device.|
| 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.|
| 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 data read. The value is of the uint8_t type. | HDF_STATUS| Reads data.|
| 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.|
| Write | **host**: structure pointer to the UART controller at the core layer.<br>**data**: pointer to the data to write. The value is of the uint8_t type.<br>**size**: data size, which is of the uint32_t type. | –| HDF_STATUS| Writes data.|
| 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.|
| SetBaud | **host**: structure pointer to the UART controller at the core layer.<br>**baudRate**: pointer to the baud rate to set. The value is of the uint32_t type. | –| HDF_STATUS| Sets the baud rate.|
| 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.|
| GetBaud | **host**: structure pointer to the UART controller at the core layer.| **baudRate**: pointer to the baud rate obtained. The value is of the uint32_t type. | HDF_STATUS| Obtains the current baud rate.|
| 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.|
| GetAttribute | **host**: structure pointer to the UART controller at the core layer.| **attribute**: structure pointer to the attribute obtained. For details, see **UartAttribute** in **uart_if.h**. | HDF_STATUS| Obtains UART attributes.|
| 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.|
| SetAttribute | **host**: structure pointer to the UART controller at the core layer.<br>**attribute**: structure pointer to the attribute to set. | –| HDF_STATUS| Sets UART attributes.|
| 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.|
| 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.|
| 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.|
| 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.|
...
@@ -61,10 +61,11 @@ The UART module adaptation involves the following steps:
...
@@ -61,10 +61,11 @@ The UART module adaptation involves the following steps:
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.
> For details about the functions in **UartHostMethod**, see [Available APIs](#available-apis).
> For details about the functions in **UartHostMethod**, see [Available APIs](#available-apis).
4. Debug the driver.<br>
4. Debug the driver.
(Optional) For new drivers, verify the basic functions, such as the UART status control and response to interrupts.
(Optional) For new drivers, verify the basic functions, such as the UART status control and response to interrupts.
...
@@ -72,7 +73,12 @@ The UART module adaptation involves the following steps:
...
@@ -72,7 +73,12 @@ The UART module adaptation involves the following steps:
The following uses **uart_hi35xx.c** as an example to present the information required for implementing device functions.
The following uses **uart_hi35xx.c** as an example to present the information required for implementing device functions.
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.
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, 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.
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.
UART driver entry example:
UART driver entry example:
...
@@ -89,9 +95,13 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -89,9 +95,13 @@ The following uses **uart_hi35xx.c** as an example to present the information re
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.<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.
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.
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.
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
-**device_info.hcs** configuration example:
```
```
...
@@ -107,7 +117,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -107,7 +117,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
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 moduleName in the HdfDriverEntry 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 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.
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 {
...
@@ -133,7 +143,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -133,7 +143,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
platform {
platform {
template uart_controller { // Template configuration. In the template, you can configure the common parameters shared by device 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 FIFOs to be received.
fifoRxEn = 1; // (Mandatory) Enable FIFOs to be received.
fifoTxEn = 1; // (Mandatory) Enable FIFOs to be transferred.
fifoTxEn = 1; // (Mandatory) Enable FIFOs to be transferred.
...
@@ -159,6 +169,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -159,6 +169,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
```
```
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).
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).
- Defining a custom structure
- 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 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.
...
@@ -169,8 +180,8 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -169,8 +180,8 @@ The following uses **uart_hi35xx.c** as an example to present the information re
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; // Flags 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)
...
@@ -180,7 +191,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -180,7 +191,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
struct UartDriverData { // Structure related to data transfer
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; // Attributes, such as the data bit and stop bit, related to data transfer
struct UartAttribute attr; // Attributes, such as the data bit and stop bit, related to data transfer.
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
...
@@ -193,7 +204,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -193,7 +204,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
#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)
RecvNotify recv; // Pointer to the function that receives serial port data
RecvNotify recv; // Pointer to the function that receives serial port data.
struct UartOps *ops; // Custom function pointer structure. For details, see device/hisilicon/drivers/uart/uart_pl011.c.
struct UartOps *ops; // Custom function pointer structure. For details, see device/hisilicon/drivers/uart/uart_pl011.c.
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.
};
};
...
@@ -208,6 +219,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -208,6 +219,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
struct UartHostMethod *method; // Hook at the core layer. You need 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**)
- Instantiating **UartHostMethod** in **UartHost** (other members are initialized by **Bind**)
...
@@ -229,15 +241,15 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -229,15 +241,15 @@ The following uses **uart_hi35xx.c** as an example to present the information re
-**Bind** function
-**Bind** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
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.
**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** HDF_STATUS
**Table 2** Description of HDF_STATUS
| Status| Description|
| Status| Description|
| -------- | -------- |
| -------- | -------- |
...
@@ -248,7 +260,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -248,7 +260,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
| HDF_SUCCESS | Initialization successful.|
| HDF_SUCCESS | Initialization successful.|
| HDF_FAILURE | Initialization failed.|
| HDF_FAILURE | Initialization failed.|
Function description:
**Function description**:
Initializes the custom structure object and **UartHost**.
Initializes the custom structure object and **UartHost**.
...
@@ -267,9 +279,9 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -267,9 +279,9 @@ The following uses **uart_hi35xx.c** as an example to present the information re
host->device = device; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and UartHost
host->device = device; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and UartHost.
device->service = &(host->service; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and UartHost
device->service = &(host->service; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and UartHost.
host->device->service->Dispatch = UartIoDispatch;// Assign values to Dispatch of service.
host->device->service->Dispatch = UartIoDispatch;// Assign values to Dispatch of service.
OsalAtomicSet(&host->atom, 0); // Initialize or set the atomic services.
OsalAtomicSet(&host->atom, 0); // Initialize or set the atomic services.
host->priv = NULL;
host->priv = NULL;
host->method = NULL;
host->method = NULL;
...
@@ -279,15 +291,15 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -279,15 +291,15 @@ The following uses **uart_hi35xx.c** as an example to present the information re
-**Init** function
-**Init** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**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 the VFS.
Initializes the custom structure object and **UartHost**, calls the **artAddDev** function at the core layer, and connects to the VFS.
...
@@ -303,7 +315,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -303,7 +315,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
...
ret = Hi35xxAttach(host, device); // Initialize the UartHost object.
ret = Hi35xxAttach(host, device); // Initialize the UartHost object.
...
...
host->method = &g_uartHostMethod; // Hook the UartHostMethod instance.
host->method = &g_uartHostMethod; // Attach the UartHostMethod instance.
return ret;
return ret;
}
}
// Initialize UartHost.
// Initialize UartHost.
...
@@ -351,17 +363,21 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -351,17 +363,21 @@ The following uses **uart_hi35xx.c** as an example to present the information re
```
```
-**Release** function
-**Release** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
No value is returned.
No value is returned.
Function description:
**Function description**:
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.
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.
> All forced conversion operations for obtaining the corresponding object can be successful only when **Init()** has the corresponding value assignment operations.
```
```
...
@@ -369,7 +385,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
...
@@ -369,7 +385,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
{
{
struct UartHost *host = NULL;
struct UartHost *host = NULL;
...
...
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.