flycat0101
驱动小牛
驱动小牛
  • 注册日期2002-06-24
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望22点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1542回复:7

(90分请教)usb host设置地址超时的问题

楼主#
更多 发布于:2003-12-05 14:45
嵌入式系统上是arm9+usb ohci控制器(这个集成在arm一起),跑linux2.4.14系统。遵循usb ohci协议。
将PC机的linux系统下usb-ohci驱动移植到这个嵌入式系统中,ohci的各个寄存器都写入初始化好了。插入usb设备时能够检测到设备(不过会出现两次,不知道这是什么原因?),可是在设置usb设备地址(set_address)时总是超时。我用示波器看过,好像是有数据发出了,因为有变化的波形。
如果正确数据发出的话(我的usb设备是好的),那么就会返回一个状态,而此时我的ohci没有产生“Write done head”中断,就说明ohci根本没有接收到这个状态(不管是正确与否的状态都应该产生这个中断啊,从而进行TD处理),ED中的HeadP指针也是没有改变。请问一下会不会是发出的数据根本就不正确啊?从而导致usb设备不知道如何处理(从而没有处理)?
如果正确的发出了数据,那么usb 设备一定会返回一个状态,此时没有产生中断,是否表明ohci接收数据有问题?硬件上不应该出现问题,那么就是软件设置的问题了,请问我该怎么处理呢?
我跟踪了set_address命令,发现在ED队列中产生了两个TD,但是本来在ED队列中就有一个TD(HeadP和TailP都指向它),所以总共有3个TD,setup命令数据在第一个TD中,最后一个TD什么事情都不作,仅仅是其NextTD为0。我从ohci协议中得知,当ED的HeadP指针和TailP指针指向同一个TD时就认为已经处理完所有TD了。我想如果在set_address命令中,只是处理前两个TD,而到第三个TD时由于HeadP和TailP相同,就结束了,从而没有处理第三个TD。不知道我这样理解是不是正确呢?

各位大虾一定帮我分析一下原因啊,搞了好长时间了,老是不能解决这个问题,快要疯掉啦

小弟在此先行谢过各位啦!

或者发邮件给我:flycat0101@sohu.com

最新喜欢:

wdy9927wdy992...
我思,故我在
dopy26
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2006-09-25
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-12-05 15:29
插入usb设备时能够检测到设备(不过会出现两次,不知道这是什么原因?)

通过什么读到两次插入设备的? 寄存器?中断?


可是在设置usb设备地址(set_address)时总是超时。我用示波器看过,好像是有数据发出了,因为有变化的波形。

可能是SOF的波形。


如果正确数据发出的话(我的usb设备是好的),那么就会返回一个状态,而此时我的ohci没有产生“Write done head”中断,就说明ohci根本没有接收到这个状态(不管是正确与否的状态都应该产生这个中断啊,从而进行TD处理),ED中的HeadP指针也是没有改变。请问一下会不会是发出的数据根本就不正确啊?从而导致usb设备不知道如何处理(从而没有处理)?

如果正确的发出了数据,那么usb 设备一定会返回一个状态,此时没有产生中断,是否表明ohci接收数据有问题?硬件上不应该出现问题,那么就是软件设置的问题了,请问我该怎么处理呢?

如果一个TD传输完毕,不管成功还是出错,肯定ED里面相应的值要发生改变。相应的中断也会出现。 估计是软件上的问题。


我想如果在set_address命令中,只是处理前两个TD,而到第三个TD时由于HeadP和TailP相同,就结束了,从而没有处理第三个TD。不知道我这样理解是不是正确呢?

对的!

可以看看TD中的data toggle 有没有设置正确。另外在set address 之前有没有获得endpoint0的maxpacketsize ?
flycat0101
驱动小牛
驱动小牛
  • 注册日期2002-06-24
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望22点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2003-12-08 11:54
[quote]插入usb设备时能够检测到设备(不过会出现两次,不知道这是什么原因?)

通过什么读到两次插入设备的? 寄存器?中断?


可是在设置usb设备地址(set_address)时总是超时。我用示波器看过,好像是有数据发出了,因为有变化的波形。

可能是SOF的波形。


如果正确数据发出的话(我的usb设备是好的),那么就会返回一个状态,而此时我的ohci没有产生“Write done head”中断,就说明ohci根本没有接收到这个状态(不管是正确与否的状态都应该产生这个中断啊,从而进行TD处理),ED中的HeadP指针也是没有改变。请问一下会不会是发出的数据根本就不正确啊?从而导致usb设备不知道如何处理(从而没有处理)?

如果正确的发出了数据,那么usb 设备一定会返回一个状态,此时没有产生中断,是否表明ohci接收数据有问题?硬件上不应该出现问题,那么就是软件设置的问题了,请问我该怎么处理呢?

