USB -- STM32F103双缓冲端点讲解(续)

目录

链接快速定位

前沿

1 为什么要设计双缓冲端点

2 双缓冲端点的原理

3 双缓冲端点的使用


链接快速定位

USB -- 初识USB协议(一)

源码下载请参考链接:USB -- STM32-FS-USB-Device驱动代码简述(二)

USB -- STM32F103虚拟串口bulk传输讲解(三)

USB -- STM32F103自定义HID设备及HID上位机中断传输讲解(四)

USB -- STM32F103 U盘(MassStorage)SDIO接口SCSI协议Bulk传输讲解(五)

USB -- STM32F103 USB DFU设备固件升级(IAP)控制传输讲解(六)

USB -- STM32F103 USB AUDIO(音频)Speak同步传输(Out传输)讲解(七)

USB -- STM32F103 USB AUDIO(音频)Microphone同步传输(In传输)讲解(八)

USB -- STM32F103 USB VIDEO(视频)Camera同步传输讲解(九)

USB -- STM32F103复合设备(HID+MassStorage)传输讲解(十)

前沿

前面的章节带大家认识了Bulk传输和同步传输,STM32F103的USB为了提高Bulk和同步传输的传输效率,设计了一种双buffer的传输机制,下面就让博主为大家简单的讲解一下双缓冲端点的原理,如有错误,请大家指正。

1 为什么要设计双缓冲端点

引用STM32F103的中文手册对双缓冲端点的解释:

USB标准不仅为不同的传输模式定义了不同的端点类型,而且对这些数据传输所需要的系统要求做了描述。其中,批量端点适用于在主机PC和USB设备之间传输大批量的数据,因为主机可以在一帧内利用尽可能多的带宽批量传输数据,使传输效率得到提高。然而,当USB设备处理前一次的数据传输时,又收到新的数据分组,它将回应NAK分组,使PC主机不断重发同样的数据分组,直到设备在可以处理数据时回应ACK分组。这样的重传占用了很多带宽,影响了批量传输的速率,因此引入了批量端点的双缓冲机制,提高数据传输率”。

当然这个解释不仅适用批量传输,同样也适用同步传输,只是同步传输没有ACK应答机制,最终的目的也是为了提高传输效率。

我们这里主要是以批量传输来讲解,同步传输类似。

2 双缓冲端点的原理

下图是普通端点的传输示意图(OUT包),正常的流程是PC下发数据到Buffer,USB读取Buffer中的数据。

但是当PC发送的数据过多和过快的时候,USB模块还没来得及取完Buffer的数据的时候,就会给PC回复NAK指令,此时PC就一直下发相同数据,直到USB把Buffer中的数据读取完回复ACK。

USB -- STM32F103双缓冲端点讲解(续)_第1张图片

下图是双Buffer原理示意图(OUT包),它类似一种乒乓的概念。也就是当USB模块读取其中一个Buffer的数据的时候,另一个空闲的Buffer能够及时接收PC下发的数据。这样就能提高USB的传输效率。

USB -- STM32F103双缓冲端点讲解(续)_第2张图片

可以这样理解,普通传输就像串行传输一样,需要一步一步的传输(发完之后再接,接完之后再发);而双缓冲端点就像并行传输一样,使数据能够同时进行发送和接收(只是这里接收的数据是上一次发送的数据)。

3 双缓冲端点的使用

以下是STM32F103中文手册对双缓冲端点使用的解释:

使用双缓冲机制时,单向端点的数据传输将使用到该端点的接收和发送两块数据缓冲区。数据翻转位用来选择当前使用到两块缓冲区中的哪一块,使应用程序可以在USB模块访问其中一块缓冲区的同时,对另一块缓冲区进行操作。例如,对一个双缓冲批量端点进行OUT分组传输时,USB模块将来自PC主机的数据保存到一个缓冲区,同时应用程序可以对另一个缓冲区中的数据进行处理(对于IN分组来说,情况是一样的)。
因为切换缓冲区的管理机制需要用到所有4个缓冲区描述表的表项,分别用来表示每个方向上的两个缓冲区的地址指针和缓冲区大小,因此用来实现双缓冲批量端点的USB_EpnR寄存器必需配置为单向。所以只需要设定STAT_RX位(作为双缓冲批量接收端点)或者STAT_TX位(作为双缓冲批量发送端点)。如果需要一个双向的双缓冲批量端点,则须使用两个USB_EpnR寄存器。
为尽可能利用双缓冲的优势,达到较高的传输速率,双缓冲批量端点的流量控制流程与其他端点的稍有不同。它只在缓冲区发生访问冲突时才会设置端点为NAK状态,而不是在每次传输成功后都将端点设为NAK状态。
DTOG位用来标识USB模块当前所使用的储存缓冲区。双缓冲批量端点接收方向的缓冲区由DTOG_RX(USB_EpnR寄存器的第14位)标识,而双缓冲批量端点发送方向的缓冲区由DTOG_TX(USB_EpnR寄存器的第6位)标识。同时,USB模块也需要知道当前哪个缓冲区正在被应用程序使用,以避免发生冲突。由于USB_EpnR寄存器中有2个DTOG位,而USB模块只使用其中的一位来标识硬件所使用的缓冲区,因此,应用程序可使用另一位来标识当前正在使用哪个缓冲区,这个新的标识被称为SW_BUF位。下表列出了双缓冲批量端点在实现发送和接收操作时,USB_EPNR寄存器的DTOG位和SW_BUF位之间的关系。

缓冲区标识位

作为发送端点

作为接收端点

DTOG

DTOG_TX(USB_EPxR寄存器的第6位)

DTOG_RX(USB_EPxR寄存器的第14位)

SW_BUF

USB_EPxR寄存器的第14位

USB_EPxR寄存器的第6位

USB模块当前使用的缓冲区由DTOG位标识,而应用程序所使用的缓冲区由SW_BUF位标识,这两个位的标识方式相同,下表描述了这种标识方式。

端点类型

DTOG位

SW_BUF位

USB模块使用的缓冲区

应用程序使用的缓冲区

IN端点

0

1

ADDRx_TX_0/COUNTx_TX_0

ADDRx_TX_1/COUNTx_TX_1

1

0

ADDRx_TX_1/COUNTx_TX_1

ADDRx_TX_0/COUNTx_TX_0

0

0

无(1)

ADDRx_TX_0/COUNTx_TX_0

1

1

无(1)

ADDRx_TX_0/COUNTx_TX_0

OUT端点

0

1

ADDRx_RX_0/COUNTx_RX_0

ADDRx_RX_1/COUNTx_RX_1

1

0

ADDRx_RX_1/COUNTx_RX_1

ADDRx_RX_0/COUNTx_RX_0

0

0

无(1)

ADDRx_RX_0/COUNTx_RX_0

1

1

无(1)

ADDRx_RX_0/COUNTx_RX_0

 (1)端点处于NAK状态。

如果是批量传输,使用双缓存端点需要使用下列方式设置:

  1. 将USB_EPnR寄存器的EP_TYPE位设为’00’,定义端点为批量端点
  2. 将USB_EPnR寄存器的EP_KIND位设为’1’,定义端点为双缓冲端点

你可能感兴趣的:(usb,stm32,嵌入式硬件,单片机,usb)