您的位置:首页 > 其它

设备驱动简介

2015-06-02 13:45 211 查看
上次已经把led驱动和按键驱动弄到了开发板上并且已经可以运行了,但是只是依葫芦画瓢的照着别人的方法做,对驱动的原理,以及如何编写驱动都不了解,这篇就写一下关于驱动的一些基础知识。

我觉得计算机不管怎么牛逼,如果无法与人交互那就没用,人无法输入命令,计算机也无法把它的运算结果展示出来,那就是白搭。所以要在计算机的外围加上各种各样的硬件,鼠标,显示器,键盘,网卡,声卡,显卡.....。那么操作系统如何来使用这些硬件?靠的就是驱动程序。驱动程序向计算机展示使用这些硬件的方法。相当于在计算机和硬件之间加了一层中间层,好像有这么一句话,所有的问题都可以通过添加中间层来解决(不知道说的对不对)。

linux的一个重要特点就是将所有的设备都当作文件处理,就是设备文件,都放在/dev目录下面,我看了一下,数量挺多。这些文件可以直接用open函数来打开。这就表示想要控制哪个设备只需要打开这个设备文件就行了,但前提是你得要现在系统中注册这个设备。

linux系统的设备分为三类:字符设备,块设备和网络设备。

字符设备通常指像普通文件或字节流一样,以字节为单位顺序读写的设备,如并口设备,虚拟控制台等

块设备通常指一些需要以块为单位随机读写的设备,如IDE硬盘,SCSI硬盘,光驱等。

网络设备通常指通过网络能向其它主机进行数据通信的设备,如网卡等。网络设备不是面向流的,所以不会将网络设备的名字映射到文件系统中。

linux内核中采用可加载的模块化设计,linux设备驱动属于内核的一部分,linux内核的一个模块可以用俩种方式被编译和加载:

1.直接编译进内核,随linux启动时加载

2.编成一个可加载可删除的模块,用命令来加载或删除。

常见的驱动程序是作为内核模块动态加载的。

insmod命令来添加模块,rmmod来删除,lsmod来查看。

/proc文件系统是一个伪文件系统,它是一种内核和内核模块用来向进程发送信息的机制。这个伪文件系统让用户可以和内核内部数据结构进行交互,获取有关系统和进程的游泳信息,在运行时通过改变内核参数来改变设置。

有关proc机制这篇博客写的很详细:http://linux.chinaunix.net/doc/2004-10-05/16.shtml

因为驱动也是以模块的形式加载的,所以来说一下基本的模块由哪些部分组成:

1.模块加载函数(必须)

2.模块卸载函数(必须)

3.模块许可证明(必须)

4.模块参数(可选)

5.模块参数(可选)

6.模块导出符号(可选)

<span style="font-size:18px;"><span style="font-size:18px;">#include <linux/init.h><span>		</span> //初始化
#include <linux/module.h> <span>	</span> //最基本头文件,支持模块动态加载
MODULE_LICENSE("Dual BSD/GPL");  //模块许可证明
static int hello_init(void)<span>	</span>//模块加载函数
{
printk(KERN_ALERT "Hello, World!\n");
return 0;
}

static void hello_exit(void)<span>	</span>//模块卸载函数
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}

module_init(hello_init);<span>	</span>//注册加载函数
module_exit(hello_exit);<span>	</span>//注册卸载函数</span></span>

一个模块大致就是这个样子,突然发现这个上一篇貌似说过了........

下面再说一下linux是如何将一个驱动加载到内核中的,这部分也是最重要的部分:

在linux驱动程序中,涉及三个重要的内核数据结构,分别是file_operation,file和inode。在linux中inode结构用于表示文件,而file结构则表示打开的文件描述符,因为对于单个文件而言可能会有许多个表示打开的文件描述符,因此可能会对应有多个file结构,但他们都指向单个inode结构。此外,每个file结构都与一组函数相关联,这组函数就是通过file_operation来指示的。

也就是当你打开一个设备文件之后,会得到一个file结构,也就是文件的描述符,这个file结构必须有一组相关联的操作,比如说read,write,ioctl等等,这些函数都是在file_operation来指向的,也就是说file_operation中存储着指向这些函数的指针。我们写驱动时实际上主要就是实现file_operation里的这些函数。

这篇文章详细的描述了file_operation:http://www.cnblogs.com/ZJoy/archive/2011/01/09/1931379.html

而struct inode结构提供了关于设备文件/dev/driver(假设设备名为driver)的信息,file结构提供关于被打开的信息,注意一个是代表文件,一个是代表打开的文件。

struct inode包括很重要的二个成员:
dev_t       i_rdev   设备文件的设备号
struct cdev *i_cdev 代表字符设备的数据结构

这样就可以将inode和设备号联系上,也就是和设备联系上。

先写到这里,下一篇介绍一下如何编写一个字符驱动程序。

写的真够烂的,不知道有没有人看............
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设备驱动