USB--USBD缓冲区相关说明
前沿
我们在查看用户手册的时候,会发现USBD的寄存器地址有两块,一块是0x40005C00 - 0x40005FFF,一块是0x40006000 - 0x400063FF,
本篇为大家讲解这两个寄存器地址有什么区别和联系。
0x40005C00是USB寄存器的基地址,所有其他USB寄存器会相对于基地址有所偏移。
0x40006000是USB的SRAM的地址(可以理解为0x40006000地址处挂了一块512Byte的SRAM),该地址不仅存放着USB通信过程中的数
据,还存放着缓冲区描述表,该描述表存放USB的数据信息,包括端点数据的相对地址、端点数据长度以及端点的数据。
因此0x40005C00和0x40006000地址没有必然的联系,只是0x40005C00是USB寄存器的基地址,0x40006000是存放USB数据是SRAM的起始地址。
接下来重点讲解0x40006000这块RAM。
1,USBD_BTABLE寄存器介绍。
字面意思很好理解,该寄存器存放着上面缓冲区描述表位于SRAM中的位置,但需注意如果该寄存器值为0x200,
那么缓冲区描述表起始位置就是为0x0x40006400(原因是因为USB模块是16bit寻址,而APB1总线是32bit寻址,
所以每32bit数据中只使用16bit作为有效数据)。不过一般为了好分配空间,都是设为0.
2, 512 SRAM介绍
先看下缓冲区描述表
缓冲区描述表分为:
- 发送缓冲区地址寄存器n(n=[0..7])
- 发送数据字节数寄存器n(n=[0..7])
- 接收缓冲区地址寄存器n(n=[0..7])
- 接收数据字节数寄存器n(n=[0..7])
一共8个端点,那缓冲区描述表就由4*8=32个寄存器来描述,所以如果8个端点全用完那么总大小为32*2=64个字节。
那么512字节缓冲区就只剩下512-64字节用于接收/发送数据。
我们发现6000-6400这个区间是1K大小,为什么说是512字节大小呢?
原因:因为USB模块是16bit寻址,而APB1总线是32bit寻址,所以每32bit数据中只使用16bit作为有效数据。
可能听起来有点不好理解,举个例子:一个人走路风格是一步两个台阶,那么奇数台阶他就踩不到,所以我们奇数台阶
就不能存数据,把数据放在偶数台阶,奇数空间保留即可。
排完了发送缓冲区地址寄存器、发送数据字节数寄存器、接收缓冲区地址寄存器和接收数据字节数寄存器的地址之后,地址所存的数据就在剩下的空间中
按照上述寄存器中的地址值来存储端点通信的数据了。
3,例程缓冲区分配举例讲解:
那么1处就是设置的BTABLE寄存器的值,因为缓冲区描述表占用64字节,那么自然2处端点0只能从0x40开始了。
后面就是按需排列了,每个端点需要最大多少缓冲区,就分配多大,我这里都是给的64字节。
问题1:基于上述案例,我端点0起始地址不设成0x40可不可以
答:可以,上述案例用到0,1,2,3,4五个端点,那么实际就占用了5*8=40个字节空间,对应十六进制起始地址就是0x28,所以
设成0x28也是可以的,这样还可以节省一定空间。
问题2:如果上述我只用到0,1,2,4四个端点,断电五不用,那起始地址是不是就要减小8
答:不是,端点3相关寄存器依然会预留在2-4中间。这样会浪费几个字节空间,虽然也是可以利用的,但用起来较麻烦。
所以还是尽量使用连续的端点号,不要跳跃使用。