The Liquid Crystal Display (LCD) driver performs operations such as powering on the LCD and initializing the internal registers of the driver integrated circuits (ICs).
The display driver model based on the [Hardware Driver Foundation (HDF)](../driver/driver-hdf-overview.md) provides the following functions:
The display driver model based on the [Hardware Driver Foundation (HDF)](driver-overview-foundation.md) provides the following functions:
- Provides a basic framework for LCD driver development to improve development efficiency.
...
...
@@ -62,11 +62,13 @@ Before applying your device with OpenHarmony system, you need to perform LCD dri
### Available APIs
To adjust the parameters of the LCD, establish a display channel with the display, and implement the display effect, use **display::host** to register the **PanelInfo** struct and interface information and add device description.
2. Adapt the driver to the chip at the SoC adapter layer.
3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for:
3. Add the LCD panel driver and register the panel driver data in the driver entry function **Init**. The driver data interface implements the following features:
- Powering on/off the LCD device
Based on the LCD hardware connection, use the GPIO APIs provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier.
Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier.
4. (Optional) Implement other HDF APIs, such as **Release()**, as required.
4. (Optional) Implement other HDF interfaces as required.
5. (Optional) Create other device nodes for implementing service logic or debugging based on the HDF as required.
...
...
@@ -136,7 +138,7 @@ The following uses the Hi35xx series chips as an example to describe how to perf
}
```
2. Configure the chip platform driver information in the **drivers/hdf_core/framework/model/display/driver/adapter_soc/hi35xx_disp.c file**.
2. Configure the chip platform driver information in **drivers/hdf_core/framework/model/display/driver/adapter_soc/hi35xx_disp.c**.
```c++
/* Configuration of the display driver to adapt to the MIPI and chip platform */
...
...
@@ -179,9 +181,9 @@ The following uses the Hi35xx series chips as an example to describe how to perf
}
```
3. Add a device in **drivers/hdf_core/framework/model/display/driver/panel/mipi_icn9700.c**.
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.
...
...
@@ -21,7 +21,7 @@ The figure below shows 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.
The following describes how to start and run the light module driver on an RK3568 board that runs the standard system.
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.
...
...
@@ -42,17 +42,74 @@ The light driver model provides APIs for obtaining information about all the lig
**Table 1** APIs of the light driver model
**NOTE**<br>The following APIs are C interfaces. For details about the interface declaration, see [/drivers/peripheral/light/interfaces/include](https://gitee.com/openharmony/drivers_peripheral/tree/master/light/interfaces/include).
| 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. |
| int32_t (*GetLightInfo)(struct LightInfo **lightInfo, 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)(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 light effect.|
| int32_t (*TurnOffLight)(uint32_t lightId) | Turns off available lights in the list based on the specified light type. |
| int32_t (*TurnOnMultiLights)(uint32_t lightId, const struct LightColor *colors, const uint32_t count); | Turns on multiple sub-lights of a light based on the specified light type ID. |
### How to Develop
Develop the light driver based on the HDF and driver entry, configure resources, and parse the HCS configuration file.
1. Configure the light driver in the host.
### 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-hdf-manage.md). The light driver entry is defined as follows:
- The code is as follows:
```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. 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 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.
lightId = [1]; // Lightid can contain multiple logical light IDs. For example, 1 indicates the power indicator.
lightName = "battery";
lightNumber = 1;
busRNum = 147; // GPIO value corresponding to red (light effect color).
busGNum = 146; // GPIO value corresponding to green (light effect color).
busBNum = 149; // GPIO value corresponding to blue (light effect color).
defaultBrightness = 0X00FFFFFF; // Default luminance value of the system. B: bits 0 to 7; R: bits 8 to 15; G: bits 16 to 23; extended bits 24 to 31.
onTime = 50; // Minimum duration (in milliseconds) supported by the system when the flash is on.
offTime = 50; // Minimum duration (in milliseconds) supported by the system when the flash is off.
}
}
}
}
}
```
3. Implement the light driver in **drivers\hdf_core\framework\model\misc\light\driver\src\light_driver.c**.
- Define the **HdfDriverEntry** object of the light driver. The driver entry function is defined as follows:
```c
/* Register the light entry data structure object. */
...
...
@@ -63,36 +120,13 @@ The light driver model provides APIs for obtaining information about all the lig
.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. */
/* 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 calls Release() to release resources and exit. */
HDF_INIT(g_lightDriverEntry);
```
-Develop the light abstract driver. Specifically, implement the **Bind**, **Init**, **Release**, and **Dispatch** functions.
if (OsalMutexInit(&drvData->mutex) != HDF_SUCCESS) {
return HDF_FAILURE;
}
/* Initialize the workqueue. */
if (HdfWorkQueueInit(&drvData->workQueue, LIGHT_WORK_QUEUE_NAME) != HDF_SUCCESS) {
HDF_LOGE("%s: init workQueue fail!", __func__);
return HDF_FAILURE;
}
/* Initialize work items. */
if (HdfWorkInit(&drvData->work, LightWorkEntry, (void*)drvData) != HDF_SUCCESS) {
HDF_LOGE("%s: init work fail!", __func__);
return HDF_FAILURE;
}
/* Parse the HCS. */
if (GetLightConfigData(device->property) != HDF_SUCCESS) {
HDF_LOGE("%s: get light config fail!", __func__);
return HDF_FAILURE;
}
/* Set the GPIO pin direction. */
if (SetLightGpioDir(drvData) != HDF_SUCCESS) {
HDF_LOGE("%s: set light gpio dir fail!", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
```
- Implement **Release()** of the light driver. When the driver is unloaded or **Init** fails to be executed, **Release()** can be used to release resources. The implementation is as follows:
```c
/* Release the resources allocated for driver initialization. */
for (i = LIGHT_TYPE_NONE; i < LIGHT_TYPE_BUTT; ++i) {
for (i = LIGHT_ID_NONE; i < LIGHT_ID_BUTT; ++i) {
if (drvData->info[i] != NULL) {
OsalMemFree(drvData->info[i]);
drvData->info[i] = NULL;
}
}
/* Destroy workqueue resources. */
/* Destroy the work queue resource if the sensor is in position. */
HdfWorkDestroy(&drvData->work);
HdfWorkQueueDestroy(&drvData->workQueue);
(void)OsalMutexDestroy(&drvData->mutex);
...
...
@@ -159,194 +204,584 @@ The light driver model provides APIs for obtaining information about all the lig
}
```
- 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.
- The light driver parses the light device management configuration information from the HCS file.
```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. 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.
/* Obtain the Light basic configuration from the HCS file. */
HDF_LOGE("%s: get light base config fail", __func__);
return HDF_FAILURE;
}
}
.....
return HDF_SUCCESS;
}
```
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.
- Use the internal APIs of the light driver to obtain the light type information, set the blinking mode, turn on and trun off lights, and create and destroy timers based on the blinking mode.
- The **GetAllLightInfo** interface is implemented as follows:
```c
/* Call GetAllLightInfo() to obtain the light types, call TurnOnLight() to turn on lights,
and call TurnOffLight() to turn off lights. */
/* The light driver service calls GetAllLightInfo() to obtain the light type information. */
/* 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.
if (!HdfSbufReadBuffer(data, (const void **)&buf, &len)) {
HDF_LOGE("%s: light read data failed", __func__);
return HDF_FAILURE;
}
/* Receive the lightBrightness value passed in. Bits 24 to 31 indicate 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.
Set the light brightness to a value ranging from 0 to 255 if supported. */
/* If the specified blinking duration is less than the minimum time period supported by the system, the time configured by the system (in HCS) is used. */
if (!HdfSbufWriteInt32(sbuf, LIGHT_OPS_IO_CMD_ENABLE_MULTI_LIGHTS)) {
ret = HDF_FAILURE;
goto EXIT;
}
if (!HdfSbufWriteBuffer(sbuf, colors, sizeof(*colors))) {
ret = HDF_FAILURE;
goto EXIT;
}
if (!HdfSbufWriteInt32(sbuf, count)) {
ret = HDF_FAILURE;
goto EXIT;
}
ret = SendLightMsg(LIGHT_IO_CMD_OPS, sbuf, NULL);
if (ret != HDF_SUCCESS) {
}
return ret;
EXIT:
HdfSbufRecycle(sbuf);
(void)OsalMutexUnlock(&priv->mutex);
}
```
### Verification
After the driver is developed, develop auto-test cases in the light unit test to verify the basic functionalities of the driver. Use the developer self-test platform as the test environment.
```c++
/* Initialize the LightInterfaceInstance before executing the test case. */
voidHdfLightTest::SetUpTestCase()
{
- The reference test code is as follows:
```c
#include <cmath>
#include <cstdio>
#include <gtest/gtest.h>
#include <securec.h>
#include "hdf_base.h"
#include "osal_time.h"
#include "osal_mem.h"
#include "light_if.h"
#include "light_type.h"
usingnamespacetesting::ext;
conststructLightInterface*g_lightDev=nullptr;
staticstructLightInfo*g_lightInfo=nullptr;
staticuint32_tg_count=0;
/* Initialize the LightInterfaceInstance before executing the test case. */
classHdfLightTest:publictesting::Test{
public:
staticvoidSetUpTestCase();
staticvoidTearDownTestCase();
voidSetUp();
voidTearDown();
};
voidHdfLightTest::SetUpTestCase()
{
g_lightDev=NewLightInterfaceInstance();
if(g_lightDev==nullptr){
printf("test light get Module instance fail\n\r");
@@ -23,7 +23,7 @@ The figure below illustrates how a motion driver works.

1. MSDP: The MSDP service obtains a Motion HDI service instance from the Motion Proxy and calls the Motion HDI API.
2. IDL: The IService Manager allocates a Motion HDI instance requested by the MSDP service, and the Motion Proxy forwards the instance to the MSDP service. After the MSDP service calls the HDI API provided by the Motion Proxy, Motion Stub is called through Inter-Process Communication (IPC) to invoke the Motion Service API. The code is automatically generated by a tool and does not need to be developed by the component vendor.
2. IDL: The MSDP service obtains a Motion HDI service instance from the Motion Proxy and calls the Motion HDI API. The interface instance is allocated by IService Manager. After the MSDP service calls the HDI API provided by the Motion Proxy, Motion Stub is called through Inter-Process Communication (IPC) to invoke the Motion Service API. The code is automatically generated by a tool and does not need to be developed by the component vendor.
3. HDI Service: The HDI service consists of Motion Interface Driver, Motion Service, and Motion Impl. Motion Interface Driver provides the motion driver code. A **HdfDriverEntry** structure is defined to implement the **Init**, **Bind**, and **Release** functions. The **HDF_INIT** macro is used to load the driver in the functions. Motion Service provides the motion recognition service interface class. The specific implementation is described in Motion Impl. The code of HDI Service must be developed by the component vendor.
## Development Guidelines
...
...
@@ -36,6 +36,8 @@ The motion driver provides capabilities for the MSDP service to enable or disabl
**Table 1** Available APIs
**NOTE**<br>The following table lists the C++ function interfaces generated by the IDL interface description. For details about the interface declaration, see the IDL file [/drivers/interface/motion/v1_0/](https://gitee.com/openharmony/drivers_interface/tree/master/motion).
| int32_t EnableMotion(int32_t motionType) | Enables motion recognition of the specified type. The motion recognition data can be obtained only after the motion recognition is enabled.|
...
...
@@ -48,29 +50,30 @@ The motion driver provides capabilities for the MSDP service to enable or disabl
The development procedure is as follows:
1. Develop the user-mode driver for motion recognition based on the HDF.
2. Implement the **EnableMotion**, **DisableMotion**, **Register**, and **Unregister** APIs.
The motion recognition directory structure is as follows:
```undefined
/drivers/peripheral/motion # Developed by the vendor.
├── hdi_service # Driver capabilities provided by the motion recognition module for the MSDP service layer.
├── test # Test code for the motion recognition module.
│ └── unittest\hdi # HDI unit test code for the motion recognition module.
```
/drivers/peripheral/motion // Developed by the vendor.
├── hdi_service // Driver capability provided by the motion module for upper-layer services.
├── test // Test codes for the motion module.
│ └── unittest\hdi // HDI unit test code of the motion driver module.
```
The following describes how to develop a user-mode motion driver based on the HDF. For details, see [motion_interface_driver.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/motion/hdi_service/motion_interface_driver.cpp).
The following describes how to develop a user-mode motion driver based on the HDF. For details, see [motion_if_driver.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/motion/hdi_service/motion_if_driver.cpp).
You need to implement the **Bind()**, **Init()**, **Release()**, and **Dispatch()** functions. The **Bind()** function binds the service capability with the driver; **Init()** implements the initialization required before the driver is loaded; **Release()** reclaims resources when **Init()** fails; **Dispatch()** implements the service, which is bound in **Bind()**.
```c++
// Custom HdfMotionInterfaceHost object
```c
/* Custom HdfMotionInterfaceHost object. */
structHdfMotionInterfaceHost{
structIDeviceIoServiceioService;
OHOS::sptr<OHOS::IRemoteObject>stub;
};
// Enable the IPC service to call the response API.
/* Enable the IPC service to call the response API. */
// Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind function and then the Init function. If the Init function fails to be called, the HDF will call Release to release driver resources and exit the driver model.
/* Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind function and then the Init function. If the Init function fails to be called, the HDF will call Release to release driver resources and exit the driver model. */
The following uses the acceleration sensor driver on the Hi3516D V300 development board of the standard system as an example to describe the driver loading and running process.
The following uses the acceleration sensor driver on the RK3568 development board of the standard system as an example to describe the driver loading and running process.
1. The sensor host reads the sensor device management configuration from **Sensor Host** in the **device_info.hcs** file.
2. The sensor host parses the sensor management configuration from the HCB database and associates the configuration with the sensor driver.
...
...
@@ -44,7 +44,7 @@ The following uses the acceleration sensor driver on the Hi3516D V300 developmen
### When to Use
- Data provided by the gravity and gyroscope sensors denotes the tilt and rotation of the device, which helps your application improve user experience in games.
- Data provided by the gravity and gyroscope sensors denotes the tilt and rotation of the device, which helps improve user experience in games.
- Data provided by the proximity sensor denotes the distance between the device and a visible object, which enables the device to automatically turn on or off its screen accordingly to prevent accidental touch on the screen. For example, when the proximity sensor detects the user face approaches the earpiece during a call, it triggers backlight of the screen to be turned off. This prevents the screen from being accidentally touched and further reduces power consumption.
- Data provided by the barometric pressure sensor helps your application accurately determine the altitude of the device.
- Data provided by the ambient light sensor helps your device automatically adjust its backlight.
...
...
@@ -55,19 +55,17 @@ The following uses the acceleration sensor driver on the Hi3516D V300 developmen
The sensor driver model offers the following APIs:
- Sensor HDI APIs, for easier sensor service development
- APIs for implementing sensor driver model capabilities
- APIs for loading, registering, and deregitering sensor drivers, and detecting sensors based on the HDF
- APIs for loading, registering, and deregistering sensor drivers, and detecting sensors based on the HDF.
- Unified driver API, register configuration parsing API, bus access abstract API, and platform abstract API for the same type of sensors
- APIs to be implemented by developers
Based on the HDF Configuration Source (HCS) and differentiated configuration for sensors of the same type, you need to implement serialized configuration of sensor device parameters and some sensor device operation interfaces to simplify sensor driver development.
- APIs to be implemented by developers: Based on the HDF Configuration Source (HCS) and differentiated configuration for sensors of the same type, developers need to implement serialized configuration of sensor device parameters and some sensor device operation interfaces to simplify sensor driver development.
The sensor driver model provides APIs for the hardware service to make sensor service development easier. See the table below.
**Table 1** APIs of the sensor driver model
**NOTE**<br>The following APIs are C interfaces. For details about the interface declaration, see [/drivers/peripheral/sensor/interfaces/include](https://gitee.com/openharmony/drivers_peripheral/tree/master/sensor/interfaces/include).
| API| Description|
| ----- | -------- |
| int32_t GetAllSensors(struct SensorInformation **sensorInfo, int32_t *count) | Obtains information about all registered sensors in the system. The sensor information includes the sensor name, sensor vendor, firmware version, hardware version, sensor type ID, sensor ID, maximum range, accuracy, and power consumption.|
...
...
@@ -79,8 +77,6 @@ The sensor driver model provides APIs for the hardware service to make sensor se
| int32_t Register(int32_t groupId, RecordDataCallback cb) | Registers a sensor data callback based on the group ID.|
| int32_t Unregister(int32_t groupId, RecordDataCallback cb) | Deregisters a sensor data callback based on the group ID.|
The sensor driver model provides driver development APIs that do not require further implementation. See the table below.
**Table 2** Sensor driver development APIs
...
...
@@ -99,8 +95,6 @@ The sensor driver model provides driver development APIs that do not require fur
| int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg) | Obtains the sensor bus handle information.|
| int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg) | Releases the sensor bus handle information.|
The sensor driver model also provides certain driver development APIs that need to be implemented by driver developers. See the table below.
**Table 3** APIs to be implemented by driver developers
...
...
@@ -113,18 +107,42 @@ The sensor driver model also provides certain driver development APIs that need
| int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval) | Sets the processing time of the data reporting thread for the current sensor based on the sampling interval and data reporting interval.|
| int32_t SetMode(int32_t mode) | Sets the data reporting mode of the current sensor device.|
| int32_t SetOption(uint32_t option) | Sets the register configuration such as the range and accuracy based on sensor options.|
For details about the interface implementation, see [How to Develop](#how-to-develop).
### How to Develop
1. Develop the acceleration sensor abstract driver. Specifically, implement the **Bind**, **Init**, **Release**, and **Dispatch** functions.
The following describes how to develop an acceleration sensor driver based on the HDF and the driver entry. Sensor driver development includes abstracted driver development and differentiated driver development. The abstracted driver development implements the common interfaces for different devices with the same sensor ID. The differentiated driver development implements device-specific interfaces.
1. Develop the abstracted driver of the acceleration sensor.
- Configure the host information for the abstracted driver of the acceleration sensor in **vendor\hihope\rk3568\hdf_config\khdf\device_info\device_info.hcs**.
The code is as follows:
```c
/* Device information HCS configuration of the acceleration sensor. */
device_sensor_accel :: device {
device0 :: deviceNode {
policy = 1; // Policy for the driver to publish services.
priority = 100; // Priority (0–200) for starting the 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_SENSOR_ACCEL"; // Driver name. It must be the same as moduleName in the driver entry structure.
serviceName = "sensor_accel"; // Name of the service published by the driver. The name must be unique.
deviceMatchAttr = "hdf_sensor_accel_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.
}
}
```
- Implement the entry function for the acceleration sensor.
- Implement the abstracted driver of the acceleration sensor in **drivers\hdf_core\framework\model\sensor\driver\accel\sensor_accel_driver.c**.
- Define the **HdfDriverEntry** object of the abstracted driver. The driver entry function is defined as follows:
```c
/* Register the entry structure object of the acceleration sensor. */
struct HdfDriverEntry g_sensorAccelDevEntry = {
.moduleVersion = 1, // Version of the acceleration sensor module.
.moduleVersion = 1, // Version of the accelerometer sensor module.
.moduleName = "HDF_SENSOR_ACCEL", // Name of the acceleration sensor module. The value must be the same as that of moduleName in the device_info.hcs file.
.Bind = BindAccelDriver, // Function for binding an acceleration sensor.
.Init = InitAccelDriver, // Function for initializing an acceleration sensor.
...
...
@@ -135,10 +153,9 @@ The sensor driver model also provides certain driver development APIs that need
HDF_INIT(g_sensorAccelDevEntry);
```
- Implement interfaces for acceleration sensor driver operations.
- Implement **Bind()** for the abstracted driver of the acceleration sensor.
```c
/* Bind the service provided by the acceleration sensor driver to the HDF. */
/* Provide the initialization interface for the chipset driver to parse the basic acceleration sensor configuration (acceleration information, bus configuration, and sensor detection register configuration), detect sensors, and parse sensor registers. */
```
- Implement **Release()** for the abstracted driver of the acceleration sensor. When the driver is unloaded or **Init()** fails, **Release()** can be used to release resources.
/* Release the resources if the sensor is in position. */
if (drvData->detectFlag && drvData->accelCfg != NULL) {
AccelReleaseCfgData(drvData->accelCfg);
}
OsalMemFree(drvData->accelCfg);
drvData->accelCfg = NULL;
/* Destroy the work queue resource if the sensor is in position. */
HdfWorkDestroy(&drvData->accelWork);
HdfWorkQueueDestroy(&drvData->accelWorkQueue);
OsalMemFree(drvData);
}
```
- Implement the internal interfaces for the abstracted driver of the acceleration sensor.
- Implement the initialization interface provided for the differentiated driver. This interface parses the basic configuration information (acceleration sensor information, acceleration sensor bus configuration, and acceleration sensor detection register configuration) of the acceleration sensor, detects devices, and parses the device register. The initialization interface is implementation is as follows:
@@ -216,90 +284,34 @@ The sensor driver model also provides certain driver development APIs that need
HDF_LOGE("%s: Get sensor base config failed", __func__);
goto BASE_CONFIG_EXIT;
}
/* Continue the next detection if the sensor is not detected. */
/* If the device is not in position (the device ID exists), return to detect the next device. */
if (DetectSensorDevice(drvData->accelCfg) != HDF_SUCCESS) {
HDF_LOGI("%s: Accel sensor detect device no exist", __func__);
drvData->detectFlag = false;
goto BASE_CONFIG_EXIT;
}
drvData->detectFlag = true;
/* Parse the sensor register. */
drvData->detectFlag = true;
if (InitAccelAfterDetected(drvData->accelCfg) != HDF_SUCCESS) {
HDF_LOGE("%s: Accel sensor detect device no exist", __func__);
goto INIT_EXIT;
}
return drvData->accelCfg;
...
}
/* The entry function of the acceleration sensor driver is used to initialize the sensor private data structure object, allocate space for the sensor HCS data configuration object, call the entry function for initializing the sensor HCS data configuration, detect whether the sensor device is in position, create a timer for sensor data reporting, register the sensor normalization APIs, and register the sensor device. */
/* Release the resources if the sensor is in position. */
if (drvData->detectFlag) {
AccelReleaseCfgData(drvData->accelCfg);
}
OsalMemFree(drvData->accelCfg);
drvData->accelCfg = NULL;
/* Destroy the work queue resource if the sensor is in position. */
HdfWorkDestroy(&drvData->accelWork);
HdfWorkQueueDestroy(&drvData->accelWorkQueue);
OsalMemFree(drvData);
}
```
2. Configure the device information about the acceleration sensor driver.
The acceleration sensor model uses the HCS as the configuration source code. For details about the HCS configuration fields, see [Driver Configuration Management](driver-hdf-manage.md).
```hcs
/* Device information HCS configuration of the acceleration sensor. */
device_sensor_accel :: device {
device0 :: deviceNode {
policy = 1; // Policy for the driver to publish services.
priority = 100; // Priority (0–200) for starting the 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_SENSOR_ACCEL"; // Driver name. It must be the same as moduleName in the driver entry structure.
serviceName = "sensor_accel"; // Name of the service published by the driver. The name must be unique.
deviceMatchAttr = "hdf_sensor_accel_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.
3. Develop the internal interfaces of the acceleration sensor abstract driver. Specifically, implement the **Enable**, **Disable**, **SetBatch**, **SetMode**, **SetOption**, **AccelCreateCfgData**, **AccelReleaseCfgData**, and **AccelRegisterChipOps** functions.
if (mode <= SENSOR_WORK_MODE_DEFAULT || mode >= SENSOR_WORK_MODE_MAX) {
HDF_LOGE("%s: The current mode is not supported", __func__);
return HDF_FAILURE;
}
staticint32_tSetAccelOption(uint32_toption)
{
(void)option;
return HDF_SUCCESS;
}
/* Set the sensor options. */
```
- Implement **SetOption()** as follows.
```c
static int32_t SetAccelOption(uint32_t option)
{
(void)option;
returnHDF_ERR_NOT_SUPPORT;
return HDF_SUCCESS;
}
```
4. Develop the acceleration sensor chipset driver. Specifically, implement the **Bind**, **Init**, **Release**, and **Dispatch** functions.
2. Develop the differentiated drivers for acceleration sensors.
- Configure the host information for the differentiated driver of the acceleration sensor in **vendor\hihope\rk3568\hdf_config\khdf\device_info\device_info.hcs**.
The code is as follows:
```c
/* Message interaction of the acceleration sensor chipset driver */
policy = 1; // Policy for publishing drive services.
priority = 120; // 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_SENSOR_ACCEL_MXC6655XA"; // Driver name, which must be the same as moduleName in the driver entry structure.
serviceName = "hdf_accel_mxc6655xa"; // Name of the service published by acceleration mxc6655xa. It must be unique.
deviceMatchAttr = "hdf_sensor_accel_mxc6655xa_driver"; // Keyword for matching the private data of the driver. The value must be the same as the match_attr value in the private data configuration table of the driver.
}
}
```
returnHDF_SUCCESS;
- Configure the private HCS for the differentiated driver of the acceleration sensor.
.moduleVersion = 1, // Module version of the mxc6655xa acceleration sensor.
.moduleName = "HDF_SENSOR_ACCEL_MXC6655XA", // Module name of the mxc6655xa acceleration sensor. The value must be the same as the value of moduleName of the acceleration sensor in the device_info.hcs file.
.Bind = Mxc6655xaBindDriver, // Bind function of the mxc6655xa acceleration sensor.
.Init = Mxc6655xaInitDriver, // Init function of the mxc6655xa acceleration sensor.
.Release = Mxc6655xaReleaseDriver, // Release function of the mxc6655xa acceleration sensor.
};
/* 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 calls Release() to release resources and exit. */
HDF_INIT(g_accelMxc6655xaDevEntry);
```
- Implement **Bind()** for the differentiated driver as follows.
x = SensorConvertData(reg[ACCEL_X_AXIS_MSB], reg[ACCEL_X_AXIS_LSB]);
y = SensorConvertData(reg[ACCEL_Y_AXIS_MSB], reg[ACCEL_Y_AXIS_LSB]);
z = SensorConvertData(reg[ACCEL_Z_AXIS_MSB], reg[ACCEL_Z_AXIS_LSB]);
rawData->x = x;
rawData->y = y;
rawData->z = z;
return HDF_SUCCESS;
}
/* Read the event data of the accelerator. Register this function in Mxc6655xaInitDriver() to pass in the data to the abstracted driver of the acceleration sensor. */
ret = SensorRawDataToRemapData(cfg->direction, tmp, sizeof(tmp) / sizeof(tmp[0]));
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: BMI160 report data failed",__func__);
HDF_LOGE("%s: MXC6655XA convert raw data failed", __func__);
return HDF_FAILURE;
}
event->dataLen = sizeof(tmp);
event->data = (uint8_t *)&tmp;
return ret;
}
```
### Verification
After the driver is developed, develop test cases in the sensor unit test to verify the basic functions of the driver. Use your test platform to set up the test environment.
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.
```c++
staticint32_tg_sensorDataFlag=0;// Whether to report sensor data.
staticconststructSensorInterface*g_sensorDev=nullptr;// Retain the obtained sensor interface instance address.