ms3d_duck
驱动牛犊
驱动牛犊
  • 注册日期2004-04-23
  • 最后登录2005-03-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1327回复:4

大家来讨论:对USB体系运作之我见

楼主#
更多 发布于:2004-05-23 11:49
利用课余时间学USB快一周了,有点小体会,和大家讨论一下,中间肯定有错的,希望高手指出!!

首先在DriverEntry例程中定义一系列
DriverObject->MajorFunction[IRP_MJ_***]=用于执行相应IRP的函数名;
这种对应关系应该都是在DriverEntry例程中定义的吧,要不让操作系统如何知道要调用哪个函数呢。(我不是很确定)当然DriverEntry是个例外,应为她有固定的函数名,所以系统知道到哪里去找她。

在这以后,要让USB器件做出相应动作,只要在应用程序中发送相应IRP就可以了。IRP是应用程序在执行某一API时发送的,如执行ReadFile(...),系统将在内存中生成一个IRP:IRP_MJ_READ,然后在DriverEntry定义的那个函数对应表中寻找相应函数执行。

至此,程序的执行由应用程序跳入到了驱动程序。

前几天一直觉得那些读取器件、管道和端口的状态、描述符的函数没什么用,现在忽然觉得的确有必要,必须在进行读写之前将那些端口的地址保存到内存中的一个区域,以供将来读写数据的时候用,否则的话怎么知道往哪里写呢。

虽然最终的目的是为了获得端点的地址,但由于USB的描述符是那种树形的,所以只有耐着性子一层一层往下读了。

有了那些端点的指针之后,就可以对数据读写了,然后返回给应用程序(如何返回的还不太清楚,请高手指点)

对USB设备的读写包括获取描述符,好像使用的不再是IRP了,而使用的是URB。在驱动程序收到应用程序发送的IRP之后,就要对USB器件执行相应的操作,这个操作好像是通过向USBD发送URB来实现的。URB中包含了操作的信息。

但由于USB驱动不能直接操纵硬件,所以这个URB不能直接送达硬件,必须把她传递给更低一级的驱动对象USBD。
和应用程序向驱动传递信息一样,USB驱动对象向USBD传递消息时
也用的是IRP,因此,必须将要执行的操作(即URB的信息)以约定的方式包含到一个IRP中。这里的约定方式当然不是你我说了算的,微软老大已经约定好了,可以通过调用
IoBuildDeviceIoControlRequest等等一系列宏(Walter Oney说她们是宏) 生成一个IRP,然后通过这么几句话把URB传递过去
nextStack = IoGetNextIrpStackLocation(irp);
nextStack->Parameters.Others.Argument1 = Urb;
在这以后执行
ntStatus = IoCallDriver(DeviceExtension>TopOfStackDeviceObject,irp);
就可以让低层的USBD去为你干活了。至于USBD是如何工作的,现在看来好像是透明的。
(不知这么说对不对)


这里还有两个问题没搞清楚:
读取设备描述符的目的是不是的确像我理解的那样主要为了获得端点地址?

还有一个原则性问题不太清楚:那些端点的地址、设备描述符到底在哪里。是在INF文件中指出,并在初次安装是写入注册表的吗?  还是那些东西都存在于USB器件中,每次运行驱动是都要发送相应URB来获到(如果那样的话得浪费器件上多少个寄存器啊)?


以上都是本菜鸟的个人所见,目前还只是从理论上看了看USB,没做过实际设备,不知以上对USB体系的理解是否正确?望大虾们赐教!!(还有我是学医学工程的,没有相应的软件工程基础,有些术语不很规范,望指出)


在写此文期间,步行者赢了活塞,大快人心。不过之前的森林狼败北湖人,让人有些...
哎,O.K.组合的威力不承认也没办法呀!!......

最新喜欢:

brightfengbright...
arthurcao
驱动小牛
驱动小牛
  • 注册日期2003-10-12
  • 最后登录2012-07-08
  • 粉丝0
  • 关注0
  • 积分92分
  • 威望20点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-05-23 20:54
老兄说的不错,总结的也精彩。
至于端点、管道、设备的描述符的内容是和固件放到一起编译的,生成的最后。HEX文件就是你要下载到USB RAM中的了。
他们的植可以改的。
arthurcao喜欢开源。
ms3d_duck
驱动牛犊
驱动牛犊
  • 注册日期2004-04-23
  • 最后登录2005-03-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-05-23 20:25
是不是说  那些端点、管道、设备的描述符的内容都是存在于USB设备的RAM/ROM/FLASH中的(望能指出具体在哪里),
其内容是用户可以随意修改的吗?还是厂商固化的?


同时更正关于DriverEntry例程的说法:
作为驱动入口的例程不是非得用DriverEntry,也可以用其他名字,只要在Link时指出就可以。(谢谢chen3feng的指点)
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-05-23 19:42
1,读取描述符的主要目的是保存设备的信息,包括你说的保存端点的信息,如端点的个数,端点最大包大小、类型等,这些是为以后的readfile,writefile做准备,因为这些操作要用到端点地址和类型;还有一个目的是方便应用程序查询,因为在设备识别时获得描述符一定会执行,否则枚举失败,也有可能主机应用程序会查询设备的信息,保存起来的话可以随时返回给应用程序。

2,端点地址、设备描述符在设备的固件程序里定义,这些信息在每一次识别时主机都会要求返回,这是usb总线协议规定的。
ms3d_duck
驱动牛犊
驱动牛犊
  • 注册日期2004-04-23
  • 最后登录2005-03-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-05-23 14:39
没人回应??
我的理解是对是错请各位发言啊!!!百家争鸣的论坛才有活力吗!

好歹偶也是花了2个小时写的呢。

我是初学者,用兴趣的话可以加我qq=124208470
游客

返回顶部