【问题标题】:Shared receive buffer for USB endpoints?USB端点的共享接收缓冲区?
【发布时间】:2019-11-18 13:24:00
【问题描述】:

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

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

但就来自 SETUP & OUT 事务的传入数据而言,我想到可以通过将所有端点配置为使用共享缓冲区来节省内存。考虑到 USB 事务的性质,一次只能发生一个这样的事务时,每个端点都有自己的缓冲区似乎很浪费。

显然,这种方法需要足够快地处理事务中断,以便释放共享缓冲区并及时为新事务做好准备,以应对下一个事务可能是 - 但这已经是控制端点的要求,其中一些 SETUP事务紧跟在 OUT 之后。

那么,假设时机可行,是否还有其他原因导致这种方法行不通?

【问题讨论】:

    标签: usb microcontroller


    【解决方案1】:

    可能不会。

    通常,微控制器上的 USB 模块通过跟踪它已将数据写入哪些数据包缓冲区来处理 OUT 数据包,并等待您的固件说它已完成处理缓冲区,然后再从计算机接受更多数据并覆盖缓冲区。如果端点没有可用于接收更多数据的缓冲区,但计算机向端点发送了一个 OUT 数据包,则 USB 模块通常会以 NAK 数据包响应计算机,告诉计算机它应该稍后重试。在这种情况下,您的固件可能需要很长时间才能处理 OUT 数据包。

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

    即使您实际上可以让它工作,这意味着您节省一点内存的方案会将 USB 事件的服务变成实时任务(即需要您的代码在几个微秒)。如果你以后想在你的系统中添加另一个实时任务,那将是非常困难的,因为你总是要准备好被你的 USB 处理代码打断。

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

    【讨论】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-08
      • 2012-12-05
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      相关资源
      最近更新 更多