前言:

振动器是Android智能手机操作系统中比较常见的功能之一,在实际应用中可以将来电显示设置为振动模式作为提醒。在Android系统中,通过振动系统米快可以实现俩点铃声和来电的振动功能。。本篇blog主要是向大家介绍在高通平台上移植振动器驱动框架以及代码实现的过程。

一、振动器系统框架

振动器系统自下而上包含了驱动程序、振动器系统硬件抽象层、振动器系统Java框架类、Java框架中振动器系统使用等几部分,其结构如下图所示

Android振动器系统的框架结构 振动器系统结构元素

结构说明:

1)驱动程序:某个特定硬件凭条振动其的驱动程序。通常是基于Android的timed output 驱动框架来实现的。

2)硬件抽象层:振动器系统的硬件抽象层的接口路径是hardware/libhardware_legacy/include/hardware_legacy/vibrator.h

其默认代码路径是:hardware/libhardware_legacy/vibrator/vibrator.c

因为Android振动器的硬件抽象层是libhardware_legacy.so的一部分。所以通常并不需要重新实现。

3)JNI框架部分:代码路径是frameworks/base/services/jni/com_andriod_server_vibrarorservice.cpp

此文件定义了振动器的JNI部分,通过调用硬件抽象层向上层提供接口。

4)Java应用部分:振动器系统的Java不封的代码路径是frameworks/base/services/java/com/android/server/vibratorservice.java和frameworks/base/vore/java/android/ps/vibrator.java

文件vibaratorservice.java通过调用vibratorService JNI来实现包com.android.server中的类VibratorService。

类Vibtator.java中实现Android.os包中的Vibrator类。这是想Java层提供的API。

二、代码分析

1)在hardware/libhardware_legacy/include/hardware_legacy/vibrator.h中主要实现功能分析:

int vibrator_exists(); //判断设备是否注册到系统中

int vibrator_on(int timeout_ms); //按照形参的值来决定Vibrator运行的时间

int vibrator_off(); //关闭Vibtator


2)在hardware/libhardware_legacy/vibrator/vibrator.c中主要函数分析:

int vibrator_exists(); //判断设备是否注册到系统中

static int sendit(int timeout_ms); //设置Vibrator的运行时间

int vibrator_on(int timeout_ms); //开启Vibrator

int vibrator_off(); //关闭Vibrator

3)在frameworks/base/services/jni/com_andriod_server_vibrarorservice.cpp中主要函数分析:

static JNINativeMethod method_table[] = {

  { "vibratorOn", "(J)V", (void*)vibrator_on }, // 振动器开
 
  { "vibratorOff", "()V", (void*)vibrator_off } // 振动器关
 
  };
 
  int register_android_server_VibratorService(JNIEnv *env) {
 
  return jniRegisterNativeMethods(env, "com/android/server/VibratorService",
 
  method_table, NELEM(method_table));
 
  }
  //vibratorOn()和vibratorOff()这两个函数的实现分别如下所示:
 
  
 
  static void vibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms){
 
  vibrator_on(timeout_ms);
 
  }
 
  static void vibratorOff(JNIEnv *env, jobject clazz){
 
  vibrator_off();
 
  }

frameworks/base/services/java/com/android/server/目录中的VibratorService.java通过调用VibratorService JNI来实现com.android.server包中的VibratorService类。

  frameworks/base/core/java/android/os/目录中的Vibrator.java文件实现了android.os包中的Vibrator类。它通过调用vibrator的Java服务来实现(获得名称为vibrator的服务),配合同目录中的IVibratorService.aidl文件向应用程序层提供Vibrator的相关API。


4)在内核驱动代码kernel/arch/arm/mach-msm/msm_vibrator.c中的实现:

#define PMIC_VIBRATOR_LEVEL     (3000) //设置震动强度,3000mv  
  
static struct work_struct work_vibrator;  
static int vibe_state; //记录motor的状态  
static struct hrtimer vibe_timer;  
  
static DEFINE_MUTEX(vibe_mtx);  
static spinlock_t vibe_lock;  
  
