深圳有名的做公司网站,关键词优化公司,wordpress 前台表单,wordpress php7 兼容异步通知的全称是信号驱动的异步IO#xff0c;通过信号的方式#xff0c;放期望获取的资源可用时#xff0c;驱动会主动通知指定的应用程序#xff0c;和应用层的信号相对应#xff0c;这里使用的是信号SIGIO。操作步骤是…异步通知的全称是信号驱动的异步IO通过信号的方式放期望获取的资源可用时驱动会主动通知指定的应用程序和应用层的信号相对应这里使用的是信号SIGIO。操作步骤是 应用层程序将自己注册为接收来自设备文件的SIGIO信号的进程驱动实现相应的接口以期具有向所有注册接收这个设备驱动SIGIO信号的应用程序发SIGIO信号的能力。驱动在适当的位置调用发送函数应用程序即可接收到SIGIO信号。整个机制的框架 应用层接收SIGIO 和其他信号一样应用层需要注册一个信号处理函数 注册的方式还是使用signal()或sigaction() 此外应用层还需要把自己加入到驱动的通知链表中加入的代码如下 fcntl(dev_fd,F_SETOWN,getpid());
int oflags fcntl(dev_fd,F_GETFL);
fcntl(dev_fdF_SETFLoflags|FASYNC);
...
while(1); 完成了上面的工作应用层的程序就可以静待SIGIO的到来了。 驱动发送SIGIO 应用层注册好了最终的发送还是看设备驱动的处理方式为了使设备支持异步通知机制参照应用层的接口驱动程序中涉及3项工作。 支持F_SETOWN命令能在这个命令中下设置filp-f_owner为对应进程的ID这部分内核已经做了支持F_SETFL,每当FASYNC标志改变时驱动程序中的fasync()将得以执行so驱动中要实现fasync()。当设备资源可用时通过kill_fasync()发送SIGIO为了在内核中实现上面这三个功能驱动需要使用1个结构2个API结构是struct fasync_struct,函数是fasync_helper()和kill_fasync() struct fasync_struct { spinlock_t fa_lock;int magic;int fa_fd;struct fasync_struct *fa_next; /* singly linked list */struct file *fa_file;struct rcu_head fa_rcu;
}; fasync_helper()的作用是将一个fasync_struct的对象注册进内核应用层执行fcntl(dev_fdF_SETFLoflags|FASYNC)时会回调驱动的fops.fasync()所以通常将fasync_helper()放到fasync()的实现中。 /***fasync_helper - 将一个fasync_struct对象注册进内核*fd:文件描述符由fasync传入*filp:file指针由fasync传入*sig:信号类型通常使用的就是SIGIO*dev_fasync:事前准备的fasync_struct对象指针的指针*/
int fasync_helper(int fd, struct file * filp, int sig, struct fasync_struct ** dev_fasync); 下面这个API就是释放SIGIO根据需求的不同放到不同的位置。 /***kill_fasync - 释放一个信号*dev_fasync:事前使用fasync_helper注册进内核的fasync_struct对象指针的指针*filp:file指针由fasync传入*sig:信号类型通常使用的就是SIGIO*flag:标志通常如果资源可读用POLLIN如果资源可写用POLLOUT*/
void kill_fasync(struct fasync_struct **dev_fasync, int sig, int flag); 驱动模板 下面这个驱动模板针对在硬件中断到来(资源可用)的时候向应用层发信号实际的操作中表明资源可用的情境还有很多 static struct fasync_struct *fasync NULL;static irqreturn_t handler(int irq, void *dev)
{kill_fasync(fasync, SIGIO, POLLIN);return IRQ_HANDLED;
}
static int demo_fasync(int fd, struct file *filp, int mode)
{return fasync_helper(fd, filp, mode, fasync);
}
struct file_operations fops {....fasync demo_fasync,...
}
static int __init demo_init(void)
{...request_irq(irq, handler, IRQF_TRIGGER_RISING, demo, NULL);...
} 转载于:https://www.cnblogs.com/xiaojiang1025/p/6376561.html