zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    小总结下iphone开发环境搭建过程!
    Raspberry Pi之旅 【序】
    linux虚拟机中配置samba的实现文件共享的方法
    编写高质量的代码1尽量使用StringBuilder
    ArcEngine开发点滴1
    开源Firebird .NET Provider V0.9.0.0发布
    .NET的Ant构建系统 NAnt 0.91发布!
    iis7.5 发布rest服务,put请求返回404错误 解决方法
    COM学习笔记(1)
    2004年南京美食地图 [转载]
  • 原文地址:https://www.cnblogs.com/klcf0220/p/3192504.html
Copyright © 2011-2022 走看看