功能简介
为了快速开发马达驱动,基于HDF(Hardware Driver Foundation)驱动框架开发了马达(Vibrator)驱动模型。马达驱动模型,屏蔽设备驱动与系统交互的实现,为硬件服务层提供统一稳定的驱动接口能力,为驱动开发者提供开放的接口和解析接口的能力,用于不同操作系统马达设备部件的部署指导和马达设备部件驱动的开发。马达驱动模型如图1所示:
图 1 马达驱动模型图
基本概念
根据振动原理的不同,目前马达可以分为两种:
-
转子马达
转子马达依靠旋转带动配重振动,分为普通转子和币型转子两种。转子马达的启停反应慢,并且无法实现多种振动模式,但其优点是成本低且体积小。
-
线性马达
线性马达依靠磁力快速抖动配重来振动,分为纵向线性马达和横向线性马达两种。线性马达的启停都非常快,可以实现不同振感且具有良好的方向性。
系统通过调用马达驱动接口实现对设备的振动控制。目前,马达只有两种振动方式:
-
单次振动
单次振动是指按照指定的时间控制振动时长。
-
周期振动
周期振动是指按照预置的效果模式控制振动。例如:预置效果为“haptic.clock.timer” = [600, 600, 200, 600],表示等待600ms,振动600ms,等待200ms,振动600ms。
运作机制
通过介绍马达驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如图2所示:
图2 马达驱动运行图
以标准系统RK3568产品为例,介绍马达模块驱动加载及运行流程:
- Device Manager从device_info.hcs配置文件中读取Vibrator管理配置信息。
- HCS Parser解析Vibrator管理配置信息,并加载对应的马达抽象驱动。
- Device Manager从linear_vibrator_config.hcs配置文件中读取Vibrator数据配置信息。
- HCS Parser解析Vibrator数据配置信息,并加载对应的Haptic驱动。
- Vibrator Proxy获取到Vibrator HDI接口服务实例后,通过IPC(Inter-Process Communication)调用到Vibrator Stub。
- Vibrator Stub主要处理与IPC相关的业务逻辑,完成参数反序列化后调用Vibrator Controller。
- Vibrator Controller中是HDI接口的真正实现,通过IPC调用Vibrator抽象驱动接口。
- 在Haptic驱动中起线程,解析效果模块。
- Haptic驱动调用马达抽象驱动中的Start接口。
- 马达抽象驱动进一步调用马达差异化驱动中的Start接口,控制马达设备以给定的效果振动。
开发指导
场景介绍
当设备需要设置不同的振动效果时,可以调用Vibrator模块,例如,设备的按键可以设置不同强度和时长的振动,闹钟和来电可以设置不同强度和时长的单次或周期性振动。
接口说明
马达驱动模型支持静态HCS配置和动态参数两种振动效果配置能力。马达硬件服务调用StartOnce接口动态配置持续振动,调用Start接口启动静态配置的振动效果。马达驱动模型对外开放的API接口能力,如下表所示。
表 1 马达驱动模型对外API接口能力介绍
注:以下接口列举的为C接口,接口声明见文件/drivers/peripheral/vibrator/interfaces/include。
接口名 | 功能描述 |
---|---|
int32_t (*StartOnce)(uint32_t duration) | 控制马达以执行给定持续时间的单次振动,duration表示单次振动的持续时间。 |
int32_t (*Start)(const char *effectType) | 控制马达以预置效果执行周期性振动,effectType表示指向预设效果类型的指针。 |
int32_t (*Stop)(enum VibratorMode mode) | 停止马达振动,mode表示振动模式,可以是单次或周期性的。 |
int32_t (*EnableVibratorModulation)(uint32_t duration, int32_t intensity, int32_t frequency) | 根据传入的振动效果启动马达,duration表示马达振动的持续时间,intensity表示振动周期内的马达振幅,frequency表示振动周期内的马达频率。 |
int32_t (*GetVibratorInfo)(struct VibratorInfo **vibratorInfo) | 获取系统中支持设置振幅和频率的所有马达信息,vibratorInfo表示指向马达信息的指针。 |
int32_t (*EnableCompositeEffect)(struct CompositeEffect *effect); | 控制马达以自定义复合效果进行周期性振动。 |
int32_t (*GetEffectInfo)(const char *effectType, struct EffectInfo *effectInfo); | 获取指定效果类型的振动效果信息。 |
int32_t (*IsVibratorRunning)(bool state); | 获取到的马达当前是否正在振动。 |
int32_t (*PlayHapticPattern)(const HapticPaket& pkg); | 以pkg数据包的形式下发高清振动数据进行振动。 |
int32_t (*GetHapticCapacity)(HapticCapacity& hapticCapacity); | 获取马达振动能力,包含是否支持高清振动、是否支持预定义波形、是否支持延时振动。 |
int32_t (*GetHapticStartUpTime)(int32_t mode, int32_t& startUpTime); | 获取起振延时,mode表示振动模式,startUpTime是出参,表示起振延时。 |
开发步骤
Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能力接口,包括马达一次振动、马达效果配置震动、马达停止。基于HDF驱动框架开发的马达驱动模型,实现跨操作系统迁移、器件差异配置等功能。以线性马达驱动为例介绍马达驱动开发。
-
开发马达抽象驱动。
-
马达抽象驱动在Vibrator Host中的配置信息,代码实现路径如下:vendor\hihope\rk3568\hdf_config\khdf\device_info\device_info.hcs。
具体代码实现如下:
/* 马达设备HCS配置 */ vibrator :: host { hostName = "vibrator_host"; device_vibrator :: device { device0 :: deviceNode { policy = 2; // 驱动服务发布的策略 priority = 100; // 驱动启动优先级(0-200),值越大优先级越低,建议配置100,优先级相同则不保证device的加载顺序 preload = 0; // 驱动按需加载字段,0表示加载,2表示不加载 permission = 0664; // 驱动创建设备节点权限 moduleName = "HDF_VIBRATOR"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 serviceName = "hdf_misc_vibrator"; // 驱动对外发布服务的名称,必须唯一 deviceMatchAttr = "hdf_vibrator_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 } } }
-
创建马达效果模型,解析马达效果HCS配置,代码实现路径:drivers\hdf_core\framework\model\misc\vibrator\driver\src\vibrator_haptic.c。
具体代码实现如下:
/* 创建马达效果模型 */ int32_t CreateVibratorHaptic(struct HdfDeviceObject *device) { struct VibratorHapticData *hapticData = NULL; CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE); hapticData = (struct VibratorHapticData *)OsalMemCalloc(sizeof(*hapticData)); CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_ERR_MALLOC_FAIL); g_vibratorHapticData = hapticData; hapticData->supportHaptic = false; if (OsalMutexInit(&hapticData->mutex) != HDF_SUCCESS) { HDF_LOGE("%s: fail to init mutex", __func__); goto EXIT; } DListHeadInit(&hapticData->effectSeqHead); // get haptic hcs if (ParserVibratorHapticConfig(device->property) != HDF_SUCCESS) { HDF_LOGE("%s: parser haptic config fail!", __func__); goto EXIT; } return HDF_SUCCESS; EXIT: OsalMemFree(hapticData); return HDF_FAILURE; }
-
马达抽象驱动代码实现路径:drivers\hdf_core\framework\model\misc\vibrator\driver\src\vibrator_driver.c。
-
马达抽象驱动对应的HdfDriverEntry对象,其中,Driver Entry入口函数定义如下:
/* 注册马达抽象驱动入口数据结构体对象 */ struct HdfDriverEntry g_vibratorDriverEntry = { .moduleVersion = 1, // 马达模块版本号 .moduleName = "HDF_VIBRATOR", // 马达模块名,要与device_info
-
-