如果一个TD传输完毕,不管成功还是出错,肯定ED里面相应的值要发生改变。相应的中断也会出现。 估计是软件上的问题。


我想如果在set_address命令中,只是处理前两个TD,而到第三个TD时由于HeadP和TailP相同,就结束了,从而没有处理第三个TD。不知道我这样理解是不是正确呢?

对的!

可以看看TD中的data toggle 有没有设置正确。另外在set address 之前有没有获得endpoint0的maxpacketsize ? [/quote]

对于第一个问题,我找到了原因。其实读到一次设备插入,然后进行设备枚举,如果不成功就重新再枚举一次,所以就出现了分配两次地址的情况,如果第一次枚举成功就不会出现第二次了。linux中检测root hub状态的是由一个专门的定时器控制,检查其寄存器状态,同时再配合一个hub的事件队列。进行usb枚举是有一个专门的线程完成。如果状态改变,同时hub事件队列为空,则唤醒线程进行枚举。

设置地址时出现的波形的问题。
如果是SOF的话,应该每次都是一样的吧?并且在没有设备插入时也应该有SOF的,可是在没有插入设备时没有出现波形,当枚举停止时也就没有波形出现了,同时每次的波形还不一样。所有我怀疑是不是发出的数据不对(也有可能是每次设置的地址不一样引起)。
再问一个问题,每次的SOF都会产生一个输出的波形吗?这个波形是什么样子的?

有没有可能我的数据发出后没有收到usb设备返回的状态信息,从而一直处于等待状态返回的状态?导致最后的超时?

我是按照linux中usb部分的源码改的,涉及到TD部分几乎没有动过,我想data toggle 估计是没有问题的。另外就是在linux中他是先设置usb设备的地址,然后再取得设备描述符的前8个字节的,也就是获得endpoint0的maxpacketsize。对于设置地址来说,我认为这个在前或者是在后是没有影响的。

大侠,再帮我分析分析

唉,公司里就我一个人作这个东东,没有人交流啊
郁闷!
我思,故我在
dopy26
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2006-09-25
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-12-08 17:26
如果是SOF的话,应该每次都是一样的吧?

这么肯定? 那framenumber 和 crc5 是相同的么?

并且在没有设备插入时也应该有SOF的,可是在没有插入设备时没有出现波形

建议看看ohci规范, SOF什么时候产生?


再问一个问题,每次的SOF都会产生一个输出的波形吗?这个波形是什么样子的?

有。 没有传输的时候看到的波形只会是SOF。

有没有可能我的数据发出后没有收到usb设备返回的状态信息,从而一直处于等待状态返回的状态?导致最后的超时?

sure


我是按照linux中usb部分的源码改的,涉及到TD部分几乎没有动过,我想data toggle 估计是没有问题的。

偶没看过linux, 不清楚。


另外就是在linux中他是先设置usb设备的地址,然后再取得设备描述符的前8个字节的,也就是获得endpoint0的maxpacketsize。对于设置地址来说,我认为这个在前或者是在后是没有影响的。

要是不先获得maxpacketsize的话, control传输就可能出错。


你做usb driver有多久了? 呵呵
 :cool:

[编辑 -  12/8/03 by  dopy26]
flycat0101
驱动小牛
驱动小牛
  • 注册日期2002-06-24
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望22点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2003-12-08 19:03
[quote]如果是SOF的话,应该每次都是一样的吧?

这么肯定? 那framenumber 和 crc5 是相同的么?

并且在没有设备插入时也应该有SOF的,可是在没有插入设备时没有出现波形

建议看看ohci规范, SOF什么时候产生?


再问一个问题,每次的SOF都会产生一个输出的波形吗?这个波形是什么样子的?

有。 没有传输的时候看到的波形只会是SOF。




要是不先获得maxpacketsize的话, control传输就可能出错。


你做usb driver有多久了? 呵呵
 :cool:

[编辑 -  12/8/03 by  dopy26] [/quote]
呵呵,大侠见笑了,我作usb host也4个月了,不过从来没有注意过这个sof,因为没有用到过。
我又仔细看了一下波形,每一毫秒产生一个波形,并且前面部分几乎不变。这是一个SOF波形。我把从示波器上得到的最后一个信号画出来了,也作为附件传上来了。

这么看来是我的数据根本就没有发出来,唉,还得看看芯片文档。
这个usb host是集成在一颗ARM芯片中的,usb host和内存交换数据不是经过ARM的MMU,而是经过一个Local Bus和Local Bus MMU,看来是local bus有问题,唉,郁闷。
多谢大侠了,长了一些见识。

分数先送上。

