linux輸入子系統

2021-07-25 11:16:31 字數 4496 閱讀 3660

/* 參考drivers\input\keyboard\gpio_keys.c */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

struct pin_desc;

struct pin_desc pins_desc[4] = ,,,

,};static struct input_dev *buttons_dev;

static struct pin_desc *irq_pd;

static struct timer_list buttons_timer;

static irqreturn_t buttons_irq(int irq, void *dev_id)

static void buttons_timer_function(unsigned long data)

else

}static int buttons_init(void)

return 0;

}static void buttons_exit(void)

del_timer(&buttons_timer);

input_unregister_device(buttons_dev);

input_free_device(buttons_dev);

}module_init(buttons_init);

module_exit(buttons_exit);

module_license("gpl");

drivers/input/input.c:

input_init > err = register_chrdev(input_major, "input", &input_fops);

// 放入鍊錶

list_add_tail(&handler->node, &input_handler_list);

// 對於每個input_dev,呼叫input_attach_handler

list_for_each_entry(dev, &input_dev_list, node)

input_attach_handler(dev, handler); // 根據input_handler的id_table判斷能否支援這個input_dev

註冊輸入裝置:

input_register_device

// 放入鍊錶

list_add_tail(&dev->node, &input_dev_list);

// 對於每乙個input_handler,都呼叫input_attach_handler

list_for_each_entry(handler, &input_handler_list, node)

input_attach_handler(dev, handler); // 根據input_handler的id_table判斷能否支援這個input_dev

input_attach_handler

id = input_match_device(handler->id_table, dev);

error = handler->connect(handler, dev, id);

註冊input_dev或input_handler時,會兩兩比較左邊的input_dev和右邊的input_handler,

根據input_handler的id_table判斷這個input_handler能否支援這個input_dev,

如果能支援,則呼叫input_handler的connect函式建立"連線"

怎麼建立連線?

1. 分配乙個input_handle結構體

2. input_handle.dev = input_dev;  // 指向左邊的input_dev

input_handle.handler = input_handler;  // 指向右邊的input_handler

3. 註冊:

input_handler->h_list = &input_handle;

inpu_dev->h_list      = &input_handle;

evdev_connect

evdev = kzalloc(sizeof(struct evdev), gfp_kernel); // 分配乙個input_handle

// 設定

evdev->handle.dev = dev;  // 指向左邊的input_dev

evdev->handle.name = evdev->name;

evdev->handle.handler = handler;  // 指向右邊的input_handler

evdev->handle.private = evdev;

// 註冊

error = input_register_handle(&evdev->handle);

// 否則休眠

retval = wait_event_interruptible(evdev->wait,

client->head != client->tail || !evdev->exist);

誰來喚醒?

evdev_event

wake_up_interruptible(&evdev->wait);

evdev_event被誰呼叫?

猜:應該是硬體相關的**,input_dev那層呼叫的

在裝置的中斷服務程式裡,確定事件是什麼,然後呼叫相應的input_handler的event處理函式

gpio_keys_isr

// 上報事件

input_event(input, type, button->code, !!state);

input_sync(input);

input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)

struct input_handle *handle;

list_for_each_entry(handle, &dev->h_list, d_node)

if (handle->open)

handle->handler->event(handle, type, code, value);

怎麼寫符合輸入子系統框架的驅動程式?

1. 分配乙個input_dev結構體

2. 設定

3. 註冊

4. 硬體相關的**,比如在中斷服務程式裡上報事件

struct input_dev {

void *private;

const char *name;

const char *phys;

const char *uniq;

struct input_id id;

unsigned long evbit[nbits(ev_max)];   // 表示能產生哪類事件

unsigned long keybit[nbits(key_max)]; // 表示能產生哪些按鍵

unsigned long relbit[nbits(rel_max)]; // 表示能產生哪些相對位移事件, x,y,滾輪

unsigned long absbit[nbits(abs_max)]; // 表示能產生哪些絕對位移事件, x,y

unsigned long mscbit[nbits(msc_max)];

unsigned long ledbit[nbits(led_max)];

unsigned long sndbit[nbits(snd_max)];

unsigned long ffbit[nbits(ff_max)];

unsigned long swbit[nbits(sw_max)];

測試:1. 

hexdump /dev/event1  (open(/dev/event1), read(), )

秒        微秒    類  code    value

0000000 0bb2 0000 0e48 000c 0001 0026 0001 0000

0000010 0bb2 0000 0e54 000c 0000 0000 0000 0000

0000020 0bb2 0000 5815 000e 0001 0026 0000 0000

0000030 0bb2 0000 581f 000e 0000 0000 0000 0000

2. 如果沒有啟動qt:

cat /dev/tty1

按:s2,s3,s4

就可以得到ls

或者:exec 0

Linux輸入子系統

1.1.input子系統概述 輸入裝置 如按鍵,鍵盤,觸控螢幕,滑鼠等 是典型的字元裝置,其一般的工作機制是低層在按鍵,觸控等動作發生時產生乙個中斷 或驅動通過timer定時查詢 然後cpu通過spi,i2c或者外部儲存器匯流排讀取鍵值,座標等資料,放乙個緩衝區,字元裝置驅動管理該緩衝區,而驅動的r...

Linux輸入子系統

linux系統提供了input子系統,按鍵 觸控螢幕 鍵盤 滑鼠等輸入都可以利用input介面函式來實現裝置驅動,最重要的資料結構是struct input dev 在linux 核心中,input裝置用input dev 結構 體描述,使用input子系統實現輸入裝置驅動的時候,驅動的核心工作是向...

Linux輸入子系統

位址 linux輸入子系統 按鍵與觸控螢幕的裝置驅動,在linux系統中實現這類裝置驅動的方法是利用input子系統。linux系統提供了input子系統,按鍵 觸控螢幕 鍵盤 滑鼠等輸入都可以利用input介面函式來實現裝置驅動,按鍵和觸控螢幕裝置驅動都可以作為input裝置驅動而實現。在linu...