ANDROID5.0触摸屏校准

1.校准原理:

1)首先生成校准用的参数,可以使用tslib生成校准参数,也可以使用校准app生成;使用校准app进行校准对使用者要求比较低,使用者可以不用学习复杂的命令;本文使用app方式

2)生成校准参数后,以后驱动每次接收到触摸事件就会使用校准参数进行校准

 2.校准app

校准功能完全实现在在src目录里的MainActivity.java里,内容如下:

package com.wss.calibrate2;

import android.app.Activity;
import android.os.Bundle;
import android.view.Display;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import android.os.SystemProperties;

public class MainActivity extends Activity {

static final int SAMPLE_COUNTS = 5;
static final int POINT_DEGREE = 2;
static final int FACTOR_COUNTS = 7;
static final int TOP_LEFT = 0;
static final int TOP_RIGHT = 1;
static final int BOTTOM_RIGHT = 2;
static final int BOTTOM_LEFT = 3;
static final int CENTER = 4;
static final int X_AXIS = 0;
static final int Y_AXIS = 1;
static final int EDGE_GAP = 50;

static final String CALIBRATION_FILE = "/data/calibration";
static final String TAG = "Calibration";
static final boolean DEBUG = true;

private int X_RES;
private int Y_RES;
private Display dpy;

class calibration {
int x[] = new int[5];
int y[] = new int[5];
int xfb[] = new int[5];
int yfb[] = new int[5];
int a[] = new int[7];
};
private calibration cal;

String proGetStartString=null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//proGetStartString=SystemProperties.get("sys.config.calibrate");
//Log.w(TAG, "Calibration"+proGetStartString);
SystemProperties.set("sys.config.calibrate", "start");
cal = new calibration();
dpy = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
X_RES = dpy.getWidth();
Y_RES = dpy.getHeight();
this.initScreenPoints();
this.initScreenPoints();
setContentView(new MyView(this));



}