static void update_vibrator(struct work_struct *work)  
{  
        set_pmic_vibrator(vibe_state);  
}  
//star timer or not,schedule work.NOT control vibrator voltage!  
static void vibrator_enable(struct timed_output_dev *dev, int value)  
{  
        unsigned long   flags;  
        spin_lock_irqsave(&vibe_lock, flags);  
        hrtimer_cancel(&vibe_timer);  
  
        if (value == 0)  
                vibe_state = 0;  
        else {  
                value = (value > 15000 ? 15000 : value);          
                vibe_state = 1;  
                hrtimer_start(&vibe_timer,  
                              ktime_set(value / 1000, (value % 1000) * 1000000),  
                              HRTIMER_MODE_REL);  
        }  
        spin_unlock_irqrestore(&vibe_lock, flags);  
        schedule_work(&work_vibrator);//执行这个函数会立即导致work_vibrator这个work_struct中的func函数被调用  
}  
static int vibrator_get_time(struct timed_output_dev *dev)  
{  
        if (hrtimer_active(&vibe_timer)) {  
                ktime_t r = hrtimer_get_remaining(&vibe_timer);  
                return r.tv.sec * 1000 + r.tv.nsec / 1000000;  
        } else  
                return 0;  
}  
//turn ON/OFF Motor  
static void set_pmic_vibrator(int on)  
{  
    static struct msm_rpc_endpoint *vib_endpoint;  
    struct set_vib_on_off_req {  
        struct rpc_request_hdr hdr;  
        uint32_t data;  
    } req;  
    if(mutex_lock_interruptible(&vibe_mtx))  
               return;  
  
    if (!vib_endpoint) {  
        vib_endpoint = msm_rpc_connect(PM_LIBPROG, PM_LIBVERS, 0);  
        if (IS_ERR(vib_endpoint)) {  
            printk(KERN_ERR "init vib rpc failed!\n");  
            vib_endpoint = 0;  
            mutex_unlock(&vibe_mtx);  
            return;  
        }  
    }  
  
    if (on)  
        req.data = cpu_to_be32(PMIC_VIBRATOR_LEVEL);//bigendian32,设置驱动马达的voltage  
    else  
        req.data = cpu_to_be32(0);//停止震动  
  
    //控制电压,使motor震动或关闭  
    msm_rpc_call(vib_endpoint, HTC_PROCEDURE_SET_VIB_ON_OFF, &req,  
        sizeof(req), 5 * HZ);  
  
    mutex_unlock(&vibe_mtx);  
}   
//定时器time out会调用这个函数,修改state,调度work  
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)  
{  
        vibe_state = 0;  
        schedule_work(&work_vibrator);//  
        return HRTIMER_NORESTART;  
}  
<pre name="code" class="cpp">static struct timed_output_dev pmic_vibrator = {   
        .name = "vibrator",//sysFS下文件夹的名字 /sys/class/timed_output/vibrator  
        .get_time = vibrator_get_time,  
        .enable = vibrator_enable,  
};  
<pre name="code" class="cpp">void __init msm_init_pmic_vibrator(void)  
{  
        INIT_WORK(&work_vibrator, update_vibrator);//仅仅是初始化work_vibrator这个结构体  
  
        spin_lock_init(&vibe_lock);  
        vibe_state = 0;  
  
        hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);//初始hrtimer  
        vibe_timer.function = vibrator_timer_func;//给定时器超时callback函数赋值  
  
        timed_output_dev_register(&pmic_vibrator);//注册这个vibrator设备  
}  
  
MODULE_DESCRIPTION("timed output pmic vibrator device");  
MODULE_LICENSE("GPL");

