linux划屏原理,linux的觸摸屏之一:原理及APK調試

(1)原理:本文拋開技術層次上來說說LINUX觸摸屏設備驅動原理。觸摸屏,就是用一塊AD轉換模塊來將屏幕上的觸摸信號轉成數字信號。觸摸屏常用的是四線電阻,當觸摸時候,功能模塊會將模擬信號轉換成數字信號,就是通常說的AD轉換。在LINUX中,通常是通過中斷來讀取這些數字的。觸摸屏幕的時候,中斷發生,LINUX通過串口或者I2C,SPI或者內部數據通道等去讀取轉換后的數字,然后把數值傳給INPUT層。 為什么要校驗?原因A,觸摸屏與LCD顯示屏是兩個不同的物理器件。LCD處理的像素,例如我們通常所說的分辨率是600x800,實際就是指每行的寬度是600個像素,高度是800個像素,而觸摸屏處理的數據是點的物理坐標,該坐標是通過觸摸屏控制器采集到的。兩者之間需要一定的轉換。B,其次在安裝觸摸屏時,不可避免的存在着一定的誤差,如旋轉,平移的,這同樣需要校正解決。C,再次,電阻式觸摸屏的材料本身有差異而且隨着時間的推移,其參數也會有所變化,因此需要經常性的校正(電容式觸摸屏只需要一次校正即可)。

a8c801e86b91265e4a47892847b769a9.jpe

比較常用的校驗程序是TSLIB。通過TSLIB校驗后,應用程序讀取TSLIB里的數值,這個時候就能准確定位了。校正原理: 觸摸屏的校正過程一般為:依次在屏幕的幾個不同位置顯示某種標記(如"+"),用觸摸筆點擊這些標記, 完成校正。如果PT(x, y)表示觸摸屏上的一個點,PL(x, y)表示LCD上的一個點,校正的結果就是得到一個轉換矩陣M,使PL(x, y) = M·PT(x, y)。最終,假設LCD三個點的坐標為(XL1, YL1),(XL2, YL2),(XL2, YL2), 對應觸摸屏上的三個點是(XT1, YT1),(XT2, YT2),(XT3, YT3),則聯立兩個方程組為:

a8d1c3fddbc47256f082041c83f70877.jpe

這樣,觸摸屏的校正實際上就是解上面的方程組,得到6個系數:A、B、C、D、E、F。而上面方程組按照克萊姆法則解即可。在得到6個系數后,以后通過觸摸屏得到的所有坐標,帶入公式(1)中就可以得到LCD上以像素表示的坐標。

實際上,在校正時,采集的觸摸屏的點坐標有一定的誤差,也就是說采集幾個三組點坐標,分別計算A、B、C、D、E、F,其結果不盡相同。在tslib的ts_calibrate中,采集了五組點坐標,具體代碼參見ts_calibrate.c中的perform_calibration()。一般來說,采集的點越多,校正的精確性就越高。只是采集點過多就會冗余,對校正精確性的提高作用很少,反而增加了計算時間。

歸結過程如下:

android 的坐標轉換處理:This implementation is a linear transformation using 7 parameters

(a, b, c, d, e, f and s) to transform the device coordinates (Xd, Yd) into screen coordinates (Xs, Ys) using the following equations:

s*Xs = a*Xd + b*Yd + c

s*Ys = d*Xd + e*Yd + f

其中:Xs,Ys:LCD坐標;Xd,Yd:觸摸屏坐標。

(2)調試:觸摸屏一直定位不准,會有偏移。同事經過一段時間的調試之后,解決了此問題。解決方式如下:

1,原理:Calibrate: 下載tslibonandroid,通過它來在屏幕上顯示五個坐標,點擊這五個坐標,得到需要的7個參數,實現坐標轉換。

過程:icon(apk)->jni->*.so(tslib)->生成校正參數(a0~a6)。校正時候,必須通知driver,校正完成或者校正失敗都要通知driver。而touch  driver每次上電后需要讀取一次校正參數,如果讀取失敗則使用默認參數。

2,改動:

- 在$kernel/driver/input/touchscreen/s3c-ts.c,添加跟上層cupcake接口的函數。

- 改動$kernel/dirver/char/vt_ioctl.c

