提交 fd492d81 编写于 作者: A Annie_wang

update docs

Signed-off-by: NAnnie_wang <annie.wangli@huawei.com>
上级 1d1b6b4d
...@@ -5,23 +5,18 @@ ...@@ -5,23 +5,18 @@
### Regulator ### Regulator
The regulator module controls the voltage and current supplies of some devices in the system.
### Basic Concepts
The regulator module controls the voltage and current supplies of some devices in the system. In an embedded system (especially a mobile phone), it is important to control the power consumption, which directly affects the battery endurance. You can use a regulator to shut down the power supply to an idle module in the system or reduce the voltage and current for the module. The regulator module controls the voltage and current supplies of some devices in the system. In an embedded system (especially a mobile phone), it is important to control the power consumption, which directly affects the battery endurance. You can use a regulator to shut down the power supply to an idle module in the system or reduce the voltage and current for the module.
### Working Principles ### Working Principles
In the Hardware Driver Foundation (HDF), the regulator module uses the unified service mode for API adaptation. In this mode, a device service is used as the regulator manager to handle external access requests in a unified manner, which is reflected in the configuration file. The unified service mode applies to the scenario where there are many device objects of the same type, for example, when the regulator has more than 10 controllers. If the independent service mode is used, more device nodes need to be configured and more memory resources will be consumed by services. In the Hardware Driver Foundation (HDF), the regulator module uses the unified service mode for API adaptation. In this mode, a device service is used as the regulator manager to handle external access requests in a unified manner, which is reflected in the configuration file. The unified service mode applies when there are many device objects of the same type, for example, when the regulator has more than 10 controllers. If the independent service mode is used, more device nodes need to be configured and more memory resources will be consumed by services.
The regulator module is divided into the following layers: The regulator module is divided into the following layers:
- Interface layer: provides APIs for opening or closing a device and writing data.
- Core layer: provides the capabilities of binding, initializing, and releasing devices.
- Adaptation layer: implements other functions.
- The interface layer provides APIs for opening or closing a device and writing data. ![](../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.
- The core layer provides the capabilities of binding, initializing, and releasing devices.
- The adaptation layer implements other functions.
![](../public_sys-resources/icon-note.gif)NOTE<br/>The core layer can call the functions of the interface layer and uses the hook to call functions of the adaptation layer. In this way, the adaptation layer can indirectly call the functions of the interface layer, but the interface layer cannot call the functions of the adaptation layer.
**Figure 1** Unified service mode **Figure 1** Unified service mode
...@@ -33,13 +28,12 @@ The regulator module is divided into the following layers: ...@@ -33,13 +28,12 @@ The regulator module is divided into the following layers:
Currently, the regulator module supports only the kernels (LiteOS) of mini and small systems. Currently, the regulator module supports only the kernels (LiteOS) of mini and small systems.
## Development Guidelines
### When to Use ### When to Use
The regulator module controls the voltage and current supplies of some devices in the system. 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: The functions in **RegulatorMethod** are used to call the corresponding regulator driver functions:
...@@ -65,31 +59,34 @@ struct RegulatorMethod { ...@@ -65,31 +59,34 @@ struct RegulatorMethod {
| Method | Input Parameter | Return Value | Description | | Method | Input Parameter | Return Value | Description |
| ------------ | ------------------------------------------------------------ | ------------------ | ---------------- | | ------------ | ----------------------------------------------------------- | ----------------- | ---------------- |
| open | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Opens a device. | | open | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Opens a device. |
| close | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Closes a device. | | close | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Closes a device. |
| release | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Releases a device handle. | | release | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Releases a device handle. |
| enable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Enabling a Regulator | | enable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Enables a regulator. |
| disable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Disabling a Regulator | | disable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Disables a regulator. |
| forceDisable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Forcibly Disabling a Regulator | | forceDisable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Forcibly disables a regulator. |
| setVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**minUv**: minimum voltage to set. It is a uint32_t variable.<br>**maxUv**: maximum voltage to set. It is a uint32_t variable.| HDF_STATUS| Sets the output voltage range.| | setVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**minUv**: minimum voltage to set. It is a uint32_t variable.<br>**maxUv**: maximum voltage to set. It is a uint32_t variable.| HDF_STATUS| Sets the output voltage range.|
| getVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**voltage**: pointer to the output voltage value.| HDF_STATUS| Obtains the voltage. | | getVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**voltage**: pointer to the output voltage.| HDF_STATUS| Obtains the voltage. |
| setCurrent | **node**: structure pointer to the regulator node at the core layer.<br>**minUa**: minimum current to set. It is a uint32_t variable.<br>**maxUa**: maximum current to set. It is a uint32_t variable.| HDF_STATUS| Sets the output current range.| | setCurrent | **node**: structure pointer to the regulator node at the core layer.<br>**minUa**: minimum current to set. It is a uint32_t variable.<br>**maxUa**: maximum current to set. It is a uint32_t variable.| HDF_STATUS| Sets the output current range.|
| 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. | | 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. | | 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: The regulator module adaptation procedure is as follows:
- Instantiate the driver entry. 1. Instantiate the driver entry.
- Configure attribute files. 2. Configure attribute files.
- Instantiate the core layer APIs. 3. Instantiate the core layer APIs.
- Debug the driver. 4. Debug the driver.
## Development Example
1. Instantiate the driver entry. 1. Instantiate the driver entry.
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 are 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.
...@@ -100,7 +97,7 @@ The regulator module adaptation procedure is as follows: ...@@ -100,7 +97,7 @@ The regulator module adaptation procedure is as follows:
.Init = VirtualRegulatorInit, .Init = VirtualRegulatorInit,
.Release = VirtualRegulatorRelease, .Release = VirtualRegulatorRelease,
}; };
// Call HDF_INIT to register the driver entry with the HDF framework. // Call HDF_INIT to register the driver entry with the HDF.
HDF_INIT(g_regulatorDriverEntry); HDF_INIT(g_regulatorDriverEntry);
``` ```
...@@ -115,15 +112,15 @@ The regulator module adaptation procedure is as follows: ...@@ -115,15 +112,15 @@ The regulator module adaptation procedure is as follows:
| Member | Value | | Member | Value |
| --------------- | ------------------------------------------------------------ | | --------------- | ------------------------------------------------------------ |
| policy | **0**, which indicates that no service is published. | | policy | **0**, which indicates that no service is published. |
| priority | Driver startup priority. The value range is 0 to 200. A larger value indicates a lower priority. If the priorities are the same, the device loading sequence is not ensured.| | priority | Driver startup priority, which ranges form 0 to 200. A larger value indicates a lower priority. If the priorities are the same, the device loading sequence is not ensured.|
| permission | Driver permission. | | permission | Driver permission. |
| moduleName | The value is **HDF_PLATFORM_REGULATOR_MANAGER**. | | moduleName | **HDF_PLATFORM_REGULATOR_MANAGER** |
| serviceName | The value is **HDF_PLATFORM_REGULATOR_MANAGER**. | | serviceName | **HDF_PLATFORM_REGULATOR_MANAGER** |
| deviceMatchAttr | Reserved. | | deviceMatchAttr | This parameter is 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. 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.
- **device_info.hcs** configuration reference - **device_info.hcs** configuration example
``` ```
root { root {
...@@ -132,14 +129,14 @@ The regulator module adaptation procedure is as follows: ...@@ -132,14 +129,14 @@ The regulator module adaptation procedure is as follows:
hostName = "platform_host"; hostName = "platform_host";
priority = 50; priority = 50;
device_regulator :: device { device_regulator :: device {
device0 :: deviceNode { // Configure an HDF device node for each regulator controller. device0:: deviceNode { // Set an HDF device node for each regulator controller.
policy = 1; // 2: visible in user mode; 1: visible in kernel mode; 0: no service required. policy = 1; // Policy for the driver to publish services.
priority = 50; // Driver startup priority. priority = 50; // Driver startup priority.
permission = 0644; // Permission to create device nodes of the driver. 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. */ /* (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. */
moduleName = "HDF_PLATFORM_REGULATOR_MANAGER"; moduleName = "HDF_PLATFORM_REGULATOR_MANAGER";
serviceName = "HDF_PLATFORM_REGULATOR_MANAGER"; // (Mandatory) Unique name of the service published by the driver. serviceName = "HDF_PLATFORM_REGULATOR_MANAGER"; // (Mandatory) Unique name of the service published by the driver.
/* (Mandatory) Set the controller private data, which must be same as that in regulator_config.hcs. */ /* (Mandatory) Set the controller private data, which must be same as that in regulator_config.hcs. */
deviceMatchAttr = "hdf_platform_regulator_manager"; deviceMatchAttr = "hdf_platform_regulator_manager";
} }
device1 :: deviceNode { device1 :: deviceNode {
...@@ -155,7 +152,7 @@ The regulator module adaptation procedure is as follows: ...@@ -155,7 +152,7 @@ The regulator module adaptation procedure is as follows:
} }
``` ```
- **regulator\_config.hcs** reference: - **regulator\_config.hcs** configuration example:
``` ```
root { root {
...@@ -184,7 +181,7 @@ The regulator module adaptation procedure is as follows: ...@@ -184,7 +181,7 @@ The regulator module adaptation procedure is as follows:
minUa = 0; minUa = 0;
maxUa = 0; maxUa = 0;
} }
/* Each regulator controller corresponds to a controller node. If there are multiple regulator controllers, add the corresponding controller nodes one by one.*/ /* Each regulator controller corresponds to a controller node. If there are multiple regulator controllers, add the corresponding controller nodes one by one. */
controller_0x130d0001 :: regulator_controller { controller_0x130d0001 :: regulator_controller {
device_num = 1; device_num = 1;
name = "regulator_adapter_2"; name = "regulator_adapter_2";
...@@ -201,146 +198,152 @@ The regulator module adaptation procedure is as follows: ...@@ -201,146 +198,152 @@ The regulator module adaptation procedure is as follows:
} }
``` ```
3. Instantiate the APIs of the core layer. 3. Instantiate the APIs of the core layer.
- Initialize the **RegulatorNode** object at the core layer, including initializing the vendor custom structure (passing parameters and data), instantiating **RegulatorMethod** (used to call underlying functions of the driver) in **PinCntlr**, and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**).
- Initializing the vendor custom structure
The **RegulatorNode** structure holds parameters and data for the driver. The HDF obtains the values in **regulator\_config.hcs** using **DeviceResourceIface**. 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).
``` - Defining a custom structure
// RegulatorNode is the controller structure at the core layer. Its members are assigned with values by using the Init function.
struct RegulatorNode { The **RegulatorNode** structure holds parameters and data for the driver. The HDF obtains the values in **regulator_config.hcs** using **DeviceResourceIface**.
struct RegulatorDesc regulatorInfo;
struct DListHead node;
struct RegulatorMethod *ops;
void *priv; ```
struct OsalMutex lock; // RegulatorNode is the core layer controller structure. The Init function assigns values to the members of RegulatorNode.
}; struct RegulatorNode {
struct RegulatorDesc regulatorInfo;
struct RegulatorDesc { struct DListHead node;
const char *name; /* Regulator name. */ struct RegulatorMethod *ops;
const char *parentName; /* Regulator parent node name. */ void *priv;
struct RegulatorConstraints constraints; /* Regulator constraint information. */ struct OsalMutex lock;
uint32_t minUv; /* Minimum output voltage. */ };
uint32_t maxUv; /* Maximum output voltage. */
uint32_t minUa; /* Minimum output current. */ struct RegulatorDesc {
uint32_t maxUa; /* Maximum output current. */ const char *name; /* Regulator name. */
uint32_t status; /* Regulator status, which can be on or off. */ const char *parentName; /* Regulator parent node name. */
int useCount; struct RegulatorConstraints constraints; /* Regulator constraint information. */
int consumerRegNums; /* Number of regulator consumers. */ uint32_t minUv; /* Minimum output voltage. */
RegulatorStatusChangecb cb; /* Variable used to notify the regulator status changes. */ uint32_t maxUv; /* Maximum output voltage. */
}; uint32_t minUa; /* Minimum output current. */
uint32_t maxUa; /* Maximum output current. */
struct RegulatorConstraints { uint32_t status; /* Regulator status, which can be on or off. */
uint8_t alwaysOn; /* Whether the regulator is always on. */ int useCount;
uint8_t mode; /* Voltage or current. */ int consumerRegNums; /* Number of regulator consumers. */
uint32_t minUv; /* Minimum output voltage allowed. */ RegulatorStatusChangecb cb; /* Variable used to notify the regulator status changes. */
uint32_t maxUv; /* Maximum output voltage allowed. */ };
uint32_t minUa; /* Minimum output current allowed. */
uint32_t maxUa; /* Maximum output current allowed. */ struct RegulatorConstraints {
}; uint8_t alwaysOn; /* Whether the regulator is always on. */
``` uint8_t mode; /* Voltage or current. */
uint32_t minUv; /* Minimum output voltage allowed. */
uint32_t maxUv; /* Maximum output voltage allowed. */
uint32_t minUa; /* Minimum output current allowed. */
uint32_t maxUa; /* Maximum output current allowed. */
};
```
- Instantiating **RegulatorMethod** (other members are initialized by **Init**)
```c
// Example of regulator_virtual.c: Instantiate the hooks.
static struct RegulatorMethod g_method = {
.enable = VirtualRegulatorEnable,
.disable = VirtualRegulatorDisable,
.setVoltage = VirtualRegulatorSetVoltage,
.getVoltage = VirtualRegulatorGetVoltage,
.setCurrent = VirtualRegulatorSetCurrent,
.getCurrent = VirtualRegulatorGetCurrent,
.getStatus = VirtualRegulatorGetStatus,
};
```
- **Init** function
Input parameter:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
- Instantiating **RegulatorMethod** (other members are initialized by **Init**)
**HDF\_STATUS**
The table below lists some states. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.
**Table 2** HDF_STATUS
| State | 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. |
Function description:
Initializes the custom structure and **RegulatorNode** members, and adds the regulator controller by calling the **RegulatorNodeAdd** function at the core layer.
```c ```c
// Example of regulator_virtual.c: Instantiate the hook. static int32_t VirtualRegulatorInit(struct HdfDeviceObject *device)
static struct RegulatorMethod g_method = { {
.enable = VirtualRegulatorEnable, int32_t ret;
.disable = VirtualRegulatorDisable, const struct DeviceResourceNode *childNode = NULL;
.setVoltage = VirtualRegulatorSetVoltage, ...
.getVoltage = VirtualRegulatorGetVoltage, DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
.setCurrent = VirtualRegulatorSetCurrent, ret = VirtualRegulatorParseAndInit(device, childNode);// (Mandatory) The implementation is as follows:
.getCurrent = VirtualRegulatorGetCurrent, ...
.getStatus = VirtualRegulatorGetStatus, }
}; ...
}
static int32_t VirtualRegulatorParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
{
int32_t ret;
struct RegulatorNode *regNode = NULL;
(void)device;
regNode = (struct RegulatorNode *)OsalMemCalloc(sizeof(*regNode));// Load the .hcs file.
...
ret = VirtualRegulatorReadHcs(regNode, node);// Read .hcs information.
...
regNode->priv = (void *)node; // Instantiate the node.
regNode->ops = &g_method; // Instantiate OPS.
ret = RegulatorNodeAdd(regNode); // Add the node.
...
}
``` ```
- **Release** function
- **Init** function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
Return value: Input parameter:
**HDF\_STATUS** (The following table lists some states. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.) **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**Table 2** HDF\_STATUS Return value:
| State | Description | No value is return.
| ---------------------- | -------------- |
| HDF_ERR_INVALID_OBJECT | Invalid controller object.| Function description:
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory. |
| HDF_ERR_INVALID_PARAM | Invalid parameter. | 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.
| HDF_ERR_IO | I/O error. |
| HDF_SUCCESS | Initialization successful. |
| HDF_FAILURE | Initialization failed. |
Function description:
Initializes the custom structure and **RegulatorNode** members, and adds the regulator controller by calling the **RegulatorNodeAdd** function at the core layer.
```c ```c
static int32_t VirtualRegulatorInit(struct HdfDeviceObject *device) static void VirtualRegulatorRelease(struct HdfDeviceObject *device)
{ {
int32_t ret;
const struct DeviceResourceNode *childNode = NULL;
...
DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
ret = VirtualRegulatorParseAndInit(device, childNode);// (Mandatory) The implementation is as follows:
...
}
...
}
static int32_t VirtualRegulatorParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
{
int32_t ret;
struct RegulatorNode *regNode = NULL;
(void)device;
regNode = (struct RegulatorNode *)OsalMemCalloc(sizeof(*regNode));// Load the .hcs file.
...
ret = VirtualRegulatorReadHcs(regNode, node);// Read .hcs information.
...
regNode->priv = (void *)node; // Instantiate the node.
regNode->ops = &g_method; // Instantiate OPS.
ret = RegulatorNodeAdd(regNode); // Add the node.
... ...
RegulatorNodeRemoveAll();// (Mandatory) Call the function at the core layer to release regulator controller devices and services.
} }
``` ```
- **Release** function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
Return value:
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.
```c
static void VirtualRegulatorRelease(struct HdfDeviceObject *device)
{
...
RegulatorNodeRemoveAll();// (Mandatory) Call the function at the core layer to release regulator controller devices and services.
}
```
4. (Optional) Debug the driver.
Verify the basic functions of the new driver, for example, whether the test cases are successful after the driver is loaded. 4. Debug the driver.
\ No newline at end of file
(Optional) Verify the basic functions of the new driver, for example, check whether the test cases are successful after the driver is loaded.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册