首页 文章

USB:具有中断传输和原始HID的低延迟(<1ms)

提问于
浏览
1

我有一个项目需要定期读取外部IMU陀螺仪数据并将数据发送到Android手机 .

我正在使用一个meensy 2.0板通过I2C查询IMU并使用原始HID通过USB发送它 . 我正在使用RawHID变量,该变量在teensyduino的usb_rawhid的usb_api.h中声明 .

我已经读过使用中断传输的全速USB可能有1ms的最大延迟,并希望实现这1ms的最大延迟 . 我不确定要寻求什么来实现这个最大延迟,并希望了解指针 . 我的最终目标是每2 ms(500 Hz)接收一次陀螺仪数据 .

我所知道的一些事情可能是一个问题:

1)我已将RAWHID_TX_SIZE更改为6个字节(陀螺仪值仅需6个字节),RAWHID_TX_INTERVAL设置为1 ms(最快) . 当前在我不需要的接口中指定了OUT endpoints ,我不确定删除它是否可以改善延迟 .

2)Android将teensy识别为“hiddev USB HID v1.11 Device” . 我不确定这是完整的原始HID还是它试图解析它 . Teensy正在使用上面指定的原始HID .

3)在Android中,特定线程尝试在UsbRequest上进行queue(),然后是requestWait() . 数据到达时的处理速度非常快(即:将其存储在全局变量中),但我受线程调度程序的支配 .

所以这些是我所知道的一些指针(并不完全确定它们如何影响最大延迟) . 我很乐意听取人们的反馈,并指出如何改善我的最大USB延迟的新方向 . 查找有关减少中断传输的USB延迟的信息很吓人 .

1 回答

  • 2

    对于USB,它都是轮询 . 每1 ms你有一个“帧”,由没有或多个传输描述符组成,其中每个传输描述符告诉USB控制器轮询哪个USB设备 .

    通常,USB控制器使用传输描述符开始帧以进行中断传输 . 这意味着使用单个中断传输描述符(几乎)保证每ms进行一次轮询 . 如果你的设备有一个要发送的中断,它会在轮询时返回它;所以你最坏的情况下你会得到1毫秒的延迟 .

    可以要求USB控制器不经常轮询设备(例如,等时传输) . 也可以要求USB控制器在相同的1ms帧中多次轮询设备;但是因为它通常会中断传输描述符,所以你几乎可以在几乎同时进行两次轮询,并且之间存在“差不多1 ms”的间隙,因此这对最坏情况的延迟没有帮助 .

    大多数情况下,据我所知,对于“<2 ms”的要求,USB规格/协议,USB控制器,内核的USB控制器驱动程序和内核的USB HID驱动程序根本不是问题 . 问题是及时将USB HID驱动程序中的数据传送到用户空间进程/线程 .

    不幸的是,Linux / Andriod不是一个实时操作系统 . 它不提供任何保证 . 您将受到线程调度程序(也可能是JVM的垃圾收集器)的支配 . 你可能无能为力 .

    我建议你找出为什么你需要每2 ms接收一次陀螺仪数据 . 举一个简单的例子,您可以为陀螺仪数据添加时间戳,让接收线程从这些时间戳“重建历史记录”,以便接收线程根本不需要低延迟吗?

相关问题