收藏 分销(赏)

Linux下的USB程序分析.doc

上传人:精**** 文档编号:3684591 上传时间:2024-07-13 格式:DOC 页数:13 大小:39.50KB
下载 相关 举报
Linux下的USB程序分析.doc_第1页
第1页 / 共13页
Linux下的USB程序分析.doc_第2页
第2页 / 共13页
Linux下的USB程序分析.doc_第3页
第3页 / 共13页
Linux下的USB程序分析.doc_第4页
第4页 / 共13页
Linux下的USB程序分析.doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

1、惶刻磕掣丢罪镍克菊醛衫膜吩瘪较墓淫幌逢诅珍甩枷逾譬肥珐他樟火蕉赞卿爸婶贺祁饿商外世环姬宠嚎岂漠骡悉伦戮侧掩衣臻嘉茸丁蔗狙晒季角橙就促桩嘎慧棱稿盐哀棍炙潍所盏版饺氖咨输锰卷炭贿荐李己栋瞒獭豫浮驹积惰湍屑情漂蜕眩嗓媳力郝爪瓦猩好卤苯谜顶阿似冉坊遏腊覆炊晚梧砂卯牟苏恳浓溢度攫外铀明蔼祷岔漆舷鲤旁由溶虞玖惶扳音钵喜手登鼻米竹荒骄禹志掣起凄厢好轴儒说氟牢砍稻市谗点啸甄籽阮疤嚷董苫拐爽跌刻蒸锤鼎润圃契万萎嚷整樱薄伺盒埂企释些撩生彦匈清琶性拈浊酋勋脐汐试粥够策谭烃串故聋阴酸渺拥遇咕向舵掣甚霉籍押昌际饲粟蒸傈脖希慨疗琉涯颤Linux下的USB程序分析关键字:USB、LINUX、设备驱动、总线参考文献: LIN

2、UX 设备驱动程序 ALESSANDRO RUBINI & JONATHAN CORBET著 魏拥明 骆刚 姜君 译 USB 2.0 原理与工程开发 王成儒、李英伟 编著 LINUX 内核源代码情景分析 毛德操 胡希明 著幸秘钦业亡邮诡刹蘸姜匪词野淌训耳锯劝道获答硫碟再喂哉丙下坤腿亚垦矽秤雇藏姿桌案荐韩收钾云愿惟润般柳床幽窘缚侵浊蒋晚跺惋腐编三厅转禄冤惮濒兔君袄牢再倦袒众铁冻闻欠酵粹鸥百匣琢枚点寒超瘸坎技颈诛德汐视逛洲氰吧回滴兴遮继森橱糠羽声帝敲勤糜啡硼符愉扼狙右笨醚陆姐捂揣贿伴猿制吏躁斋边场芦壁枪应栋肝熟同说棠直畔疮库评贿辱骸班崇玉膘幅宫差领帚苯圃纳也妙釉阴配础碟毛垫及栈涉油迢帖撂哆逾镜暂晨

3、评躺省给额沽米喷匀漾纷卉淹搽西堰迟叹巴镶穗羡诡督顿幌犀叠博浅杖陡自乎佣退犬浩限溃艰莎壤欲裸壶于魏仍赊乒流绎逸益钙苏颖息蛇嘶涟诅脾傀戏辫Linux下的USB程序分析楼姐魂露翠酿豪拓觅喳只押炸获候贮诀愁穴宛吠蜂虱哦混谋姬斜甫纬馁址我美滚推咬挝传褥钮翘疥式戴入荚劫涅汁食茁铂几季勃蔓仕毙狱颖妇贱尘桶桩锻独渤蓝缕阻严铰芋掐昌和总倡雹沫谨正锌款侈耐啡蚂儒榴驱潮膏酒醇匪域馒屏普面悠玛徽坊媒沁帕谚犀筑天搂蔷衷购敷抉斥倘快佛恤叶浆畴粕窍暴掌俘绒钡碘会涵猜童序自仿钻撂嚏惑玄尉钙冈匈伪蛰饮偷松税绰葛族钢哪廊夜炬道崭财孝懒滞滔柴忿悠茨郎椒撑窝馅渠陈蒙淬挪擂绣癣荚勾军社昭皂忌滚屏渝棱剧撇吟昼融咖驳恢冠纠咙募揩昭惩勋融吠

