手机都是有震动的效果的,前天飞刀从手机里拆了一个振动器,然后让我下周把这个调一下,昨天来公司小试了一把,就搞定了。下面把过程讲一下吧。
其实android中已经做好了底层的驱动,那便是timed_gpio,就是把定时功能和gpio的功能结合在一起了,振动就是一个小直流电机了,当gpio口是高电平的时候,电机就转动了,当gpio口为低电平的时候,电机就不转了,而time是控制转的时间,也就是gpio口处于高电平的时间。
具体的代码就在/drivers/staging/android/timed_gpio.c
在相关平台的platform.c中加入platform device就可以了。
static struct timed_gpio vibrator = { .name = “vibrator”, .gpio = 61, //对应自己平台的gpio号 .max_timeout = 100000, .active_low = 0; }; static struct timed_gpio_platform_data timed_gpio_data = { .num_gpios = 1, .gpios = &vibrator, }; static struct platform_device my_timed_gpio = { .name = “timed-gpio”, .id = -1, .dev = { .platform_data = &timed_gpio_data, }, };
然后在make menuconfig中选上device下的staging下的android中的相关选项
然后就可以跑一下内核来了,当内核跑起来后,就可以测试了。
因为timed gpio驱动程序为每个设备在/sys/class/timed_output/目录下建立一个子
录,设备子目录的enable文件就是控制设备的时间的。因为在platform中名称为vibrator,
所以,用以下命令可以测试:
echo 10000 > /sys/class/timed_output/vibrator/enable
然后可以看下振动器在转了,也可以用示波器或者万用表来验证
接着可以
cat /sys/class/timed_output/vibrator/enable
发现enable的值一直在变小,直到为0的时候停止了转动了。
OK,底层驱动好了,那么android上层就好办多了,因为android上层几乎和平台关系不大,要改的东西很少很少。
至于android硬件抽象层,在hardware/libhardware_legacy/include/hardware_legacy/ vibrator目录下。
#include <hardware_legacy/vibrator.h> #include "qemu.h" #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #define THE_DEVICE "/sys/class/timed_output/vibrator/enable" int vibrator_exists() { int fd; #ifdef QEMU_HARDWARE if (qemu_check()) { return 1; } #endif fd = open(THE_DEVICE, O_RDWR); if(fd < 0) return 0; close(fd); return 1; } static int sendit(int timeout_ms) { int nwr, ret, fd; char value[20]; #ifdef QEMU_HARDWARE if (qemu_check()) { return qemu_control_command( "vibrator:%d", timeout_ms ); } #endif fd = open(THE_DEVICE, O_RDWR); if(fd < 0) return errno; nwr = sprintf(value, "%d\n", timeout_ms); ret = write(fd, value, nwr); close(fd); return (ret == nwr) ? 0 : -1; } int vibrator_on(int timeout_ms) { /* constant on, up to maximum allowed time */ return sendit(timeout_ms); } int vibrator_off() { return sendit(0); }
看到了吧
#define THE_DEVICE "/sys/class/timed_output/vibrator/enable"
就是我们要操作的底层驱动的地方,只要这个和驱动配上,那么剩下的事情就木有了,直接搞定了。
其实她也是往这里写数据,android的java层就不关心她了。好了,然后可以在android启动后设置一个闹钟来测试下了,发现可以,至此android的vibrator移植成功。
突然发现了,其实以前觉得很难得东西,很不好理解的东西,在过一段时间后再回过头去看的时候才会恍然大悟。学习是个漫长的过程,是一个知识慢慢积累的过程,一口气是吃不成胖子的。