基于Linux2.6 内核的fps200 指纹采集器
USB 设备驱动开发
黄康莹*
作者简介:黄康莹,(1987-),男,硕士研究生,主要研究方向:通信系统. E-mail: 40 器对当前要采集的行进行充电,充电的上限电压为预设的VDD。在充电的同电,内部信号
图1 芯片结构框图[1]
会激活一组采样和保持电路来存储下这一行充电后的电压值。在第二个阶段,当前行的
45 传感器模块会对一个指定的电流源进行放电操作。放电的速率正比于寄存器中预设的电流大
小,而在整个放电的过程中,内部信号会激活采样和保持电路,这些电路会记录下最终的电
压值。由每一个传感器模块的充电电压值和放电电压值可以得到这个模块电容的大小,在每
一行被采集后,这一行的数据都会最终被数字化。
采集器的敏感度是可以由放电电流和放电时间来调节的。放电电流是由放电电流寄存器
50 (DCR)来控制的。而放电时间则是由放电时间寄存器(DTR)来控制。
1.3 主要资源及配置流程
前面已经介绍过,fps200 具有多种工作模式,由于本文使用的是USB 模式,所以下面
着重介绍USB 相关的配置。
1.3.1 引脚的使用
55 USB 模式下主要使用如下引脚:
DP, DM, EXTINT, XTAL1, XTAL2
其中XTAL1 和XTAL2 必须连接到12MHz 的晶振电路
1.3.2 USB 端点号
端点0 (Endpoint 0)
60 端点0 是一个控制端点,主要用于设备枚举和配置用。可以使用控制传输模式对端点0
进行读和写操作。
端点1(Endpoint 1)
端点1 是块传输操作端点,主要是读取CTRLA 寄存器,这个寄存器中存储了A/D 转换
的结果。除了最后一次GETROW 操作所获取到的数据包有可能小于64 字节外,其余的数
65 据包大小均为64 个字节。
端点2(Endpoint 2)
端点2 是一个中断传输端点,当有中断事件发生时,ISR 中的内容可以通过端点2 传输。
1.3.3 配置过程
初始化配置是保证fps200 能正确工作的重要阶段。在初始化配置的过程中主要需要使
70 用到的寄存器包括:CTRLB, DTR, DCR, PGC 一共4 个。
图2 初始化流程
如图2 所示,fps200 的初始化流程实剥去较为简单,没有太多的寄存器需要配置,只需
75 要将CTRLB 寄存器的第2 位和第0 位设为1,然后等待一定的时间即可。
图3 参数调整
图3 主要显示了如何去调整fps200 指纹采集器的参数。主要是三个寄存器参数对于指
80 纹采集影响较大。DTR 寄存器主要是控制电容的充电时间。DCR 寄存器主要是控制充电电
流的大小。而PGC 寄存器主要控制的是增益大小。
2 USB 体系结构
USB 是通用串行总线的简称,它支持热插拔和多种数据传输模式。USB 采用的是主从
协议,这种协议只允许主机主动发起来客户端的会话。图1-4 是PC 环境下的USB 接口,
85 USB 主控制器作为南桥芯片的一部分与PCI 总线连接在一起,通过北桥芯片与处理器进行
通信。
2.1 总线速率
USB 支持3 种可选速率,最初的USB1.0 接口只支持1.5Mbps 的低速USB 通信方式。
90 图4 PC 环境下的USB 框架
而USB1.0 的下一代标准USB1.1 则支持12Mbps 的工作速率,被称为全速USB,当前
最为常用的USB 接口为USB2.0,最高支持480Mbps 的工作速率,被称为高速USB 接口。
一般如USB 键盘和鼠标都采用低速USB 通信方式,而如U 盘和一些存储设备则采用
95 全速或者是高速USB 接口。
2.2 主机控制器
USB 的主机控制器主要支持以下一些标准:
通用主机控制接口(UHCI):
UHCI 标准主要是由Intel 提出,主要为非PC 系统上以及带有SiS 和Ali 芯片组的PC
100 主板上的USB 芯片提供支持。
开放主机控制接口(OHCI):
OHCI 标准主要由Compaq 和Microsoft 提出。
增强型主机控制接口(EHCI):
EHCI 主要用于USB2.0 设备,它通常会配备一个UHCI 或者是OHCI 来处理低速USB
105 通信。
USB OTG 控制器:
主要被用于嵌入式微处理器上。通过OTG 的支持,每一个通信节点既能担当主机的角
色也能担当客户机的角色
2.3 传输类型
110 USB 设备主要支持4 种数据传输类型:
控制传输:用于传输配置和控制信息
批量传输:用于传输大量的对时间不敏感的数据
中断传输:用于传输少量对时间敏感的数据
同步传输:用于固定比特率的实时数据传输
115 以上提到的四种传输类型,在fps200 指纹采集的驱动程序中实际只使用了两种,一种
是控制传输,本文使用了这种传输方式来配置fps200 的各个寄存器,而另一种是批量传输
方式,指纹采集器所采集到的所有图像数据都是以这种方式发送到PC 机的。
3 USB 设备驱动
Linux 下USB 的驱动程序主要分为USB 主机驱动程序和USB 设备驱动程序,而USB
120 主机驱动程序主要驱动USB 控制器,这些驱动一般在Linux 内核原始中就有提供。而本文
编写的指纹采集器驱动实际是一个USB 设备驱动程序。
3.1 USB 设备驱动整体结构
Linux 实现了几类通用的USB 设备驱动,主要划分为如下几个设备类[2]:
音频设备类,通信设备类,HID 设备类,显示设备类,海量存储设备类,电源设备类,
125 打印设备类,集线器设备类。
USB 设备驱动是指从主机角度观察,怎样访问被插入的USB 设备,而不是指USB 设
备内部本身运行的固件程序。USB 设备内的固件被称为“设备用户固件”,“设备用户固
件”完成设备内部的控制任务,并在USB 传输中对接收到的设备请求做出解释并予以正确
的响应。
130 在Linux 内核中,主要使用usb_driver 结构体来描述一个USB 设备驱动,usb_driver 结
构体的定义如下所示[3]:
struct usb_driver{
const char *name;
int (*probe)(struct usb_interface *intf,
135 const struct usb_device_id *id);
void (*disconnect)(struct usb_interface *intf);
int (*ioctl)(struct usb_interface *intf, unsigned int code,
void *buf);
int (*suspend)(struct usb_interface *intf, pm_message_t message);
140 int (*resume)(struct usb_interface *intf);
...
};
由usb_driver 结构体中定义的函数接口可以看出,实际在编写USB 设备驱动的时候,
实际就是要编写相应功能的函数,然后注册到usb_driver 这个结构体之中。而对应于本文的
145 指纹采集器的驱动,具体的构成如图5 所示:
在编写新的USB 设备驱动程序的时候,主要完成的工作是probe()和disconnect()函数,
即探测和断开函数,它们分别在设备被插入和拔出的时候被调用,用于初始化和释放软硬件
资源。
对usb_driver 的注册和注销主要通过两个函数完成:
150 int usb_register(struct usb_driver *new_driver);
void usb_deregister(struct usb_driver *driver);
图5 USB 驱动整体结构
155 3.2 URB 请求块
usb_driver 结构体中所定义的函数是与USB 总线相关的部分,真正USB 设备驱动的主
体是USB 设备本身所属类型的驱动,如字符设备,tty 设备,块设备和输入设备等。因此
USB 设备驱动包含其作为总线上挂载设备的驱动和本身所属类型的驱动两个部分。
usb_driver 与platform_driver 类似,起到了“牵线”的作用,在probe()里注册相应的字
160 符,tty 设备,而在disconnect()里注销相应的字符,tty 设备。
尽管USB 本身所属设备驱动的结构与其不挂在USB 总线上时完全相同,但是在访问方
式上却发生了很大的变化,与USB 设备通信时不再是I/O 内存和I/O 端口的访问,而贯穿
始终的是称为URB 的USB 请求块。
urb 请求块是USB 设备驱动程序中用来描述与USB 设备通信所用的基本载体和核心数
165 所结构。
USB 设备的每一个端点都处理一个urb 队列,一个urb 的典型生命周期如下:
创建urb 结构体,usb_alloc_urb();
初始化urb 结构体, 有四种方式: 中断方式: usb_fill_int_urb() , 批量方式:
usb_fill_bulk_urb(),控制方式:usb_fill_control_urb(),等时方式:手工初始化iso_urb;
170 提交给USB 核心:usb_submit_urb();
USB 主机控制器处理;
完成本次urb 操作:urb->complete()。
3.3 探测和断开函数
探测函数(probe)主要应该完成如下工作[4]:
175 1. 探测设备的端点地址、缓冲区大小,初始化任何可能用于控制USB 设备的数据结构
2. 把已初始化的数据结构的指针保存在接口设备中
3. 注册USB 设备
断开函数(disconnect)应该完成的工作:
1. 释放所有设备分配的资源
180 2. 设置接口设备的数据指针为NULL
3. 注销USB 设备
图6 Probe 函数的流程图[5]
185 3.4 使用控制传输模式配置寄存器
通过以上分析,下面给出使用控制传输模式配置寄存器的实例:
读取寄存器的函数:
static int fps200_usb_readRegister(struct usb_device *usbdev,
int reg, unsigned char *data){
190 return usb_control_msg(usbdev, /* the device */
usb_rcvctrlpipe(usbdev, 0), /* pipe */
FPS200_USB_READ_REQUEST, /* request */
USB_TYPE_VENDOR | USB_DIR_IN |
USB_RECIP_DEVICE,/* bmRequestType */
195 reg, /* value */
0, /* index */
data,
1, //the length of data
FPS200_USB_TIMEOUT);
200 }
写入寄存器的函数:
static int fps200_usb_writeRegister(struct usb_device *usbdev,
int reg, unsigned char data){
return usb_control_msg(usbdev, /* the device */
usb_sndctrlpipe(205 usbdev, 0), /* pipe */
FPS200_USB_WRITE_REQUEST, /* request */
USB_TYPE_VENDOR | USB_DIR_OUT |
USB_RECIP_DEVICE,/* bmRequestType */
(data << 8) | reg, /* value */
210 0, /* index */
NULL,
0,
FPS200_USB_TIMEOUT);
}
215 4 结论
本文给出了fps200 指纹采集器的USB 设备驱动程序的编写方法。首先介绍了fps200 指
纹采集器的芯片特点以及主要工作原理和配置流程。接着介绍了USB 体系结构,包括总线
速率,主机控制器和传输类型,最后着重介绍了USB 设备驱动程序的编写方法。通过本文
的对Linux 环境下USB 设备驱动的分析,结合fps200 文档中详细讲解的配置流程,本文最
220 终在Linux 2.6 内核下完成了fps200 USB 设备驱动程序的编写。
图7 实验结果
[参考文献] (References)
225 [1] Veridicom. FPS200 Solid2 State Fingerprint Sensor[Z]. Veridicom International, 2005
[2] 毛德操,胡希明.Linux 内核源代码情景分析[M] 毛德操. 浙江:浙江大学出版社, 2003.
[3] 宋宝华,Linux 设备驱动开发详细(2 版)[Z]. 北京:人民邮电出版社,2010.
[4] Venkateswaran 精通Linux 驱动程序开发[Z]. 北京:人民邮电出版社,2009.
[5] 罗苑棠,嵌入式Linux 驱动程序和系统开发实例精讲[Z]. 北京:电子工业出版社,2009
学术论文网Tag:代写硕士论文 代写论文 代写毕业论文 代写毕业设计
|