Linux设备驱动开发详解 笔记9 异步通知与异步I/O
异步通知:一旦设备就绪,则主动通知应用程序,这样应用程序根本不需要查询设备状态,这一点非常类似于硬件上的“中断”的概念,比较准确的称谓是“信号驱动的异步I/O
//启动信号驱动机制
signal(SIGIO, input_handler);//让input_handler()处理SIGIO信号
fcntl(fd, F_SETOWN, getpid());//设置本进程为STDIN_FILENO文件的拥有者,让内核知道将信号发给本进程
oflags = fcntl(fd, F_GETFL);//下面两句:设置FASYNC标志,启动异步通知标志
fcntl(fd, F_SETFL, oflags | FASYNC);
设备驱动中异步通知编程比较简单,主要用到一项数据结构和两个函数
数据结构:
struct xxx_dev
{
Struct cdev cdev;
……
Struct fasync_struct *async_queue;
}
Int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
Void kill_fasync(struct fasync_struct **fa, int sig, int band);
static int globalfifo_fasync(int fd, struct file *filp, int mode)
{
struct globalfifo_dev *dev = filp->private_data;
return fasync_helper(fd, filp, mode, &dev->async_queue);
}
static ssize_t globalfifo_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
struct globalfifo_dev *dev = filp->private_data; //获得设备结构体指针
……
if (dev->async_queue)
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
ret = count;
}
int globalfifo_release(struct inode *inode, struct file *filp)
{
globalfifo_fasync( - 1, filp, 0);
return 0;
}
AIO基本思想是允许进程发起很多I/O操作,而不用阻塞或等待任何操作完成
异步IO和标准IO之间的另一个区别是不能立即访问这个函数的返回状态,因为并没有阻塞在read()调用上。在标准的read()调用中,返回状态是在该函数返回时提供的,但是在异步IO中,我们要使用aio_return()函数,只有在aio_error()调
相关文档:
Author-------Dansen-----xzd2734@163.com
wait_queue_head_t wait_q;
首先看看
wait_queue_head_t这个等待队列的结构
在wait.h中定义了这个结构
typedef struct
__wait_queue_head wait_queue_head_t;
struct __wait_queue_head {
wq_lock_t
lock;
struct list_head task_list;
};
# define wq_ ......
在用户空间,使用ioctl系统调用来控制设备,原型如下:
int ioctl(int fd, unsigned long cmd, ...);
第三个参数不表示一个变数目的参数,而是一个类型可选的参数。第三个参数依赖于控制命令。一些命令不用参数,一些用一个整数值,一些使用指针
1、ioctl函数定义命令
在编写ioctl代码之前,首先需要定义命令。为了防止 ......
我的第一个shell程序:tt1.sh
while true
do
date;
sleep 1;
done
执行方式1:sh tt1.sh
执行方式2:./tt1.sh(要求该文件有可执行权限)
Shell变量:
环境变量:
工具:echo 回显
&n ......
使用下列洪可以通过主设备号和次设备号生成dev_t
MKDEV(int major, int mainor)
如果复制的内存是简单类型,如char、int、long等,则可以使用简单的put_user()和get_user()
Linux系统建议以如图方式定义ioctl命令码
命了码的设备类型字段为一个“幻数”,可以是0-0xff之间的值,内核中的ioctl-number ......