zoukankan      html  css  js  c++  java
  • linux device driver3 读书笔记(一)

    一:机制与策略(转)

      http://www.51hei.com/bbs/dpj-29441-1.html

      机制mechanism,策略policy。如果你看过《linux device drivers》,里面给出了大概的介绍。机制提供了干什么(do what),策略提供如何做(how to do)。驱动程序完成机制的功能,把策略的实现留给用户的应用程序。

     
           通常在机制中,驱动程序要完成打开,关闭,读写,控制等功能。这些都是设备使用时最基本的操作。而策略中就要实现一些高级的数据处理或界面功能。通过例子来说明会更好些。
     
           以RTC(实时时钟设备)为例。假设RTC共有8个REG,分别是2个控制寄存器、年寄存器、月寄存器、日寄存器、时寄存器、分寄存器、秒寄存器。RTC的启动和关闭分别通过设定控制寄存器的某一个位来完成。
     
           1.    驱动程序提供open,release,write,read函数。Open和release不多说了,具体介绍一下read和write的功能。Read中通过IO端口操作可以读入这8个寄存器的值,Write中通过IO端口操作可以写入这8个寄存器的值。仅仅这样驱动程序已经为应用程序提供了所有完成对RTC设备访问的接口。这样或许对应用程序操作RTC不是很方便,因此在发布驱动程序的时候,我们提供了针对RTC的用户函数库。比如setDate,setTime等,这些函数无非就是把驱动程序中的read和write组合调用了一下。但是采用这种策略,用户写应用程序时就会更方便,对底层的细节就不必知道的太多。
     
           2.    另一个可以选择的机制就是驱动程序中引入ioctl函数,驱动程序把setDate,setTime操作的功能在ioctl函数中实现。Ioctl通过IO端口操作访问8个寄存器就可以完成。将来驱动程序发布时,不用提供用户函数库。只要告诉开发人员IOCTL函数的操作码即可,使用不同的ioctl调用就可以完成setDate,setTime功能。
     
          通过上面两种情况可以看出,机制不同提供的策略选择不同,机制可以把策略中的一些功能集成。但是如何选择正确的机制和策略组合呢?
     
          针对上面2中机制提供,分析各自优缺点:
          第一种方案中,由于没有提供Ioctl函数,驱动程序必然会占用内存小。而且对于RTC设备,我们不会经常去setDate,setTime,因此这种小概率使用的函数放到用户库中实现更好。
          第二中方案,不用提供用户函数库,发布方便。但是ioctl函数会常驻内存中,尽管他可能一直得不到调用!这中方式更符合面向对象的编程思想。

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

    二:用户空间和内核空间

    一个模块在内核空间运行, 而应用程序在用户空间运行. 这个概念是操作系统理论的基础,

    驱动模块试涉及到内核态以及用户态,当应用程序发出一个systerm call或者被硬件的中断挂起,内核在上下文中执行systerm call(系统调用),内核和应用程序的memory map也不同,所以

    内核的内存空间以及应用程序的内存空间不能互相访问,要用到copy_to_user 以及copy_from_user函数;

    内核程序与应用程序最大的不同是内核是并发的,而应用程序是按顺序执行的;所以应用程序不用担心上线文切换,而内核必须要做好上下文切换;

    2.6内核以后,内核是抢占式的,这必须要求内核代码是可重入的

    内核的栈是非常小的,内核共用4k的栈,所以当需要大的结构体时,是使用堆内存;kzalloc

    驱动模块的代码中的函数以及数据结构跟内核的版本紧密相连,所以编译模块的时候要选用正确的内核版本,安装模块的时候也要选择正确的内核版本;

    如果

    2.6 预备知识

    #include <linux/module.h>      包含大量的模块加载卸载的头文件 如module_init 、module_exit等函数
    #include <linux/init.h>        指定清理的初始化函数,init的初始化函数

    MODULE_LICENSE("GPL");      内核认识的特定许可有, "GPL"( 适用 GNU 通用公共许可的任何版本 ),

    MODULE_AUTHOR ( 声明谁编写了模块 ),

    MODULE_DESCRIPION( 一个人可读的关于模块做什么的声明 ),

    MODULE_VERSION ( 一个代码修订版本号

    MODULE_ALIAS ( 模块为人所知的另一个名子 )

    以及 MODULE_DEVICE_TABLE ( 来告知用户空间, 模块支持那些设备 ).

    2.7 初始化中的错误处理

    这点很重要,比如你在insmodu 一个模块的时候加载失败,如果这个驱动模块的代码没有进行相关错误处理,在加载会出现更多问题

    错误恢复是最好使用goto语句;

     1 int __init my_init_function(void)
     2 {
     3 int err;
     4 err = register_this(ptr1, "skull"); /* registration takes a pointer and a name */
     5 if (err)
     6 goto fail_this;
     7 err = register_that(ptr2, "skull");
     8 if (err)
     9 goto fail_that;
    10 err = register_those(ptr3, "skull");
    11 if (err)
    12 goto fail_those;
    13 return 0; /* success */
    14 fail_those:
    15 unregister_that(ptr2, "skull");
    16 fail_that:
    17 unregister_this(ptr1, "skull");
    18 fail_this:
    19 return err; /* propagate the error */
    20 }

    或者在失败的时候直接执行你的清理函数即可,但是这样需要更多的上下文切换,消耗更过的内存空间,寄存器等;或者可以下下面一个函数;

    检查每种操作的状态,在清理,但是这样做的坏处是需要定义很多歌变量,还是用goto比较好;

     1 struct something *item1;
     2 struct somethingelse *item2;
     3 int stuff_ok;
     4 void my_cleanup(void)
     5 {
     6 if (item1)
     7 release_thing(item1);
     8 if (item2)
     9 release_thing2(item2);
    10 if (stuff_ok)
    11 unregister_stuff();
    12 return;
    13 }
     1 int __init my_init(void)
     2 {
     3 int err = -ENOMEM;
     4 item1 = allocate_thing(arguments);
     5 item2 = allocate_thing2(arguments2);
     6 if (!item2 || !item2)
     7 goto fail;
     8 err = register_stuff(item1, item2);
     9 if (!err)
    10 stuff_ok = 1;
    11 else
    12 goto fail;
    13 return 0; /* success */
    14 fail:
    15 my_cleanup();
    16 return err;
    17 }
  • 相关阅读:
    网站是HTTP?10分钟变成HTTPS!域名免费添加配置SSL证书,变成https//环境
    纯JS实现在一个字符串b中查找另一个字符串a出现的所有位置,并且不使用字符串的方法(递归)
    网站怎么上传到服务器流程,从本地到服务器上线过程并通过域名(IP地址)进行访问
    html5新特性-header,nav,footer,aside,article,section等各元素的详解
    Django2.2中间件详解
    掌握使用gitlab ci构建Android包的正确方式
    回想让你最有成就感的bug是什么?你是如何发现这个bug的?
    聊聊用Selenium做自动化碰到了哪些坑?都是怎么解决的?
    关于手机淘宝3.25bug我的一些思考与建议
    用docker搭建selenium grid分布式环境实践之路
  • 原文地址:https://www.cnblogs.com/biaohc/p/6682036.html
Copyright © 2011-2022 走看看