linux input event簡單使用

最近需要在kernel  的驅動裏邊將事件傳到用戶空間,打算用input子系統做,用戶空間開一個線程用epoll方式來讀取數據,

記錄一下如何快速簡單使用input子系統上報事件。

//定義一個input_dev 類型結構體變量
static struct input_dev* test_input_dev = NULL;

//創建並初始化	
test_input_dev  = input_allocate_device();
if (test_input_dev == NULL) {
	printk(KERN_ERR"failed to allocate test input device\n");
	return -1;
}
test_input_dev->name = "test_input_event";
set_bit(EV_MSC,  test_input_dev->evbit);
set_bit(MSC_RAW, test_input_dev->mscbit);

//註冊節點
if (input_register_device(test_input_dev)) {
	pr_err("%s: failed to register test input device\n", __func__);
	input_free_device(test_input_dev);
	return -1;
}

/*邏輯處理*/
//上報事件
input_event(test_input_dev, EV_MSC, MSC_RAW, value);
input_sync(test_input_dev);


//隨驅動取消註冊
input_unregister_device(test_input_dev);
input_free_device(test_input_dev);

關於爲何要用EV_MSC類型,是因爲這次上報事件的類型input裏邊沒有定義,並且有時若你要上報的值範圍不在input子系統對應類型規定的值範圍內會出現值報不上去的情況,所以乾脆用EV_MSC比較好。另外一個原因就是以前在Android 8.1(高通驍龍845平臺,kernel 4.9)上用ABS類型可以報上去的值,到了android 9.0(同樣高通驍龍845平臺,kernel 4.9)就報不上去了,具體原因還沒有去深究。

簡單跟了一下源碼,爲何報不上去,應該是初始化的時候需要設定一個上報值的範圍,後面調用input_event()上報事件的時候有一個過濾檢測:

//android/kernel/msm-4.9/drivers/input/input.c

void input_event(struct input_dev *dev,
		 unsigned int type, unsigned int code, int value)
{
	unsigned long flags;

	if (is_event_supported(type, dev->evbit, EV_MAX)) {

		spin_lock_irqsave(&dev->event_lock, flags);
		input_handle_event(dev, type, code, value);
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}
}


static inline int is_event_supported(unsigned int code,
				     unsigned long *bm, unsigned int max)
{
	return code <= max && test_bit(code, bm);
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章