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

【实战经验】USB CDC类入门培训  

[复制链接]
zero99 发布时间:2017-7-28 17:27
USB CDC类入门培训

$ U1 p& d- @/ V: ]0 M% ?6 C1 前言) e! i8 T: D6 r$ u1 P
本文节选自2017年度USB CDC类培训内容的整理,主要目的是以方便些没有到现场参加培训的碟粉们可以参阅学习。本文力求从理论到实践,尽量给读者一个整体了解USB CDC类的窗口。当然,阅读此文,还是需要基本的USB知识,这个请读者自行预备。3 J5 t4 w# I3 D6 o  C' c7 F

& \, V; k+ k6 l- w7 v" O2 USB CDC类基础理论知识介绍
& z8 m6 a4 }1 ], ?, [% g# l+ h# I, h0 A1 G2 e
2.1 USB CDC类、USB2.0标准与PSTN之间的关系
( s7 V: s! z: m  M5 i1 BCDC(Communication Device Class)类是USB2.0标准下的一个子类,定义了通信相关设备的抽象集合。它与USB2.0标准以及其下的子类的相互关系如下图所示:
. X4 |! ?# k# G1 I& w  G3 t 11.png
) r+ r$ z  A- `+ s' Y! a* y- P图 1 USB2.0标准、CDC、PSTN之间的关系
6 q9 w$ U9 j; {" [: C' P9 c7 }) T2 f; n: v4 T6 d& l0 g
如上图,USB2.0标准下定义了很多子类,有音频类,CDC类,HID,打印,大容量存储类,HUB,智能卡等等,这些在urb.org官网上有具体的定义,这里我们主要讲的是通信类CDC,CDC类下面,根据具体的应用场合,又有一些子类,这里我们主要讲的是PSTN(Public Switched Telephone Network)。从PSTN官方标准文档来看,PSTN子类是一个与电信相关的子类,而这里,我们只是将它作为一个普通的通信设备使用,并没有使用到它的一些电话特性。
  k+ z% a, \# l, O* k7 B4 {2 G% y5 ?) z/ f4 D0 [# H
2.2 从一个具体的CDC类通信数据说起* e& j2 D  h8 ?* `) @% ~6 @! ~
12.png / Y& O$ m3 [# ?9 }' F1 m
图 2 一个具体的CDC类设备通信数据
, e# k& c+ b- N# q$ N6 J
3 [- e0 r% T* y" ~如上图,USB CDC类的通信部分主要包含三部分:枚举过程、虚拟串口操作和数据通信。其中虚拟串口操作部分并不一定强制需要,因为若跳过这些虚拟串口的操作,实际上USB依然是可以通信的,这也就是为什么上图中,在操作虚拟串口之前会有两条数据通信的数据。之所以会有虚拟串口操作,主要是我们通常使用PC作为Host端,在PC端使用一个串口工具来与其进行通信,PC端的对应驱动将其虚拟成一个普通串口,这样一来,可以方便PC端软件通过操作串口的方式来与其进行通信,但实际上,Host端与Device端物理上是通过USB总线来进行通信的,与串口没有关系,这一虚拟化过程,起决定性作用的是对应驱动,包含如何将每一条具体的虚拟串口操作对应到实际上的USB操作。这里需要注意地是,Host端与Device端的USB通信速率并不受所谓的串口波特率影响,它就是标准的USB2.0全速(12Mbps)速度,实际速率取决于总线的实际使用率、驱动访问USB外设有效速率(两边)以及外部环境对通信本身造成的干扰率等等因素组成。, ~5 H) s5 y' A! t

9 }8 e4 B% B/ ~$ ~/ ]2.3 CDC类设备枚举过程
; N. F* {2 o' w6 }. sCDC类设备与其他标准USB设备枚举过程的并没有什么特殊的地方。在设备描述符内可以使用DeviceClass=0x00, SubClass=0x00, Protocol=0x00 表示此类信息在接口描述符内给出;或者也可以使用0x02,0x00,0x00;来表明该设备为CDC类设备。或者使用0xef, 0x02,0x01表示当前为复合设备。& l! g  r' ^, j. L$ B) c

