歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

交叉編譯tslib1.4過程詳述,配合QT4.5.3成功在Mini2440運行成功

移植tslib-1.4所遇到的問題分析與總結(elephant半原創:在移植過程中參考了一些網友的資料,現在結合我遇到的問題分析一下移植過程)

一:移植環境

1:主機環境:Ret Hat Enterprise 5

2: 交叉工具鏈:arm-linux-gcc-4.3.2

3: 開發平台:友善之臂mini2440+統寶3.5寸屏

4:所需的軟件資源:

tslib-1.4.tar.gz  qt-x11-opensource-src-4.5.3.tar.gz   qt-embedded-opensource-src-4.5.3.tar.gz

(QT的移植是參考網上找到一篇較好的移植手冊,但是此手冊的作者不知道是無心之失還是咋的,給的資料有所保留。不過思路比較清晰以及解析的比較詳細,還是非常值得參考的)

參照的文章鏈接地址為:http://www.linuxidc.com/Linux/2012-08/68412.htm

二:交叉編譯tslib-1.4

為什麼要移植tslib1.4呢?

在移植好觸摸屏的驅動後(在移植內核的時候完成),一般都要移植一個tslib來配合,在用戶層對觸摸屏的數據進行濾波和矯正,同時也可以給應用程序一個統一的接口,很多GUI都支持tslib的接口。我移植到開發板的QT版本是QT4,所以用tslib-1.4進行觸摸屏校正,因為QT4只是支持tslib-1.4(目前最新版),QT2支持的是tslib-1.3版本,所以在移植過程中先要看清楚自己移植的是什麼版本。 

簡單描述tslib校正觸摸屏原理:

   Tslib是觸摸屏驅動和應用層之間的適配層,它從觸摸屏驅動處獲得原始的設備坐標數據,通過一系列的去噪、去抖、坐標變換等操作,來去除噪聲並將原始的設備坐標轉換為相應的屏幕坐標。通過tslib/src/tslib.h文件可以看出,在tslib中為應用層提供了2個主要的接口ts_open(),ts_close();ts_read()和ts_read_raw(),其中ts_read()為正常情況下的接口,ts_read_raw()為校准情況下使用的接口。從tslib默認的ts.conf文件中可以看出包括如下基本插件:(強烈建議通讀這個配置文件並理解這個文件所寫的內容)

   pthres 為Tslib 提供的觸摸屏靈敏度門檻插件;

   variance 為Tslib提供的觸摸屏濾波算法插件;

   dejitter 為Tslib 提供的觸摸屏去噪算法插件;

   linear為Tslib 提供的觸摸屏坐標變換插件。 

tslib 從觸摸屏驅動采樣到的設備坐標進行處理再提供給應用端的過程大體如下:

   raw device --> variance --> dejitter --> linear --> application
    module         module       module      module

再來看看ts_calibrate主要做了哪些事情,校准情況下,tslib對驅動采樣到的數據進行處理的一般過程如下:
   1。讀取屏上5個點的坐標(Top Left,Top Right,Bottom Left,Bottom Right,Center),在進行一系列的變換,取樣的5個點,實際上是包含3個不同的X值,3個不同的Y值。和scaling 值一共7個值,一起保存到/etc/pointercal中.(觸摸屏校准文件)

   2.這個/etc/pointercal文件主要是供linear插件使用。而我們每次的觸摸的操作都進行多次觸摸坐標變換。

至此已經找到解決問題的大體的方法了。在校准觸摸屏後只需及時的讓linear插件再次讀取新的/etc/pointeracal文件,這樣新校准的坐標信息就及時的更新到上層應用。下面就要考慮具體實現的問題了。

1。從linear.c文件可以看出在該模塊初始化時讀取了/etc/pointercal文件。只要在linear_read()中讀取新的/etc/pointercal文件即可。

2。校准後保存了一個新的pointercal文件,但ts_lib怎麼知道當前的pointercal文件是應該讀取的新文件。剛開始的時候我們在linear.c的linear_read()函數中采取計數輪詢的方式查看/etc/poinercal文件的最後更新時間,如果當前的更新時間大於上次更新時間,就去讀取下pointercal文件。我們暫且不說在一台剛下流水線的機器,它的rtc時間是不確定,再進行時間比較時會出現錯誤。另外始終的輪詢的方式和ts_lib的采樣間隔時間值很小。這樣用戶在進行觸摸屏常按操作時,會非常明顯的消耗系統資源。

3。此時想到的辦法就是進程通信,ts_lib是個動態庫運行於系統中,他存在系統中不是以進程方式,但可以采取折衷方法,將調用ts_lib的進程號(實際上就是X的進程號)保存到一個配置文件中。這樣在使用ts_calibrate校准觸摸屏後,利用信號的方式給ts_lib發送用戶自定義信號,ts_lib的lineral.c中加一個簡單的信號處理函數。在接受到信號後就去讀取下新的pointercal文件。正常情況下不做任何的輪詢和讀取操作。

從上說的3個步驟中完全解決了校准後應用端觸摸及時生效的問題。還有個次要問題就是如何鎖屏?這需要從內核入手了,查看linux2.6內核/drivers/input/evdev.c從該驅動提供的ioctl中看到對基於evdev的輸入設備都提供EVIOCGRAB實現。顧名思義,grab就是將當前的輸入操作抓取到當前的操作中,讓當前操作之外的所有應用端讀不到觸摸屏的觸摸操作。由驅動源碼就很容易知道該如何實現鎖屏解鎖操作了。源碼如下:

