你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32的bulk双缓冲传输速度的讨论,硬件的坑永远填不完

[复制链接]
STMCU小助手 发布时间:2022-2-7 21:06
USB 1.0的最高12Mbps.! U) h/ @$ }$ h  R$ x
USB 2.0的高速模式480Mbps,全速模式12Mbps,低速模式1.5Mbps
% B# M  ?* `$ o7 N5 h2 h- }
而是设置STM32端的USART的波特率。PC与STM32传输速度是以USB1.1的理论速度传输的,是不能设置的。

8 c1 m& L, C& S& o) _接收到数据,置NAK->将缓冲区数据拷贝到用户区(用户处理过程)->发ACK通知主机完成了完整的接收可以发送下一个->主机发送下一个,# N3 E* E# v* c* ^# R$ r
. a8 L. a5 h- t, H% r/ b& ]+ z
前天测试自己编写的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以上,我现在的速度应该还有很大的提升才是。
$ N& M2 {4 u  p6 U    看看程序,发现& ?. g9 x/ O# J
void EP3_OUT_Callback(void)//EP3 OUT的回调函数,当EP3接收到数据时候中断调用该函数
6 n& K  p! D& S, K$ c# s$ F5 a/ R{
; [' y/ z' U  Q' i' f4 h  count_out = GetEPRxCount(ENDP3);//获得接收到的数据长度
6 |* B& }, l' q) O! Q9 k0 x4 ~  PMAToUserBufferCopy(buffer_out, ENDP3_RXADDR, count_out);//将数据从USB EP3 RX的缓冲区拷贝到用户指定的数组中/ S+ D+ Y' p8 {: Z- A  u
  SetEPRxValid(ENDP3); //完成拷贝后置有效状态,从而EP3发送ACK主机可以进行下一个数据包的发送
; C! ]+ F. c. W% s' |; W6 P}
. f( R# c/ X" V* c. _6 P    试着将PMAToUserBufferCopy这句注释掉(这样STM32就不处理接收到的数据了)后再测试速度,惊奇地发现速度竟然达到了 997KB/S!晚上仔细想了想,数据肯定是要使用的,这个数据拷贝的过程的时间消费总是少不了的;由于通常情况下USB设备BULK数据接收的步骤就 是:接收到数据,置NAK->将缓冲区数据拷贝到用户区(用户处理过程)->发ACK通知主机完成了完整的接收可以发送下一个->主机 发送下一个,按照以上的步骤USB接收一步步的进行,只要STM32不完成数据处理,状态就一直是NAK,主机就会不停地发送该数据包,浪费了带宽,因此 就会导致我上面最大速度500KB/S难以再增加的情况!不甘心啊~~( T# G4 K; H6 ?5 j) [
    昨天晚上又仔细研究了STM32的技术参考手册的USB章节内容,里面提到BULK可以采用双缓冲机制(PING-PONG)进行处理,正好可以解决上面 的情况。双缓冲机制的原理就是分配2块接收缓冲,STM32的用户处理和USB接口可以分别交替占用2个缓冲区,当USB端点接收数据写其中一个缓冲区的 时候,用户的应用程序可以同时处理另一个缓冲区,这样缓冲区依次交换占有者,只要用户处理程序在USB端点接收的时间片段内完成处理,就能够完全不影响 USB的通讯速度!
  _4 M% W) L. x3 d! O) E" n! K/ S    程序部分修改
4 z5 S% V0 Q. n$ l一、EP3_OUT的设置修改,3 r0 K' D: _" E% g$ u' y( ]
//ZYP:修改EP3为BULK双缓冲方式-------------------------* l/ E  D* \# E( q
  SetEPType(ENDP3, EP_BULK);! j# J" ?9 z' W/ J- v
  SetEPDoubleBuff(ENDP3);