1 f' d: E. o  ?9 j$ UCDC类设备在枚举过程中最主要的信息存储在配置描述符内:
- b& n6 z6 j1 Q! ~, X 13.png ' G' V5 f! P. p* F$ W
图 3 USB CDC类配置描述符的结构( E' R4 u7 }) F  t1 c+ e: }
! M8 B) b; s7 K8 i" U: ^' _
如上图所示,CDC类的配置描述符一般包含两个接口(Interface 0),一个控制接口,另外一个是数据接口(Interface 1), 除此之外,还有一个虚线指向的IAD(Interface Association Description),这个表示这个是不是可选的,得根据实际情况来确定其是否真实存在。3 z9 h9 G2 ]' {1 ]
3 V0 J5 V/ A8 l5 P8 p# i

" m6 @. \& Z2 o) z3 y# }# s' r2 d2 C' b2.3 1 控制接口% @4 ?: v6 H% O0 q
控制接口下包含类描述符合一个端点(ie:0x82),这个端点(中断传输模式)为异步通知消息的端点,当设备端需要向Host端发送异步消息时,可以通错此端点来发送,但平时主机端都是通过端点0来向设备端发送控制消息的,比如那些虚拟串口的操作指令等等。( `7 W) p4 ?" f; z$ t
- G1 M& Q! x! x: ?7 {3 _
除这异步通知端点外,控制接口下还包含CDC类相关描述符,这其中就包含Header描述符,Call Management描述符,ACM描述符以及Union描述符。这些功能描述符整合在一起用来描述此USB设备的一些功能特性,比如AT指令支持情况,ACM模型下的指令集支持情况,以及还有哪些接口与此接口一起对应Host端的一个功能(驱动)。0 V" a8 c9 b/ a
! A. `! z) F/ ]5 a& t+ v
在具体配置描述符内的控制接口内,功能描述符紧跟在接口描述符后,最后才是端点描述符。2 x/ k8 |, E' n* d

5 ^/ l1 U* l2 U2 }! H' U●   控制接口
& I! `/ ]8 `; V9 t 14.png
" @) K5 x& M( H2 H# j: t" o% C0 I% i图 4 控制接口描述符* D: e0 F1 u4 v
5 |# U* w! ?) i2 T' o5 z0 c
控制接口主要用来做设备管理和电话管理(可选),设备管理涉及到请求(request)和通知(notification),端点0一般用做请求,一般用来控制和配置设备的运行状态,而非0端点(0x82)一般用作异步事件通知,设备端通过此端点向主机端发送设备内部的一些事件,比如串口状态变化事件,电话状态改变等等。- ?5 R4 N- k6 p) `( C+ t9 _

1 _4 Z1 I- M2 n- T3 y6 [! a, g这里使用到ACM模型,后续将讲到这个模型,并且这里指明使用到V250版本的AT指令,这些指令是与电话相关的,但在我们这里讲的CDC通信实际上并不需要使用这些与电话相关的指令,它只是简单通信而已,这里指出AT指令也没有关系,只是实际不用它而已。* X- U2 J) I" H9 p  p
$ }+ x. b3 \, p  i
如上图,bNumEndpoints表示此接口下包含的端点数,这里为1个,即那个异步通知端点。bInterfaceSubClass为0x02,ACM通信模型,bInterfaceProtocol表示AT指令集的版本,虽然这里举例为V2.50,但实际上并没有使用到任何AT指令,因此它放8 F3 r# U8 N: S  k# G

1 U/ M1 @) a4 J& z9 i" `4 A●   Header功能描述符  C$ L$ q5 _/ w* U
15.png
) M+ E$ r5 Q! Y* {+ I图 5 Header功能描述符
& U1 U4 b* [+ n) S. q  i
3 q; a4 f6 ]/ j% l0 T  p  ?Header功能描述符表示功能描述符的开始,其他紧跟的内容就是此设备的功能描述符的内容。bcdCDC表示的是CDC的版本。! v' x( t* D6 b) x

