色偷偷偷久久伊人大杳蕉,色爽交视频免费观看,欧美扒开腿做爽爽爽a片,欧美孕交alscan巨交xxx,日日碰狠狠躁久久躁蜜桃

x
x

linux驅(qū)動(dòng)-Input輸入子系統(tǒng)

發(fā)布時(shí)間:2015-5-21 08:37    發(fā)布者:Fundyqds
以前,看過(guò)國(guó)嵌關(guān)于input子系統(tǒng)的視頻課程,說(shuō)實(shí)話,我看完后腦子里很亂,給我的印象好像是input子系統(tǒng)驅(qū)動(dòng)是一個(gè)全新的驅(qū)動(dòng)架構(gòu),疑惑相當(dāng)多。前幾天在網(wǎng)上,看到有很多人介紹韋東山老師的linux驅(qū)動(dòng)課程很不錯(cuò),于是,我就買(mǎi)了第二期的視頻,看了韋老師講解的input子系統(tǒng)視頻課程后,我完全明白了整個(gè)input子系統(tǒng)的工作機(jī)制。為了方便以后查閱,對(duì)input子系統(tǒng)的整體框架總結(jié)如下:

典型的輸入設(shè)備(如鍵盤(pán)、鼠標(biāo))的工作機(jī)制都是差不多的,都是在設(shè)備有動(dòng)作時(shí),向CPU產(chǎn)生一個(gè)中斷,通知它讀取相應(yīng)的數(shù)據(jù)。Linux為了方便開(kāi)發(fā)這一類(lèi)驅(qū)動(dòng),它實(shí)現(xiàn)了這類(lèi)驅(qū)動(dòng)的通用部分,只留下與設(shè)備相關(guān)的部分,這樣使得開(kāi)發(fā)這一類(lèi)驅(qū)動(dòng)更加方便。
在Linux中,Input子系統(tǒng)由三大部分組成,它們是Input子系統(tǒng)核心層、Input子系統(tǒng)事件處理層和Input子系統(tǒng)設(shè)備驅(qū)動(dòng)層。在通常情況下,Input子系統(tǒng)核心層和Input子系統(tǒng)事件處理層都已經(jīng)實(shí)現(xiàn)了,而作為驅(qū)動(dòng)開(kāi)發(fā)者,我們僅僅只需要完成Input子系統(tǒng)設(shè)備驅(qū)動(dòng)層。
對(duì)于一個(gè)完整的驅(qū)動(dòng)程序,我們首先需要確定設(shè)備的主設(shè)備號(hào),次設(shè)備號(hào),然后向系統(tǒng)注冊(cè)該設(shè)備,最后實(shí)現(xiàn)file_operations結(jié)構(gòu)體中的函數(shù)。在Input子系統(tǒng)中,這些步驟會(huì)分布到不同的層中,最后三個(gè)層通過(guò)一些聯(lián)系構(gòu)成了一個(gè)完整的驅(qū)動(dòng)程序。
在input子系統(tǒng)中有三個(gè)比較中要的結(jié)構(gòu)體,它們分別是input_handler結(jié)構(gòu)體、input_dev結(jié)構(gòu)體、input_handle結(jié)構(gòu)體。它們的具體代碼如下:
struct input_handler {
void *private; //driver相關(guān)數(shù)據(jù)
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); //input_event函數(shù)會(huì)調(diào)用此函數(shù)
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
const struct file_operations *fops; //file_operation結(jié)構(gòu)體,會(huì)替換input.c里的file_operation結(jié)構(gòu)體
int minor;
const char *name; //input_handler名稱(chēng)
const struct input_device_id *id_table;
const struct input_device_id *blacklist;
struct list_head        h_list; //與該handler相關(guān)的handle
struct list_head        node;
};
struct input_dev {
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;
int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
struct ff_device *ff;
unsigned int repeat_key;
struct timer_list timer;
int sync;
int abs[ABS_MAX + 1];
int rep[REP_MAX + 1];
unsigned long key[BITS_TO_LONGS(KEY_CNT)];
unsigned long led[BITS_TO_LONGS(LED_CNT)];
unsigned long snd[BITS_TO_LONGS(SND_CNT)];
unsigned long sw[BITS_TO_LONGS(SW_CNT)];
int absmax[ABS_MAX + 1];
int absmin[ABS_MAX + 1];
int absfuzz[ABS_MAX + 1];
int absflat[ABS_MAX + 1];
int absres[ABS_MAX + 1];
int (*open)(struct input_dev *dev);
void (*close)(struct input_dev *dev);
int (*flush)(struct input_dev *dev, struct file *file);
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
struct input_handle *grab;
spinlock_t event_lock;
struct mutex mutex;
unsigned int users;
bool going_away;
struct device dev;
struct list_head        h_list;  //與該input_dev相關(guān)的handle
struct list_head        node;
};
struct input_handle {
void *private;
int open;
const char *name;
struct input_dev *dev;  //指向input_dev
struct input_handler *handler; //指向input_handler
struct list_head        d_node;
struct list_head        h_node;
};
在Input.c(drivers/input)的input_init函數(shù)中,有:
err=register_chrdev(INPUT_MAJOR, "input", &input_fops)
它向系統(tǒng)中注冊(cè)了一個(gè)主設(shè)備號(hào)為INPUT_MAJOR(13),名為input的設(shè)備。而它的file_operations結(jié)構(gòu)體,如下所示:
static const struct file_operations input_fops = {
   .owner = THIS_MODULE,
   .open = input_open_file,
};
它僅僅實(shí)現(xiàn)了open函數(shù),為沒(méi)有實(shí)現(xiàn)其他函數(shù)。其實(shí)其他函數(shù)會(huì)在其open函數(shù)中實(shí)現(xiàn)。
在input_open_file函數(shù)中,會(huì)把Input子系統(tǒng)的事件處理層相關(guān)結(jié)構(gòu)體handler的file_operations賦值給input_fops,從而完整的實(shí)現(xiàn)了file_operations結(jié)構(gòu)體。具體實(shí)現(xiàn)的代碼:
new_fops = fops_get(handler->fops)
file->f_op = new_fops;
從這里我們可以看出一個(gè)Input子系統(tǒng)的驅(qū)動(dòng)的file_operations結(jié)構(gòu)體是在handler結(jié)構(gòu)體中實(shí)現(xiàn)的。
對(duì)于input_handler結(jié)構(gòu)體,它是input子系統(tǒng)中事件處理層相關(guān)的結(jié)構(gòu)體,對(duì)于一個(gè)具體的事件處理,需要向事件處理層注冊(cè)這樣一個(gè)結(jié)構(gòu)體,如在鼠標(biāo)的事件處理程序mousedev.c的mousedev_init函數(shù)中,會(huì)調(diào)用input_register_handler函數(shù),注冊(cè)一個(gè)具體的handler。而在input_register_handler函數(shù)中,會(huì)將handler添加到input_handler_list中,然后在input_dev_list中尋找相匹配的dev。具體代碼:
list_for_each_entry(dev, &input_dev_list, node)
input_attach_handler(dev, handler);
因而,要形成一個(gè)完成的驅(qū)動(dòng),則必須有相應(yīng)的dev。
對(duì)于input_dev結(jié)構(gòu)體,它是input子系統(tǒng)中設(shè)備驅(qū)動(dòng)層相關(guān)的結(jié)構(gòu)體,對(duì)于一個(gè)具體的設(shè)備,需要向設(shè)備驅(qū)動(dòng)層注冊(cè)這樣一個(gè)結(jié)構(gòu)體,如在鼠標(biāo)的設(shè)備驅(qū)動(dòng)程序usbmouse.c的usb_mouse_probe函數(shù)中,會(huì)調(diào)用input_register_device函數(shù),注冊(cè)一個(gè)具體的dev。而在input_register_device函數(shù)中,會(huì)將dev添加到input_dev_list中,然后再input_handler_list尋找相匹配的handler。具體代碼:
list_add_tail(&dev->node, &input_dev_list);
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);
在input_attach_handler函數(shù)中,會(huì)調(diào)用input_match_device函數(shù),將input_dev_list中的dev與handler相匹配或?qū)nput_handler_list中的handler與dev相匹配,匹配成功后就會(huì)調(diào)用handler中的connect函數(shù)。而在connect函數(shù)中,會(huì)通過(guò)handle結(jié)構(gòu)體將匹配好的handler和dev聯(lián)系起來(lái)。如mousedev.c中,connect函數(shù)中調(diào)用了mousedev_create函數(shù),而在mousedev_create函數(shù)中,將handle結(jié)構(gòu)中的handler指向匹配好的handler,而dev指向匹配好的dev,然后會(huì)調(diào)用input_register_handle函數(shù)。
mousedev->handle.dev = input_get_device(dev);
mousedev->handle.name = dev_name(&mousedev->dev);
error = input_register_handle(&mousedev->handle);
在 input_register_handle函數(shù)中,將input_handle結(jié)構(gòu)體中的d_node和h_node成員分別添加到了匹配好的dev結(jié)構(gòu)體的h_list中和匹配好的handler結(jié)構(gòu)體的h_list中。
struct input_handler *handler = handle->handler;
struct input_dev *dev = handle->dev;
list_add_tail_rcu(&handle->d_node, &dev->h_list);
list_add_tail(&handle->h_node, &handler->h_list);
這樣,Input驅(qū)動(dòng)程序中的設(shè)備驅(qū)動(dòng)和事件處理就這樣無(wú)縫連接起來(lái)了,無(wú)論是我們先有了handler還是先有了dev,input子系統(tǒng)都會(huì)找了與之匹配的dev或handler,使得三部分之間更加整體化。

本文地址:http://m.54549.cn/thread-149581-1-1.html     【打印本頁(yè)】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表