Linux字符设备驱动

设备驱动分层结构示意图:

wps_clip_image-28530

字符设备驱动程序示意图:

wps_clip_image-5947

分配和释放设备编号
必须先在<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

实例代码:http://download.csdn.net/detail/klcf0220/5863303

原文地址:https://www.cnblogs.com/klcf0220/p/3192504.html