日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux内核关闭触摸屏校准,linux内核usb触摸屏驱动bug调试- selected device is not a touchscreen I understand...

發(fā)布時間:2025/3/19 linux 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux内核关闭触摸屏校准,linux内核usb触摸屏驱动bug调试- selected device is not a touchscreen I understand... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

近期給客戶調試一塊數(shù)控板,今天客戶帶過來一個屏,并且有一個usb的觸摸屏芯片接在屏上。屏很快就弄好正常顯示。

觸摸屏在內核下找到usb 觸摸屏驅動,內核啟動后這個usb轉的觸摸屏也正常找到,注冊為event接口事件event0, cat /dev/event0,觸摸屏幕有亂碼輸出,說明usb觸摸屏驅動產(chǎn)生中斷并且將采集數(shù)據(jù)上報input子系統(tǒng)了。

然后用我移植的tslib中有幾個校準測試程序,運行,發(fā)現(xiàn)出現(xiàn)下面的錯誤:

selected device is not a touchscreen I understand

屏上出現(xiàn)校準界面,但是校準的5個點瞬間連了一遍程序就出錯結束了。

多次嘗試都是這個結果,我就插入一個usb的鼠標,識別產(chǎn)生event1,我就講為tslib運行設置的環(huán)境變量中tslib的設備設為event1,再運行校準程序,發(fā)現(xiàn)現(xiàn)象跟觸摸屏的一樣。也就說tslib中應該是有容錯處理,會先根據(jù)一些條件來判斷這個環(huán)境變量指定的設備是否是一個真正的觸摸屏設備。

想多無意,還是多看代碼,于是在tslib源碼中找到上面這句的出處如下:

static int check_fd(struct tslib_input *i)

{

struct tsdev *ts = i->module.dev;

int version;

u_int32_t bit;

u_int64_t absbit;

if (! ((ioctl(ts->fd, EVIOCGVERSION, &version) >= 0) &&

(version == EV_VERSION) &&

(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;

}

if (bit & (1 << EV_SYN))

i->using_syn = 1;

return 0;

}

這個check_fd中會根據(jù)這些條件來判斷是否打印如上錯誤。

第一個條件是ioctl獲取version,內核源碼下找到ioctl定義在driver/input/evdev.c中,對應命令EVIOCGVERSION定義值為0x10000 而編譯器中input.h中定義值也是0x10000,這個條件沒有問題。我看網(wǎng)上關于這個錯誤大部分問題都是處在這里。可惜我的不是,繼續(xù)往下。

第二個條件是獲取input設備的bit標志,也就是看這個是被是否是一個觸摸屏設備。usb設備我之前也沒有接觸過,但是根據(jù)cat /dev/event0,有反應,說明usb部分采集數(shù)據(jù)是沒有問題的,只是上報給input子系統(tǒng)出了問題,所以應該想到的是看一下usb觸摸屏驅動注冊input設備的部分代碼,在usb觸摸屏驅動driver/usb/input/usbtouchscreen.c中的probe函數(shù)中代碼如下:

input_dev->name = usbtouch->name;

input_dev->phys = usbtouch->phys;

usb_to_input_id(udev, &input_dev->id);

input_dev->cdev.dev = &intf->dev;

input_dev->private = usbtouch;

input_dev->open = usbtouch_open;

input_dev->close = usbtouch_close;

input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);

input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);

input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);

input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);

if (type->max_press)

input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,

type->max_press, 0, 0);

可以看到evbit中設置了EV_ABS標志位。這樣第二個條件也滿足了。

第三個條件是獲取專為觸摸屏input設備準備的absbit標志中是否有觸摸屏對應的標志位,因為之前寫過一個觸摸屏驅動,所以知道觸摸屏標志位為x y press,也就是坐標以及按壓。

在input_set_abs_params實現(xiàn)中是為absbit置各種標志位。并且設置對應標志的范圍(min max),但是這個標志比如x y press的范圍在后面沒有看到使用,我也實驗發(fā)現(xiàn)min max都寫0也沒有問題,這個是題外話了。

這里就出現(xiàn)了問題了,usb觸摸屏中枚舉出來的設備中max_press和min_press都沒有設置,為0,所以最后這個設置press標志位的函數(shù)就沒有調用。

所以我上面出現(xiàn)selected device is not a touchscreen I understand 是因為? absbit & (1 << ABS_PRESSURE)不滿足造成的!

我把if判斷注釋掉,然后重編內核啟動,運行tslib測試程序,發(fā)現(xiàn)不會出現(xiàn)上面的錯誤退出了,這個問題算是解決。后來我實驗發(fā)現(xiàn)input_set_abs_params中設置x y press的min max都沒有用到,即使這些都設置為0也沒有影響。

校準測試程序正常算是運行,但是我點擊屏幕,校準程序并沒有檢測到我的點擊行為,接著就遇到了這個問題。接著研究搞定!

運行tslib測試程序沒有檢測到點擊事件,但是cat /dev/event0時點擊屏幕是有東西傳給input子系統(tǒng)的,這說明觸摸屏中斷是正常的。

之間編寫另外一個觸摸屏驅動的時候點擊事件上報坐標數(shù)據(jù)給input子系統(tǒng)是在觸摸屏的中斷中做的,因此需要找到這段代碼來看一下有沒有問題,在usbtouchscreen.c中找到如下代碼:

static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,

unsigned char *pkt, int len)

{

struct usbtouch_device_info *type = usbtouch->type;

if (!type->read_data(usbtouch, pkt))

return;

input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch);

if (swap_xy) {

input_report_abs(usbtouch->input, ABS_X, usbtouch->y);

input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);

} else {

input_report_abs(usbtouch->input, ABS_X, usbtouch->x);

input_report_abs(usbtouch->input, ABS_Y, usbtouch->y);

}

if (type->max_press)

input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press);

input_sync(usbtouch->input);

}

這段代碼是中斷中上報數(shù)據(jù)給input子系統(tǒng)的部分,report key是標志輸入事件是否按下和彈起,而對于觸摸屏來說上報的數(shù)據(jù)包括x y press,這段代碼中可以看出由于max_press為0,所以中斷中一直沒有上報press,也就是說usb觸摸屏一直上報的是坐標,但是press值一直為0,所以上層程序就會認為沒有按壓下去。所以沒有反應。在中斷中加打印,發(fā)現(xiàn)從usb讀出來的數(shù)據(jù)press值為0,不管是按下還是彈起,但是touch在按下的時候是1,彈起的時候是0,可以用這個值來上報給input子系統(tǒng)當前的press,函數(shù)修改如下:

static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,

unsigned char *pkt, int len)

{

struct usbtouch_device_info *type = usbtouch->type;

if (!type->read_data(usbtouch, pkt))

return;

input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch);

//zk modify for usb touchpad

input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->touch);

if (swap_xy) {

input_report_abs(usbtouch->input, ABS_X, usbtouch->y);

input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);

} else {

input_report_abs(usbtouch->input, ABS_X, usbtouch->x);

input_report_abs(usbtouch->input, ABS_Y, usbtouch->y);

}

#if 0

if (type->max_press)

input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press);

#endif

input_sync(usbtouch->input);

}

重新編譯內核,啟動,運行tslib的校準測試程序,可以正常點擊,并且tslib程序可以檢測到觸摸屏數(shù)據(jù)了!成功!!

總結

以上是生活随笔為你收集整理的linux内核关闭触摸屏校准,linux内核usb触摸屏驱动bug调试- selected device is not a touchscreen I understand...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。