搜索
bottom↓
回复: 148

极速狂飙!STM32 USB 程序将BULK EP改成双缓冲机制后,接收OUT数据的速度从原先的500KB/

  [复制链接]

出0入0汤圆

发表于 2008-1-12 20:23:08 | 显示全部楼层 |阅读模式
前天测试自己编写的USB驱动程序时候发现从主机到STM32的OUT传输(主机到设备)速率竟然只有最高33KB/S,实在是晕死了。经过研究后发现是驱动程序中设置的PIPE MaxTransferSize参数的关系,原先设置64只能33KB/S,后参考其他USB设备驱动程序的值,设置成了65535,再测试USB OUT的速度,达到了500KB/S,终于解决了驱动程序的瓶颈。不过算下USB 2.0全速的通讯速率是12Mb/S,排除掉CRC、令牌、SOF等等开销怎么也应该不止最大500KB/S啊。到网上看了看,基本上应该能达到600KB/S~700KB/S以上,我现在的速度应该还有很大的提升才是。
    看看程序,发现
void EP3_OUT_Callback(void)//EP3 OUT的回调函数,当EP3接收到数据时候中断调用该函数
{
  count_out = GetEPRxCount(ENDP3);//获得接收到的数据长度
  PMAToUserBufferCopy(buffer_out, ENDP3_RXADDR, count_out);//将数据从USB EP3 RX的缓冲区拷贝到用户指定的数组中
  SetEPRxValid(ENDP3); //完成拷贝后置有效状态,从而EP3发送ACK主机可以进行下一个数据包的发送
}
    试着将PMAToUserBufferCopy这句注释掉(这样STM32就不处理接收到的数据了)后再测试速度,惊奇地发现速度竟然达到了997KB/S!晚上仔细想了想,数据肯定是要使用的,这个数据拷贝的过程的时间消费总是少不了的;由于通常情况下USB设备BULK数据接收的步骤就是:接收到数据,置NAK->将缓冲区数据拷贝到用户区(用户处理过程)->发ACK通知主机完成了完整的接收可以发送下一个->主机发送下一个,按照以上的步骤USB接收一步步的进行,只要STM32不完成数据处理,状态就一直是NAK,主机就会不停地发送该数据包,浪费了带宽,因此就会导致我上面最大速度500KB/S难以再增加的情况!不甘心啊~~
    昨天晚上又仔细研究了STM32的技术参考手册的USB章节内容,里面提到BULK可以采用双缓冲机制(PING-PONG)进行处理,正好可以解决上面的情况。双缓冲机制的原理就是分配2块接收缓冲,STM32的用户处理和USB接口可以分别交替占用2个缓冲区,当USB端点接收数据写其中一个缓冲区的时候,用户的应用程序可以同时处理另一个缓冲区,这样缓冲区依次交换占有者,只要用户处理程序在USB端点接收的时间片段内完成处理,就能够完全不影响USB的通讯速度!
    程序部分修改
一、EP3_OUT的设置修改,
//ZYP:修改EP3为BULK双缓冲方式-------------------------
  SetEPType(ENDP3, EP_BULK);
  SetEPDoubleBuff(ENDP3);
  SetEPDblBuffAddr(ENDP3, ENDP3_BUF0Addr, ENDP3_BUF1Addr);
  SetEPDblBuffCount(ENDP3, EP_DBUF_OUT, VIRTUAL_COM_PORT_DATA_SIZE);
  ClearDTOG_RX(ENDP3);
  ClearDTOG_TX(ENDP3);
  ToggleDTOG_TX(ENDP3);
  SetEPRxStatus(ENDP3, EP_RX_VALID);
  SetEPTxStatus(ENDP3, EP_TX_DIS);
