前面我们学习了鼠标是如何如何通过应用程序来读取事件和坐标值的,后面也写了一个简单的input系统的按键驱动程序。
博文如下,讲的内容非常清楚,给小白来入手当然是非常容易的:
http://blog.csdn.net/morixinguan/article/details/69808832
这节,我们来学习一下触摸屏事件获取,然后上一个基于4412开发板ft5x0x型号的x,y坐标值读取,后面我们将从零开始实现这款触摸屏的驱动程序:
首先,我们要明白一个概念,触摸屏在input系统中是一类什么事件呢?
前面我们知道,鼠标是相对事件,也就是相对一个位置的坐标点,那么不是固定的。坐标点会在相对位移上报。
按键是按键事件,有对于的键值,键值也会上报。
那么触摸屏是什么事件?
绝对事件,也就是,触摸的坐标点X和Y会在屏幕的分辨率范围内上报一个绝对的坐标(X,Y)。
那么上报对于的类型(type)如下:EV_ABS
对于的code如下:
绝对于X:
ABS_MT_POSITION_X
绝对于Y:
ABS_MT_POSITION_Y
我用了一个程序获取了屏幕的分辨率,得知分辨率宽为480,高为800。
首先,写这个程序时,我通过adb进到Android根目录,然后用getevent -p查到触摸屏的事件节点为event0,同时也知道触摸屏是一个绝对事件,如下:
接下来,我在Android5.0的源代码external目录下创建了如下目录:Getft5x0x_Test
该目录下有如下两个文件文件:
Android.mk Get_ft5x0x_tp.c
(1)先看Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_SHARED_LIBRARIES += libcutils libutils
#LOCAL_STATIC_LIBRARIES += libz libstdc++ libpng libvtpng
LOCAL_STATIC_LIBRARIES += libz libstdc++ libpng
LOCAL_SRC_FILES := Get_ft5x0x_tp.c
LOCAL_MODULE := ft5x0x_tp
include $(BUILD_EXECUTABLE)
(2)Get_ft5x0x_tp.c
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <dirent.h>
#include <inttypes.h>
#include <errno.h>
//ft5x0x_ts触摸屏事件初始化
int touch_fd = -1 ;
int ft5x0x_ts__init(void)
{
touch_fd = open("/dev/input/event0", O_RDONLY);
if (touch_fd < 0)
{
printf("open /dev/input/event0 failed\n");
return -1;
}
return 0;
}
//获取ft5x0x_ts触摸屏上的坐标点
int Get_ft5x0x_ts_postion(int *x, int *y)
{
int touch_ret = -1 ;
//1、定义一个结构体变量用来描述ft5x0x触摸屏事件
struct input_event ft5x0x_ts ;
//2、读事件
touch_ret = read(touch_fd ,&ft5x0x_ts ,sizeof(ft5x0x_ts));
if(touch_ret < 0){
printf("read touch fair!\n");
}
//3、判断事件类型
switch(ft5x0x_ts.type)
{
case EV_SYN:
break ;
case EV_ABS:
if(ft5x0x_ts.code == ABS_MT_POSITION_X){
*x = ft5x0x_ts.value ;
}
if(ft5x0x_ts.code == ABS_MT_POSITION_Y){
*y = ft5x0x_ts.value ;
}
defalut:
break ;
}
return 0;
}
int main(int argc, char **argv)
{
int tp_ret ;
int ft5x0x_x = 0;
int ft5x0x_y = 0;
tp_ret = ft5x0x_ts__init();
if(-1 == tp_ret){
printf("tp init fair!\n");
return -1 ;
}
printf("tp init success!\n");
while(1)
{ //获取屏幕上的绝对坐标点
Get_ft5x0x_ts_postion(&ft5x0x_x,&ft5x0x_y);
printf("ft5x0x_x:%d ft5x0x_y:%d\n",ft5x0x_x,ft5x0x_y);
usleep(100);
}
return 0;
}
编写万makefile还有.c程序后:
我们切换到Android的根目录下:
用以下命令编译这个程序:
使用m,mm,mmm命令之前一定要先:
执行:source和lunch这两个步骤,如下:
root@morixinguan:/work/android-5.0.2# source build/envsetup.sh
including device/samsung/manta/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including device/friendly-arm/tiny4412/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/asus/deb/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/asus/grouper/vendorsetup.sh
including device/asus/tilapia/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/lge/hammerhead/vendorsetup.sh
including device/lge/mako/vendorsetup.sh
including sdk/bash_completion/adb.bash
root@morixinguan:/work/android-5.0.2# lunch
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_mips-eng
4. aosp_mips64-eng
5. aosp_x86-eng
6. aosp_x86_64-eng
7. aosp_manta-userdebug
8. aosp_shamu-userdebug
9. full_tiny4412-userdebug
10. full_tiny4412-eng
11. mini_emulator_x86_64-userdebug
12. m_e_arm-userdebug
13. mini_emulator_mips-userdebug
14. mini_emulator_arm64-userdebug
15. mini_emulator_x86-userdebug
16. aosp_deb-userdebug
17. full_fugu-userdebug
18. aosp_fugu-userdebug
19. aosp_grouper-userdebug
20. aosp_tilapia-userdebug
21. aosp_flo-userdebug
22. aosp_hammerhead-userdebug
23. aosp_mako-userdebug
Which would you like? [aosp_arm-eng] 20
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.0.2
TARGET_PRODUCT=aosp_tilapia
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.8.0-46-generic-x86_64-with-Ubuntu-16.04-xenial
HOST_BUILD_TYPE=release
BUILD_ID=LRX22G
OUT_DIR=out
============================================
root@morixinguan:/work/android-5.0.2#
接下来,编译程序:
mmm external/Getft5x0x_Test/
然后我们看到以下图片显示:
这个二进制生成的绝对路径是在out目录下,我们需要ft5x0x_tp这个文件,这个名字就是上面Android.mk里面对应的:
LOCAL_MODULE := ft5x0x_tp
Install: out/target/product/tiny4412/system/bin/ft5x0x_tp
将这个文件拷贝到当前目录下:
cp out/target/product/tiny4412/system/bin/ft5x0x_tp .
然后,用USB线连接你的开发板,然后用adb命令将ft5x0x_tp push到system/bin/目录下,这个目录是Android的根文件系统下的一个命令,很多命令都在这个目录下。
如果没有安装adb,可以apt-get install adb 安装adb
push完毕以后:
我们在终端: adb shell切换到根目录下:
执行ft5x0x_tp这个bin文件,然后我们触摸触摸屏,如下,坐标值打印出来了。