# ]/ T! _9 v# s6 c+ [% n●ACM功能描述符
/ O% }$ M" [6 y3 C/ e 16.png
6 J& U8 \1 z" [/ `图 6 ACM功能描述符
# ]1 S# i+ W* E; b! f' N4 R' Y! R5 l
ACM(Abstract Control Model),即抽象控制模型,PSTN下,除了ACM模型还有还有DLM(Direct Line Mode), TCM(Telephone Control Model)。4 ]9 o3 B+ ?' C% Z( O8 v

4 p+ ?5 k9 h6 @8 I* }4 QPSTN定义了三种模型LM(Direct Line Mode),ACM(Abstract Control Model)和TCM(Telephone Control Model).
- z0 l7 B* U5 E4 j      •    DLM模型下,USB设备直接将模拟信号转化为数字信号,并放到USB上传输,数据接口直接使用Audio类传输音频数据,控制接口传输的也都是些比较原始的指令,比如脉宽设置,发送脉宽等等;
( r) Q. [% G: K) v( @- B/ ?      •    ACM模型则可以很好的支持AT V250指令集,数据接口可以使用Audio类或CDC DATA,控制接口传输的也是比较抽象的高层指令,比如设置、获取波特率,设置获取与通信相关的参数等等,而AT指令可以通过控制接口或者数据接口,这个在控制接口下的功能描述符Call Management Descriptor中指明。* {- f4 u7 E1 A; [" w; V) j- `0 q% g/ B
      •    TCM是指在物理上存在多个连接,可以将接口0和接口1分别对应到不同的物理连接上。
- Y+ C/ R+ t/ O# Y. c! P! l% W1 `此外,不同的通信模型对应的指令集合(控制指令)也是不同的,而上图中bmCapliblities为位图,内部bit0~bit3分别表示4类控制指令集在此设备的支持情况。
: ]/ d0 @, O0 x: F
# A3 ~7 y( Y: ~6 o7 e$ t9 J 17.png - a  B- w8 F( s/ [
图 7 ACM模型下的控制指令集$ N5 Q/ g- ?6 n+ M0 I$ ^0 b
1 B$ A8 z, S& m6 _) U# k2 t
如上表,为ACM模型下的指令集,但不是说,这些个指令就一定会在ACM模型下存在,此USB设备是不是支持此某个控制指令,还得看bmCapliblities这个参数具体对应位是否使能。2 B; `& ]9 w7 u3 i( u
! {; D# ]4 J' f, F' e% m, i
在实际的STM32 USB协议栈中,针对于CDC类,使用LineStateCoding,GetLineCoding,SetControlState类指令,用来读取,设置串口波特率以及串口的打开与关闭,这个具体的映射实现是通过主机端的驱动来实现;从设备端来看,当设备端收到这些来自主机端操作串口的控制指令时,这些指令具体怎么执行完全取决于设备端,也就说,所有的这些操作,比如设置波特率为115200,对于设备端来说这个只是个通过SetLineCoding指令传过来的一个参数而已,具体怎么处理这个参数,取决于设备端应用程序具体怎么处理这个参数,这个有用户来处理,这个115200波特率与USB本身的波特率12Mbps(全速)是没有关系的。9 F  M% G& g$ l+ u

/ w8 s$ M6 ^0 u/ o, s2 b. ^& X% a● Call Management功能描述符
% p7 v9 x8 V; S! E% w: n$ r 18.png
  {1 N5 j/ k( ]( V  [图 8 Call Management功能描述符8 [& {2 y! N. }' n4 q, G4 S

+ E$ w1 [& Q5 R$ G, NCall Management描述的就是电话相关的东西,AT指令集的支持情况。但在这里,我们并没有用到任何与电话相关的指令,因此bmCapabilities下的位图各个位都是为0:Bit0:是否支持电话相关的指令(AT指令集);Bit1:电话相关的指令(AT指令集)是否经过Comm. Class Interface; bDataInterface表示如有电话时,电话数据内容对应的接口号。+ I! g- w% ?- P1 u. u
" ]7 i; ^# h" w$ P7 `  h& V
●  Union功能描述符: \) N5 Y# X6 k7 t- o* G
19.png
7 X+ }0 ]0 l( C3 O! m图 9 Union功能描述符
* B9 Z! y1 }% G: H: j9 X& P0 i3 c. O  F. {! T
Union描述符就是用来告诉主机端,哪些接口是联合在一起的,对应着一个功能,这个功能需要主机装载对应的驱动来实现,因此,功能与驱动是一对一的关系。这里bControlInterface值为0,则表示接口0为控制接口,bSubBoardinateInterface0值为1,表示接口1为控制接口0的下级接口,即数据接口。在CDC标准中,控制接口是必须的,而数据接口是可选的,因此,数据接口为控制接口的附属。) p( |. t; k8 g8 z( Z7 \9 L
( g: m. M  T: f
2.3.2 数据接口8 c. b: A. R9 Z. p, |9 O' @
21.png : b6 |0 B" p$ a* b
图 10 数据接口
$ V8 I! j: P: L  g2 U- G2 Y; h& A) }7 g$ h$ A# n0 U* w) c/ C
数据接口比较简单,就是数据通信的,用到两个端点IN/OUT 0x81/0x01,为块传输类型。
: P) Y9 ^: z' ]  I7 Z% w: }
6 n7 n2 V, w  r% k# Z, T2 z# H2.3.3 IAD(Interface Association Descriptor)
: c3 \% g9 P  u1 W. `9 m* s, }4 |: Z# i 22.jpg
7 u; D7 }: V3 O0 l: p5 s- ~图 11 IAD描述符6 f( s6 \$ G* A: n+ l' ~/ R+ D

" u9 Y, ?- J+ q& cUSB刚出来的时候,一开始默认是一个接口对应一个功能,而一个功能对应着主机端的一个驱动,这在当时是OK的,但是后来,人们发现,需要多个接口对应一个功能的时候,比如这个CDC,除了数据接口外还需要控制接口,这在当时是没有这方面的统一标准,于是就出了Union来表示多个接口对应一个功能的情况。再后来,USB标准协会又增加了IAD。6 G/ t# h- {( N+ m  p6 u
: g/ f4 G( V9 j# g& s1 Q
IAD与Union类似,Union是旧版本下实现多个接口对应一个功能的功能描述符,而IAD是USB协会后来针对多个接口对应一个功能的情况而扩展的,旧的主机可能只支持Union方式,但IAD并不会影响旧版本主机对设备的识别,因为旧版本主机会通过Union来识别哪些接口是联合在一起的,对于IAD则跳过忽略;而新版主机则可以通过IAD来识别,跳过忽略老的Union,因此两者可以完美兼容,互不影响。因而主机端可以精确地装载对应的驱动。( P' M' y8 C/ f1 h. c
8 F# v% w  V7 Q2 a, ^' Z1 e/ a% G- ~
IAD只用在设备描述符中只用了device class code,并且指明了使用IAD来识别设备,比如bDeviceClass: Miscellaneous (0xef), bDeviceSubClass: Common (0x02), bDeviceProtocol: Interface Association Descriptor (0x01)就是一个例子; 0x02,0x00,0x00是另外一个例子。, r/ r) f1 h( _$ I/ j) I
5 `5 A, X, L+ \1 O4 o
如上图,bFirstInterface值为0,表示第一个接口个接口0,默认为控制接口;bInterfaceCount值为2,标志此功能总共存在2个接口,那么第二个接口就是接口1,因为USB2.0 IAD ECN补充标准规定,这里提到的接口号必须是连续的,也就是说,接口0为第一个控制接口,那么接口1则为数据接口。" a7 U/ ^8 h1 J- H, w( d' P) \