private boolean perform_calibration() {
float n, x, y, x2, y2, xy, z, zx, zy;
float det, a, b, c, e, f, g;
float scaling = (float)65536.0;

n = x = y = x2 = y2 = xy = 0;
for (int i = 0; i < SAMPLE_COUNTS; i++) {
n += 1.0;
x += (float)cal.x[i];
y += (float)cal.y[i];
x2 += (float)(cal.x[i] * cal.x[i]);
y2 += (float)(cal.y[i] * cal.y[i]);
xy += (float)(cal.x[i] * cal.y[i]);
}

det = n * (x2 * y2 - xy * xy) + x * (xy * y - x * y2) + y * (x * xy - y * x2);
if (det < 0.1 && det > -0.1) {
Log.w(TAG, "determinant is too small, det =" + det);
return false;
}

if (DEBUG) {
Log.i(TAG, "(n,x,y,x2,y2,xy,det)=("
+ n + ","
+ x + ","
+ y + ","
+ x2 + ","
+ y2 + ","
+ xy + ","
+ det + ")");
}

a = (x2 * y2 - xy * xy) / det;
b = (xy * y - x * y2) / det;
c = (x * xy - y * x2) / det;
e = (n * y2 - y * y) / det;
f = (x * y - n * xy) / det;
g = (n * x2 - x * x) / det;

Log.i(TAG, "(a,b,c,e,f,g)=("
+ a + ","
+ b + ","
+ c + ","
+ e + ","
+ f + ","
+ g + ")");

// Get sums for x calibration
z = zx = zy = 0;
for(int i = 0; i < SAMPLE_COUNTS; i++) {
z += (float)cal.xfb[i];
zx += (float)(cal.xfb[i] * cal.x[i]);
zy += (float)(cal.xfb[i] * cal.y[i]);
}
// Now multiply out to get the calibration for X coordination
cal.a[0] = (int)((a * z + b * zx + c * zy) * (scaling));
cal.a[1] = (int)((b * z + e * zx + f * zy) * (scaling));
cal.a[2] = (int)((c * z + f * zx + g * zy) * (scaling));
// Get sums for y calibration
z = zx = zy = 0;
for(int i = 0;i < SAMPLE_COUNTS; i++) {
z += (float)cal.yfb[i];
zx += (float)(cal.yfb[i] * cal.x[i]);
zy += (float)(cal.yfb[i] * cal.y[i]);
}
// Now multiply out to get the calibration for Y coordination
cal.a[3] = (int)((a * z + b * zx + c * zy) * (scaling));
cal.a[4] = (int)((b * z + e * zx + f * zy) * (scaling));
cal.a[5] = (int)((c * z + f * zx + g * zy) * (scaling));

cal.a[6] = (int)scaling;

return true;
}
private boolean initScreenPoints() {
cal.xfb[TOP_LEFT] = EDGE_GAP; // TopLeft
cal.yfb[TOP_LEFT] = EDGE_GAP;

cal.xfb[TOP_RIGHT] = X_RES - EDGE_GAP; // TopRight
cal.yfb[TOP_RIGHT] = EDGE_GAP;

cal.xfb[BOTTOM_RIGHT] = X_RES - EDGE_GAP; // BottomRight
cal.yfb[BOTTOM_RIGHT] = Y_RES - EDGE_GAP;

cal.xfb[BOTTOM_LEFT] = EDGE_GAP; // BottomLeft
cal.yfb[BOTTOM_LEFT] = Y_RES - EDGE_GAP;

cal.xfb[CENTER] = X_RES / 2; // Center
cal.yfb[CENTER] = Y_RES / 2;

Log.w(TAG, "cal.yfb[center] =" + cal.yfb[CENTER]);

return true;
}
private boolean saveCalibrationResult() {
FileOutputStream os;
String res = "";

// save the calibration factor in file system for InputDevice
try {
os = new FileOutputStream(CALIBRATION_FILE);
res = String.format("%d %d %d %d %d %d %d", cal.a[1], cal.a[2], cal.a[0], cal.a[4], cal.a[5], cal.a[3], cal.a[6]);

if (DEBUG) {
Log.i(TAG, "calibration result=" + res);
}
os.write(res.getBytes());
os.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
Log.w(TAG, "open calibration file write error!!!!!: " + CALIBRATION_FILE );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}

public class MyView extends View {
private Canvas cv;
private Paint paint;
private Bitmap bmp;
private int screen_pos;
private Context mContext;
public MyView(Context c) {
super(c);
// set full screen and no title
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setmContext(c);
paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
bmp = Bitmap.createBitmap(X_RES, Y_RES, Bitmap.Config.ARGB_8888);
cv = new Canvas(bmp);
screen_pos = 0;
drawCalibrationCross(screen_pos);
}

protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(bmp, 0, 0, null);
}

private boolean drawCalibrationCross(int pos) {

if (DEBUG) {
Log.i(TAG, "draw cross at pos " + pos);
}

cv.drawColor(Color.BLACK);

// draw X line
cv.drawLine(cal.xfb[pos] - 10, cal.yfb[pos],
cal.xfb[pos] - 2, cal.yfb[pos], paint);
cv.drawLine(cal.xfb[pos] + 2, cal.yfb[pos],
cal.xfb[pos] + 10, cal.yfb[pos], paint);

// draw Y line
cv.drawLine(cal.xfb[pos], cal.yfb[pos] - 10,
cal.xfb[pos], cal.yfb[pos] - 2, paint);
cv.drawLine(cal.xfb[pos], cal.yfb[pos] + 2,
cal.xfb[pos], cal.yfb[pos] + 10, paint);
invalidate();
return true;
}
public boolean onTouchEvent(MotionEvent event) {
float tmpx, tmpy;
boolean ret;
String proGetString=null;
if (screen_pos > SAMPLE_COUNTS - 1) {
Log.i(TAG, "get sample ok");
return true;
}

if (event.getAction() == MotionEvent.ACTION_UP) {
tmpx = event.getX();
tmpy = event.getY();
if(Math.abs(cal.xfb[screen_pos]-tmpx)>15&&
Math.abs(cal.yfb[screen_pos]-tmpy)>15){
//Toast.makeText(mContext, R.string.toast, Toast.LENGTH_SHORT).show();
return false;
}

cal.x[screen_pos] = (int)(event.getX()*4096.0/(float)X_RES + 0.5);
cal.y[screen_pos] = (int)(event.getY()*4096.0/(float)Y_RES + 0.5);

if (screen_pos == 4) {
ret = perform_calibration();
if (ret) {
saveCalibrationResult();
SystemProperties.set("sys.config.calibrate", "done");
//proGetString=SystemProperties.get("sys.config.calibrate");
//Log.w(TAG, "Calibration"+proGetString);
finish();
return true;
} else {
screen_pos = 0;
Log.w(TAG, "Calibration failed");
}
} else {
screen_pos++;
drawCalibrationCross(screen_pos);
}
}
return true;
}

public Context getmContext() {
return mContext;
}

public void setmContext(Context mContext) {
this.mContext = mContext;
}

}
}