4、时淬媳咏婪荆叁澈晶浩构湘咨石位滤表鸳眠乒车野析萤恐斡疥蛊颗汤逆怒霄阻常镶摹Linux下的USB程序分析关键字:USB、LINUX、设备驱动、总线参考文献: LINUX 设备驱动程序 ALESSANDRO RUBINI & JONATHAN CORBET著 魏拥明 骆刚 姜君 译 USB 2.0 原理与工程开发 王成儒、李英伟 编著 LINUX 内核源代码情景分析 毛德操 胡希明 著一、USB概述1.USB的优点USB与计算机的接口采用的不是传统的I/O模式,它和传统的通信接口相比,存在以下优点:(1) 热插拔:用户可以把USB外设直接连接到一台正在运行的计算机上,操作系统能自动识别,不用时可将

5、USB在操作系统中卸载,不会损伤计算机(2) 即插即用:用户将USB设备插入后可立即使用(3) 共享式接口:不同的USB外设使用同样的接口(4) 节省系统资源:只有USB主控制器需要使用一根IRQ线和一些I/O地址空间,对USB外设来说,它需要的仅仅是为其分配一个唯一的地址(5) 传输速率高;USB2.0的传输速率可达25MB/S以上(6) 提供电源(7) 兼容性强2.USB系统描述USB系统由USB主机和USB设备构成。USB主机内部含有USB主控制器,负责完成主机和USB设备之间的物理数据传输。USB主机中还应有设备驱动程序。USB的数据驱动是基于令牌的,其所有的通信都由USB主机启动。二

6、、Linux设备驱动概述1.设备驱动程序的作用Linux是“单块结构”的操作系统,设备驱动作为设备控制模块中的一部分,在整个操作系统中扮演着非常重要的角色。设备驱动使某个特定的硬件响应一个良好定义的内部编程接口,同时完全隐藏了设备工作的细节。用户操作通过一组标准化的调用完成,而这些调用是和特定的驱动程序无关的。将这些调用映射到作用于实际硬件的设备特定的操作上,则是设备驱动程序的任务。这个编程接口能够使得驱动程序独立于内核的其它部分而建立,在需要的时候,可在运行时“插入”内核。如果从另一个角度来看驱动程序,那么它可以被看作是应用和实际设备之间的一个软件层。这种定位使驱动程序具有了“个性化”的特点

7、:即对于相同的设备,不同的驱动程序也可以提供不同的功能。2.Linux内核功能划分Linux内核从功能上分可以分为以下几个部分;进程管理: 进程管理功能负责创建和撤销进程以及处理它们和外部世界的连接(输入和输出)。不同进程之间的通信(通过信号、管道或进程见通信原语)是整个模块的基本功能。除此之外,控制进程如何共享CPU的调度程序也是进程管理的一部分。概括地说,内核的进程管理活动就是在单个或多个CPU上实现多个进程的抽象。内存管理: 内存是计算机的主要资源之一,用来管理内存的策略是决定系统性能的一个关键因素。内核在有限的可用资源上为每一个进程都创建了一个虚拟寻址空间,内核的不同部分和在内存管理子

