LDD3 D03 补

  • 15:02-16:47 90m 18p

     

    3 字符驱动

    模块化的字符驱动

    什么是模块化?

     

    scull的设计

    编写驱动的第一步是定义驱动将要提供给用户程序的能力(机制)。

    全局意味着如果设备被多次打开,设备中含有的数据由所有打开他的文件描述符共享。

    永久意味着如果设备关闭又重新打开,数据不会丢失。

     

    主次编号

    支付设备通过文件系统的名字来存取。这些名字被称为文件系统的特殊文件,或设备文件。

     

    传统上,主编号标识设备相连的驱动。

    次编号被内核用来决定引用那个设备。

     

    分配和释放设备编号

    在建立一个字符驱动时需要做的第一件事是:获取一个或多个设备编号来使用。

    【可以指定 主编号,也可以动态让内核给你分配】

     

    不管你如何分配你的设备编号,你应当在不再使用它时释放它。

    【这通常是在模块的cleanup 函数】

     

    【为了避免冲突,应该使用动态分配来获取你的主设备编号】

    动态分配的缺点是你无法提前创建设备节点

    什么是设备节点?

     

    作为scull源码的一部分,我们提过了一个相当完整和可配置的init脚本例子,称为scull.init。它接收传统的参数--start,stop和restart以完成 scull_load 和 scull_unload 的角色。

    【init 脚本规范 】

     

    安排住编号最好的方式,是缺省使用动态分配,而留给自己在加载时指定主编号的选择权。

    【一个全局变量初始化为0,表示动态分配。 可以选择主编号,或者在编译前修改宏定义或者在insmod 或是用脚本load时指定一个编号。】

     

    一些重要数据结构

    文件操作

     

    scull设备驱动只实现最重要的设备方法. 它的 file_operations 结构是如下初始化的:

    structfile_operations scull_fops = {

    .owner =THIS_MODULE,

    .llseek =scull_llseek,

    .read =scull_read,

    .write =scull_write,

    .ioctl =scull_ioctl,

    .open =scull_open,

    .release =scull_release,

    };

    这个声明使用标准的C标记式结构初始化语法。这种方式是首选的,因为它是驱动在结构定义的改变之间更加可移植,并且有争议地,使代码更加紧凑可读。

     

    文件结构

    struct file 和 定义在 C 库的 FILE 没有任何关系。

    文件结构代表一个打开的文件。它由内核在open时创建,并传递给在文件上操作的任何函数,直到最后的关闭。在文件的所有实例都关闭后,内核释放这个数据结构。

     

    inode 结构

    作为一个更可移植的编程方法,应使用宏来从inode 获取主次编号

     

    字符设备注册

    内核在内部使用类型 scructcdev 结构来代表字符设备。

    有两种方法来分配并注册一个或几个这样的结构。

    分配一个独立的 cdev 结构用 cdev_alloc()

     

    如果 cdev 结构嵌入到你设备的某个结构,则用 cdev_init()函数来初始化。

     

    一旦 cdev 结构建立,最后的步骤是把他告诉内核,调用 cdev_add()

    注意两点:

    • cdev_add 可能失败
    • 一旦成功,则内核可以调用它的操作。所以在你的驱动完全准备好之前,不要调用它。

     

    open 和 release

    open 方法

    open应当进行下面的操作

    • 检查设备特定的错误(例如设备没准备好, 或者类似的硬件错误
    • 如果它第一次打开, 初始化设备
    •  如果需要, 更新 f_op 指针.
    •  分配并填充要放进 filp->private_data 的任何数据结构

     

    【应当使用 宏 container_of  来获得 指针,类型的转换】

     

    release 方法

    release 应该执行下面的任务:

    • 释放open 分配在filp->private_data 中的任何东西
    • 在最后的 close 关闭设备

     

    不是每次close 系统调用都会引起调用release方法。只有真正释放设备数据结构的调用会执行该方法。

    内核维持一个文件结构被使用多少次的计数器。fork和dup都不增加它,只有open增加它。每次close,计数器减少,直到为0 时执行release。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值