//------------------------------------------------------
二、EP3_OUT回调函数的修改
void EP3_OUT_Callback(void)
{
//ZYP:以下是修改成EP3双缓冲OUT后的处理函数
  if (GetENDPOINT(ENDP3) & EP_DTOG_TX)//先判断本次接收到的数据是放在哪块缓冲区的
  {
    FreeUserBuffer(ENDP3, EP_DBUF_OUT); //先释放用户对缓冲区的占有,这样的话USB的下一个接收过程可以立刻进行,同时用户并行进行下面处理
    count_out = GetEPDblBuf0Count(ENDP3);//读取接收到的字节数
    PMAToUserBufferCopy(buffer_out, ENDP3_BUF0Addr, count_out);
  }
  else
  {
    FreeUserBuffer(ENDP3, EP_DBUF_OUT);
    count_out = GetEPDblBuf1Count(ENDP3);
    PMAToUserBufferCopy(buffer_out, ENDP3_BUF1Addr, count_out);
  }
}
    经过上面的修改,终于解决了STM32在处理接收数据时导致主机等待的情况,用BUS HOUND软件测试了下


    哈哈,这下终于爽了。

PS:上面的FreeUserBuffer(ENDP3, EP_DBUF_OUT); 这句话的上下位置是关键,如果放到函数的后面,则仍旧会有主机等待STM32处理数据的情况,速度仍然是500KB/S!
    把这句话放在拷贝函数的前面的话就真正把双缓冲PING-PONG机制用起来了。大致算了下PMAToUserBufferCopy(buffer_out, ENDP3_BUF1Addr, count_out);这句话当count_out为最大值64的时候STM32执行需要302个周期,72MHZ情况下约4.2微秒执行时间,而USB传输按照12Mb/s的线速度传输64字节的数据至少也得40微秒,因此只要PMAToUserBufferCopy的时间不超过40微秒,就不会导致缓冲区竞争的情况。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2008-1-12 20:27:19 | 显示全部楼层
我来凑个热闹

出0入50汤圆

发表于 2008-1-13 15:37:45 | 显示全部楼层
我就等你USB示波器出炉了,表明了:有志者事竟成!

出0入4汤圆

发表于 2008-1-13 15:54:05 | 显示全部楼层
STM32的价格多少一片 带USB的?

好买吗?

出0入0汤圆

发表于 2008-1-13 16:55:49 | 显示全部楼层
楼主牛人,帮顶做记号

出0入0汤圆

 楼主| 发表于 2008-1-13 22:32:00 | 显示全部楼层
USB示波器的STM32固件部分的基础知识准备工作看起来倒是差不多了,USB传输的速度也挺满意的。就是模拟前端(信号放大衰减)就是以前画了个草图,一直也没实验。最近一直在搞软件,已经好长时间没动烙铁了,有点懒了,呵呵。
    STM32好像不大好买到,我也没买过。前几天论坛上好像看到有人发卖STM32的帖子,另外21IC上面的ST论坛里面好像也有ST代理的广告,供应STM32,不知道能不能零售

出0入0汤圆

发表于 2008-1-13 23:06:15 | 显示全部楼层
顶一个!楼主牛啊!

出50入0汤圆

发表于 2008-1-13 23:37:12 | 显示全部楼层
顶,我的STM32的PACK在做了,努力向楼主学习

出50入0汤圆

发表于 2008-1-14 09:18:37 | 显示全部楼层
力源有卖,就是贵了点

出0入0汤圆

发表于 2008-1-14 11:16:20 | 显示全部楼层
请问,LZ是在什么环境下开发的呢?

出0入0汤圆

 楼主| 发表于 2008-1-14 15:35:57 | 显示全部楼层
【7楼】 cddyy 兄弟,问一下,你说的STM32的PACK是什么?是否是自己做的最小系统板或者转接板?


【9楼】 hahacomcn :开发环境? STM32是用的KEIL MDK3.15B评估版 + ULINK,ST的STM32固件开发包+USB开发包
上位机的驱动程序开发环境是微软的WindowsXP DDK sp1 + MS VC6.0 + DriverStudio 3.1

