• 嵌入式Linux驱动学习之路(二十一)字符设备驱动程序总结和块设备驱动程序的引入


    字符设备驱动程序

    应用程序是调用C库中的open read write等函数。而为了操作硬件,所以引入了驱动模块。

    构建一个简单的驱动,有一下步骤。

      1. 创建file_operations

      2. 申请设备号

      3. 注册字符设备驱动,

      4. 驱动入口

      5. 驱动出口

    检查数据是否到来的方式:

      1. 查询方式

      2. 休眠唤醒方式

         如果设备出现异常而无法唤醒时,则将永远处于休眠状态。

      3. poll机制

         如果没有被唤醒,则在一定时间内可自己唤醒。

      4. 异步通知(信号) 

    而以上的几种方式通用性不高,为了增强通用性,使用输入子系统。

    块设备驱动程序

      在读取硬盘的时候,磁头需要定位,但是定位是非常损耗时间的。

      flash的操作也是一样的。在写之前需要擦除整块。

      如果我们现在进行一下操作:1.写扇区0  2.写扇区1 

      1. 写扇区0:

        读出整块到buffer

        修改buffer中相应的内容,

        擦除整块

        写入整块

      2.读扇区1则是重复上述步骤。

     而上述的方法在操作的时候太过于繁杂,浪费时间。所以操作系统在处理的时候优化了一次。

      1. 把读写放入队列

      2.调用队列的处理函数(优化/调顺序/合并)

    块设备驱动程序框架:

    ---------------------------------------------------------(文件的读写)

      app:  open、write、read等          (把对文件的读写转化为对扇区的读写)

    ----------------------------------------------------------

      文件系统: vfat、ext2、ext3、yaffs2、jffs2 

    ------------------ ll_rw_block --------------------------

      块设备驱动程序

    ---------------------------------------------------------- 

       硬件:  硬盘、Flash

    ---------------------------------------------------------- 

    分析 ll_rw_block :(1. 把“读写”放入队列     2. 调用队列的处理函数( 优化 / 调顺序 / 合并 ))

      for (i = 0; i < nr; i++) {

        struct buffer_head *bh = bhs[i];

        submit_bh(WRITE, bh);

          struct bio *bio;    //使用bh来构造bio (block input/output)

          submit_bio(rw, bio);  //通用的构造请求:使用bio来构造请求(request)

            generic_make_request(bio);  

              __generic_make_request(bio);

                request_queue_t *q = bdev_get_queue(bio->bi_bdev);  //找到队列

                ret = q->make_request_fn(q, bio);  //默认函数是__make_request

                  __make_request

                    elv_merge(q, &req, bio);    //尝试合并

                    init_request_from_bio(req, bio);    //如果尝试合并不成功 使用bio构造请求

                    add_request(q, req);        //把请求放入队列

                    __generic_unplug_device(q);  //执行队列

                      q->request_fn(q);    //调用队列的处理函数

      }

    如何编写块设备驱动程序呢?

    1. 分配gendisk

    2. 设置

    2.1分配/设置队列: request_queue_t   //提供读写能力

      blk_init_queue

    2. 2 设置gendisk其他信息        //提供属性:容量,扇区大小等

    3. 注册: add_disk

  • 相关阅读:
    数据结构8.4_动态存储管理之伙伴系统
    http code码实验
    php问题
    对称加密和非对称加密
    公钥与私钥,HTTPS详解
    数字证书原理,公钥私钥加密原理
    简明 Nginx Location Url 配置笔记
    HTTP状态码精简版
    给你掰扯清楚什么是正向代理,什么是反向代理
    关键字
  • 原文地址:https://www.cnblogs.com/ynxf/p/6033445.html
Copyright © 2020-2023  润新知