hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2622回复:23

关于bulk和interrupt传输的困惑

楼主#
更多 发布于:2003-01-19 09:40
书上说interrupt是bulk的一种情况,只是bulk利用sof,1ms发一次表示帧到达,而interrupt是人为控制若干ms发一次,但是这样的话bulk不是也是中断了,二者到底什么区别呢?

最新喜欢:

skylglskylgl
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-01-19 13:10
  其实所谓的中断传输就是bulk传输,和真正的硬件中断是没有关系的,之所以称其为中断传输是因为这种传输能保证主机在最短的延迟时间里响应或发送数据,这一点与硬件中断很相似。它的工作原理是主机定时查询设备的状况,以便随时响应或发送数据,查询的时间间隔可以由你来定义,计算公式你可以到协议上去找。除了定时这一项外,其余的都与bulk是一样的。

其实bulk并不是象你想的那样要严格以sof为基准(iso是这样的),只是说sof是一个传输时间片的开始,在这个时间片里你可进行各种各样的传输,如果这个时间片结束了,那就要等到下一个时间片开始后才能进行余下的传输。

高速情况下每个微帧(1/8ms)最多可以传输13个512字节的bulk数据,但是如果你定义的中断传输的时间间隔是这个时间的话,那它只能进行一次最多512字节的数据传输(全速是最多64字节,高速情况是我自己理解的,详细情况需要查一下协议),如果这个时间片里设备没有准备好数据,那就必须等到下一个时间片才能进行中断传输。但是bulk传输则不然,你可以让主机不断的发送in或out令牌,不断的进行数据传输,直到这个时间片结束为止。如果刚开始的时候设备没有准备好数据,那主机就不断的查询,当设备准备好数据并且这个时间片还没有结束,就可以进行bulk传输(与中断不同)!


不知道说清楚了没有,这是我个人的理解,仅作参考,如果有错误之处还望知道的仁兄不吝赐教呀!
hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-01-19 15:11
多谢jinghuiren指正:
送上一些分表示感谢,还有一个比较困惑的问题,当我利用硬件即fpga的fifo把数据放入设备是,它怎么知道有数据了去相应主机的in令牌包,把数据传过去;令一种表述是,如果我利用control panel把数据通过2端口送入,我是否可以用我的应用程序从6端口读出,当然固件使用了bulkloop,它的功能是将数据从2搬到6。多谢!


jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-01-19 15:33
第一个问题:你不用管怎么响应设备的in令牌包,你之需要不断的填充端点,达到最大包大小时该端点会自动有效,如果此时候主机的in令牌包到来,那数据会自动打包送走,不需要你来干预。
第二个问题:是!你试一下就知道了呀,可以用keilc来监视看一下传输过程。
netpk
驱动牛犊
驱动牛犊
  • 注册日期2002-08-23
  • 最后登录2010-09-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-01-20 12:51
\"高速情况下每个微帧(1/8ms)最多可以传输13个512字节的bulk数据\"
请教jinghuiren,这个速度要怎么样才能达到呢,使用所有的BulkEndPoints吗,在应用程序中如何不断发出In令牌才能在一次请求中写入那么多的数据?
谢谢!
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-01-20 13:48
  那只是协议上规定的的最大数据,实际上是不可能达到那么高的速度的,你要想不断的往端点填充数据,那主机方就要不停的读,可是你设备方有那么多的数据要传吗,而且你的设备方的外部控制器的时钟能达到480M吗,这些都是问题。

端点多了并不见得就快,如果在没有太多错误的情况下,使用1个端点,配置成双重缓冲是最快的!
dacongtou
驱动中牛
驱动中牛
  • 注册日期2002-11-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-01-20 13:56
第一个问题:你不用管怎么响应设备的in令牌包,你之需要不断的填充端点,达到最大包大小时该端点会自动有效,如果此时候主机的in令牌包到来,那数据会自动打包送走,不需要你来干预。


可是我觉得应该在填充完毕后给一个0fah命令,使能端点缓冲区才行啊...
netpk
驱动牛犊
驱动牛犊
  • 注册日期2002-08-23
  • 最后登录2010-09-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-01-20 14:42
 那只是协议上规定的的最大数据,实际上是不可能达到那么高的速度的,你要想不断的往端点填充数据,那主机方就要不停的读,可是你设备方有那么多的数据要传吗,而且你的设备方的外部控制器的时钟能达到480M吗,这些都是问题。

端点多了并不见得就快,如果在没有太多错误的情况下,使用1个端点,配置成双重缓冲是最快的!


多谢jinghuiren,可惜没有办法给分……
我还想问一下,配成双缓冲后的单个In端点
是使用Interrupt还是查询方式传输快?
hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-01-20 15:00
 可是我觉得应该在填充完毕后给一个0fah命令,使能端点缓冲区才行啊...
