一.裝置驅動
我的觸摸屏是usb接口的
可以參考下這2篇檔案
http://blog.csdn.net/paomadi/article/details/8754783 usb觸摸屏
http://blog.csdn.net/paomadi/article/details/8309861 輸入子系統
不是usb接口的或者自己想寫多一個也可以(需要我的源碼的請留郵箱說下,我貼一部分)
usb子系統部分關鍵在于urb的資料傳遞
input子系統部分關鍵在于事件的設定及上報
#define M //多點觸摸點數
在初始化init或者probe方法中
input_dev=input_allocate_device();//配置設定初始化輸入裝置
//(最好建構一個對象結構體,包含input裝置和usb裝置,或其他裝置,将各個子系統的裝置捆綁到一個對象中去)
set_bit(EV_KEY, input_dev->evbit); //設定事件類型标志位
set_bit(EV_ABS, input_dev->evbit);
set_bit(BTN_TOUCH, input_dev->keybit); //設定按鍵類型标志
#if M
//多點的這麼設定參數(我的屏隻支援單點,so沒親測)
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,1920, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,1080, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
#else
//單點的參數設定
input_set_abs_params(input_dev, ABS_X, 0, 0x7FFF, 0, 0); //設定參數
input_set_abs_params(input_dev, ABS_Y, 0, 0x7FFF, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
#endif
在接收到資料之後上報事件給input子系統
#if M
//input_report_abs(touch->input, ABS_MT_TOUCH_MAJOR, 0);
for(i=0;i<M;i++){
input_report_abs(touchkit->input, ABS_MT_TRACKING_ID,0);
input_report_key(touchkit->input, BTN_TOUCH, touchkit->press);
input_report_abs(touchkit->input, ABS_MT_POSITION_X, touchkit->x);
input_report_abs(touchkit->input, ABS_MT_POSITION_Y, touchkit->y);
input_report_abs(touchkit->input, ABS_PRESSURE, touchkit->press);
input_mt_sync(touchkit->input);
}
#else
input_report_abs(input_dev, ABS_X, touchkit->x);
input_report_abs(input_dev, ABS_Y, touchkit->y);
input_report_key(input_dev, BTN_TOUCH,touchkit->press);
input_report_abs(input_dev, ABS_PRESSURE, touchkit->press);
#endif
input_sync(input_dev);
usb能比對直接用hid子系統那是極好的
可以這樣調試hid的裝置
mkidr /tmp/debugfs
mount -t debugfs debugfs /tmp/debugfs
cd /tmp/debugfs
cd hid
cd 進對應的hid裝置檔案夾
cat event
其他的一些調試檢視方法
ls -l /dev/input檢視輸入input裝置
其中可以看到 lrwxrwxrwx 1 root root 6 Jan 1 2000 touchscreen0 -> event1
/dev/input/touchscreen0是連結檔案,連結到對應的觸摸屏event1裝置
檢視event1是否觸摸裝置
cd /sys/class/input
cd event1
cd device
cat name
或者
cat /proc/bus/input/devices
比較Handlers和Name
cat /dev/input/touchscreen|hexdump 點選觸摸屏檢視接收到的資料
二.tslib
更新工具
sudo apt-get install autoconf
sudo apt-get install automake
sudo apt-get install libtool
解壓tslib
tar xzf tslib-1.4.tar.gz
cd tslib
生産configure檔案
./autogen.sh
建立安裝目錄
mkdir tmp
配置生成makefile檔案
echo "ac_cv_func_malloc_0_nonnull=yes" >arm-none-linux-gnueabi.cache
./configure --host=arm-none-linux-gnueabi --cache-file=arm-none-linux-gnueabi.cache --prefix=$(pwd)/tmp
編譯tslib
make
安裝tslib
make install
安裝完成後生成4個目錄
/bin 目錄包含ts_calibrate ts_test ts_harvest ts_print ts_print_raw測試執行檔案
/etc 目錄包含ts.conf配置檔案
/include 目錄包含 tslib.h頭檔案
/lib 目錄包含 pkgconfig目錄和ts目錄和*.so(libts.so等)動态連結庫
檢驗檔案是否用交叉工具鍊編譯的
file ts_calibrate檢視列印的資訊
檔案系統配置
将/bin目錄的和/etc目錄下的檔案複制到目标闆檔案系統的同樣目錄下
/include和/lib目錄複制到目标闆檔案系統的/usr目錄下
配置ts.conf
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
配置環境變量
打開目标闆檔案系統/etc/profile檔案
export LD_LIBRARY_PATH=/usr/lib/ --庫檔案目錄
export TSLIB_ROOT=/usr/ --tslib庫檔案/頭檔案根目錄
export TSLIB_TSDEVICE=/dev/input/touchscreen0 --觸摸屏裝置檔案路徑
export TSLIB_CALIBFILE=/etc/pointercal --校正檔案路徑 運作ts_calibrates會自動生成
export TSLIB_CONFFILE=/etc/ts.conf --配置檔案路徑
export TSLIB_CONSOLEDEVICE=none --
export TSLIB_FBDEVICE=/dev/fb0 --fb顯示裝置檔案路徑
export TSLIB_TSEVENTTYPE=INPUT --觸摸事件類型 input子系統
export TSLIB_PLUGINDIR=/usr/lib/ts --
tslib測試
運作ts_calibrate
列印:
xres = 1920, yres = 1080
顯示屏出現校正畫面
點選方塊(左上角)
列印:
Took 1 samples...
Top left : X = 752 Y = 1248
再次點選方塊(右上角)
列印:
Took 2 samples...
Top right : X = 31938 Y = 1468
再次點選方塊(右下角)
列印:
Took 2 samples...
Bot right : X = 31986 Y = 30926
再次點選方塊(左下角)
列印:
Took 1 samples...
Bot left : X = 728 Y = 31278
再次點選方塊(正中間)
列印:
Took 1 samples...
Center : X = 16387 Y = 16403
3.813721 0.058434 0.000070
3.860352 0.000071 0.032752
Calibration constants: 249936 3829 4 252992 4 2146 65536
校驗完在/etc目錄下生成/etc/pointercal
ts_calibrate可能會遇到一些問題
提示不是支援的觸摸屏:檢視TSLIB_TSDEVICE環境變量是否設定對
沒點選方塊就自動校正了:1.驅動BTN_TOUCH或者ABS_PRESSURE的值固化成1了(有上報按下事件沒上報松開事件)
2.庫檔案放錯位置
運作ts_test
點選Drag按鈕 可以拖動小方塊
點選Draw按鈕 可以在螢幕上畫線
點選的時候會列印:xxx:[x坐标] [y坐标] [按下1/松開0]
1345221722.121520: 1920 1074 1
1345221722.121520: 1920 1074 1
1345221722.354517: 1920 1078 0
1345221724.035519: 1851 838 1
1345221724.045521: 1849 835 1
1345221724.065520: 1845 829 1
1345221724.081520: 1840 823 1
1345221724.091521: 1834 816 1
1345221724.104521: 1828 810 1
1345221724.121520: 1821 803 1
1345221724.137518: 1814 797 1
1345221724.153520: 1807 790 1
三.qt everywhere 4.8.1編譯
重新配置tslib
/configure --host=arm-none-linux-gnueabi --cache-file=arm-none-linux-gnueabi.cache --prefix=/usr/local/tslib
修改安裝目錄
make
make install
修改qt-everywhere-opensource-src-4.8.1/mkspecs/qws/【xxx】/qmake.conf檔案
QMAKE_CC = arm-none-linux-gnueabi-gcc -lts
QMAKE_CXX = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK_SHLIB = arm-none-linux-gnueabi-g++ -lts
QMAKE_INCDIR =/usr/local/tslib/include
QMAKE_LIBDIR =/usr/local/tslib/lib
配置qt
.configure 後面加上 -no-mouse-linuxtp -qt-mouse-tslib
在test的過程中列印
Mouse driver(qt) ......pc tslib
表示庫安裝成功并成功檢測到
編譯qt
make
make install
example裡面選擇應用程式(推薦qt-everywhere-opensource-src-4.8.1/examples/widgets/calculator)
拷貝到目标闆檔案系統裡
ldd calculator 檢視calculator需要調用的庫
列印:
libts-0.0.so.0 => /usr/lib/libts-0.0.so.0 (0x2ac3f000)
libQtGui.so.4 => /usr/lib/libQtGui.so.4 (0x2ac49000)
libQtNetwork.so.4 => /usr/lib/libQtNetwork.so.4 (0x2b6ae000)
libQtCore.so.4 => /usr/lib/libQtCore.so.4 (0x2b7d6000)
libpthread.so.0 => /lib/libpthread.so.0 (0x2ab6a000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x2bb35000)
libm.so.6 => /lib/libm.so.6 (0x2ab8a000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x2ab40000)
libc.so.6 => /lib/libc.so.6 (0x2bc07000)
libdl.so.2 => /lib/libdl.so.2 (0x2bd31000)
librt.so.1 => /lib/librt.so.1 (0x2ab10000)
/lib/ld-linux.so.3 (0x2aaea000)
看到libts-0.0.so.0說明tslib在qt中移植成功
ldd是個腳本,交叉工具鍊裡面找
拷貝庫檔案到/usr/lib
在qt-everywhere-opensource-src-4.8.1/lib裡面有la、prl、so和so.xxx檔案
拷貝so和so.xxx檔案就行
配置環境變量
打開目标闆檔案系統/etc/profile檔案,添加以下
export LD_LIBRARY_PATH=/usr/lib/ ----庫檔案目錄
export QWS_SIZE=1920x1080 ----分辨率
export QWS_MOUSE_PROTO="tslib:/dev/input/touchscreen0 mouseman:/dev/input/mouse0" ----"滑鼠"類型
QWS_MOUSE_PROTO指定qt的滑鼠,由【”】【第1個裝置名字】【:】【裝置檔案路徑】【空格】【第2個裝置名字】【:】【裝置檔案路徑】...【“】構成裝置名字不區分大小寫
裝置名字可以是:(tslib、qnx、integrity、linuxtp、auto、intellimouse、microsoft、mousesystems、mouseman、linuxinput、usb、linuxis...)
該環境變量在qt源碼qt-everywhere-opensource-src-4.8.1/src/gui/embedded/Qwindowsystem_qws.cpp的QWSServer::openMouse()函數中讀取
QString mice=QString::fromLatin1(qgetenv("QWS_MOUSE_PROTO"))語句讀入到mice,調試分析可以從這裡入手
列印讀取的環境變量:qDebug()<<mice,讀取環境變量到mice後會判斷mice中有多少個空格" ",也就是判斷有多少個“滑鼠”裝置,個數作為後面for語句的循環因子,
for語句則調用QWSMouseHandler *handler=d->newMouseHandler(mouse.at(i))建立"滑鼠"句柄,-->QMouseDriverFactory::create-->具體“滑鼠”裝置句柄的建立函數
QWSMouseHandler *QMouseDriverFactory::create(const QString& key, const QString &device)
{
QString driver = key.toLower();
#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX)
if (driver == QLatin1String("qnx") || driver.isEmpty())
return new QQnxMouseHandler(key, device);
#endif
#if defined(Q_OS_INTEGRITY) && !defined(QT_NO_MOUSE_INTEGRITY)
if (driver == QLatin1String("integrity") || driver.isEmpty())
return new QIntMouseHandler(key, device);
#endif
#ifndef QT_NO_QWS_MOUSE_LINUXTP
if (driver == QLatin1String("linuxtp") || driver.isEmpty())
return new QWSLinuxTPMouseHandler(key, device);
#endif
#ifndef QT_NO_QWS_MOUSE_PC
if (driver == QLatin1String("auto")
|| driver == QLatin1String("intellimouse")
|| driver == QLatin1String("microsoft")
|| driver == QLatin1String("mousesystems")
|| driver == QLatin1String("mouseman")
|| driver.isEmpty()) {
return new QWSPcMouseHandler(key, device); //mice...
}
#endif
#ifndef QT_NO_QWS_MOUSE_TSLIB
if (driver == QLatin1String("tslib") || driver.isEmpty()) //tslib
return new QWSTslibMouseHandler(key, device);
#endif
# ifndef QT_NO_QWS_MOUSE_LINUXINPUT
if (driver == QLatin1String("linuxinput") || \
driver == QLatin1String("usb") || \
driver == QLatin1String("linuxis"))
return new QWSLinuxInputMouseHandler(device);
# endif
#ifndef QT_NO_QWS_MOUSE_QVFB
if (driver == QLatin1String("qvfbmouse") || driver == QLatin1String("qvfb"))
return new QVFbMouseHandler(key, device);
#endif
#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
#ifndef QT_NO_LIBRARY
if (QWSMouseHandlerFactoryInterface *factory = qobject_cast<QWSMouseHandlerFactoryInterface*>(loader()->instance(driver)))
return factory->create(driver, device);
#endif
#endif
return 0;
}
如果滑鼠類型沒指定(mouseman之類的),則預設會調用/dev/input/mice這樣會使你的觸摸有點漂移的感覺,
這個情況很多人都碰到過,如果不需要滑鼠 指定mouseman:/dev/NULL這樣的話就沒問題了。
凡是指定了滑鼠裝置的話都會引起觸摸屏有點漂移的感覺.當你再觸摸觸摸屏時候,qt會讀取你的觸摸裝置的資料和滑鼠裝置的資料
結果就是相對位移+絕對位移的處理結果,有點漂移,但還是勉強可以觸摸.
還有一種情況會引起漂移現象,那就是你的環境變量沒讀取對,
也就是QWS_MOUSE_PROTO為空,是以最好添加qDebug()<<mice去調試一下,悲劇的是我就是碰到這種情況,即使用env檢視是正确的也不一定說明你讀取的環境變量是對的,你的應用程式
可能是在其他級别的使用者或者在其他的bash環境下執行的,你的環境變量不一定對他起效.修改代碼調試編譯qt時候隻需重新make一次,然後把前面說的庫檔案拷貝過去目标闆就行了,
不費時間的
這裡的QWS_MOUSE_PROTO的設定最好要寫個shell腳本測試下是否插了滑鼠,是否插了觸摸屏根據判斷的結果來不同的設定QWS_MOUSE_PROTO環境變量最好
檢視你應用程式調用了那個input裝置,使用lsof指令工具
lsof /dev/input/touchscreen0
列印:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
xxxx 1771 root 41r CHR 13,65 0t0 2326 /dev/input/event1
就是說xxxx打開了/dev/input/touchscreen0這個裝置,這個裝置是連結檔案連結到/dev/input/event1
如果裝置檔案打開正确,但是觸摸時候滑鼠指針不動,運作一下ts_calibrate生成pointercal檔案後再試試
這裡可以添加下面shell腳本,在你打開qt應用程式前先判斷是否校正過了,矯正過則執行qt程式,沒校正過則校正一下
if [ ! -f "/etc/pointercal" ]; then
ts_calibrate
fi
實作觸摸屏+滑鼠同時熱拔插的方法:
1.export QWS_MOUSE_PROTO="tslib:/dev/input/touchscreen0 mouseman:/dev/input/mice"
觸摸屏的裝置節點可以是你自己的裝置節點,滑鼠的裝置節點必須是mice
2裝置節點随着熱拔插不能發生變化
usb觸摸屏,如果給hid子系統識别到,那可能受它架構束縛,熱拔插節點會變化,我的方法是自己寫usb觸摸屏驅動,當然要先和hid子系統脫鈎
在/driver/hid/hid-core.c檔案中hid_bus_match函數中,添加了
static int hid_bus_match(struct device *dev, struct device_driver *drv)
{
struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
if(hdev->vendor==0x1111){
//printk("touch__________________________%s\n",__func__); //touch
return 0;
}
1111假設是我的觸摸屏的廠商id,這樣就比對失敗了
其次,自己寫的usb觸摸屏驅動随着熱拔插裝置節點也不能變化,那麼...
我們知道input裝置是虛拟的裝置(沒有硬體裝置的),那麼随着usb的插拔這個虛拟裝置并不需要unregister,也就是說你usb_driver的disconnect方法中别input_unregister_device,釋放在module_exit中釋放
在usb_driver的probe方法中也别input_allocate_device和input_register_device這兩個方法放在module_init的函數中
這樣以input裝置節點就不會變了,熱拔插也沒問題了
3.滑鼠對觸摸屏的影響
qt底層用QSocketNotifier監聽着:/dev/input/touchscreen0和/dev/input/mice兩個裝置節點,一有資料可讀就調用其connect指定的SLOT函數(qt的信号與槽)
tslib的:
int fd = ts_fd(dev);//擷取裝置的fd(/dev/input/touchscreen0)
mouseNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); //建立了QsocketNotifier監聽fd
connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));//調用readMouseData方法
讀資料的函數void QWSTslibMouseHandlerPrivate::readMouseData()
滑鼠的:
QSocketNotifier *mouseNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData(int)));
讀資料的函數void QWSPcMouseHandlerPrivate::readMouseData(int fd)
添加點調試資訊進去,發現每次點選觸摸屏不僅會引起/dev/input/touchscreen0可讀,而且會引起/dev/input/mice裝置可讀.移動滑鼠的話就隻有/dev/input/mice可讀而已,
so問題必須是出現在/dev/input/mice裝置相關的源碼中,就是moousedev.c啦.
我幹的活就是注釋掉和絕對坐标相關的代碼,如下:
static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
unsigned int code, int value)
{
int min, max, size;
#if 0 //MHB
switch (code) {
case ABS_X:
min = input_abs_get_min(dev, ABS_X);
max = input_abs_get_max(dev, ABS_X);
size = max - min;
if (size == 0)
size = xres ? : 1;
clamp(value, min, max);
//printk("size=%d,xres=%d\n",size,xres);
mousedev->packet.x = ((value - min) * xres) / size;
mousedev->packet.abs_event = 1;
break;
case ABS_Y:
min = input_abs_get_min(dev, ABS_Y);
max = input_abs_get_max(dev, ABS_Y);
size = max - min;
if (size == 0)
size = yres ? : 1;
clamp(value, min, max);
//printk("size=%d,yres=%d\n",size,yres);
mousedev->packet.y = yres - ((value - min) * yres) / size;
mousedev->packet.abs_event = 1;
break;
}
#endif
}
這樣注釋掉上報的ABS_X和ABS_Y事件對于/dev/input/mice來說等于給截斷了,是以觸摸的時候不會引起/dev/input/mice裝置的可讀,同時也不會影響相對位移事件對/dev/input/mice的通訊
由于mice這個節點是固定的,是以也支援熱拔插
ok現在應該滑鼠觸摸屏都支援熱拔插了,而且滑鼠和觸摸兩個操作不會互相影響了。
補充最近的收獲
由于硬體上的usb開關小闆有點設計問題,切換usb的時候隻是切換資料口,5v和gnd都沒有切換,使得熱拔插問題又不行了。
改成走hid路線,屏蔽usbtouchscreen.c的驅動-->比對hid
(hid的代碼參考MODULE_AUTHOR("Stephane Chatty <[email protected]>")的代碼高版本核心中drivers/hid/hid-multitouch.c)
碰到問題1:
hid驅動識别出是多點的,走多點的驅動,而tslib是隻支援單點的,所有出現"selected device is not a touchscreen I understand"
if (
!(
(ioctl(ts->fd, EVIOCGVERSION, &version) >= 0) &&
(version == 0x010001) &&
(ioctl(ts->fd, EVIOCGBIT(0, sizeof(bit) * 8), &bit) >= 0) &&
(bit & (1 << EV_ABS)) &&
(ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit) * 8), &absbit) >= 0) &&
(absbit & (1 << ABS_X)) &&
(absbit & (1 << ABS_Y)) &&
(absbit & (1 << ABS_PRESSURE))
)
)
{
fprintf(stderr, "selected device is not a touchscreen I understand\n");
return -1;
}
解決方法:
1.修改上報事件:多點改為單點
驅動中上報事件修改成ABS_X,ABS_Y..
for (i=0; i<td->num_expected; i++)
{
input_report_abs(input, ABS_MT_TOUCH_MAJOR, td->slots[i].valid);
if (td->slots[i].valid)
{
input_report_abs(input, ABS_MT_TRACKING_ID, td->slots[i].id);
input_report_abs(input, ABS_MT_POSITION_X, td->slots[i].x);
input_report_abs(input, ABS_MT_POSITION_Y, td->slots[i].y);
}
input_mt_sync(input);
}
改成
input_report_abs(input, ABS_X,td->slots[i].x);
input_report_abs(input, ABS_Y, td->slots[i].y);
input_report_abs(input, ABS_PRESSURE, td->slots[i].valid); //按下?
2.修改input裝置屬性設定
在hidinput_connect函數中
if(hid->vendor==0xxxx){
set_bit(EV_KEY, input_dev->evbit);
set_bit(EV_ABS, input_dev->evbit);
set_bit(BTN_TOUCH, input_dev->keybit);
input_set_abs_params(input_dev, ABS_X, 0, 0x7FFF, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 0, 0x7FFF, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
}
else{
input_dev->setkeycode_new = hidinput_setkeycode;
input_dev->getkeycode_new = hidinput_getkeycode;
}
ok,這樣hid就識别成單點的了,ts_lib就認裝置了
注意:hidinput_connect是對所有hid裝置都作用的,是以添加if(hid->vendor==0xxxx) xxxx為廠商ID這個是必須的,不然滑鼠鍵盤等裝置會變成觸摸屏裝置了。
問題2:熱拔插
在hidinput_connect函數中可以看到input裝置是動态配置設定的
hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
input_dev = input_allocate_device();
雖然udev會識别觸摸屏,并産生/dev/input/touchscreen0連結節點(/etc/udev/rules.d/local.rules檔案中)
# Create a symlink to any touchscreen input device
SUBSYSTEM=="input", KERNEL=="event[0-9]*", SYSFS{modalias}=="input:*-e0*,3,*a0,1,*18,*", SYMLINK+="input/touchscreen0"
SUBSYSTEM=="input", KERNEL=="event[0-9]*", SYSFS{modalias}=="ads7846", SYMLINK+="input/touchscreen0"
但是對于tslib來說還是不能熱拔插的(必須重新開機 ts_test或對應的qt程式)
是以需要按以前方法脫離usb裝置和input裝置,不好改
索性添加一個虛拟的input裝置
在Stephane Chatty的程式中修改
先添加全局結構體
#define TOUCH 1
#if TOUCH
static struct input_dev *Vtouch;
#endif
module_init方法中添加
#if TOUCH
Vtouch=input_allocate_device(); //輸入裝置記憶體配置設定->設定參數->注冊
set_bit(EV_KEY, Vtouch->evbit);
set_bit(EV_ABS, Vtouch->evbit);
set_bit(BTN_TOUCH, Vtouch->keybit);
input_set_abs_params(Vtouch, ABS_X, 0, 0x7FFF, 0, 0);
input_set_abs_params(Vtouch, ABS_Y, 0, 0x7FFF, 0, 0);
input_set_abs_params(Vtouch, ABS_PRESSURE, 0, 1, 0, 0);
Vtouch->name = "Vtouch";
Vtouch->phys = "paomadi";
Vtouch->id.bustype = BUS_USB;
Vtouch->id.vendor = 0xxxx;
Vtouch->id.product = 0x0000;
Vtouch->id.version = 0x0000;
if(input_register_device(Vtouch))
printk("input_register_device error!\n");
#endif
注意這個Vtouch->name域,後面有大作用哦
在module_exit方法中添加
#if TOUCH
input_unregister_device(Vtouch);
#endif
在上報事件中來個很賤的招
input_report_abs(input, ABS_X,td->slots[i].x);
input_report_abs(input, ABS_Y, td->slots[i].y);
input_report_abs(input, ABS_PRESSURE, td->slots[i].valid);
#if TOUCH
input_report_abs(Vtouch, ABS_X,td->slots[i].x);
input_report_abs(Vtouch, ABS_Y, td->slots[i].y);
input_report_abs(Vtouch, ABS_PRESSURE, td->slots[i].valid);
input_sync(Vtouch);
#endif
好,這樣虛拟的input裝置節點就固定了,不會随着usb拔插而改變
但是它可能是event0也可以是event1...關鍵看它啥時候給input_register_device了,這就有潛在的危險"萬一不是event0呢!"
souceinsight搜尋"event%d"
在/drivers/input/Evdev.c檔案的evdev_connect函數中修改
if(dev->name=="Vtouch"){ // touch
dev_set_name(&evdev->dev, "Vtouch");
}
else{
dev_set_name(&evdev->dev, "event%d", minor);
}
編譯核心更新到開發闆,你會發現/dev/input下沒有Vtouch
so ..修改udev規則/etc/udev/rules.d/udev.rules檔案
#input devices分支下添加
KERNEL=="Vtouch” NAME="input/%k"
重新開機闆子/dev/input/Vtouch檔案就存在了
修改ts_lib的配置環境變量
export QWS_MOUSE_PROTO="tslib:/dev/input/Vtouch mouseman:/dev/input/mice"
export TSLIB_TSDEVICE="/dev/input/Vtouch"
ok全部搞定