1. 程式人生 > >Linux Input子系統淺析(二)-- 模擬tp上報鍵值【轉】

Linux Input子系統淺析(二)-- 模擬tp上報鍵值【轉】

repo input 開啟 handle 工程 static 我們 pro kthread

轉自:https://blog.csdn.net/xiaopangzi313/article/details/52383226

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/xiaopangzi313/article/details/52383226
通過前一節的分析得到,linux Input子系統上傳數據本質上是將input_dev的數據,上報給input_handler,
當用戶讀入event時,驅動層只需要利用copy_to_user將數據傳遞至用戶空間。當然,以上只是內核中Linux input
的機制,作為驅動工程師我們該如何使用input子系統呢?考慮到部分讀者沒有嵌入式設備,作者從一個虛擬嵌入式

設備的編寫,描述Input subsystem 的使用。
實際的嵌入式設備中,用的input system的設備很多,如gsensor,psensor,touch panel等,本文著重模擬一個
virsual touch 設備,讓其向上層空間報值,然後用戶空間可以通過通用IO來捕獲鍵值或者坐標。
一、 虛擬設備的編寫流程
1.定義虛擬設備結構體
struct touch_dev{
struct platform_device *p_dev; //定義平臺設備,這個不為必須
struct input_dev *input; //定義input設備結構體
int x; //定義坐標X
int y; //定義坐標Y,當然如果需要也可以添加鍵值
struct task_struct *run_thread; //定義內核線程,為了讓用戶空間隨時都抓到坐標,我們可以開啟線程
不斷上報
};
2. 註冊平臺設備和驅動
platform_device_register_simple("v_touch",-1,NULL,0);
platform_device_register_simple("v_touch",-1,NULL,0);
3. probe 函數實現
kthread_run(vtouch_thread,vtouch_dev,"vtouch_thread");
4. 內核線程實現
static int vtouch_thread(void *data)
{
int x,y;
struct touch_dev *vtouch_dev = (struct touch_dev*)data;

printk(KERN_INFO "vtouch thread running\n");

do{

...

printk("vtouch thread report\n");
msleep(2000);
} while(!kthread_should_stop());//線程退出條件

return 0;
}
二、 input 設備的添加流程
1.在 probe中添加
//為input device申請內存
vtouch_dev->input = input_allocate_device();
//設置 vtouch 設備名稱
vtouch_dev->input->name = "vtouch";
//設置設備支持坐標事件,包括X坐標,Y坐標事件,Z坐標事件。
set_bit(EV_ABS,vtouch_dev->input->evbit);
//對於X軸範圍是-1024到+1024,數據誤差是-2到+2,中心平滑位置是0
input_set_abs_params(vtouch_dev->input, ABS_X, -1024, 1024, 2, 0);
//同上
input_set_abs_params(vtouch_dev->input, ABS_Y, -1024, 1024, 2, 0);
//註冊輸入設備
ret = input_register_device(vtouch_dev->input);
if(ret < 0){
printk("%s register input device error\n",__func__);
goto input_register;
}
2.在線程中添加

//上報絕對坐標
input_report_abs(vtouch_dev->input,ABS_X,x);
input_report_abs(vtouch_dev->input,ABS_Y,y);
//上報同步通知
input_sync(vtouch_dev->input); //對於坐標必須添加
三、應用程序編寫
int main(void)
{
struct input_event ev;
int count,x,y;

int fd = open(EVENT_DEV, O_RDWR);


while(1){
count = read(fd, &ev,sizeof(struct input_event));
if(EV_ABS == ev.type){
if(ev.code == ABS_X){
x = ev.value;
}else if(ev.code == ABS_Y){
y = ev.value;
}
printf("position: x=%d, y=%d\n",x,y);
}else if(EV_SYN == ev.type){
puts("sync!");
}
}

return 0;
}
整體源碼如下:
驅動: input_simulate.c

應用: input_simulate_test.c

四、調試過程
1. 通過
cat /proc/bus/input/devices
查看與dev、input目錄下的event對應的設備

2. ./a.out //運行應用程序

實驗效果:

五、總結

就單純使用而言,應用input subsystem 我們只需要做以下工作,

1. 定義input_device 並分配調用input_allocate_device(); 分配空間

2. 設置input_dev 支持的事件類型如:set_bit,input_set_abs_params

3. 調用input_register_device 註冊input_dev

4. 調用input_report_abs,input_sync上報事件
---------------------
作者:xiaopangzi313
來源:CSDN
原文:https://blog.csdn.net/xiaopangzi313/article/details/52383226
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

Linux Input子系統淺析(二)-- 模擬tp上報鍵值【轉】