Chinaunix首页 | 论坛 | 博客
  • 博客访问: 297305
  • 博文数量: 69
  • 博客积分: 3093
  • 博客等级: 中校
  • 技术积分: 626
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-17 13:48
文章分类

全部博文(69)

文章存档

2011年(27)

2010年(11)

2009年(31)

分类: LINUX

2009-08-20 18:05:15

linux硬件驱动(usb)

模块:模块用来装载到内核中,用来实现设备驱动程序。

linux对于一个硬件的驱动,使用两种方式加载:
  1.   直接加载到内核代码中,启动内核时就会驱动此硬件设备
  2.   以模块方式加载,编译生成一个.o的文件,当应用程序需要时加载进内核空间运行

   so (通常说的硬件驱动其实就是一个硬件驱动模块及.o文件)

设备文件(设备节点):

设备文件(设备节点)指定(主设备号)&& (次设备号)
主设备号:对应着确定的驱动程序。
(声明设备所使用的驱动程序,设备号相当于硬件驱动程序的一个标识)
次设备号:区分不同属性,不同使用方法,不同位置,不同操作
设备号从/proc/drives中获取,so 先有驱动程序在内核中,才有设备节点在目录中。

SCSI(并口):通常使用的的usb存储设备,是模拟scsi硬盘而进行设计的。

Linux硬件驱动架构:
.o驱动模块文件--(如果需要使用这个驱动程序,首先要加载运行它)-->insmod *.o--(驱动程序根据字符设备类型或块设备类型(鼠标属于字符设备,硬盘属于块设备))向系统注册-->注册成功之后系统返回一个主设备号---(根据主设备号创建一个放置在/dev目录下的设备文件)-->(mknod 用来创建设备文件需要用到设备号这个参数)----->我们访问硬件时,就可以对设备文件通过open,read,write等命令进行,而驱动就会接收到相应的read,write操作而根据自己模块中的相应函数进行。


上层调用api.o 驱动drive.o

与模块相关的一些东西:

1. /lib/modules/2.6.**目录,下面是针对当前内核版本的模块。
2. 查看模块的依赖关系是否正确(depmod设置)
3. 加载模块而不需要知道具体的模块位置(modprobe)
4. 文件/etc/modules.conf文件,当kernel需要时直接去该文件中查找别名加载

modprobe用于加载系统已经通过depmod登记过的模块,insmod一般是针对具体的.o进行文件的加载。
USB骨架程序的设计:
(Usb子系统提供一种方法去注册一个次设备号和file_operations函数指针)
1.  USB驱动的注册和注销(注册时会发送一个消息usb_register)
2.  插入时linux-hotplug自动装载程序MODULE_DEVICE_TABLE(设备节点,设备文件)
3.  驱动程序将调用probe(探测)函数,函数参usb_device结构指针,接口号和接口ID都会被传递到函数中,成功返回一个含有设备驱动程序状态的指针,否则返回NULL
4.  之后调用devfs_register 函数注册
5.  如果设备从usb总线拔掉,设备指针会调用disconnect函数,驱动程序就需要清除那些被分配了的所有私有数据关闭urbs,并且从devfs上注销自己

执行上述之后驱动就已经和设备绑定了,任何用户态程序要操作此设备都可以通过file_operations结构所定义的函数进行了。

首先需要打开设备:
1.  open函数中MODULE_INC_USE_COUNT宏是一个关键,(作用是起到一个计数的作用,有一个用户态程序打开一个设备,计数器就加一,例如,我们以模块方式加入一个驱动,若计数器不为零,就说明仍然有用户程序在使用此驱动,这时候,你就不能通过rmmod命令卸载驱动模块了。)
2.  当open完设备后,read、write函数就可以收、发数据了。
3.  skel的write、和read函数 (他们是完成驱动对读写等操作的响应)
阅读(1821) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~