輸入子系統框架之我見

2021-06-08 19:33:02 字數 2575 閱讀 4211

輸入子系統是linux驅動中很重要的一部分,按鍵、觸控螢幕、滑鼠等等的驅動都可以通過這個框架來構建,下面就來總結下輸入子系統的框架。

核心層主要在input.c檔案中,

class_register(&input_class);

register_chrdev(input_major, "input", &input_fops);

先註冊個類,類下建立裝置,裝置號為13,操作函式為input_fops。

static const struct file_operations input_fops = ;

操作函式裡面只有乙個open函式,open可以得到inode、file結構體。由inode可以得到次裝置號,

input_handler   *handler = input_table[iminor(inode) >> 5];

input_table中根據次裝置號存放有輸入裝置的input_handler結構體,裡面包含有真正的操作函式,然後存放於file中:

file->f_op = new_fops;

這就是大致流程,就是input.c中轉站完成的任務。

下面做進一步的分析,主要是input_handler和input_dev兩個部分的連線:

以evdev.c來說明input_handler:

在evdev.c中,先構造input_handler結構體,並構造出真正的操作函式

static struct input_handler evdev_handler = ;

然後註冊,放入到input_table中去:

input_register_handler(&evdev_handler);

---->>> input_table[handler->minor >> 5] = handler;

再構造input_dev結構體,裡面包含了支援的事件型別等,然後註冊裝置:input_register_device(&input_dev),裡面具體完成什麼工作暫且先不分析。

來總起來看一下這兩個註冊,在input_dev和input_handler結構體中,都有兩個雙向鍊錶,這是核心負責管理的,我們可以不用去理它,但是深入理解這幾個鍊錶,對輸入子系統各個模組之間的關係會更加清晰。

註冊input_handler時,在input_register_handler的最後有:

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

list_for_each_entry(dev, &input_dev_list, node)

input_attach_handler(dev, handler);

首先把input_handler結構體裡的node放到input_handler_list中,構成了乙個input_handler鍊錶。然後對input_dev_list(這個鍊錶在註冊input_dev時會構造)中的每一項,都呼叫 input_attach_handler(dev, handler);就是把handler和dev看看是否匹配,就是說比較handler能否處理dev。

再看看註冊input_dev時,在input_register_device的最後也有:

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

list_for_each_entry(handler, &input_handler_list, node)

input_attach_handler(dev, handler);

input_dev中也有兩個雙向鍊錶,其一為node,把node放入input_dev_list中,就構造出了input_dev鍊錶,然後對input_handler鍊錶中的每一項呼叫input_attach_handler(dev, handler);看看input_handler是否支援input_dev。

由以上分析可知,無論是先註冊input_dev還是input_handler,都會先把他們放入到裝置鍊錶、處理鍊錶中去,註冊乙個input_dev時,就對input_handler鍊錶中的每一項handler比較,看是否支援。當註冊input_handler時,就會對input_dev鍊錶中每一項比較,看是否可以支援。

當判斷匹配時,比較input_handler的id_table和dev,當匹配時,就會呼叫input_handler的connect函式,在evdev.c中,connect函式構造了input_handle結構體,裡面的handler指向input_handler,dev指向input_dev,input_handle裡面也有兩個鍊錶,把它們分別放入input_dev和input_handler結構體的另外乙個鍊錶中,這樣,input_handler、input_dev和input_handle三者就建立了聯絡。

當應用程式讀資料時,如果緩衝區沒資料,並且檔案是非阻塞的,那麼,程式就會睡眠,當硬體裝置發生改變,就會上報事件input_event,然後就會呼叫input_handler的event中的處理函式,就會喚醒應用程式,來完成讀操作。

我們在寫輸入子系統的驅動函式時,只需要構造出input_dev,並且,在中斷處理函式中上報事件,就可以完成操作,input_handler系統已經幫我們完成。

以上就是輸入子系統的大概框架,說的比較粗淺,待以後逐步完善。

輸入子系統(1) 框架認識

入口函式 drivers input input.c input init err register chrdev input major,input input fops static const struct file operations input fops owner this modul...

linux輸入子系統 5 學習框架

注 本系列 input子系統學習系列文章,是我在實際開發過程中遇到也是必須啃下去的第乙個linux驅動,所以有必要記載下來的。由於剛開始未接觸過input子系統,部分資料還是借鑑網路,本系列文章是本人的學習心得以及集百家所長的產物。input subsystem理論部分 input subsyste...

輸入子系統

驅動函式操作步驟 在初始化函式中 1.分配乙個input dev結構體 struct input dev buttons dev buttons dev input allocate device 2.設定 2.1 能產生哪類事件 set bit ev key,buttons dev evbit s...