環境:Ubuntu-18.04 64位
交叉編譯器:arm-hisiv600-linux
tslib版本:tslib-1.4
一、安裝tslib庫
1、下載tslib源碼包
- 鏈接:https://pan.baidu.com/s/1I4polpLf9dunFh03f4A-fA
- 提取碼:pu2i
- 源碼包名:tslib-1.4.tar.gz
2、安裝交叉編譯tslib必須的一些工具
$ sudo apt-get install autoconf
$ sudo apt-get install automake
$ sudo apt-get install libtool
3、拷貝源碼包到海思開發平台,並解壓源碼包
$ sudo tar -xvf tslib-1.4.tar.gz
$ cd tslib
4、生成config文件
$ sudo ./autogen.sh
沒有報錯則會生成 configure 文件。
5、創建安裝目錄
$ mkdir -p /home/temp/tslib
6、生成Makefile文件
要 make 編譯 tslib,必須要有 Makefile 文件,那么就需要先運行所生成的 ./configure 進行配置,然后再生成 Makefile:
$ sudo ./configure --host=arm-hisiv600-linux --prefix=/home/temp/tslib/ CC=/opt/hisi-linux/x86-arm/arm-hisiv600-linux/target/bin/arm-hisiv600-linux-gcc
--host 指定交叉編譯工具鏈的前綴,--prefix 指定所編譯生成Tslib庫的執行文件、頭文件和動態庫的路徑,CC 指定交叉編譯器的絕對路徑。
7、編譯
$ sudo make
首次編譯報錯如下:
ts_test.o: In function `main':
ts_test.c:(.text+0x52c): undefined reference to `rpl_malloc'
fbutils.o: In function `open_framebuffer':
fbutils.c:(.text+0x108): undefined reference to `rpl_malloc'
collect2: ld returned 1 exit status
make[2]: *** [ts_test] 錯誤 1
make[2]:正在離開目錄 `/root/library/tslib/tslib/tests'
make[1]: *** [all-recursive] 錯誤 1
make[1]:正在離開目錄 `/root/library/tslib/tslib'
make: *** [all] 錯誤 2
出錯:編譯 tslib,執行 make 時提示undefined reference to rpl_malloc
是因為 config.h.in 文件中有#undef malloc
,需要把#undef malloc
注釋掉:
$ sudo vi config.h.in
修改之后,重新make,成功。
8、安裝
$ sudo make install
會出現警告信息:
libtool: warning: remember to run 'libtool --finish /home/temp/tslib/lib/ts/'
需要執行:
$ sudo libtool --finish /home/temp/tslib/lib/ts/
然后在安裝目錄下可見成功安裝了,有如下 4 個文件夾:
bin etc include lib
二、移植tslib到ARM開發板
把編譯生成的 tslib 庫拷貝到開發板上任意路徑,我拷貝到 /usr/local 目錄下,這里最重要就是設置環境變量,為什么要設置?我前言有提到,運行應用程序需要鏈接它的依賴庫,怎么找它額依賴庫,就在環境變量的路徑下面尋找。
1、編輯全局環境變量文件:
$ vi /etc/profile
在最后添加上以下幾行:
# touchscreen lib - tslib
export TS_ROOT=/usr/local/tslib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TS_ROOT/lib
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FDDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CALIBFILE=$TS_ROOT/etc/pointercal
export TSLIB_CONFFILE=$TS_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TS_ROOT/lib/ts
export QWS_MOUSE_PROTO=tslib:/dev/input/event1
- TS_ROOT:設置一個根目錄,方便更改
- LD_LIBRARY_PATH:添加共享庫的目錄
- TSLIB_CONSOLEDEVICE:控制台設備文件名,一般不需要
- TSLIB_FBDEVICE:fb0 為ARM中的一塊內存,我們可以理解為 PC 的顯存,要顯示應用層的圖形界面都不能繞過它
- TSLIB_TSDEVICE:指定觸摸屏設備(內核支持觸摸屏驅動),不確定哪個設備是觸摸屏,可執行:
$ cat event0 // 或其他event1 2 3
,然后按下觸摸屏,串口有信息輸出則是 - TSLIB_CALIBFILE:校准的數據文件,由 ts_calibrate 校准程序生成
- TSLIB_CONFFILE:tslib 的配置文件,一般情況下不需要更改
- TSLIB_PLUGINDIR:插件的目錄
- QWS_MOUSE_PROTO:Qt 輸入設備的環境變量(不設置此項,校准后光標是准的,鼠標不准)
2、使環境變量生效:
$ source /etc/profile
就可以了,跑 tslib/bin 目錄下的幾個測試程序試下。
3、出現問題1:
$ ./ts_calibrate
No raw modules loaded.
ts_config: No such file or directory
編輯 tslib/etc/ts.conf 文件, 至少開放一個 module_raw(去掉注釋),並刪掉該行前面的空格。如下圖:
4、出現問題2:
運行 bin 下的可執行文件出現 selected device is not a touchscreen I understand 問題,說明你
的 tslib 中的輸入系統和內核 input 系統版本不匹配,當然也有其他原因,這是最常見的情況
- 1. 將內核源代碼里的 include/linux/input.h 中的 #define EV_VERSION 0x010001 改為:
#define EV_VERSION 0x010000
- 2. 將 arm 交叉編譯工具中的頭文件庫中的 linux/input.h 中的 #define EV_VERSION 0x010000 改為 #define EV_VERSION 0x010001,然后再編譯 tslib 庫
本人是修改了交叉編譯工具中的 input 文件,命令如下:
sudo vi /home/ljh/hisisdk/Hi3531DV100_SDK_V2.0.4.0/osdrv/opensource/kernel/linux-3.18.y/include/uapi/linux/input.h
查找到宏並修改即可。
5、運行可執行程序:
再次運行---成功,在 ARM 板上有顯示了,提示你去校准。過程輸出如下:
/usr/local/tslib/bin # ./ts_calibrate
xres = 800, yres = 480
Took 1 samples...
Top left : X = 32 Y = 52
Took 1 samples...
Top right : X = 741 Y = 28
Took 1 samples...
Bot right : X = 738 Y = 431
Took 1 samples...
Bot left : X = 44 Y = 431
Took 1 samples...
Center : X = 398 Y = 242
13.063293 0.997416 -0.011207
3.655334 0.016685 0.970556
Calibration constants: 856116 65366 -734 239556 1093 63606 65536
bin 目錄下的其他幾個測試程序(ts_calibrate、ts_harvest、ts_print、ts_print_raw ts_test)也可以跑來試下。
三、擴展
1、Tslib ts_calibrate校准原理
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 對驅動采樣到的數據進行處理的一般過程如下:
- 讀取屏上 5 個點的坐標(Top Left,Top Right,Bottom Left,Bottom Right,Center),在進行一系列的變換,取樣的 5 個點,實際上是包含 3 個不同的 X 值,3 個不同的 Y 值。和 scaling 值一共 7 個值,一起保存到 /etc/pointercal 中。
- 這個 /etc/pointercal 文件主要是供 linear 插件使用。而我們每次的觸摸的操作都進行多次觸摸坐標變換。
在校准觸摸屏后只需及時的讓 linear 插件再次讀取新的/ etc/pointeracal 文件,這樣新校准的坐標信息就及時的更新到上層應用。
Tslib配置文件ts.conf介紹
Tslib 的配置文件 ts.conf 同樣是個十分重要的部分,在 ts.conf 中配置了需要加載的插件、插件加載順序以及插件的一些約束參數,這些配置參數對觸摸屏的觸摸效果具有十分重要的影響。其中:
- pthres 為Tslib 提供的觸摸屏靈敏度門檻插件 默認參數為pmin=1;
- variance 為Tslib提供的觸摸屏濾波算法插件 默認參數為delta=30;
- dejitter 為Tslib 提供的觸摸屏去噪算法插件 默認參數為delta=100;
- linear為Tslib 提供的觸摸屏坐標變換插件。
由於各種因素的影響,在不同的硬件平台上,相關參數可能需要調整。以上參數的相互關系為:
- 采樣間隔越大,采樣點越少,采樣越失真,但因為信息量少,容易出現丟筆划等丟失信息情況,但表現出來的圖形效果將會越好;
- 去噪算法跟采樣間隔應密切互動,采樣間隔越大,去噪約束應越小,反之采樣間隔越小,去噪約束應越大。
- 去抖算法為相對獨立的部分,去抖算法越復雜,帶來的計算量將會變大,系統負載將會變重,但良好的去抖算法可以更好的去除抖動,在進行圖形繪制時將會得到更好的效果;靈敏度和 ts 門檻值為觸摸屏的靈敏指標,一般不需要進行變動,參考參考值即可。
參考:
Qt5.8與觸摸Tslib-1.4庫ARM-ZYNQ平台的移植(一)
移植tslib庫出現selected device is not a touchscreen I understand的解決方法