打印

stm32f105 USB DEVICE SOS!!

[复制链接]
楼主: 03024003
手机看帖
扫描二维码
随时随地手机跟帖
21
xinzha| | 2010-1-4 17:51 | 只看该作者 回帖奖励 |倒序浏览
DI和DO是你看到在总线上的数据,如果数目相等,就是说明所有的DO,stm32都已经给回答。如果DO数目大于DI,说明stm32在接收到某些包之后没有回答。而在正常情况下,在总线上看到的一定是DI和DO一样,这里要注意一点,你发出的请求如果没有实际数据响应,总线上是什么都看不到的。
这种测试是要找到问题的产生在整个链路的哪个部分。

使用特权

评论回复
22
03024003|  楼主 | 2010-1-4 18:23 | 只看该作者
我现在的程序是这样的,如果本次测试只有OUT指令,或者只有IN指令(不管OUT还是IN指令,间隔多长时间都可以,这样出问题的时候就应该排除了超时的可能性),那么程序执行一点问题没有,bus hound抓取的数据肯定是一OUT一IN。

但是只要他俩不是成对出现的时候就会有问题了,连续多次OUT后,再IN(即当TxFifo中有数据的时候,主机没有读取,而是继续发送OUT指令)。

使用特权

评论回复
23
xinzha| | 2010-1-4 18:33 | 只看该作者
IN请求一定要比OUT请求多或者至少相等,如果不能保证这一点,出问题是必然的。
另外还要考虑TxFifo和RxFifo的设计,如果这两个Fifo不是独立的,而是分时复用的话,那就一定会出问题(不过应该商用项目上没有这样设计的...)。

使用特权

评论回复
24
xinzha| | 2010-1-4 18:40 | 只看该作者
还是先去看一下usb的协议吧,如果你的OUT请求期望设备有回答,那么在你发出OUT之后IN也应该挂上,在linux下有类似于下面这样的系统调用:
usb_control_msg(pd_device->udev, 
                         usb_rcvctrlpipe(pd_device->udev, 0),
                         REQ_GET_CMD | cmdid,
                         USB_DIR_IN | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
                         lower_16,
                         upper_16,
                         &data,
                         (dataLen + sizeof(*cmd_status)),
                         USB_CTRL_GET_TIMEOUT);
这种系统调用就是直接向设备发一个命令,然后将data的地址交给usb kernel,挂一个IN请求。

使用特权

评论回复
25
03024003|  楼主 | 2010-1-4 18:49 | 只看该作者
你说的是控制端点的OUT与IN,我是批量端点的OUT和IN。

- 当主机不停的IN指令(正确收到数据)时,控制端点发送OUT指令也会造成先前的影响。

使用特权

评论回复
26
香水城| | 2010-1-4 18:52 | 只看该作者
你如何确定你的主机驱动程序发出了IN请求?是否主机根本没有发出IN请求?

使用特权

评论回复
27
03024003|  楼主 | 2010-1-4 18:55 | 只看该作者
主机发送IN指令,如果下位机不给出响应,主机这边会一直等待的,我就是这么判断出他已经发出了IN指令请求的,不知道对不对。。。

使用特权

评论回复
28
xinzha| | 2010-1-4 20:30 | 只看该作者
BULK另当别论,按照道理来说,单次的BULK成功,多次的也应该成功。如果确信IN请求已经发出来,还是认为device这一侧的接收命令处理出现了问题,连续接收多个命令却一个响应也没出去的话,处理流程可能乱了。

使用特权

评论回复
29
03024003|  楼主 | 2010-1-5 08:57 | 只看该作者
BULK端点应该是任意的OUT和IN都可以的,没必要几个OUT后必须给出IN,或者几个IN后必须给出OUT吧.

使用特权

评论回复
30
香水城| | 2010-1-5 09:06 | 只看该作者
我还是在3楼的那几个基本问题。

使用特权

评论回复
31
03024003|  楼主 | 2010-1-5 09:18 | 只看该作者
- 主机是PC机,XP系统.
- 主机驱动是CyAPI,应该是个很成熟的usb驱动.
- 通过CyAPI的接口函数来操作usb读写.
- 单独测试的时候是没有问题的(即只有批量端点的OUT或IN).

使用特权

评论回复
32
xinzha| | 2010-1-5 09:45 | 只看该作者
是没必要给,可你设备侧每接到一个命令都妄图回答,你能暂存多少命令多少回答,你的设备侧有多强壮,是否做了足够的保护?

使用特权

