全部博文(13)
2012年(13)
分类:
2012-06-03 20:41:55
原文地址:Android系统移植技术详解三 作者:embededgood
(1)android启动文件系统后调用的第一个应用程序是/init,此文件的很重要的内容是解析了init.rc和init.xxx.rc
两个配置文件,然后执行解析出来的任务。相关代码在android源代码/system/core/init/init.c文件中,如下:
parse_config_file("/init.rc");
/*
pull the kernel commandline and ramdisk properties file in */
qemu_init();
import_kernel_cmdline(0);
get_hardware_name();
snprintf(tmp, sizeof(tmp),
"/init.%s.rc", hardware);
parse_config_file(tmp);
(2)从上面代码可以看到,第一个配置文件名称固定为init.rc,而第二个配置文件格式为init.xxx.rc,其中xxx部分的内容
是从内核读取的,具体是读取文件/proc/cpuinfo中的Hardware部分,然后截取其部分内容。Hardware部分是定义在内核的
主板定义文件中,我的平台是定义在内核arch/arm/mach-mmp/merlin.c中,我的平台定义如下:
MACHINE_START(ARDENT_MERLIN,
"PXA168-based Merlin Platform")
.phys_io = APB_PHYS_BASE,
.boot_params =
0x00000100,
.io_pg_offst = (APB_VIRT_BASE >>
18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa168_init_irq,
.timer =
&pxa168_timer,
.init_machine =
merlin_init,
MACHINE_END
这样截取到的hardware部分的内容就为pxa168-based,也就是说我的平台的第二个配置文件应该命名为init.pxa168-based.rc
(3)从上面看init.xxx.rc中的xxx内容是取决是内核中主板的定义的,如果觉得麻烦,可以将其在代码中写死,例如:
parse_config_file(“init.merlin.rc”);
(4)配置文件的语法如下:
(a)配置文件的内容包含有4种:
动作(Action)
命令(Commands)
服务(Services)
选项(Options)
(b)动作和命令一起使用,形式如下:
on
on
property:persist.service.adb.enable=1
start
adbd
(c)服务和选项一起使用,形式如下:
service
service 服务名称
服务对应的命令的路径 命令的参数
选项
选项
...
举例如下:
service
ril-daemon /system/bin/rild
socket rild stream
660 root radio
socket rild-debug stream 660
radio system
user root
group radio cache inet misc
audio
上面的服务对应到/system/bin/rild命令,没有参数,服务名称为ril-daemon,后面的内容都是服务的选项。
(d)选项是影响服务启动和运行的参数,主要的选项如下:
disabled
禁用服务,此服务开机时不会自动启动,但是可以在应用程序中手动启动它。
socket
创建一个名为/dev/socket/
类型type的值为dgram或者stream
perm表示该套接字的访问权限,user和group表示改套接字所属的用户和组,这两个参数默认都是0,因此可以不设置。
user
group
capability
[
oneshot
服务只启动一次,一旦关闭就不能再启动。
class
(e)动作触发条件
boot
device-added-
device-removed-
service-exited-
(f)命令(Command)的形式
exec
export
ifup
import
hostname
class_start
class_stop
domainname
insmod
mkdir
mount
mount ubifs ubi1_0 /data nosuid nodev
setkey
暂时未定义
setprop
setrlimit
#
set RLIMIT_NICE to allow priorities from 19 to -20
setrlimit 13 40 40
没看懂是什么意思。
start
stop
symlink
symlink /system/etc /etc
write
(g)系统属性(Property)
android初始化过程中会修改一些属性,通过getprop命令我们可以看到属性值,这些属性指示了某些动作或者服务的状态,主要如下:
init.action
如果当前某个动作正在执行则init.action属性的值等于该动作的名称,否则为""
init.command
如果当前某个命令正在执行则init.command属性的值等于该命令的名称,否则为""
init.svc.
首先了解一下tslib的运行原理,tslib的运行分成两部分
(1)校验
在LCD固定坐标位置依次显示出5个坐标让用户触摸,把LCD坐标和用户触摸时驱动屏驱动底层的坐标总共5组值保存起来
运行tslib库的算法对其进行运算,得出校准用7个值
(2)校准
每次触摸屏驱动读取到硬件坐标时应用校准用的7个值对该坐标进行一次运算,然后将运算后的坐标作为正常坐标即可。
按照上面的原理,
(1)我们先修改内核部分,我的平台用的触摸屏幕驱动是tsc2007,驱动文件为内核/drivers/input/touchscreen
目录下的tsc2007.c和ts_linear.c
其中,ts_linear.c中定义的是校准模块,该模块在proc文件系统中建立了7个文件,用来存放校准用的7个点,7的点的默认值
为1,0,0,0,1,0,1,对应的目标平台文件系统的位置为/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6等7个文件
此模块中还定义了一个校准函数ts_linear_scale,此函数的主要内容是读取a0,a1,a2,a3,a4,a5,a6等7个文件中的值作为7个
校准值与传入的触摸平坐标值进行运算,返回运算结果。
ts_linear_scale函数定义如下:
int
ts_linear_scale(int *x, int *y, int swap_xy)
{
int xtemp, ytemp;
xtemp = *x;
ytemp = *y;
if (cal.a[6] == 0)
return -EINVAL;
*x =
(cal.a[2] + cal.a[0] * xtemp + cal.a[1] * ytemp) / cal.a[6];
*y = (cal.a[5] + cal.a[3] * xtemp + cal.a[4] * ytemp) /
cal.a[6];
if (swap_xy) {
int tmp = *x;
*x = *y;
*y = tmp;
}
return 0;
}
ts2007.c为触摸屏驱,与其他驱动不同的地方是在取得硬件坐标值发送之前先调用了ts_linear_scale函数对坐标值进行了校准
if (x > 0 && y >
0)
{
ts_linear_scale(&x, &y, invert);
input_report_abs(input, ABS_X,
x);
input_report_abs(input, ABS_Y, y);
input_report_abs(input,
ABS_PRESSURE, 255);
input_report_abs(input, ABS_TOOL_WIDTH, 1);
input_report_key(input, BTN_TOUCH, 1);
input_sync(input);
}
(2)在android源代码/system/core/rootdir/init.rc文件中添加tslib相关的宏定义如下:
#
touchscreen parameters
export TSLIB_FBDEVICE
/dev/graphics/fb0
export TSLIB_CALIBFILE
/data/etc/pointercal
export TSLIB_CONFFILE
/system/etc/ts.conf
export TSLIB_TRIGGERDEV
/dev/input/event0
export TSLIB_TSDEVICE
/dev/input/event1
(2)移植tslib库到android系统,比较麻烦,看下一节的内容。
(3)校验程序完成后会将生成的7个校准值写入到环境变量TSLIB_CALIBFILE对应的路径/data/etc/pointercal文件中
(4)校验完后将pointercal文件中的7个值分别写入到/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6文件即可。
(5)开机启动的时候我们编写一个应用程序,首先判断环境变量TSLIB_CALIBFILE对应的路径/data/etc/pointercal文件是否存在,如果
文件存在而且非空,则将该文件中的7个值取出来分别写入到/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6文件
(6)为了确保未校验前触摸屏可用,我们将一次校验后得出的7个坐标值作为初始值,修改到内核ts_linear.c文件中。
下面是源代码:
ts_linear.c文件
/*
*
Touchscreen Linear Scale Adaptor
*
*
Copyright (C) 2009 Marvell Corporation
*
*
Author: Mark F. Brown
*
Based on tslib 1.0 plugin linear.c by Russel King
*
*
This library is licensed under GPL.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* sysctl-tuning
infrastructure.
*/
static struct ts_calibration {
/*
Linear scaling and offset parameters for x,y (can include rotation)
*/
int a[7];
} cal;
static ctl_table
ts_proc_calibration_table[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname
= "a0",
.data = &cal.a[0],
.maxlen = sizeof(int),
.mode =
0666,
.proc_handler = &proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "a1",
.data = &cal.a[1],
.maxlen =
sizeof(int),
.mode = 0666,
.proc_handler = &proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "a2",
.data = &cal.a[2],
.maxlen =
sizeof(int),
.mode = 0666,
.proc_handler = &proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "a3",
.data = &cal.a[3],
.maxlen =
sizeof(int),
.mode = 0666,
.proc_handler = &proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "a4",
.data = &cal.a[4],
.maxlen =
sizeof(int),
.mode = 0666,
.proc_handler = &proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "a5",
.data = &cal.a[5],
.maxlen =
sizeof(int),
.mode = 0666,
.proc_handler = &proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "a6",
.data = &cal.a[6],
.maxlen =
sizeof(int),
.mode = 0666,
.proc_handler = &proc_dointvec,
},
{.ctl_name = 0}
};
static
ctl_table ts_proc_root[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname
= "ts_device",
.mode =
0555,
.child =
ts_proc_calibration_table,
},
{.ctl_name = 0}
};
static ctl_table ts_dev_root[] = {
{
.ctl_name = CTL_DEV,
.procname = "dev",
.mode
= 0555,
.child = ts_proc_root,
},
{.ctl_name = 0}
};
static
struct ctl_table_header *ts_sysctl_header;
int
ts_linear_scale(int *x, int *y, int swap_xy)
{
int xtemp, ytemp;
xtemp = *x;
ytemp = *y;
if (cal.a[6] == 0)
return -EINVAL;
*x =
(cal.a[2] + cal.a[0] * xtemp + cal.a[1] * ytemp) / cal.a[6];
*y = (cal.a[5] + cal.a[3] * xtemp + cal.a[4] * ytemp) /
cal.a[6];
if (swap_xy) {
int tmp = *x;
*x = *y;
*y = tmp;
}
return
0;
}
EXPORT_SYMBOL(ts_linear_scale);
static int
__init ts_linear_init(void)
{
ts_sysctl_header = register_sysctl_table(ts_dev_root);
/* Use default values that leave ts numbers unchanged after transform
*/
cal.a[0] = 1;
cal.a[1]
= 0;
cal.a[2] = 0;
cal.a[3] = 0;
cal.a[4] = 1;
cal.a[5] = 0;
cal.a[6] = 1;
return 0;
}
static void __exit
ts_linear_cleanup(void)
{
unregister_sysctl_table(ts_sysctl_header);
}
module_init(ts_linear_init);
module_exit(ts_linear_cleanup);
MODULE_DESCRIPTION("touch
screen linear scaling
driver");
MODULE_LICENSE("GPL");
ts2007.c
/*
*
linux/drivers/input/touchscreen/tsc2007.c
*
*
touch screen driver for tsc2007
*
* Copyright
(C) 2006, Marvell Corporation
*
* This
program is free software; you can redistribute it and/or modify
*
it under the terms of the GNU General Public License version 2 as
*
published by the Free Software Foundation.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
extern int ts_linear_scale(int *x, int
*y, int swap_xy);
/* Use MAV filter */
#define
TSC_CMD_SETUP 0xb0
/* Use 12-bit */
#define TSC_CMD_X
0xc0
#define TSC_CMD_PLATEX 0x80
#define TSC_CMD_Y 0xd0
#define
TSC_CMD_PLATEY 0x90
#define TSC_X_MAX 4096
#define
TSC_Y_MAX 4096
#define TSC_X_MIN 0
#define TSC_Y_MIN 0
/*
delay time for compute x, y, computed as us */
#define
DEBUG
#ifdef DEBUG
#define TS_DEBUG(fmt,args...)
printk(KERN_DEBUG fmt, ##args )
#else
#define
TS_DEBUG(fmt,args...)
#endif
static int x_min=TSC_X_MIN;
static
int y_min=TSC_Y_MIN;
static int x_max=TSC_X_MAX;
static int
y_max=TSC_Y_MAX;
static int invert = 0;
static int
debounce_time = 150;
static int init_debounce = true;
static
int delay_time = 1;
enum tsc2007_status {
PEN_UP,
PEN_DOWN,
};
struct _tsc2007
{
struct input_dev *dev;
int x; /* X sample values */
int y; /* Y sample values
*/
int status;
struct
work_struct irq_work;
struct i2c_client
*client;
unsigned long last_touch;
};
struct
_tsc2007 *g_tsc2007;
/* update abs params when min and max
coordinate values are set */
int tsc2007_proc_minmax(struct
ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
struct _tsc2007 *tsc2007= g_tsc2007;
struct
input_dev *input = tsc2007->dev;
/*
update value */
int ret = proc_dointvec(table,
write, filp, buffer, lenp, ppos);
/*
updated abs params */
if (input) {
TS_DEBUG(KERN_DEBUG "update x_min %d x_max
%d"
" y_min %d y_max %d\n", x_min, x_max,
y_min, y_max);
input_set_abs_params(input, ABS_X, x_min, x_max,
0, 0);
input_set_abs_params(input, ABS_Y, y_min, y_max, 0, 0);
}
return ret;
}
static ctl_table
tsc2007_proc_table[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname = "x-max",
.data =
&x_max,
.maxlen
= sizeof(int),
.mode = 0666,
.proc_handler =
&tsc2007_proc_minmax,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "y-max",
.data =
&y_max,
.maxlen
= sizeof(int),
.mode = 0666,
.proc_handler =
&tsc2007_proc_minmax,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "x-min",
.data =
&x_min,
.maxlen
= sizeof(int),
.mode = 0666,
.proc_handler =
&tsc2007_proc_minmax,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "y-min",
.data =
&y_min,
.maxlen
= sizeof(int),
.mode = 0666,
.proc_handler =
&tsc2007_proc_minmax,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "invert_xy",
.data =
&invert,
.maxlen
= sizeof(int),
.mode = 0666,
.proc_handler =
&proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "debounce_time",
.data =
&debounce_time,
.maxlen = sizeof(int),
.mode =
0666,
.proc_handler
= &proc_dointvec,
},
{
.ctl_name
= CTL_UNNUMBERED,
.procname = "delay_time",
.data =
&delay_time,
.maxlen
= sizeof(int),
.mode = 0666,
.proc_handler =
&proc_dointvec,
},
{
.ctl_name = 0 }
};
static ctl_table tsc2007_proc_root[] =
{
{
.ctl_name = CTL_UNNUMBERED,
.procname = "ts_device",
.mode =
0555,
.child
= tsc2007_proc_table,
},
{ .ctl_name = 0 }
};
static ctl_table
tsc2007_proc_dev_root[] = {
{
.ctl_name = CTL_DEV,
.procname = "dev",
.mode =
0555,
.child
= tsc2007_proc_root,
},
{ .ctl_name = 0 }
};
static struct ctl_table_header
*sysctl_header;
static int __init init_sysctl(void)
{
sysctl_header = register_sysctl_table(tsc2007_proc_dev_root);
return 0;
}
static void __exit cleanup_sysctl(void)
{
unregister_sysctl_table(sysctl_header);
}
static int
tsc2007_measure(struct i2c_client *client, int *x, int * y)
{
u8 x_buf[2] = {0, 0};
u8 y_buf[2] = {0,
0};
i2c_smbus_write_byte(client,
TSC_CMD_PLATEX);
msleep_interruptible(delay_time);
i2c_smbus_write_byte(client, TSC_CMD_X);
i2c_master_recv(client, x_buf, 2);
*x =
(x_buf[0]<<4) | (x_buf[1] >>4);
i2c_smbus_write_byte(client, TSC_CMD_PLATEY);
msleep_interruptible(delay_time);
i2c_smbus_write_byte(client, TSC_CMD_Y);
i2c_master_recv(client, y_buf, 2);
*y =
(y_buf[0]<<4) | (y_buf[1] >>4);
*y
= 4096 - *y; //added by allen
printk("\ntouchscreen x = 0x%x, y = 0x%x\n",*x,*y);
return 0;
}
static void tsc2007_irq_work(struct work_struct
*work)
{
struct _tsc2007 *tsc2007=
g_tsc2007;
struct i2c_client *client =
tsc2007-> client;
struct input_dev *input =
tsc2007->dev;
int x = -1, y = -1,
is_valid = 0;
int tmp_x = 0, tmp_y = 0;
int gpio = irq_to_gpio(client->irq);
/* Ignore if PEN_DOWN */
if(PEN_UP ==
tsc2007->status){
if
(gpio_request(gpio, "tsc2007 touch detect")) {
printk(KERN_ERR "Request
GPIO failed, gpio: %X\n", gpio);
return;
}
gpio_direction_input(gpio);
while(0
== gpio_get_value(gpio)){
if ((jiffies_to_msecs(
((long)jiffies - (long)tsc2007->last_touch)) <
debounce_time &&
tsc2007->status == PEN_DOWN)
||
init_debounce)
{
init_debounce = false;
tsc2007_measure(client, &tmp_x,
&tmp_y);
TS_DEBUG(KERN_DEBUG
"dropping pen touch %lu %lu
(%u)\n",
jiffies, tsc2007->last_touch,
jiffies_to_msecs(
(long)jiffies -
(long)tsc2007->last_touch));
schedule();
continue;
}
/* continue report x, y */
if (x > 0 && y > 0)
{
ts_linear_scale(&x, &y,
invert);
input_report_abs(input, ABS_X, x);
input_report_abs(input, ABS_Y, y);
input_report_abs(input,
ABS_PRESSURE, 255);
input_report_abs(input, ABS_TOOL_WIDTH, 1);
input_report_key(input, BTN_TOUCH, 1);
input_sync(input);
}
tsc2007->status = PEN_DOWN;
tsc2007_measure(client, &x,
&y);
TS_DEBUG(KERN_DEBUG "pen down x=%d y=%d!\n", x, y);
is_valid = 1;
schedule();
}
if
(is_valid)
{
/*consider PEN_UP */
tsc2007->status =
PEN_UP;
input_report_abs(input, ABS_PRESSURE, 0);
input_report_abs(input, ABS_TOOL_WIDTH, 1);
input_report_key(input,
BTN_TOUCH, 0);
input_sync(input);
tsc2007->last_touch = jiffies;
TS_DEBUG(KERN_DEBUG "pen up!\n");
}
gpio_free(gpio);
}
}
static
irqreturn_t tsc2007_interrupt(int irq, void *dev_id)
{
schedule_work(&g_tsc2007->irq_work);
return IRQ_HANDLED;
}
static int
__devinit tsc2007_probe(struct i2c_client *client,
const struct
i2c_device_id *id)
{
struct _tsc2007
*tsc2007;
struct input_dev *input_dev;
int ret;
tsc2007 = kzalloc(sizeof(struct
_tsc2007), GFP_KERNEL);
input_dev =
input_allocate_device();
g_tsc2007 =
tsc2007;
if (!tsc2007 || !input_dev) {
ret = -ENOMEM;
goto fail1;
}
i2c_set_clientdata(client, tsc2007);
tsc2007->dev = input_dev;
input_dev->name = "tsc2007";
input_dev->phys = "tsc2007/input0";
//input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &client->dev;
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(BTN_TOUCH, input_dev->keybit);
__set_bit(EV_ABS, input_dev->evbit);
__set_bit(ABS_PRESSURE, input_dev->evbit);
__set_bit(ABS_X, input_dev->evbit);
__set_bit(ABS_Y, input_dev->evbit);
input_set_abs_params(input_dev, ABS_X, x_min, x_max, 0, 0);
input_set_abs_params(input_dev, ABS_Y, y_min, y_max, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
ret = request_irq(client->irq, tsc2007_interrupt,
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
"tsc2007 irq", NULL);
if (ret){
printk(KERN_ERR
"tsc2007 request irq failed\n");
goto fail2;
}
ret =
input_register_device(tsc2007->dev);
if
(ret){
printk(KERN_ERR
"tsc2007 register device fail\n");
goto fail2;
}
/*init */
tsc2007->status = PEN_UP;
tsc2007->client = client;
tsc2007->last_touch = jiffies;
INIT_WORK(&tsc2007->irq_work, tsc2007_irq_work);
/* init tsc2007 */
i2c_smbus_write_byte(client,
TSC_CMD_SETUP);
return 0;
fail2:
free_irq(client->irq, client);
fail1:
i2c_set_clientdata(client, NULL);
input_free_device(input_dev);
kfree(tsc2007);
return ret;
}
static
int __devexit tsc2007_remove(struct i2c_client *client)
{
struct _tsc2007 *tsc2007 = i2c_get_clientdata(client);
if(client->irq)
free_irq(client->irq, client);
i2c_set_clientdata(client, NULL);
input_unregister_device(tsc2007->dev);
kfree(tsc2007);
return 0;
}
static
struct i2c_device_id tsc2007_idtable[] = {
{
"tsc2007", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
static
struct i2c_driver tsc2007_driver = {
.driver =
{
.name =
"tsc2007",
},
.id_table = tsc2007_idtable,
.probe = tsc2007_probe,
.remove =
__devexit_p(tsc2007_remove),
};
static int __init
tsc2007_ts_init(void)
{
init_sysctl();
return i2c_add_driver(&tsc2007_driver);
}
static void __exit tsc2007_ts_exit(void)
{
cleanup_sysctl();
i2c_del_driver(&tsc2007_driver);
}
module_init(tsc2007_ts_init);
module_exit(tsc2007_ts_exit);
MODULE_DESCRIPTION("tsc2007
touch screen driver");
MODULE_LICENSE("GPL");
(1)切换至tslib目录然后执行如下命令(以marvell平台为例)
./autogen.sh
echo
"ac_cv_func_malloc_0_nonnull=yes" >
arm-marvell-linux.cache
./configure
--host=arm-marvell-linux-gnueabi --prefix=/work/svn/ts_build
--cache-file=arm-marvell-linux.cache
上面三步仅仅是为了取得tslib目录下的config.h文件
(2)将tslib复制到android源代码vendor/
(3)修改vendor/
include
$(LOCAL_PATH)/tslib/Mdroid.mk
一定要主义LOCAL_PATH这个宏的时效性
(4)在tslib目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:=
$(call my-dir)
include $(CLEAR_VARS)
TS_PATH :=
$(LOCAL_PATH)
include $(TS_PATH)/src/Mdroid.mk
include
$(TS_PATH)/plugins/Mdroid.mk
include
$(TS_PATH)/tests/Mdroid.mk
include $(CLEAR_VARS)
file :=
$(TARGET_OUT_ETC)/ts.conf
$(file) : $(TS_PATH)/etc/ts.conf |
$(ACP)
$(transform-prebuilt-to-target)
ALL_PREBUILT +=
$(file)
(5)在tslib/src目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:=
$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=
ts_attach.c ts_close.c ts_config.c \
ts_error.c
ts_fd.c ts_load_module.c ts_open.c ts_parse_vars.c \
ts_read.c ts_read_raw.c ts_option.c
LOCAL_C_INCLUDES +=
\
$(LOCAL_PATH)/../
LOCAL_SHARED_LIBRARIES += libutils
libcutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_PRELINK_MODULE
:= false
LOCAL_MODULE := libts
include
$(BUILD_SHARED_LIBRARY)
(6)在tslib/plugins目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:=
$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=
input-raw.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src
LOCAL_SHARED_LIBRARIES :=
libts
LOCAL_MODULE := input
LOCAL_PRELINK_MODULE :=
false
include $(BUILD_SHARED_LIBRARY)
include
$(CLEAR_VARS)
LOCAL_SRC_FILES:= pthres.c
LOCAL_C_INCLUDES
+= \
$(LOCAL_PATH)/../
\
$(LOCAL_PATH)/../src
LOCAL_SHARED_LIBRARIES :=
libts
LOCAL_MODULE := pthres
LOCAL_PRELINK_MODULE :=
false
include $(BUILD_SHARED_LIBRARY)
include
$(CLEAR_VARS)
LOCAL_SRC_FILES:= variance.c
LOCAL_C_INCLUDES
+= \
$(LOCAL_PATH)/../
\
$(LOCAL_PATH)/../src
LOCAL_SHARED_LIBRARIES :=
libts
LOCAL_MODULE := variance
LOCAL_PRELINK_MODULE :=
false
include $(BUILD_SHARED_LIBRARY)
include
$(CLEAR_VARS)
LOCAL_SRC_FILES:= dejitter.c
LOCAL_C_INCLUDES
+= \
$(LOCAL_PATH)/../
\
$(LOCAL_PATH)/../src
LOCAL_SHARED_LIBRARIES :=
libts
LOCAL_MODULE := dejitter
LOCAL_PRELINK_MODULE :=
false
include $(BUILD_SHARED_LIBRARY)
include
$(CLEAR_VARS)
LOCAL_SRC_FILES:= linear.c
LOCAL_C_INCLUDES
+= \
$(LOCAL_PATH)/../
\
$(LOCAL_PATH)/../src
LOCAL_SHARED_LIBRARIES :=
libts
LOCAL_MODULE := linear
LOCAL_PRELINK_MODULE :=
false
include
$(BUILD_SHARED_LIBRARY)
(7)在tslib/tests目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:=
$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=
ts_calibrate.c fbutils.c testutils.c font_8x8.c
font_8x16.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src
LOCAL_SHARED_LIBRARIES :=
libts
LOCAL_SHARED_LIBRARIES += libutils
libcutils
LOCAL_MODULE := tscalibrate
include
$(BUILD_EXECUTABLE)
(8)在tslib/config.h文件中加入如下定义:
#define
TS_CONF "/system/etc/ts.conf"
#define PLUGIN_DIR
"/system/lib"
#define TS_POINTERCAL
"/data/etc/pointercal"
(9)将下面路径文件
tslib/src/ts_open.c
tslib/tests/ts_calibrate.c
tslib/tests/fbutils.c
中的
#include
#include
(10)
static
int clearbuf(struct tsdev *ts)
修改为
static
void clearbuf(struct tsdev
*ts)
(11)修改tslib/etc/ts.conf内容如下:
module_raw
input
module pthres pmin=1
module variance delta=30
module
dejitter delta=100
module
linear
(12)在android源代码init.rc中声明tslib相关的宏如下:
#
touchscreen parameters
export TSLIB_FBDEVICE
/dev/graphics/fb0
export TSLIB_CALIBFILE
/data/etc/pointercal
export TSLIB_CONFFILE
/system/etc/ts.conf
export TSLIB_TRIGGERDEV
/dev/input/event0
export TSLIB_TSDEVICE
/dev/input/event1
(13)重新编译后即可调用tscalibrate命令来校验触摸屏,校验后产生一个/data/etc/pointercal文件