您的位置:首页 > 运维架构 > Linux

浅谈linux驱动之-字符设备驱动程序

2012-02-21 23:29 357 查看
嵌入式爱好者群 122879839

大概分以下五个知识点:

1.设备号

2.创建设备文件

3.设备注册

4.重要数据结构

5.设备操作

首先我们谈谈设备号,其实设备号分主设备号和次设备号,主设备号用来区别不同的设备,次设备号用来区别同一类设备不同型号设备(打个比方,cs8900和dm9000都是网卡设备,那么他们的主设备号就是一样的,而次设备号的存在就是为了区分哪个是cs8900哪个是dm9000)。

那怎么查看设备号呢,用ls -l命令,现在我们看图说话



接下来我们输入ls -l命令



这里就可以一目了然了,前面的是主设备号,后面的就是次设备号。

那么有朋友问了,设备号用来干嘛的?

这里我画个图



我们这里的字符设备文件和字符设备驱动都对应的一个号,当这个号相同的时候,字符设备文件就和字符设备驱动关联上了。这里用的是一个设备号来建立这个联系。

接下来我们看看在内核当中是如何表述设备号的,其实在linux内核当中,这个主次设备号是有规律的,主次设备号加在一起,实质就是unsigned int 32位整数,它用dev_t来描述。其中高12位是主设备号,低20位是次设备号。一般情况下,我们不会说出现上千个设备的,所有主设备号是够用的,2的12次方是多少?4096,也就是说最多支持4096种类型的设备。

我们是怎样从dev_t分离出主设备号和次设备号的呢?

用MAJOR(dev_t dev)这个宏分离出主设备号,用MINOR(dev_t dev)这个宏分离出次设备号。

linux内核如何给设备分配设备号呢?分两种:静态申请,动态分配。

如何静态申请呢?

首先我们要知道设备号存放在哪里?我们来看下图



然后打开这个文挡



上面描述可能还有点问题,总之你选用的设备号,是前面没有出现过的才行。

然后使用register_chrdev_region这个函数去注册去申请设备号。

int register_chrdev_region(dev_from,unsigned count,const char*name)

from代表你希望使用的设备号是多少?比如我选个500,总之前面没出现过就行。

count表示希望申请使用设备号的数目,比如我们申请了5个,那么系统就会给你留5个号出来,打个比方,500 0,500 1, 500 2, 500 3,500 4.

name是设备名,比如serial。

接下来我们谈谈动态分配,我们常常会担心自己选的设备号前面已经用过了,担心设备号选错引起不必要的麻烦,那么我们现在就采取动态分配设备号的方式,让内核来分配设备号,内核一定比我们清楚哪些设备号是空闲的.我们用alloc_chrdev_region这个函数来分配设备号。这里有个需要注意的,这里动态分配设备号,一定是要在驱动安装之后才能执行的。动态分配int alloc_chrdev_region(dev_t*dev,unsigned baseminor,unsigned count,const char*name),意思就是请求内核分配count个设备号,且次设备号从baseminor开始。(dev是主设备号,baseminor是起始次设备号,count是分配的设备号数目,name是设备名)。

设备号是相当宝贵的,不用的时候请注销掉,void unregister_chrdev_region(dev_t from,unsigned count)

有了设备号之后我们要创建设备文件了,创建设备文件的办法有两种:

1.mknod,命令手工创建

2.自动创建

mknod用法,mknod filename type major minor,这里filename表示设备名,type表示设备类型(比如clock,char啊),major是主设备号,minor是次设备号。

打个比方



在linux字符驱动程序设计中,有三种非常重要的数据结构:

struct file(表示打开的文件,系统每个打开的文件内核都有一个关联的struct file,内核打开文件的时候创建,在文件关闭之后是自动释放)

struct inode(记录文件物理信息,比如文件的位置,比如一个设备文件的设备号是多少,一个文件可以有多个file结构,但只有一个inode)

struct file_operations(一个函数指针的集合,定义能在设备上进行的操作,结构中的成员指向驱动中的函数,这些函数实现一个特别的操作,对于不支持的操作,保存为null)打个比方,我们应用程序需要通过驱动程序来对硬件进行操作,比如我们应用程序发出一个read的调用,那么我们驱动程序凭什么对你发出的read做出反应?那么请看下面的一张图



还是拿read来做例子,应用程序发出read,全凭这张图里函数的转换,驱动程序做出反应,调用memory read。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