2 h- l" J( S# U8 b/ b1 ?3 W8 g  SetEPDblBuffAddr(ENDP3, ENDP3_BUF0Addr, ENDP3_BUF1Addr);
6 e# D. R8 z5 d2 J, l7 z  SetEPDblBuffCount(ENDP3, EP_DBUF_OUT, VIRTUAL_COM_PORT_DATA_SIZE);  w& \# I" s2 U; u
  ClearDTOG_RX(ENDP3);2 }  F. L3 d% ^* ^0 c
  ClearDTOG_TX(ENDP3);8 ?0 ^4 I. w" e: Q
  ToggleDTOG_TX(ENDP3);
- g; u7 S; m1 |  E' \7 U  SetEPRxStatus(ENDP3, EP_RX_VALID);# }7 A! ~/ t, ^
  SetEPTxStatus(ENDP3, EP_TX_DIS);( }! Q0 Q0 k, ]0 z4 X
//------------------------------------------------------, G3 a1 d& T: r0 u9 E2 Y8 n7 @! O
二、EP3_OUT回调函数的修改
1 F3 m% i4 y( K# z+ H4 o, Tvoid EP3_OUT_Callback(void), E2 S  Q4 E2 h; x
{
2 [6 o: s- A7 N. q7 _//ZYP:以下是修改成EP3双缓冲OUT后的处理函数
+ D. M( ?, S1 J5 r0 ]  if (GetENDPOINT(ENDP3) & EP_DTOG_TX)//先判断本次接收到的数据是放在哪块缓冲区的0 c8 z1 b0 [2 {( _. i! S  e- L1 f
  {
2 H: n( f! ?1 e9 W0 P    FreeUserBuffer(ENDP3, EP_DBUF_OUT); //先释放用户对缓冲区的占有,这样的话USB的下一个接收过程可以立刻进行,用另一块缓冲区,同时用户并行进行下面处理,在另一块接收完之前,处理完用户数据就行,否则缓冲区竞争。5 o9 g4 f- g3 j7 t/ z# O5 N2 `! U6 }, b
    count_out = GetEPDblBuf0Count(ENDP3);//读取接收到的字节数,
' `5 t$ _5 l/ W5 W    PMAToUserBufferCopy(buffer_out, ENDP3_BUF0Addr, count_out);5 f* K: g, X( h
  }# c" Z6 o! \/ C; O* O7 @
  else* X  E6 ?1 S# k
  {
4 A2 y  p+ V* d$ K3 `4 K, @8 H4 B    FreeUserBuffer(ENDP3, EP_DBUF_OUT);
& |9 i( L. ]/ I3 U    count_out = GetEPDblBuf1Count(ENDP3);- ~  r+ x5 ^- m3 _" S, _5 c
    PMAToUserBufferCopy(buffer_out, ENDP3_BUF1Addr, count_out);
, z" w* ^" }" X7 p& I+ K, `  }, s7 \% B. _. Z9 L
}
  D' Z: {4 r% Y0 t* E4 ?. A    经过上面的修改,终于解决了STM32在处理接收数据时导致主机等待的情况,用BUS HOUND软件测试了下; \0 f0 _) S: C1 O8 S4 C% j1 x- J

5 R1 }" l! w6 K& i6 m PS:上面的FreeUserBuffer(ENDP3, EP_DBUF_OUT); 这句话的上下位置是关键,如果放到函数的后面,则仍旧会有主机等待STM32处理数据的情况,速度仍然是500KB/S!, O" f' ~9 P7 o0 V7 q/ Z
    把这句话放在拷贝函数的前面的话就真正把双缓冲PING-PONG机制用起来了。大致算了下 PMAToUserBufferCopy(buffer_out, ENDP3_BUF1Addr, count_out);这句话当count_out为最大值64的时候STM32执行需要302个周期,72MHZ情况下约4.2微秒执行时间,而USB 传输按照12Mb/s的线速度传输64字节的数据至少也得40微秒,因此只要PMAToUserBufferCopy的时间不超过40微秒,就不会导致缓 冲区竞争的情况。
- G2 ~; G8 l% J. z( J
" C, l5 @; i# G! {$ [+ N4 g4 q, g! Q* L6 s* T" P
赞 收藏 评论0 发布时间:2022-2-7 21:06

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版