- 在$cupcake/development/中添加calibrate整個文件夾(實現java icon和JNI調用),該文件夾負責生成一個android應用軟件apk

- 在$cupcake/external/中添加tslibonandroid整個文件夾(實現生成校正參數)

- 在$cupcake/vendor/sec/smdk6410/init.rc,改動跟touch screen相關文件的屬性權限。

把kernel和cupcake完整編譯后,燒錄進板子。cupcake會在out/target/product/smdk6410/obj/APPS/Calibrate_intermediates下生成一個對應的apk文件,將該apk文件改名后安裝入平台,點擊即可運行與WINCE相似的校准過程。

3,程序過程:

A,點擊APK,開始運行程序。在Calibrate.java中:onCreate-》tsmainloop。同時:

public native void tsmainloop();   //JNI函數申明

System.loadLibrary("calibrate-jni");   //載入庫libcalibrate-jni.o

B,JNI的C函數原型定義在com_android_calibrate_Calibrate.cpp中:

#include "../../../external/tslibonandroid/tests/calibratejni.h" //該文件所在的文件夾作為當前目錄回退3層再進入其他子目錄

static void tsmainloop(JNIEnv *env, jobject object)

{

ts_main();

}

在該文件中,還定義了方法跟class:

static const char *classPathName = "com/android/calibrate/Calibrate"; //指向該CPP被調用的class

static JNINativeMethod methods[] = {

{"tsmainloop", "()V", (void*)tsmainloop },

};

完成JNI的注冊。

C,在external/tslibonandroid/tests路徑下的ts_calibrate.c完成TSLIB過程,如下:

#define TSLIB_TSDEVICE   "/dev/input/event1"      //內核為TS分配的INPUT設備名

#define DEVICE_NAME      "/dev/myts"                    //要訪問的TS字符設備名

#define TSLIB_CALIBFILE  "/system/etc/pointercal"

#define TS_POINTERCAL    "/system/etc/pointercal"      //最終需要用到的pointercal文件,寫入7個參數

#define TSLIB_CONFFILE  "/system/etc/tslib/ts.conf"     //tslib中的配置文件

typedef  struct {

int x[5], xfb[5];   //x方向的觸摸屏參數,LCD參數

int y[5], yfb[5];   //y方向的觸摸屏參數,LCD參數

int a[7];              //存儲那七個參數

} calibration;

ts_main()

{

calibration cal;

char cal_buffer[256];

char buffer[5] = "OK";

int fd = open("/dev/myts",O_RDWR);    //打開內核定義的TS字符設備,寫入OK字符

write(fd,buffer,2);

close(fd);

struct tsdev *ts = ts_open(getenv("TSLIB_TSDEVICE"),0)  //打開內核TS設備

ts_config(ts);                                                          //讀取ts.conf,給ts配置

open_framebuffer();                                              //打開顯示設備,准備畫圖

put_string_center (xres / 2, yres / 4, "TSLIB calibration utility", 1);               //在屏幕中心放置字符串

put_string_center (xres / 2, yres / 4 + 20, "Touch crosshair to calibrate", 2);  //表示程序運行開始

clearbuf(ts);                                                             //清空TS

get_sample (ts, &cal, 0, 50,        50,        "Top left");

get_sample (ts, &cal, 1, xres - 50, 50,        "Top right");

get_sample (ts, &cal, 2, xres - 50, yres - 50, "Bot right");

get_sample (ts, &cal, 3, 50,        yres - 50, "Bot left");     //按照左上,右上,右下,左下,中五個次序,讀取采樣值,按

get_sample (ts, &cal, 4, xres / 2,  yres / 2,  "Center");    //0,1,2,3,4這個index編號存儲在cal變量中

if (perform_calibration (&cal))   //如果校驗成功

{

cal_fd = open (getenv("TSLIB_CALIBFILE"), O_CREAT | O_RDWR,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

//打開系統的pointercal文件

sprintf (cal_buffer,"%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]);

//把cal的7個參數值組合到cal_buffer變量中

write (cal_fd, cal_buffer, strlen (cal_buffer) + 1);    //寫入7個參數到pointercal文件中

}

strcpy(buffer,"END");

fd = open("/dev/myts",O_RDWR);

printf("fd: %d/n",fd);

write(fd,buffer,3);

close(fd);                //寫END到內字符設備myts中

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值