300 likes | 529 Views
USB 设备驱动开发. USB device developer. 课程目标. USB 简介 Linux USB 信息查看和使用 Linux USB 驱动程序开发 USB 设备驱动的移植. USB 简介. USB 是英文 “ Universal Serial Bus ” 的缩写,意为 “ 通用串行总线 ” 。是由 Compaq( 康柏 ) 、 DEC 、 IBM 、 Intel 、 NEC 、微软以及 Northern Telecom (北方电讯)等公司于 1994 年 11 月共同提出的 .
E N D
USB设备驱动开发 USB device developer
课程目标 • USB简介 • Linux USB信息查看和使用 • Linux USB驱动程序开发 • USB设备驱动的移植
USB简介 • USB是英文“Universal Serial Bus”的缩写,意为“通用串行总线”。是由Compaq(康柏)、DEC、IBM、Intel、NEC、微软以及Northern Telecom(北方电讯)等公司于1994年11月共同提出的. • USB使用一个4针插头作为标准插头,并通过这个标准接头,采用菊花瓣形式把所有外设连接起来,它采用串行方式传输数据,目前最大数据传输率为12Mbps, 支持多数据流和多个设备并行操作,允许外设热插拔。 • 目前USB接口虽然只发展了2代(USB1.0/1.1,USB2.0),但是USB综合了一个多平台标准的所有优点 -- 包括降低成本,增加兼容性,可连接大量的外部设备,融合先进的功能和品质。使其逐步成为PC接口标准,进入了高速发展期。 • SBC2410板可以接受U盘,USB键盘,USB摄像头,USB网卡.
USB的优点(1) • USB为所有的USB外设提供了单一的、易于操作的标准的连接类型。这样一来就简化了USB外设的设计,同时也简化了用户在判断哪个插头对应哪个插槽时的任务,实现了单一的数据通用接口。 • USB排除了各个设备象鼠标、调制解调器、键盘和打印机设备对去系统资源的需求,因而减少了硬件的复杂性和对端口的占用,整个的USB的系统只有一个端口和一个中断,节省了系统资源。 可以热插拔 • USB支持热插拔(hotplug),也就是说在不关PC的情况下可以安全的插上和断开USB设备,动态的加载驱动程序。其他普通的外围连接标准,如SCSI设备等必须在关掉主机的情况下才能增加或移走外围设备。不占用系统中断 • USB支持PNP。当插入USB设备的时候,计算机系统检测该外设并且通过自动的加载相关的驱动程序来对该设备进行配置,并使其正常工作。
USB的优点(2) • USB在设备供电方面提供了灵活性。USB直接连接到Hub或者是连接到Host的设备可以通过USB电缆供电,也可以通过电池或者其它的电力设备来供电,或使用两种供电方式的组合.并且支持节约能源的挂机和唤醒模式。 如手机供电,USB风扇,USB冰箱就是利用工作原理 • 速度快。USB支持三种设备传输速率:1.5 Mb/s(低速设备)、12 Mb/s(中速设备)和480 Mb/s(高速设备)。 • 连接灵活。一个USB口理论上可以连接127个USB设备。连接的方式也十分灵活,既可以使用 串行连接,也可以使用集线器Hub,把多个设备连接在一起,再同PC机的USB口相接。
USB设备 • 一个USB系统包含三类硬件设备: USB主机(USB HOST)、 USB设备(USB DEVICE)、USB集线器(USB HUB)。 • USB技术规范将使用USB进行数据传输的双方划分为两种角色——Host和Slave • 并且规定,数据传输只能发生在Host和Slave之间 • 绝大多数Host功能角色被集成在各种类型的PC机上,如笔记本电脑、台式机、Mac机及服务器等 • 而各种各样的基本USB的移动设备都集成了USB Slave功能角色,例如U盘、带USB接口的数码相机等 • 因此两台HOST之间不能直接通过USB传送数据的. • S3C2410同时集成了USB Host和Slave功能, • USB OTG规范 • 这样划分HOST,Slave在某一些场合并不太方便.如一台数码相机本身只能做Slave设备,但如果直接驱动普通USB打印机,则办不到,因为都同为Slave设备 • USB OTG规范是对USB 2.0的补充,根据规范.一个USB OTG接口可以同具备HOST,Slave功能,这个规范正在发展中,并未大规模普及.
USB 的总线拓扑 • USB总线最多可支持127个USB外设连接到计算机系统。USB的拓扑是树形结构,有1个USB根集线器(root hub),下面还可有若干集线器。1个集线器下面可接若干USB接口。
USB Host 控制器 • 一个 USB 系统仅可以有一个主机,而为 USB 器件连接主机系统提供主机接口的部件被称为 USB 主机控制器。 USB 主机控制器是一个由硬件、软件和固件( Firmware )组成的复合体。 • 目前USB HOST控制器有三大类 • “OHCI”驱动程序用来为非 PC 系统上的(以及带有 SiS 和 ALi 芯片组的 PC 主板上的)USB 芯片提供支持。 • “UHCI”驱动程序用来为大多数其它 PC 主板(包括 Intel 和 Via)上的 USB 实现提供支持 • 。“EHCI”驱动程序设计成为实现新的高速 USB 2.0 协议的芯片提供支持。包含了OHCI,UHCI. • SBC2410采用OHCI兼容的USB1.1 协议 控制器
USB发展动向 • PoweredUSB • 根据USB规范,USB总线可为每个连接的外设提供+5 V/500 mA的电源,对于很多小功率的外设已能满足要求,但是当外设需要超过500mA电流时,就需要外接电源。这不符合“即插即用”的构思。PoweredUSB为解决这一个问题被提出 • Exterme USB 超远程USB传输 • USB规范规定了USB总线的连线长度最大为5m,使用集线器来扩展,也只能级联5级,即最大为30m。这限制了USB在数据采集、设备监控等方面的应用。Icron公司开发了Exterme USB技术,可以将连线距离扩展到500m~2000m。 • 基于超宽带技术(UWB) • USB正在逐步进入无线传输领域。Cypress公司推出的WirelessUSB,实现了10 m的通信距离,可在2.4GHz ISM频段下工作。以Intel公司为首的7家技术重量级公司发起组成了无线USB组织,旨在开发一种基于超宽带技术(UWB)的无线USB协议 ,UWB是近距的无线高速传输的代表,用于取代红外,蓝牙等低速无线传输技术.
Linux 对USB的支持(1) • 要启用 Linux USB 支持,首先进入“USB support”节并启用“Support for USB”选项(对应模块为usbcore.o)。 • USB支持三种USB控制器 • “EHCI”(对应模块为ehci-hcd.o)、 • “UHCI”(对应模块为usb-uhci.o)、 • “UHCI (alternate driver)”和“OHCI”(对应模块为usb-ohci.o)。 • Linux USB 驱动程序有三种不同的 USB 主控制器选项是因为在主板和 PCI 卡上有三种不同类型的 USB 芯片。“EHCI”驱动程序设计成为实现新的高速 USB 2.0 协议的芯片提供支持。“OHCI”驱动程序用来为非 PC 系统上的(以及带有 SiS 和 ALi 芯片组的 PC 主板上的)USB 芯片提供支持。“UHCI”驱动程序用来为大多数其它 PC 主板(包括 Intel 和 Via)上的 USB 实现提供支持。
Linux 对USB的支持(2) • 启用了“USB support”和适当的“?HCI”USB 主控制器驱动程序后,使 USB 启动并运行只需再进行几个步骤。 • 1.启用“Preliminary USB device filesystem”, • 这是是usbdevfs支持,即在/proc/bus/usb下示设备信息 • 2.然后确保启用所有特定于将与 Linux 一起使用的实际 USB 外围设备的驱动程序。 • 如SBC2410缺省启动USB Mass Storage supprot 即,U盘支持,和USB打印机的支持.
查看USB信息 • 查看已经安装设备 cat /proc/bus/usb/devices • 查看已安装驱动 cat /proc/bus/usb/drives
USB HID • 在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等。 • USB报告描述符(Report Descriptor)是HID设备中的一个描述符,它是比较复杂的一个描述符。
USB 驱动结构 • USB 驱动位于不同的内核子系统(块, 网络, 字符, 等等)和硬件控制器之间. USB 核心提供了一个接口给 USB 驱动用来存取和控制 USB 硬件, 而不必担心出现在系统中的不同的 USB 硬件控制器.
USB 设备描述(1) • 一个USB设备包含配置(config), 接口(interface), 和端点(endpoint), • 端点(endpoint) • USB 通讯的最基本形式是通过某些称为 端点 的. 一个 USB 端点只能在一个方向承载数据, 或者从主机到设备(称为输出端点)或者从设备到主机(称为输入端点). 端点可看作一个单向的管道. • 一个 USB 端点可是 4 种不同类型的一种, 它来描述数据如何被传送 • USB 端点在内核中使用结构 struct usb_host_endpoint 来描述. 这个结构包含真实的端点信息在另一个结构中, 称为 struct usb_endpoint_descriptor.
USB 设备描述(2) • Endpoint 类型 • CONTROL • 控制端点被用来允许对 USB 设备的不同部分存取. 通常用作配置设备, 获取关于设备的信息, 发送命令到设备, 或者获取关于设备的状态报告. 这些端点在尺寸上常常较小. 每个 USB 设备有一个控制端点称为"端点 0", 被 USB 核用来在插入时配置设备. 这些传送由 USB 协议保证来总有足够的带宽使它到达设备. • INTERRUPT • 中断端点传送小量的数据, 以固定的速率在每次 USB 主请求设备数据时. 这些端点对 USB 键盘和鼠标来说是主要的传送方法. 它们还用来传送数据到 USB 设备来控制设备, 但通常不用来传送大量数据. 这些传送由 USB 协议保证来总有足够的带宽使它到达设备. • BULK • 块端点传送大量的数据. 这些端点常常比中断端点大(它们一次可持有更多的字符). 它们是普遍的, 对于需要传送不能有任何数据丢失的数据. 这些传送不被 USB 协议保证来一直使它在特定时间范围内完成. 如果总线上没有足够的空间来发送整个 BULK 报文, 它被分为多次传送到或者从设备. 这些端点普遍在打印机, 存储器, 和网络设备上. • ISOCHRONOUS • 同步端点也传送大量数据, 但是这个数据常常不被保证它完成. 这些端点用在可以处理数据丢失的设备中, 并且更多依赖于保持持续的数据流. 实时数据收集, 例如音频和视频设备, 一直都使用这些端点.
USB 设备描述(2) • 接口 (Interface) • USB 端点被绑在接口中. USB 接口只处理一类 USB 逻辑连接, 例如一个鼠标, 一个键盘, 或者一个音频流. 一些 USB 设备有多个接口, 例如一个 USB 扬声器可能有 2 个接口: 一个 USB 键盘给按钮和一个 USB 音频流. 因为一个 USB 接口表示基本的功能, 每个 USB 驱动控制一个接口; 因此, 对扬声器的例子, Linux 需要 2 个不同的驱动给一个硬件设备. • USB 接口在内核中使用 struct usb_interface 结构来描述. 这个结构是 USB 核传递给 USB 驱动的并且是 USB 驱动接下来负责控制的.
USB 设备描述(2) • 配置数据(config) • USB 接口是自己被捆绑到配置的. 一个 USB 设备可有多个配置并且可能在它们之间转换以便改变设备的状态 • 通常一个USB设备只有一个配置. • 整个USB设备由struct usb_device 来表示
USB 的 Urbs • linux 内核中的 USB 代码和所有的 USB 设备通讯使用称为 urb 的东西( USB request block). 这个请求块用 struct urb 结构描述并且可在 include/linux/usb.h 中找到. • 一个 urb 用来发送或接受数据到或者从一个特定 USB 设备上的特定的 USB 端点, 以一种异步的方式. 它用起来非常象一个 kiocb 结构被用在文件系统异步 I/O 代码, 或者如同一个 struct skbuff 用在网络代码中. 一个 USB 设备驱动可能分配许多 urb 给一个端点或者可能重用单个 urb 给多个不同的端点, 根据驱动的需要. 设备中的每个端点都处理一个 urb 队列, 以至于多个 urb 可被发送到相同的端点, 在队列清空之前. 一个 urb 的典型生命循环如下: • 被一个 USB 设备驱动创建. • 安排给一个特定 USB 设备的特定端点. • 提交给 USB 核心, 被 USB 设备驱动. • 提交给特定设备的被 USB 核心指定的 USB 主机控制器驱动, . • 被 USB 主机控制器处理, 它做一个 USB 传送到设备. • 当 urb 完成, USB 主机控制器驱动通知 USB 设备驱动.
USB驱动框架 • 在Linux kernel源码目录中driver/usb/usb-skeleton.c为我们提供了一个最基础的USB驱动程序。我们称为USB骨架。通过它我们仅需要修改极少的部分,就可以完成一个USB设备的驱动。 • Linux USB 驱动程序需要做的第一件事情就是在Linux USB 子系统里注册,并提供一些相关信息,例如这个驱动程序支持那种设备,当被支持的设备从系统插入或拔出时,会有哪些动作。所有这些信息都传送到USB 子系统中,
USB驱动框架 • 在usb框架驱动程序中是这样来表示注册信息的: static struct usb_driver skel_driver = { name: "skeleton", probe: skel_probe, disconnect: skel_disconnect, fops: &skel_fops, minor: USB_SKEL_MINOR_BASE, id_table: skel_table, };
USB驱动的注册和注销 • Usb驱动程序在注册时会发送一个命令给usb_register,通常在驱动程序的初始化函数里。 • 当要从系统卸载驱动程序时,需要注销usb子系统。即需要usb_unregister 函数处理: static void __exit usb_skel_exit(void) { /* deregister this driver with the USB subsystem */ usb_deregister(&skel_driver); } module_exit(usb_skel_exit);
插入USB的处理 • 当usb设备插入时,为了使linux-hotplug(Linux中PCI、USB等设备热插拔支持)系统自动装载驱动程序,你需要创建一个MODULE_DEVICE_TABLE。 /* table of devices that work with this driver */ static struct usb_device_id skel_table [] = { { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, skel_table); • USB_DEVICE宏利用厂商ID和产品ID为我们提供了一个设备的唯一标识。当系统插入一个ID匹配的USB设备到USB总线时,驱动会在USB core中注册。驱动程序中probe 函数也就会被调用。usb_device 结构指针、接口号和接口ID都会被传递到函数中。 • static void * skel_probe(struct usb_device *dev, • unsigned int ifnum, const struct usb_device_id *id)
注册devfs • 在骨架驱动程序里,最后一点是我们要注册devfs。我们创建一个缓冲用来保存那些被发送给usb设备的数据和那些从设备上接受的数据,同时USB urb 被初始化,并且我们在devfs子系统中注册设备,允许devfs用户访问我们的设备。注册过程如下: • /* initialize the devfs node for this device • and register it */ • sprintf(name, "skel%d", skel->minor); • skel->devfs = devfs_register • (usb_devfs_handle, name, • DEVFS_FL_DEFAULT, USB_MAJOR, • USB_SKEL_MINOR_BASE + skel->minor, • S_IFCHR | S_IRUSR | S_IWUSR | • S_IRGRP | S_IWGRP | S_IROTH, • &skel_fops, NULL);
拨出USB设备处理 • 当然最后,如果设备从usb总线拔掉,设备指针会调用disconnect 函数。驱动程序就需要清除那些被分配了的所有私有数据、关闭urbs,并且从devfs上注销掉自己。 • /* remove our devfs node */ • devfs_unregister(skel->devfs);
USB设备的读写 • write、和read函数 • 他们是完成驱动对读写等操作的响应。 • 在skel_write中,一个FILL_BULK_URB函数,就完成了urb 系统callbak和我们自己的skel_write_bulk_callback之间的联系。注意skel_write_bulk_callback是中断方式,所以要注意时间不能太久,本程序中它就只是报告一些urb的状态等。 • read 函数与write 函数稍有不同在于:程序并没有用urb 将数据从设备传送到驱动程序,而是我们用usb_bulk_msg 函数代替,这个函数能够不需要创建urbs 和操作urb函数的情况下,来发送数据给设备,或者从设备来接收数据。我们调用usb_bulk_msg函数并传提一个存储空间,用来缓冲和放置驱动收到的数据,若没有收到数据,就失败并返回一个错误信息。 • usb_bulk_msg函数 • 当对usb设备进行一次读或者写时,usb_bulk_msg 函数是非常有用的; 然而, 当你需要连续地对设备进行读/写时,建议你建立一个自己的urbs,同时将urbs 提交给usb子系统。
谢谢,请提问 在疯狂的时代把握未来