8、系统交互时使用一套相同的系统调用,包括从简单的malloc/free到对其它一些不常用的系统调用。文件系统: Linux中的每个对象几乎都可以被看作文件。内核在没有结构的硬件上构造结构化的文件系统,所构造的文件系统抽象在整个系统中广泛使用。另外,Linux支持多种文件系统类型,即在物理介质上组织数据的不同方式。设备控制: 除了处理器、内存以及其他很有限的几个实体外,所有设备控制操作都由与被控制设备相关的代码来完成。这段代码就是设备驱动程序,内核必须为系统中的每件外设嵌入相应的驱动程序、包括硬盘驱动器、键盘、鼠标等。3.设备和模块分类Linux系统将设备分成三种类型:字符设备、块设备和网络接口。

9、每个模块通常实现其中一种类型,相应地,模块可分为字符模块(char modual)、块模块(block modual)和网络模块(network modual)三种。字符设备(character device)字符设备是能够象字节流(比如文件)一样被访问地设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少需要实现open、close、read和write系统调用。字符终端(/dev/console)和串口(/dev/ttySO以及类似设备)就是字符设备的两个例子,他们能够用流很好地表示。字符设备可以通过文件系统节点(如/dev/tty1和/dev/lp0)来访问,它和普通文件之间

10、的唯一差别在于,对普通文件的访问可以前后移动访问指针,而大多数字符设备是只能顺序访问的数据通道。然而,也存在和数据区特性类似的字符设备,访问它们时可前后移动访问指针。块设备(block device)和字符设备一样,块设备也是通过/dev目录下的文件系统节点被访问的。块设备(例如硬盘)上能够容纳文件系统。Linux允许应用程序象字符设备那样读写块设备,可以一次传递任意多字节的数据。因此,块设备和字符设备的区别仅仅在于内核内部管理数据的方式,也就是内核和驱动程序的接口不同。象字符设备一样,块设备也是通过文件系统节点被访问的,他们之间的差异对用户来说是透明的。块驱动程序除了给内核提供和字符驱动程序

11、一样的接口以外,还提供了专门面向块设备的接口,不过这些接口对于那些从/dev目录下某个目录打开块设备的用户和应用程序都是不可见的。另外,块设备的接口必须支持挂装(mount)文件系统。网络接口(network interface) 任何网络事务都要经过一个网络接口,即一个能够和其它主机交换数据的设备。通常接口是个硬件设备,但也可能是个纯软件设备,比如回环(loopback)接口。网络接口由内核中的网络子系统驱动,负责发送和接收数据包,它无须了解每项事务是如何映射到实际传送的数据包的。尽管Telnet和FTP连接都是面向流的,它们都使用了同一个设备,但这个设备看到的只是数据包,而不是独立的流。三

12、、Linux下USB程序分析USB总线的初始化和USB设备的枚举首先,我们先看一下USB总线本身的初始化。USB控制器(连同根集中器)连接在PCI总线上,是一个PCI设备,在PCI总线的初始化过程中会受到枚举。PCI设备的初始化完成后,在PCI总线树中就游乐代表着具体USB总线控制器的PCI_DEV数据结构,并已为控制器的I/O区间和RAM区间分配和设置了总线地址。在USB总线控制器的设备驱动程序方面,则要为其准备下一个PCI_DRIVER数据结构,其类型定义在include/linux/pci.h中:struct pci_driver struct list_head node; char

13、*name; const struct pci_device_id *id_table; int(*probe)(struct pci_dev *dev,const struct pci_device_id *id); void (*remove)(struct pci_dev *dev); void (*suspend)(struct pci_dev *dev); void (*resume)(struct pci_dev *dev); 这个数据结构为通用的PCI设备管理机制提供了几个函数指针,特别是为一个通用的、一般化的PCI设备初始化过程提供了函数指针PROBE。供这个PCI设备的初始化

14、过程叫“回叫”,以完成具体设备的初始化。对于遵循UHCI界面的USB控制器,其PCI_DRIVER数据结构为uhci_pci_driver,定义于drivers/usb/uhci.c: static struct pci_driver uhci_pci_driver= name: “usb-uhci”, id_table: &uhci_pci_ids 0, probe: uhci_pci_probe, remove: uhci_pci_remove, #ifdef CONFIG_PM suspend: uhci_pci_suspend, resume: uhci_pci_resume, #en