////////////////////////////////////
if(!(EP2468STAT & bmEP2EMPTY))
  { // check EP2 EMPTY(busy) bit in EP2468STAT (SFR), core set\'s this bit when FIFO is empty
     if(!(EP2468STAT & bmEP6FULL))
     {  // check EP6 FULL(busy) bit in EP2468STAT (SFR), core set\'s this bit when FIFO is full
   这是我从程序中取出的一段,这儿的core自动设置,应该就是指
它自动取数据当满时。
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-01-20 18:53
netpk:
      配成双缓冲后的单个In端点用BULK方式是最快的。


hemu:
      你的那种方式还是让8051参与了数据传输!8051不参与数据传输的情况是将AUTOIN设为1,这样固件中的TD_POLL( )函数是空的,没有你摘出的那几行代码,此时只要缓冲区被填满,数据就会自动生效发走,也就是所谓的slave fifo模式,你可以在仔细看一下技术参考第九章的9。3。11节,里面有说明
jfory
驱动小牛
驱动小牛
  • 注册日期2002-05-14
  • 最后登录2003-06-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-01-21 09:09
长,长,长,长.....
hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-01-21 11:09
jinghuiren :
   看来你对速度挺有研究的,想再问你一个速度问题,我的ad是40mhz,我才用gpif能否保证再25ns内把数据取走,来防止数据重叠,如果不行的话,我是否只能用slave fifo模式了
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-01-21 17:00
如果你能用slave fifo的模式能把数据顺利取走,那估计用gpif肯定能行,因为据说后者比前者快!但是好像前者简单一点吧。

还有你40M的AD是多少位的(40M式采样率吧),如果是8位的,那每秒钟能产生数据40M字节,这个数据量可不小,但是理论上USB控制器能把数据全部传到主机上,前提是你的外部控制器填充端点的速度足够快!只要你能把数据写到端点里,USB就能给你发走。否则你肯定不能保证数据不重叠,因此速度的瓶颈在填充USB端点的外部控制器的时钟(如果你用100M的DSP来做这件事,那没问题,如果你用51来做,肯定不行,因为68013内部51的时钟是48M,但是51是4时钟周期执行一条指令,所以是12M,因此不行)。
netpk
驱动牛犊
驱动牛犊
  • 注册日期2002-08-23
  • 最后登录2010-09-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-01-22 10:42
jinghuiren真是对USB设备理解的太透彻了,一问一答解决了我很多疑难问题,呵呵,我决定赠送100分表示心意(好像要我自己开贴?)!
我们这些初学者,就是需要大侠这样的人的指导啊……
大侠请看我的新贴……
hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-01-22 11:05
太好了!
我看fifo的工作模式,觉得它应该简单一些吗,从设备吗被动者应该简单阿?
填充的速度上限是12mhz,所以我在ad和usb中间加一个fifo什么的,只要理论上把数据至少4个数据归为一帧送就没问题了是吗?
引用:只要你能把数据写到端点里,USB就能给你发走
主机中断((1/40mhz)*一帧数据个数),大概在1毫秒级,他响应来的给吗?
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-01-22 15:08
    你别用中断方式,你用bulk方式,上层应用程序循环不停的读,下面设备放不停的写端点。

   按你的意思你还是要用51来读取外加fifo中的数据,你要是4个数据里取一个那倒是可行的,不过你还得外加逻辑来控制吧,我原始以为你外部还有一个控制起来专管填充端点,七是用CPLD来实现填充端点和一些控制工作就可以了。这样会比用51快的多,当然造价要贵一点了。
hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-01-22 15:44
引用:你别用中断方式,你用bulk方式,上层应用程序循环不停的读,下面设备放不停的写端点。
    我就是这么想的,关于fifo只是我对“因为68013内部51的时钟是48M,但是51是4时钟周期执行一条指令,所以是12M”的理解,认为我利用fifo将数据的速度降到10mzh,所有的问题就解决了。
    实际上我就是用cpld,我的采集卡以前是pci擦卡形式,完全做好了,只是老师想将它改用usb数据传输方式,当然其中没有fifo,我想可能要用fpga了,当时我用它的资源做了个fifo。
    方案我就是那样想的,只是我在做pci卡时遇到,主机相应硬件中断1ms时就来不及取数了,我怕在这儿也遇到,“只要你能把数据写到端点里,USB就能给你发走”是否是说没有这个问题,只有我及时向端点送数。
    总结一下,由于ad采样太快,时时我的port,gpif,fifo工作模式多不适用,所以我的比较理想的方式使用fpga,或cpld进行数据缓存,存满一帧(如256字节)就取添丛端口,上层应用程序发现端点有数就去读,其中端点设置成双缓冲形式。对吧?
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-01-22 16:21
没错!
有一点要纠正,就是上层应用程序不能发现你的端点已经满了,所以在速度很快的情况下你必须在上层不断的调用DeviceIoCtl函数来主动读设备的数据,如果设备没准备好就会发送nak给你,host controller如果收到nak,它会接着发送下一个in令牌到设备,直到读到数据为止,应用程序中一旦读取到数据就接着发送下一个DeviceIo命令,当收集一定的数据后可以存放到文件中,如此循环往复,所以建议为读写数据专门开一个线程。
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-01-22 16:29
    在说明一点,usb设备与主机的通讯不是用中断实现的,而是用查询实现的,所以不会有主机来不及读数的问题,除非是信号太差,传输中出现多次错误。


当端点中的数据为满时,只要主机方的in令牌到来,数据就会自动打包发走,然后上面发送下一个in令牌到设备,在这两个in令牌的发送间隔内,你的设备肯定不会把端点填满(发送速率是480Mbps),所以实际上是主机在等待你把数据准备好,而不是你准备好了数据通知主机(usb侍从设备,除了远程唤醒外它不会主动向主机发送任何的信息!)

hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2003-01-23 11:12
\"因此速度的瓶颈在填充USB端点的外部控制器的时钟(如果你用100M的DSP来做这件事,那没问题,如果你用51来做,肯定不行,因为68013内部51的时钟是48M,但是51是4时钟周期执行一条指令,所以是12M,因此不行)。\"
原来我看fifo和gpif的读写,以为可以完成40mhz传输,因为他们是单周期读写的,数据进入缓冲,不就可以读了吗?
上一页
游客

返回顶部