设备linux下USB大容量存储设备驱动分析与实现.doc

usb大容量存储设备  时间:2021-01-10  阅读:()

l inux下USB大容量存储设备驱动分析与实现

【摘要】本文介绍了linux USB子系统架构及USB协议重点分析了linux下USB大容量存储设备驱动程序并结合U盘特点对设备驱动程序做了可靠的裁剪 以交叉编译和控制台调试的方式在TQ2440 ARM开发板上成功实现了设备驱动模块的加载与卸载最终达到了U盘热插拔和读写的目的。

【关键词】 USB大容量存储设备设备驱动

USB universal serial bus通用串行总线是一种高速、支持即插即用和热插拔的总线标准 由intel、 microsoft等公司制定适用于多种USB外围设备U盘、 USB键盘鼠标、 USB摄像头等与主机之间的高速数据传输 USB2.0协议规定的最大传输速率可达480Mb/s突破了传统串行总线的带宽限制。

Linux作为一种性能稳定可定制兼容性强的开源操作系统在嵌入式设备中得到了广泛应用且开发者可以方便地获得linux社区提供的强大技术支持从而能够大大降低开发成本。

本文以天嵌公司的TQ2440 ARM开发板为硬件平台 以linux2.6.30为操作系统内核通过串口工具secure CRT使用金士顿U盘作为USB存储设备 的分析并实现了linux下USB大容量存储设备驱动。

1.USB子系统

类似于linuxscsi子系统 USB子系统也采用树形拓扑结构层级关

系因系统功能的不同而不同拓扑模型如图1所示。系统作为主机时拓扑层级为 USB设备驱动、 USB核心、 USB主控制器驱动作为从设备时层级为 Gadget驱动、 Gadget API、 USB设备控制器驱动。本文以linux为主机系统 U盘为从设备 因此只讨论主机侧拓扑结构。

USB设备驱动负责 向USB核心注册设备驱动、管理USB设备的探测与断开、实现与USB核心通信 USB核心提供一系列数据结构宏定义和函数来抽象底层硬件设备为设备驱动和主控器驱动提供特定的接口读取并解析USB设备和配置描述符为USB设备分配地址转发设备驱动数据包配置设备维护设备链表和设备驱动链表维护设备信息 USB主控制器驱动负责与核心层通信、管理主控制器与设备的实际通信。

通常厂商提供主控制器驱动而linux实现了USB核心usb core部分 因此本文将研究USB设备驱动。

2.USB协议

2. 1设备配置接口端点

USB协议用设备device、配置confi-guration、接口interface、端点endpoint来描述设备的全部信息。每个设备有一个或多个配置

configuration 同一时刻只能有一个配置处于活跃状态每个配置有一个或多个接口 interface每个接口都有特定的设备驱动例如USB 音响有音量调节旋钮和扬声器则对应于旋钮驱动和扬声器驱动每个接口有零个或多个端点endpoint端点是通信的末端数据传输以管道

pipe的形式在端点上实现管道具有单向传输性 因此通常要为设备分配多个管道读设备时使用上行管道写设备时使用下行管道。

2. 2传输方式

数据传输有四种方式

控制control传输用于非周期性的可靠传输如USB鼠标键盘等中断interrupt传输用于速率稳定的数据传输批量bulk传输用于大量数据传输对数据传输时间要求不高如U盘、硬盘、软盘等等时isochronous传输用于实时数据传输且对数据传输误码率要求不高如摄像头、扬声器等。

根据传输方式的不同端点分为控制端点、 中断端点、批量端点、等时端点四种端点0缺省为控制端点其它端点需分配设置。管道分为控制管道、 中断管道、批量管道、等时管道。

2. 3传输协议

根据存储介质的不同 USB大容量存储Mass storage设备通常分为两类 scsi设备和floppy设备。传输协议关系如图2所示主机与scsi 设备之间采用Bulk Only方式传输数据设备内部采用scsi命令传输主机与floppy设备之间采用CBI control/bulk/interrupt方式传输数据设备内部采用UFI universal floppy interface协议传输。

3.接口

USB设备每个接口都有特定的设备驱动设备驱动用接口描述符