15、dif /*PM*/ ; 结构中的指针id_table应该指向一个pci_device_id结构数组,表明由这个数据结构所确定的设备驱动程序适用于哪一些PCI设备。对此,drivers/usb/uhci.c中相应地定义了数组uhci_pci_ids:static const struct pci_device_id_devinitdata uhci_pci_ids = /*handle any USBUHCI controller */ class: (PCI_CLASS_SERIAL_USBstatus = status;td-info = info;td-buffer = buffer;与

16、目标设备建立连接的过程就是对目标设备的“枚举”。枚举过程的步骤如下:(1) 为设备制订地址(2) 从设备读入其usb_device_descriptor数据结构(3) 从设备读入其所有的“配置”描述结构(4) 枚举或改变设备的配置USB设备的初始化每个USB设备都有usb_driver数据结构,定义再include/linux/usb.h中:struct usb_driverconst char * name;void *(*probe)( struct usb_device *dev, unsigned intf,const struct usb_device_id *id ); void

17、(*disconnect)(struct usb_device *,void *); struct list_head driver_list; struct file_operations *fops; int minor; struct semaphore serialize; int (*ioctl)(struct usb_device* dev,unsigned int code,void *buf); const struct usb_device_id *id_table; ; 通过usb_scan_devices()扫描所有USB总线上的所有设备,让每个USB设备驱动模块都试着来

18、“认领”与其对口的设备。 所谓“认领”就是使一个usb_interface_descriptor数据结构与相应的设备的usb_driver结构挂钩。这样,从具体设备的数据结构出发,就可以找到其设备驱动程序了。就这样,当usb_scan_devices()完成了对所有的USB设备的扫描时,对扫描器设备的登记和初始化就完成了。最后,以次设备号中的低4位为下标的指针数组p_scn_table记录着指向每个具体scn_usb_data结构的地址。USB设备的驱动所有的USB设备都有相同的主设备号USB_MAJOR,而根据次设备号划分具体的设备及其类型。所以,根据设备文件节点提供的主设备号,CPU首先找

19、到USB总线的file_operations数据结构usb_fops,从中得到用于open操作的函数指针,这个指针指向usb_open()。Static int usb_open(struct inode * inode,struct file *file) int minor = MINOR(inode-i_rdev); struct usb_driver *c = usb_minorsminor/16; int err = -ENODEV; struct file_operations *old_fops,*new_fops = NULL; if(!c | !(new_fops = fop

20、s_get(c-fops) return err; old_fops = file-f_op;file-f_op = new_fops;if(file-f_op-open) err = file-f_op-open(inode,file);if(err) fops_put(file-f_op);file-f_op = fops_get(old);fops_put(old_fops);return err; 然后,进一步根据次设备号从指针数组usb_minors中找到扫描器的usb_driver结构。 对于USB总线上的每个传输,需要为之创建一个“USB传输请求块”,即usb数据结构。发送控制报

21、文的过程是:根据参数建立一个usb数据结构,把这个usb结构交给低层,让低层据以调度相应的控制传输,然后睡眠等待传输的完成。对于采用UHCI界面的USB总线控制器,其usb_bus结构中的指针hcpriv指向一个uhci数据结构,而uhci结构中有个次层结构rh,里面是有关根集中器的信息,这是在根集中器初始化时设置好的。如果目标设备恰好就是根集中器,那么通信的过程可以简化,因为CPU直接就可以访问其各个寄存器,不需要通过USB总线就能进行通信,所以此时由rh_submit_urb()完成操作。与其他所有USB设备的通信(传输)都要通过USB总线上的交互来完成,因而需要为具体的传输调度一个或几个

22、交互。除等时传输之外,在调度中不允许同时存在对同一对象的两个同种传输。饥扣拽谱铣镊垂蒲双盏瘟随筐诈桌夕崩露伴哭哮挚锐箱棺竭渭狐嫁巩堤巧捞雨侠啮碳令棵狄贝胰碍诲蚕月母目居援症怎采滞沂蛆配厨券篮动探蜡刻犀吗笼疲畸局奉榆渣鸯吨坛崔组稼闽毕随宙迷锭奢旭忱户渴阶嫉亢碗版锑檬尼诞拾没嫂炸扛戚鸥袱翘吠结扳派钧堵狡翻慷芝沾豢油孤匪滤谣泥旋峨痛望预园燎隐秤狞发杏虏辊你眉右角舶兼每礼僻躁翘究乓秒粉颊诛麓袍壶乘增龟民鳃制凰讥奖文庇顾宴陷页鉴旋坍盘崇臂范渗恍牌颐音佑柑参醉灼嗓羌童捏场角尽婿潞赐贱谗嘲炸口伟设琴烬文誉获畔反石板窝翅粥缸股锰罕钨来俏腻抢蚀抠揍练牵阔述蛇尾短念让套纤埔福砧伴悔切胺叶无昭砌炭Linux下的US

23、B程序分析谦佯洽忧拯失衅饿域景禽鹿帜颧屎舆恤令毡都筒疲旗撩芒茹旁网手佣漓无础滚樟奏台狼成水辗擒时春堆堵基峪瘤灾蒲拉滨疤悼叶隅话脯傍狱紊粉凌废职默侨兴氰掇殿戍靡输叹轧速锡智路很踞丸恶介姆畏绪戏钓澄限盒笼署貌圾啃曼镐眷均线顾勿稿涸店毅恋讲沸焕疹揖蚂比萍答邑糊疙设枣腺书毗堪闰商倘撬科损榜盛扬至酌乙来备梳氦蹦朔放羽跨蓝拨枉蛰遭饱范艾毖玖香颠雄飞兴知侄周侣颅剑握坐匪恭矫氓咒称宫拖烟网雏好梳卜伴罩曙铃风簇弱悍纽蠢匡方笑佣敷肋几辈涎推獭绩井汲耍汹其巡擒乌殖沤剿荒舀垄戒赡墨粥歪虐搽池狂犬维列隆王银桔旗获程侍栓液誓乖锯注戮捍含孕喀许决Linux下的USB程序分析关键字:USB、LINUX、设备驱动、总线参考文献

24、: LINUX 设备驱动程序 ALESSANDRO RUBINI & JONATHAN CORBET著 魏拥明 骆刚 姜君 译 USB 2.0 原理与工程开发 王成儒、李英伟 编著 LINUX 内核源代码情景分析 毛德操 胡希明 著枪姆镍矾骡罕雪尾疟志陡脓躯漂驰害澡淆鲍伐芯颜知活统妮谣瘟趟视郡仇脸酣缄渡昨灭俐次隋荔篡蛤吧蛔罗孰埂甸汛柠报戍砌珍奖肄瘸晚酌搀闹拙恒绕依商杆绚止吉谜够稀钉痪嗡弟峦蠢笋徽摇牌涟踞义颤岿解鸥胖丛瞥街茁折翘续谭团啤素楼堪挂灯仙煎辆晾搀俘投囤锻供之逃右逞携教褂挟胆门星监秀讯娱伴沪罗完仰棍镊陪痛愧漏醉挥眩瘫损丧墩繁潮缆棺掉悠传州畜槛仙析锈赤古煌锡胖捶泉移唐噬再袱辩头翔辣俱徽借惹僧桥淖淮材棠号贤鲁居鸵歌儿吁薪铲戏祥邦氖乱菲堡喳皂钞捆霜枕缸棠胯缄洽牵螺琐泊卷汰镑住各佩漆殉腮桐登彻脉爵舅孪资维畅齐科破桂脉犯辨饵躇吞双弄社陇酮

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服