我試圖通過USB從我的嵌入式Linux設備發送/接收音頻到/從Windows主機。通過USB發送和接收音頻的Linux設備驅動程序
據我所知,有2種協議通過USB發送音頻 - USB音頻類1和2(UAC1 & UAC2)。我發現他們在這裏解釋:http://www.thewelltemperedcomputer.com/HW/USB_Audio.htm。
我目前在Linux中使用現有的UAC1設備驅動程序來從主機PC獲取音頻。這個對我有用。我正在嘗試將設備驅動程序更改爲也能夠將音頻發送到主機PC。
我看到有一個UAC2驅動程序(在最新的Linux內核中)同時發送和接收來自主機的音頻。但是我想要一個UAC1驅動程序來實現這一點,這樣我就不必在Windows主機上安裝任何額外的驅動程序(特別是我必須購買的驅動程序:http://www.thesycon.de/eng/usb_audiodriver.shtml)。我修改了linux/drivers/usb/gadget/f_audio.c中的linux設備驅動程序(我使用的是舊版本的內核)。我已將USB頭描述符更改爲包含用於向主機發送音頻的額外端點。
struct usb_endpoint_descriptor hs_epout_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
.wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE),
.bInterval = 4,
};
IN端點被定義爲:
static struct usb_descriptor_header *hs_audio_desc[] = {
(struct usb_descriptor_header *)&std_ac_if_desc,
(struct usb_descriptor_header *)&ac_hdr_desc,
(struct usb_descriptor_header *)&usb_it_desc,
(struct usb_descriptor_header *)&usb_ot_desc,
(struct usb_descriptor_header *)&std_as_out_if0_desc,
(struct usb_descriptor_header *)&std_as_out_if1_desc,
(struct usb_descriptor_header *)&as_out_hdr_desc,
(struct usb_descriptor_header *)&as_out_fmt1_desc,
(struct usb_descriptor_header *)&hs_epout_desc,
(struct usb_descriptor_header *)&as_iso_out_desc,
(struct usb_descriptor_header *)&std_as_in_if0_desc,
(struct usb_descriptor_header *)&std_as_in_if1_desc,
(struct usb_descriptor_header *)&as_in_hdr_desc,
(struct usb_descriptor_header *)&as_in_fmt1_desc,
(struct usb_descriptor_header *)&hs_epin_desc,
(struct usb_descriptor_header *)&as_iso_in_desc,
NULL,
};
作爲OUT端點被定義
struct usb_endpoint_descriptor hs_epin_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
.wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE),
.bInterval = 4,
};
在epautoconf.c中,bEndpointAddress端點字段通常與或運算端點號碼。我看到我的情況,這是發生。 我的OUT端點的'bEndpointAddress'字段是0x01,而當我在epautoconf.c中打印它時,我的IN端點是0x81。 但我無法在主機端看到它。在我的Windows PC上,我使用USB View工具查看描述符,並看到值爲0x00和0x80。
什麼可能會改變bEndpointAdress的值?
這些都是使用USB查看工具的USB描述我看到在Windows:
Device Descriptor:
bcdUSB: 0x0200
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x40 (64)
idVendor: 0x1D6B
idProduct: 0x0101
bcdDevice: 0x0316
iManufacturer: 0x01
0x0409: "Linux 3.2.0 with musb-hdrc"
iProduct: 0x02
0x0409: "Linux USB Audio Gadget"
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: High
Device Address: 0x13
Open Pipes: 0
Configuration Descriptor:
wTotalLength: 0x0095
bNumInterfaces: 0x03
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0xC0 (Bus Powered Self Powered)
MaxPower: 0x01 (2 Ma)
Interface Descriptor:
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x01 (Audio Control)
bInterfaceProtocol: 0x00
iInterface: 0x04
0x0409: "Topology Control"
Audio Control Interface Header Descriptor:
bLength: 0x0A
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bcdADC: 0x0100
wTotalLength: 0x001F
bInCollection: 0x02
baInterfaceNr[1]: 0x01
baInterfaceNr[2]: 0x02
Audio Control Input Terminal Descriptor:
bLength: 0x0C
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bTerminalID: 0x02
wTerminalType: 0x0201 (Microphone)
bAssocTerminal: 0x00
bNrChannels: 0x02
wChannelConfig: 0x0003
iChannelNames: 0x00
iTerminal: 0x07
Audio Control Output Terminal Descriptor:
bLength: 0x09
bDescriptorType: 0x24
bDescriptorSubtype: 0x03
bTerminalID: 0x01
wTerminalType: 0x0301 (Speaker)
bAssocTerminal: 0x00
bSoruceID: 0x00
iTerminal: 0x09
Interface Descriptor:
bInterfaceNumber: 0x01
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0B
0x0409: "Playback Inactive"
Interface Descriptor:
bInterfaceNumber: 0x01
bAlternateSetting: 0x01
bNumEndpoints: 0x01
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0C
0x0409: "Playback Active"
Audio Streaming Class Specific Interface Descriptor:
bLength: 0x07
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bTerminalLink: 0x01
bDelay: 0x01
wFormatTag: 0x0001 (PCM)
Audio Streaming Format Type Descriptor:
bLength: 0x0B
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bFormatType: 0x01
bNrChannels: 0x00
bSubframeSize: 0x02
bBitResolution: 0x10
bSamFreqType: 0x01
tSamFreq[1]: 0x00BB80 (48000 Hz)
Endpoint Descriptor:
bEndpointAddress: 0x00 OUT
Transfer Type: Isochronous
wMaxPacketSize: 0x00C8 (200)
bInterval: 0x04
Audio Streaming Class Specific Audio Data Endpoint Descriptor:
bLength: 0x07
bDescriptorType: 0x25
bDescriptorSubtype: 0x01
bmAttributes: 0x00
bLockDelayUnits: 0x00
wLockDelay: 0x0000
Interface Descriptor:
bInterfaceNumber: 0x02
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0D
0x0409: "Capture Inactive"
Interface Descriptor:
bInterfaceNumber: 0x02
bAlternateSetting: 0x01
bNumEndpoints: 0x01
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0E
0x0409: "Capture Active"
Audio Streaming Class Specific Interface Descriptor:
bLength: 0x07
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bTerminalLink: 0x02
bDelay: 0x01
wFormatTag: 0x0001 (PCM)
Audio Streaming Format Type Descriptor:
bLength: 0x0B
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bFormatType: 0x01
bNrChannels: 0x00
bSubframeSize: 0x02
bBitResolution: 0x10
bSamFreqType: 0x01
tSamFreq[1]: 0x00BB80 (48000 Hz)
Endpoint Descriptor:
bEndpointAddress: 0x80 IN
Transfer Type: Isochronous
wMaxPacketSize: 0x00C8 (200)
bInterval: 0x04
Audio Streaming Class Specific Audio Data Endpoint Descriptor:
bLength: 0x07
bDescriptorType: 0x25
bDescriptorSubtype: 0x01
bmAttributes: 0x00
bLockDelayUnits: 0x00
wLockDelay: 0x0000
爲什麼不能在Windows安裝UAC1驅動程序?
您是否嘗試過使用'的#pragma包(1)'周圍的結構的聲明? – 2014-12-03 01:03:33
謝謝彼得。但是bLength和bInterval等其他元素與定義的值相同。只有bEndpointAddress被更改。 – linux22 2014-12-03 15:37:20
我剛剛嘗試使用#pragma pack(1)。不幸的是,這沒有什麼區別。 – linux22 2014-12-03 16:18:58