• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Vibrator
2
3## 概述
4
5### 功能简介
6
7为了快速开发马达驱动,基于HDF(Hardware Driver Foundation)驱动框架开发了马达(Vibrator)驱动模型。马达驱动模型,屏蔽设备驱动与系统交互的实现,为硬件服务层提供统一稳定的驱动接口能力,为驱动开发者提供开放的接口和解析接口的能力,用于不同操作系统马达设备部件的部署指导和马达设备部件驱动的开发。马达驱动模型如图1所示:
8
9**图 1** 马达驱动模型图
10
11![Vibrator驱动模型图](figures/Vibrator驱动模型图.png)
12
13### 基本概念
14
15根据振动原理的不同,目前马达可以分为两种:
16
17- 转子马达
18
19  转子马达依靠旋转带动配重振动,分为普通转子和币型转子两种。转子马达的启停反应慢,并且无法实现多种振动模式,但其优点是成本低且体积小。
20
21- 线性马达
22
23  线性马达依靠磁力快速抖动配重来振动,分为纵向线性马达和横向线性马达两种。线性马达的启停都非常快,可以实现不同振感且具有良好的方向性。
24
25系统通过调用马达驱动接口实现对设备的振动控制。目前,马达只有两种振动方式:
26
27- 单次振动
28
29  单次振动是指按照指定的时间控制振动时长。
30
31- 周期振动
32
33  周期振动是指按照预置的效果模式控制振动。例如:预置效果为“haptic.clock.timer” = [600, 600, 200, 600],表示等待600ms,振动600ms,等待200ms,振动600ms。
34
35### 运作机制
36
37通过介绍马达驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如图2所示:
38
39**图2** 马达驱动运行图
40
41![Vibrator驱动运行图](figures/Vibrator驱动运行图.png)
42
43以标准系统Hi3516DV300产品为例,介绍马达模块驱动加载及运行流程:
44
451. Device Manager从device_info.hcs配置文件中读取Vibrator管理配置信息。
462. HCS Parser解析Vibrator管理配置信息,并加载对应的马达抽象驱动。
473. Device Manager从linear_vibrator_config.hcs配置文件中读取Vibrator数据配置信息。
484. HCS Parser解析Vibrator数据配置信息,并加载对应的Haptic驱动。
495. Vibrator Proxy获取到Vibrator HDI接口服务实例后,通过IPC(Inter-Process Communication)调用到Vibrator Stub。
506. Vibrator Stub主要处理与IPC相关的业务逻辑,完成参数反序列化后调用Vibrator Controller。
517. Vibrator Controller中是HDI接口的真正实现,通过IPC调用Vibrator抽象驱动接口。
528. 在Haptic驱动中起线程,解析效果模块。
539. Haptic驱动调用马达抽象驱动中的Start接口。
5410. 马达抽象驱动进一步调用马达差异化驱动中的Start接口,控制马达设备以给定的效果振动。
55
56## 开发指导
57
58### 场景介绍
59
60当设备需要设置不同的振动效果时,可以调用Vibrator模块,例如,设备的按键可以设置不同强度和时长的振动,闹钟和来电可以设置不同强度和时长的单次或周期性振动。
61
62### 接口说明
63
64马达驱动模型支持静态HCS配置和动态参数两种振动效果配置能力。马达硬件服务调用StartOnce接口动态配置持续振动,调用Start接口启动静态配置的振动效果。马达驱动模型对外开放的API接口能力,如下表所示。
65
66**表 1** 马达驱动模型对外API接口能力介绍
67
68| 接口名                                  | 功能描述                                           |
69| -------------------------------------- | ------------------------------------------------ |
70| int32_t (*StartOnce)([in] uint32_t duration)                        | 控制马达以执行给定持续时间的单次振动,duration表示单次振动的持续时间。       |
71| int32_t (*Start)([in] const char *effectType)                        | 控制马达以预置效果执行周期性振动,effectType表示指向预设效果类型的指针。     |
72| int32_t (*Stop)([in] enum VibratorMode mode)                         | 停止马达振动,mode表示振动模式,可以是单次或周期性的。                             |
73| int32_t (*EnableVibratorModulation)(uint32_t duration, int32_t intensity, int32_t frequency) | 根据传入的振动效果启动马达,duration表示马达振动的持续时间,intensity表示振动周期内的马达振幅,frequency表示振动周期内的马达频率。 |
74| int32_t (*GetVibratorInfo)([out] struct VibratorInfo **vibratorInfo) | 获取系统中支持设置振幅和频率的所有马达信息,vibratorInfo表示指向马达信息的指针。 |
75
76### 开发步骤
77
78Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能力接口,包括马达一次振动、马达效果配置震动、马达停止。基于HDF驱动框架开发的马达驱动模型,实现跨操作系统迁移、器件差异配置等功能。具体的开发步骤如下:
79
801. 基于HDF驱动框架,按照驱动Driver Entry程序,完成马达抽象驱动开发(主要由Bind、Init、Release、Dispatch函数接口实现),配置资源和HCS解析。
81
82   - 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出马达驱动模型,使用HCS作为配置描述源码。HCS配置字段详细介绍参考[配置管理](driver-hdf-manage.md)。其中Driver Entry入口函数定义如下:
83
84     ```c
85     /* 注册马达抽象驱动入口数据结构体对象 */
86     struct HdfDriverEntry g_vibratorDriverEntry = {
87         .moduleVersion = 1,               // 马达模块版本号
88         .moduleName = "HDF_VIBRATOR",     // 马达模块名,要与device_info.hcs文件里的马达moduleName字段值一样
89         .Bind = BindVibratorDriver,       // 马达绑定函数
90         .Init = InitVibratorDriver,       // 马达初始化函数
91         .Release = ReleaseVibratorDriver, // 马达资源释放函数
92     };
93     /* 调用HDF_INIT将驱动入口注册到HDF框架中 */
94     HDF_INIT(g_vibratorDriverEntry);
95     ```
96
97   - 基于HDF驱动框架,按照驱动Driver Entry程序,完成马达抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现。
98
99     ```c
100     /* 马达驱动对外发布的能力 */
101     static int32_t DispatchVibrator(struct HdfDeviceIoClient *client,
102         int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
103     {
104         int32_t loop;
105
106         for (loop = 0; loop < sizeof(g_vibratorCmdHandle) / sizeof(g_vibratorCmdHandle[0]); ++loop) {
107             if ((cmd == g_vibratorCmdHandle[loop].cmd) && (g_vibratorCmdHandle[loop].func != NULL)) {
108                 return g_vibratorCmdHandle[loop].func(data, reply);
109             }
110         }
111
112         return HDF_SUCCESS;
113     }
114
115     /* 马达驱动对外提供的服务绑定到HDF框架 */
116     int32_t BindVibratorDriver(struct HdfDeviceObject *device)
117     {
118         struct VibratorDriverData *drvData = NULL;
119         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
120
121         drvData = (struct VibratorDriverData *)OsalMemCalloc(sizeof(*drvData));
122         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL);
123
124         drvData->ioService.Dispatch = DispatchVibrator;
125         drvData->device = device;
126         device->service = &drvData->ioService;
127         g_vibratorDrvData = drvData;
128
129         return HDF_SUCCESS;
130     }
131
132     /* 马达驱动初始化入口函数*/
133     int32_t InitVibratorDriver(struct HdfDeviceObject *device)
134     {
135         struct VibratorDriverData *drvData = NULL;
136
137         drvData->mode = VIBRATOR_MODE_BUTT;
138         drvData->state = VIBRATOR_STATE_IDLE;
139         ......
140         if (CreateVibratorHaptic(device) != HDF_SUCCESS) {
141             HDF_LOGE("%s: init workQueue failed!", __func__);
142             return HDF_FAILURE;
143         }
144
145         return HDF_SUCCESS;
146     }
147
148     /* 释放马达驱动初始化时分配的资源 */
149     void ReleaseVibratorDriver(struct HdfDeviceObject *device)
150     {
151         struct VibratorDriverData *drvData = NULL;
152         ......
153         (void)DestroyVibratorHaptic();
154         (void)OsalMutexDestroy(&drvData->mutex);
155         (void)OsalMemFree(drvData);
156         g_vibratorDrvData = NULL;
157     }
158     ```
159
160   - 在系统启动过程中,HDF设备管理模块通过设备HCS配置信息,加载马达抽象驱动,并对外发布马达驱动接口。
161
162     ```c
163     /* 马达设备HCS配置 */
164     vibrator :: host {
165         hostName = "vibrator_host";
166         device_vibrator :: device {
167             device0 :: deviceNode {
168                 policy = 2;                              // 驱动服务发布的策略
169                 priority = 100;                          // 驱动启动优先级(0-200),值越大优先级越低,建议配置100,优先级相同则不保证device的加载顺序
170                 preload = 0;                             // 驱动按需加载字段,0表示加载,2表示不加载
171                 permission = 0664;                       // 驱动创建设备节点权限
172                 moduleName = "HDF_VIBRATOR";             // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致
173                 serviceName = "hdf_misc_vibrator";       // 驱动对外发布服务的名称,必须唯一
174                 deviceMatchAttr = "hdf_vibrator_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等
175            }
176        }
177     }
178     ```
179
1802. 创建马达效果模型,解析马达效果HCS配置。
181
182   - 创建马达效果模型。
183
184     ```c
185     /* 创建马达效果模型,分配资源,解析马达效果HCS配置 */
186     int32_t CreateVibratorHaptic(struct HdfDeviceObject *device)
187     {
188         struct VibratorHapticData *hapticData = NULL;
189         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
190
191         hapticData = (struct VibratorHapticData *)OsalMemCalloc(sizeof(*hapticData));
192         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_ERR_MALLOC_FAIL);
193         g_vibratorHapticData = hapticData;
194         hapticData->supportHaptic = false;
195
196         if (OsalMutexInit(&hapticData->mutex) != HDF_SUCCESS) {
197             HDF_LOGE("%s: failed to init mutex", __func__);
198             goto EXIT;
199         }
200
201         DListHeadInit(&hapticData->effectSeqHead);
202
203         /* 解析马达效果HCS配置 */
204         if (ParserVibratorHapticConfig(device->property) != HDF_SUCCESS) {
205             HDF_LOGE("%s: parser haptic config failed!", __func__);
206             goto EXIT;
207         }
208
209         return HDF_SUCCESS;
210     EXIT:
211         OsalMemFree(hapticData);
212         return HDF_FAILURE;
213     }
214     ```
215
216   - 马达效果模型使用HCS作为配置描述源码,HCS配置文件字段详细介绍参考[配置管理](driver-hdf-manage.md)。
217
218     ```c
219     /* 马达数据配置模板(vibrator_config.hcs) */
220     root {
221         vibratorConfig {
222             boardConfig {
223                 match_attr = "hdf_vibrator_driver"; // 需要和马达设备配置文件中的match_attr字段保持一致
224                 vibratorAttr {
225                     /* 0:转子;1:线性 */
226                     deviceType = 1;                 // 设备类型
227                     supportPreset = 1;              // 支持的预设类型
228                 }
229                 vibratorHapticConfig {
230                     haptic_clock_timer {
231                         effectName = "haptic.clock.timer";
232                         type = 1;                   // 0:内置模式;1:时间序列
233                         seq = [600, 600, 200, 600]; // 时间序列
234                     }
235                     haptic_default_effect {
236                         effectName = "haptic.default.effect";
237                         type = 0;
238                         seq = [0, 3, 800, 1];
239                     }
240                 }
241             }
242         }
243     }
244     ```
245
2463. 完成马达信息获取、振动模式设置和停止的接口开发,并实现根据振动模式创建和销毁定时器。
247
248   马达硬件服务调用StartOnce接口动态配置持续振动时间,调用StartEffect接口启动静态配置的振动效果,为驱动开发者提供抽象的配置接口能力。
249
250   ```c
251   /* 按照指定持续时间触发振动马达,duration为振动持续时长。 */
252   static int32_t StartOnce(struct HdfSBuf *data, struct HdfSBuf *reply)
253   {
254       uint32_t duration;
255       int32_t ret;
256       struct VibratorEffectCfg config;
257       struct VibratorDriverData *drvData = GetVibratorDrvData();
258       (void)reply;
259       ......
260       config.cfgMode = VIBRATOR_MODE_ONCE;
261       config.duration = duration;
262       config.effect = NULL;
263       /* 根据振动效果的模式创建定时器 */
264       ret = StartHaptic(&config);
265       if (ret != HDF_SUCCESS) {
266           HDF_LOGE("%s: start haptic failed!", __func__);
267           return ret;
268       }
269
270       return HDF_SUCCESS;
271   }
272
273   /* 按照预置效果启动马达,effectType表示预置的振动效果。 */
274   static int32_t StartEffect(struct HdfSBuf *data, struct HdfSBuf *reply)
275   {
276       int32_t ret;
277       const char *effect = NULL;
278       struct VibratorEffectCfg config;
279       struct VibratorDriverData *drvData = GetVibratorDrvData();
280       (void)reply;
281       ......
282       config.cfgMode = VIBRATOR_MODE_PRESET;
283       config.duration = 0;
284       config.effect = effect;
285
286       ret = StartHaptic(&config);
287       if (ret != HDF_SUCCESS) {
288           HDF_LOGE("%s: start haptic failed!", __func__);
289           return ret;
290       }
291
292       return HDF_SUCCESS;
293   }
294
295   /* 按照指定的振动模式停止马达振动 */
296   static int32_t Stop(struct HdfSBuf *data, struct HdfSBuf *reply)
297   {
298       int32_t ret;
299       int32_t mode;
300       struct VibratorDriverData *drvData = GetVibratorDrvData();
301       (void)reply;
302       ......
303       /* 停止马达效果振动,销毁马达定时器。 */
304       ret = StopHaptic();
305       if (ret != HDF_SUCCESS) {
306           HDF_LOGE("%s: stop haptic failed!", __func__);
307           return ret;
308       }
309
310       (void)OsalMutexLock(&drvData->mutex);
311       drvData->mode = VIBRATOR_MODE_BUTT;
312       (void)OsalMutexUnlock(&drvData->mutex);
313
314       return HDF_SUCCESS;
315   }
316
317   /* 按照指定振幅、频率、持续时间触发振动马达。duration为振动持续时长,intensity为振动强度,frequency为振动频率。 */
318   static int32_t EnableModulationParameter(struct HdfSBuf *data, struct HdfSBuf *reply)
319   {
320       (void)reply;
321       struct VibratorEffectCfg config;
322       struct VibratorDriverData *drvData;
323       uint32_t duration;
324       int32_t intensity;
325       int32_t frequency;
326       int32_t ret;
327       .....
328       (void)OsalMutexLock(&drvData->mutex);
329       drvData->mode = VIBRATOR_MODE_ONCE;
330       (void)OsalMutexUnlock(&drvData->mutex);
331       /* 设置振幅和频率 */
332       ret = drvData->ops.SetParameter(intensity, frequency);
333       if (ret != HDF_SUCCESS) {
334           HDF_LOGE("%s: set parameter failed", __func__);
335           return HDF_FAILURE;
336       }
337
338       config.cfgMode = VIBRATOR_MODE_ONCE;
339       config.duration = duration;
340       config.effect = NULL;
341
342       ret = StartHaptic(&config);
343       if (ret != HDF_SUCCESS) {
344           HDF_LOGE("%s: start haptic failed", __func__);
345           return HDF_FAILURE;
346       }
347
348       return HDF_SUCCESS;
349   }
350
351   /* 获取马达信息,包括是否支持振幅和频率的设置及振幅和频率的设置范围。 */
352   static int32_t GetVibratorInfo(struct HdfSBuf *data, struct HdfSBuf *reply)
353   {
354       (void)data;
355       struct VibratorDriverData *drvData;
356
357       drvData = GetVibratorDrvData();
358       CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
359       CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM);
360
361       if (!HdfSbufWriteBuffer(reply, &drvData->vibratorInfo, sizeof(drvData->vibratorInfo))) {
362           HDF_LOGE("%s: write sbuf failed", __func__);
363           return HDF_FAILURE;
364       }
365
366       return HDF_SUCCESS;
367   }
368   ```
369
3704. 马达驱动模型提供给开发者马达驱动差异化接口,开发者实现差异化接口。
371
372   - 在差异化器件驱动初始化成功时,注册差异实现接口,方便实现器件差异的驱动接口。
373
374     ```c
375     /* 注册马达差异化实现接口 */
376     int32_t RegisterVibrator(struct VibratorOps *ops)
377     {
378         struct VibratorDriverData *drvData = GetVibratorDrvData();
379
380         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(ops, HDF_FAILURE);
381         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
382
383         (void)OsalMutexLock(&drvData->mutex);
384         drvData->ops.Start = ops->Start;
385         drvData->ops.StartEffect = ops->StartEffect;
386         drvData->ops.Stop = ops->Stop;
387         drvData->ops.SetParameter = ops->SetParameter;
388         (void)OsalMutexUnlock(&drvData->mutex);
389
390         return HDF_SUCCESS;
391     }
392
393     /* 注册马达信息接口 */
394     int32_t RegisterVibratorInfo(struct VibratorInfo *vibratorInfo)
395     {
396         struct VibratorDriverData *drvData = GetVibratorDrvData();
397
398         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorInfo, HDF_FAILURE);
399         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
400
401         (void)OsalMutexLock(&drvData->mutex);
402         if (memcpy_s(&drvData->vibratorInfo, sizeof(drvData->vibratorInfo), vibratorInfo, sizeof(*vibratorInfo)) != EOK) {
403             HDF_LOGE("%s: Memcpy vibrator config failed", __func__);
404             return HDF_FAILURE;
405         }
406         (void)OsalMutexUnlock(&drvData->mutex);
407
408         return HDF_SUCCESS;
409     }
410     ```
411
412
413
414   - 马达驱动模型提供给开发者马达驱动差异化接口,具体实现如下:
415
416     ```c
417     /* 按照指定的振动模式停止马达的振动 */
418     static int32_t StopModulationParameter()
419     {
420         uint8_t value[DRV2605L_VALUE_BUTT];
421         struct Drv2605lDriverData *drvData = NULL;
422         drvData = GetDrv2605lDrvData();
423
424         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
425         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData->drv2605lCfgData, HDF_FAILURE);
426
427         value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_MODE;
428         value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_MODE_STANDBY;
429         if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
430             HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
431             return HDF_FAILURE;
432         }
433
434         value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN;
435         value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultIntensity;
436         if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
437             HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
438         }
439
440         value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON;
441         value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultFrequency;
442         if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
443             HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
444         }
445
446         return HDF_SUCCESS;
447     }
448
449     /* 设置马达振幅和频率 */
450     static void SetModulationParameter(int32_t intensity, int32_t frequency)
451     {
452         uint8_t value[DRV2605L_VALUE_BUTT];
453         struct Drv2605lDriverData *drvData = NULL;
454         drvData = GetDrv2605lDrvData();
455
456         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
457
458         if (intensity != 0) {
459             value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN;
460             value[DRV2605L_VALUE_INDEX] = (uint8_t)INTENSITY_MAPPING_VALUE(intensity);
461             if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
462                 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
463                 return;
464             }
465         } else {
466             HDF_LOGD("%s: the setting of intensity 0 is not supported and \
467                 will be set as the system default intensity", __func__);
468         }
469
470         if (frequency != 0) {
471             value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON;
472             value[DRV2605L_VALUE_INDEX] = (uint8_t)FREQUENCY_MAPPING_VALUE(frequency);
473             if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) {
474                 HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]);
475                 return;
476             }
477         } else {
478             HDF_LOGD("%s: the setting of frequency 0 is not supported and \
479                 will be set as the system default frequency", __func__);
480         }
481     }
482     ```
483
484### 调测验证
485
486驱动开发完成后,在马达单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。
487
488```c++
489/* 用例执行前,初始化马达接口实例。 */
490void HdfVibratorTest::SetUpTestCase()
491{
492    g_vibratorDev = NewVibratorInterfaceInstance();
493}
494/* 用例资源释放 */
495void HdfVibratorTest::TearDownTestCase()
496{
497    if(g_vibratorDev != nullptr){
498        FreeVibratorInterfaceInstance();
499        g_vibratorDev = nullptr;
500    }
501}
502
503/* 测试单次振动 */
504HWTEST_F(HdfVibratorTest, PerformOneShotVibratorDuration_001, TestSize.Level1)
505{
506    ASSERT_NE(nullptr, g_vibratorDev);
507
508    int32_t startRet = g_vibratorDev->StartOnce(g_duration);
509    EXPECT_EQ(startRet, HDF_SUCCESS);
510
511    OsalMSleep(g_sleepTime1);
512
513    int32_t endRet = g_vibratorDev->Stop(VIBRATOR_MODE_ONCE);
514    EXPECT_EQ(endRet, HDF_SUCCESS);
515}
516/* 测试预置效果振动 */
517HWTEST_F(HdfVibratorTest, ExecuteVibratorEffect_002, TestSize.Level1)
518{
519    ASSERT_NE(nullptr, g_vibratorDev);
520
521    int32_t startRet = g_vibratorDev->Start(g_builtIn);
522    EXPECT_EQ(startRet, HDF_SUCCESS);
523
524    OsalMSleep(g_sleepTime1);
525
526    int32_t endRet = g_vibratorDev->Stop(VIBRATOR_MODE_PRESET);
527    EXPECT_EQ(endRet, HDF_SUCCESS);
528}
529/* 获取马达信息,包括是否支持振幅和频率的设置及振幅和频率的设置范围。 */
530HWTEST_F(HdfVibratorTest, GetVibratorInfo_001, TestSize.Level1)
531{
532    ASSERT_NE(nullptr, g_vibratorDev);
533
534    int32_t startRet = g_vibratorDev->GetVibratorInfo(&g_vibratorInfo);
535    EXPECT_EQ(startRet, HDF_SUCCESS);
536    EXPECT_NE(g_vibratorInfo, nullptr);
537
538    printf("intensity = %d, intensityMaxValue = %d, intensityMinValue = %d\n\t",
539    g_vibratorInfo->isSupportIntensity, g_vibratorInfo->intensityMaxValue, g_vibratorInfo->intensityMinValue);
540    printf("frequency = %d, frequencyMaxValue = %d, frequencyMinValue = %d\n\t",
541    g_vibratorInfo->isSupportFrequency, g_vibratorInfo->frequencyMaxValue, g_vibratorInfo->frequencyMinValue);
542}
543/* 按照指定振幅、频率、持续时间触发振动马达。duration为振动持续时长,intensity为振动强度,frequency为振动频率。 */
544HWTEST_F(HdfVibratorTest, EnableVibratorModulation_001, TestSize.Level1)
545{
546    int32_t startRet;
547    ASSERT_NE(nullptr, g_vibratorDev);
548    EXPECT_GT(g_duration, 0);
549
550    if ((g_vibratorInfo->isSupportIntensity == 1) || (g_vibratorInfo->isSupportFrequency == 1)) {
551        EXPECT_GE(g_intensity1, g_vibratorInfo->intensityMinValue);
552        EXPECT_LE(g_intensity1, g_vibratorInfo->intensityMaxValue);
553        EXPECT_GE(g_frequency1, g_vibratorInfo->frequencyMinValue);
554        EXPECT_LE(g_frequency1, g_vibratorInfo->frequencyMaxValue);
555
556        startRet = g_vibratorDev->EnableVibratorModulation(g_duration, g_intensity1, g_frequency1);
557        EXPECT_EQ(startRet, HDF_SUCCESS);
558        OsalMSleep(g_sleepTime1);
559        startRet = g_vibratorDev->Stop(VIBRATOR_MODE_ONCE);
560        EXPECT_EQ(startRet, HDF_SUCCESS);
561    }
562}
563```
564
565