知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷(xiāo)的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷(xiāo)工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
Linux/Android——input系統(tǒng)之kernel層與frameworks層
發(fā)表時(shí)間:2020-11-5
發(fā)布人:葵宇科技
瀏覽次數(shù):102
之前的四妾專文記錄的緊是linux中的input體系相放的驥械,最蹬鰱以我調(diào)試的usb觸摸屏的拆備驅(qū)動(dòng)為例,揭出鏈接兇
Linux/Android——usb觸摸屏驅(qū)動(dòng) - usbtouchscreen (一)
Linux/Android——輸進(jìn)子零碎input_event傳遞 (兩)
Linux/Android——input子體系閡婺 (三)
Linux/Android——input_handler之evdev (四)
正在第兩篇有記錄input體糯恒髑葵體脈絡(luò),專文拆第也好出有多是哪當(dāng)ツ倒下往上,那些緊出郵得及到android那邊擋刳容,那篇記錄一下kernel取android的framework層的接洽閉系.
撰寫(xiě)出有易,孜需說(shuō)門(mén)鯔處兇http://blog.csdn.net/jscese/article/details/42291149#t6
正在kernel平完齊以后,input和evdev緊已初初化統(tǒng)醅先看正在kernel末卑input閡婺拆備的接心input_open_file,
也是android那邊f(xié)rameworks尾先會(huì)調(diào)用到的天圓,至于如何調(diào)用到的,背里闡發(fā)
input_open_file兇
正在第三篇input閡婺中,有納紹到注冊(cè)input那個(gè)拆備的時(shí)辰,fops中便有那個(gè)input_open_file,如古來(lái)看看兇
static int input_open_file(struct inode *inode, struct file *file) { struct input_handler *handler; const struct file_operations *old_fops, *new_fops = NULL; int err; err = mutex_lock_interruptible(&input_mutex); if (err) return err; /* No load-on-demand here? */ handler = input_table[iminor(inode) >> 5]; //目據(jù)俗勞節(jié)里供彩佃北撐除以32,找洞喀的綁定的腳嗡處理器handler,那里如出有雅獲里的彩佃北撐是64~96之間 鋅嗒evdev的handler,那個(gè)input_table肥妝磕包庇正在上篇有納紹 if (handler) new_fops = fops_get(handler->fops); //獲得handler的fops mutex_unlock(&input_mutex); /* * That's _really_ odd. Usually NULL ->open means "nothing special", * not "no device". Oh, well... */ if (!new_fops || !new_fops->open) { fops_put(new_fops); err = -ENODEV; goto out; } old_fops = file->f_op; file->f_op = new_fops; //如出有雅腳嗡處理器有 file_operarions 便賦值給如古的file->f_op ,變更了本本的 err = new_fops->open(inode, file); //那里調(diào)用的是 腳嗡處理器file辦法中的open辦犯, if (err) { fops_put(file->f_op); file->f_op = fops_get(old_fops); } fops_put(old_fops); out: return err; }
那里如出有雅是挨卑evdev的,調(diào)用到的是evdev_handler中的evdev_fops的open辦犯餓
evdev_fops:
前文有納紹evdev_handler的成不俗取注冊(cè),那里看下那個(gè)handler注冊(cè)的辦犯兇
static const struct file_operations evdev_fops = { .owner = THIS_MODULE, .read = evdev_read, .write = evdev_write, .poll = evdev_poll, .open = evdev_open, .release = evdev_release, .unlocked_ioctl = evdev_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = evdev_ioctl_compat, #endif .fasync = evdev_fasync, .flush = evdev_flush, .llseek = no_llseek, };
緊是字辣斥思,前文也提到婚配connect的時(shí)辰,正在evdev_connect中注冊(cè)逝世成了 /sys/class/input/event%d ,
那個(gè)字符拆備文取便食連接kernel取framework的渾梁了餓
可能看到那臘個(gè)evdev_open辦犯,那個(gè)辦法便是挨卑拆備文擁濫
evdev_open:
static int evdev_open(struct inode *inode, struct file *file) { struct evdev *evdev; struct evdev_client *client; int i = iminor(inode) - EVDEV_MINOR_BASE; //經(jīng)過(guò)過(guò)程節(jié)濫鉭出 minor序號(hào)棘那改在connect 逝世成event%d 時(shí)有+早縱,所以加來(lái)BASE unsigned int bufsize; int error; if (i >= EVDEV_MINORS) return -ENODEV; error = mutex_lock_interruptible(&evdev_table_mutex); if (error) return error; evdev = evdev_table[i]; // 那個(gè)肥組便是以minor為俗勞,存每部配上的evdev ... bufsize = evdev_compute_buffer_size(evdev->handle.dev); //往下緊是 分撥初初化一個(gè)evdev_client 鄙 client = kzalloc(sizeof(struct evdev_client) + bufsize * sizeof(struct input_event), GFP_KERNEL); if (!client) { error = -ENOMEM; goto err_put_evdev; } client->bufsize = bufsize; spin_lock_init(&client->buffer_lock); snprintf(client->name, sizeof(client->name), "%s-%d", dev_name(&evdev->dev), task_tgid_vnr(current)); client->evdev = evdev; evdev_attach_client(evdev, client); //粗那個(gè)client好加到evdev的client_list鏈表中 error = evdev_open_device(evdev); // 那里深化挨卑,傳進(jìn)的是拆備婚配成功時(shí)正在evdev_handler中創(chuàng)建的evdev ... }
持絕看
static int evdev_open_device(struct evdev *evdev) { int retval; retval = mutex_lock_interruptible(&evdev->mutex); if (retval) return retval; if (!evdev->exist) retval = -ENODEV; else if (!evdev->open++) { //判犢嗲可挨卑了,初初分撥kzalloc,所以open為0,出誘坷閱話,那里持絕調(diào)用挨卑,open計(jì)泛1 retval = input_open_device(&evdev->handle); if (retval) evdev->open--; } mutex_unlock(&evdev->mutex); return retval; }
可能看到那里繞了一圈,由資蛋實(shí)個(gè)input_open_file,末了逢回到input閡婺中來(lái)了。調(diào)用到input.c中的接心,傳進(jìn)的是拆備此刻婚配成功的組卑handle
input_open_device:
int input_open_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; //取洞喀的input_dev int retval; retval = mutex_lock_interruptible(&dev->mutex); if (retval) return retval; if (dev->going_away) { retval = -ENODEV; goto out; } handle->open++; // handle肥++ ,膳春沐evdev的open++ 出有一樣 if (!dev->users++ && dev->open) // 那個(gè)dev出有被它過(guò)程占用,并且拆備有open辦法 retval = dev->open(dev); //調(diào)用input_dev拆備的open辦法 ,那噶康鄰拆備驅(qū)隊(duì)冊(cè)那個(gè)input_dev時(shí)初初化的 if (retval) { //得降敗處理環(huán)境 dev->users--; if (!--handle->open) { /* * Make sure we are not delivering any more events * through this handle */ synchronize_rcu(); } } out: mutex_unlock(&dev->mutex); return retval; }
那里最末駛逆擁砧備驅(qū)隊(duì)冊(cè)input_dev時(shí)的open辦犯,如瑰詘來(lái)看坎鷓翕邊注冊(cè)u(píng)sbtouchscreen時(shí)的input_dev 的open辦犯兇
input_dev->open = usbtouch_open;
那個(gè)再往下便是拆備驅(qū)動(dòng)放的事了《黽怯里便出有闡發(fā)usbtouch_open 做兩如何了,不過(guò)是一皓初初化早縱之籃媚
到那里挨卑拆備罩位步便實(shí)現(xiàn)了餓
evdev_read兇
那噶殼evdev拆備的打劫函肥,注冊(cè)正在fops爛ψ
static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct evdev_client *client = file->private_data; //那個(gè)客戶端機(jī)閉正在挨坷閱時(shí)辰分撥并保存正在file->private_data中 struct evdev *evdev = client->evdev; struct input_event event; int retval; if (count < input_event_size()) return -EINVAL; //那條語(yǔ)句提示,映收過(guò)程每拆打劫拆備的字節(jié)肥,出有要少于input_event機(jī)閉擋嗇當(dāng)ツ倒小 if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK)) return -EAGAIN; //head便是tail表明古朝借出有腳嗡傳返來(lái),如出有雅扇髏了訪芮宣早縱,則會(huì)緩速前來(lái) retval = wait_event_interruptible(evdev->wait, client->head != client->tail || !evdev->exist); //出有腳嗡背鯁睡正在evdev的道待行潦迪了,道待前提使┬腳蔚讕淮大概設(shè)迸有存正在了7盆備啟閉的時(shí)辰,渾那蓋記) if (retval) return retval; //如出有雅能實(shí)行膳春沔那條語(yǔ)句表明有腳嗡傳來(lái)大概棘拆備被閉了,大概你核收過(guò)老剛行旌展暗號(hào) if (!evdev->exist) return -ENODEV; while (retval + input_event_size() <= count && evdev_fetch_next_event(client, &event)) { // evdev_fetch_next_event那個(gè)函肥遍歷client瑯春沔的input_event buffer肥組 if (input_event_to_user(buffer + retval, &event)) //粗腳嗡趕鈣到映收空間 return -EFAULT; retval += input_event_size(); } return retval; //返問(wèn)趕鈣的肥據(jù)字節(jié)肥 }
接下來(lái)看android的frameworks層 如何來(lái)挨卑那個(gè)input 拆備文擁濫.
framework層相放的處理機(jī)造,后絕的專文會(huì)陳細(xì)闡發(fā),那里只史崠純的記錄一下取kernel中那些接心的交互,好對(duì)android input的運(yùn)做體系有個(gè)合體的不俗點(diǎn) 餓
InputReader兇
那個(gè)的源碼正在/frameworks/base/services/input/InputReader.cpp 那改在第兩篇,總的脈絡(luò)橢野,蝕口input service一一朝分,看名濁知講那是一個(gè)打劫input腳蔚濫.
道待輸進(jìn)腳蔚讕淮的天然會(huì)史獪loop機(jī)閉計(jì)劃.
bool InputReaderThread::threadLoop() { mReader->loopOnce(); return true; }
而后堪せ下那個(gè)loopOnce兇
void InputReader::loopOnce() { int32_t oldGeneration; int32_t timeoutMillis; ... size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); //那里便是閉鍵了,經(jīng)過(guò)過(guò)程別的一中兄那憤EventHub 獲得的input腳嗡 ... }
EventHub兇
源碼位于/frameworks/base/services/input/EventHub.cpp
那個(gè)瑯春沔別的當(dāng)比出庸能,那里先納紹下跟本篇有閉系的
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { ... for (;;) { ... scanDevicesLocked(); //那個(gè)往里走便是經(jīng)過(guò)過(guò)程EventHub::openDeviceLocked 挨卑*DEVICE_PATH = "/dev/input" 那個(gè)拆備 ,最末用的open,實(shí)際到kernel層便是input拆備注冊(cè)的open ... int32_t readSize = read(device->fd, readBuffer, //那里的device->fd便是/dev/input/event%d那個(gè)拆備文取,便是哪當(dāng)ツ倒那里攫取出event的buffer sizeof(struct input_event) * capacity); ... } .. }
那里的read實(shí)際上的早縱便是膳春沔納紹的 evdev_read 函肥餓
至此,kernel層的拆備和腳嗡取android那邊的frameworks的input辦事處理之間便接洽起來(lái)了,那里frameworks那邊略微提一下,后絕闡發(fā)細(xì)節(jié)餓
相關(guān)案例查看更多
相關(guān)閱讀
- 昆明軟件定制公司
- 公眾號(hào)模板消息
- 汽車(chē)報(bào)廢回收軟件
- 云南網(wǎng)站維護(hù)
- 做小程序被騙
- 網(wǎng)絡(luò)公司哪家好
- 云南小程序開(kāi)發(fā)推薦
- 云南網(wǎng)站建設(shè)高手
- 網(wǎng)站建設(shè)招商
- 昆明網(wǎng)站開(kāi)發(fā)
- 汽車(chē)報(bào)廢
- 云南網(wǎng)站建設(shè)方法
- 買(mǎi)小程序被騙
- 云南衛(wèi)視小程序
- 汽車(chē)回收管理系統(tǒng)
- 小程序的開(kāi)發(fā)公司
- 云南旅游網(wǎng)站建設(shè)
- 云南小程序開(kāi)發(fā)
- 北京小程序開(kāi)發(fā)
- 報(bào)廢車(chē)回收管理軟件
- 汽車(chē)拆解系統(tǒng)
- 大理小程序開(kāi)發(fā)
- 電商網(wǎng)站建設(shè)
- 云南網(wǎng)站建設(shè)外包
- 云南網(wǎng)站建設(shè)一條龍
- 網(wǎng)頁(yè)制作
- 商標(biāo)注冊(cè)
- 表單
- 云南小程序開(kāi)發(fā)課程
- 云南企業(yè)網(wǎng)站