设备驱动分层结构示意图:
字符设备驱动程序示意图:
分配和释放设备编号
必须先在<linux/fs.h>中声明:
1、 int register_chrdev_region(dev_t first, unsigned int count, char *name);
这里, first 是你要分配的起始设备编号. first 的次编号部分常常是 0, 但是没有要求是那个效果.
count 是你请求的连续设备编号的总数.最后, name 是应当连接到这个编号范围的设备的名字; 它会出现在 /proc/devices 和 sysfs 中.
如同大部分内核函数, 如果分配成功进行, register_chrdev_region 的返回值是 0. 出错的情况下, 返回一个负的错误码, 你不能存取请求的区域.
2、 int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
使用这个函数, dev 是一个只输出的参数, 它在函数成功完成时持有你的分配范围的第一个数。
fisetminor 应当是请求的第一个要用的次编号; 它常常是 0。count 和 name 参数如同给 request_chrdev_region 的一样.
3、 void unregister_chrdev_region(dev_t first, unsigned int count);
调用 unregister_chrdev_region 的地方常常是你的模块的 cleanup 函数.
一些重要的数据结构
file_operations 结构:
struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
.ioctl = scull_ioctl,
.open = scull_open,
.release = scull_release,
};
file 结构
struct file, 定义于 <linux/fs.h>, 是设备驱动中第二个最重要的数据结构.注意,file 与用户空间程序的 FILE 指针没有任何关系.
一个 FILE 定义在 C库中, 从不出现在内核代码中. 一个 struct file, 另一方面, 是一个内核结构, 从不出现在用户程序中.
在内核源码中, struct file 的指针常常称为 file 或者 filp("file pointer"). 我们将一直称这个指针为 filp 以避免和结构自身混淆。因此,file 指的是结构, 而 filp 是结构指针。
inode 结构
字符设备驱动的读写:
open 方法
int (*open)(struct inode *inode, struct file *filp);
宏container_of(pointer, container_type, container_field);
scull_open 的代码(稍微简化过)是:
int scull_open(struct inode *inode, struct file *filp)
{
struct scull_dev *dev; /* device information */
dev = container_of(inode->i_cdev, struct scull_dev, cdev);
filp->private_data = dev; /* for other methods */
/* now trim to 0 the length of the device if open was write-only */
if ( (filp->f_flags & O_ACCMODE) == O_WRONLY)
{
scull_trim(dev); /* ignore errors */
}
return 0; /* success */
}
release 方法
int scull_release(struct inode *inode, struct file *filp)
{
return 0;
}
读和写(read and write)
ssize_t read(struct file *filp, char __user *buff, size_t count, loff_t *offp);
ssize_t write(struct file *filp, const char __user *buff, size_t count, loff_t *offp);
unsigned long copy_to_user(void __user *to,const void *from,unsigned long count);
unsigned long copy_from_user(void *to,const void __user *from,unsigned long count);
详细文档及代码下载链接:http://download.csdn.net/detail/klcf0220/5760569