未验证 提交 7ea6dd84 编写于 作者: O openharmony_ci 提交者: Gitee

!9169 【翻译完成】#I5LO8W

Merge pull request !9169 from Annie_wang/PR7966A
......@@ -22,10 +22,10 @@ struct MipiDsiCntlrMethod { // Member functions of the core layer structure
int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
void (*toHs)(struct MipiDsiCntlr *cntlr);
void (*toLp)(struct MipiDsiCntlr *cntlr);
void (*enterUlps)(struct MipiDsiCntlr *cntlr);// (Optional) Enter the Ultra-Low Power State (ULPS).
void (*enterUlps)(struct MipiDsiCntlr *cntlr); // (Optional) Enter the Ultra-Low Power State (ULPS).
void (*exitUlps)(struct MipiDsiCntlr *cntlr); // (Optional) Exit the ULPS.
int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);// (Optional) Enable or disable power control.
int32_t (*attach)(struct MipiDsiCntlr *cntlr);// (Optional) Attach a DSI device to the host.
int32_t (*attach)(struct MipiDsiCntlr *cntlr); // (Optional) Attach a DSI device to the host.
};
```
......@@ -34,7 +34,7 @@ struct MipiDsiCntlrMethod { // Member functions of the core layer structure
| Function| Input Parameter| Output Parameter| Return Value| Description|
| -------- | -------- | -------- | -------- | -------- |
| setCntlrCfg | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets controller parameters.|
| setCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>cmd: structure pointer to the commands to send.| –| HDF_STATUS| Sends commands to a display device.|
| setCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>**cmd**: structure pointer to the commands to send. | –| HDF_STATUS| Sends commands to a display device.|
| getCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>**cmd**: pointer to the command description structure.<br>**readLen**: length of the data to read.| **out**: structure pointer to the data obtained.| HDF_STATUS| Reads data by sending commands.|
| toHs | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the high speed (HS) mode.|
| toLp | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the low power (LP) mode.|
......@@ -44,14 +44,14 @@ struct MipiDsiCntlrMethod { // Member functions of the core layer structure
The MIPI DSI module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
1. Configure attribute files.
- Add the **deviceNode** description to the **device_info.hcs** file.
- (Optional) Add the **mipidsi_config.hcs** file.
2. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
3. Instantiate the MIPI DSI controller object.
- Initialize **MipiDsiCntlr**.
- Instantiate **MipiDsiCntlrMethod** in the **MipiDsiCntlr** object.
......@@ -59,6 +59,7 @@ The MIPI DSI module adaptation involves the following steps:
> For details about the functions in **MipiDsiCntlrMethod**, see [Available APIs](#available-apis).
4. Debug the driver.
(Optional) For new drivers, verify basic functions, for example, check the information returned after the driver is attached and whether data is successfully transmitted.
......@@ -66,7 +67,9 @@ The MIPI DSI module adaptation involves the following steps:
The following uses **mipi_tx_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions.
1. Configure the device attributes in **xx_config.hcs** and add the **deviceNode** information to the **device_info.hcs** file. <br>The device attribute values are closely related to the default values or value range of the **MipiDsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration.
1. Configure the device attributes in **xx_config.hcs** and add the **deviceNode** information to the **device_info.hcs** file.
The device attribute values are closely related to the default values or value range of the **MipiDsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration.
In this example, no additional attribute needs to be configured for the MIPI DSI controller. If required, add the **deviceMatchAttr** information to **deviceNode** in the **device_info** file and add the **mipidsi_config** file.
......@@ -93,10 +96,13 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
}
```
2. 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**. The function pointer members in the **HdfDriverEntry** structure are filled by the vendors' operation functions. 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.
2. 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**. The function pointer members in the **HdfDriverEntry** structure are filled by the vendors' operation functions. 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.
- MIPI DSI driver entry example
MIPI DSI driver entry example:
```
struct HdfDriverEntry g_mipiTxDriverEntry = {
......@@ -109,11 +115,11 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
```
3. Initialize the **MipiDsiCntlr** 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 **MipiDsiCntlrMethod** in **MipiDsiCntlr** (so that the underlying driver functions can be called).
- Defining a custom structure
To the driver, the custom structure holds parameters and data. Generally, the values in the **config** file are used to initialize the structure members. However, in this example, the MIPI DSI has no device attribute file. Therefore, the basic member structure is similar to that of **MipiDsiCntlr**.
```
typedef struct {
unsigned int devno; // Device number
......@@ -137,8 +143,8 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
void *priv;
};
```
- Instantiating **MipiDsiCntlrMethod** in **MipiDsiCntlr** (other members are initialized by **Init**)
- Instantiating **MipiDsiCntlrMethod** in **MipiDsiCntlr** (other members are initialized by **Init**)
```
static struct MipiDsiCntlrMethod g_method = {
......@@ -149,6 +155,7 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
.toLp = Hi35xxToLp,
};
```
- **Init** function
**Input parameter**:
......@@ -157,23 +164,23 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
**Return value**:
HDF_STATUS<br>The table below lists some status. For more information, see HDF_STATUS in the /drivers/framework/include/utils/hdf_base.h file.
**HDF_STATUS**
The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
| Status| Description|
| -------- | -------- |
| HDF_ERR_INVALID_OBJECT | Invalid object.|
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory.|
| HDF_ERR_INVALID_PARAM | Invalid parameter.|
| HDF_ERR_IO | I/O error.|
| HDF_SUCCESS | Operation successful.|
| HDF_FAILURE | Operation failed.|
| Status | Description |
| ---------------------- | -------------------------- |
| HDF_ERR_INVALID_OBJECT | Invalid object. |
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory. |
| HDF_ERR_INVALID_PARAM | Invalid parameter. |
| HDF_ERR_IO | I/O error. |
| HDF_SUCCESS | Operation successful. |
| HDF_FAILURE | Operation failed. |
**Function description**:
Attaches the **MipiDsiCntlrMethod** instance, calls **MipiDsiRegisterCntlr**, and performs other vendor-defined initialization operations.
```
static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
{
......@@ -182,7 +189,7 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
// static struct MipiDsiCntlr g_mipiTx {
// .devNo=0
//};
g_mipiTx.ops = &g_method;// Attach the MipiDsiCntlrMethod instance.
g_mipiTx.ops = &g_method; // Attach the MipiDsiCntlrMethod instance.
ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer.
...
return MipiTxDrvInit(0); // (Mandatory) Device initialization customized by the vendor.
......@@ -209,6 +216,7 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
return HDF_FAILURE;
}
```
- **Release** function
**Input parameter**:
......@@ -221,8 +229,11 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
**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. 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.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
```
static void Hi35xxMipiTxRelease(struct HdfDeviceObject *device)
......@@ -238,3 +249,5 @@ The following uses **mipi_tx_hi35xx.c** as an example to present the contents th
HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
}
```
......@@ -75,6 +75,7 @@ The MMC module adaptation involves the following steps:
> For details about the functions in **MmcCntlrOps**, see [Available APIs](#available-apis).
4. Debug the driver.
(Optional) For new drivers, verify the basic functions, for example, check the information returned after the **MmcCntlrOps** instance is attached and whether the device starts successfully.
......@@ -82,7 +83,9 @@ The MMC module adaptation involves the following steps:
The following uses **himci.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.
......@@ -101,7 +104,9 @@ The following uses **himci.c** as an example to present the information required
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **mmc_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 **MmcCntlr** members at the core layer. If there are multiple devices, you need to add the **deviceNode** information to the **device_info** file and add the device attributes to the **mmc_config** file for each device.
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 **MmcCntlr** members at the core layer.
If there are multiple devices, you need to add the **deviceNode** information to the **device_info** file and add the device attributes to the **mmc_config** file for each device.
- **device_info.hcs** configuration example
......@@ -165,7 +170,7 @@ The following uses **himci.c** as an example to present the information required
hostId = 0; // (Mandatory) Host ID
regBasePhy = 0x10020000;// (Mandatory) Physical base address of the register
irqNum = 63; // (Mandatory) Interrupt number
devType = 2; // (Mandatory) Device type, which can be eMMC, SD, SDIO, or COMBO
devType = 2; // (Mandatory) Device type, which can be eMMC, SD, SDIO, or COMBO.
caps = 0x0001e045; // (Mandatory) Attribute register. For details, see MmcCaps in mmc_caps.h.
}
controller_0x10100000 :: mmc_controller {
......@@ -199,6 +204,7 @@ The following uses **himci.c** as an example to present the information required
```
3. Initialize the **MmcCntlr** 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 **MmcCntlrOps** in **MmcCntlr** (so that the underlying driver functions can be called).
- 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 **mmc_config.hcs** file to initialize the members in the custom structure and passes important parameters to the **MmcCntlr** object at the core layer.
......@@ -225,7 +231,7 @@ The following uses **himci.c** as an example to present the information required
bool waitForEvent;
HIMCI_EVENT himciEvent;
};
// MmcCntlr is the core layer controller structure. The bind function assigns values to the members of MmcCntlr.
// MmcCntlr is the core layer controller structure. The Bind function assigns values to the members of MmcCntlr.
struct MmcCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *hdfDevObj;
......@@ -284,7 +290,7 @@ The following uses **himci.c** as an example to present the information required
**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.
| Status| Description|
| -------- | -------- |
......@@ -318,7 +324,7 @@ The following uses **himci.c** as an example to present the information required
...
ret = HimciHostParse(host, obj); // (Mandatory) Initialize HimciHost. If the initialization fails, execute goto _ERR.
...
ret = HimciHostInit(host, cntlr);// Customized initialization. If the initialization fails, execute goto _ERR.
ret = HimciHostInit(host, cntlr); // Customized initialization. If the initialization fails, execute goto _ERR.
...
ret = MmcCntlrAdd(cntlr); // Call the functions at the core layer. If the operation fails, execute goto _ERR.
...
......@@ -374,16 +380,19 @@ The following uses **himci.c** as an example to present the information required
**Function description**:
Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If 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 value assignment operations.
Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
> All forced conversion operations for obtaining the corresponding object can be successful only when **Init()** has the corresponding value assignment operations.
```
static void HimciMmcRelease(struct HdfDeviceObject *obj)
{
struct MmcCntlr *cntlr = NULL;
...
cntlr = (struct MmcCntlr *)obj->service;// Forcibly convert HdfDeviceObject to MmcCntlr by using service. For details about the value assignment, see the Bind function.
cntlr = (struct MmcCntlr *)obj->service; // Forcibly convert HdfDeviceObject to MmcCntlr by using service. For details about the value assignment, see the Bind function.
...
HimciDeleteHost((struct HimciHost *)cntlr->priv);// Customized memory release function. A forced conversion from MmcCntlr to HimciHost is involved in the process.
}
```
......@@ -20,10 +20,9 @@ Pin, as a software concept, provides APIs for uniformly managing the pins from d
### Working Principles
In the HDF, the pin module does not support the user mode and therefore does not need to publish services. It uses the service-free mode in interface adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the OS that does not distinguish the user mode and the kernel mode. The **DevHandle**, a void pointer, directly points to the kernel mode address of the device object.
In the HDF, the pin module does not support the user mode and therefore does not need to publish services. The pin module uses the service-free mode (as shown in Figure 1) in interface adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the OS that does not distinguish the user mode and the kernel mode. The **DevHandle**, a void pointer, directly points to the kernel mode address of the device object.
The pin module is divided into the following layers:
- Interface layer: provides APIs for obtaining a pin, setting or obtaining the pull type, pull strength, and functions of a pin, and releasing a pin.
- Core layer: provides the capabilities of matching pin resources and adding, removing, and managing pin controllers. The core layer interacts with the adaptation layer by using hooks.
- Adaptation layer: instantiates hooks to implement specific functions.
......@@ -44,8 +43,7 @@ The pin module is used to manage pin resources. When the devices from SoC vendor
### Available APIs
The **PinCntlrMethod** APIs are used to call the functions of the pin driver.
**PinCntlrMethod** definition:
The **PinCntlrMethod** structure defines callbacks to be invoked to call the functions of the pin driver.
```c
struct PinCntlrMethod {
......@@ -58,7 +56,7 @@ struct PinCntlrMethod {
};
```
**Table 1** APIs for the members in the PinCntlrMethod structure
**Table 1** Callbacks in the PinCntlrMethod structure
| API | Input Parameter | Output Parameter | Return Value| Description|
| ------------ | ------------------------------------------- | ------ | ---- | ---- |
......@@ -73,18 +71,22 @@ struct PinCntlrMethod {
The pin module adaptation procedure is as follows:
- Instantiate the driver entry.
- Configure attribute files.
- Instantiate the core layer APIs.
- Debug the driver.
1. Instantiate the driver entry.
2. Configure attribute files.
3. Instantiate the core layer APIs.
4. Debug the driver.
### Development Example
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
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**.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
Generally, the HDF calls the **Init()** function to load the driver. If **Init()** fails to be called, the HDF calls **Release()** to release driver resources and exit.
Generally, the HDF calls the **Init** function to load the driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
```c
static struct HdfDriverEntry g_hi35xxPinDriverEntry = {
......@@ -92,13 +94,15 @@ The pin module adaptation procedure is as follows:
.Bind = Hi35xxPinBind,
.Init = Hi35xxPinInit,
.Release = Hi35xxPinRelease,
.moduleName = "hi35xx_pin_driver",// (Mandatory) The value must be the same as that of moduleName in the .hcs file.
.moduleName = "hi35xx_pin_driver", // (Mandatory) The value must be the same as that of moduleName in the .hcs file.
};
HDF_INIT(g_hi35xxPinDriverEntry);// Call HDF_INIT to register the driver entry with the HDF.
HDF_INIT(g_hi35xxPinDriverEntry); // Call HDF_INIT to register the driver entry with the HDF.
```
2. Configure attribute files.
- Add the device node description to the **vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs** file.
```c
root {
device_info {
......@@ -107,7 +111,7 @@ The pin module adaptation procedure is as follows:
priority = 50;
device_pin :: device {
device0:: deviceNode { // Set an HDF device node for each pin controller.
policy = 0; // 2: visible in user mode; 1: visible in kernel mode; 0: no service required.
policy = 0; // Policy for publishing services.
priority = 10; // Driver startup priority.
permission = 0644; // Permission to create device nodes for the driver.
/* (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. */
......@@ -122,13 +126,14 @@ The pin module adaptation procedure is as follows:
moduleName = "hi35xx_pin_driver";
deviceMatchAttr = "hisilicon_hi35xx_pin_1";
}
......
...
}
}
}
}
```
- Add the **pin_config.hcs** file.
Configure the device attributes in the **device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs** file. The parameters are set as follows:
```c
root {
......@@ -164,16 +169,18 @@ The pin module adaptation procedure is as follows:
F1 = "SFC_CLK";
F2 = "SFC_BOOT_MODE";
}
...... // Correspond to the pins of the pin controller. Add pins according to actual situation.
... // Correspond to the pins of the pin controller. Add pins according to actual situation.
}
...// Each pin controller corresponds to a controller node. If there are multiple pin controllers, add the corresponding controller nodes one by one.
... // Each pin controller corresponds to a controller node. If there are multiple pin controllers, add the corresponding controller nodes one by one.
}
}
}
```
3. Instantiate the pin controller object.
- Initialize the **PinCntlr** object.
Call **Hi35xxPinCntlrInit** to initialize the **PinCntlr** members.
```c
......@@ -209,7 +216,7 @@ The pin module adaptation procedure is as follows:
uint32_t pinCount;
};
// PinCntlr is the controller structure at the core layer. Its members are assigned with values by using the Init() function.
// PinCntlr is the controller structure at the core layer. The Init function assigns values to PinCntlr.
struct PinCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *device;
......@@ -268,29 +275,31 @@ The pin module adaptation procedure is as follows:
}
```
- Instantiate the callback structure **PinCntlrMethod** in **PinCntlr**. Other members are initialized by using the **Init()** function.
- Instantiate the callback structure **PinCntlrMethod** in **PinCntlr**. Other members are initialized by using the **Init** function.
```c
// The members of the PinCntlrMethod structure are all callbacks. Vendors need to implement the corresponding functions according to Table 1.
static struct PinCntlrMethod g_method = {
.SetPinPull = Hi35xxPinSetPull, // Set the pull type.
.GetPinPull = Hi35xxPinGetPull, // Obtains the pull type.
.GetPinPull = Hi35xxPinGetPull, // Obtain the pull type.
.SetPinStrength = Hi35xxPinSetStrength, // Set the pull strength.
.GetPinStrength = Hi35xxPinGetStrength, // Obtains the pull strength.
.GetPinStrength = Hi35xxPinGetStrength, // Obtain the pull strength.
.SetPinFunc = Hi35xxPinSetFunc, // Set the pin functions.
.GetPinFunc = Hi35xxPinGetFunc, // Obtain the pin functions.
};
```
- **Init()** function
- **Init** function
**Input parameter**:
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**HDF\_STATUS** (The following table lists some states. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.)
**Return value**:
**HDF\_STATUS** <br>The table below describes some status. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.
| **State** | **Description** |
| **Status** | **Description** |
| ---------------------- | -------------- |
| HDF_ERR_INVALID_OBJECT | Invalid controller object.|
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory. |
......@@ -299,8 +308,9 @@ The pin module adaptation procedure is as follows:
| HDF_SUCCESS | Initialization successful. |
| HDF_FAILURE | Initialization failed. |
Function description:
Initializes the custom structure object and **PinCntlr** members, and connects to the pin controller by calling the **PinCntlrAdd()** function.
**Function description**:
Initializes the custom structure object and **PinCntlr** members, and connects to the pin controller by calling the **PinCntlrAdd** function.
```c
static int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc, const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps)
......@@ -322,7 +332,7 @@ The pin module adaptation procedure is as follows:
}
funcNum++;
......
...
return HDF_SUCCESS;
}
......@@ -341,7 +351,7 @@ The pin module adaptation procedure is as follows:
HDF_LOGE("%s: read pinName failed", __func__);
return ret;
}
......
...
ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:Pin read Func failed", __func__);
......@@ -349,20 +359,20 @@ The pin module adaptation procedure is as follows:
}
hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName;
hi35xx->cntlr.pins[index].priv = (void *)node;
......
...
return HDF_SUCCESS;
}
static int32_t Hi35xxPinInit(struct HdfDeviceObject *device)
{
......
...
struct Hi35xxPinCntlr *hi35xx = NULL;
......
...
ret = Hi35xxPinCntlrInit(device, hi35xx); // Initialize the pin controller.
......
...
DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { // Traverses each child node of the pin controller.
ret = Hi35xxPinParsePinNode(childNode, hi35xx, index); // Parsing the child nodes.
......
ret = Hi35xxPinParsePinNode(childNode, hi35xx, index); // Parse child nodes.
...
}
hi35xx->cntlr.method = &g_method; // Instantiate method.
......@@ -375,19 +385,19 @@ The pin module adaptation procedure is as follows:
}
```
- **Release()** function
- **Release** function
Input parameters:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
No value is returned.
Function description:
**Function description**:
Releases memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. If 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** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, **Release** can be called to release driver resources.
```c
static void Hi35xxPinRelease(struct HdfDeviceObject *device)
......@@ -426,4 +436,5 @@ The pin module adaptation procedure is as follows:
}
```
4. Debug the driver.
(Optional) Verify basic functionalities of new drivers. For example, verify the information returned when the driver is loaded and whether data is successfully transmitted.
......@@ -27,7 +27,7 @@ struct PwmMethod {
| Function| Input Parameter| Return Value| Description|
| -------- | -------- | -------- | -------- |
| setConfig | -**pwm**: structure pointer to the PWM controller at the core layer.<br>-**config**: structure pointer to the attributes to set.| HDF_STATUS| Sets attributes.|
| setConfig | **pwm**: structure pointer to the PWM controller at the core layer.<br>**config**: structure pointer to the attributes to set.| HDF_STATUS| Sets attributes.|
| open | **pwm**: structure pointer to the PWM controller at the core layer.| HDF_STATUS| Opens a device.|
| close | **pwm**: structure pointer to the PWM controller at the core layer.| HDF_STATUS| Closes a device.|
......@@ -51,6 +51,7 @@ The PWM module adaptation involves the following steps:
> For details about the functions in **PwmMethod**, see [Available APIs](#available-apis).
4. Debug the driver.
(Optional) For new drivers, verify the basic functions, such as the PWM status control and response to interrupts.
......@@ -58,7 +59,11 @@ The PWM module adaptation involves the following steps:
The following uses **pwm_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.
......@@ -76,7 +81,10 @@ The following uses **pwm_hi35xx.c** as an example to present the information req
HDF_INIT(g_hdfPwm);
```
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **pwm_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 **PwmDev** members at the core layer. If there are multiple devices, you need to add the **deviceNode** information to the **device_info** file and add the device attributes to the **pwm_config** file for each device.
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **pwm_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 **PwmDev** members at the core layer. If there are multiple devices, you need to add the **deviceNode** information to the **device_info** file and add the device attributes to the **pwm_config** file for each device.
- **device_info.hcs** configuration example
......@@ -86,11 +94,11 @@ The following uses **pwm_hi35xx.c** as an example to present the information req
platform :: host {
hostName = "platform_host";
priority = 50;
device_pwm :: device {// Configure an HDF device node for each PWM controller.
device_pwm :: device { // Configure an HDF device node for each PWM controller.
device0 :: deviceNode {
policy = 1; // Publish kernel-mode services.
priority = 80; // Driver startup priority
permission = 0644; // Permission to create device nodes for the driver.
policy = 1; // Publish services for kernel-mode processes.
priority = 80; // Driver startup priority.
permission = 0644; // Permission for the driver to create a device node.
moduleName = "HDF_PLATFORM_PWM"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
serviceName = "HDF_PLATFORM_PWM_0"; // (Mandatory) Unique name of the service published by the driver.
deviceMatchAttr = "hisilicon_hi35xx_pwm_0";// (Mandatory) Used to configure the private data of the controller.
......@@ -135,10 +143,11 @@ The following uses **pwm_hi35xx.c** as an example to present the information req
}
```
3. Initialize the **PwmDev** 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 **PwmMethod** in **PwmDev** (so that the underlying driver functions can be called).
3. Initialize the **wmDev** 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 **PwmMethod** in **PwmDev** (so that the underlying driver functions can be called).
- 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 **pwm_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number, to the **GpioCntlr** 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 **pwm_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number, to the object at the core layer.
```
......@@ -193,7 +202,7 @@ The following uses **pwm_hi35xx.c** as an example to present the information req
**Return value**:
HDF_STATUS<br>The table below lists 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.
| Status| Description|
| -------- | -------- |
......@@ -210,7 +219,7 @@ The following uses **pwm_hi35xx.c** as an example to present the information req
```
// The bind function is empty. It can be combined with the init function or implement related operations based on the vendor's requirements.
// The Bind function is empty. It can be combined with the Init function or implement related operations based on service requirements.
static int32_t HdfPwmBind(struct HdfDeviceObject *obj)
{
(void)obj;
......@@ -246,7 +255,7 @@ The following uses **pwm_hi35xx.c** as an example to present the information req
hp->dev.cfg.status = PWM_DISABLE_STATUS; // Initialize PwmDev.
hp->dev.cfg.number = 0; // Initialize PwmDev.
hp->dev.busy = false; // Initialize PwmDev.
if (PwmDeviceAdd(obj, &(hp->dev)) ) != HDF_SUCCESS) {// (Important) Call the core layer function to initialize hp->dev devices and services.
if (PwmDeviceAdd(obj, &(hp->dev)) ) != HDF_SUCCESS) { // Call the core layer function to initialize devices and services.
OsalIoUnmap((void *)hp->base);
return HDF_FAILURE;
}
......
......@@ -16,7 +16,7 @@ The regulator module is divided into the following layers:
- Core layer: provides the capabilities of binding, initializing, and releasing devices.
- Adaptation layer: implements other functions.
![](../public_sys-resources/icon-note.gif)NOTE<br/>The core layer can call the APIs of the interface layer and uses hooks to call APIs of the adaptation layer. In this way, the adaptation layer can indirectly call the APIs of the interface layer, but the interface layer cannot call the APIs of the adaptation layer.
![](../public_sys-resources/icon-note.gif) **NOTE**<br/>The core layer can call the APIs of the interface layer and uses hooks to call APIs of the adaptation layer. In this way, the adaptation layer can indirectly call the APIs of the interface layer, but the interface layer cannot call the APIs of the adaptation layer.
**Figure 1** Unified service mode
......@@ -28,12 +28,13 @@ The regulator module is divided into the following layers:
Currently, the regulator module supports only the kernels (LiteOS) of mini and small systems.
## Development Guidelines
### When to Use
The regulator module controls the voltage and current supplies of some devices in the system.
## Available APIs
### Available APIs
The functions in **RegulatorMethod** are used to call the corresponding regulator driver functions:
......@@ -72,8 +73,7 @@ struct RegulatorMethod {
| getCurrent | **node**: structure pointer to the regulator node at the core layer.<br>**regCurrent**: pointer to the output current, which is of the uint32_t type.| HDF_STATUS| Obtains the current. |
| getStatus | **node**: structure pointer to the regulator node at the core layer.<br>**status**: pointer to the output status, which is of the uint32_t type.| HDF_STATUS| Obtains the device status. |
## How to Develop
### How to Develop
The regulator module adaptation procedure is as follows:
......@@ -86,9 +86,11 @@ The regulator module adaptation procedure is as follows:
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.
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 **Init()** function to load the driver. If **Init()** fails to be called, the HDF calls **Release** to release driver resources and exit.
Generally, the HDF calls the **Init** function to load the driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
```
struct HdfDriverEntry g_regulatorDriverEntry = {
......@@ -116,7 +118,7 @@ The regulator module adaptation procedure is as follows:
| permission | Driver permission. |
| moduleName | **HDF_PLATFORM_REGULATOR_MANAGER** |
| serviceName | **HDF_PLATFORM_REGULATOR_MANAGER** |
| deviceMatchAttr | This parameter is reserved. |
| deviceMatchAttr | Reserved. |
Configure regulator controller information from the second node. This node specifies a type of regulator controllers rather than a specific regulator controller. In this example, there is only one regulator device. If there are multiple regulator devices, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **regulator\_config** file.
......@@ -198,7 +200,7 @@ The regulator module adaptation procedure is as follows:
}
```
3. Instantiate the APIs of the core layer.
3. Instantiate the core layer APIs.
Initialize the **RegulatorNode** 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 **RegulatorMethod** in **RegulatorNode** (so that the underlying driver functions can be called).
......@@ -206,8 +208,6 @@ The regulator module adaptation procedure is as follows:
The **RegulatorNode** structure holds parameters and data for the driver. The HDF obtains the values in **regulator_config.hcs** using **DeviceResourceIface**.
```
// RegulatorNode is the core layer controller structure. The Init function assigns values to the members of RegulatorNode.
struct RegulatorNode {
......@@ -228,7 +228,7 @@ The regulator module adaptation procedure is as follows:
uint32_t maxUa; /* Maximum output current. */
uint32_t status; /* Regulator status, which can be on or off. */
int useCount;
int consumerRegNums; /* Number of regulator consumers. */
int consumerRegNums; /* Number of the regulator consumers. */
RegulatorStatusChangecb cb; /* Variable used to notify the regulator status changes. */
};
......@@ -263,19 +263,19 @@ The regulator module adaptation procedure is as follows:
- **Init** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
**HDF\_STATUS**
The table below lists some states. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.
The table below describes some status. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.
**Table 2** HDF_STATUS
**Table 2** Description of HDF_STATUS
| State | Description |
| Status | Description |
| ---------------------- | -------------- |
| HDF_ERR_INVALID_OBJECT | Invalid controller object.|
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory. |
......@@ -284,7 +284,7 @@ The regulator module adaptation procedure is as follows:
| HDF_SUCCESS | Initialization successful. |
| HDF_FAILURE | Initialization failed. |
Function description:
**Function description**:
Initializes the custom structure and **RegulatorNode** members, and adds the regulator controller by calling the **RegulatorNodeAdd** function at the core layer.
......@@ -310,9 +310,9 @@ The regulator module adaptation procedure is as follows:
regNode = (struct RegulatorNode *)OsalMemCalloc(sizeof(*regNode));// Load the .hcs file.
...
ret = VirtualRegulatorReadHcs(regNode, node);// Read .hcs information.
ret = VirtualRegulatorReadHcs(regNode, node); // Read .hcs information.
...
regNode->priv = (void *)node; // Instantiate the node.
regNode->priv = (void *)node; ; // Instantiate the node.
regNode->ops = &g_method; // Instantiate OPS.
ret = RegulatorNodeAdd(regNode); // Add the node.
......@@ -322,15 +322,15 @@ The regulator module adaptation procedure is as follows:
- **Release** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
No value is return.
No value is returned.
Function description:
**Function description**:
Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
......
......@@ -67,6 +67,7 @@ The RTC module adaptation involves the following steps:
> For details about the functions in **RtcMethod**, see [Available APIs](#available-apis).
4. Debug the driver.
(Optional) For new drivers, verify the basic functions, such as the RTC status control and response to interrupts.
......@@ -74,7 +75,12 @@ The RTC module adaptation involves the following steps:
The following uses **rtc_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 framework, 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.
RTC driver entry example:
......@@ -94,6 +100,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information req
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **rtc_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 **RtcHost** members at the core layer.
In this example, there is only one RTC controller. If there are multiple RTC controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **rtc_config** file for each controller.
- **device_info.hcs** configuration example
......@@ -143,12 +150,12 @@ The following uses **rtc_hi35xx.c** as an example to present the information req
}
```
3. Initialize the **RtcHost** 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 **RtcMethod** in **RtcHost** (so that the underlying driver functions can be called).
3. Initialize the **RtcHost** 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 **RtcMethod** in **RtcHost** (so that the underlying driver functions can be called).
- 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 **rtc_config.hcs** file to initialize the members in the custom structure.
```
struct RtcConfigInfo {
uint32_t spiBaseAddr; // Used for address mapping.
......@@ -172,8 +179,8 @@ The following uses **rtc_hi35xx.c** as an example to present the information req
void *data;
};
```
- Instantiating **RtcMethod** in **RtcHost** (other members are initialized by **Init**)
- Instantiating **RtcMethod** in **RtcHost** (other members are initialized by **Init**)
```
// Example in rtc_hi35xx.c: instantiate the hook.
......@@ -194,58 +201,58 @@ The following uses **rtc_hi35xx.c** as an example to present the information req
- **Bind** function
Input parameter:
**Input parameter**:
**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**
**Table 2** HDF_STATUS
The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
| Status| Description|
| -------- | -------- |
| HDF_ERR_INVALID_OBJECT | Invalid controller object.|
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory.|
| HDF_ERR_INVALID_PARAM | Invalid parameter.|
| HDF_ERR_IO | I/O error.|
| HDF_SUCCESS | Initialization successful.|
| HDF_FAILURE | Initialization failed.|
**Table 2** Description of HDF_STATUS
Function description:
| Status | Description |
| ---------------------- | -------------------------- |
| HDF_ERR_INVALID_OBJECT | Invalid controller object. |
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory. |
| HDF_ERR_INVALID_PARAM | Invalid parameter. |
| HDF_ERR_IO | I/O error. |
| HDF_SUCCESS | Initialization successful. |
| HDF_FAILURE | Initialization failed. |
Binds the **HdfDeviceObject** object and **RtcHost**.
**Function description**:
Binds the **HdfDeviceObject** object and **RtcHost**.
```
static int32_t HiRtcBind(struct HdfDeviceObject *device)
{
struct RtcHost *host = NULL;
host = RtcHostCreate(device); // Allocate memory and attach the device host and the device.
host = RtcHostCreate(device); // Allocate memory and attach the device host with the device.
// Prerequisite for conversion between HdfDeviceObject and RtcHost.
...
device->service = &host->service; // Prerequisite for conversion between HdfDeviceObject and RtcHost.
// It helps implement the global host by calling RtcHostFromDevice.
// It helps implement a global host by calling RtcHostFromDevice.
return HDF_SUCCESS;
}
```
- **Init** function
Input parameter:
**Input parameter**:
**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 **RtcHost**.
```
static int32_t HiRtcInit(struct HdfDeviceObject *device)
{
......@@ -255,7 +262,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information req
host = RtcHostFromDevice(device);// Forcibly convert HdfDeviceObject to RtcHost.
rtcInfo = OsalMemCalloc(sizeof(*rtcInfo));
...
// HiRtcConfigData reads attributes from the device configuration tree and fills the values in supportAnaCtrl, supportLock, spiBaseAddr, regAddrLength, and irq in rtcInfo.
// HiRtcConfigData reads attributes from the device configuration tree and fills in supportAnaCtrl, supportLock, spiBaseAddr, regAddrLength and irq of RTCInfo.
// Provide parameters for HiRtcSwInit and HiRtcSwInit. When HiRtcSwInit and HiRtcSwInit fail to be executed internally, Release() can be called to release memory.
if (HiRtcConfigData(rtcInfo, device->property) != 0) {
...
......@@ -273,19 +280,24 @@ The following uses **rtc_hi35xx.c** as an example to present the information req
return HDF_SUCCESS;
}
```
- **Release** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
No value is returned.
Function description:
**Function description**:
Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If 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** function in the driver entry structure. If 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** or **Bind** function has the corresponding value assignment operations.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
> All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** or **Bind** function has the corresponding value assignment operations.
```
......
......@@ -53,7 +53,8 @@ The SPI module adaptation involves the following steps:
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
> For details about the functions in **SpiCntlrMethod**, 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 SPI status control and response to interrupts.
......@@ -61,7 +62,12 @@ The SPI module adaptation involves the following steps:
The following uses **spi_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 framework, 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.
SPI driver entry example:
......@@ -124,14 +130,14 @@ The following uses **spi_hi35xx.c** as an example to present the information req
```
root {
platform {
spi_config {// Configure private data for each SPI controller.
spi_config { // Configure private data for each SPI controller.
template spi_controller { // Template configuration. In the template, you can configure the common parameters shared by device nodes.
serviceName = "";
match_attr = "";
transferMode = 0; // Data transfer mode. The value **0** indicates interrupt transfer, **1** indicates flow control transfer, and **2** indicates DMA transfer.
busNum = 0; // Bus number.
clkRate = 100000000;
bitsPerWord = 8 // Number of bits per word.
bitsPerWord = 8; // Number of bits per word.
mode = 19; // SPI data input/output mode.
maxSpeedHz = 0; // Maximum clock frequency.
minSpeedHz = 0; // Minimum clock frequency.
......@@ -168,7 +174,8 @@ The following uses **spi_hi35xx.c** as an example to present the information req
}
```
3. Initialize the **SpiCntlr** 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 **SpiCntlrMethod** in **SpiCntlr** (so that the underlying driver functions can be called).
3. Initialize the **SpiCntlr** 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 **SpiCntlrMethod** in **SpiCntlr** (so that the underlying driver functions can be called).
- 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 **spi_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number and bus number, to the **SpiCntlr** object at the core layer.
......@@ -231,15 +238,15 @@ The following uses **spi_hi35xx.c** as an example to present the information req
- **Bind** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
HDF_STATUS
**HDF_STATUS**
Function description:
**Function description**:
Associates the **SpiCntlr** object with **HdfDeviceObject**.
......@@ -253,14 +260,14 @@ The following uses **spi_hi35xx.c** as an example to present the information req
struct SpiCntlr *SpiCntlrCreate(struct HdfDeviceObject *device)
{
struct SpiCntlr *cntlr = NULL; // Create the SpiCntlr object at the core layer.
struct SpiCntlr *cntlr = NULL; // Create an SpiCntlr object.
...
cntlr = (struct SpiCntlr *)OsalMemCalloc(sizeof(*cntlr));// Allocate memory.
...
cntlr->device = device; // Prerequisites for conversion between HdfDeviceObject and SpiCntlr.
device->service = &(cntlr->service); // Prerequisites for conversion between HdfDeviceObject and SpiCntlr.
(void)OsalMutexInit(&cntlr->lock); // Initialize the lock.
DListHeadInit(&cntlr->list); // Add the corresponding nodes.
DListHeadInit(&cntlr->list); // Add nodes.
cntlr->priv = NULL;
return cntlr;
}
......@@ -268,17 +275,15 @@ The following uses **spi_hi35xx.c** as an example to present the information req
- **Init** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
HDF_STATUS
**Return value**:
The table below lists 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|
| -------- | -------- |
......@@ -289,7 +294,7 @@ The following uses **spi_hi35xx.c** as an example to present the information req
| HDF_SUCCESS | Initialization successful.|
| HDF_FAILURE | Initialization failed.|
Function description:
**Function description**:
Initializes the custom structure object and **SpiCntlr**.
......@@ -300,10 +305,10 @@ The following uses **spi_hi35xx.c** as an example to present the information req
int32_t ret;
struct SpiCntlr *cntlr = NULL;
...
cntlr = SpiCntlrFromDevice(device); // Use service to forcibly convert HdfDeviceObject to SpiCntlr. For details about the value assignment, see the Bind function.
cntlr = SpiCntlrFromDevice(device); // Forcibly convert HdfDeviceObject to SpiCntlr using service. For details about the value assignment, see the Bind function.
// return (device == NULL) ? NULL : (struct SpiCntlr *)device->service;
...
ret = Pl022Init(cntlr, device); // (Mandatory) Instantiate the operation object customized by the vendor. The following is an example:
ret = Pl022Init(cntlr, device); // (Mandatory) Instantiate the custom operation object. The following is an example:
...
ret = Pl022Probe(cntlr->priv);
...
......@@ -319,7 +324,7 @@ The following uses **spi_hi35xx.c** as an example to present the information req
...
ret = SpiGetBaseCfgFromHcs(pl022, device->property); // Initialize busNum, numCs, speed, fifoSize, clkRate, mode, bitsPerWord, and transferMode.
...
ret = SpiGetRegCfgFromHcs(pl022, device->property); // Initialize regBase, phyBase, irqNum, regCrg, clkEnBit, clkRstBit, regMiscCtrl, miscCtrlCs, and miscCtrlCsShift.
ret = SpiGetRegCfgFromHcs(pl022, device->property); // Initialize regBase, phyBase, irqNum, regCrg, clkEnBit, clkRstBit, regMiscCtrl, regMiscCtrl, miscCtrlCs, and miscCtrlCsShift.
...
// Calculate the frequencies corresponding to the maximum and minimum speeds.
pl022->maxSpeedHz = (pl022->clkRate) / ((SCR_MIN + 1) * CPSDVSR_MIN);
......@@ -338,20 +343,22 @@ The following uses **spi_hi35xx.c** as an example to present the information req
return 0;
}
```
- **Release** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
No value is returned.
Function description:
**Function description**:
Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If 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 value assignment operations.
Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
> All forced conversion operations for obtaining the corresponding object can be successful only when **Init()** has the corresponding value assignment operations.
```
......@@ -359,7 +366,7 @@ The following uses **spi_hi35xx.c** as an example to present the information req
{
struct SpiCntlr *cntlr = NULL;
...
cntlr = SpiCntlrFromDevice(device); // Use service to forcibly convert HdfDeviceObject to SpiCntlr. For details about the value assignment, see the Bind function.
cntlr = SpiCntlrFromDevice(device); // Forced conversion from HdfDeviceObject to SpiCntlr is involved. For details about the value assignment, see the Bind function.
// return (device==NULL) ?NULL:(struct SpiCntlr *)device->service;
...
if (cntlr->priv != NULL) {
......
......@@ -36,12 +36,12 @@ struct UartHostMethod {
| -------- | -------- | -------- | -------- | -------- |
| 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.|
| 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.|
| 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.|
| 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.|
| 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.|
| 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.|
| 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.|
| 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 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 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 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 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 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.|
| 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.|
......@@ -64,7 +64,8 @@ The UART module adaptation involves the following steps:
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
> 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.
......@@ -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.
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.
UART driver entry example:
......@@ -89,9 +95,13 @@ The following uses **uart_hi35xx.c** as an example to present the information re
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.
- **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
priority = 40; // Driver startup priority.
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.
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.
}
device1 :: deviceNode {
......@@ -133,7 +143,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
platform {
template uart_controller { // Template configuration. In the template, you can configure the common parameters shared by device nodes.
match_attr = "";
num = 0; // (Mandatory) Device number
num = 0; // (Mandatory) Device number.
baudrate = 115200; // (Mandatory) Baud rate. Set the value based on service requirements.
fifoRxEn = 1; // (Mandatory) Enable FIFOs to be received.
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
```
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
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
int32_t enable;
unsigned long physBase; // Physical address
uint32_t irqNum; // Interrupt number
uint32_t defaultBaudrate;// Default baud rate
uint32_t flags; // Flags related to the following three macros.
uint32_t defaultBaudrate; // Default baud rate
uint32_t flags; // Flags related to the following three macros
#define PL011_FLG_IRQ_REQUESTED (1 << 0)
#define PL011_FLG_DMA_RX_REQUESTED (1 << 1)
#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
struct UartDriverData { // Structure related to data transfer
uint32_t num;
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.
struct UartTransfer *rxTransfer; // Buffer (FIFO structure)
wait_queue_head_t wait; // Queuing signal related to conditional variables
int32_t count; // Data count
......@@ -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_TX (1 << 1)
#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.
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
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**)
......@@ -229,15 +241,15 @@ The following uses **uart_hi35xx.c** as an example to present the information re
- **Bind** function
Input parameter:
**Input parameter**:
**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|
| -------- | -------- |
......@@ -248,7 +260,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
| HDF_SUCCESS | Initialization successful.|
| HDF_FAILURE | Initialization failed.|
Function description:
**Function description**:
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
...
host = (struct UartHost *)OsalMemCalloc(sizeof(*host));// Allocate memory.
...
host->device = device; // (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 = device; // (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.
OsalAtomicSet(&host->atom, 0); // Initialize or set the atomic services.
host->priv = NULL;
host->method = NULL;
......@@ -279,15 +291,15 @@ The following uses **uart_hi35xx.c** as an example to present the information re
- **Init** function
Input parameter:
**Input parameter**:
**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.
......@@ -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.
...
host->method = &g_uartHostMethod; // Hook the UartHostMethod instance.
host->method = &g_uartHostMethod; // Attach the UartHostMethod instance.
return ret;
}
// Initialize UartHost.
......@@ -351,17 +363,21 @@ The following uses **uart_hi35xx.c** as an example to present the information re
```
- **Release** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
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.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> 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
{
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.
...
if (host->priv != NULL) {
Hi35xxDetach(host); // Customized memory release function.
......@@ -382,10 +398,10 @@ The following uses **uart_hi35xx.c** as an example to present the information re
struct UartDriverData *udd = NULL;
struct UartPl011Port *port = NULL;
...
udd = host->priv; // Convert UartHost to UartDriverData.
udd = host->priv; // The conversion from UartHost to UartDriverData is involved.
...
UartRemoveDev(host);// Remove the VFS.
port = udd->private;// Convert UartDriverData to UartPl011Port.
UartRemoveDev (host); // Remove the VFS.
port = udd->private; // The conversion from UartDriverData to UartPl011Port is involved.
if (port != NULL) {
if (port->physBase != 0) {
OsalIoUnmap((void *)port->physBase);// Unmap addresses.
......@@ -393,7 +409,7 @@ The following uses **uart_hi35xx.c** as an example to present the information re
OsalMemFree(port);
udd->private = NULL;
}
OsalMemFree(udd);//Release UartDriverData.
OsalMemFree (udd); // Release UartDriverData.
host->priv = NULL;
}
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册