出0入0汤圆

发表于 2008-1-14 19:53:51 | 显示全部楼层
搂主能不能先公布USB传输的代码?我现在也在搞STM32,已经调通了USB_CDC例子,现在在利用USBLib写自己的代码,好像搞不定。

出0入0汤圆

发表于 2008-1-14 21:39:59 | 显示全部楼层
极品贴,狂顶……

出0入0汤圆

发表于 2008-3-24 17:29:51 | 显示全部楼层
搂主:我记得USB 1.0通讯速率是12Mb/S,USB 2.0全速的通讯速率是480Mb/S 。不是你说的“USB 2.0全速的通讯速率是12Mb/S”,挑毛拣刺了,楼主别生气。

出0入0汤圆

发表于 2008-3-24 17:37:47 | 显示全部楼层
ls, 你挑错了

usb速度有三种
低速low speed 1.5M
全速full speed 12M
高速high speed 480M

别被usb2.0给迷惑了, usb2.0 不等于 480Mbps

出0入0汤圆

发表于 2008-3-24 17:40:20 | 显示全部楼层
楼上的楼上你错了,480Mb/s是USB2.0的高速模式。

出0入0汤圆

发表于 2008-3-24 17:55:58 | 显示全部楼层
牛人真多啊!

出0入0汤圆

发表于 2008-3-24 23:01:36 | 显示全部楼层
不错。。。好文章

出10入210汤圆

发表于 2008-3-25 08:14:54 | 显示全部楼层
【14楼】 bozai 章其波 是对的。
1.0的最高12Mbps.
2.0的高速模式480Mbps,全速模式12Mbps,低速模式1.5Mbps.

出0入0汤圆

发表于 2008-3-25 08:52:26 | 显示全部楼层
stm32的片子,力源有卖的,100脚的也就40多点,不算贵,比mega128贵一些,比mega1280便宜些

出0入0汤圆

发表于 2008-3-25 10:15:29 | 显示全部楼层
这是我USB的读写速度
1

出0入0汤圆

发表于 2008-5-8 23:28:46 | 显示全部楼层
楼主,我刚开始搞stm32,usb也是第一次做,请问pc端的usb驱动是不是要自己写啊?
有没有什么可以看看?

出0入0汤圆

发表于 2008-8-10 22:07:06 | 显示全部楼层
以下蓝色文字由版主:bluelucky 于:2008-08-10,22:07:06 加入。
<font color=black>请发贴人注意:
本贴放在这分区不合适,即将移走
原来分区:[1032]ARM技术论坛
即将移去的分区:[3011]Cortex-M3技术讨论区
移动执行时间:自本贴发表0小时后

任何的疑问或咨询,请可随时联系站长。谢谢你的支持!
</font>

出0入0汤圆

发表于 2008-8-20 15:38:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-8-20 15:55:54 | 显示全部楼层
好文

出0入93汤圆

发表于 2008-8-20 16:15:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-8-20 19:54:14 | 显示全部楼层
谢谢楼主经验分享!

出0入0汤圆

发表于 2008-8-20 20:26:08 | 显示全部楼层
好~~学习中~~~

出0入0汤圆

发表于 2008-8-20 21:23:36 | 显示全部楼层
……帖子有点老……

不过还是说一句

双缓冲对内存的消耗太大了……

出0入0汤圆

发表于 2008-9-1 18:10:09 | 显示全部楼层
【14楼】 bozai 章其波 正解 需要480M的同学们可以看看68013芯片 好像是CY的 (非广告)

楼主发的是猛贴呀 赞

出0入0汤圆

发表于 2008-9-1 18:24:13 | 显示全部楼层
我顶~~~~~

出0入0汤圆

发表于 2008-9-26 12:41:01 | 显示全部楼层
老帖子&nbsp;&nbsp;&nbsp;但是好贴还是要顶的&nbsp;&nbsp;

