USB端点的共享接收缓冲区?

USB端点的共享接收缓冲区?,usb,microcontroller,Usb,Microcontroller,我正在为微控制器开发一个USB设备驱动程序(Atmel/Microchip SAMD21,但我认为这是一个一般性的问题)。我需要控制和数据的多个端点,USB硬件使用每个端点描述符(除其他外)定位输入和输出数据的缓冲区 由于IN数据是由主机自行决定轮询的,因此每个端点都有自己的IN缓冲区是有意义的,因此任何端点的数据(如果有要发送的数据)在轮询时都立即可用 但就设置和输出事务中的传入数据而言,我想到,通过配置所有端点以使用共享缓冲区,可以节省内存。考虑到USB事务的性质,一次只能发生一个这样的事务

我正在为微控制器开发一个USB设备驱动程序(Atmel/Microchip SAMD21,但我认为这是一个一般性的问题)。我需要控制和数据的多个端点,USB硬件使用每个端点描述符(除其他外)定位输入和输出数据的缓冲区

由于IN数据是由主机自行决定轮询的,因此每个端点都有自己的IN缓冲区是有意义的,因此任何端点的数据(如果有要发送的数据)在轮询时都立即可用

但就设置和输出事务中的传入数据而言,我想到,通过配置所有端点以使用共享缓冲区,可以节省内存。考虑到USB事务的性质,一次只能发生一个这样的事务,每个端点拥有自己的缓冲区似乎是浪费

显然,这种方法需要足够快地处理事务中断,以便释放共享缓冲区,并及时为下一个事务做好准备,但这已经是控制端点的要求,其中一些设置事务之后会立即执行OUT

那么,假设时间安排是可行的,那么这种方法不起作用还有其他原因吗?

可能没有

通常,微控制器上的USB模块通过跟踪已写入数据的数据包缓冲区来处理数据包,并在从计算机接收更多数据并覆盖缓冲区之前,等待固件说明已完成对缓冲区的处理。如果端点没有可用于接收更多数据的缓冲区,但计算机向端点发送OUT数据包,则USB模块通常使用NAK数据包响应计算机,该数据包告诉计算机应稍后重试。在这种情况下,您的固件可能需要处理输出数据包所需的时间

通过将多个端点配置为使用同一缓冲区,您将搞乱这个系统。当您在任何端点上接收到输出数据包时,USB模块(可能)不知道多个端点使用相同的缓冲区,因此它不会在其他输出端点上发出NAK数据包。如果它立即收到另一个OUT数据包,它会将其写入同一个缓冲区,覆盖上一个数据包。因此,每当您收到一个数据包时,您的代码都必须以尽可能快的速度执行一些操作,如从该缓冲区复制数据、禁用其他输出端点或重新分配缓冲区

即使你能真正做到这一点,这也意味着你节省一点内存的计划将USB事件的服务变成了一个实时任务(即,一个需要你的代码在几微秒内做出响应的任务)。如果您想在以后向系统中添加另一个实时任务,这将非常困难,因为您必须随时准备好被USB处理代码中断

SAMD21有大量内存(32KB),因此您可能不需要担心优化这部分内存。

我同意。你没有提到你正在创建的设备的速度。低速缓存只需要几个8字节的缓冲区。全速,几个64字节的缓冲区。高速,可能是8个64字节的缓冲区,具体取决于您的使用。一个超高速设备,你仍然只会说一些512字节的缓冲区

我将为每个端点创建一个环形缓冲区。这样您就不会四处移动数据。您只需使用指向内存环中某个项的指针。具有一个控制端点、一个中断端点和两个批量端点的全速设备,每个端点每个环有16个64字节的条目,仍然只有4k RAM的总量,占RAM总量的1/8


但是,我不熟悉SAMD21,因此请检查规范以确保它能正常工作。

很有趣。我还没有读到足够多的USB规范,所以我想知道是否存在主机时间限制,这些限制指定了设备上相同或不同端点的数据包之间的最小间隔。看起来,除了低级别的数据包间隔(如您所说,几微秒),交易似乎没有更高级别的时间限制。这意味着在任何数据包(设置或输出)之后,我们需要准备好尽快接收下一个数据包。这当然意味着最小的中断处理和双/循环缓冲可能很快变得必要——但这甚至适用于单端点。但问题仍然存在:如果我有多个端点,那么如果我决定的话,它们为什么不能共享一个这样的缓冲/处理机制呢?我还没有使用过SAMD21的USB模块,但是如果它设计得很好,你实际上不需要中断,因为当你从PC接收数据时,USB模块会自动将其存储在数据包缓冲区(如果可用)中,如果没有数据包缓冲区,则会使用NAK响应计算机。计算机将重试。不让多个端点共享同一缓冲区的技术原因是USB模块可能不是为此而设计的;当您在端点a上接收数据包时,它不会自动NAK所有其他OUT端点上的数据包。假设您有两个名为a和B的OUT端点共享同一缓冲区。(让我们暂时忽略控制端点。)计算机向端点A发送一个OUT数据包,该数据包存储在缓冲区中。现在,在计算机向端点B发送数据包并覆盖第一个数据包之前,您的代码必须以尽可能快的速度重新配置端点B或从该缓冲区中复制数据。如果端点具有不同的缓冲区,则可以在处理OUT数据包之前无限期等待,并且不会丢失任何数据。这要归功于USB的裸体机制。非常好的观点,可能值得一写作为自己的答案!