, {& |; ^5 x$ a- f$ d4 G下面我们来个具体的IAD例子:/ w( c1 O, u  J' u! t" ^
23.png , ~1 x. q! t! N7 X6 R2 k
图 12 IAD存在时的设备描述符% {/ W1 i8 r2 F  s3 h, I# x
7 H. {! Y. g4 ^) p& K: L
24.png
8 [5 {  ~" E; J( T7 Q" F图 13 IAD
. z& [% ~1 x* q8 x
# i8 g) Y/ v( S3 I' O如上图所示,一般IAD存在的情况下,在设备描述符中DeviceClass等三个参数不再都为0x00,图12中为0xef,0x02,0x01,这个表示是复合设备,此时,可以使用IAD来定义多个接口联合起来对应一个USB驱动。从IAD中可以看出,bFunctionClass参数就定义了此IAD表示的设备为CDC类设备,ACM模型。就这样,通过IAD描述符,实现了与Union功能描述符相同的功能。9 o3 X7 V2 U) I# ]" J1 g3 \; n

( H2 [7 e8 z, b, l4 f, g6 M9 X2.3.4 ACM模型& g6 x. d/ X$ p1 _( ~& N
之前我们已经在控制接口中的功能描述符中已有对ACM(Abstract Control Mode)模型的简介,也有提到过,在PSTN中,除了ACM模式,还有TCM,DLM模式。这三种模式,不同的模式下包含的控制指令集是不尽相同的,有部分控制指令可能同时存在两个或三个模式下,除了控制指令,还有异步通知消息,这个在三个不同模式下也是不相同的。: Q- H7 o& G) F/ N4 Y
31.jpg
; E! A# }0 I2 i" b图 14 ACM模式下的控制指令集( G1 |+ _1 _5 Q* U: f# P+ Q7 y
32.jpg
) d  ]3 ^) C3 n7 b; ]% @3 j1 \6 m7 o图 15 ACM模式下的异步通知消息
) \% R. w" {  z/ ^; E+ u 33.jpg ( S! \: I$ i' a2 `$ p
图 16 DLM模式下的控制指令集
3 Z3 Y- l- ]: |; d; {6 K 34.jpg
. o( u% O" z  h: n; b# ]7 o# ~  u图 17 DLM模式下的异步通知消息
7 z, }+ \* K- a! p
41.jpg
% N8 ]4 L9 o0 D# b( Q0 E1 X图 18 TCM模式下的控制指令集2 l+ m) i1 v4 p' I9 d3 X5 c$ H
42.jpg 3 U& p8 h/ C  V: n
图 19 TCM模式下的异步通知消息
' s0 q2 ], q. H5 y9 R8 d
- q4 n. M) b0 U由图14~19可知,当设备选择了某个模型后,其控制指令集和异步通知消息也就得符合此模式下的对应集合,否则则不符合标准。这里我们主要是使用到ACM模式,因此,此ACM模式下的有Host端发现Device端的控制指令和有Device端向Host端发送的异步通知消息都是固定的那么几条指令或消息,但并不是说,只要是ACM模式,那么就表示此模式下的所有控制指令和异步通知消息都必须支持。控制指令在设备端的控制接口描述符中的ACM功能描述符中的bCapabilities字段有按
7 j% w& E$ b7 ~- h9 Z位定义ACM模式下的控制指令的支持情况,而异步通知消息,则完全看device端的应用情况是否需要,并没有在任何描述符中指出那些消息是否支持。
9 J! x& O% H' S- m7 V% ]& f
2 M% [' N6 x- r5 U. Q: X( E在ST给出的CDC例程中,主要是使用到了SetLineCoding指令来设置和修改虚拟串口的波特率,使用GetLineCoding来获取当前波特率,使用SetControlLineState来打开或关闭串口,这种操作是在Host端CDC驱动来具体映射实现的,至于Device端收到这些个控制指令该怎么处理,就是另外一回事了,Device端也可以完全不做任何处理,有CubeMx自动生成的CDC类代码就是这样,对接收到的任何控制指令到没有做任何处理,当然,如果需要的话,则按应用的需要来处理,这个完全取决于用户。
: J2 O5 q7 G; L0 V4 c 41.png 4 C  w/ j" M& H/ E! a1 x9 C* C
图 20 控制指令操作虚拟串口
* Z6 t: v) N, I2 m, O7 y* c, H 42.png
) f) _% r/ k) t# G; \图 21 一个ACM模式下的异步通知消息例子
* A5 I7 _+ U& ]/ M5 O& V7 e
7 f& P0 j* g$ F% p* H( m9 d3 CDC类软件框架介绍
( }. n: ~! `. e" L! R
7 _) y+ G) P# k* C9 k. P3.1 CDC软件框架简介# P/ a4 X, W! W8 ~8 p
43.png 4 ]( [9 A8 \# V- ^) J6 R
图 22 CDC类软件框架
' D: w0 d) K1 I3 s0 a8 b" j8 F9 d  j3 I! k; ?' d, B' h7 ~. A' H4 e
如上图所示,黄色USB Device Core部分为USB设备库文件,属于中间件,它为USB协议栈的核心源文件,一般不需要修改:, g4 c1 P! N5 x9 q* N/ D
●    USB Device Core中,Log/debug为打印/调试开关;; L" Y; @2 g* J! s( S$ Q, C/ ~
●    core为USB设备核心;- _7 p+ i! L6 [6 z
●    USB request中定义了枚举过程中各种标准请求的处理;3 ^  ?' [. e6 L
●    I/O request为底层针对USB通信接口的封装。
: _; T- U6 t, l* a, ~1 S% W
! b% o; Y# K, t黄色USB Device Class部分为USB类文件,也属于中间件,USB设备库,目前ST DEMO中支持的类有HID, Customer HID, CDC, MSC, DFU, Audio, ST提供了这些类的源码框架,其他的Class或者是复合设备需要自己根据实际需求情况进行扩展或定制。如果用户需求只是需要一个标准类,比如CDC通信,那么最好就使用现成的代码,不需要做任何修改就可以实现这个CDC类通信的功能。
% A& B- @7 b5 l$ Q$ |) k
) \: t  [* r5 I* x* C' \蓝色USB Device HAL Driver为HAL库部分,是对USB外设接口的封装,属于底层驱动,不需要修改,它分为PCD和LL Driver,PCD处于LL Driver之上。$ L4 ^1 L" U3 p, J

% F) z7 s+ T. P! @洋红色USB Device Configuration为USB配置封装,位于USB底层HAL层驱动与中间件USB协议栈之间,一方面向上层(USB设备库)提供各种操作调用接口,另一方面,向底层USB驱动提供各种回调接口。正是由于它的存在,使得USB协议栈(USB设备库)与底层硬件完全分离,从而使USB设备库具有更加兼容所有STM32的通用性。USB Device Configuration为开放给用户的源文件,用户可以根据自己的某些特殊需要进行修改,也可以使用默认的源文件,假如没有任何特殊要求的话,我们使用默认即可。
8 t# Z" ~% ]" b5 Z  @0 x, X4 I9 c$ l# K" E. h
Application为应用层,USB Device Class有可能将自己对应该的操作接口封装在一个操作数据结构中,由应用来具体实现这些操作,在系统初始化时,由应用将已经定义好的操作接口注册到对应的USB类中,比如usbd_cdc_if, 就这样,使得应用层的应用代码与属于中间件层的USB协议栈分离。同时,USB协议栈会将一些字符串描述符放到APP中,当USB初始化时将这些已经定义好的字符串通过指针初始化到USB协议栈中,以便后续需要时获取。
' D5 Z! r3 w6 m2 m+ |; w; T/ R
( q) A8 P8 r/ _% {3 z+ }) t8 ^* m9 N: G  g
3.2 工程源码文件与软件框架的对应关系
1 s6 J6 {; c6 J! Z5 K 44.jpg 5 |& V) v* |  Y& V8 \+ k9 ^6 S# S& v
图23 CDC工程中源码与软件框架的对应关系
6 e# d; T7 P" q: K4 r
% @/ H$ k% W9 z) w- t9 k3.3 USBD内核与USBD_CDC的关系" F. R* s& H0 ?- U2 v4 \: ]( `
3.1节中,我们已经提到过ST官方Cube库中提供的官方USB协议栈,主要是包含了USBD内核与USB各种类。USBD内核一般是固定的,用户一般不需要修改,但USBD类,如果用户需要修改或者扩展,比如复合设备或者用户自定义设备,还有就是,ST目前官方提供的USB设备类的DEMO程序并没有囊括所有USB类,因此,若用户需要实现这些官方提供DEMO之外的USB类时,则用户需要根据自己的需要来定制化自己的USB类,那么又该如何开始呢?
1 w7 k; i) A5 E+ j9 ^! t9 X6 g5 s0 i% n% e3 s4 ~2 y
我们已经知道,ST提供的USB协议栈中已经有USBD内核,且这个内核源文件一般是不需要修改的,那么这里我们需要自定义这么一个USB类,那么我们首先得知道,这个我们需要自定义的USB类是如何与USBD内核打交道的?
; W1 o1 q* Y2 ]. }9 I5 k8 @. H( d  D9 b
' x2 ^$ j9 D& y- fUSB协议栈将所有USB类都抽象成一个数据结构:USBD_ClassTypeDef,其定义如下所示:7 f4 _5 C- }- L4 t
45.jpg
$ D$ ]* ~4 a) F- t, [0 n3 r 46.png 6 Z8 `* r! k1 C, L

/ [8 ~1 }  D3 j. q, b7 h8 ~& ~这个结构体是一个抽象类,定义了一些虚拟函数,比如初始化,反初始化,类请求指令处理函数,端点0发送完成,端点0接收处理,数据发送完成,数据接收处理,SOF中断处理,同步传输发送未完成,同步传输接收未完成处理等等;用户在实现自己具体的USB类的时候需要将它实例化,USBD_ClassTypeDef结构体是USBD内核提供给外部定义一个USB设备类的窗口,而USB类文件(如usbd_cdc.c)实际就是实现这个结构体具体实例化的过程。最后将这个具体实例化的对象注册到USBD内核的同时, USBD内核与USBD类也进行了关联。  q5 p% A' I6 w- T6 w- K" |8 ^
47.jpg
) t5 K1 r% t4 \5 E图 24 USBD核与CDC类的关系0 E6 r/ X1 ~8 x: ]) Z8 b. x

2 Y6 p  g- V6 q......   ......  
9 J. f" P9 G) M$ [* x' g2 q- I8 T

) d0 P# T9 H1 j& B# c
1 g- C# G7 M9 z) W* s由于帖子过长,更多详细信息下方文档中的PDF及代码!

1 r3 i7 K! f2 X! f9 |/ S# Q4 T3 s8 r, _$ B
) ~7 Z$ g. ~: {" U% b( s- `: I# J- ]  m

: B8 x  D5 r3 `
! O" [$ B* W7 N+ M4 \
* q6 u$ B& a; ^1 s8 a- D
文档下载" }: l9 y# C) W$ J, g/ S

& _1 `- H. F0 N* B
# y9 I/ H# w. N- l/ A
更多实战经验
( S4 \' F5 @$ n  b4 q: F4 R
收藏 9 评论15 发布时间:2017-7-28 17:27

举报

15个回答
creep 回答时间:2017-7-28 17:46:16
牛逼。         
Paderboy 回答时间:2017-7-28 20:10:27
太牛逼。。
Stm32McuLover 回答时间:2017-7-28 20:27:31
破总牛逼
群星闪烁 回答时间:2017-7-30 18:24:36
牛逼,写的非常详细
asmhai 回答时间:2017-9-12 10:45:05
初级入门中,上面没看明白!!!保存下来。
asmhai 回答时间:2017-9-12 11:16:31
签到签到
枫天123 回答时间:2017-12-7 16:09:31
看不懂额
, N* Q. W8 q) h2 ~& r; a
zzfd97 回答时间:2017-12-14 14:31:17
太牛逼。。
wylew 回答时间:2018-1-11 15:17:01
您好!我想问下,如果在基于CDC类ACM上开发组合设备,就是基于一个设备上配置多个接口设备功能,即CDC_ACM+Mass Storage这样的有问题吗?
Mr.Luav 回答时间:2018-2-4 14:01:11
好资源啊   学习!
路平 回答时间:2018-4-27 10:49:22
厉害
liuer2004_82 回答时间:2018-5-22 21:33:56
讲解有深度。。。。。。。。。3ks
ZCShou 回答时间:2018-7-28 18:30:15
楼主有没有原培训资料的附件啊,正常培训资料里有个 CDC_training.tdc 的USB 报文
467386895 回答时间:2020-11-17 21:27:45
MARK
12下一页

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版