linux中三种驱动设备
linux系统将设备分为3类:字符设备、块设备、网络设备。
字符设备
字符设备是能够像字节流(类似文件)一样被访问的设备,有字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少要实现open、close、read、write系统调用。字符设备可以通过文件系统节点来访问,这些设备文件和普通文件之间的唯一差别在于对普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道。一个字符设备是一种字节流设备,对设备的存取只能按顺序按字节的存取而不能随机访问,字符设备没有请求缓冲区,所有的访问请求都是按顺序执行的。但事实上现在一些高级字符设备也可以从指定位置一次读取一块数据。块设备
块设备也是通过设备节点来访问。块设备上能够容纳文件系统。在大多数unix系统中,进行I/O操作时块设备每次只能传输一个或多个完整的块,而每块包含512字节(或更2的更高次幂字节的数据)。linux可以让应用程序向字符设备一样读写块设备,允许一次传递任意多字节的数据。因而,块设备和字符设备的区别仅仅在于内核内部管理数据的方式,也就是内核及驱动程序之间的软件接口,而这些不同对用户来讲是透明的。在内核中,和字符驱动程序相比,块驱动程序具有完全不同的接口。存储设备一 般属于块设备,块设备有请求缓冲区,并且支持随机访问而不必按照顺序去存取数据,比如你可以 先存取后面的数据,然后在存取前面的数据,这对字符设备来说是不可能的。Linux下的磁盘设备都是块设备,尽管在Linux下有块设备节点,但应用程序一般是通过文件系统及其高速缓存来访问块设备的,而不是直接通过设备节点来读写块设备上的数据。网络设备
网络设备不同于字符设备和块设备,它是面向报文的而不是面向流的,它不支持随机访问,也没有请求缓冲区。由于不是面向流的设备,因此将网络接口映射到文件系统中的节点比较困难。内核和网络设备驱动程序间的通讯,完全不同于内核和字符以及块驱动程序之间的通讯,内核调用一套和数据包传输相关的函数而不是read,write。网络接口没有像字符设备和块设备一样的设备号,只有一个唯一的名字,如eth0、eth1等,而这个名字也不需要与设备文件节点对应。
字符设备与块设备的区别
- 字符设备是面向流的,最小访问单位是字节;而块设备是面向块的,最小访问单位是512字节或2的更高次幂。
- 字符设备只能顺序按字节访问,而块设备可随机访问。
- 块设备上可容纳文件系统,访问形式上,字符设备通过设备节点访问,而块设备虽然也可通过设备节点访问,但一般是通过文件系统来访问数据的。
- 网络设备没有设备节点是因为,网络设备是面向报文的,很难实现相关read、write等文件读写函数。所以驱动的实现也与字符设备和块设备不同。
字符设备与块设备的区分
每一个字符设备或者块设备都在/dev目录下对应一个设备文件。读者可以通过查看/dev目录下的文件的属性,来区分设备是字符设备还是块设备。使用cd命令进入/dev目录,并执行ls -l命令就可以看到设备的属性
[root@tom /]# cd /dev /*进入/dev目录*/
[root@tom dev]# ls -l /*列出/dev中文件的信息*/、
/*第1字段 2 3 4 5 6 7 8 */
crw-rw----+ 1 root root 14, 12 12-21 22:56 adsp
crw------- 1 root root 10, 175 12-21 22:56 agpgart
crw-rw----+ 1 root root 14, 4 12-21 22:56 audio
brw-r----- 1 root disk 253, 0 12-21 22:56 dm-0
brw-r----- 1 root disk 253, 1 12-21 22:56 dm-1
crw-rw---- 1 root root 14, 9 12-21 22:56 dmmidi
ls -l命令的第1个字段中的第1个字符c表示设备是字符设备,b表示设备是块设备;
第234字段对驱动程序开发来说没有关系;
第5,6字段分别表示设备的主设备号和次设备号;
第7字段表示文件的最后修改时间。第8字段表示设备的名字。
由第1和8字段可知,adsp是字符设备,dm-0是块设备。其中adsp设备的主设备号是14,次设备号是12。
混杂设备
在linux系统中,存在一类字符设备,它们共享一个主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice)。所有的混杂设备形成一个链表,对设备访问时内核根据次设备号查找到相应的miscdevice设备。
- 混杂设备与字符驱动的区别:
- 相对字符驱动而言,内核封装好了api,相对更容易开发;
-
由于只占用一个从设备号,故而每一个驱动都只能用于一个设备,无法和字符驱动比,能够用于多个设备;
驱动开发流程
- 查看原理图,理解设备的工作原理。
- 定义主设备号。
设备由一个主设备号和一个次设备号来标识。主设备号唯一标识了设备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅
由设备驱动程序解释,区分被一个设备驱动控制下的某个独立的设备。 - 实现初始化函数。在驱动程序中实现驱动的注册和卸载。
- 设计所要实现的文件操作,定义file--operations结构。
- 实现所需的文件操作调用,如read,write等。
- 实现中断服务,并用request--irq向内核注册,中断并不是每个设备驱动所必需的。
- 编译该驱动程序到内核中,或者用insmod命令加载模块。
- 测试该设备,编写应用程序,对驱动程序进行测试。