当使用 SET_INTERFACE 激活备用设置时,FunctionFS 会停止端点。知道为什么吗?

FunctionFS stalls endpoint when alternate setting is activated with SET_INTERFACE. Any idea why?

我正在尝试使用 FunctionFS 和 FS 驱动程序创建小工具。我的小工具由两个函数组成,配置如下:

Function 1:
Interface 0:
     Endpoint BULK OUT 0x01
     Endpoint BULK IN 0x81

Function 2:
Interface 0 Alternate setting 0:
     No Endpoint
Interface 0 Alternate setting 1:
     Endpoint BULK OUT 0x02
     Endpoint BULK IN 0x82

小工具在 IMX8 板上运行。 OS 是内核为 4.14.98 的 Debian。

一切正常,直到我使用另一台计算机上的 libusb libusb_set_interface_alt_setting 激活功能 2 中的替代设置 1。 libusb 没有显示错误,但交换的 USB 数据包显示 STALL 已从开发板返回。内核日志中也没有关于 STALL 的调试信息。这个问题不是由 libusb 引起的,因为如果我将小工具连接到另一个不依赖 libusb 进行通信的板,我也会遇到同样的问题(和 STALL)。

我尝试更改 USB 描述符(端点地址,函数 1 中的备用设置)和代码(当我打开端点时,使用一个函数而不是两个)但没有任何改变结果。我还查看了内核源代码以找出错误所在,但没有发现明显的地方可以创建 STALL。

还有其他人遇到过类似的问题或对我如何弄清楚发生了什么有任何想法吗?非常感谢您的帮助。

我弄明白了,所以我会把答案放在这里以防其他人遇到这个问题。

FunctionFS (f_fs.c) 不完全支持备用设置。该实现具有更改为另一个备用设置 (ffs_func_set_alt(...)) 的代码,但它需要复合 (composite.c) 使用的另一个函数来识别当前正在使用的备用设置 (ffs_func_get_alt(...))。当设备接收到 SET_INTERFACE 时,composite.c 中的函数 composite_setup(...) 检查是否实现了 get_alt 函数。如果不是,并且要激活的备用设置不为零,则 returns 错误。

如果你想使用具有备用设置的 FunctionFS,唯一的方法是使用 FunctionFS 作为基础创建你自己的 gadget 函数并写入缺少的 ffs_func_get_alt。有关如何编写它的灵感,请查看 f_uvc 函数。完成后,将新模块复制到内核并修改 Makefiles、Kconfig 和 modules.order 以将模块添加到编译过程中。那应该给你一个模块,你可以在内核 .config 文件中 select。

我测试了这个解决方案,它工作正常。修改内核以添加功能也不是太难。互联网上有很多这方面的指南。

祝你好运:)