interface descriptor来描述设备接口属性及通信特征代码清单如下struct usb_interface_descriptor {

接口描述符包含三个重要域 bInterfa-ceClass 、

bInterfaceSubClass 、 bInter-faceProtocol  分别对应于接口类型

cla-ss接口子类型subclass接口协议protocol。

U盘属于Mass Storage类设备所以bInterfaceClass=Mass Storage 即接口类型为Mass Storage U盘在linux下表现为一种scsi块设备对它的操作必须遵守scsi协议规范 因此bInterfaceSubClass=SCSI Transparent即子类型为SCSI Transparent最初的存储设备采用CBI

control/bulk/interrupt传输方式 control端点传输控制块 bulk 端点传输数据 interrupt端点传输状态信息 因此造成了端点资源的极大浪费 随着USB技术的发展 Bulk-Only传输方式得到了普及相比于CBI这种传输方式统一使用bulk端点来传输控制块、数据及状态信息节省了端点资源提高了总线利用率对于U盘bInterfaceProtocol=Bulk Only Transport即接口传输协议为Bulk Only Transport。 4.urb urb usb request block是设备驱动用来描述与设备通信的数据结构载体是主机与USB设备通信的“电波”。urb处理流程如图3所示当scsi host获得一个scsi命令后将其添加到命令链表中设备驱动循环检测scsi命令链表并取出命令将其赋给USB设备的srb scsi request block至此USB设备驱动已获取了一个scsi命令块而在USB子系统中命令的传输载体为urb因此需构建包含scsi命令的urb并将其传递给USB核心层步骤如下

1动态分配并初始化urb usb_alloc_urb  →usb_init_urb  

2运行控制线程

For     {kthread_run usb_stor_control_thread us” usb-storage”

„„}

实际上usb_stor_control_thread是一个死循环线程它负责完成检测urb是否存在→检测urb请求是否超时→检测urb传输方向→检测目标scsi target和逻辑单元号scsi lun→proto_handler  →检测urb传递状态。 proto_handler是一个指向urb传输类型函数的指针实现方式如下

当设备接口子类subclass为US_SC_SCSI即设备表现为scsi块设备时 proto_handler指向的是usb_stor_transparent_scs i_command 在这个函数中又使用了函数指针transport transport指向的具体函数在获取传输方式时就已经指定实现方式如下

当传输方式为US_PR_BULK即Bulk_Only传输时 transport指向usb_stor_Bulk_transport  这个函数负责填充urb并将其传递给USB 核心。 USB核心获得urb控制权后将其传递给指定的主控制器驱动至此实现了urb从设备驱动到主控制器驱动的传输。 当urb传输完成后主控制器驱动将通知设备驱动urb的传输状态。

5.设备驱动程序分析

设备驱动模块的入口和出口分别为module_init  和module_exit