另外再问一个问题,就是我的usb host端没有什么问题吧?下面是我在set_address时得到的一些数据:
First TD MPUVA:C09B7180   LBVA:309B7180
TD[0] MPUVA:C09B71C0      LBVA:309B71C0
TD[1] MPUVA:C09B7200      LBVA:309B7200
TD1->hwCBP:30B3FAC0     hwBE:30B3FAC7
TD2->hwCBP:0            hwBE:0
ED->hwHeadP:309B7180      hwTailP:309B7200

MPUVA是arm的虚拟地址,后者LBVA是local bus虚拟地址,也就是usb host所要的地址(一般PC机中这个地址是物理地址),这两个地址指向相同的物理地址.从这些数据看,好像是没有什么问题的呀,是吗?

最后一点就是set_address命令是只有8个字节的setup命令,没有数据返回;而取得maxpacketsize的命令也是8个字节的,只是它要求返回数据,如果不取得maxpacketsize而按8个字节进行传输的话,也不会出现问题,你以为呢?所以我认为这个地方不会出现问题。
我思,故我在
dopy26
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2006-09-25
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-12-09 11:28

另外再问一个问题,就是我的usb host端没有什么问题吧?下面是我在set_address时得到的一些数据:
First TD MPUVA:C09B7180   LBVA:309B7180
TD[0] MPUVA:C09B71C0      LBVA:309B71C0
TD[1] MPUVA:C09B7200      LBVA:309B7200
TD1->hwCBP:30B3FAC0     hwBE:30B3FAC7
TD2->hwCBP:0            hwBE:0
ED->hwHeadP:309B7180      hwTailP:309B7200

我觉得td2应该是ohci规范上说的Null TD。从上面的数据看来, 这个null td并没有放在TD序列上。所以当ED中的headP=309b7200 = tailP =309b7200 的时候传输就停下来了,而309b7200这个TD的传输不会产生。 建议读一下OHCI的相关内容。

最后一点就是set_address命令是只有8个字节的setup命令,没有数据返回;而取得maxpacketsize的命令也是8个字节的,只是它要求返回数据,如果不取得maxpacketsize而按8个字节进行传输的话,也不会出现问题,你以为呢?所以我认为这个地方不会出现问题。

会出问题, 虽然很多设备的control endpoint maxpacketsize都是8,但并不都是。 我用过的一款U disk就是64byte , hehe, 猜猜会出什么错?


flycat0101
驱动小牛
驱动小牛
  • 注册日期2002-06-24
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望22点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2003-12-09 13:02
[quote]
另外再问一个问题,就是我的usb host端没有什么问题吧?下面是我在set_address时得到的一些数据:
First TD MPUVA:C09B7180   LBVA:309B7180
TD[0] MPUVA:C09B71C0      LBVA:309B71C0
TD[1] MPUVA:C09B7200      LBVA:309B7200
TD1->hwCBP:30B3FAC0     hwBE:30B3FAC7
TD2->hwCBP:0            hwBE:0
ED->hwHeadP:309B7180      hwTailP:309B7200

我觉得td2应该是ohci规范上说的Null TD。从上面的数据看来, 这个null td并没有放在TD序列上。所以当ED中的headP=309b7200 = tailP =309b7200 的时候传输就停下来了,而309b7200这个TD的传输不会产生。 建议读一下OHCI的相关内容。

最后一点就是set_address命令是只有8个字节的setup命令,没有数据返回;而取得maxpacketsize的命令也是8个字节的,只是它要求返回数据,如果不取得maxpacketsize而按8个字节进行传输的话,也不会出现问题,你以为呢?所以我认为这个地方不会出现问题。

会出问题, 虽然很多设备的control endpoint maxpacketsize都是8,但并不都是。 我用过的一款U disk就是64byte , hehe, 猜猜会出什么错?
 [/quote]

上传的数据没有表达清楚,应该是这样:
TD[0] MPUVA:C09B7180   LBVA:309B7180
TD[1] MPUVA:C09B71C0      LBVA:309B71C0
TD[2] MPUVA:C09B7200      LBVA:309B7200
TD[0]->hwCBP:30B3FAC0     hwBE:30B3FAC7
TD[1]->hwCBP:0            hwBE:0
ED->hwHeadP:309B7180      hwTailP:309B7200
TD0的NextTD指向TD1,TD1的NextTD指向TD2,而TD2的NextTD为0
由于是设置地址,只有8个字节的数据,所以只有第一个TD有数据,而第二个TD是没有数据的,其DP为输入;所有这三个TD都挂入队列了。

如果你说的那个U disk是必须用64byte的话,那么第一个命令(得到前8个字节的get_descriptor,在windows系统中)就会出错了吧?
我思,故我在
dopy26
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2006-09-25
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-12-09 15:30
TD是用对了的。

如果U disk 的control endpoint maxpacketsize = 64 ,而你在ED中相应的值是8,就会data overrun . 所以我一开始就说 : 在set address之前必须先作一遍 get_DeviceDescriptor (得到maxpacketsize)。
游客

返回顶部