精华内容
下载资源
问答
  • 一次设备进行控制,保护作用的设备叫做二次设备,如继电器,控制开关,指示灯,测量仪表等。 另解: 一次设备通常包含以下五类: (1)、能量转换设备(如发电机、变压器、电动机等) (2)、开关设备(断路器...
    完成发电-输电-配电功能的设备叫做一次设备,如发电机,断路器,电流电压互感器,变压器,避雷器等;
    对一次设备进行控制,保护作用的设备叫做二次设备,如继电器,控制开关,指示灯,测量仪表等。
    另解:
    一次设备通常包含以下五类:
    (1)、能量转换设备(如发电机、变压器、电动机等)
    (2)、开关设备(断路器、熔断器、负荷开关、隔离开关等)
    (3)、载流导体(母线、绝缘子和电缆等)
    (4)、互感器(电压、电流等互感器)
    (5)、电抗器和避雷器(电抗器主要用于限制电路中的短路电流;避雷器则用于限制电气设备的过电压)
    二次设备:对电气一次设备的工作状态进行监测、控制和保护的辅助性电气设备称为二次设备。例如各种电气仪表、继电器、自动控制设备、信号电缆和控制电缆等。
    
    展开全文
  • 通过老大的提示,自己的努力,完成了第三章的学习,最后自己实现了个类似书本scull字符设备驱动模块。  什么叫字符设备,什么叫字符设备驱动。...、主设备号与次设备号 在自己的系统上输入: ls -l /d

    通过老大的提示,自己的努力,完成了第三章的学习,最后自己实现了一个类似书本scull字符设备驱动模块。

       什么叫字符设备,什么叫字符设备驱动。字符设备和字符设备驱动是两个不同的概念。字符设备就是以字节为单位进行顺序访问的一类设备的总称。典型的常用的字符设备有:键盘,串口,控制台等。字符设备驱动程序就是提供操作字符设备的机制。

    一、主设备号与次设备号

    在自己的系统上输入: ls -l /dev观察输出。我们会发现如下面所示的文件的详细信息。

    view plaincopy to clipboardprint?

    1.      crw-r--r--  1 root root        4,   0  6月 26 2010 systty  

    2.      crw-rw-rw-  1 root tty         5,   0  6月 26 2010 tty  

    3.      crw--w----  1 root root        4,   0  6月 26 2010 tty0  

    4.      crw--w----  1 root root        4,   1  6月 26 2010 tty1  

    5.      crw--w----  1 root tty         4,  10  6月 26 2010 tty10  

    6.      crw--w----  1 root tty         4,  11  6月 26 2010 tty11   

    这是我系统输出的一部分。我们对字符设备的访问是通过文件系统内的设备名称进行的。内核把设备当作特殊的文件或者说是设备文件来进行操作。它们通常位于/dev目录下。crw-rw-rw- 这一部分是文件权限等方面的说明。第一项的“c"标识它是一个字符设备文件,可能你会看到其他的文件是"b" "l"字样,它们代表不同的设备文件类型。文件拥有者和拥有组后面两个数字就是设备的主设备号和次设备号。例如4、5都是主设备号,0 、1 、10 、11等都是次设备号。

    主设备号用来标识设备对应的驱动程序;次设备号用于正确确定设备文件对应的设备。这个怎么理解呢?例如我们要操作某个设备,我们怎么做呢?首先,我们要知道设备在/dev下的设备文件名。这个设备文件提供主设备号以及次设备号。然后内核通过设备文件提供的主设备找到设备驱动程序(操作设备由驱动程序实现)。最后通过主设备号和次设备构成的设备号找到正确的设备。有了操作的对象(设备)和操作的方法(驱动程序)那就可以完成了我们的要求。一个驱动程序可以操作多个设备,所以不同的设备可以具有相同的主设备号。那为什么说次设备号用于正确确定设备文件呢?不是说通过主设备号和次设备号构成的设备号找到正确的设备吗?确实是这样,因为我们在添加设备到内核的时候我们是关联设备号的。因为不同的设备可以具有相同的主设备号,那不同的次设备号和相同的主设备号结合不就构成了不同的设备号了?不就标识了不同的设备?这么说可能会让人有更晕的感觉。不急,等到理解了设备的注册后再来理解这个应该比较容易。但确实只能是不同的设备才能标识不同的设备。假如一个设备的的主设备是4次设备是5,另一个设备主设备是5次设备是5,那不能说这两个是同一个设备吧。只能综合主设备和次设备才可以的嘛。接下来就是设备编号的介绍。

    二、设备编号的内部表达

           在上面主设备和次设备的介绍中我们提到设备编号,真正能标识不同的设备的是设备编号。每一个设备有一个唯一的设备编号。经常看电影我们看到,监狱里的犯人都不被呼姓名,而直接呼囚衣上的编号,我们现在说的设备也就是这个意思。

           在内核中,用dev_t类型来保存设备编号,我们可以猜测它其实是一个无符号整型。这个类型在<linux/types.h>中定义。

           设备号由主设备号和次设备号构成。如:广东省深圳市这个东东由省名和市名构成。内核提供三个宏来实现这三个东东的转换。分别是:MKDEV(int major, int minor)    MAJOR(dev_tdev)   MINOR(dev_t dev)。这三个宏名非常直观表明作用,不必多说。这三个宏在<linux/kde_t.h>中定义。

    三、分配和释放设备编号

         内核是通过设备编号找到设备的,理所当然地要建立一个字符设备那必须要获得字符设备编号。要建立多少个字符设备就要得到多少个字符设备编号。完成这一工作有两种方式,一种是静态获取,一种是动态获取。分别由:register_chrdev_region()  alloc_chrdev_region()这两个函数实现。成功调用申请设备编号的函数后,在系统的/proc/devices下就会包含设备以及设备主设备号的信息。函数在<linux/fs.h>中声明。字符设备不再使用时应该释放它们占用的编号。由unregister_chrdev_region()。这三个函数的原型如下:

    view plaincopy to clipboardprint?

    1.      int register_chrdev_region(dev_t first, unsigned int count,  

    2.      char *name);     

    3.      int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,  

    4.      unsigned int count, char *name);     

    5.      void unregister_chrdev_region(dev_t first, unsigned int count);        

    分配多个设备编号时,分配到的编号的主设备号都是一样的。所以有时也说成是分配主设备号,其实我我也想知道分配函数的源代码,可是我不知道它在哪里定义,也不知道怎么找。

    四、动态分配主设备号

          我自己也真想知道是分配了主设备号再得到设备号,还是分配设备才得到主设备号。反正传出参数dev_t类型,意思是说参数是设备编号。当然这不影响我们的学习,但是知道个所以然是最好的,好读书并求甚解是最好的。

           关于选择静态还是动态分配的讨论书本说的比较清楚,并且也很容易看懂,那就多看看书。一般我们采用动态的分配的方式。作者提供的相关源代码我认为非常经典了。我们在完成字符设备编号的申请完全可以只做些变量名的修改就可以使用了。

    view plaincopy to clipboardprint?

    1.      if (scull_major) {  

    2.          dev = MKDEV(scull_major, scull_minor);  

    3.          result = register_chrdev_region(dev, scull_nr_devs, "scull");  

    4.      } else {  

    5.          result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,"scull");  

    6.          scull_major = MAJOR(dev);  

    7.      }  

    8.      if (result < 0) {  

    9.          printk(KERN_WARNING "scull: can't get major %d\n", scull_major);  

    10.      return result;  

    11.  }  

     

    一旦分配了设备号就可以读取/proc/devices以获得主设备号。作者提供的源代码包含一个scull_load脚本主要实现三个功能:一、加载模块。二、获取主设备号(awk这个工具)。三、建立设备节点,也就是设备文件(mknod)。更多的技巧书本也讲得比较详细,比较容易懂。

    五、字符设备的注册

        分配好设备编号后就可以注册字符设备了。内核中由struct cdev结构表示字符设备。这个结构在<linux/cdev>中定义。

    view plaincopy to clipboardprint?

    1.      struct cdev {  

    2.              struct kobject kobj;  

    3.              struct module *owner;  

    4.              const struct file_operations *ops;  

    5.              struct list_head list;  

    6.              dev_t dev;  

    7.              unsigned int count;  

    8.      };  

        字符设备的注册分三步:一、定义字符设备结构。二、初始化。三、添加字符设备到内核中。下面我们一步步地理解。

         根据分配和初始化字符设备结构的不同,有两种不同的方式。

    方法一、

    1、动态获得字符设备结构并初始化

     

    view plaincopy to clipboardprint?

    1.      struct cdev *my_cdev = cdev_alloc();  

    2.      my_cdev->ops = *my_fops;  

    3.      my_cdev->ower = THIS_MODULE;  

    cdev_alloc()只是动态分配了一个struct cdev结构,所以我们必须自己初始化struct cdev成员。一般我们设备owner和ops(这个结构我们随后再讲)

    cdev_alloc()函数的代码可以在<fs/char_dev.c>中找到

    view plaincopy to clipboardprint?

    1.      struct cdev *cdev_alloc(void)  

    2.      {  

    3.              struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);  

    4.              if (p) {  

    5.                      INIT_LIST_HEAD(&p->list);  

    6.                      kobject_init(&p->kobj, &ktype_cdev_dynamic);  

    7.              }  

    8.              return p;  

    9.      }  

    2、把设备好的cdev结构添加到内核中去:

    view plaincopy to clipboardprint?

    1.      int cdev_add(struct cdev *dev, dev_t num; unsigned int count);  

    从这个添加函数的参数我们知道,字符设备结构和设备编号是关联的。这也是为什么我们在注册设备前必须要先获得设备编号。

    方法二、

    1、分配一个字符设备结构。

    很简单,struct cdev cdev;这个方法是书本采用的方法。但这里有一个不太容易理解的地方。书本把字符设备嵌入到了scull这个设备里。我在看书本的时候晕了好久,书本又说字符设备内核结构是struct cdev,但scull的结构又是struct scull_dev,这个要注意区分。嵌入到scull这个设备里后,在分配这种设备时,肯定也就分配了struct cdev.

    2、初始化字符设备结构

    view plaincopy to clipboardprint?

    1.      static void scull_setup_cdev(struct scull_dev *dev, int index)  

    2.      {  

    3.          int err, devno = MKDEV(scull_major, scull_minor + index);  

    4.            

    5.          cdev_init(&dev->cdev, &scull_fops);  

    6.          dev->cdev.owner = THIS_MODULE;  

    7.          dev->cdev.ops = &scull_fops;  //这句可以省略,在cdev_init中已经做过  

    8.          err = cdev_add (&dev->cdev, devno, 1);  

    9.          /* Fail gracefully if need be */  

    10.      if (err)  

    11.          printk(KERN_NOTICE "Error %d adding scull%d", err, index);  

    12.  }  

    初始化设备用到了一个函数:cdev_init()看了原型就知道为什么那句可以省掉了。

    原型:

    view plaincopy to clipboardprint?

    1.      void cdev_init(struct cdev *cdev, const struct file_operations *fops)  

    2.      {  

    3.              memset(cdev, 0, sizeof *cdev);  

    4.              INIT_LIST_HEAD(&cdev->list);  

    5.              kobject_init(&cdev->kobj, &ktype_cdev_default);  

    6.              cdev->ops = fops;  

    7.      }  

    3、添加设备结构到内核中去,和上面的方法一样。

    两种方式完成的工作是一模一样的,只不过是用到的函数不一样。

    到目前为止我们已经完成了字符设备的创建,并把它添加到内核里了。不过工作才刚刚开始。

    六、file_operations结构

          到目前为止我们已经完成了设备的创建工作。接下来我们就要定义操作设备的机制。关于机制和策略的讨论已经超出我现在的水平了。设备驱动程序提供我们操作设备的能力。对设备能做什么操作是由我们编写的驱动程序决定的。内核提供一个结构把这些操作和设备关联起来。这个结构就是file_operations。这个结构在<linux/fs.h>中定义。file_operations就是把对设备能做的操作与设备关联起来。浏览这个结构的内容的时候你会发现,它的成员包含一系列的函数指针,这些函数的函数名和linux的系统调用是一样的。对,它们是一一对应关系。比如我们调用系统调用:read("/dev/scull",buf,5)这个系统调用最终就会调用scull这个设备的file_operations里的read成员。当然在这你在知道什么叫系统调用。非常有必要快速浏览一个file_operations这个结构的内容。

          那这个结构怎么用呢?我们不是说这个结构把设备操作能力与设备关联起来吗?那我们猜想它肯定是在设备创建的时候与设备关联的。事实也是我们猜想的这样。再返回设备注册的时候所做的操作。还记得吗,有两种设备注册方式。一是用cdev_alloc(),然后我们再初始化这字符设备结构中的一个重要的成员:my_cdev->ops=fops。注意查看一下structcdev这个结构的成员,它有这样一个成员,struct file_operations *ops,fops通过就是一个指向file_operations结构的指针。这样设备就与file_operations结构关联了。书本提供的源代码是这样实现的:

    view plaincopy to clipboardprint?

    1.      struct file_operations scull_fops{  

    2.              .owner = THIS_MODULE,  

    3.              .llseek = scull_llseek,  

    4.              .read   = scull_read,  

    5.              .write   = scull_write,  

    6.              .ioctl   = scull_ioctl,  

    7.              .open    = scull_open,  

    8.              .release = scull_release,  

    9.      };  

    定义了一个scull_fops结构,然后用这个结构初始化scull_dev这个设备的struct cdev结构成员。有个成员:owner不是一个操作函数指针,关于它的说明请参考书本,几乎所有的情况下它都要被初始化成THIS_MODLE.其实书本的的例子是把struct cdev这个内核表示的字符设备结构嵌入到scull这个设备里。所以它struct cdev的ops成员的方式如下:

    view plaincopy to clipboardprint?

    1.      static void scull_setup_cdev(struct scull_dev *dev, int index)  

    2.      {  

    3.          int err, devno = MKDEV(scull_major, scull_minor + index);  

    4.            

    5.          cdev_init(&dev->cdev, &scull_fops);  

    6.          dev->cdev.owner = THIS_MODULE;  

    7.          dev->cdev.ops = &scull_fops;  //其实这句可以省略  

    8.          err = cdev_add (&dev->cdev, devno, 1);  

    9.          /* Fail gracefully if need be */  

    10.      if (err)  

    11.          printk(KERN_NOTICE "Error %d adding scull%d", err, index);  

    12.  }  

    这样设备和定义操作设备能力就关联起来了。理解file_operations的作用非常重要,因为在我看来编写一个字符设备驱动最重要的就是编写file_operations函数成员。其实应该说几乎所以的设备驱动程序都是这样的。

    到这里基本上应该可以得到了一个字符设备驱动程序的架构了。

    七、file和inode结构。

    书本重点提到了file和inode,但好像基本上很少讲到file和inode,我在看书的时候就很奇怪,都说这两个结构是很重要的,必不可少的,那为什么讲的时候没给人一种重要的感觉。呵呵,至少我在看书的时候有这个奇怪。file表示一个打开的文件,也就是说只有文件被打开才分配这样的结构。inode是文件在内核内部的表示,准确地说应该是文件在文件系统上的表示,不管怎么样,只要文件存在于文件系统上,那就分配一个inode结构。再进一步区别file和inode,file结构只在打开文件时分配,并且打开一次分配一个,同时打开多次,那就分配多个,但都指向同一个inode.另外习惯上用filp来指向file结构。这两个重要的结构在<linux/fs.h>里定义,非常有必要参考书本上的介绍去理解这两个结构的成员。

    注意这个两个结构是作为驱动程序模块的传入参数被内核传进来的,所以在我们的驱动模块里不会看到它们被定义。怎么理解呢?

            先说inode,inode是文件系统上表示文件,而file是打开的文件在内核内的表示。还是不解?很难办,因为我也很难描述。我尽量吧,呵呵。我们注册设备的时候只是让内核在内部表示这个设备,我们也说过内核把设备当作特殊的文件看待,但文件又要创建在文件系统的基础上,而文件系统又是通过inode来描述文件。这个时候我们用到一个工具:mknod,这个工具就是在文件系统上创建一个已经在内核注册了的设备,用文件的形式表示设备。mknod的用法是:mknod  /dev/scull0 c major minor总共4个参数,设备文件名,设备文件类型(c表示字符设备,b表示块设备),主设备号,次设备号。这个命令要root用户才能运行。这个工具就是在文件系统上创建inode结构。inode结构有两个重要的成员:dev_t  i_rdev,包含设备编号,struct cdev *i_cdev;指向我们设备编号对应的设备。再来看mknod的用法,major minor组成dev_t i_rdev也就是设备编号,struct cdev *i_cdev指向这个设备编号对应的设备结构。

         因为我们已经用足够多的信息创建了设备文件,所以我们访问设备文件的时候就可以通过设备文件的inode结构里的dev_t i_rdev和struct cdev *i_cdev找到我们注册的设备结构。还是不懂?再来看一下我们向内核添加字符设备结构的代码,

    view plaincopy to clipboardprint?

    1.      int cdev_add(struct cdev *dev, dev_t num, unsigned int count),  

    第一个参数第二个参数不就是我们介绍的那两个成员吗?

        还有file结构。我们说过file结构表示打开的文件。这个结构是内核在打开设备文件的时候创建的,也就是说,内核在其内部用file结构表示每一个打开的文件,所以file结构是内核创建的,不用在驱动程序里定义,也不可能在驱动程序里定义,只有内核才有创建这个结构的能力。关于file结构的内核也是我们必须要了解的。我们再仔细看struct file_operations各函数指针成员,那些函数的参数都包含:strict inode,struct file 这两个参数。而且我们要记住这两个参数是由内核传给驱动模块的。来看具体的例子:

    view plaincopy to clipboardprint?

    1.      int scull_open(struct inode *inode, struct file *filp)  

    2.      {  

    3.              struct scull_dev *dev;  

    4.              dev = container_of(inode->i_cdev, struct scull_dev,cdev);  

    5.              filp->private_data = dev;  

    6.              return 0;  

    7.      }  

    省略了一些语句,但不影响讨论。其实还不是很明显,为了简化讨论的简结,这里不深入讨论了,其实是我深入不了,呵呵。假设有下面操作设备文件的调用:

    view plaincopy to clipboardprint?

    1.      int fd;  

    2.      fd = open("/dev/scull0", buf,5); //这个是系统调用open,请参考它的用法。  

    内核在处理这个调用的时候大概会做这些工作:

    一、调用system_call来处理系统调用open,老实处理的具体细节我也不懂,呵呵。

    二、通过/dev/scull0这个设备文件的主设备号找到驱动程序,通过设备文件的inode的dev_t i_rdev和struct cdev *i_cdev找到具体的设备

    三、通过驱动程序模块和设备结构的ops(file_operations)调用scull_open

    四、返回filp

    描述得比较粗糙,这是因为我本身理解得也比较粗糙,还请高手指点,当然如果理解错误并误人子弟,我表示歉意。

    这里省略了file_operations结构成员的编写,其实它是一个驱动程序最重要的部分。但由于每个人每个驱动提供的机制不一样,编写这个结构的成员的方法各不一样。总的来说,你要驱动程序提供什么机制就编写对应的成员,而每个成员都有一个具体的系统调用与其对应。理解了字符设备驱动程序的结构后再理解scull设备就比较容易了。书本的scull设备的结构总的来说还是比较复杂的,所以其file_operations对于一个学习驱动程序的新手来说还是比较难理解的。但是我相信,理解了书本上讲到的理论后再去读源代码应该比较容易,然后再反过来去理解理论就可以比较深入地理解那些原理了。

    附:

    一、这是我们老大在我们学习时提出的几点要求,大家也可以参考,按着这些要求去看书,去学习。

    1, 理解什么是字符设备
    2,字符设备的主设备号,次设备号,内核使用主设备号,找到驱动模块,而次设备号,通过什么途径传递给驱动模块代码使用的。

    3,怎样自己创建设备节点, mknod的使用方法

    4,主设备号可以预先固定,也可以通过alloc_chrdev_region动态获得的。驱动中是怎么注册字符设备的。思考一下注册的操作,内核会做哪  些工作

         可以通过cat /proc/devices获得装载的模块主设备号,可以通过一个脚本,读取这个文件,获得主设备号,并通过mknod创建设备节点。

    5,字符设备的file_operations包括那些成员函数指针,这些指针在应用中是怎么对应使用的。

    6,尝试写一个字符设备驱动,理解每个kernel API的用法和含义。

     

    展开全文
  • 图片加载中由于图片太大... 其中第一次采样是只是单纯的获取图片的宽高,对图片并没有什么非分之想... ,首先需要用到采样的条件,通 过 BitmapFactory.Options得到一个 opts(姑且这样),然后通过这个 opts.inJust

                                               图片的二次采样,防止图片加载导致内存不足       

    图片加载中由于图片太大导致的会导致设备的内存不足,所以这里就需要对图片的大小进行一定的裁剪,通常称之为图片的二次采样,

           其中第一次采样是只是单纯的获取图片的宽和高,对图片并没有什么非分之想...委屈  ,首先需要用到采样的条件,通                    过 BitmapFactory.Options得到一个

    opts(姑且这样叫),然后通过这个 opts.inJustDecodeBounds = true;这里的话,inJustDecodeBounds字面意思就知道仅仅获取图片的        边缘(也就是宽和高),

          第一次采样让它为true,只获取图片原始的宽和高,第二次采样的时候就要将它置为false,要真正开始采样了..

          采样的时候有一个采样比率,默认是1, 如果是 1 的话,他就是图片原始的宽高,如果是 2 的话,他就是取图片宽和高的1/2,也就是宽取一       半,高取一半,这样获取的图片就是原始图片的1/4 大了,以此类推,如果是4 的话,获取的图片大小就是原始图片的1/16了,采样比率都是       2的倍数...

          代码:

          

     //galaxy2这张图片,不进行压缩,大小是2.78M
            //图片===图片的二次采样
    
            //第一次,假采,并不会生成bitmap ,目的图片的宽高
    
            //采样的条件
            BitmapFactory.Options opts = new BitmapFactory.Options();
    
            //仅仅采集边界===宽高
            opts.inJustDecodeBounds = true;//
    
            Bitmap bitmap = BitmapFactory
                    .decodeResource(getResources(), R.mipmap.galaxy2,opts);
    
            Log.d("flag", "----------------->download: 第一次采样的bitmap: " +bitmap);
    
            int rawHeight = opts.outHeight;//图片原始的高度
            int rawWidth = opts.outWidth;//图片原始的宽度
    
            Log.d("flag", "----------------->download: 原始图片的宽: " +rawWidth+", 高: "+rawHeight);
            //第二次
            opts.inJustDecodeBounds = false;//采集的bitmap图片
    
            int inSampleSize = 1;
    
            //计算采样比率
            //标准100*100; 300*300;100*200
            //标准 100*100px
            while (rawHeight>=100*inSampleSize&&rawWidth>=200*inSampleSize){
                inSampleSize*=2;
            }
            Log.d("flag", "----------------->download: 采样比率: " +inSampleSize);
            opts.inSampleSize = inSampleSize;//采样比率= 2 图片原图1/4
    
            //第二次采集图片
            mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.galaxy2,opts);
    
            //采样比率16采样之后的大小是:0.01M
            //采样比率8采样之后的大小是:0.04M
            Log.d("flag", "----------------->download: bitmap进行二次采样的大小是: " +
                    mBitmap.getByteCount()*1.0f/1024/1024);
    
            img.setImageBitmap(mBitmap);
    //标准100*100; 300*300;100*200  这个就是想让采样后的图片多大
    如果理想的图片宽 和 高乘以采样的比率比原始图片的宽.高小,那么继续将采样的比率乘以2,继续采..直到符合条件为止,然后所得的tp就是想要的图片大小

    .. 
     

    展开全文
  •  本文首先对五种传统解决方法的优缺点应用电路图进行对比,最后介绍由深圳光华源科技有限公司开发出的自适应二次后稳压集成电路的特点以及应用注意事项。  首先解释什么叫多路输出反激电源。举例来说,对于个...
  • (六)混杂设备miscdevices

    2020-10-16 14:24:48
    目录什么是混杂设备、查看...1)主设备号10,次设备号不同。 2)简化cdev的设计流程 3)使用上cdev是没有差异。   、查看一下系统中的混杂设备 [root@GEC6818 /]#cat /proc/devices Character devices:

    一、什么是混杂设备

    混杂设备也叫杂项设备,是普通字符设备驱动(struct cdev)的一个封装,可以简化一个普通字符设备驱动的设计流程。

    混杂设备的特点:
    1)主设备号10,次设备号不同。
    2)简化cdev的设计流程
    3)使用上和cdev是没有差异。
     

    二、查看系统中的混杂设备

    [root@GEC6818 /]#cat /proc/devices
    Character devices:
      1 mem
      5 /dev/tty
      5 /dev/console
      5 /dev/ptmx
      5 ttyprintk
     10 misc    ----->混杂设备
    
    [root@GEC6818 /]#cat /proc/misc 
     42 network_throughput
     43 memory_throughput
     44 network_latency
     45 cpu_dma_latency
     46 xt_qtaguid
     47 alarm
     48 log_system
     49 log_radio
     50 log_events
     51 log_main
     52 ashmem
     53 binder
     54 uhid
     236 device-mapper
     55 hdmi-cec
     56 nxp-scaler
     223 uinput
     57 keychord
     1 psaux
     58 usb_accessory
     59 mtp_usb
     60 android_adb
     200 tun
     61 tgt
     237 loop-control
     62 sw_sync
     229 fuse
     235 autofs
     63 ion
    

     

    二、混杂设备的设计过程

    1、普通字符设备驱动的设计流程

    -------定义并初始化一个字符设备---------
    1)定义一个字符设备—>struct cdev
    2)定义并初始化字符设备的文件操作集—>struct file_operations
    3)给字符设备申请一个设备号—>设备号=主设备号<<20 + 次设备号
    4)初始化字符设备
    5)将字符设备加入内核

    -------自动生成设备文件---------
    6)创建class
    7)创建device,其中device是属于class的

    -------得到物理地址对应的虚拟地址-------
    8)申请物理内存区,申请SFR的地址区。SFR — Special Function Register: GPIOEOUT
    9)内存的动态映射,得到物理地址对应的虚拟地址
    10)访问虚拟地址

    2、混杂设备驱动的设计流程
    1)定义文件操作集
    2)定义一个混杂设备,并完成混杂设备的初始化
    3)注册一个混杂设备

    4)申请物理内存区,申请SFR的地址区。SFR — Special Function Register: GPIOEOUT
    5)内存的动态映射,得到物理地址对应的虚拟地址
    6)访问虚拟地址

     

    三、混杂设备的设计模型

    1、混杂设备
    struct miscdevice ---->来描述一个混杂设备

    #include <linux/miscdevice.h>
    struct miscdevice  {
    	int minor;
    	const char *name;
    	const struct file_operations *fops;
    	struct list_head list;
    	struct device *parent;
    	struct device *this_device;
    	const char *nodename;
    	umode_t mode;
    };
    

    成员说明:
    int minor; —>次设备号
    const char *name; ---->混杂设备的名字,也是设备文件的名字。
    const struct file_operations *fops; —>文件操作集

    2、混杂设备的注册

    int misc_register(struct miscdevice * misc);
    

    3、混杂设备的注销

    int misc_deregister(struct miscdevice *misc);
    

     

    四、附录

    代码示例:led_drv.c

    展开全文
  • 混杂设备(miscdevice)

    2021-05-05 14:16:01
    1)主设备号10,次设备号不同。 2)简化cdev的设计流程 3)使用上cdev是没有差异。 、查看一下系统中的混杂设备 [root@GEC6818 /]#cat /proc/devices Character devices: 1 mem 5 /dev/tty 5 /dev/console 5...
  • 先从我的第一份 Java 开发实习工作说起吧~实习生工作日常我是在大二暑期开始了我人生的第一次实习,岗位正是 Java 开发,还混了个 title “助理 Java 工程师”!这家公司属于一家中型企业,作为第一份实习,我...
  • 我是在大二暑期开始了我人生的第一次实习,岗位正是 Java 开发,还混了个 title “助理 Java 工程师”! 这家公司属于一家中型企业,作为第一份实习,我已经很满足了。 刚进入公司的第一天,在导师运维同学的...
  • 第1章 计算机系统概论 1. 什么是计算机系统、计算机硬件计算机软件?硬件软件哪个更重要?...机器字长:指CPU一次能处理的进制数据的位数,通常与CPU的寄存器位数有关。 指令字长:一条指令的进制代码位数。 8.
  • 1. 什么是计算机系统、计算机硬件计算机软件?硬件软件哪个更重要? 解:P3 ... 机器字长:指CPU一次能处理的进制数据的位数,通常与CPU的寄存器位数有关。 指令字长:一条指令的进制代码位数。
  • 十三种设计模式【PDF版】

    热门讨论 2011-05-30 14:13:49
    翻译: 很多程序员在读完这本书,宣布自己相当于经历了一次"主显节"(纪念那稣降生受洗的双重节日),如果你从来没有读 过这本书,你会在你的程序教育生涯里存在一个严重裂沟,所以你应该立即挽救弥补! 可以这么说:GoF ...
  • 电气基本概念

    2020-12-11 07:59:42
    答:运行中的电气设备和电力线路,如果由于绝缘损坏而使带电部分碰触接地的金属构件或直接与大地发生连接时称接地短路。 哪些电气设备必须进行接地或接零保护? 答:1)发电机变压器、高低压电器;2)电力设备传动...
  • 任何东西(包括硬件)在Linux看来都是文件设备,有字符和二进制形式的设备。如打印机、键盘都是字符设备,打印机、光驱是块设备。当成文件处理的好处就是编程简单,只需针对文件编程就可以了。 在Linux中,机器中所有...
  • 3.Linux如何管理分区

    2018-04-20 15:02:00
    任何东西(包括硬件)在Linux看来都是文件设备,有字符和二进制形式的设备。如打印机、键盘都是字符设备,打印机、光驱是块设备。当成文件处理的好处就是编程简单,只需针对文件编程就可以了。在Linux中,机器中所有...
  • 答:mknod 命令结合设备的主设备号和次设备号,可创建个设备文件。 评:这只是其中种方式,也手动创建设备文件。还有 UDEV/MDEV 自动创建设 备文件的方式,UDEV/MDEV 是运行在用户态的程序,可以动态管理设备...
  • 2.改为”复习1次“,间隔3天后才会在“第二次复习”中看到 版本V2013[4] 更新时间:2013-05-20 1.知识点列表直接显示附件,可设置双击打开文档--在视图-->选项-->02知识库编辑 中设置 2.全文搜索功能完善 3.回收站...
  • UASRT

    2018-04-26 10:06:22
    1. 串口是什么?...2. 通信:串行通信、并行通信数字信号是8位...另一种方法是使用8条数据线分别传送8位,一次传送一个字节,并行通信。串行通信并行通信的区别并行通信传输中有多个数据位,同时在两个设备之...
  • 存取时间又称存储访问时间,是指从启动一次存储器操作到完成该操作所经历的时间。 存储周期是指连续两次独立的存储器操作(如连续两次读操作)所需间隔的最小时间。 存储器带宽是指存储器在单位时间中的数据传输...
  • 5、牵引变电一次设备包括什么? …………………………………………………………………….. 6、牵引变电所有哪几个电压等级?.........................................................................................
  • (2)进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。 (3)引入进程的意义是描述多道程序设计系统中程序的动态执行过程。 2、进程的定义及特征 (1)程序进程的区别 (2...
  • 新版Android开发教程.rar

    千次下载 热门讨论 2010-12-14 15:49:11
    Android 是个专门针对移动设备的软件集,它包括个操作系统,中间件一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具 API 接口。 特性 ...
  • DELPHI串口编程

    2015-12-10 21:39:48
    8位口可以一次输入输出8位数据;半8位也可以。  EPP口(增强并行口):由Intel等公司开发,允许8位双向数据传送,可以连接各种非打印机设备,如扫描仪、LAN适配器、磁盘驱动器CDROM 驱动器等。  ECP口(扩展...
  • “我的手机怎么开不了机?...明明头天学会了,可第天就忘了,使用说明文档我们又不能随时待命。 可这个世界并不会因为他们的不解变得缓慢,以前到现场才能完成的挂号、买票、缴费,现在通通需要用手机才
  • 唐朔飞计算机组成原理答案完整版

    热门讨论 2011-12-11 21:51:19
     机器字长:指CPU一次能处理的进制数据的位数,通常与CPU的寄存器位数有关。  指令字长:一条指令的进制代码位数。 8. 解释下列英文缩写的中文含义: CPU、PC、IR、CU、ALU、ACC、MQ、X、MAR、MDR、I/O、...
  • 2019数据运营思维导图

    2019-03-29 21:34:09
    以目标为导向,学会数据拆分 细分到极致 追踪思路 运营的问题,是追踪出来的,不是一次就看出来的 所有的数据都是靠积累沉淀才能发现问题,单一的数字没有任何 意义,只能称为 “数值” 结合/拆分思路 追踪数据,...
  • 数据运营思维导图

    2018-04-26 14:24:22
    运营的问题,是追踪出来的,不是一次就看出来的 所有的数据都是靠积累沉淀才能发现问题,单一的数字没有任何意义,只能称为 “数值” 结合/拆分思路 追踪数据,多个维度结合分析。 从多个维度拆分数据 对比...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    第十章 域 属 性 .139 12.1 域 .139 12.2 属 性 .143 12.3 小 结 .146 第十三章 事件索引指示器 .148 13.1 事 件 .148 13.2 索引指示器 .151 13.3 小 结 .154 第十四章 继 承 .155 14.1 C#的...
  • 以瑞星为例,在2002年的时候每周升级一次,03年是三次,到了07年每周升级21次,也就是每天升级3次,为什么会有这样一种变化呢,就是因为现在的病毒数量跟以前已经不是在一个数量级上了,但是频繁升级是否能够解决...

空空如也

空空如也

1 2 3 4
收藏数 70
精华内容 28
关键字:

什么叫一次设备和二次设备