  它们分别调用模块初始化函数usb_stor_init usb_stor_init和卸载函数usb_stor_exit usb_stor_exit实现向USB核心注册驱动和卸载驱动。注册驱动时调用usb_register &usb_storage_driver卸载时

调用usb_deregister &usb_storage_driver。 usb_storage_driver是设备驱动的“心脏”它为设备驱动与USB核心提供了通信接口其中定义了各种驱动操作函数代码清单如下name为模块名。probe对应驱动函数storage_probe   storage_probe  完成

获取接口数据→保存接口数据→分配设备DMA映射缓存→获取不常见设备可裁剪掉→获取传输类型→获取传输协议→设置管道→设置控制发送管道→设置控制接收管道→设置bulk发送管道→设置bulk接收管道→设置中断接收管道→分配初始化并传递urb给核心层→向scsi总线层添加scsi host→创建scsi总线扫描线程→开始scsi线程扫描。 U盘插入后 USB核心调用设备驱动程序的probe函数在总线维护的设备链表中寻找适合该驱动的设备如果找到则将驱动绑定到总线。disconnect对应的驱动函数为usb_storage_disconnect  它负责完成停止scsi扫描→移除scsi host→停止接收新的scsi命令→释放所有的总线和设备资源。 U 盘拔出后 USB 核心调用usb_storage_disconnect  解除驱动与总线的绑定。suspend和resume实现系统待机状态下设备挂起操作它们对应的驱动函数usb_stor_suspend  和usb_stor_resume  依赖于内核电源管理配置项Power Management support。为了达到低耗的效果 Linux对设备电源有严格的管理 当系统待机时设备应处于低功率状态下 因此要对耗电设备执行挂起操作。pre_reset和post_reset负责端口重启后获取接口数据。 id_table

是驱动支持的设备列表 USB设备品种繁多而一个驱动模块只能支持特定的一个或多个设备最多16个设备 因此需要在驱动中建立USB设备表代码实现如下struct usb_device_id usb_storage_usb_ids[]={

{USB_DEVICE USB_MASS_VENDOR_ID USB_MASS_PRODUCT_ID } 

{ } } 

MODULE_DEVICE_TABLE usb skel_table

USB_MASS_VENDOR_IDUSB_MASS_PRODUCT_ID分别为设备厂商id和设备id每个出厂设备的id都不一样驱动利用id来寻找与之匹配的设备。

本文使用KINSTON U盘作为大容量存储设备。设备功耗小待机时无需电源管理支持热插拔不需要重启USB端口。

6.驱动编译与调试

6. 1驱动编译

本文要实现的是在TQ2440开发板上使用U盘 因此要用交叉编译的方式编译驱动模块。在内核主目录下执行make menuconfig命令配置内核在device drivers下勾选USB support选项在USB support下以模块方式添加对USB Mass Storatge设备支持如图4所示然后保存退出。修改内核主目录下的Makefile将编译器改为交叉编译器。在内核根目录下执行make命令编译内核生成zImage.bin内核镜像。将编译好的uboot 镜像、 内核镜像以及文件系统镜像下载到开发板。 再执行make SUBDIR=drivers/usb/modules生成usb-storage.ko驱动模块将其下载到开发板。

6. 2驱动调试

本文采用secure CRT在windows平台上调试。启动系统后在secure CRT中执行insmod usb-storage.ko命令加载USB驱动模块后显示如图5所示。

模块加载成功使用lsmod命令可以看到系统已加载的模块如图6所示。

插入U盘后显示如图7所示。

可以看到主控制器驱动 U盘厂商id产品id制造商 串口号等信息至此整个U盘驱动平台已经搭好使用fdisk-l查看系统磁盘显示如图8所示。

可以看到设备/dev/sda及其分区/dev

/sda1容量4006M使用命令mount-tvfat/dev/sda1/mnt将其挂载到/mnt目录即可查看和读写U盘。

7.结束语

在TQ2440开发板上成功实现了USB大容量存储设备驱动模块的加载和卸载 U盘读写正常支持热插拔。随着信息技术不断发展信息量的增大无疑将对便携式存储设备的容量和数据传输速度提出更高要求 USB 设备驱动程序的设计与优化将成为嵌入式系统开发者的重要课题。

参考文献

[1]杨建华杨宇东陈安胡跃明.基于嵌入式linux的USB驱动设计[J] .福建电脑 2009 4 11-12.

[2]张波张曦煌.基于嵌入式linux的U盘驱动的分析与改进[J] .计

算机工程与设计 2008 29 15 3917-3940.

[3]巍婺张焕强方贵明.基于linux的USB驱动程序实现[J] .计算机应用 2002 8 17-19.

[4]邓飞.USB设备驱动程序设计[J] .湖南科技学院学报 2006 11217-219.

[5]张鹏孙世磊刘瑞北何明聪.LINUX+ARM下的USB驱动开发[J] .计算机工程与科学 2006 28 3 106-133.

[6]梁孔科杨林楠张丽莲.基于S3C2410与Linux的USB驱动的设计[J] .福建电脑 2008 4 2-4.

[7]王平施文灶黄晞江华丽.基于嵌入式ARM9的USB设计与实现[J] .现代电子技术 2009 12 33-35.

[8]赵鹏.基于嵌入式Linux的USB驱动程序的设计与实现[J] .电脑开发与应用 2011 24 6 65-66.

[9]冯韬李广军.嵌入式Linux下的USB2.0海量存储设备驱动设计[J] .福建电脑 2008 7 158-160.

[10]陈明罗映红.一种嵌入式系统USB驱动程序的设计[J] .太原科技 2009 2 78-79.

远程登录VNC无法连接出现

今天有网友提到自己在Linux服务器中安装VNC桌面的时候安装都没有问题,但是在登录远程的时候居然有出现灰色界面,有三行代码提示"Accept clipboard from viewers,Send clipboard to viewers,Send primary selection to viewers"。即便我们重新登录也不行,这个到底如何解决呢?这里找几个可以解决的可能办法,我们多多尝试。...

香港物理服务器 E5-2660v2 16G 500GSSD 增送20G防御 688/月 华纳云

#年终感恩活动#华纳云海外物理机688元/月,续费同价,50M CN2 GIA/100M国际大带宽可选,超800G 防御,不限流华纳云成立于2015年,隶属于香港联合通讯国际有限公司。拥有香港政府颁发的商业登记证明,作为APNIC 和 ARIN 会员单位,现有香港、美国等多个地区数据中心资源,百G丰富带宽接入,坚持为海内外用户提供自研顶级硬件防火墙服务,支持T B级超大防护带宽,单IP防护最大可达...

wordpress通用企业主题 wordpress高级企业自适应主题

wordpress高级企业自适应主题,通用型企业展示平台 + 流行宽屏设计,自适应PC+移动端屏幕设备,完美企业站功能体验+高效的自定义设置平台。一套完美自适应多终端移动屏幕设备的WordPress高级企业自适应主题, 主题设置模块包括:基本设置、首页设置、社会化网络设置、底部设置、SEO设置; 可以自定义设置网站通用功能模块、相关栏目、在线客服及更多网站功能。点击进入:wordpress高级企业...

usb大容量存储设备为你推荐
云主机租用云主机这么火,你知道怎么租用最便宜吗php虚拟主机求php虚拟主机提供商。。。哪里的 好,价格也优惠的美国虚拟空间请问租用美国虚拟空间,需不需要遵守美国的法律?服务器租赁服务器出租是什么意思,来点简单能看得懂的美国vps主机求介绍一款英国的VPS主机?查询ip怎么查看IP地址php虚拟空间我已经有一套网站php代码和模板,并且有自己的虚拟空间和域名,怎么才能把我的代码加入到网站上.网站空间商个人网站备案如何从空间商到备案网站空间商网站备案为什么是空间商备案?求解网站空间商哪有好一点的网站空间商?欢迎友友们给我推荐下,
动态域名 上海vps 中国域名交易中心 mach5 59.99美元 日志分析软件 美国php主机 ubuntu更新源 台湾谷歌网址 免空 php空间购买 中国电信测速网 常州联通宽带 服务器论坛 广东主机托管 nnt 时间同步服务器 建站行业 在线tracert ssd 更多