truct tsdev *ts;
char *tsdevice = "/dev/input/event0";
ts = ts_open(tsdevice, 0);
int ts_tmpfd = ts_fd(ts);
if (ts_tmpfd== -1)
{
    perror("ts_open");
    exit(1);
}
unsigned long val =1;
int ioctl_ret=ioctl(ts_tmpfd,EVIOCGRAB,&val);
printf("now lock the ts ioctl ret is:%d/n",ioctl_ret);

if (ioctl_ret!=0)
{
    printf("Error: %s/n", strerror(errno));
    exit(1);
}
printf("lock the ts success /n");

現在開始交叉編譯tslib,在開始編譯前需要確定自己的開發環境是否安裝了autoconf、automake和 libtool等軟件包。之前我的虛擬機並不是完全安裝,在編譯過程中出現很多問題,在這裡我建議大家虛擬機完全安裝。不過如果確實不想重裝系統的話,也可以手動安裝,之前我自己就是手動安裝的,雖然成功安裝了tslib軟件,但是在後續的QT移植過程中出現很多不可預知的錯誤,因此還是建議大家的虛擬機是完全安裝的。可以利用命令查看自己虛擬機上的autoconf版本:autoconf –V

在開始編譯tslib前還有一個問題需要特別注意:就是要確定在編譯時所用的工具是交叉工具鏈而不是PC平台下的GCC工具,因為我要運行的平台是嵌入式ARM架構而不是PC的X86架構。關於這一點,在網上找到很多資料都沒有說明,幾經尋找之下,終於看到一篇文章對這一點作了說明。詳細解析tslib-1.4交叉編譯:http://www.linuxidc.com/Linux/2010-04/25562.htm

第一步:解壓源碼包:

tar  xvzf tslib-1.4.tar.gz

cd tslib

第二步:進入tslib之後關鍵是要設置交叉編譯環境(下面是根據我自己的實際情況所添加的)——如果不設置交叉編譯環境,在移植到開發板時,執行./ts_calibrate程序時會出現以下錯誤:

./ts_calibrate: line 1: syntax error :”(” unexpected.

$export PATH=$PATH:/usr/local/arm/4.3.2/bin

$export CC=arm-linux-gcc

$export CXX=arm-linux-g++

設置好交叉編譯環境後就可以開始安裝了:

執行./autogen.sh

執行./autogen.sh之後可能會有上述信息出現,但是我的機器上灰常不給力,只是顯示出其中幾行信息,一開始以為是出錯,但是最後還是移植成功,證明這步就算只出現幾行信息並無多大關系。

接著執行以下命令:

./configure  --prefix=/usr/local/tslib/  --host=arm-linux  ac_cv_func_malloc_0_nonnull=yes

(1)有些開發板在執行此命令時需要添加—enable inputapi=no或者—enable input=no,至於是哪一個就需要根據tslib目錄下的configure文件才可以知道。(建議這個文件還是看一下)。由於友善之臂mini2440的觸摸屏驅動是支持ioctl操作的(在內核移植時做觸摸屏驅動時可以看到源碼中是支持ioctl的),因此我在這裡並沒有加上—enable inputapi=no.

(2)如果沒有加上ac_cv_func_malloc_0_nonnull=yes會出現交叉編譯錯誤:undefined reference to `rpl_malloc'. 這是由ac_cv_func_malloc_0_nonnull檢查引起的,為了不讓它檢查,產生一個cache文件daiq_tslib.cache,欺騙configure再執行:因此為了編譯的順利進行,在配置的時候需要加上這一句:ac_cv_func_malloc_0_nonnull=yes

最後執行make & make install就可以在指定的路徑上成功安裝tslib。我的指定路徑是/usr/local/tslib/,在這個文件下安裝成功的話會有四個目錄:lib/  etc/  include/  bin/. 

安裝好tslib之後將動態鏈接庫文件拷貝到根文件系統中,(注意tslib依賴的是動態鏈接庫文件),如果忘記拷貝動態鏈接庫的話會出現以下錯誤:

拷貝進去之後需要在自己的根文件系統的/etc/profile(在文件的一開始添加下面的內容)設置tslib的環境變量(要根據自己的實際情況來設置),下面是我的開發板所設置的有關tslib的環境變量:

# Ash profile

#vim syntax=sh

#No core files by default

echo "Set ENV for tslib......"

export  QTDIR=/usr/local/Trolltech/QtEmbedded-4.5.3-arm(文件系統中QT的安裝目錄)

export TSLIB_ROOT=/usr/local/tslib   (tslib的目錄)

export TSLIB_CONSOLEDEVICE=none

export TSLIB_FBDEVICE=/dev/fb0

export TSLIB_TSDEVICE=/dev/input/event0

export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf export TSLIB_CALIBFILE=$TSLIB_ROOT/etc/pointercal

export POINTERCAL_FILE=$TSLIB_ROOT/etc/pointercal

export  QWS_DISPLAY=LinuxFb:dev/fb0

export set QWS_SIZE=320x240

export QWS_MOUSE_PROTO=Tslib:/dev/input/event0
export LD_LIBRARY_PATH=$TSLIB_ROOT/lib:$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH

echo “the env is successful”

當配置好這些環境變量後下載到開發板,執行./ts_calibrate時如果出現:

ts_open: No such file or directory

說明環境變量設置有問題,可以用env命令查看一下有沒有你剛才設置的環境變量。在設置環境變量這一個環節上是比較重要的,要保證在每一個目錄下都存在你需要用到的文件。

如果移植成功:

cd /usr/local/tslib/bin   

./ts_calibrate    校准觸摸屏

./ts_test         測試觸摸屏

Copyright © Linux教程網 All Rights Reserved