项目自定义 Function:f_bytrans 与 f_audio_raw
本树function/Makefile第 53-56 行无条件以obj-m编译两个 2024 年新增的私有 Function,上游内核不存在,是本项目(YPC Encode)的扩展。两者结构相似:ConfigFS function + 字符设备 + kfifo,用户态经/dev节点与 Host 交换数据。
1. f_bytrans(字节透传,/dev/msgtrans*)
1.1 USB 接口
单接口 Vendor Specific(class 0xFF),3 个端点(f_bytrans.c:63):
| 端点 | FS | HS | SS |
|---|---|---|---|
| Bulk IN | 64B | 512B | 1024B + burst 15 |
| Bulk OUT | 64B | 512B | 1024B + burst 15 |
| Interrupt IN | 64B/interval16 | 512B/interval4 | 1024B/interval2 |
Interrupt IN 用于向 Host 上报RX_FIFO_FULL(0xA0)/TX_FIFO_FULL(0xA1)流控事件(宏定义 36-37 行)。
1.2 核心结构与资源
struct f_bytrans(213 行):
tx_fifo/rx_fifo:各 512KB kfifo(FIFO_SIZE=524288);send_thread:内核线程bytrans_send,从 tx_fifo 取数据组 bulk IN 请求(847 行);wq:workqueue 处理 bulk OUT completion 入 rx_fifo;- 包缓冲
MAX_PACKET_SIZE=1024、每 URBMAX_PACKET_COUNT=32事务; - 字符设备:
cdev_add于 901 行,device_create于 908 行,节点名msgtrans<minor>,classbytrans,minor 由 IDA 分配。
1.3 数据路径
1 | Host -> bulk OUT -> bytrans_bulk_out_complete -> workqueue -> rx_fifo |
1.4 生命周期与注册
bytrans_alloc_inst_fixed()(989 行)创建 instance 并初始化 configfs item(item_ops 966 行、attrs 977 行);bytrans_alloc()(787 行)创建 function,function.name = "bytrans"(809 行);DECLARE_USB_FUNCTION_INIT(bytrans, ...)(1011 行)注册,ConfigFS 用法:
1 | mkdir functions/bytrans.0 |
- 释放路径
bytrans_free_inst()(778 行);unbind 时kthread_stop(937 行)。
1.5 审阅要点(潜在风险)
- send_thread/workqueue 与
set_alt/disable并发:断开时在途 request 与 kfifo 状态需要严格同步,注意online标志的内存序; - 代码含大量
BYTRANS_DEBUGpr_info,量产应降级; - FIFO 满策略依赖 Host 配合中断通知,Host 端不理会时会丢数据或阻塞;
- 字符设备无并发 open 保护说明,多进程同时读写语义未定义,应用侧应单实例使用。
2. f_audio_raw(原始音频,/dev/audio_raw.*)
2.1 设计动机
绕开 UAC 标准协议栈,用 Vendor Specific 接口 + isochronous 端点直接传原始音频字节,Host 侧配套私有驱动/应用。相比 f_uac2 省去 ALSA 和 class request 复杂度,但失去标准 Host 兼容性。
2.2 USB 接口
单接口两个 alternate setting(116-137 行):
- alt 0:无端点(空闲);
- alt 1:isoc IN + isoc OUT 各一(FS 1023B/interval1,HS 1024B/interval4,SS 1024B/interval2 加 companion)。
audio_raw_set_alt()(687 行)在 alt 1 时使能端点、预队 OUT 请求并置online/rx_enabled/tx_enabled。
2.3 数据面
struct f_audio_raw(48 行起):
fifo_rx:64KB kfifo(FIFO_SIZE37 行);- IN/OUT 各
MAX_URBS=32个预分配 request; - 读写超时
WRITE_TIMEOUT_MS/READ_TIMEOUT_MS = 5000。
1 | Host -> isoc OUT complete (274行) -> kfifo_in(fifo_rx) -> read_wait唤醒 |
isoc 无重传:OUT 侧 fifo 满时新数据直接丢弃(281 行仅打 debug),IN 侧欠载表现为 Host 收流中断。实时性依赖应用及时消费/供给。
2.4 字符设备与实例
- class
audio_raw(862 行创建),chrdev region 256 个 minor(873 行); - 每实例节点名
audio_raw.<instance_id>(964 行),function.name = "audio_raw"(968 行); audio_raw_alloc_inst()(847 行)分配实例,DECLARE_USB_FUNCTION_INIT于 993 行;- ConfigFS:
mkdir functions/audio_raw.0后同常规流程。
2.5 审阅要点
- 文件为新写代码,含中文注释和 debug 日志,风格与上游不一致(缩进混用),合入主线前需清理;
- offline 竞争:
read/write在等待中检查!fa->online退出(352/398 行),但 completion 与 disable 的时序仍需重点测试拔线场景; - isoc 带宽在 HS interval4 下约 1024B/500µs≈2MB/s,设计音频格式时须核对是否够用;
- OUT 丢弃策略意味着不能承载不容忍丢包的数据,只适合音频类容错流。
3. 与标准方案的选型对照
| 需求 | 建议 |
|---|---|
| 标准 Host 免驱音频 | f_uac1/f_uac2 |
| 私有低延迟音频流、自控协议 | f_audio_raw(本树方案) |
| 可靠字节/消息通道 | f_bytrans(bulk,有流控) 或 FunctionFS |
| 用户态完整协议栈 | FunctionFS |
两个自定义 function 均为obj-m,部署需确认模块随镜像安装并在组装 gadget 前 modprobe。
正在加载留言…