精华内容
下载资源
问答
  • 字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标、键盘、显示器、串口等等,当我们执行ls -l/dev的时候,就能...
  • 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序。可以有一个读,一个写进程共享该字符设备,进行聊天;也可以由多个读和多个写进程共享该字符设备,进行聊天
  • 字符设备驱动

    2012-07-21 16:07:17
    字符设备驱动 字符设备 驱动 内核 linux
  • 在Linux内核里面,设备(device)主要分为字符设备,块设备,网络设备,字符设备驱动是Linux驱动基础,在看《Linux 设备驱动开发详解》这本书的过程中,把字符设备相知识记录整理如下。 字符设备驱动的组成 字符设备...
  • 字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标、键盘、显示器、串口等等,当我们执行 ls -l /dev 的时候,能...
  • 主要介绍了Linux 字符设备驱动框架详细介绍的相关资料,字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,这里提供简单的实例,需要的朋友可以参考下
  • Linux主要将设备分为二类:字符设备和块设备。字符设备是指设备发送和接收数据以字符的形式进行,本文详细解析了Linux字符设备驱动程序。
  • 字符设备、块设备、网络设备

    千次阅读 2017-08-25 10:48:33
    字符设备、块设备、网络设备设备模型设备驱动的代码量占内核程序的50%设备模型的意义: 为了降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型(也称作Driver ...

    字符设备、块设备、网络设备

    这里写图片描述

    设备模型

    设备驱动的代码量占内核程序的50%

    设备模型的意义:
    为了降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型(也称作Driver Model)的概念。设备模型将硬件设备归纳、分类,然后抽象出一套标准的数据结构和接口。驱动的开发,就简化为对内核所规定的数据结构的填充和实现。

    因为硬件设备多种多样,使得设备驱动程序繁多,设备模型将硬件设备分类,抽象出一套标准的数据结构和接口。

    一、字符设备

    1.特点

    一个字节一个字节读写的设备,
    读取数据需要按照先后数据(顺序读取
    常见的字符设备有鼠标、键盘、串口、控制台和LED设备
    每个字符设备在/dev目录下对应一个设备文件,linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备。

    2.上层应用如何调用底层驱动?

    1.应用层的程序open(“/dev/xxx”,mode,flags)打开设备文件,进入内核中,即虚拟文件系统中。
    2.VFS层的设备文件有对应的struct inode,其中包含该设备对应的设备号,设备类型,返回的设备的结构体。
    3.在驱动层中,根据设备类型和设备号就可以找到对应的设备驱动的结构体,用i_cdev保存。该结构体中有很重要的一个操作函数接口file_operations。
    4.在打开设备文件时,会分配一个struct file,将操作函数接口的地址保存在该结构体中。
    5.VFS层 向应用层返回一个fd,fd是和struct file相对应,这样,应用层可以通过fd调用操作函数,即通过驱动层调用硬件设备了。

    这里写图片描述
    这里写图片描述

    二、块设备

    1.特点

    数据以固定长度进行传输,比如512K
    从设备的任意位置(可跳)读取,但实际上,块设备会读一定长度的内容,而只返回用户要求访问的内容,所以随机访问实际上还是读了全部内容。
    块设备包括硬盘、磁盘、U盘和SD卡
    每个块设备在/dev目录下对应一个设备文件,linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作块设备。
    块设备可以容纳文件系统,比如磁盘

    三、网络设备

    1.特点

    面向报文而不是面向流的,因此将网络接口映射到文件系统的节点比较困难
    内核调用一套和数据包相关的函数,而不是read,write。
    网络接口没有像字符设备和块设备一样的设备号,只有唯一的名字,如eth0,eth1
    主要通过socket操作,打开通常用命令行,

    2.关系

    网络协议接口层:网络层,IP
    网络设备接口层:将协议和各种网络驱动连接在一起,这一层提供一组通用函数供底层网络设备驱动使用。
    网络驱动接口层:数据链路层,提供对物理层访问的设备驱动程序,这可以是各种介质,例如串口链路或以太网设备。包括LLC和MAC层
    物理层:PHY层
    这里写图片描述

    展开全文
  • linux字符设备驱动

    2012-04-27 21:53:01
    1)编写一个简单的字符设备驱动程序,该字符设备包括打开、读、写、I/O控制与释放五个基本操作。 2)编写一个测试程序,测试字符设备驱动程序的正确性。 3)要求在实验报告中列出Linux内核的版本与内核加载的过程
  • 字符设备与块设备的区别

    千次阅读 多人点赞 2019-06-18 13:46:31
    字符设备与块设备的区别 字符设备与块设备的区别 在LINUX里面,设备类型分为:字符设备、块设备以及网络设备,PCI是一种和ISA为一类的总线结构,归属于网络驱动设备~~~ 字符设备、块设备主要区别是:在对字符设备...

    字符设备与块设备的区别

    字符设备与块设备的区别  

    在LINUX里面,设备类型分为:字符设备、块设备以及网络设备, PCI是一种和ISA为一类的总线结构,归属于网络驱动设备~~~ 

     字符设备、块设备主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,而块设备则不然,它利用一块系统内存作为缓冲区,当用户进程对设备请求能满足用户的要求时,就返回请求的数据,如果不能就调用请求函数来进行实际的I/O操作,因此,块设备主要是针对磁盘等慢速设备设计的,以免消耗过多的CPU时间来等待~~~

     

    系统中能够随机(不需要按顺序)访问固定大小数据片(chunks)的设备被称作块设备,这些数据片就称作块。最常见的块设备是硬盘,除此以外,还有软盘驱动器、CD-ROM驱动器和闪存等等许多其他块设备。注意,它们都是以安装文件系统的方式使用的——这也是块设备的一般访问方式。

     

      另一种基本的设备类型是字符设备。字符设备按照字符流的方式被有序访问,像串口和键盘就都属于字符设备。如果一个硬件设备是以字符流的方式被访问的话,那就应该将它归于字符设备;反过来,如果一个设备是随机(无序的)访问的,那么它就属于块设备。

     

         这两种类型的设备的根本区别在于它们是否可以被随机访问——换句话说就是,能否在访问设备时随意地从一个位置跳转到另一个位置。举个例子,键盘这种设备提供的就是一个数据流,当你敲入"fox" 这个字符串时,键盘驱动程序会按照和输入完全相同的顺序返回这个由三个字符组成的数据流。如果让键盘驱动程序打乱顺序来读字符串,或读取其他字符,都是没有意义的。所以键盘就是一种典型的字符设备,它提供的就是用户从键盘输入的字符流。对键盘进行读操作会得到一个字符流,首先是"f",然后是"o",最后是"x",最终是文件的结束(EOF)。当没人敲键盘时,字符流就是空的。硬盘设备的情况就不大一样了。硬盘设备的驱动可能要求读取磁盘上任意块的内容,然后又转去读取别的块的内容,而被读取的块在磁盘上位置不一定要连续,所以说硬盘可以被随机访问,而不是以流的方式被访问,显然它是一个块设备。

     

      内核管理块设备要比管理字符设备细致得多,需要考虑的问题和完成的工作相比字符设备来说要复杂许多。这是因为字符设备仅仅需要控制一个位置—当前位置—而块设备访问的位置必须能够在介质的不同区间前后移动。所以事实上内核不必提供一个专门的子系统来管理字符设备,但是对块设备的管理却必须要有一个专门的提供服务的子系统。不仅仅是因为块设备的复杂性远远高于字符设备,更重要的原因是块设备对执行性能的要求很高;对硬盘每多一分利用都会对整个系统的性能带来提升,其效果要远远比键盘吞吐速度成倍的提高大得多。另外,我们将会看到,块设备的复杂性会为这种优化留下很大的施展空间。

     

      块设备通过系统缓存进行读取,不是直接和物理磁盘读取字符设备可以直接物理磁盘读取,不经过系统缓存。(如键盘,直接相应中断)

     

    字符设备是裸设备 通过查看 ll /dev/vg00/ 下的内容 若开头带c字符的则为字符设备

    块设备是文件设备 通过查看 ll /dev/vg00/ 下的内容 若开头带b字符的则为块符设备

     

    在使用上,只要在对数据库方面的应用需要考虑是选择块设备还是字符设备。一般数据库厂商会建议你建库时使用裸设备(字符设备),空间管理完全由数据库引擎进行管理,这样所有数据和日志直接写盘,当发生系统故障时,不至于丢失数据。但还有一种说法是使用块设备便于管理维护人员的系统管理,因为使用裸设备在第一次分配出去之后,这个设备的空间就不能做任何其他用途了,但块设备则不然,你想使用多少空间就分配多少,你可以进行自由的扩展,而无需一次性的全部分配出去。所以我建议在创建数据库master库使用裸设备,而业务数据库及tempdb则使用块设备。

     

    展开全文
  • Linux字符设备驱动

    千次阅读 2017-08-27 18:36:35
    1. Linux设备类型Linux内核中的设备可分为三类:字符设备、块设备和网络设备。 字符设备(Character device):适合面向字符的数据交换,因其数据传输量较低。对这种设备的读写是按字符进行的,而且这些字符是连续...

    1. Linux设备类型

    Linux内核中的设备可分为三类:字符设备、块设备和网络设备。
    字符设备(Character device):适合面向字符的数据交换,因其数据传输量较低。对这种设备的读写是按字符进行的,而且这些字符是连续地形成一个数据流。他不具备缓冲区,所以对这种设备的读写是实时的,如终端、磁带机、串口、键盘等。
    块设备(Block device):是一种具有一定结构的随机存取设备,对这种设备的读写是按固定大小的数据块进行的,他使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或从设备中一次性读出放入到缓冲区。块设备通常都是以安装文件系统的方式使用的——这也是块设备一般的访问方式。
    每个字符设备和块设备都有与之对应的设备文件,这种文件并不指向磁盘或其他存储介质上的数据,只是用来建立与某个设备驱动程序的关联,让应用程序可以像访问普通文件一样来访问和操作设备,而无需过多关注设备之间的差异。正如下图所示:
    这里写图片描述

    Linux驱动程序中字符设备和块设备的几点区别:

    • 字符设备只能以字节为最小单位访问,而块设备以固定长度的块为单位,例如512字节,1024字节等,即使只请求一个字节的数据,也会从设备中取出完整块的数据;
    • 块设备可以随机访问(在数据中的任何位置进行访问),但是字符设备不做要求(有些字符设备可以提供数据的随机访问,驱动程序可选择是否实现);
    • 块设备的读写会有大规模的缓存,已经读取的数据会保存在内存中,如果再次读取则直接从内存中获得,写入操作也使用了缓存以便延迟处理,减少了IO次数和占用的CPU时间。而字符设备每次的读写请求必须与设备交互才能完成,因此没有必要使用缓存。

    网络设备(Network device):网络设备用于管理系统中的(物理或虚拟)网卡,处理网口上网络数据的收发,并提供协议栈和特定网卡之间关联的统一接口。和字串设备/块设备不同的是,网络设备在/dev下面不会有对应的设备文件,而是通过net_device结构来定义网卡提供的服务并可供用户程序读取和配置(如配置IP地址等)。和字符设备类似,网络设备不会关联到实际的存储介质或特定文件系统上。

    2. 设备文件

    2.1 文件属性

    一个设备文件对应的设备并不是通过其文件名标识,而是通过文件的主、从设备号标识的。这些号码在系统中作为特别的文件属性管理。

    root@openwrt:/bin# ls -l /dev/mtdblock* /dev/ttyS*
    brw-r--r-- 1 root  root  31,  0 Jan  1  1970 /dev/mtdblock0
    brw-r--r-- 1 root  root  31,  1 Jan  1  1970 /dev/mtdblock1
    brw-r--r-- 1 root  root  31,  2 Jan  1  1970 /dev/mtdblock2
    crw-rw-rw- 1 root  root  4,  64 Jan  1  1970 /dev/ttyS0
    crw------- 1 root  root  4,  65 Aug 24 17:53 /dev/ttyS1

    上面打印出了/dev中的几个设备文件,这些文件的属性和普通文件有两处很重要的差别:
     文件类型(访问权限之前的字母)是b或c,分别表示块设备和字符设备。
     设备文件没有文件长度,而增加了另外两个值:[主设备号, 从设备号],二者共同形成一个唯一的号码,内核可由此查找对应的设备驱动程序。

    2.2 主从设备号

    内核通过主从设备号来标识匹配的驱动程序。主设备号用于寻址设备驱动程序自身,系统中可能存在几个同样类型的设备,他们由同一个设备驱动程序管理,也就是说,一个主设备号对应一个驱动程序,一个次设备号对应驱动程序所实现的某个设备实例。例如上面的ttyS0和ttyS1两个设备的主设备号是同一个,而驱动程序管理的各个设备则通过不同的从设备号指定。
    为驱动程序和设备分配的主从设备号,主要是通过一个半官方的组织管理,设备号的当前列表可以从http://www.lanana.org或内核源码中的Documentation/devices.txt中获取,而内核源码的

    MAJOR(dev_t dev); //从dev_t中提取主设备号
    MINOR(dev_t dev); //从dev_t中提取从设备号
    MKDEV(int major, int minor); //根据主从设备号产生一个dev_t类型的值

    3. 字符设备创建过程

    3.1 管理字符设备

    每个字符设备都有一个struct cdev实例与之对应,全局变量cdev_map是一个散列表,用来跟踪系统中所有的字符设备对象。(块设备也是这种做法,每个块设备的struct genhd实例都由全局变量bdev_map来跟踪维护。)
    针对字符设备还有一个设备号数据库,即全局数组chrdevs[CHRDEV_MAJOR_HASH_SIZE]。仍然使用散列表来记录所有已分配的设备号范围,使用主设备作为散列键,散列方法很简单:(major % 255)。
    数组的每个散列元素以及冲突链表的每个元素都是一个struct char_device_struct结构,定义如下:

    static struct char_device_struct {
        struct char_device_struct *next;
        unsigned int major; //主设备号
        unsigned int baseminor; //子设备号的起始值
        int minorct; //子设备号的个数
        char name[64];
        struct cdev *cdev;      /* will die */
    } *chrdevs[CHRDEV_MAJOR_HASH_SIZE];

    结构体中的next指针指向冲突链表中的下一个元素。每个散列值的冲突链表由major从小到大排列,major相同的则由子设备号从小到大排列。不会也不允许存在设备号重叠的情况。

    3.2 注册字符设备

    通过MKDEV我们可以得到一个dev_t类型的设备编号,这个编号被作为要分配的设备编号范围的起始值,其次设备号通常为0。申请多个连续的设备编号的必要函数为:

    int register_chrdev_region(dev_t from, unsigned count, const char *name);

    这个函数有三个参数:first是设备编号范围的起始值,即上面通过MKDEV获得的dev_t类型的值,count是申请连续设备编号的个数,name是与该设备范围关联的设备名称,它将出现在/proc/devices和sysfs中。分配成功该函数返回0,失败返回错误码。
    该函数将设备号 first ~ (first+count-1) 全部占为己有,字符设备的设备号数据库会将这些设备号记录为已分配,不能再被其他驱动程序申请使用。如果在申请过程中发现其中某些设备编号已经被分配过了(设备号重叠),register_chrdev_region会返回-EBUSY错误码。
    对应的释放设备号的方法为:

    void unregister_chrdev_region(dev_t from, unsigned count);

    另外还有下面两个函数:

    int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name) [1]
    unregister_chrdev_region(dev_t from, unsigned count) [2]

    函数[1]可以动态分配主设备编号,当我们不确定要使用哪个主设备号时可以使用这个函数,该函数中basenimor和count用于请求次设备号,获取到的主设备号以及baseminor组成的dev_t存放在第一个参数dev中,同样的,分配成功该函数返回0,失败返回错误码。函数[2]用于归还设备编号。
    注意alloc_chrdev_region只能申请一个major,而register_chrdev_region申请的设备号范围可以包含多个major,即同时申请多个major。

    3.3 激活字符设备

    在获取了设备号范围后,需要将设备添加到系统的字符设备数据库(即上面讲到的全局变量cdev_map)中,以激活设备。这就需要用cdev_init初始化一个struct cdev实例,并调用cdev_add添加到系统中(对应的删除方法为cdev_del())。

    void cdev_init(struct cdev *cdev, const struct file_operations *fops);
    int cdev_add(struct cdev *p, dev_t dev, unsigned count);

    cdev_init的参数cdev即字符设备实例,可以静态定义或使用cdev_alloc()动态分配。参数fops指向与设备实际通信的函数集合,下面会讲到。

    3.4 创建设备文件

    用户程序通过设备文件名来操作设备(如open/read/write/ioctl/close),因此要将设备文件(在/dev下)创建好。
    如果文件系统必须是只读的,则只能在打包镜像期间,通过mknod来预创建设备文件,mknod命令要指定设备类型、主从设备号和文件名。这种做法的问题是,所有设备文件都要手动创建,如果设备数非常多则是一件很无聊的事;其次,由于设备文件被放到磁盘文件系统中,如果一个设备已经不需要了,就会残留在系统中;最后,驱动程序必须使用mknod约定好的主从设备号来创建设备,降低了机动性。
    可以使用udev机制来动态创建设备节点,它依赖于用户态程序udevd来监听内核的消息,并根据udev规则(/etc/udev/udev.conf中配置以及/etc/udev/rules.d/下的规则)创建设备文件。而/dev被挂载为tmpfs,这样在系统重启后,原有的设备文件被清空,由驱动程序更新。
    在内核中注册并激活设备后,要调用device_create(),该函数在/sys中注册相应设备,并发送一个add device的通知,udevd便可收到该通知并在/dev下创建设备文件。

    struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);

    另外,在嵌入式设备上,还有一个轻量级的工具mdev,机制和用法和udev类似,以及WRT系统上使用的hotplug2,有兴趣可以用用看。
    其他接口
    还有一个旧的注册字符设备的函数register_chrdev,这个函数从register到add一气呵成,不过新的代码不应该使用该函数,一来太自动化,驱动程序无法知道cdev的任何信息,而且该函数不支持大于255的子设备号。
    可以把一些简单的字符设备驱动初始化为混杂驱动程序,所有混杂设备的主设备号都是10。混杂驱动程序只需调用misc_register()即可完成一个字符设备的完整注册过程,例如:

    static struct miscdevice gpio_smi_dev = {
       .minor       = MISC_DYNAMIC_MINOR,
       .name        = "gpiosmi",
       .fops        = &gpiosmi_fops,
    };
    
    static int __init gpio_smi_init(void)
    {
    int ret;
    ret = misc_register(&gpio_smi_dev);
        if(0 != ret)
        {
            return -1;
        }
    
        return 0;
    }
    
    static void __exit gpio_smi_exit(void)
    {
        misc_deregister(&gpio_smi_dev);
    }
    
    module_init(gpio_smi_init);
    module_exit(gpio_smi_exit);

    在struct miscdevice结构体中,可以通过minor指定子设备号,或者指定为MISC_DYNAMIC_MINOR来让系统动态分配一个从设备号,分配好后会重新赋值给minor。
    每一个混杂驱动程序自动出现在/sys/class/misc/目录下,而不必在驱动程序中再创建。

    3.5 操作设备文件

    关联到inode
    我们说用户程序可以想操作普通文件一样来操作设备文件,那么每个设备文件肯定要关联到虚拟文件系统中的一个inode。

    struct inode {
        umode_t     i_mode;
        ... ...
        dev_t           i_rdev;
      ... ...
        const struct file_operations    *i_fop;
        ... ...
        struct list_head    i_devices;
        union {
            ... ...
            struct block_device *i_bdev;
            struct cdev     *i_cdev;
        };
        ... ...
    };

    其中,i_mode存储了文件类型(普通文件、目录文件、字符设备、块设备、套接字等),而i_rdev中存储了主从设备号。i_fop是一组函数指针集合,包括许多文件操作(open/read/write等)来下发各种具体文件操作。内核根据inode表示字符设备还是块设备来使用i_bdev或i_cdev指向更多具体信息,i_devices是一个链表节点,以字符设备为例,cdev的list成员是一个链表,设备文件被打开一次,就会创建一个inode并插入到这个链表中,inode的i_devices成员即为链表元素。
    寻找文件操作
    在打开一个设备文件时,各文件系统的实现会调用init_special_inode函数为设备创建一个inode并设置默认的文件操作处理函数。

    void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
    {
        inode->i_mode = mode;
        if (S_ISCHR(mode)) {
            inode->i_fop = &def_chr_fops;
            inode->i_rdev = rdev;
        } else if (S_ISBLK(mode)) {
            inode->i_fop = &def_blk_fops;
            inode->i_rdev = rdev;
        } else if (S_ISFIFO(mode))
            inode->i_fop = &pipefifo_fops;
        else if (S_ISSOCK(mode))
            inode->i_fop = &bad_sock_fops;
        else
            printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for"
                      " inode %s:%lu\n", mode, inode->i_sb->s_id,
                      inode->i_ino);
    }
    EXPORT_SYMBOL(init_special_inode);

    可见对于所有的字符设备,VFS层的文件操作集合由def_chr_fops提供,其中打开文件的函数为chrdev_open(),该函数通过inode->i_cdev或inode->i_rdev获取到字符设备的struct cdev实例,接着调用特定于该设备的文件操作集合cdev-> ops的open方法(如果在该设备的驱动程序中有定义的话)。
    额外说一下,为设备定义特定文件操作通常的做法是,首先为主设备号设置一个特定的文件操作集合(例如misc的所有设备都指向misc_fops),接下来如果某个设备需要对某些操作做补充,则定义特定于该从设备号的操作函数来覆盖原操作。通常要提供的操作有open/read/write/ unlocked_ioctl/release等。

    4. 伪字符设备驱动

    顺便介绍一些并没有关联到实际设备的字符驱动,例如/dev/null,/dev/random,他们可以提供一些简单常用的服务,下面这些字符设备的主设备号都是1(MEM_MAJOR),定义在drivers/char/mem.c中。
    /dev/null
    接收你不想在命令行上显示的数据,该设备的write不处理数据,只是返回写的长度。
    /dev/zero
    获取一串0字符,相当于将一段内存memset为’\0’。
    /dev/mem
    让我们可以直接操作或映射物理地址空间,可赋与mmap()并操作返回的区域。
    /dev/random/dev/urandom
    随机数发生器,从random读取的随机数的随机性要高于urandom。但random可能输出一定数量随机数后阻塞停止(可以在一个新终端操作键盘或鼠标补充熵池让random继续产生随机数)。

    展开全文
  • 字符设备、块设备、网络设备 设备模型 设备驱动的代码量占内核程序的50% 设备模型的意义: 为了降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型(也称作...

    字符设备、块设备、网络设备

    在这里插入图片描述
    设备模型
    设备驱动的代码量占内核程序的50%

    设备模型的意义:
    为了降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型(也称作Driver Model)的概念。设备模型将硬件设备归纳、分类,然后抽象出一套标准的数据结构和接口。驱动的开发,就简化为对内核所规定的数据结构的填充和实现。

    因为硬件设备多种多样,使得设备驱动程序繁多,设备模型将硬件设备分类,抽象出一套标准的数据结构和接口。

    一、字符设备
    1.特点
    一个字节一个字节读写的设备,
    读取数据需要按照先后数据(顺序读取)
    常见的字符设备有鼠标、键盘、串口、控制台和LED设备
    每个字符设备在/dev目录下对应一个设备文件,linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备。

    2.上层应用如何调用底层驱动?
    1.应用层的程序open(“/dev/xxx”,mode,flags)打开设备文件,进入内核中,即虚拟文件系统中。
    2.VFS层的设备文件有对应的struct inode,其中包含该设备对应的设备号,设备类型,返回的设备的结构体。
    3.在驱动层中,根据设备类型和设备号就可以找到对应的设备驱动的结构体,用i_cdev保存。该结构体中有很重要的一个操作函数接口file_operations。
    4.在打开设备文件时,会分配一个struct file,将操作函数接口的地址保存在该结构体中。
    5.VFS层 向应用层返回一个fd,fd是和struct file相对应,这样,应用层可以通过fd调用操作函数,即通过驱动层调用硬件设备了。

    在这里插入图片描述
    在这里插入图片描述
    二、块设备
    1.特点
    数据以固定长度进行传输,比如512K
    从设备的任意位置(可跳)读取,但实际上,块设备会读一定长度的内容,而只返回用户要求访问的内容,所以随机访问实际上还是读了全部内容。
    块设备包括硬盘、磁盘、U盘和SD卡等
    每个块设备在/dev目录下对应一个设备文件,linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作块设备。
    块设备可以容纳文件系统,比如磁盘

    三、网络设备
    1.特点
    面向报文而不是面向流的,因此将网络接口映射到文件系统的节点比较困难
    内核调用一套和数据包相关的函数,而不是read,write。
    网络接口没有像字符设备和块设备一样的设备号,只有唯一的名字,如eth0,eth1
    主要通过socket操作,打开通常用命令行,

    2.关系
    网络协议接口层:网络层,IP
    网络设备接口层:将协议和各种网络驱动连接在一起,这一层提供一组通用函数供底层网络设备驱动使用。
    网络驱动接口层:数据链路层,提供对物理层访问的设备驱动程序,这可以是各种介质,例如串口链路或以太网设备。包括LLC和MAC层
    物理层:PHY层
    在这里插入图片描述
    ————————————————
    版权声明:本文为CSDN博主「qq_27840681」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_27840681/article/details/77567094

    展开全文
  • 关于块设备 和 字符设备 介绍:                 系统中能够随机(不需要按顺序)访问固定大小数据片(chunks)的设备被称作块设备,这些数据片就称作块。     &...
  • 配合我写的两篇关于简单字符设备和块设备驱动使用,这里是两个驱动程序的完整文件,使用的是 Ubuntu 16.0 的系统环境
  • 一、字符设备基础知识 1、设备驱动分类  linux系统将设备分为3类:字符设备、块设备、网络设备。使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据...
  • 字符设备文件 .rar

    2009-08-09 21:19:00
    字符设备文件 .rar 字符设备文件 .rar 字符设备文件 .rar 字符设备文件 .rar 字符设备文件 .rar 字符设备文件 .rar
  • linux 字符设备驱动 字符设备是指在I/O传输过程中以字符为单位进行传输的设备,例如键盘,打印机等。请注意,以字符为单位并不一定意味着是以字节为单位,因为有的编码规则规定,1个字符占16比特,合2个字节。  在...
  • Linux字符设备驱动剖析

    千次阅读 2015-05-23 23:09:13
    忠于源码,讲述linux字符设备驱动的那些事儿,重点讲述字符设备的创建和访问过程。
  • 主要对linux下字符设备与块设备的区别进行详细地解答,在学习字符设备驱动,以及面试方面都有帮助
  • linux虚拟字符设备驱动程序 globalmem虚拟字符设备 不依赖硬件
  • Linux设备驱动之字符设备驱动

    万次阅读 多人点赞 2016-07-01 19:36:15
    一、linux系统将设备分为3类:字符设备、块设备、网络设备。 应用程序调用的流程框图: 三种设备的定义分别如下, 字符设备:只能一个字节一个字节的读写的设备,不能随机读取设备内存中的某一数据,读取...
  • 字符设备驱动模型

    千次阅读 2016-05-08 21:48:23
    在Linux系统中,设备的类型非常繁多,如:字符设备,块设备,网络接口设备,USB设备,PCI设备,平台设备,混杂设备……,而设备类型不同,也意味着其对应的驱动程序模型不同,这样就导致了我们需要去掌握众多的驱动...
  • 字符设备驱动的一些简单代码,字符设备驱动的一些简单代码,字符设备驱动的一些简单代码,自己做的,欢迎下载。。
  • 深入理解Linux字符设备驱动

    千次阅读 2016-03-20 11:09:13
    文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次、组成框架和交互、如何编写驱动、设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解。
  • 一个虚拟的linux字符设备驱动实例,包括对/sys, 及/dev下设备文件的自动生成
  • 字符设备的上层没有磁盘文件系统,所以字符设备的file_operations成员函数就直接由字符设备驱动提供(一般字符设备都会实现相应的fops集),因此file_operations 也就成为了字符设备驱动的核心。 特点: 一个...
  • 字符设备驱动基础知识

    万次阅读 2019-07-20 21:28:48
    一、字符设备结构体(cdev) 在Linux内核中, 使用cdev结构体来描述一个字符设备。 struct cdev { struct kobject kobj; //内嵌的kobject对象 struct module *owner;//所属模块 const struct file_operations *ops;...
  • OpenWrt 15.字符设备驱动软件包测试 掌握字符设备驱动的编译方法 掌握字符设备驱动的加载和卸载方法
  • Linux字符设备驱动架构分析,Linux字符设备驱动架构分析,Linux字符设备驱动架构分析

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 565,890
精华内容 226,356
关键字:

字符设备