微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我无法在基于自定义 USB CDC 类的 STM32 设备上接收超过 64 个字节

如何解决我无法在基于自定义 USB CDC 类的 STM32 设备上接收超过 64 个字节

目前我尝试将 720 字节从 Windows 应用程序发送到自定义 STM32 设备(现在为了测试目的,我使用 Blue Pill - STM32F103xxx)。啊,我忘了指出我完全是编程新手:)。所以在设备端我有 1000 字节的缓冲区用于接收和发送(感谢 STMCube 为此)。带有终端程序(数据包小于 64 字节)的测试设备工作。然后我重新编写 Microsoft 示例之一,以便能够向设备发送更多数据。 Windows 上使用的设备驱动程序是“usbser.sys”。简而言之,我的控制台程序执行以下操作:

  1. 计算 SINE weave (360) 样本 - 16 字节大小
  2. 将它们作为 720 字节发送到 USB 设备(COM 端口的字节大小协议) 我的问题是进入设备的字节数不超过 64 个。 我在某处读到这个原因可以是内置的 Rx,Tx Windows 缓冲区(64 字节长,在互联网上的某个地方提到过),为此我在下面的代码中插入:
    • SetupComm(hCom,1000,1000) 希望这能解决我的麻烦,但没有。下面是“我的”代码,有什么想法可以解决这个问题吗?
+-------+------+
|  Id   | Mode |
+-------+------+
| 16607 |    1 |
+-------+------+

解决方法

USB 批量端点实现基于流的协议,即无限的字节流。这与基于消息的协议形成对比。因此 USB 批量端点没有消息、消息开始或结束的概念。这也适用于 USB CDC,因为它基于批量端点。

在较低的 USB 级别,字节流被拆分为最多 64 个字节的数据包。按照 USB 全速标准,数据包不能大于 64 字节。

如果主机发送相隔超过 1 毫秒的小数据块,它们将在单独的数据包中发送和接收,看起来 USB 是一种基于消息的协议。但是,对于超过 64 字节的块,它们会被拆分为更小的数据包。如果发送的小块间隔小于 1ms,主机会将它们合并成更大的数据包。

您的设计似乎要求对数据进行分组,例如问题中提到的 720 字节组。如果这是一项要求,则必须实施分组,例如首先发送组的大小,然后发送数据。

由于较大的组被分成 64 字节的块,并且每个数据包都会调用接收回调,因此必须加入数据包,直到完整组可用。

还要注意您当前代码中的一些问题(请参阅 usbd_cdc_if.c,line 264):

  USBD_CDC_SetRxBuffer(&hUsbDeviceFS,&Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  NewDataFromUsb = *Len;

USBD_CDC_SetRxBuffer 为要接收的下一个数据包设置缓冲区。如果你总是使用相同的缓冲区——就像在这种情况下——它是不需要的。初始设置就足够了。但是,如果当前数据包不包含完整组,则可以使用它来设置新缓冲区。

尽管有它的名字,USBD_CDC_ReceivePacket 没有收到数据包。相反,它允许接收下一个包裹。仅当缓冲区中的数据已被处理并且缓冲区已准备好接收下一个数据包时才应调用它。您当前的实现存在缓冲区在处理之前被覆盖的风险,特别是如果您发送一组超过 64 个字节的数据包,这可能会导致快速连续的数据包。

请注意,此处并未提及 Windows。 Windows 代码似乎没问题。更改为 Winusb.sys 只会让您的生活更艰难,但不会让您的数据包大于 64 字节。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。