1e41f4b71Sopenharmony_ci# Sensor
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## Overview
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci### Function
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ciThe sensor driver model shields the hardware difference and provides interfaces for the upper-layer sensor service to implement basic sensor capabilities, including querying the sensor list, enabling or disabling a sensor, subscribing to or unsubscribing from sensor data changes, and setting sensor attributes. Developed based on the Hardware Driver Foundation (HDF), the sensor driver model leverages the capabilities of the OS adaptation layer (OSAL) and platform driver interfaces (such as I2C, SPI, and UART buses) to shield the difference between OSs and platform bus resources, achieving "one-time development and multi-system deployment" of the sensor driver. The figure below shows the architecture of the sensor driver model.
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci**Figure 1** Sensor driver model
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci![Sensor driver model](figures/sensor_driver_model.png)
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci### Basic Concepts
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ciCurrently, sensors are classified into the following types by sensor ID:
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci- Medical sensors: The sensor IDs range from 128 to 160.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci- Traditional sensors: The sensor IDs are out of the range of 128 to 160.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci### Working Principles
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ciThe following figure shows how a sensor driver works.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci**Figure 2** How a sensor driver works
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci![How sensor driver works](figures/sensor_working.png)
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ciThe 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.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci1. The sensor host reads the sensor device management configuration from **Sensor Host** in the **device_info.hcs** file.
33e41f4b71Sopenharmony_ci2. The sensor host parses the sensor management configuration from the HCB database and associates the configuration with the sensor driver.
34e41f4b71Sopenharmony_ci3. The sensor host loads and initializes the sensor manager driver.
35e41f4b71Sopenharmony_ci4. The sensor manager driver publishes the sensor APIs for the hardware driver interface (HDI).
36e41f4b71Sopenharmony_ci5. The sensor host reads the acceleration sensor driver configuration information from **Sensor Host** in the **device_info.hcs** configuration file.
37e41f4b71Sopenharmony_ci6. The sensor host loads the acceleration sensor abstract driver and calls the initialization interface to allocate the sensor driver resources and create the data processing queue.
38e41f4b71Sopenharmony_ci7. The sensor host reads the chipset driver configuration and private configuration of the acceleration sensor from the **accel_xxx_config.hcs** file.
39e41f4b71Sopenharmony_ci8. The acceleration sensor chipset driver calls the common configuration parsing interface to parse the sensor attributes and registers.
40e41f4b71Sopenharmony_ci9. The chipset driver detects sensors, allocates configuration resources to the acceleration sensor, and registers the acceleration sensor chipset interfaces.
41e41f4b71Sopenharmony_ci10. Upon successful sensor detection, the chipset driver instructs the abstract driver to register the acceleration sensor to the sensor manager driver.
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci## Development Guidelines
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci### When to Use
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci- Data provided by the gravity and gyroscope sensors denotes the tilt and rotation of the device, which helps improve user experience in games.
48e41f4b71Sopenharmony_ci- 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.
49e41f4b71Sopenharmony_ci- Data provided by the barometric pressure sensor helps your application accurately determine the altitude of the device.
50e41f4b71Sopenharmony_ci- Data provided by the ambient light sensor helps your device automatically adjust its backlight.
51e41f4b71Sopenharmony_ci- Data provided by the Hall effect sensor implements the smart cover mode of your device. When the smart cover is closed, a small window is opened on the phone to reduce power consumption. 
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci### Available APIs
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ciThe sensor driver model offers the following APIs:
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci- Sensor HDI APIs, for easier sensor service development
58e41f4b71Sopenharmony_ci- APIs for implementing sensor driver model capabilities
59e41f4b71Sopenharmony_ci  - APIs for loading, registering, and deregistering sensor drivers, and detecting sensors based on the HDF.
60e41f4b71Sopenharmony_ci  - Unified driver API, register configuration parsing API, bus access abstract API, and platform abstract API for the same type of sensors
61e41f4b71Sopenharmony_ci- 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.
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ciThe sensor driver model provides APIs for the hardware service to make sensor service development easier. See the table below.
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci**Table 1** APIs of the sensor driver model
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci**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).
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci| API| Description|
70e41f4b71Sopenharmony_ci| ----- | -------- |
71e41f4b71Sopenharmony_ci| 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.|
72e41f4b71Sopenharmony_ci| int32_t Enable(int32_t sensorId) | Enables a sensor. The subscriber can obtain sensor data only after the sensor is enabled.|
73e41f4b71Sopenharmony_ci| int32_t Disable(int32_t sensorId) | Disables a sensor.|
74e41f4b71Sopenharmony_ci| int32_t SetBatch(int32_t sensorId, int64_t samplingInterval, int64_t reportInterval) | Sets the sampling interval and data reporting interval for a sensor.|
75e41f4b71Sopenharmony_ci| int32_t SetMode(int32_t sensorId, int32_t mode) | Sets the data reporting mode for a sensor.|
76e41f4b71Sopenharmony_ci| int32_t SetOption(int32_t sensorId, uint32_t option) | Sets options for a sensor, including its range and accuracy.|
77e41f4b71Sopenharmony_ci| int32_t Register(int32_t groupId, RecordDataCallback cb) | Registers a sensor data callback based on the group ID.|
78e41f4b71Sopenharmony_ci| int32_t Unregister(int32_t groupId, RecordDataCallback cb) | Deregisters a sensor data callback based on the group ID.|
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ciThe sensor driver model provides driver development APIs that do not require further implementation. See the table below.
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci **Table 2** Sensor driver development APIs
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci| API| Description|
85e41f4b71Sopenharmony_ci| ----- | -------- |
86e41f4b71Sopenharmony_ci| int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo) | Adds a sensor of the current type to the sensor management module.|
87e41f4b71Sopenharmony_ci| int32_t DeleteSensorDevice(const struct SensorBasicInfo *sensorBaseInfo) | Deletes a sensor from the sensor management module.|
88e41f4b71Sopenharmony_ci| int32_t ReportSensorEvent(const struct SensorReportEvent *events) | Reports data of a specified sensor type.|
89e41f4b71Sopenharmony_ci| int32_t ReadSensor(struct SensorBusCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen) | Reads sensor configuration data from the sensor register based on the bus configuration.|
90e41f4b71Sopenharmony_ci| int32_t WriteSensor(struct SensorBusCfg *busCfg, uint8_t *writeData, uint16_t len) | Writes sensor configuration data to the sensor register based on the bus configuration.|
91e41f4b71Sopenharmony_ci| int32_t SetSensorRegCfgArray(struct SensorBusCfg *busCfg, const struct SensorRegCfgGroupNode *group); | Sets the sensor register group configuration based on the sensor bus type.|
92e41f4b71Sopenharmony_ci| int32_t GetSensorBaseConfigData(const struct DeviceResourceNode *node, struct SensorCfgData *config) | Obtains basic configuration information such as sensor, bus, and attribute configurations based on the device information HCS configuration, and initializes the basic configuration data structure.|
93e41f4b71Sopenharmony_ci| int32_t ParseSensorRegConfig(struct SensorCfgData *config) | Parses the register group information based on the device information HCS configuration and initializes the configuration data structure.|
94e41f4b71Sopenharmony_ci| void ReleaseSensorAllRegConfig(struct SensorCfgData *config) | Releases the resources allocated to the sensor configuration data structure.|
95e41f4b71Sopenharmony_ci| int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg) | Obtains the sensor bus handle information.|
96e41f4b71Sopenharmony_ci| int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg) | Releases the sensor bus handle information.|
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ciThe sensor driver model also provides certain driver development APIs that need to be implemented by driver developers. See the table below.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci**Table 3** APIs to be implemented by driver developers
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci| API| Description|
103e41f4b71Sopenharmony_ci| ----- | -------- |
104e41f4b71Sopenharmony_ci| int32_t init(void) | Initializes the sensor device configuration after a sensor is detected.|
105e41f4b71Sopenharmony_ci| int32_t Enable(void) | Enables the current sensor by delivering the register configuration in the enabling operation group based on the device information HCS configuration.|
106e41f4b71Sopenharmony_ci| int32_t Disable(void) | Disables the current sensor by delivering the register configuration in the disabling operation group based on the device information HCS configuration.|
107e41f4b71Sopenharmony_ci| 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.|
108e41f4b71Sopenharmony_ci| int32_t SetMode(int32_t mode) | Sets the data reporting mode of the current sensor device.|
109e41f4b71Sopenharmony_ci| int32_t SetOption(uint32_t option) | Sets the register configuration such as the range and accuracy based on sensor options.|
110e41f4b71Sopenharmony_ci| void ReadSensorData(void) | Reads sensor data.                                            |
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ciFor details about the interface implementation, see [How to Develop](#how-to-develop).
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci### How to Develop
116e41f4b71Sopenharmony_ciThe 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.
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ci1. Develop the abstracted driver of the acceleration sensor.
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ci   - Configure the host information for the abstracted driver of the acceleration sensor in **vendor\hihope\rk3568\hdf_config\khdf\device_info\device_info.hcs**.
121e41f4b71Sopenharmony_ci
122e41f4b71Sopenharmony_ci     The code is as follows:
123e41f4b71Sopenharmony_ci
124e41f4b71Sopenharmony_ci     ```c
125e41f4b71Sopenharmony_ci     /* Device information HCS configuration of the acceleration sensor. */
126e41f4b71Sopenharmony_ci     device_sensor_accel :: device {
127e41f4b71Sopenharmony_ci         device0 :: deviceNode {
128e41f4b71Sopenharmony_ci             policy = 1;                                  // Policy for the driver to publish services.
129e41f4b71Sopenharmony_ci             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.
130e41f4b71Sopenharmony_ci             preload = 0;                                 // The value 0 means to load the driver by default during the startup of the system. The value 2 means the opposite.
131e41f4b71Sopenharmony_ci             permission = 0664;                           // Permission for the device node created.
132e41f4b71Sopenharmony_ci             moduleName = "HDF_SENSOR_ACCEL";             // Driver name. It must be the same as moduleName in the driver entry structure.
133e41f4b71Sopenharmony_ci             serviceName = "sensor_accel";                // Name of the service published by the driver. The name must be unique.
134e41f4b71Sopenharmony_ci             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.
135e41f4b71Sopenharmony_ci         }
136e41f4b71Sopenharmony_ci     } 
137e41f4b71Sopenharmony_ci     ```
138e41f4b71Sopenharmony_ci
139e41f4b71Sopenharmony_ci   - Implement the abstracted driver of the acceleration sensor in **drivers\hdf_core\framework\model\sensor\driver\accel\sensor_accel_driver.c**.
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci     - Define the **HdfDriverEntry** object of the abstracted driver. The driver entry function is defined as follows:
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci       ```c
144e41f4b71Sopenharmony_ci       struct HdfDriverEntry g_sensorAccelDevEntry = {
145e41f4b71Sopenharmony_ci           .moduleVersion = 1,                // Version of the accelerometer sensor module.
146e41f4b71Sopenharmony_ci           .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.
147e41f4b71Sopenharmony_ci           .Bind = BindAccelDriver,           // Function for binding an acceleration sensor.
148e41f4b71Sopenharmony_ci           .Init = InitAccelDriver,           // Function for initializing an acceleration sensor.
149e41f4b71Sopenharmony_ci           .Release = ReleaseAccelDriver      // Function for releasing acceleration sensor resources.
150e41f4b71Sopenharmony_ci       };
151e41f4b71Sopenharmony_ci       
152e41f4b71Sopenharmony_ci       /* 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. */
153e41f4b71Sopenharmony_ci       HDF_INIT(g_sensorAccelDevEntry);
154e41f4b71Sopenharmony_ci       ```
155e41f4b71Sopenharmony_ci
156e41f4b71Sopenharmony_ci     - Implement **Bind()** for the abstracted driver of the acceleration sensor.
157e41f4b71Sopenharmony_ci
158e41f4b71Sopenharmony_ci       ```c
159e41f4b71Sopenharmony_ci       int32_t AccelBindDriver(struct HdfDeviceObject *device)
160e41f4b71Sopenharmony_ci       {
161e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
162e41f4b71Sopenharmony_ci       
163e41f4b71Sopenharmony_ci           struct AccelDrvData *drvData = (struct AccelDrvData *)OsalMemCalloc(sizeof(*drvData));
164e41f4b71Sopenharmony_ci           if (drvData == NULL) {
165e41f4b71Sopenharmony_ci               HDF_LOGE("%s: Malloc accel drv data fail!", __func__);
166e41f4b71Sopenharmony_ci               return HDF_ERR_MALLOC_FAIL;
167e41f4b71Sopenharmony_ci           }
168e41f4b71Sopenharmony_ci       
169e41f4b71Sopenharmony_ci           drvData->ioService.Dispatch = DispatchAccel;
170e41f4b71Sopenharmony_ci           drvData->device = device;
171e41f4b71Sopenharmony_ci           device->service = &drvData->ioService;
172e41f4b71Sopenharmony_ci           g_accelDrvData = drvData;
173e41f4b71Sopenharmony_ci           return HDF_SUCCESS;
174e41f4b71Sopenharmony_ci       }
175e41f4b71Sopenharmony_ci       ```
176e41f4b71Sopenharmony_ci
177e41f4b71Sopenharmony_ci     - Implement **Init()** for the abstracted driver of the acceleration sensor.
178e41f4b71Sopenharmony_ci
179e41f4b71Sopenharmony_ci       ```c
180e41f4b71Sopenharmony_ci       int32_t AccelInitDriver(struct HdfDeviceObject *device)
181e41f4b71Sopenharmony_ci       {
182e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
183e41f4b71Sopenharmony_ci           struct AccelDrvData *drvData = (struct AccelDrvData *)device->service;
184e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
185e41f4b71Sopenharmony_ci       	 /* Initialize work queue resources. */
186e41f4b71Sopenharmony_ci           if (InitAccelData(drvData) != HDF_SUCCESS) {
187e41f4b71Sopenharmony_ci               HDF_LOGE("%s: Init accel config failed", __func__);
188e41f4b71Sopenharmony_ci               return HDF_FAILURE;
189e41f4b71Sopenharmony_ci           }
190e41f4b71Sopenharmony_ci       	/* Allocate acceleration configuration resources. */
191e41f4b71Sopenharmony_ci           drvData->accelCfg = (struct SensorCfgData            *)OsalMemCalloc(sizeof(*drvData->accelCfg));
192e41f4b71Sopenharmony_ci           if (drvData->accelCfg == NULL) {
193e41f4b71Sopenharmony_ci               HDF_LOGE("%s: Malloc accel config data failed", __func__);
194e41f4b71Sopenharmony_ci               return HDF_FAILURE;
195e41f4b71Sopenharmony_ci           }
196e41f4b71Sopenharmony_ci       	/* Register the register group information. */
197e41f4b71Sopenharmony_ci           drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0];
198e41f4b71Sopenharmony_ci           drvData->cb = NULL;
199e41f4b71Sopenharmony_ci       	
200e41f4b71Sopenharmony_ci           HDF_LOGI("%s: Init accel driver success", __func__);
201e41f4b71Sopenharmony_ci           return HDF_SUCCESS;
202e41f4b71Sopenharmony_ci       }
203e41f4b71Sopenharmony_ci       ```
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci     - 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.
206e41f4b71Sopenharmony_ci
207e41f4b71Sopenharmony_ci       ```c
208e41f4b71Sopenharmony_ci       void AccelReleaseDriver(struct HdfDeviceObject *device)
209e41f4b71Sopenharmony_ci       {
210e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN(device);
211e41f4b71Sopenharmony_ci       
212e41f4b71Sopenharmony_ci           struct AccelDrvData *drvData = (struct AccelDrvData *)device->service;
213e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN(drvData);
214e41f4b71Sopenharmony_ci       	/* Release the resources if the sensor is in position. */
215e41f4b71Sopenharmony_ci           if (drvData->detectFlag && drvData->accelCfg != NULL) {
216e41f4b71Sopenharmony_ci               AccelReleaseCfgData(drvData->accelCfg);
217e41f4b71Sopenharmony_ci           }
218e41f4b71Sopenharmony_ci       
219e41f4b71Sopenharmony_ci           OsalMemFree(drvData->accelCfg);
220e41f4b71Sopenharmony_ci           drvData->accelCfg = NULL;
221e41f4b71Sopenharmony_ci       	/* Destroy the work queue resource if the sensor is in position. */
222e41f4b71Sopenharmony_ci           HdfWorkDestroy(&drvData->accelWork);
223e41f4b71Sopenharmony_ci           HdfWorkQueueDestroy(&drvData->accelWorkQueue);
224e41f4b71Sopenharmony_ci           OsalMemFree(drvData);
225e41f4b71Sopenharmony_ci       }
226e41f4b71Sopenharmony_ci       ```
227e41f4b71Sopenharmony_ci
228e41f4b71Sopenharmony_ci     - Implement the internal interfaces for the abstracted driver of the acceleration sensor.
229e41f4b71Sopenharmony_ci
230e41f4b71Sopenharmony_ci       - 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:
231e41f4b71Sopenharmony_ci
232e41f4b71Sopenharmony_ci         ```c
233e41f4b71Sopenharmony_ci         static int32_t InitAccelAfterDetected(struct SensorCfgData *config)
234e41f4b71Sopenharmony_ci         {
235e41f4b71Sopenharmony_ci             struct SensorDeviceInfo deviceInfo;
236e41f4b71Sopenharmony_ci             CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
237e41f4b71Sopenharmony_ci         	/* Initialize the acceleration sensor. */
238e41f4b71Sopenharmony_ci             if (InitAccelOps(config, &deviceInfo) != HDF_SUCCESS) {
239e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Init accel ops failed", __func__);
240e41f4b71Sopenharmony_ci                 return HDF_FAILURE;
241e41f4b71Sopenharmony_ci             }
242e41f4b71Sopenharmony_ci         	/* Register the accelerometer device with the sensor device management module. */
243e41f4b71Sopenharmony_ci             if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
244e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Add accel device failed", __func__);
245e41f4b71Sopenharmony_ci                 return HDF_FAILURE;
246e41f4b71Sopenharmony_ci             }
247e41f4b71Sopenharmony_ci         	/* Parse the sensor register. */
248e41f4b71Sopenharmony_ci             if (ParseSensorDirection(config) != HDF_SUCCESS) {
249e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Parse accel direction failed", __func__);
250e41f4b71Sopenharmony_ci                 (void)DeleteSensorDevice(&config->sensorInfo);
251e41f4b71Sopenharmony_ci                 return HDF_FAILURE;
252e41f4b71Sopenharmony_ci             }
253e41f4b71Sopenharmony_ci         
254e41f4b71Sopenharmony_ci             if (ParseSensorRegConfig(config) != HDF_SUCCESS) {
255e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Parse sensor register failed", __func__);
256e41f4b71Sopenharmony_ci                 (void)DeleteSensorDevice(&config->sensorInfo);
257e41f4b71Sopenharmony_ci                 ReleaseSensorAllRegConfig(config);
258e41f4b71Sopenharmony_ci                 ReleaseSensorDirectionConfig(config);
259e41f4b71Sopenharmony_ci                 return HDF_FAILURE;
260e41f4b71Sopenharmony_ci             }
261e41f4b71Sopenharmony_ci             return HDF_SUCCESS;
262e41f4b71Sopenharmony_ci         }
263e41f4b71Sopenharmony_ci         
264e41f4b71Sopenharmony_ci         struct SensorCfgData *AccelCreateCfgData(const struct DeviceResourceNode *node)
265e41f4b71Sopenharmony_ci         {
266e41f4b71Sopenharmony_ci             struct AccelDrvData *drvData = AccelGetDrvData();
267e41f4b71Sopenharmony_ci         	/* If the device is not in position, return to detect the next device. */
268e41f4b71Sopenharmony_ci             if (drvData == NULL || node == NULL) {
269e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel node pointer NULL", __func__);
270e41f4b71Sopenharmony_ci                 return NULL;
271e41f4b71Sopenharmony_ci             }
272e41f4b71Sopenharmony_ci         
273e41f4b71Sopenharmony_ci             if (drvData->detectFlag) {
274e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel sensor have detected", __func__);
275e41f4b71Sopenharmony_ci                 return NULL;
276e41f4b71Sopenharmony_ci             }
277e41f4b71Sopenharmony_ci         
278e41f4b71Sopenharmony_ci             if (drvData->accelCfg == NULL) {
279e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel accelCfg pointer NULL", __func__);
280e41f4b71Sopenharmony_ci                 return NULL;
281e41f4b71Sopenharmony_ci             }
282e41f4b71Sopenharmony_ci         	/* Parse the basic sensor configuration. */
283e41f4b71Sopenharmony_ci             if (GetSensorBaseConfigData(node, drvData->accelCfg) != HDF_SUCCESS) {
284e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Get sensor base config failed", __func__);
285e41f4b71Sopenharmony_ci                 goto BASE_CONFIG_EXIT;
286e41f4b71Sopenharmony_ci             }
287e41f4b71Sopenharmony_ci         	/* If the device is not in position (the device ID exists), return to detect the next device. */
288e41f4b71Sopenharmony_ci             if (DetectSensorDevice(drvData->accelCfg) != HDF_SUCCESS) {
289e41f4b71Sopenharmony_ci                 HDF_LOGI("%s: Accel sensor detect device no exist", __func__);
290e41f4b71Sopenharmony_ci                 drvData->detectFlag = false;
291e41f4b71Sopenharmony_ci                 goto BASE_CONFIG_EXIT;
292e41f4b71Sopenharmony_ci             }
293e41f4b71Sopenharmony_ci         	/* Parse the sensor register. */
294e41f4b71Sopenharmony_ci             drvData->detectFlag = true;
295e41f4b71Sopenharmony_ci             if (InitAccelAfterDetected(drvData->accelCfg) != HDF_SUCCESS) {
296e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel sensor detect device no exist", __func__);
297e41f4b71Sopenharmony_ci                 goto INIT_EXIT;
298e41f4b71Sopenharmony_ci             }
299e41f4b71Sopenharmony_ci             return drvData->accelCfg;
300e41f4b71Sopenharmony_ci         
301e41f4b71Sopenharmony_ci         INIT_EXIT:
302e41f4b71Sopenharmony_ci             (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg);
303e41f4b71Sopenharmony_ci         BASE_CONFIG_EXIT:
304e41f4b71Sopenharmony_ci             drvData->accelCfg->root = NULL;
305e41f4b71Sopenharmony_ci             (void)memset_s(&drvData->accelCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
306e41f4b71Sopenharmony_ci             (void)memset_s(&drvData->accelCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
307e41f4b71Sopenharmony_ci             (void)memset_s(&drvData->accelCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
308e41f4b71Sopenharmony_ci             return drvData->accelCfg;
309e41f4b71Sopenharmony_ci         }
310e41f4b71Sopenharmony_ci         ```
311e41f4b71Sopenharmony_ci
312e41f4b71Sopenharmony_ci       - Implement **Enable()** as follows.
313e41f4b71Sopenharmony_ci
314e41f4b71Sopenharmony_ci         ```c
315e41f4b71Sopenharmony_ci         static int32_t SetAccelEnable(void)
316e41f4b71Sopenharmony_ci         {
317e41f4b71Sopenharmony_ci             int32_t ret;
318e41f4b71Sopenharmony_ci             struct AccelDrvData *drvData = AccelGetDrvData();
319e41f4b71Sopenharmony_ci         
320e41f4b71Sopenharmony_ci             CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
321e41f4b71Sopenharmony_ci             CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
322e41f4b71Sopenharmony_ci         
323e41f4b71Sopenharmony_ci             if (drvData->enable) {
324e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel sensor is enabled", __func__);
325e41f4b71Sopenharmony_ci                 return HDF_SUCCESS;
326e41f4b71Sopenharmony_ci             }
327e41f4b71Sopenharmony_ci         	/* Set the register. */
328e41f4b71Sopenharmony_ci             ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
329e41f4b71Sopenharmony_ci             if (ret != HDF_SUCCESS) {
330e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel sensor enable config failed", __func__);
331e41f4b71Sopenharmony_ci                 return ret;
332e41f4b71Sopenharmony_ci             }
333e41f4b71Sopenharmony_ci         	/* Create a timer. */
334e41f4b71Sopenharmony_ci             ret = OsalTimerCreate(&drvData->accelTimer, SENSOR_TIMER_MIN_TIME, AccelTimerEntry, (uintptr_t)drvData);
335e41f4b71Sopenharmony_ci             if (ret != HDF_SUCCESS) {
336e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel create timer failed[%d]", __func__, ret);
337e41f4b71Sopenharmony_ci                 return ret;
338e41f4b71Sopenharmony_ci             }
339e41f4b71Sopenharmony_ci         	/* Start the timer to report data. */
340e41f4b71Sopenharmony_ci             ret = OsalTimerStartLoop(&drvData->accelTimer);
341e41f4b71Sopenharmony_ci             if (ret != HDF_SUCCESS) {
342e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel start timer failed[%d]", __func__, ret);
343e41f4b71Sopenharmony_ci                 return ret;
344e41f4b71Sopenharmony_ci             }
345e41f4b71Sopenharmony_ci             drvData->enable = true;
346e41f4b71Sopenharmony_ci         
347e41f4b71Sopenharmony_ci             return HDF_SUCCESS;
348e41f4b71Sopenharmony_ci         }
349e41f4b71Sopenharmony_ci         ```
350e41f4b71Sopenharmony_ci
351e41f4b71Sopenharmony_ci       - Implement **Disable()** as follows.
352e41f4b71Sopenharmony_ci
353e41f4b71Sopenharmony_ci         ```c
354e41f4b71Sopenharmony_ci         static int32_t SetAccelDisable(void)
355e41f4b71Sopenharmony_ci         {
356e41f4b71Sopenharmony_ci             int32_t ret;
357e41f4b71Sopenharmony_ci             struct AccelDrvData *drvData = AccelGetDrvData();
358e41f4b71Sopenharmony_ci         
359e41f4b71Sopenharmony_ci             CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
360e41f4b71Sopenharmony_ci             CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
361e41f4b71Sopenharmony_ci         
362e41f4b71Sopenharmony_ci             if (!drvData->enable) {
363e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel sensor had disable", __func__);
364e41f4b71Sopenharmony_ci                 return HDF_SUCCESS;
365e41f4b71Sopenharmony_ci             }
366e41f4b71Sopenharmony_ci         	/* Set the register. */
367e41f4b71Sopenharmony_ci             ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
368e41f4b71Sopenharmony_ci             if (ret != HDF_SUCCESS) {
369e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel sensor disable config failed", __func__);
370e41f4b71Sopenharmony_ci                 return ret;
371e41f4b71Sopenharmony_ci             }
372e41f4b71Sopenharmony_ci         	/* Delete the timer. */
373e41f4b71Sopenharmony_ci             ret = OsalTimerDelete(&drvData->accelTimer);
374e41f4b71Sopenharmony_ci             if (ret != HDF_SUCCESS) {
375e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: Accel delete timer failed", __func__);
376e41f4b71Sopenharmony_ci                 return ret;
377e41f4b71Sopenharmony_ci             }
378e41f4b71Sopenharmony_ci             drvData->enable = false;
379e41f4b71Sopenharmony_ci         
380e41f4b71Sopenharmony_ci             return HDF_SUCCESS;
381e41f4b71Sopenharmony_ci         }
382e41f4b71Sopenharmony_ci         ```
383e41f4b71Sopenharmony_ci
384e41f4b71Sopenharmony_ci       - Implement **SetBatch()** as follows.
385e41f4b71Sopenharmony_ci
386e41f4b71Sopenharmony_ci         ```c
387e41f4b71Sopenharmony_ci         static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval)
388e41f4b71Sopenharmony_ci         {
389e41f4b71Sopenharmony_ci             (void)interval;
390e41f4b71Sopenharmony_ci         
391e41f4b71Sopenharmony_ci             struct AccelDrvData *drvData = NULL;
392e41f4b71Sopenharmony_ci         
393e41f4b71Sopenharmony_ci             drvData = AccelGetDrvData();
394e41f4b71Sopenharmony_ci             CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
395e41f4b71Sopenharmony_ci         	/* Set the sampling rate for the timer. */
396e41f4b71Sopenharmony_ci             drvData->interval = samplingInterval;
397e41f4b71Sopenharmony_ci         
398e41f4b71Sopenharmony_ci             return HDF_SUCCESS;
399e41f4b71Sopenharmony_ci         }
400e41f4b71Sopenharmony_ci         ```
401e41f4b71Sopenharmony_ci
402e41f4b71Sopenharmony_ci       - Implement **SetMode()** as follows.
403e41f4b71Sopenharmony_ci
404e41f4b71Sopenharmony_ci         ```c
405e41f4b71Sopenharmony_ci         static int32_t SetAccelMode(int32_t mode)
406e41f4b71Sopenharmony_ci         {
407e41f4b71Sopenharmony_ci             if (mode <= SENSOR_WORK_MODE_DEFAULT || mode >= SENSOR_WORK_MODE_MAX) {
408e41f4b71Sopenharmony_ci                 HDF_LOGE("%s: The current mode is not supported", __func__);
409e41f4b71Sopenharmony_ci                 return HDF_FAILURE;
410e41f4b71Sopenharmony_ci             }
411e41f4b71Sopenharmony_ci         
412e41f4b71Sopenharmony_ci             return HDF_SUCCESS;
413e41f4b71Sopenharmony_ci         }
414e41f4b71Sopenharmony_ci         ```
415e41f4b71Sopenharmony_ci
416e41f4b71Sopenharmony_ci       - Implement **SetOption()** as follows.
417e41f4b71Sopenharmony_ci
418e41f4b71Sopenharmony_ci         ```c
419e41f4b71Sopenharmony_ci         static int32_t SetAccelOption(uint32_t option)
420e41f4b71Sopenharmony_ci         {
421e41f4b71Sopenharmony_ci             (void)option;
422e41f4b71Sopenharmony_ci             return HDF_SUCCESS;
423e41f4b71Sopenharmony_ci         }
424e41f4b71Sopenharmony_ci         ```
425e41f4b71Sopenharmony_ci
426e41f4b71Sopenharmony_ci2. Develop the differentiated drivers for acceleration sensors.
427e41f4b71Sopenharmony_ci
428e41f4b71Sopenharmony_ci   - Configure the host information for the differentiated driver of the acceleration sensor in **vendor\hihope\rk3568\hdf_config\khdf\device_info\device_info.hcs**.
429e41f4b71Sopenharmony_ci
430e41f4b71Sopenharmony_ci     The code is as follows:
431e41f4b71Sopenharmony_ci
432e41f4b71Sopenharmony_ci     ```c
433e41f4b71Sopenharmony_ci     device_sensor_mxc6655xa :: device {
434e41f4b71Sopenharmony_ci         device0 :: deviceNode {
435e41f4b71Sopenharmony_ci             policy = 1; 		    // Policy for publishing drive services.
436e41f4b71Sopenharmony_ci             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. 
437e41f4b71Sopenharmony_ci             preload = 0;             // Whether to load the driver on demand. The value 0 means to load the driver on demand, and 2 means the opposite.
438e41f4b71Sopenharmony_ci             permission = 0664;       // Permission for the driver to create a device node.
439e41f4b71Sopenharmony_ci             moduleName = "HDF_SENSOR_ACCEL_MXC6655XA";  // Driver name, which must be the same as moduleName in the driver entry structure.
440e41f4b71Sopenharmony_ci             serviceName = "hdf_accel_mxc6655xa";        // Name of the service published by acceleration mxc6655xa. It must be unique.
441e41f4b71Sopenharmony_ci             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.
442e41f4b71Sopenharmony_ci         }
443e41f4b71Sopenharmony_ci     }
444e41f4b71Sopenharmony_ci     ```
445e41f4b71Sopenharmony_ci
446e41f4b71Sopenharmony_ci   - Configure the private HCS for the differentiated driver of the acceleration sensor.
447e41f4b71Sopenharmony_ci
448e41f4b71Sopenharmony_ci     - Code path: **vendor\hihope\rk3568\hdf_config\khdf\sensor\accel\mxc6655xa_config.hcs**.
449e41f4b71Sopenharmony_ci
450e41f4b71Sopenharmony_ci     - The code is as follows:
451e41f4b71Sopenharmony_ci
452e41f4b71Sopenharmony_ci       ```c
453e41f4b71Sopenharmony_ci       #include "../sensor_common.hcs"
454e41f4b71Sopenharmony_ci       root {
455e41f4b71Sopenharmony_ci           accel_mxc6655xa_chip_config : sensorConfig {
456e41f4b71Sopenharmony_ci               match_attr = "hdf_sensor_accel_mxc6655xa_driver";
457e41f4b71Sopenharmony_ci               sensorInfo :: sensorDeviceInfo {
458e41f4b71Sopenharmony_ci                   sensorName = "accelerometer";
459e41f4b71Sopenharmony_ci                   vendorName = "memsi_mxc6655xa"; // Max string length is 16 bytes
460e41f4b71Sopenharmony_ci                   sensorTypeId = 1;               // enum SensorTypeTag
461e41f4b71Sopenharmony_ci                   sensorId = 1;                   // User-defined sensor ID
462e41f4b71Sopenharmony_ci                   power = 230;
463e41f4b71Sopenharmony_ci                   minDelay = 5000000;             // Nanosecond
464e41f4b71Sopenharmony_ci                   maxDelay = 200000000;           // Nanosecond
465e41f4b71Sopenharmony_ci               }
466e41f4b71Sopenharmony_ci               sensorBusConfig :: sensorBusInfo {
467e41f4b71Sopenharmony_ci                   busType = 0;                    // 0:i2c 1:spi
468e41f4b71Sopenharmony_ci                   busNum = 5;
469e41f4b71Sopenharmony_ci                   busAddr = 0x15;
470e41f4b71Sopenharmony_ci                   regWidth = 1;                   // 1 byte
471e41f4b71Sopenharmony_ci               }
472e41f4b71Sopenharmony_ci               sensorIdAttr :: sensorIdInfo {
473e41f4b71Sopenharmony_ci                   chipName = "mxc6655xa";
474e41f4b71Sopenharmony_ci                   chipIdRegister = 0x0f;
475e41f4b71Sopenharmony_ci                   chipIdValue = 0x05;             // Read the value based on the device ID register or check the value in the related chip datasheet.
476e41f4b71Sopenharmony_ci               }
477e41f4b71Sopenharmony_ci               sensorDirection {
478e41f4b71Sopenharmony_ci                   direction = 1;                  // chip direction range of value:0-7
479e41f4b71Sopenharmony_ci                   /* <sign> 1:negative  0:positive
480e41f4b71Sopenharmony_ci                      <map> 0:AXIS_X  1:AXIS_Y  2:AXIS_Z
481e41f4b71Sopenharmony_ci                   */
482e41f4b71Sopenharmony_ci                   /* sign[AXIS_X], sign[AXIS_Y], sign[AXIS_Z], map[AXIS_X], map[AXIS_Y], map[AXIS_Z] */
483e41f4b71Sopenharmony_ci                   convert = [
484e41f4b71Sopenharmony_ci                       0, 0, 0, 0, 1, 2,
485e41f4b71Sopenharmony_ci                       1, 0, 0, 1, 0, 2,
486e41f4b71Sopenharmony_ci                       0, 0, 1, 0, 1, 2,
487e41f4b71Sopenharmony_ci                       0, 1, 0, 1, 0, 2,
488e41f4b71Sopenharmony_ci                       1, 0, 1, 0, 1, 2,
489e41f4b71Sopenharmony_ci                       0, 0, 1, 1, 0, 2,
490e41f4b71Sopenharmony_ci                       0, 1, 1, 0, 1, 2,
491e41f4b71Sopenharmony_ci                       1, 1, 1, 1, 0, 2
492e41f4b71Sopenharmony_ci                   ];
493e41f4b71Sopenharmony_ci               }
494e41f4b71Sopenharmony_ci               sensorRegConfig {
495e41f4b71Sopenharmony_ci                   /*  regAddr: register address
496e41f4b71Sopenharmony_ci                       value: config register value
497e41f4b71Sopenharmony_ci                       len: size of value
498e41f4b71Sopenharmony_ci                       mask: mask of value
499e41f4b71Sopenharmony_ci                       delay: config register delay time (ms)
500e41f4b71Sopenharmony_ci                       opsType: enum SensorOpsType 0-none 1-read 2-write 3-read_check 4-update_bit
501e41f4b71Sopenharmony_ci                       calType: enum SensorBitCalType 0-none 1-set 2-revert 3-xor 4-left shift 5-right shift
502e41f4b71Sopenharmony_ci                       shiftNum: shift bits
503e41f4b71Sopenharmony_ci                       debug: 0-no debug 1-debug
504e41f4b71Sopenharmony_ci                       save: 0-no save 1-save
505e41f4b71Sopenharmony_ci                   */
506e41f4b71Sopenharmony_ci                   /* regAddr, value, mask, len, delay, opsType, calType, shiftNum, debug, save */
507e41f4b71Sopenharmony_ci                   initSeqConfig = [
508e41f4b71Sopenharmony_ci                       0x7e,    0xb6, 0xff,   1,     5,       2,       0,        0,     0,    0,
509e41f4b71Sopenharmony_ci                       0x7e,    0x10, 0xff,   1,     5,       2,       0,        0,     0,    0
510e41f4b71Sopenharmony_ci                   ];
511e41f4b71Sopenharmony_ci                   enableSeqConfig = [
512e41f4b71Sopenharmony_ci                       0x7e,    0x11, 0xff,   1,     5,       2,       0,        0,     0,    0,
513e41f4b71Sopenharmony_ci                       0x41,    0x03, 0xff,   1,     0,       2,       0,        0,     0,    0,
514e41f4b71Sopenharmony_ci                       0x40,    0x08, 0xff,   1,     0,       2,       0,        0,     0,    0
515e41f4b71Sopenharmony_ci                   ];
516e41f4b71Sopenharmony_ci                   disableSeqConfig = [
517e41f4b71Sopenharmony_ci                       0x7e,    0x10, 0xff,   1,     5,       2,       0,        0,     0,    0
518e41f4b71Sopenharmony_ci                   ];
519e41f4b71Sopenharmony_ci               }
520e41f4b71Sopenharmony_ci           }
521e41f4b71Sopenharmony_ci       }
522e41f4b71Sopenharmony_ci       ```
523e41f4b71Sopenharmony_ci
524e41f4b71Sopenharmony_ci   - Implement the code for the differentiated driver in **drivers\peripheral\sensor\chipset\accel\accel_mxc6655xa.c**.
525e41f4b71Sopenharmony_ci
526e41f4b71Sopenharmony_ci     - Define the **HdfDriverEntry** object corresponding to the acceleration sensor chipset driver. The driver entry function is defined as follows:
527e41f4b71Sopenharmony_ci
528e41f4b71Sopenharmony_ci       ```c
529e41f4b71Sopenharmony_ci       /* Register the entry struct object of the mxc6655xa acceleration sensor. */
530e41f4b71Sopenharmony_ci       struct HdfDriverEntry g_accelMxc6655xaDevEntry = {
531e41f4b71Sopenharmony_ci           .moduleVersion = 1,                         // Module version of the mxc6655xa acceleration sensor.
532e41f4b71Sopenharmony_ci           .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.
533e41f4b71Sopenharmony_ci           .Bind = Mxc6655xaBindDriver,                // Bind function of the mxc6655xa acceleration sensor.
534e41f4b71Sopenharmony_ci           .Init = Mxc6655xaInitDriver,                // Init function of the mxc6655xa acceleration sensor.
535e41f4b71Sopenharmony_ci           .Release = Mxc6655xaReleaseDriver,          // Release function of the mxc6655xa acceleration sensor.
536e41f4b71Sopenharmony_ci       };
537e41f4b71Sopenharmony_ci       /* 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. */
538e41f4b71Sopenharmony_ci       HDF_INIT(g_accelMxc6655xaDevEntry);
539e41f4b71Sopenharmony_ci       ```
540e41f4b71Sopenharmony_ci
541e41f4b71Sopenharmony_ci     - Implement **Bind()** for the differentiated driver as follows.
542e41f4b71Sopenharmony_ci
543e41f4b71Sopenharmony_ci       ```c
544e41f4b71Sopenharmony_ci       int32_t Mxc6655xaBindDriver(struct HdfDeviceObject *device)
545e41f4b71Sopenharmony_ci       {
546e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
547e41f4b71Sopenharmony_ci       
548e41f4b71Sopenharmony_ci           struct Mxc6655xaDrvData *drvData = (struct Mxc6655xaDrvData *)OsalMemCalloc(sizeof(*drvData));
549e41f4b71Sopenharmony_ci           if (drvData == NULL) {
550e41f4b71Sopenharmony_ci               HDF_LOGE("%s: Malloc MXC6655XA drv data fail", __func__);
551e41f4b71Sopenharmony_ci               return HDF_ERR_MALLOC_FAIL;
552e41f4b71Sopenharmony_ci           }
553e41f4b71Sopenharmony_ci       
554e41f4b71Sopenharmony_ci           drvData->ioService.Dispatch = DispatchMXC6655xa;
555e41f4b71Sopenharmony_ci           drvData->device = device;
556e41f4b71Sopenharmony_ci           device->service = &drvData->ioService;
557e41f4b71Sopenharmony_ci           g_mxc6655xaDrvData = drvData;
558e41f4b71Sopenharmony_ci       
559e41f4b71Sopenharmony_ci           return HDF_SUCCESS;
560e41f4b71Sopenharmony_ci       }
561e41f4b71Sopenharmony_ci       ```
562e41f4b71Sopenharmony_ci
563e41f4b71Sopenharmony_ci     - Implement **Init()** for the differentiated driver as follows.
564e41f4b71Sopenharmony_ci
565e41f4b71Sopenharmony_ci       ```c
566e41f4b71Sopenharmony_ci       int32_t Mxc6655xaInitDriver(struct HdfDeviceObject *device)
567e41f4b71Sopenharmony_ci       {
568e41f4b71Sopenharmony_ci           int32_t ret;
569e41f4b71Sopenharmony_ci           struct AccelOpsCall ops;
570e41f4b71Sopenharmony_ci       
571e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
572e41f4b71Sopenharmony_ci           struct Mxc6655xaDrvData *drvData = (struct Mxc6655xaDrvData *)device->service;
573e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
574e41f4b71Sopenharmony_ci       
575e41f4b71Sopenharmony_ci           drvData->sensorCfg = AccelCreateCfgData(device->property);
576e41f4b71Sopenharmony_ci           if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
577e41f4b71Sopenharmony_ci               HDF_LOGD("%s: Creating accelcfg failed because detection failed", __func__);
578e41f4b71Sopenharmony_ci               return HDF_ERR_NOT_SUPPORT;
579e41f4b71Sopenharmony_ci           }
580e41f4b71Sopenharmony_ci       
581e41f4b71Sopenharmony_ci           ops.Init = NULL;
582e41f4b71Sopenharmony_ci           ops.ReadData = ReadMxc6655xaData;
583e41f4b71Sopenharmony_ci           ret = AccelRegisterChipOps(&ops);
584e41f4b71Sopenharmony_ci           if (ret != HDF_SUCCESS) {
585e41f4b71Sopenharmony_ci               HDF_LOGE("%s: Register MXC6655XA accel failed", __func__);
586e41f4b71Sopenharmony_ci               return HDF_FAILURE;
587e41f4b71Sopenharmony_ci           }
588e41f4b71Sopenharmony_ci       
589e41f4b71Sopenharmony_ci           ret = InitMxc6655xa(drvData->sensorCfg);
590e41f4b71Sopenharmony_ci           if (ret != HDF_SUCCESS) {
591e41f4b71Sopenharmony_ci               HDF_LOGE("%s: Init MXC6655XA accel failed", __func__);
592e41f4b71Sopenharmony_ci               return HDF_FAILURE;
593e41f4b71Sopenharmony_ci           }
594e41f4b71Sopenharmony_ci       
595e41f4b71Sopenharmony_ci           return HDF_SUCCESS;
596e41f4b71Sopenharmony_ci       }
597e41f4b71Sopenharmony_ci       ```
598e41f4b71Sopenharmony_ci
599e41f4b71Sopenharmony_ci     - Implement **Release()** for the differentiated driver as follows.
600e41f4b71Sopenharmony_ci
601e41f4b71Sopenharmony_ci       ```c
602e41f4b71Sopenharmony_ci       void Mxc6655xaReleaseDriver(struct HdfDeviceObject *device)
603e41f4b71Sopenharmony_ci       {
604e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN(device);
605e41f4b71Sopenharmony_ci       
606e41f4b71Sopenharmony_ci           struct Mxc6655xaDrvData *drvData = (struct Mxc6655xaDrvData *)device->service;
607e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN(drvData);
608e41f4b71Sopenharmony_ci       
609e41f4b71Sopenharmony_ci           if (drvData->sensorCfg != NULL) {
610e41f4b71Sopenharmony_ci               AccelReleaseCfgData(drvData->sensorCfg);
611e41f4b71Sopenharmony_ci               drvData->sensorCfg = NULL;
612e41f4b71Sopenharmony_ci           }
613e41f4b71Sopenharmony_ci           OsalMemFree(drvData);
614e41f4b71Sopenharmony_ci       }
615e41f4b71Sopenharmony_ci       ```
616e41f4b71Sopenharmony_ci
617e41f4b71Sopenharmony_ci     - Implement the internal interfaces of the differentiated driver of the acceleration sensor.
618e41f4b71Sopenharmony_ci
619e41f4b71Sopenharmony_ci       You need to implement **ReadMxc6655xaData** and register it in **Mxc6655xaInitDriver**. The implementation is as follows:
620e41f4b71Sopenharmony_ci
621e41f4b71Sopenharmony_ci       ```c
622e41f4b71Sopenharmony_ci       static int32_t ReadMxc6655xaRawData(struct SensorCfgData *data, struct AccelData *rawData, uint64_t *timestamp)
623e41f4b71Sopenharmony_ci       {
624e41f4b71Sopenharmony_ci           uint8_t status = 0;
625e41f4b71Sopenharmony_ci           uint8_t reg[ACCEL_AXIS_BUTT];
626e41f4b71Sopenharmony_ci           OsalTimespec time;
627e41f4b71Sopenharmony_ci           int32_t x;
628e41f4b71Sopenharmony_ci           int32_t y;
629e41f4b71Sopenharmony_ci           int32_t z;
630e41f4b71Sopenharmony_ci       
631e41f4b71Sopenharmony_ci           (void)memset_s(&time, sizeof(time), 0, sizeof(time));
632e41f4b71Sopenharmony_ci           (void)memset_s(reg, sizeof(reg), 0, sizeof(reg));
633e41f4b71Sopenharmony_ci       
634e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
635e41f4b71Sopenharmony_ci       
636e41f4b71Sopenharmony_ci           if (OsalGetTime(&time) != HDF_SUCCESS) {
637e41f4b71Sopenharmony_ci               HDF_LOGE("%s: Get time failed", __func__);
638e41f4b71Sopenharmony_ci               return HDF_FAILURE;
639e41f4b71Sopenharmony_ci           }
640e41f4b71Sopenharmony_ci           *timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT; /* unit nanosecond */
641e41f4b71Sopenharmony_ci       
642e41f4b71Sopenharmony_ci           int32_t ret = ReadSensor(&data->busCfg, MXC6655XA_STATUS_ADDR, &status, sizeof(uint8_t));
643e41f4b71Sopenharmony_ci           if (ret != HDF_SUCCESS) {
644e41f4b71Sopenharmony_ci               HDF_LOGE("%s: data status [%u] ret [%d]", __func__, status, ret);
645e41f4b71Sopenharmony_ci               return HDF_FAILURE;
646e41f4b71Sopenharmony_ci           }
647e41f4b71Sopenharmony_ci       
648e41f4b71Sopenharmony_ci           ret = ReadSensor(&data->busCfg, MXC6655XA_ACCEL_X_LSB_ADDR, &reg[ACCEL_X_AXIS_LSB], sizeof(uint8_t));
649e41f4b71Sopenharmony_ci           CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
650e41f4b71Sopenharmony_ci       
651e41f4b71Sopenharmony_ci           ret = ReadSensor(&data->busCfg, MXC6655XA_ACCEL_X_MSB_ADDR, &reg[ACCEL_X_AXIS_MSB], sizeof(uint8_t));
652e41f4b71Sopenharmony_ci           CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
653e41f4b71Sopenharmony_ci       
654e41f4b71Sopenharmony_ci           ret = ReadSensor(&data->busCfg, MXC6655XA_ACCEL_Y_LSB_ADDR, &reg[ACCEL_Y_AXIS_LSB], sizeof(uint8_t));
655e41f4b71Sopenharmony_ci           CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
656e41f4b71Sopenharmony_ci       
657e41f4b71Sopenharmony_ci           ret = ReadSensor(&data->busCfg, MXC6655XA_ACCEL_Y_MSB_ADDR, &reg[ACCEL_Y_AXIS_MSB], sizeof(uint8_t));
658e41f4b71Sopenharmony_ci           CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
659e41f4b71Sopenharmony_ci       
660e41f4b71Sopenharmony_ci           ret = ReadSensor(&data->busCfg, MXC6655XA_ACCEL_Z_LSB_ADDR, &reg[ACCEL_Z_AXIS_LSB], sizeof(uint8_t));
661e41f4b71Sopenharmony_ci           CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
662e41f4b71Sopenharmony_ci       
663e41f4b71Sopenharmony_ci           ret = ReadSensor(&data->busCfg, MXC6655XA_ACCEL_Z_MSB_ADDR, &reg[ACCEL_Z_AXIS_MSB], sizeof(uint8_t));
664e41f4b71Sopenharmony_ci           CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
665e41f4b71Sopenharmony_ci       
666e41f4b71Sopenharmony_ci           x = SensorConvertData(reg[ACCEL_X_AXIS_MSB], reg[ACCEL_X_AXIS_LSB]);
667e41f4b71Sopenharmony_ci           y = SensorConvertData(reg[ACCEL_Y_AXIS_MSB], reg[ACCEL_Y_AXIS_LSB]);
668e41f4b71Sopenharmony_ci           z = SensorConvertData(reg[ACCEL_Z_AXIS_MSB], reg[ACCEL_Z_AXIS_LSB]);
669e41f4b71Sopenharmony_ci           rawData->x = x;
670e41f4b71Sopenharmony_ci           rawData->y = y;
671e41f4b71Sopenharmony_ci           rawData->z = z;
672e41f4b71Sopenharmony_ci       
673e41f4b71Sopenharmony_ci           return HDF_SUCCESS;
674e41f4b71Sopenharmony_ci       }
675e41f4b71Sopenharmony_ci       /* 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. */
676e41f4b71Sopenharmony_ci       int32_t ReadMxc6655xaData(struct SensorCfgData *cfg, struct SensorReportEvent *event)
677e41f4b71Sopenharmony_ci       {
678e41f4b71Sopenharmony_ci           int32_t ret;
679e41f4b71Sopenharmony_ci           struct AccelData rawData = { 0, 0, 0 };
680e41f4b71Sopenharmony_ci           static int32_t tmp[ACCEL_AXIS_NUM];
681e41f4b71Sopenharmony_ci       
682e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(cfg, HDF_ERR_INVALID_PARAM);
683e41f4b71Sopenharmony_ci           CHECK_NULL_PTR_RETURN_VALUE(event, HDF_ERR_INVALID_PARAM);
684e41f4b71Sopenharmony_ci       
685e41f4b71Sopenharmony_ci           ret = ReadMxc6655xaRawData(cfg, &rawData, &event->timestamp);
686e41f4b71Sopenharmony_ci           if (ret != HDF_SUCCESS) {
687e41f4b71Sopenharmony_ci               HDF_LOGE("%s: MXC6655XA read raw data failed", __func__);
688e41f4b71Sopenharmony_ci               return HDF_FAILURE;
689e41f4b71Sopenharmony_ci           }
690e41f4b71Sopenharmony_ci       
691e41f4b71Sopenharmony_ci           event->sensorId = SENSOR_TAG_ACCELEROMETER;
692e41f4b71Sopenharmony_ci           event->option = 0;
693e41f4b71Sopenharmony_ci           event->mode = SENSOR_WORK_MODE_REALTIME;
694e41f4b71Sopenharmony_ci       
695e41f4b71Sopenharmony_ci           rawData.x = rawData.x * MXC6655XA_ACC_SENSITIVITY_2G;
696e41f4b71Sopenharmony_ci           rawData.y = rawData.y * MXC6655XA_ACC_SENSITIVITY_2G;
697e41f4b71Sopenharmony_ci           rawData.z = rawData.z * MXC6655XA_ACC_SENSITIVITY_2G;
698e41f4b71Sopenharmony_ci       
699e41f4b71Sopenharmony_ci           tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_CONVERT_UNIT) / SENSOR_CONVERT_UNIT;
700e41f4b71Sopenharmony_ci           tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_CONVERT_UNIT) / SENSOR_CONVERT_UNIT;
701e41f4b71Sopenharmony_ci           tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_CONVERT_UNIT) / SENSOR_CONVERT_UNIT;
702e41f4b71Sopenharmony_ci       
703e41f4b71Sopenharmony_ci           ret = SensorRawDataToRemapData(cfg->direction, tmp, sizeof(tmp) / sizeof(tmp[0]));
704e41f4b71Sopenharmony_ci           if (ret != HDF_SUCCESS) {
705e41f4b71Sopenharmony_ci               HDF_LOGE("%s: MXC6655XA convert raw data failed", __func__);
706e41f4b71Sopenharmony_ci               return HDF_FAILURE;
707e41f4b71Sopenharmony_ci           }
708e41f4b71Sopenharmony_ci       
709e41f4b71Sopenharmony_ci           event->dataLen = sizeof(tmp);
710e41f4b71Sopenharmony_ci           event->data = (uint8_t *)&tmp;
711e41f4b71Sopenharmony_ci       
712e41f4b71Sopenharmony_ci           return ret;
713e41f4b71Sopenharmony_ci       }
714e41f4b71Sopenharmony_ci       ```
715e41f4b71Sopenharmony_ci
716e41f4b71Sopenharmony_ci### Verification
717e41f4b71Sopenharmony_ci
718e41f4b71Sopenharmony_ciAfter 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.
719e41f4b71Sopenharmony_ci
720e41f4b71Sopenharmony_ci- The reference test code is as follows:
721e41f4b71Sopenharmony_ci
722e41f4b71Sopenharmony_ci  ```c
723e41f4b71Sopenharmony_ci  #include <cmath>
724e41f4b71Sopenharmony_ci  #include <cstdio>
725e41f4b71Sopenharmony_ci  #include <unistd.h>
726e41f4b71Sopenharmony_ci  #include <gtest/gtest.h>
727e41f4b71Sopenharmony_ci  #include <securec.h>
728e41f4b71Sopenharmony_ci  #include "hdf_base.h"
729e41f4b71Sopenharmony_ci  #include "osal_mem.h"
730e41f4b71Sopenharmony_ci  #include "osal_time.h"
731e41f4b71Sopenharmony_ci  #include "sensor_if.h"
732e41f4b71Sopenharmony_ci  #include "sensor_type.h"
733e41f4b71Sopenharmony_ci  
734e41f4b71Sopenharmony_ci  using namespace testing::ext;
735e41f4b71Sopenharmony_ci  const struct SensorInterface *g_sensorDev = nullptr;
736e41f4b71Sopenharmony_ci  /* Create a callback. */
737e41f4b71Sopenharmony_ci  static int32_t SensorDataCallback(const struct SensorEvents *event)
738e41f4b71Sopenharmony_ci  {
739e41f4b71Sopenharmony_ci      if (event == NULL) {
740e41f4b71Sopenharmony_ci          return HDF_FAILURE;
741e41f4b71Sopenharmony_ci      }
742e41f4b71Sopenharmony_ci  
743e41f4b71Sopenharmony_ci      float *data = (float*)event->data;
744e41f4b71Sopenharmony_ci      printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp,
745e41f4b71Sopenharmony_ci          event->sensorId, (*data), *(data + 1), *(data + 2));
746e41f4b71Sopenharmony_ci  
747e41f4b71Sopenharmony_ci      return HDF_SUCCESS;
748e41f4b71Sopenharmony_ci  }
749e41f4b71Sopenharmony_ci  
750e41f4b71Sopenharmony_ci  class HdfSensorTest : public testing::Test {
751e41f4b71Sopenharmony_ci  public:
752e41f4b71Sopenharmony_ci      static void SetUpTestCase();
753e41f4b71Sopenharmony_ci      static void TearDownTestCase();
754e41f4b71Sopenharmony_ci      void SetUp();
755e41f4b71Sopenharmony_ci      void TearDown();
756e41f4b71Sopenharmony_ci  };
757e41f4b71Sopenharmony_ci  
758e41f4b71Sopenharmony_ci  /* Initialize the sensor interface instance before executing the test cases. */
759e41f4b71Sopenharmony_ci  void HdfSensorTest::SetUpTestCase()
760e41f4b71Sopenharmony_ci  {
761e41f4b71Sopenharmony_ci      g_sensorDev = NewSensorInterfaceInstance();
762e41f4b71Sopenharmony_ci      if (g_sensorDev == nullptr) {
763e41f4b71Sopenharmony_ci          printf("test sensor get module instance failed\n\r");
764e41f4b71Sopenharmony_ci      }
765e41f4b71Sopenharmony_ci  }
766e41f4b71Sopenharmony_ci  /* Release case resources. */
767e41f4b71Sopenharmony_ci  void HdfSensorTest::TearDownTestCase()
768e41f4b71Sopenharmony_ci  {
769e41f4b71Sopenharmony_ci      if (g_sensorDev != nullptr) {
770e41f4b71Sopenharmony_ci          FreeSensorInterfaceInstance();
771e41f4b71Sopenharmony_ci          g_sensorDev = nullptr;
772e41f4b71Sopenharmony_ci      }
773e41f4b71Sopenharmony_ci  }
774e41f4b71Sopenharmony_ci  
775e41f4b71Sopenharmony_ci  void HdfSensorTest::SetUp()
776e41f4b71Sopenharmony_ci  {
777e41f4b71Sopenharmony_ci  }
778e41f4b71Sopenharmony_ci  
779e41f4b71Sopenharmony_ci  void HdfSensorTest::TearDown()
780e41f4b71Sopenharmony_ci  {
781e41f4b71Sopenharmony_ci  }
782e41f4b71Sopenharmony_ci  
783e41f4b71Sopenharmony_ci  HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0)
784e41f4b71Sopenharmony_ci  {
785e41f4b71Sopenharmony_ci      int ret;
786e41f4b71Sopenharmony_ci      struct SensorInformation *sensorInfo = NULL;
787e41f4b71Sopenharmony_ci      int32_t count = 0;
788e41f4b71Sopenharmony_ci      int32_t sensorInterval = 200000000; /* Set the data sampling rate to 200000000, in the unit of nanoseconds (200 ms). */
789e41f4b71Sopenharmony_ci      int32_t reportInterval = 400000000;
790e41f4b71Sopenharmony_ci  
791e41f4b71Sopenharmony_ci       /* 2. Register a sensor data callback. */
792e41f4b71Sopenharmony_ci      ret = g_sensorDev->Register(TRADITIONAL_SENSOR_TYPE, SensorDataCallback);
793e41f4b71Sopenharmony_ci      if (ret != 0) {
794e41f4b71Sopenharmony_ci          return;
795e41f4b71Sopenharmony_ci      }
796e41f4b71Sopenharmony_ci      printf("Register success\n");
797e41f4b71Sopenharmony_ci  
798e41f4b71Sopenharmony_ci      /* 3. Obtain the list of sensors supported by the device. */ 
799e41f4b71Sopenharmony_ci      ret = g_sensorDev->GetAllSensors(&sensorInfo, &count);
800e41f4b71Sopenharmony_ci      if (ret != 0) {
801e41f4b71Sopenharmony_ci          return;
802e41f4b71Sopenharmony_ci      }
803e41f4b71Sopenharmony_ci  
804e41f4b71Sopenharmony_ci      printf("GetAllSensors count: %d\n", count);
805e41f4b71Sopenharmony_ci  
806e41f4b71Sopenharmony_ci      for (int i = 0; i < count; i++)
807e41f4b71Sopenharmony_ci      {
808e41f4b71Sopenharmony_ci          printf("sensor [%d]: sensorName: %s, vendorName: %s, sensorTypeId: %d, sensorId: %d\n", i,
809e41f4b71Sopenharmony_ci                 sensorInfo[i].sensorName, sensorInfo[i].vendorName, sensorInfo[i].sensorTypeId, sensorInfo[i].sensorId);
810e41f4b71Sopenharmony_ci      }
811e41f4b71Sopenharmony_ci  
812e41f4b71Sopenharmony_ci      for (int i = 0; i < count; i++)
813e41f4b71Sopenharmony_ci      {
814e41f4b71Sopenharmony_ci          /* 4. Set the sensor sampling rate. */ 
815e41f4b71Sopenharmony_ci          ret = g_sensorDev->SetBatch(sensorInfo[i].sensorId, sensorInterval, reportInterval);
816e41f4b71Sopenharmony_ci          if (ret != 0) {
817e41f4b71Sopenharmony_ci              printf("SetBatch failed\n ,ret: %d",ret);
818e41f4b71Sopenharmony_ci              continue;
819e41f4b71Sopenharmony_ci          }
820e41f4b71Sopenharmony_ci          printf("SetBatch success\n");
821e41f4b71Sopenharmony_ci  
822e41f4b71Sopenharmony_ci          /* 5. Enable the sensor. */ 
823e41f4b71Sopenharmony_ci          ret = g_sensorDev->Enable(sensorInfo[i].sensorId);
824e41f4b71Sopenharmony_ci          if (ret != 0) {
825e41f4b71Sopenharmony_ci              continue;
826e41f4b71Sopenharmony_ci          }
827e41f4b71Sopenharmony_ci       printf("Enable success\n");
828e41f4b71Sopenharmony_ci  
829e41f4b71Sopenharmony_ci       usleep(1000 * 1000);
830e41f4b71Sopenharmony_ci  
831e41f4b71Sopenharmony_ci          /* 6. Disable the sensor. */ 
832e41f4b71Sopenharmony_ci          ret = g_sensorDev->Disable(sensorInfo[i].sensorId);
833e41f4b71Sopenharmony_ci          if (ret != 0) {
834e41f4b71Sopenharmony_ci              continue;
835e41f4b71Sopenharmony_ci          }
836e41f4b71Sopenharmony_ci          printf("Disable success\n");
837e41f4b71Sopenharmony_ci      }
838e41f4b71Sopenharmony_ci  
839e41f4b71Sopenharmony_ci      /* 7. Unregister the sensor data callback. */ 
840e41f4b71Sopenharmony_ci      ret = g_sensorDev->Unregister(TRADITIONAL_SENSOR_TYPE, SensorDataCallback);
841e41f4b71Sopenharmony_ci      if (ret != 0) {
842e41f4b71Sopenharmony_ci          return;
843e41f4b71Sopenharmony_ci      }
844e41f4b71Sopenharmony_ci      printf("Unregister success\n");
845e41f4b71Sopenharmony_ci  }
846e41f4b71Sopenharmony_ci  ```
847e41f4b71Sopenharmony_ci
848e41f4b71Sopenharmony_ci- The reference code of the .gn file is as follows: 
849e41f4b71Sopenharmony_ci
850e41f4b71Sopenharmony_ci  ```
851e41f4b71Sopenharmony_ci  import("//build/ohos.gni")
852e41f4b71Sopenharmony_ci  import("//build/test.gni")
853e41f4b71Sopenharmony_ci  import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni")
854e41f4b71Sopenharmony_ci  
855e41f4b71Sopenharmony_ci  module_output_path = "drivers_peripheral_sensor/sensor"
856e41f4b71Sopenharmony_ci  ohos_unittest("sensor_test") {
857e41f4b71Sopenharmony_ci    module_out_path = module_output_path
858e41f4b71Sopenharmony_ci    sources = [ "sensor_test.cpp" ]
859e41f4b71Sopenharmony_ci    include_dirs = [
860e41f4b71Sopenharmony_ci      "//drivers/peripheral/sensor/interfaces/include",
861e41f4b71Sopenharmony_ci    ]
862e41f4b71Sopenharmony_ci    deps = [ "//drivers/peripheral/sensor/hal:hdi_sensor" ]
863e41f4b71Sopenharmony_ci  
864e41f4b71Sopenharmony_ci    external_deps = [
865e41f4b71Sopenharmony_ci      "c_utils:utils",
866e41f4b71Sopenharmony_ci      "hdf_core:libhdf_utils",
867e41f4b71Sopenharmony_ci      "hiviewdfx_hilog_native:libhilog",
868e41f4b71Sopenharmony_ci    ]
869e41f4b71Sopenharmony_ci  
870e41f4b71Sopenharmony_ci    cflags = [
871e41f4b71Sopenharmony_ci      "-Wall",
872e41f4b71Sopenharmony_ci      "-Wextra",
873e41f4b71Sopenharmony_ci      "-Werror",
874e41f4b71Sopenharmony_ci      "-Wno-format",
875e41f4b71Sopenharmony_ci      "-Wno-format-extra-args",
876e41f4b71Sopenharmony_ci    ]
877e41f4b71Sopenharmony_ci  
878e41f4b71Sopenharmony_ci    install_enable = true
879e41f4b71Sopenharmony_ci    install_images = [ "vendor" ]
880e41f4b71Sopenharmony_ci    module_install_dir = "bin"
881e41f4b71Sopenharmony_ci    part_name = "unionman_products"
882e41f4b71Sopenharmony_ci  }
883e41f4b71Sopenharmony_ci  ```
884