编写好校准app后,在app顶层目录编写Android.mk,Android.mk内容如下:

1 LOCAL_PATH:= $(call my-dir)
2 include $(CLEAR_VARS)
3
4 LOCAL_MODULE_TAGS := optional
5
6 LOCAL_SRC_FILES :=
7 $(call all-java-files-under)
8
9 include $(CLEAR_VARS)
10
11 LOCAL_MODULE_TAGS := optional
12
13 LOCAL_SRC_FILES :=
14 $(call all-java-files-under, src)
15
16 LOCAL_PACKAGE_NAME := Calibrate
17 LOCAL_CERTIFICATE := platform
18 LOCAL_MULTILIB := 32
19
20 include $(BUILD_PACKAGE)
21

在17行的地方,赋予了app修改android系统属性的权限,这也是需要编写Android.mk并在android源码里编译该app的原因,因为在eclipse里编译出来的app是没有这个权限的,校准不会成功。

3.在app里指定了生成的校准参数存放在/data/calibration里面,接下来需要把校准参数传给tsc2007.c驱动(也许有其他更好的方法,因为android5.0没有frameworks/base/services/java/com/android/server/InputDevice.java文件,所以我只想到了这个方法)

把校准参数专递给tsc2007驱动需要做做两件事

1)编写copy.sh脚本,把参数传给驱动

copy.sh内容:

#!/system/bin/sh
mount -o remount,rw rootfs /
mount -o remount,rw /dev/block/mmcblk3p5 /system
mount -o remount,rw /dev/block/mmcblk3p7 /device

chmod 777 /data
chmod 777 /data/calibration
cd /data
busybox sed -i "s/ /,/g" calibration         #把校准app产生的数据格式转换为和驱动一样的格式

mkdir -p /sys/module/tsc2007/parameters/
chmod 777 /sys/
chmod 777 /sys/module/
chmod 777 /sys/module/tsc2007/
chmod 777 /sys/module/tsc2007/parameters/
chmod 777 /sys/module/tsc2007/parameters/calibration
cat calibration > /sys/module/tsc2007/parameters/calibration            #传递参数

2)修改init.rc,让android启动时自动运行copy服务

在init.rc最后添加copy服务

service copy_cal /copy_cal.sh
class main
user root
group root
disabled
oneshot

在系统启动完成时加载该服务(也是在init.rc里修改)

