輸入子系統是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...