基于MSM平台的振动器驱动移植

来源:互联网 发布:sqlserver备注查询 编辑:程序博客网 时间:2024/05/17 23:50

前言:

振动器是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");


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 姜文怎么克服口吃 说话结巴怎么办 慢性咽炎嗓子干哑说话费劲怎么办 感冒后嗓子不疼 说话费劲怎么办 小孩子在幼儿园内向老尿裤子怎么办 五岁宝宝总是抽鼻子有黄鼻涕怎么办 2岁宝宝头有大人的那么大怎么办 一岁四个月宝宝不理人不说话怎么办 两岁七个月还不会说话怎么办 2岁3个月宝宝说话结巴怎么办 两周的宝宝突然说话结巴怎么办 宝宝3岁半了说话口吃怎么办? 四十天的宝宝吐奶严重怎么办 宝宝吐奶从鼻子喷出来怎么办 六个多月宝宝吐奶一股酸味怎么办 50天的宝宝吃了就吐怎么办 微信语音群聊超过9人怎么办 四个月宝宝母乳不够不喝奶粉怎么办 四个月的宝宝母乳不够吃怎么办 火山直播十多天了还都是假人怎么办 吉利汽车锁了后屁股灯还亮怎么办 六个月凶了他突然不说话了怎么办 微信聊天聊的时间长了没话题怎么办 群聊同学加我微信不想加怎么办? 翡翠销售遇到不说话的客人怎么办 4个月宝宝吃手上瘾怎么办 宝宝吃手上瘾拒绝吃奶粉吃奶怎么办 2岁宝宝特别粘人爱哭怎么办 3岁半宝宝突然说话口吃怎么办 2岁3个月宝宝突然说话结巴怎么办 一位特爱说话爱玩的高中生怎么办 猫5天不吃不喝躲起来该怎么办 两个月的小家猫睡觉要黏人睡怎么办 成年的儿子不听话做父母要怎么办 听到孩子上课又不听话想揍他怎么办 18个月小孩脾气很犟怎么办 烦自己的孩子想弄死他怎么办 楼道经常有小孩在门口恶作剧怎么办 2岁宝宝咳嗽咳吐了怎么办 不小心把鱼刺吃下去该怎么办 儿子在学校被老师甩耳光我该怎么办 家长诬陷老师打她家孩子耳光怎么办