on property:sys.boot_completed=1
# Set default CPU frequency governor
# Set timer 40ms, min sample 60ms,hispeed at cpufreq MAX freq in freq_table at load 40%
write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor interactive
write /sys/devices/system/cpu/cpufreq/interactive/go_maxspeed_load 80
write /sys/devices/system/cpu/cpufreq/interactive/timer_rate 40000
write /sys/devices/system/cpu/cpufreq/interactive/min_sample_time 60000
write /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load 40
#write /sys/devices/system/cpu/cpufreq/interactive/hispeed_freq 792000

#####################################################
chmod 777 /copy_cal.sh
chmod 777 /data
chmod 777 /data/calibration

mkdir -p /sys/module/tsc2007/parameters/wei
chmod 777 /sys/
chmod 777 /sys/module/
chmod 777 /sys/module/tsc2007/
chmod 777 /sys/module/tsc2007/parameters/
chmod 777 /sys/module/tsc2007/parameters/calibration
start copy_cal
######################################################

4.tsc2007.c驱动(修改或添加部分标识为红色)

/*
* drivers/input/touchscreen/tsc2007.c
*
* Copyright (c) 2008 MtekVision Co., Ltd.
* Kwangwoo Lee <kwlee@mtekvision.com>
*
* Using code from:
* - ads7846.c
* Copyright (c) 2005 David Brownell
* Copyright (c) 2006 Nokia Corporation
* - corgi_ts.c
* Copyright (C) 2004-2005 Richard Purdie
* - omap_ts.[hc], ads7846.h, ts_osk.c
* Copyright (C) 2002 MontaVista Software
* Copyright (C) 2004 Texas Instruments
* Copyright (C) 2005 Dirk Behme
*
* 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 <linux/module.h>

#include <linux/slab.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>

#define TSC2007_MEASURE_TEMP0 (0x0 << 4)
#define TSC2007_MEASURE_AUX (0x2 << 4)
#define TSC2007_MEASURE_TEMP1 (0x4 << 4)
#define TSC2007_ACTIVATE_XN (0x8 << 4)
#define TSC2007_ACTIVATE_YN (0x9 << 4)
#define TSC2007_ACTIVATE_YP_XN (0xa << 4)
#define TSC2007_SETUP (0xb << 4)
#define TSC2007_MEASURE_X (0xc << 4)
#define TSC2007_MEASURE_Y (0xd << 4)
#define TSC2007_MEASURE_Z1 (0xe << 4)
#define TSC2007_MEASURE_Z2 (0xf << 4)

#define TSC2007_POWER_OFF_IRQ_EN (0x0 << 2)
#define TSC2007_ADC_ON_IRQ_DIS0 (0x1 << 2)
#define TSC2007_ADC_OFF_IRQ_EN (0x2 << 2)
#define TSC2007_ADC_ON_IRQ_DIS1 (0x3 << 2)

#define TSC2007_12BIT (0x0 << 1)
#define TSC2007_8BIT (0x1 << 1)

#define MAX_12BIT ((1 << 12) - 1)

#define ADC_ON_12BIT (TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)

#define READ_Y (ADC_ON_12BIT | TSC2007_MEASURE_Y)
#define READ_Z1 (ADC_ON_12BIT | TSC2007_MEASURE_Z1)
#define READ_Z2 (ADC_ON_12BIT | TSC2007_MEASURE_Z2)
#define READ_X (ADC_ON_12BIT | TSC2007_MEASURE_X)
#define PWRDOWN (TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)

#define SCREEN_X 800              #屏幕长度
#define SCREEN_Y 600              #屏幕宽度

#define I2C_SCL_GPIO 155
#define I2C_SDA_GPIO 154

static int calibration[7]={13352,51,-1289160,-145,10300,-410244,65536};   #校准初始值
module_param_array(calibration, int, NULL, S_IRUGO | S_IWUSR);                 #声明驱动参数,app产生的校准参数传递到calibration数组
struct ts_event {
u16 x;
u16 y;
u16 z1, z2;
};

static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc)
{
static u16 minX = MAX_12BIT;
static u16 maxX = 0;
static u16 minY = MAX_12BIT;
static u16 maxY = 0;
int x;
int y;

tc->x = tsc2007_xfer(tsc, READ_Y);
/* turn y- off, x+ on, then leave in lowpower */
// tc->x = tsc2007_xfer(tsc, READ_X);
tc->y = tsc2007_xfer(tsc, READ_X);
/* turn y+ off, x- on; we'll use formula #1 */
tc->z1 = tsc2007_xfer(tsc, READ_Z1);
tc->z2 = tsc2007_xfer(tsc, READ_Z2);

