当前位置:网站首页>Article take you understand interrupt the key driver of polling mechanism
Article take you understand interrupt the key driver of polling mechanism
2022-08-10 11:25:00 【life needs depth】
- This section continuesTake you to play with the interrupt mode key driver(详解)improvement,添加poll机制.
- 那么我们为什么还需要poll机制呢.之前的测试程序是这样:
while (1)
{
read(fd, &key_val, 1);
printf("key_val = 0x%x\n", key_val);
}
- 在没有poll机制的情况下,Most of the time the program is therereadthe position where it is dormant.If we don't want the program to stop at this position,Rather want when there is a key press,我们再去read,因此我们编写poll函数,测试程序调用pollfunction according to the return value,来决定是否执行read函数.
- poll机制作用:相当于定时器,Set a certain time to make the process wait for the resource,If the time is up, the interrupt is still in sleep state(等待队列),pollThe mechanism will wake up the interrupt,Get a resource once
1.pollMechanism Kernel Framework
- 如下图所示,在用户层上,使用poll或select函数时,和open、readThose functions are the same,Also into the kernelsys_poll函数里,接下来我们分析sys_poll函数来了解poll机制(位于/fs/select.c)
【 文章福利】小编推荐自己的Linux内核技术交流群:【 891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前100名进群领取,额外赠送一份价值 699the kernel package(含视频教程、电子书、实战项目及代码)
学习直通车:
内核资料直通车:
1.1 sys_poll代码如下:
asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,long timeout_msecs)
{
if (timeout_msecs > 0) //参数timeout>0
{
timeout_jiffies = msecs_to_jiffies(timeout_msecs); //Calculated by frequencytimeoutHow many count values are required for the time
}
else
{
timeout_jiffies = timeout_msecs; //如果timeout时间为0,直接赋值
}
return do_sys_poll(ufds, nfds, &timeout_jiffies); //调用do_sys_poll.
}
1.2 然后进入do_sys_poll(位于fs/select.c):
int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
{
... ...
/*初始化一个poll_wqueues变量table*/
poll_initwait(&table);
... ...
fdcount = do_poll(nfds, head, &table, timeout);
... ...
}
1.3进入poll_initwait函数,Discovery mainly implements the following sentence,This will be analyzed later:
table ->pt-> qproc=__pollwait; //__pollwait将在驱动的poll函数里的poll_wait函数用到
1.4然后进入do_poll函数, (位于fs/select.c):
static int do_poll(unsigned int nfds, struct poll_list *list, struct poll_wqueues *wait, s64 *timeout)
{
……
for (;;)
{
……
set_current_state(TASK_INTERRUPTIBLE); //Set to wait queue state
......
for (; pfd != pfd_end; pfd++) { //forRun multiple loopspoll机制
/*将pfd和ptThe parameters are substituted into those registered in our driverpoll函数*/
if (do_pollfd(pfd, pt)) //若返回非0,count++,back and exit
{ count++;
pt = NULL; } }
……
/*count非0(.poll函数返回非0),timeoutTimeout counted up0,A signal is waiting*/
if (count || !*timeout || signal_pending(current))
break;
……
/*进入休眠状态,只有当timeoutTimeout counted up0,Or exit after being woken up by an interrupt,*/
__timeout = schedule_timeout(__timeout);
……
}
__set_current_state(TASK_RUNNING); //开始运行
return count;
}
1.4.1上面do_pollfdHow exactly does the function workpfd和ptparameters are substituted?代码如下(位于fs/select.c):
static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
{
……
if (file->f_op && file->f_op->poll)
mask = file->f_op->poll(file, pwait);
……
return mask;
}
- 上面file->f_op It's what we drivefile_oprations结构体,如下图所示:
- 所以do_pollfd(pfd, pt)Just execute our driver.poll(pfd, pt)函数(第2Section begins the analysis.poll函数)
1.4.2当poll进入休眠状态后,Who will wake it up?This is to analyze our driver.poll函数(第2Section begins the analysis.poll函数)
2.写驱动程序.poll函数,并分析.poll函数:
- Add the following code to the driver in the previous section:
#include <linux/poll.h> //添加头文件
/* .poll驱动函数: third_poll */
static unsigned int third_poll(struct file *fp, poll_table * wait) //fp:文件 wait:
{
unsigned int mask =0;
poll_wait(fp, &button_wait, wait);
if(even_press) //中断事件标志, 1:Exit hibernation 0:进入休眠状态
mask |= POLLIN | POLLRDNORM ;
return mask; //当超时,It is returned to the application layer as0 ,Return when awakenedPOLLIN | POLLRDNORM ;
}
static struct file_operations third_drv_fops={
.owner = THIS_MODULE,
.open = third_drv_open,
.read = third_drv_read,
.release=third_drv_class,
.poll = third_poll, //创建.poll函数
};
2.1 在我们1.4小节do_pollThe function has the following piece of code:
if (do_pollfd(pfd, pt)) //若返回非0,count++,back and exit
{
count++;
pt = NULL;
}
- 且在1.4.1分析出: do_pollfd(pfd, pt)It is pointing to the driverthird_poll()函数,
- So when we have keys pressed, 驱动函数third_poll()就会返回mask非0值,Then in the kernel functiondo_poll里的count就++,pollmechanism and exit sleep.
2.2Analysis is in the kernelpollHow the mechanism is woken up by an interrupt in the driver
- in the drive functionthird_poll()There is the following sentence:
poll_wait(fp, &button_wait, wait);
- 如上图所示,代入参数,poll_wait()就是执行了: p->qproc(filp, button_wait, p);
- It just corresponds to us1.3小节的:
table ->pt-> qproc=__pollwait;
- 所以poll_wait()函数就是调用了: __pollwait(filp, button_wait, p);
- Then we analyze__pollwait函数,pollwait的代码如下:
static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,poll_table *p)
{
... ...
//把currentThe process is mounted to&entry->wait下
init_waitqueue_entry(&entry->wait, current);
//再&entry->waitadd tobutton_wait中断下
add_wait_queue(wait_address, &entry->wait);
}
- 它是将pollprocess was added tobutton_waitin the interrupt queue,这样,When a button is pressed,It will wake up in the interrupt service functionbutton_wait中断,同样也会唤醒poll机制,使pollMechanism re-process sleep count
2.3 驱动程序.poll函数返回值介绍
When interrupting the sleep state,返回mask为0
Returns when run:mask |= POLLIN | POLLRDNORM
The meaning of the parameters is as follows:
- 所以POLLIN | POLLRDNORM:普通数据可读|优先级带数据可读
- maskback to the application layerpoll函数,
3.Improve testing proceduresthird_poll_text.c(添加poll函数)
- 在linux中可以通过man poll 来查看poll函数如何使用
- poll函数原型如下(#include <poll.h>):
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
参数介绍:
1) *fds:是一个pollAn array of descriptor structures(可以处理多个poll),结构体pollfd如下:
struct pollfd {
int fd; /* file descriptor 文件描述符*/
short events; /* requested events 请求的事件*/
short revents; /* returned events 返回的事件(函数返回值)*/
};
- 其中events和reventsThe value parameters are as follows:
2) nfds:表示多少个poll,如果1个,就填入1
3) timeout:定时多少ms
返回值介绍:
- 返回值为0:Indicates timeout orfdThe file descriptor could not be opened
- 返回值为 -1:表示错误
- 返回值为>0时 :are the following constants
- The final improved test code is as follows:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <poll.h> //添加poll头文件
/*useg: thirdtext */
int main(int argc,char **argv)
{
int fd,ret;
unsigned int val=0;
struct pollfd fds; //定义poll文件描述结构体
fd=open("/dev/buttons",O_RDWR);
if(fd<0)
{printf("can't open!!!\n");
return -1;}
fds.fd=fd;
fds.events= POLLIN; //请求类型是 普通或优先级带数据可读
while(1)
{
ret=poll(&fds,1,5000) ; //一个poll, 定时5000ms,进入休眠状态
if(ret==0) //超时
{
printf("time out \r\n");
}
else if(ret>0) //pollThe mechanism is awakened,表示有数据可读
{
read(fd,&val,1); //读取一个值
printf("key_val=0X%x\r\n",val);
}
}
return 0;
}
效果如下:
边栏推荐
- runtime-core.esm-bundler.js?d2dd:218 Uncaught TypeError: formRef.value?.validate is not a function
- Some tips for using Unsafe
- 学长告诉我,大厂MySQL都是通过SSH连接的
- C#实战:基于ItextSharp技术标签生成小工具
- 什么是幂等性?四种接口幂等性方案详解!
- mysql5.7 installation and deployment - yum installation
- 做自媒体月入几万?博主们都在用的几个自媒体工具
- Memory problems difficult to locate, it is because you do not use ASAN
- runtime-core.esm-bundler.js?d2dd:218 Uncaught TypeError: formRef.value?.validate is not a function
- 快速上手,征服三种不同分布式架构调用方案
猜你喜欢
【勇敢饭饭,不怕刷题之链表】链表倒数节点问题
OneFlow源码解析:算子指令在虚拟机中的执行
Some tips for using Unsafe
快手“弃”有赞与微盟“结亲”,电商SaaS行业竞争格局将变?
金九银十跳槽旺季:阿里、百度、京东、美团等技术面试题及答案
STM32 encapsulation ESP8266 a key configuration function: implementations of AP mode and the STA mode switch, server and the client to create
mysql5.7安装部署-yum安装
3 injured in 'electrical accident' at Google data center
3款不同类型的自媒体免费工具,有效提高创作、运营效率
The brave rice rice, does not fear the brush list of 】 list has a ring
随机推荐
3 injured in 'electrical accident' at Google data center
AUTOCAD - reducing spline curve control points, the advanced CAD practice (3)
「业务架构」介绍BPMN第二部分-泳道
实现内网穿透的最佳解决方案(无实名认证,完全免费)
电脑怎么设置屏幕息屏时间(日常使用分享)
Redis设计与实现
POJ 3101 Astronomy (数学)
第5章相似矩阵及二次型(4)
金九银十跳槽旺季:阿里、百度、京东、美团等技术面试题及答案
Codeforces 814 C. An impassioned circulation of affection (dp)
第二十二章 源代码文件 REST API 参考(四)
POJ 3101 Astronomy (Mathematics)
【电商运营】你真的了解社交媒体营销(SMM)吗?
不止跑路,拯救误操作rm -rf /*的小伙儿
SQL与NoSQL最终会走向融合吗?
runtime-core.esm-bundler.js?d2dd:218 Uncaught TypeError: formRef.value?.validate is not a function
OneFlow source code parsing: operator instructions executed in a virtual machine
蔚来-软件开发工程师一面记录
零基础想自学软件测试,有没有大佬可以分享下接下来的学习书籍和路线?
SQL优化最强总结 (建议收藏~)