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