#######################校准公式最后被简化为如下

if(calibration[6] != 0)
{
x = calibration[0] * (tc->x) +
calibration[1] * (tc->y) +
calibration[2];
x /= calibration[6];
if (x < 0)x = 0;
y = calibration[3] * (tc->x) +
calibration[4] * (tc->y) +
calibration[5];
y /= calibration[6];
if (y < 0)y = 0;
}
tc->x = x;
tc->y = y;

###############################校准完成

tsc2007_xfer(tsc, PWRDOWN);
}

static int tsc2007_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
struct tsc2007 *ts;
struct input_dev *input_dev;
int err;

if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_WORD_DATA))
return -EIO;

ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL);
if (!ts)
return -ENOMEM;

if (pdata)
err = tsc2007_probe_pdev(client, ts, pdata, id);
else
err = tsc2007_probe_dt(client, ts);
if (err)
return err;

input_dev = devm_input_allocate_device(&client->dev);
if (!input_dev)
return -ENOMEM;

i2c_set_clientdata(client, ts);

ts->client = client;
ts->irq = client->irq;
ts->input = input_dev;
init_waitqueue_head(&ts->wait);

snprintf(ts->phys, sizeof(ts->phys),"%s/input0", dev_name(&client->dev));

input_dev->name = "TSC2007 Touchscreen";
input_dev->phys = ts->phys;
input_dev->id.bustype = BUS_I2C;

input_dev->open = tsc2007_open;
input_dev->close = tsc2007_close;

input_set_drvdata(input_dev, ts);

__set_bit(EV_ABS,input_dev->evbit);
__set_bit(EV_KEY,input_dev->evbit);
__set_bit(EV_SYN,input_dev->evbit);

__set_bit(BTN_TOUCH,input_dev->keybit);
input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
input_set_abs_params(input_dev, ABS_X, 0, SCREEN_X, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_Y, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
ts->fuzzz, 0);

if (pdata) {
if (pdata->exit_platform_hw) {
err = devm_add_action(&client->dev,
tsc2007_call_exit_platform_hw,
&client->dev);
if (err) {
dev_err(&client->dev,
"Failed to register exit_platform_hw action, %d ",
err);
return err;
}
}

if (pdata->init_platform_hw)
pdata->init_platform_hw();

}

tsc2007_xfer(ts, PWRDOWN);

err = input_register_device(input_dev);
if (err) {
dev_err(&client->dev,
"Failed to register input device: %d ", err);
return err;
}

printk("tsc2007 proc! ");

//power management
device_init_wakeup(&client->dev,0);

return 0;
}

5.编译Calibration app

weiss@ubuntu:~/myandroid$ mmm packages/apps/Calibrate2/
编译完
weiss@ubuntu:~/myandroid$ ls out/target/product/sabresd_6dq/system
system/ system-app-backup/ system.img system_sparse.img
weiss@ubuntu:~/myandroid$ ls out/target/product/sabresd_6dq/system/app/
A2dpSinkApp CaptivePortalLogin DocumentsUI HTMLViewer PackageInstaller Provision
BasicDreams CertInstaller ethernet KeyChain PacProcessor UserDictionaryProvider
Calibrate Development FSLOta LatinIME PrintSpooler

6.把修改后的init.rc和copy.sh编译进ramdisk.img

编译ramdisk.img
weiss@ubuntu:~/myandroid$ make bootimage

