file_operation结构
由于用户程序是通过设备文件与硬件打交道,对设备文件的操作方式不外乎就是一些系统调用,如open()、read()、write()、close()等,但是如何把系统调用和驱动程序关联起来呢?这需要了解一个非常关键的数据结构:file_operation。改结构定义了文件操作接口,结构中除了owner外,每一个成员都对应着一个系统调用。具体如下:
include/linux/fs.h
817 struct file_operations{
818 struct module *owner;
819 loff_t(*llseek)(structfile *,loff_t, int );
820 ssize_t(*read)(struct file *,char*,size_t,loff_t *);
821 ssize_t(*write)(struct file *,const char*,size_t,loff_t *);
822 int(* readdir)(struct file*,void *,filedir_t);
823 unsigned int (*poll)(struct file *,structpoll_table_struct *);
824 int(* ioctl)(struct inode *,struct file*,unsigned int,unsigned long);
825 int(* mmap)(struct file *,structvm_area_struct *);
826 int(* open)(struct inode *,strcut file *);
827 int(*flush)(struct file *);
828 int(* release)(struct inode *,stuct file *);
829 int(*fsync)(srtuct file*,struct denty *, int datasync);
830 int(*fasync) (int,srtuct file*,int);
831 int(* lock)(struct file *,int,struct file_lock*);
832 ssize_t(* readv)(struct file*,const struct iovec *,unsigned long,loff_t *);
833 ssize_t(*writev)(struct file *,conststruct iovec *,unsigned long,loff_t *);
834 ssize_t(*sendpage)(struct file *,struct page *,int,size_t,loff_t*,int);
835 unsigned long(* get_unmapped_area)(structfile *,unsigned long,
unsigned long,unsigned long,unsigned long);
};
第818行的owner是一个指向拥有这个结构的模块的指针,用来表明驱动的所有者。它用来操作还在被使用时阻止模块被卸载,一般情况下初始化为THIS_MODULE。
第819~813行定义了驱动程序设备方法的接口。应用程序通过这些接口来使用具体设备驱动程序的设备方法。
在一个特定的驱动程序中,除open()和release()方法外,其他方法不是必须实现的。下面简要介绍在嵌入式硬件设备中常用成员函数的功能。
read()方法
该方法用于从设备中读取数据,非负的返回值代表成功读取的字节数。
write()方法
该方法用于写多个字节数据到设备中,非负的返回值代表写入的字节数。
ioctl()方法
该方法用于实现不容易通过read()方法和write()方法实现的设备操作。对于一个具体的设备来说,它可能有某些独特的操作,这些操作不容易通过read()方法和write()方法实现。对于这些独特的操作都是通过ioctl()方法实现。
open()方法
该方法用于应用程序使用文件前打开文件,提供给驱动程序以初始化的能力,为以后的操作准备。主要的操作有:(1)增加驱动程序使用计数器,以避免不正确的卸载驱动程序;(2)在第一次使用驱动程序支持的设备时对设备进行初始化;(3)如有必要则更新f_op指针;(4)分配并填写置于filp->private_data里的数据结构。
release()方法
该方法用于不再使用文件时的释放内存、关闭设备等。主要的操作有:(1)减少驱动程序使用计数器;(2)在驱动程序支持的设备使用完毕时对设备进行关闭操作;(3)释放由open()分配的、保存在file->private_data里的所有内容。