基于MSM平台的振动器驱动移植相关推荐

  1. esp32系列(11):ESP32 IDF平台 mpu6050 DMP 驱动移植及测试上位机开发

    目录 1 DMP 官方库介绍 1.1 DMP与MPL(Motion Processing Libraries)功能 1.2 运行MPL的硬件要求 1.3 Motion Driver 6.12 的架构 ...

  2. MTK平台的LCM驱动移植

    一.Android系统开机启动过程及驱动概述: MTK平台的显示驱动分两块,一块在LK代码里面,一块在kernel代码里面: LK的lcm驱动路径在:vendor\mediatek\proprieta ...

  3. 基于zynq7000平台的vxWorks6.9移植(上)

    1 致谢 编写本文档的目的在于指导用户如何移植基于z7平台的vxWorks6.9系统.移植之前首先感谢西安迅尔电子嵌入式工程师庞国强,本次是基于前者总结资料的基础上进行的完善,帮助新手可以以更少的指导 ...

  4. 高通平台开发系列讲解(外设篇)高通平台Camera摄像头驱动移植

    文章目录 一.高通平台摄像头软件框架 二.相关代码目录 三.驱动移植 3.1.新增camera节点 3.2.配置相关的GPIO 沉淀.分享.成长,让自己和他人都能有所收获!

  5. mtk6582平台GT9157触摸屏驱动移植

    一.GT9157触摸屏移植 1.在mediatek/config/sanstar82_cwet_kk/ProjectConfig.mk中 CUSTOM_KERNEL_TOUCHPANEL=GT9XX ...

  6. 基于MT6572/32平台 Android 版本驱动移植日志

    根据MK官网所述,在Android L 版本上Turnkey ABS 架构将会phase out,而Mediatek Turnkey架构将会全面转向Turnkey AOSP架构.本博文将会大致描述下如 ...

  7. android+usb转串口+唯一id,Android平台3G模块驱动移植-USB转串口

    Android平台3g模块是通过ril库来支持数据.短信.彩信.电话.第三方通话.USSD等功能的.其相应的组件有:rild用来为rild socket建立文件,pppd和chat为拨号文件,libr ...

  8. android usb wifi驱动下载,android 平台USB wifi驱动移植及使用

    一.   Android平台Wifi的基本代码路径 1.       Wpa_supplicant源码部分 external/wpa_supplicant_6/ 生成库libwpa_client.so ...

  9. 基于imx6的gt911触摸屏驱动移植

    参考:https://blog.csdn.net/zhuyuming/article/details/52652525?locationNum=3 实验平台:TQ_iMX6Q 其实在Linux内核官网 ...

最新文章

  1. SQL Server 2005/2008 用户数据库文件默认路径和默认备份路径修改方法
  2. 继中美之后,欧盟会成为下一个 AI 超级体吗?
  3. Handler消息处理机制详解
  4. c#如何将多个json合并_合并两个c#对象(json)列表作为父级子级
  5. java struts2 表达式语言 ognl 简介
  6. C#windows服务开发
  7. windows密钥连接linux,windows使用密钥登录linux
  8. oracle resetlogs 误删,oracle undo表空间误删恢复
  9. 非整数倍数数据位宽转换8to12
  10. mysql安装之后怎么进入_MySQL常规练习 .MySQL安装成功后的进入方式
  11. TableviewController基础
  12. C++内存管理(转)http://www.cnblogs.com/qiubole/archive/2008/03/07/1094770.html
  13. QQ密码算法 用于命令行登录
  14. 安防行业相关标准、法律及规划一览
  15. Windows10更新工具
  16. 计算机专业电子技术基础教学,计算机专业“电子技术基础”教学上的难题及对策.doc...
  17. STM32机器人控制开发教程No.2 霍尔编码器电机测速以及增量式PID控制(基于HAL库)
  18. 用JavaScript实现简单的乘法计算
  19. 如何让工作更有活力?社科院与杜兰大学金融管理硕士项目帮你充电续航
  20. html id命名规范,CSS常用类/ID命名规范

热门文章

  1. 开店前必看|咖啡行业前景怎么样?咖啡行业开店利润高吗
  2. kiwi浏览器打开网页慢_Kiwi浏览器app下载
  3. Transformer(multi-head attention)
  4. python实现12306自动抢票脚本-splinter结合chrome浏览器
  5. centos7修改ip地址(centos7怎么修改ip)
  6. 为什么大医院总是人山人海?他想用“虚拟病人”为医疗均衡寻找答案
  7. Win10 只有Edge无法上网的解决方法
  8. 从全职高手开始的系统_第一章 全职高手系统
  9. JavaScript基础-练习-页面小游戏剪刀石头布
  10. 计算机桌面太暗了怎么调亮,笔记本电脑显示器太暗怎么调亮一点?一招教你搞定!...