weiss@ubuntu:~/myandroid$ ll out/target/product/sabresd_6dq/
total 594052
drwxrwxr-x 11 weiss weiss 4096 Dec 30 14:30 ./
drwxrwxr-x 4 weiss weiss 4096 Dec 25 07:57 ../
-rw-rw-r-- 1 weiss weiss 14 Dec 10 22:31 android-info.txt
-rw-r--r-- 1 weiss weiss 7647488 Dec 30 14:30 boot.img
-rw-r--r-- 1 weiss weiss 7645440 Dec 30 14:30 boot-imx6dl.img
-rw-r--r-- 1 weiss weiss 7647488 Dec 30 14:30 boot-imx6q.img
-rw-r--r-- 1 weiss weiss 7647488 Dec 30 14:30 boot-imx6q-ldo.img
-rw-rw-r-- 1 weiss weiss 60760 Dec 30 14:08 clean_steps.mk
-rwxr-xr-x 1 weiss weiss 103133 Dec 30 14:23 .config*
drwxrwxr-x 4 weiss weiss 4096 Dec 10 05:53 data/
drwxrwxr-x 2 weiss weiss 4096 Dec 10 05:53 fake_packages/
drwxrwxr-x 5 weiss weiss 4096 Dec 10 23:12 gen/
-rwxr-xr-x 1 weiss weiss 42207 Dec 30 14:30 imx6dl-sabresd.dtb*
-rwxr-xr-x 1 weiss weiss 43129 Dec 30 14:30 imx6q-sabresd.dtb*
-rwxr-xr-x 1 weiss weiss 43129 Dec 30 14:30 imx6q-sabresd-ldo.dtb*
-rw-rw-r-- 1 weiss weiss 60318 Dec 10 22:31 installed-files.txt
-rwxr-xr-x 1 weiss weiss 6859008 Dec 30 14:30 kernel*
drwxrwxr-x 15 weiss weiss 4096 Dec 10 22:31 obj/
-rw-rw-r-- 1 weiss weiss 566 Dec 30 14:08 previous_build_config.mk
-rw-rw-r-- 1 weiss weiss 738771 Dec 30 14:30 ramdisk.img
-rw-rw-r-- 1 weiss weiss 1276096 Dec 10 22:31 ramdisk-recovery.img
drwxrwxr-x 3 weiss weiss 4096 Dec 10 22:31 recovery/
-rw-r--r-- 1 weiss weiss 8149248 Dec 10 22:31 recovery.img
-rw-r--r-- 1 weiss weiss 8147200 Dec 10 22:31 recovery-imx6dl.img
-rw-r--r-- 1 weiss weiss 8149248 Dec 10 22:31 recovery-imx6q.img
-rw-r--r-- 1 weiss weiss 8149248 Dec 10 22:31 recovery-imx6q-ldo.img
drwxrwxr-x 10 weiss weiss 4096 Dec 31 10:55 root/
drwxrwxr-x 6 weiss weiss 4096 Dec 10 05:54 symbols/
drwxrwxr-x 13 weiss weiss 4096 Dec 10 22:30 system/
drwxrwxr-x 23 weiss weiss 4096 Dec 30 10:42 system-app-backup/
-rw-rw-r-- 1 weiss weiss 377466880 Dec 30 10:47 system.img
-rw-rw-r-- 1 weiss weiss 267520620 Dec 30 10:46 system_sparse.img
-rwxr-xr-x 1 weiss weiss 384000 Dec 9 16:57 u-boot.imx*
-rwxr-xr-x 1 weiss weiss 384000 Dec 9 16:57 u-boot-imx6dl.imx*

生成ramdisk.img之后重新生成boot.img,重新烧录到手机上,便可进行校准。校准是重启生效;

注意:如果屏幕为滑鼠模式,需要添加idc文件

原文地址:https://www.cnblogs.com/thinkinglife/p/5118885.html