4. 同步端点配置与带宽计算
任务说明
在USB音频设备中,同步端点(Isochronous Endpoint)负责实时传输音频采样数据。本案例完成:为USB音频设备配置一个等时输入端点(用于音频数据从设备到主机),计算该端点所需的USB总线带宽,并设置端点描述符的关键属性。
环境与依赖
- 使用 Linux UVC/Gadget API(
linux/usb/ch9.h与linux/usb/gadget.h)进行端点配置,适用于基于 Gadget 框架的USB设备驱动开发。 - 需要内核头文件支持,编译环境为Linux内核模块或基于Gadget的用户态函数fs。
核心实现
以下代码完成:定义音频采样参数,计算等时端点所需带宽,并配置端点描述符。带宽计算遵循USB 2.0规范:每帧字节数 = 采样率 × 字节/采样 / 1000帧/秒,并向上取整到端点最大包长度整数倍。
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/errno.h>
/* 音频参数配置 */
#define AUDIO_SAMPLE_RATE 48000 /* 48kHz */
#define AUDIO_CHANNELS 2 /* 立体声 */
#define AUDIO_BYTES_PER_SAMPLE 2 /* 16bit */
/* 计算等时端点每帧需要的字节数(USB全速/高速帧周期为1ms) */
static int calc_isoc_burst_size(void)
{
uint32_t bytes_per_ms;
uint32_t packet_size;
bytes_per_ms = (AUDIO_SAMPLE_RATE * AUDIO_CHANNELS *
AUDIO_BYTES_PER_SAMPLE) / 1000;
/* 等时端点最大包长度必须是wMaxPacketSize的整数倍,
此处按高速USB(HS)取512字节对齐 */
packet_size = (bytes_per_ms + 511) & ~511;
if (packet_size > 1024) /* HS等时端点上限 */
return -EINVAL;
return packet_size;
}
/* 配置等时输入端点 */
static int config_audio_isoc_ep(struct usb_ep *ep)
{
struct usb_endpoint_descriptor ep_desc;
int burst_size;
burst_size = calc_isoc_burst_size();
if (burst_size < 0)
return burst_size;
/* 填充端点描述符 */
memset(&ep_desc, 0, sizeof(ep_desc));
ep_desc.bLength = USB_DT_ENDPOINT_SIZE;
ep_desc.bDescriptorType = USB_DT_ENDPOINT;
ep_desc.bEndpointAddress = 0x81; /* IN端点, 地址1 */
ep_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC |
USB_ENDPOINT_SYNC_ASYNC; /* 异步同步等时端点 */
ep_desc.wMaxPacketSize = cpu_to_le16(burst_size);
ep_desc.bInterval = 1; /* 每1ms帧轮询一次 */
/* 将描述符绑定到gadget端点 */
ep->desc = &ep_desc;
ep->maxpacket = burst_size;
/* 请求端点使能 */
return usb_ep_enable(ep);
}
运行与验证
- 编译:将上述代码放入内核模块或Gadget驱动源文件,使用内核构建系统编译:
make -C /lib/modules/$(uname -r)/build M=$PWD modules - 调用路径:在USB Gadget的
bind回调中,获取端点实例后调用config_audio_isoc_ep()。 - 验证方法:
- 检查函数返回值:返回0表示端点配置成功,返回
-EINVAL表示带宽超限。 - 在主机端使用
lsusb -v查看设备描述符,确认端点0x81的wMaxPacketSize为计算值(48kHz×2ch×2B/ms = 192B,向上对齐到512B后为512)。 - 通过
dmesg观察内核日志,确认无端点使能错误。
- 检查函数返回值:返回0表示端点配置成功,返回
预期输出
当音频参数为48kHz/双声道/16bit时,calc_isoc_burst_size()返回512。端点描述符中wMaxPacketSize字段值为0x0200(512字节),bInterval为1,端点类型为等时(0x05)。
关键说明
- 带宽计算基于USB全速/高速的1ms帧周期;若使用USB 3.0的微帧(125µs),需将除数改为8000并相应调整对齐逻辑。
- 实际音频数据在端点上的调度由USB控制器处理,驱动只需正确配置描述符并提交URB。
- 若采样率或通道数改变,需同步更新
AUDIO_SAMPLE_RATE等宏定义后重新编译。