嵌入式外部设备与驱动
- 格式:doc
- 大小:56.50 KB
- 文档页数:6
Linux外部设备与驱动 1. Linux 设备文件介绍: 在Linux中,所有的设备以文件的形式出现在目录 /dev 中。它们可读、可写,如果你有权限这么做的话。 Linux操作系统把设备纳入文件系统的范畴来管理。 每个设备在Linux系统上看起来都像一个文件,它们存放在/dev目录中,称为"设备节点"。 设备文件列表能够揭示设备的一些重要细节:ls -l /dev/tty3 我的系统给出如下的输出:crwxr-xr-x 1 root tty 4, 67 Mar 13 22:59 ttyS3 最左边的“c”表明这是一个字符设备。如果是“b”则意味着“块设备”,“p”=先入先出设备(FIFO),“u”=非缓冲字符设备,“d”=目 录,“l”=符号链接。数字“4,67”的意思是主设备号为4,次设备号为67。 2. Linux内核驱动之主次编号: ls -l 命令,看到在设备文件项中有 2 个数(由一个逗号分隔)在最后修改日期前面, 这里通常是文件长度出现的地方. 这些数字是给特殊设备的主次设备编号。 crw-rw-rw- 1 root root 1, 3 Apr 11 2002 null crw------- 1 root root 10, 1 Apr 11 2002 psaux crw------- 1 root root 4, 1 Oct 28 03:04 tty1 crw-rw-rw- 1 root tty 4, 64 Apr 11 2002 tty0 crw-rw---- 1 root uucp 4, 65 Apr 11 2002 ttyS1 crw--w---- 1 vcsa tty 7, 1 Apr 11 2002 vcs1 crw--w---- 1 vcsa tty 7,129 Apr 11 2002 vcsa1 crw-rw-rw- 1 root root 1, 5 Apr 11 2002 zero 主设备号:标识设备对应的驱动程序。一般“一个主设备号对应一个驱动程序”。 主编号标识设备相连的驱动. 例如, /dev/null 和 /dev/zero 都由驱动 1 来管理, 而虚拟控制台和串口终端都由驱动 4 管理; 同样, vcs1 和 vcsa1 设备都由驱动 7 管理. 现代 Linux 内核允许多个驱动共享主编号, 但是你看到的大部分设备仍然按照一个主编号一个驱动的原则来组织. 次设备号:每个驱动程序负责管理它所驱动的几个硬件实例,这些硬件实例则由次设备号来表示。同一驱动下的实例编号,用于确定设备文件所指的设备。 次编号被内核用来决定引用哪个设备. 依据驱动是如何编写的, 可以从内核得到一个设备的直接指针, 或者可以自己使用次编号作为本地设备数组的索引. 不论哪个方法, 内核自己几乎不知道次编号的任何事情, 除了它们指向你的驱动实现的设备. 可通过ls –l “设备文件名”命令查看设备的主次设备号,以及设备的类型。 3. 常见设备的清单: /dev/ttyS0 – 第一个串行口。鼠标通常接在这里。 /dev/ttyS1 – 第二个串行口。你的调制解调器很可能接在这里。 /dev/ttyS2 和 /dev/ttyS3 是第三和第四个串行口(一般不存在,但你的内置调制解调器可以被设置成使用其中之一)。 /dev/modem – 串口调制解调器。通常是一个指向 /dev/ttyS1、/dev/ttyS2 或 /dev/ttyS3 的符号链接,具体取决于你的调制解调器接在那个串行端口。 /dev/lp0 – 接在第一个并行口的打印机。通常你的打印机接在这里。 /dev/lp1 – 接在第二个并行口的打印机(一般不存在)。 /dev/fd0 – 第一个软盘驱动器(一般都有)。 /dev/fd1 – 第二个软盘驱动器。 /dev/hda – 第一个 IDE 硬盘(整个硬盘)。大多数 IBM 兼容 PC 的硬盘是 IDE 设备。 /dev/hdb – 第二个 IDE 硬盘(整个硬盘)。很多计算机中,IDE 光驱接在这里。 /dev/cdrom – 指向相应设备的链接,通常是 /dev/hdc 或 /dev/hdb(CDROM)或/dev/scd0(CD-R/RW)。 /dev/hda1 – 第一个 IDE 硬盘的第一个分区。/dev/hda2 时第一个 IDE 硬盘的第二个分区。不难猜测,/dev/hdd8 将会是第四个IDE硬盘的第八分区。 /dev/tty1 – 第一个字符终端。/dev/tty2 时第二个字符终端,以此类推。 /dev/sda – 第一个 SCSI 硬盘(整个硬盘)。在一台家用计算机中,不太可能有 SCSI 设备(昂贵)。 /dev/sdb – 第二个 SCSI 硬盘(“sdc”是第三个 SCSI 硬盘,以此类推。一个系统中可以有多个 SCSI 硬盘)。 /dev/sda1 – 第一个 SCSI 硬盘的第一个分区。 4. 设备驱动程序简介: 设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件, 应用程序可以象操作普通文件一样对硬件设备进行操作.设备驱动程序是内核的一部分,它完成以下的功能: 1.对设备初始化和释放. 2.把数据从内核传送到硬件和从硬件读取数据. 3.读取应用程序传送给设备文件的数据和回送应用程序请求的数据. 4.检测和处理设备出现的错误. 5. Linux系统设备分类: Linux系统将设备分为三种基本类型:字符设备;块设备;网络设备。 字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实 际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就 调用请求函数来进行实际的I/O操作.块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待. 字符设备 一个字符( char ) 设备是一种可以当作一个字节流来存取的设备( 如同一个文件 ); 一个字符驱动负责实现这种行为. 这样的驱动常常至少实现 open, close, read, 和 write 系统调用. 块设备 如同字符设备, 块设备通过位于 /dev 目录的文件系统结点来存取. 一个块设备(例如一个磁盘)应该是可以驻有一个文件系统的. 在大部分的. Linux, 允许应用程序读写一个块设备象一个字符设备一样 -- 它允许一次传送任意数目的字节. 结果就是块和字符设备的区别仅仅在内核在内部管理数据的方式上, 并且因此在内核/驱动的软件接口上不同 网络设备 任何网络事务都通过一个接口来进行, 网络设备就是一个能够与其他主机交换数据的设备. 通常, 一个接口是一个硬件设备, 但是它也可能是一个纯粹的软件设备, 比如环回接口。一个网络接口负责发送和接收数据报文, 在内核网络子系统的驱动下, 不必知道单个事务是如何映射到实际的被发送的报文上的。 6. Linux内核驱动之一些重要数据结构 大部分驱动程序涉及三个重要的内核数据结构:文件操作file_operations结构体、文件对象file结构体、索引节点inode结构体。 6.1 文件操作file_operations结构体: 结构体file_operations在头文件 linux/fs.h中定义,用来存储驱动提供的对设备进行各种操作的函数的指针。 结构体的每个域都对应着驱动模块用来处理某个被请求的事务的函数的地址。 struct file_operations { struct module *owner; ssize_t(*read) (struct file *, char __user *, size_t, loff_t *); ssize_t(*write) (struct file *, const char __user *, size_t, loff_t *); … } struct module *owner:第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 中定义的宏.
int (*open) (struct inode *, struct file *); 驱动程序提供open 方法,让用户进程使用设备之前,进行一些初始化的工作。例如:检查设备特定的错误;如果第一次打开设备, 则初始化设备。
int (*release) (struct inode *, struct file *); 在文件结构被释放时引用这个操作. 如同 open, release 返回值可以为 NULL.
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 用来从设备中读取数据。非负返回值表示成功读取的直接数。
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 发送数据给设备. 如果 NULL, 把-EINVAL 返回给调用 write 系统调用的程序. 如果非负, 返回值代表成功写的字节数.
loff_t (*llseek) (struct file *, loff_t, int); llseek 方法用作改变文件中的当前读/写位置, 并且新位置(正的)作为返回值. loff_t 参数是一个"long offset", loff_t是在LINUX中定义的长偏移量。
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); ioctl提供发出设备特定命令的方法(例如格式化软盘的一个磁道, 这不是读也不是写). 进行超出简单的数据传输之外的操作,各种硬件控制操作. 6.2文件对象file结构体 struct file, 定义于 , 是设备驱动中第二个最重要的数据结构. 文件结构代表一个打开的文件. (它不特定给设备驱动; 系统中每个打开的文件有一个关联的 struct file 在内核空间). 它由内核在 open 时创建, 并传递给在文件上操作的任何函数, 直到最后的