linux驱动开发之字符设备框架 - file_operations

前言

在上一节中介绍了字符设备的重要结构体 cdev,以及和 cdev 相关的一些操作函数,比如cdev_alloc()、 cdev_init() 等,但是和 cdev_init() 密切相关的一个参数 fops,并没有介绍。这节重点分析 file_operations 结构体。

正文

file_operations 结构体的成员函数是字符设备驱动程序设计的主体内容,这些内容实际上,是会通过Linux的系统调用,比如 open() 、write()等调用到的。

// (include\linux\Fs.h) 
/*
 * NOTE:
 * all file operations except setlease can be called without
 * the big kernel lock held in all filesystems.
 */
struct file_operations {
    //拥有该结构的模块的指针,一般设置为THIS_MODULE
    struct module *owner;
    //用来修改当前文件的读写位置
    loff_t (*llseek) (struct file *, loff_t, int);
    //从设备中同步读数据
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 
    //向设备发送数据
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    //异步的读取操作
    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    //异步的写操作
    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    //仅用于读取目录,对设备文件一般为NULL
    int (*readdir) (struct file *, void *, filldir_t);
    //轮询函数,判断当前是否可以进行非堵塞的读取和写入
    unsigned int (*poll) (struct file *, struct poll_table_struct *);
    //执行设备I/O控制命令
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
    //用于请求将设备内存映射到进程地址空间
    int (*mmap) (struct file *, struct vm_area_struct *);
    //打开
    int (*open) (struct inode *, struct file *);
    int (*flush) (struct file *, fl_owner_t id);
    //关闭
    int (*release) (struct inode *, struct file *);
    //刷新待处理缓冲区
    int (*fsync) (struct file *, int datasync);
    //异步sync
    int (*aio_fsync) (struct kiocb *, int datasync);
    //通知设备FASYNC标识发生变化
    int (*fasync) (int, struct file *, int);
    int (*lock) (struct file *, int, struct file_lock *);
    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    int (*check_flags)(int);
    int (*flock) (struct file *, int, struct file_lock *);
    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long, struct file_lock **);
    long (*fallocate)(struct file *file, int mode, loff_t offset,
              loff_t len);
};

总结一下在字符设备中,涉及较多的file_operations的成员函数

  1. open() 函数用于打开字符设备
  2. release() 函数用于关闭字符设备
  3. read() 函数用来从设备中读取数据,成功时函数返回读取的字节数,出错时返回一个负数
  4. write() 函数是向设备发送数据,成功时返回写入的字节数,
  5. unlocked_ioctl() 函数提供设备相关的控制命令
  6. mmap() 函数是设备内存映射到进程内存中
  7. poll()函数一般用户询问设备是否可被非堵塞到立刻读写

总结

在用户空间执行系统调用的时候,比如 open(),会调用到对应设备的file_operations的成员函数。 这样用户空间的操作,对可以由对应的字符设备的file_opeations的成员函数来实现。

参数文献

Linux 设备驱动开发详解 (宋宝华) 第二版

你可能感兴趣的:(linux驱动,Linux驱动开发)