The codec Hardware Device Interface (HDI) driver framework is implemented based on OpenHarmony Hardware Driver Foundation (HDF). The HDI driver framework implements the video hardware codec driver based on OpenMAX. It provides APIs for the upper-layer media services to obtain component encoding and decoding capabilities, create a component, set parameters, transfer data, and destroy a component. The codec driver can encode video data in YUV or RGB format to H.264 or H.265 format, and decode raw stream data from H.264 or H.265 format to YUV or RGB format.
The OpenHarmony codec Hardware Device Interface (HDI) driver framework implements the video hardware codec driver based on OpenMAX. It provides APIs for the upper-layer media services to obtain component encoding and decoding capabilities, create a component, set parameters, transfer data, and destroy a component. The codec driver can encode video data in YUV or RGB format to H.264 or H.265 format, and decode raw stream data from H.264 or H.265 format to YUV or RGB format. This document describes the codec functionality developed based on the OpenHarmony Hardware Driver Foundation (HDF).
The figure below shows the codec HDI driver framework.
The codec HDI driver framework is implemented based on the HDF. The figure below shows the codec HDI driver framework.
**Figure 1** Codec HDI driver framework
...
...
@@ -16,7 +16,7 @@ The figure below shows the codec HDI driver framework.
- Codec HDI Adapter: HDI implementation layer, which implements HDI APIs and interacts with OpenMAX Integration layer (IL).
- OpenMAX IL interface: provides OpenMAX IL APIs to directly interact with the codec HDI driver.
- Vendor Impl: vendor adaptation layer, which is the OpenMAX implementation layer adapted by each vendor.
- Codec Hardware: hardware coding and decoding device.
- Codec Hardware: hardware decoding device.
### Basic Concepts
Before you get started, understand the following concepts:
...
...
@@ -39,7 +39,7 @@ Before you get started, understand the following concepts:
- Component
An OpenMAX IL component, which is an abstraction of modules in video streams. The components in this document refer to codec components used for video encoding and decoding.
An OpenMAX IL component, which is an abstraction of modules in video streams. The components in this document refer to codec components for video encoding and decoding.
### Constraints
...
...
@@ -59,7 +59,7 @@ The codec module implements hardware encoding and decoding of video data. It con
| int32_t (*UseBuffer)(struct CodecComponentType *self, uint32_t portIndex, struct OmxCodecBuffer *buffer) | Requests a port buffer for the component. |
| int32_t (*UseBuffer)(struct CodecComponentType *self, uint32_t portIndex, struct OmxCodecBuffer *buffer) | Specifies the buffer of a component port. |
@@ -84,11 +84,11 @@ The codec module implements hardware encoding and decoding of video data. It con
For more information, see [codec](https://gitee.com/openharmony/drivers_peripheral/tree/master/codec).
### Development Procedure
### How to Develop
The codec HDI driver development procedure is as follows:
#### Registering and Initializing the Driver
Define the **HdfDriverEntry** structure (which defines the driver initialization method) and fill in the **g_codecComponentDriverEntry** structure to implement the pointers in **Bind()**, **Init()**, and **Release()**.
Define the **HdfDriverEntry** structure (which defines the driver initialization method) and fill in the **g_codecComponentDriverEntry** structure to implement the **Bind()**, **Init()**, and **Release()** pointers.
```c
structHdfDriverEntryg_codecComponentDriverEntry={
...
...
@@ -133,7 +133,7 @@ HDF_INIT(g_codecComponentDriverEntry); // Register HdfDriverEntry of the codec H
}
```
-**HdfCodecComponentTypeDriverInit**: loads the attribute configuration in the HDF Configuration Source (HCS).
-**HdfCodecComponentTypeDriverInit**: loads the attribute configuration from the HDF configuration source (HCS).
@@ -170,11 +170,12 @@ The HCS consists of the following:
- Device configuration
- Configuration of the supported components
You need to configure the driver node, loading sequence, and service name. For details about the HCS syntax, see [Configuration Management](driver-hdf-manage.md).
The HCS includes the driver node, loading sequence, and service name. For details about the HCS syntax, see [Configuration Management](driver-hdf-manage.md).
The following uses the RK3568 development board as an example. The configuration files of the standard system are in the **vendor/hihope/rk3568/hdf_config/uhdf/** directory.
Configuration file Path of the standard system:
vendor/hihope/rk3568/hdf_config/uhdf/
1.Configure the device.
1.Device configuration
Add the **codec_omx_service** configuration to **codec_host** in **device_info.hcs**. The following is an example:
```c
...
...
@@ -188,31 +189,31 @@ The following uses the RK3568 development board as an example. The configuration
priority = 100; // Priority.
moduleName = "libcodec_hdi_omx_server.z.so"; // Dynamic library of the driver.
serviceName = "codec_hdi_omx_service"; // Service name of the driver.
@@ -238,7 +239,7 @@ The following uses the RK3568 development board as an example. The configuration
### Development Example
After completing codec module driver adaptation, use the HDI APIs provided by the codec module for further development. The codec HDI provides the following features:
1. Provides codec HDI APIs for video services to implement encoding and decoding for video services.
1. Provides codec HDI APIs for video services to implement encoding and decoding of video services.
2. Provides standard interfaces for device developers to ensure that the OEM vendors comply with the HDI adapter standard. This promises a healthy evolution of the ecosystem.
The development procedure is as follows:
...
...
@@ -247,7 +248,7 @@ The development procedure is as follows:
2. Set codec parameters and information such as the video width, height, and bit rate.
3. Apply for input and output buffers.
4. Flip codec buffers, enable the component to enter the **OMX_Executing** state, and process the callbacks.
5. Deinitialize the interface instance, destroy the buffers, close the component, and releases all interface instances.
5. Deinitialize the interface instance, destroy the buffers, close the component, and releases all interface objects.
#### Initializing the Driver
Initialize the interface instance and callbacks, and create a component.
...
...
@@ -351,7 +352,7 @@ Perform the following steps:
1. Use **UseBuffer()** to apply for input and output buffers and save the buffer IDs. The buffer IDs can be used for subsequent buffer flipping.
2. Check whether the corresponding port is enabled. If not, enable the port first.
3. Use **SendCommand()** to change the component status to **OMX_StateIdle**, and wait until the operation result is obtained.
3. Use **SendCommand()** to change the component status to OMX_StateIdle, and wait until the operation result is obtained.
The RK3568 development board does not support data framing. Therefore, you need to manually divide the data into frames. Data is divided from code 0x000001 or 0x00000001 and sent to the server for processing. The sample code is as follows:
Automatic framing is not supported in rk OMX decoding. Therefore, you need to manually divide data into frames. Currently, data is divided into frames from code 0x000001 or 0x00000001 and sent to the server for processing. The sample code is as follows:
-**EventHandler**: Called when a command is executed. For example, when the command for changing the component state from **OMX_StateIdle** to **OMX_StateExecuting** is executed, this callback is invoked to return the result.
-**EmptyBufferDone**: Called when the input data is consumed. If the client needs to fill data to encode or decode, it must call **EmptyThisBuffer()** again.
-**FillBufferDone**: Called when the output data is filled. If the client needs to read the encoded or decoded data, it must call **FillThisBuffer()** again.
-**EmptyBufferDone**: Called when the input data is consumed. If the client needs to fill in data to encode or decode, call **EmptyThisBuffer()**.
-**FillBufferDone**: Called when the output data is filled. If the client needs to read the encoded or decoded data, call **FillThisBuffer()**.
Change the component state to **OMX_StateIdle**, release the input and output buffers, change the component state to **OMX_StateLoaded**, and call **DestoryComponent** to destroy the component.
Change the component state to IDLE, release the input and output buffers, change the component state to **OMX_StateLoaded**, and call **DestoryComponent** to destroy the component.
##### Example of Releasing Buffers
...
...
@@ -719,7 +721,7 @@ OpenMAX does not support framing.
**Solution**
Pass in one frame at a time when **EmptyThisBuffer** is call.
Transfer data frame by frame when **EmptyThisBuffer** is called.
## Only Green Screen Displayed During the Decoding Process
...
...
@@ -749,11 +751,11 @@ After the generated video stream (H.264 stream) is written to a file, the video
**Solution**
View the **codec_host** log generated during encoding, search for "encode params init settings", and check for incorrect parameters. If **framerate** is **0**, **xFramerate** is incorrectly set. In this case, move the framerate leftwards by 16 bits.
View the **codec_host** log generated during encoding, search for "encode params init settings", and check for incorrect parameters. If **framerate** is **0**, **xFramerate** is incorrectly set. In this case, move the framerate leftwards by 16 bits.
Check and correct the setting of **OMX_VIDEO_PARAM_AVCTYPE**.
Check the value of **OMX_VIDEO_PARAM_AVCTYPE**, and set it correctly.
# Reference
For more information, see [codec](https://gitee.com/openharmony/drivers_peripheral/tree/master/codec).
For more information, see [Codec](https://gitee.com/openharmony/drivers_peripheral/tree/master/codec).
The light driver model provides APIs for the upper-layer light hardware service layer to control lights, including obtaining the light type, setting the lighting mode and blinking effect, and turning on or off a light. This model implements functionalities such as cross-OS migration and differentiated configurations based on the Hardware Driver Foundation (HDF) to achieve the goal of "one-time development for cross-system deployment" of the light driver.
The light driver model provides APIs for the upper-layer light hardware service layer to control lights, including obtaining the light type, setting the lighting mode and blinking effect, and turning on or off a light. This model implements cross-OS porting and differentiated configurations based on the Hardware Driver Foundation (HDF) to achieve the goal of "one-time development for cross-system deployment" of the light driver.
The figure below shows the light driver model.
...
...
@@ -21,14 +21,14 @@ The figure below shows how the light driver works.
The following uses the Hi3516D V300 development board powered by the standard system as an example to describe how the light driver works.
The following describes how the light module driver loads and starts on a Hi3516D V300 board that runs the standard system.
1. The light driver reads the light device management configuration from **Light Host** in the **device_info.hcs** file.
2. The light driver reads the light data configuration from the **light_config.hcs** file.
3. The light driver parses the light device management configuration and associates with the corresponding device driver.
4. The light proxy delivers an instruction to the light stub.
5. The light stub delivers an instruction to the light controller.
6. The light abstract driver interface is started.
1. The Device Manager reads the Light device management configuration from the **device_info.hcs** file.
2. The Device Manager reads the light data configuration from the **light_config.hcs** file.
3. The HCS Parser parses the light device management configuration, loads the Light Host, and controls the Host to load the driver.
4. The Light Proxy obtains the light HDI service instance and calls the Light Stub over Inter-Process Communication (IPC).
5. The Light Stub processes IPC-related service logic and calls the Light Controller after parameter deserialization.
6. The Light Controller implements the HDI APIs and calls the Light Abstract Driver APIs to operate the light devices.
## Development Guidelines
...
...
@@ -38,33 +38,32 @@ Light control is widely used in daily life. For example, a light is blinking whe
### Available APIs
The light driver model provides APIs to obtain information about all the lights in the system and dynamically set the blinking mode and duration. The light hardware service calls the **GetLightInfo** method to obtain basic information about the light and calls the **TurnOnLight** method to make the light blinking. The table below describes the APIs of the light driver model.
The light driver model provides APIs for obtaining information about all the lights in the system and dynamically setting the blinking mode and duration. The light hardware service calls **GetLightInfo()** to obtain the basic light information, calls **TurnOnLight()** to set the blinking effect, and calls **TurnOffLight()** to turn off lights. The following table describes the APIs of the light driver model.
| int32_t (*GetLightInfo)(struct LightInfo **lightInfo, uint32_t *count) | Obtains information about all lights in the system. <br/>- **lightInfo** indicates the double pointer to the basic light information. <br/>- **count** indicates the pointer to the number of lights. |
| int32_t (*TurnOnLight)(uint32_t lightId, struct LightEffect *effect) | Turns on available lights in the list based on the specified light type. <br/>**lightId** indicates the light type, and **effect** indicates the pointer to the blinking effect. |
| int32_t (*TurnOffLight)(uint32_t lightId) | Turns off available lights in the light list based on the specified light type. <br/>**lightId** indicates the light type. |
| int32_t (*GetLightInfo)([out] struct LightInfo **lightInfo, [out] uint32_t *count) | Obtains information about all types of lights in the system. <br>**lightInfo** indicates the double pointer to the light information obtained. <br>**count** indicates the pointer to the number of lights.|
| int32_t (*TurnOnLight)([in] uint32_t lightId, [in] struct LightEffect *effect) | Turns on available lights in the list based on the specified light type. <br>**lightId** indicates the light type, and **effect** indicates the pointer to the light effect.|
| int32_t (*TurnOffLight)([in] uint32_t lightId) | Turns off available lights in the list based on the specified light type. |
### How to Develop
1. Based on the HDF and the driver entry, complete the light abstract driver development (using the **Bind**, **Init**, **Release**, and **Dispatch** functions), resource configuration, and HCS parsing. Configure the light driver device information.
### Development Procedure
1. Based on the HDF and the driver entry, complete the light abstract driver development (using the **Bind**, **Init**, **Release**, and **Dispatch** functions), resource configuration, and HCS parsing.
- Call **HDF_INIT** to register the driver entry with the HDF. Generally, the HDF calls the **Bind** function and then the **Init** function to load the driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
The light driver model uses HDF configuration source (HCS). For details about HCS fields, see [Configuration Management](../driver/driver-hdf-manage.md).
The light driver entry is defined as follows:
- The light driver model uses HDF configuration source (HCS). For details about HCS fields, see [Configuration Management](driver-hdf-manage.md). The light driver entry is defined as follows:
```c
/* Register the light entry data structure object. */
struct HdfDriverEntry g_lightDriverEntry = {
.moduleVersion = 1, // Light module version.
.moduleVersion = 1, // Version of the light module.
.moduleName = "HDF_LIGHT", // Light module name, which must be the same as the value of moduleName in the device_info.hcs file.
.Bind = BindLightDriver, // BInd the light driver.
.Init = InitLightDriver, // Initialize the light driver.
.Release = ReleaseLightDriver, // Release the light resources.
.Bind = BindLightDriver, // Bind() of the light driver.
.Init = InitLightDriver, // Init() of the light driver.
.Release = ReleaseLightDriver, // Release() of the light driver.
};
/* Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls Bind() and then Init() to load the driver. If Init() fails to be called, the HDF will call Release() to release resources and exit. */
/* Call HDF_INIT to register the driver entry with the HDF. */
HDF_INIT(g_lightDriverEntry);
```
...
...
@@ -122,7 +121,7 @@ The light driver model provides APIs to obtain information about all the lights
}
/* Initialize work items. */
if (HdfWorkInit(&drvData->work, LightWorkEntry, (void*)drvData) != HDF_SUCCESS) {
HDF_LOGE("%s: init workQueue fail!", __func__);
HDF_LOGE("%s: init work fail!", __func__);
return HDF_FAILURE;
}
/* Parse the HCS. */
...
...
@@ -160,20 +159,24 @@ The light driver model provides APIs to obtain information about all the lights
}
```
- The light device management module publishes light device APIs in the system. During the system startup process, the HDF loads the device management driver based on **Light Host** in the HCS.
- The light device management module is responsible for publishing light device APIs in the system. During the system startup process, the HDF loads the device management driver based on **Light Host** in the HCS.
```
/* Light device HCS */
```c
/* HCS of the light device. */
light :: host {
hostName = "light_host";
device_light :: device {
device0 :: deviceNode {
policy = 2; // Policy for the driver to publish services. (0: The driver does not provide services. 1: The driver publishes services for the kernel space. 2: The driver publishes services for both the kernel space and user space.)
priority = 100; // Light driver startup priority. The value ranges from 0 to 200. A larger value indicates a lower priority. The value 100 is recommended. If the priorities are the same, the device loading sequence cannot be ensured.
preload = 0; // Whether to load the driver on demand. The value 0 means to load the driver on demand; the value 2 means the opposite.
permission = 0664; // Permission for the driver to create a device node.
moduleName = "HDF_LIGHT"; // Light driver name. The value of this field must be the same as that of moduleName in the HdfDriverEntry structure.
serviceName = "hdf_light"; // Unique name of the service published by the driver.
policy = 2; // Policy for the driver to publish services. If the value is 0, the driver does not publish services. If the value is 1, the driver publishes services to the kernel space. If the value is 2, the driver publishes services to both the kernel space and user space.
priority = 100; // Priority (0–200) for starting the light driver. A larger value indicates a lower priority. The recommended value is 100. If the priorities are the same, the device loading sequence is not ensured.
preload = 0; // The value 0 means to load the driver by default during the startup of the system. The value 2 means the opposite.
permission = 0664; // Permission for the device node created.
moduleName = "HDF_LIGHT"; // Light driver name. The value must be the same as the value of moduleName in the driver entry structure.
serviceName = "hdf_light"; // Service published by the light driver. The service name must be unique.
deviceMatchAttr = "hdf_light_driver"; // 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.
}
}
}
```
2. Parse the device attribute information and registers, and register them with the light device management module.
...
...
@@ -211,16 +214,17 @@ The light driver model provides APIs to obtain information about all the lights
if(ret!=HDF_SUCCESS){
drvData->info[temp]->busBNum=LIGHT_INVALID_GPIO;
}
}
.....
returnHDF_SUCCESS;
}
```
3.Call related APIs to obtain the light type, turn on and off lights, and create and delete the timer based on the blinking mode.
3.Implement the APIs for obtaining the light type, setting the blinking mode, turning on and off lights, and creating and destroying a timer based on the blinking mode.
```c
/* Call GetAllLightInfo() to obtain the light type. Call TurnOnLight() to enable the blinking mode.
Call TurnOffLight() to stop blinking. */
/* Call GetAllLightInfo() to obtain the light types, call TurnOnLight() to turn on lights,
/* Receive the lightBrightness value passed in. Bits 24 to 31 are extension bits, bits 16 to 23 indicate red, bits 8 to 15 indicate green, and bits 0 to 7 indicate blue. If lightBrightness is not 0, enable the light in the specified color.
/* Receive the lightBrightness value passed in. Bits 24 to 31 are extension bits, bits 16 to 23 indicate red, bits 8 to 15 indicate green, and bits 0 to 7 indicate blue. If lightBrightness is not 0, turn on the light in the specified color.
Set the light brightness to a value ranging from 0 to 255 if supported. */
@@ -70,7 +70,7 @@ The USB Device DDK provides the capability of developing USB drivers on the devi
- The Adapter module is provided by the composite device configuration driver and common function driver.
## How to Develop
## Development Guidelines
The USB driver development in kernel mode is complex. Therefore, you need to have a deep understanding of the USB protocol. The USB DDK is introduced to help you to develop USB drivers in user mode more conveniently.
Developed on the Hardware Driver Foundation (HDF), the vibrator driver model makes vibrator driver development easier. The motor driver model shields the interaction between the device driver and the system and provides unified and stable driver interface capabilities for the hardware service layer. It also provides open interfaces and interface parsing capabilities for developers to develop vibrator drivers and deploy vibrators in different OSs.<br> The figure below shows the vibrator driver model.
The vibrator driver model is developed based on OpenHarmony Hardware Driver Foundation (HDF) to facilitate vibrator driver development. The vibrator driver model shields the interaction between the device driver and the system, and provides unified and stable driver interface capabilities for the hardware service layer. It also provides open interfaces and interface parsing capabilities for developing vibrator drivers and deploying vibrators in different OSs.<br> The figure below shows the vibrator driver model.
**Figure 1** Vibrator driver model
...
...
@@ -12,15 +12,25 @@ Developed on the Hardware Driver Foundation (HDF), the vibrator driver model mak
### Basic Concepts
The system controls device vibration by invoking the vibrator. There are two vibration modes:
Vibrators can be classified into the following types based on vibration mechanism:
- Rotor vibrator
The rotor vibrator uses magnetic field caused by current to drive the rotor to rotate and produce vibration. Rotor vibrators include ordinary rotor vibrators and coin rotor vibrators. The rotor vibrators cannot start or stop quickly or implement multiple vibration modes. However, they have small footprint and are cost-efficient.
- Linear vibrator
The linear vibrator drives the spring mass for linear movement and produce vibration. Linear vibrators include longitudinal and transverse linear vibrators. The linear vibrators start and stop quickly, produce different vibration inductions, and have good sense of direction.
The system calls the vibrator driver APIs to control the vibration of the device. There are two vibration modes:
- One-shot vibration
The vibrator vibrates for a specified duration.
The vibrator vibrates once for a given duration.
- Periodic vibration
The vibrator vibrates with a preset effect. For example, if **haptic.clock.timer** is set to **[600, 600, 200, 600]**, the vibrator waits for 600 ms, vibrates for 600 ms, waits for 200 ms, and vibrates for 600 ms.
The vibrator vibrates at preset intervals. For example, if **haptic.clock.timer** is set to **[600, 600, 200, 600]**, the vibrator waits for 600 ms, vibrates for 600 ms, waits for 200 ms, and vibrates for 600 ms.
### Working Principles
...
...
@@ -30,18 +40,18 @@ The figure below shows how a vibrator driver is loaded.
The following uses the vibrator driver on the Hi3516D V300 development board of the standard system as an example to describe the driver loading and running process.
The following describes how a vibrator module driver loads and starts on a Hi3516DV300 that runs the standard system.
1. The vibrator driver reads the vibrator management configuration information from **Vibrator Host** in the **device_info.hcs** file.
2. The HCS parser parses the vibrator management configuration and associates it with the vibrator abstract driver.
3. The vibrator chipset driver reads the vibrator data configuration from the **linear_vibrator_config.hcs** file.
4. The HCS parser parses the vibrator data configuration and associates it with the vibrator haptic driver.
5. The vibrator proxy delivers an instruction to the vibrator stub.
6. The vibrator stub calls the vibrator controller.
7. The vibrator host initializes the vibrator abstract driver interfaces.
8. The vibrator haptic driver starts a thread to parse the vibrator haptic module.
9. The vibrator haptic driver calls the **Start** interface in the vibrator abstract driver.
10. The vibrator abstract driver calls the **Start** interface in the vibrator chipset driver.
1. The Device Manager reads the vibrator management configuration from the **device_info.hcs** file.
2. The HDF Configuration Source (HCS) Parser parses the vibrator management configuration and loads the vibrator abstract driver.
3. The Device Manager reads the Vibrator data configuration from the **linear_vibrator_config.hcs** file.
4. The HCS Parser parses the vibrator data configuration and loads the haptic driver.
5. The Vibrator Proxy obtains the vibrator HDI service instance and sends it to the Vibrator Stub over Inter-Process Communication (IPC).
6. The Vibrator Stub processes IPC-related service logic and calls the Light Controller after parameter deserialization.
7. The Vibrator Controller implements the HDI APIs and calls the Vibrator abstract driver APIs over IPC.
8. The haptic driver starts a thread to parse the vibrator haptic module.
9. The haptic driver calls **Start()** in the vibrator abstract driver.
10. The vibrator abstract driver calls **Start()** in the vibrator differentiated driver to control the vibrator device to vibrate with a given effect.
## Development Guidelines
...
...
@@ -51,17 +61,17 @@ You can set different vibration effects as needed, for example, customizing vibr
### Available APIs
The vibrator driver model supports static HDF Configuration Source (HCS) configuration and dynamic parameter configuration. The vibrator hardware service calls **StartOnce()** to trigger continuous vibration and calls **Start()** to trigger vibration with a specified effect. The table below lists the APIs provided by the vibrator driver model for the hardware service layer.
The vibrator driver model supports static HCS and dynamic parameter configuration. The vibrator hardware service calls **StartOnce()** to trigger continuous vibration and calls **Start()** to trigger vibration with a specified effect. The following table describes the APIs provided by the vibrator driver model for the hardware service layer.
| int32_t EnableVibratorModulation(uint32_t duration, int32_t intensity, int32_t frequency) | Triggers vibration with the given **duration**, **frequency**, and **intensity**.|
| int32_t GetVibratorInfo(struct VibratorInfo **vibratorInfo); | Obtains vibrator information, including whether the intensity and frequency can be set and the intensity and frequency range.|
| int32_t (*StartOnce)([in] uint32_t duration) | Triggers a one-short vibration with a given duration.<br>**duration** specifies the duration of the one-short vibration. |
| int32_t (*Start)([in] const char *effectType) | Triggers periodic vibrations with a preset effect. <br>**effectType** indicates the pointer to the preset effect type. |
| int32_t (*Stop)([in] enum VibratorMode mode) | Stops vibration. <br>**mode** indicates the vibration mode, which can be one-short or periodic vibration. |
| int32_t (*EnableVibratorModulation)(uint32_t duration, int32_t intensity, int32_t frequency) | Triggers a vibration with the given duration, frequency, and intensity.<br>**duration** indicates the duration of the vibration.<br>**intensity** indicates the vibration amplitude.<br>**frequency** indicates the vibrator frequency in the vibration period.|
| int32_t (*GetVibratorInfo)([out] struct VibratorInfo **vibratorInfo) | Obtains information about all vibrators whose amplitude and frequency can be set in the system. <br>**vibratorInfo** indicates the pointer to the vibrator information obtained.|
### How to Develop
...
...
@@ -69,25 +79,25 @@ The vibrator driver model provides APIs for the upper-layer hardware service to
1. Develop the vibrator abstract driver based on the driver entry. Specifically, implement the **Bind**, **Init**, **Release**, and **Dispatch** functions, configure resources, and parse the HCS.
- Call **HDF_INIT** to register the driver entry with the HDF. During driver loading, the HDF calls the **Bind** function and then the **Init** function to load the driver. If the **Init** function fails to be called, the HDF calls **Release** to release the driver resources and exit the vibrator driver model. The vibrator driver model uses the HCS as the configuration source code. For details about HCS configuration fields, see [Configuration Management](driver-hdf-manage.md). The driver entry function is defined as follows:
- Call **HDF_INIT** to register the driver entry with the HDF. The HDF calls **Bind** and then **Init** to load the driver. If **Init** fails to be called, the HDF calls **Release** to release the driver resources and exit the vibrator driver model. The vibrator driver model uses the HCS as the configuration source code. For details about HCS fields, see [Configuration Management](driver-hdf-manage.md). The driver entry function is defined as follows:
```c
/* Register the entry structure object of the vibrator abstract driver. */
struct HdfDriverEntry g_vibratorDriverEntry = {
.moduleVersion = 1, // Version of the vibrator module.
.moduleVersion = 1, // Vibrator module version.
.moduleName = "HDF_VIBRATOR", // Vibrator module name, which must be the same as moduleName in the device_info.hcs file.
.Bind = BindVibratorDriver, // Function for binding a vibrator.
.Init = InitVibratorDriver, // Function for initializing a vibrator.
.Release = ReleaseVibratorDriver, // Function for releasing vibrator resources.
.Bind = BindVibratorDriver, // Bind function for the vibrator driver.
.Init = InitVibratorDriver, // Ini function for the vibrator driver.
.Release = ReleaseVibratorDriver, // Release function for the vibrator driver.
};
/* Call HDF_INIT to register the driver entry with the HDF. */
HDF_INIT(g_vibratorDriverEntry);
```
- Develop the vibrator abstract driver. Specifically, implement the **Bind**, **Init**, **Release**, and **Dispatch** functions.
```c
/* Message exchange capability of the vibrator driver. */
/* External service published by the vibrator driver. */
@@ -155,15 +165,16 @@ The vibrator driver model provides APIs for the upper-layer hardware service to
hostName = "vibrator_host";
device_vibrator :: device {
device0 :: deviceNode {
policy = 2; // Policy for publishing the driver service.
priority = 100; // Driver startup priority (0–200). A larger value indicates a lower priority. The default value 100 is recommended. The sequence for loading devices with the same priority is random.
preload = 0; // Whether to load the driver on demand. The value 0 means to load the driver on demand, and 2 means the opposite.
permission = 0664; // Permission for the driver to create a device node.
moduleName = "HDF_VIBRATOR"; // Driver name, which must be the same as moduleName in the driver entry structure.
serviceName = "hdf_misc_vibrator"; // Name of the service provided by the driver. The name must be unique.
policy = 2; // Policy for the driver to publish services.
priority = 100; // Priority (0–200) for starting the vibrator driver. A larger value indicates a lower priority. The recommended value is 100. If the priorities are the same, the device loading sequence is not ensured.
preload = 0; // The value 0 means to load the driver by default during the startup of the system. The value 2 means the opposite.
permission = 0664; // Permission for the device node created.
moduleName = "HDF_VIBRATOR"; // Vibrator driver name. It must be the same as moduleName in the driver entry structure.
serviceName = "hdf_misc_vibrator"; // Service published by the vibrator driver. The service name must be unique.
deviceMatchAttr = "hdf_vibrator_driver"; // Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver.
}
}
}
```
2. Create a vibrator haptic model and parse the haptic HCS.
...
...
@@ -204,21 +215,21 @@ The vibrator driver model provides APIs for the upper-layer hardware service to
- The vibrator haptic model uses the HCS. For details about the HCS fields, see [Configuration Management](driver-hdf-manage.md).
```hcs
```c
/* Vibrator data configuration template (vibrator_config.hcs). */
root {
vibratorConfig {
boardConfig {
match_attr = "hdf_vibrator_driver"; // The value must be the same as that of the match_attr field configured for the vibrator.
match_attr = "hdf_vibrator_driver"; // The value must be the same as that of match_attr in the vibrator device configuration file.
vibratorAttr {
/* The value 0 means a rotor vibrator, and 1 means a linear vibrator. */
deviceType = 1; // Device type.
supportPreset = 1; // Supported preset type.
upportPreset = 1; // Supported preset type.
}
vibratorHapticConfig {
haptic_clock_timer {
effectName = "haptic.clock.timer";
type = 1; // The value 0 means the built-in mode, and 1 means the time sequence.
type = 1; // The value 0 indicates the built-in mode, and 1 indicates the time sequence.
seq = [600, 600, 200, 600]; // Time sequence.
}
haptic_default_effect {
...
...
@@ -232,12 +243,12 @@ The vibrator driver model provides APIs for the upper-layer hardware service to
}
```
3.Develop the interfaces for starting and stopping vibration. A timer will be created and destroyed based on the vibration effect.
3.Implement the APIs for obtaining vibrator information, triggering and stopping a vibration, and creating and destroying a timer based on the vibration mode.
The vibrator hardware service calls **StartOnce** to start one-shot vibration with a given duration and calls **StartEffect** to start vibration with a specified effect.
The vibrator hardware service calls **StartOnce** to start a one-shot vibration with a given duration and calls **StartEffect** to start vibration with a specified effect.
```c
/* Trigger vibration with a given duration. */
/* Trigger a one-short vibration with a given duration. */
@@ -472,9 +483,9 @@ The vibrator driver model provides APIs for the upper-layer hardware service to
### Verification
After the driver is developed, develop test cases in the sensor unit test to verify the basic functions of the driver. Use the developer self-test platform as the test environment.
After the driver is developed, develop test cases in the vibrator unit test to verify the basic functionalities of the driver. Use your own platform as the test environment.
```
```c++
/* Initialize the vibrator interface instance before executing test cases. */