评论回复
33
03024003|  楼主 | 2010-1-5 09:51 | 只看该作者
是没必要给,可你设备侧每接到一个命令都妄图回答,你能暂存多少命令多少回答,你的设备侧有多强壮,是否做了足够的保护?
xinzha 发表于 2010-1-5 09:45


不管主机OUT多少次,stm32中的TxFifo中只有64个字节的数据,只有主机IN指令后,下位机产生传输完成中断后才再次放入64字节的数据,不是每次接到OUT指令就往TxFifo中放数据的.

使用特权

评论回复
34
xinzha| | 2010-1-5 10:55 | 只看该作者
不是说这个思路有问题,而是说你的软件实现出现了问题。

使用特权

评论回复
35
03024003|  楼主 | 2010-1-5 11:15 | 只看该作者
恩,关键这个软件实现问题出在哪,如果是这个usb库的bug那可就残.
不知道他官方例程是怎么回事,我用那个海量存储的例程,电脑能识别u盘,能显示出容量,但是不能格式化,这样算是好用的例程吗?

使用特权

评论回复
36
lxyppc| | 2010-1-5 11:25 | 只看该作者
楼主能把你的收发逻辑流程画出来看看吧
感觉是你程序逻辑上有问题
usb库的代码写得有点抽象,有bug也应是错误使用引入的

使用特权

评论回复
37
03024003|  楼主 | 2010-1-5 12:04 | 只看该作者
楼主能把你的收发逻辑流程画出来看看吧
感觉是你程序逻辑上有问题
usb库的代码写得有点抽象,有bug也应是错误使用引入的
lxyppc 发表于 2010-1-5 11:25

从来没画过流程图...
我把流程再说一遍吧:
- 首先stm32接收到主机的一个特定OUT指令后,往TxFifo写入64字节的数据.
- 然后当主机IN指令后可以正确读出数据,这时stm32产生传输完成中断,并再次往TxFifo中放入64字节数据.
- 如果主机只想读取stm32的数据的话,只需要发送一次特定的OUT指令就可以了,之后可以随时的,任意的读取数据了.

但问题出来了:
1.在上面流程正常读取的情况下(用线程来不停的读取stm32的数据),主机再OUT一次就会造成stm32无响应(无IN中断,主机进入死循环(等待stm32的数据)).

2.若不用线程来读取数据,而采用自己点击一下按钮读取一次数据的方式的话,则出现以下问题.
- 主机连续发送多次OUT指令后,再IN指令,stm32无中断产生(但是主机这边不死机,也就是执行IN指令的函数有返回,但是数据不对),这时OUT指令正常(即stm32可以正确接收数据),但如果再点击一次IN指令,则主机死机(进入死循环等待stm32数据),stm32无中断产生.

使用特权

评论回复
38
lxyppc| | 2010-1-5 12:31 | 只看该作者
看来楼主用的是Bulk传输的方式
Bulk传输的定义是一次性传输大量的数据,对于Bulk传输的特性我没有仔细去研究过,我只说说我遇到过现象吧

1。Bulk In对于PC上驱动端而言,就是不停地转发读取urb,一旦读取开始,就一定要完成。完成的条件是所要求的数据传输完成,或是收到不完整的包。中间不能被其它操作打断。一旦中断需要Reset USB
2。Bulk In对于设备的Firmware而言,就是在Bulk In buffer为空的时候就不停地填数据。填充数据也要满足完成条件。每次填充时中间间隔时间不能太长,太长也会导致无法继续传输,需要Reset USB

USB总线上实际上是半双工传输数据的,主机请求,从机响应
Bulk之所以转得快,是因为一旦总线空闲就主机就发送Bulk的请求

使用特权

评论回复
39
香水城| | 2010-1-5 12:41 | 只看该作者
请问在上位机发送IN TOKEN时,当下位机没有响应时,下位机回复的是NAK还是错误的数据。

如果下位机一直回复的是NAK,上位机应该在一段时间后进入超时处理。

如果下位机连续回复错误的数据(需要看是什么错误,估计Data toggle的可能性大),则上位机应该发送Set feature命令,要求下位机恢复。

使用特权

评论回复
40
03024003|  楼主 | 2010-1-5 13:54 | 只看该作者
回复38L:
stm32在复位后,如果不往TxFifo写入数据,则主机IN指令不会产生中断,主机会死机(知道读到数据为止).

主机会不定时的读取stm32的数据,有可能是1ms,也有可能是100ms,所以我只能在复位后接收到特定的OUT指令后写TxFifo,然后在传输完成的时候再次往TxFifo中填入数据.还有其他的方法吗?

回复39L:
惭愧,不确定下面响应的是NAK还是其他的什么......我感觉应该是NAK吧.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则