正在弄USB&nbsp;谢谢分享

出0入0汤圆

发表于 2008-10-29 18:49:45 | 显示全部楼层
收藏,下次搞USB好借鉴了。

出0入0汤圆

发表于 2008-10-29 21:35:55 | 显示全部楼层
请教楼主关于USB&nbsp;HOST端程序的问题,我的问题发了很多地方都没有回复,希望楼主能给点指导。以下是这问题的连接。



http://www.st.com/mcu/forums-cat-7512-23.html



http://group.ednchina.com/619/15861.aspx



谢谢!

出0入0汤圆

发表于 2008-10-29 23:58:07 | 显示全部楼层
顶一个
头像被屏蔽

出0入0汤圆

发表于 2008-10-30 08:21:52 | 显示全部楼层
MARK

出0入0汤圆

发表于 2008-10-30 17:31:04 | 显示全部楼层
STM&nbsp;USB虚拟COM端口驱动&nbsp;那里下啊?

出0入0汤圆

发表于 2008-10-30 17:33:58 | 显示全部楼层
大家帮帮我吧,,,哈哈,我是弟一次搞USB&nbsp;我只想当串口用,看了MAXCHIP的资料看不懂&nbsp;&nbsp;&nbsp;1,STM&nbsp;USB虚拟COM端口驱动&nbsp;那里下啊?



2,我下一个VCPDriver_V1.1_Setup&nbsp;&nbsp;装上过后在硬件管理器面也没有看STM&nbsp;USB串口的图标

出0入0汤圆

发表于 2008-11-3 02:43:25 | 显示全部楼层
谢谢!

出0入0汤圆

发表于 2008-11-26 20:52:43 | 显示全部楼层
真是羡慕大哥啊,小弟也正在DIY一个USB示波器,用的NXPLPC2364,USB-DMA只能达到620KB/s,看到大哥的速度,想换STM32了&nbsp;

出0入0汤圆

发表于 2008-11-27 11:53:22 | 显示全部楼层
请问大哥,您用的双缓冲机制是不是定义两个端点交替工作?

还有,STM3210X中的USB支持DMA吗?它有像NXP&nbsp;LPC23XX那样的16KB&nbsp;USB-DMA-RAM&nbsp;加上&nbsp;2KB&nbsp;FIFO吗?&nbsp;它的速度真的比LPC23XX&nbsp;USB要快?&nbsp;为什么??

出0入0汤圆

发表于 2009-3-6 22:45:38 | 显示全部楼层
重新顶起来

出0入0汤圆

发表于 2009-3-13 23:48:24 | 显示全部楼层
双缓冲对内存的消耗太大了……


******************

消耗多大?

出0入0汤圆

发表于 2009-6-18 17:31:26 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-7-13 18:05:42 | 显示全部楼层
好啊,学习了!

出0入0汤圆

发表于 2009-7-13 20:24:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-13 21:36:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-31 16:37:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-8 04:09:00 | 显示全部楼层
其实你第一次传输完,不应该应答ACK应该应答NYET,搞诉主机没有足够的缓冲区处理下次数据,下次传输的时候,主机会PING一下,确认下位机是否准备好,这样不会浪费带宽了。根本不用双缓冲。

出0入0汤圆

发表于 2009-8-8 08:04:32 | 显示全部楼层

出0入0汤圆

发表于 2009-10-13 15:54:13 | 显示全部楼层
做个记号

出0入0汤圆

发表于 2009-10-13 16:03:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-18 10:13:07 | 显示全部楼层
踩下

出20入0汤圆

发表于 2009-12-18 11:05:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-18 12:12:17 | 显示全部楼层
LZ厉害

出0入0汤圆

发表于 2010-2-14 19:51:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-27 22:28:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-1 14:26:19 | 显示全部楼层
果然很强大,学习中~

出0入0汤圆

发表于 2010-3-1 15:32:44 | 显示全部楼层
顶。

出0入0汤圆

发表于 2010-3-13 01:00:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-13 21:40:37 | 显示全部楼层
顶。

出0入0汤圆

发表于 2010-3-19 19:21:55 | 显示全部楼层
做毕业设计的时候也发现这个问题,知道用双缓冲机制,不过毕业工作后没继续了,看了你的,我有了动力!

出10入10汤圆

发表于 2010-3-19 21:39:15 | 显示全部楼层
谢谢共享!

出0入0汤圆

发表于 2010-3-19 22:06:21 | 显示全部楼层
谢谢分享

出10入95汤圆

发表于 2010-3-19 23:33:16 | 显示全部楼层
good

出0入0汤圆

发表于 2010-4-6 16:51:49 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-4-6 18:14:13 | 显示全部楼层
楼主强人

出0入0汤圆

发表于 2010-4-6 19:17:59 | 显示全部楼层
楼主强人

出0入0汤圆

发表于 2010-4-10 10:14:13 | 显示全部楼层
请问楼主,你的usb用的什么传输方式?  使用虚拟串口怎样实现速度飙升?

各位大侠  玩过的指导一下小弟啊

出0入0汤圆

发表于 2010-4-10 10:16:35 | 显示全部楼层

虚拟串口的波特率 限制 (原文件名:ourdev_544682.gif)

出0入0汤圆

发表于 2010-4-10 10:41:34 | 显示全部楼层
这个一定要顶~~~

出0入0汤圆

发表于 2010-5-12 14:37:05 | 显示全部楼层
DEMO没放出来呢

出0入0汤圆

发表于 2010-5-15 00:03:40 | 显示全部楼层
把usb的某个endp设置成双缓冲是否还需要改driver?
头像被屏蔽

出0入0汤圆

发表于 2010-5-16 09:52:53 | 显示全部楼层
把usb的某个endp设置成双缓冲是否还需要改driver?
-----------------------------------------------
否!

出0入0汤圆

发表于 2010-6-3 10:59:55 | 显示全部楼层
mark下 楼主 牛人

出0入0汤圆

发表于 2010-6-3 11:00:07 | 显示全部楼层
mark下 楼主 牛人

出0入0汤圆

发表于 2010-6-10 18:05:24 | 显示全部楼层
用bus hound 软件测量通信速率 有很大出入的!

出0入0汤圆

发表于 2010-6-13 21:44:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-15 07:10:47 | 显示全部楼层
bucuo,xuexi

出0入0汤圆

发表于 2010-6-15 10:42:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-7 10:40:25 | 显示全部楼层
楼主,你用双缓冲机制,如果应用端当前缓冲还没处理完,而USB端中断已经收完数据到另一个缓冲了,那当前应用处理的缓冲又不能腾出来给USB用,那USB不是还得等待。这样速度也是无法提高的。
问题关键是,双缓冲的SIZE得开得多大的问题吧?

出0入0汤圆

发表于 2010-7-7 10:51:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-7 11:14:58 | 显示全部楼层
我也是正在搞这个

出0入0汤圆

发表于 2010-7-18 17:44:42 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-7-18 22:23:07 | 显示全部楼层
留个记号

出0入0汤圆

发表于 2010-8-11 21:18:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-13 12:33:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-15 14:39:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-15 15:43:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-15 19:34:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-14 23:17:25 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-16 18:56:11 | 显示全部楼层
mark 一下

出0入0汤圆

发表于 2010-10-20 19:49:24 | 显示全部楼层
记录

出0入0汤圆

发表于 2010-11-23 15:19:43 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-11-23 21:01:11 | 显示全部楼层
mark STM32 USB

出0入0汤圆

发表于 2010-11-23 22:29:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-10 14:15:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-25 13:50:10 | 显示全部楼层
mark~~~

出0入0汤圆

发表于 2011-6-25 16:27:15 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-6-25 18:15:16 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-13 10:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表