UAC麦克风实例分析
+ -

UAC麦克风驱动分析

2021-07-23 1077 0

UAC麦克风驱动框架:
UAC麦克风驱动框架

应用层测试代码:https://blog.csdn.net/isunbin/article/details/81503152

对于 gadget uac1 驱动来说, 只需要通过ALSA 框架提供的API读写声卡设备即可。 也是就是说我们只要实现声卡的读写和配置理论上就可以访到麦克风硬件了。
具体读写API 参见 u_uac.c / u_uac.h

int gaudio_setup(struct gaudio * card);
void gaudio_cleanup(struct gaudio * the_card);
void u_audio_clear(struct gaudio * card);
size_t u_audio_playback(struct gaudio * card, void * buf, size_t count);
size_t u_audio_capture(struct gaudio * card, void * buf, size_t count);
int u_audio_get_playback_channels(struct gaudio * card);
int u_audio_get_playback_rate(struct gaudio * card);
int u_audio_get_capture_channels(struct gaudio * card);
int u_audio_get_capture_rate(struct gaudio * card);

f_uac.c 驱动加载过程

  1. 为f_usb_function_instance 实例申请内存并初始化实例相关参数
    DECLARE_USB_FUNCTION_INIT(uac1, f_audio_alloc_inst, f_audio_alloc);
    static struct usb_function_instance * f_audio_alloc_inst(void) {
     struct f_uac1_opts * opts;
     opts = kzalloc(sizeof( * opts), GFP_KERNEL);
     if (!opts) return ERR_PTR(-ENOMEM);
     mutex_init( & opts - > lock);
     opts - > func_inst.free_func_inst = f_audio_free_inst;
     config_group_init_type_name( & opts - > func_inst.group, "", & f_uac1_func_type);
     opts - > req_capture_buf_size = UAC1_IN_EP_MAX_PACKET_SIZE;
     opts - > req_capture_count = UAC1_IN_REQ_COUNT;
     opts - > audio_capture_buf_size = UAC1_AUDIO_CAPTURE_BUF_SIZE;
     opts - > sample_rate = UAC1_SAMPLE_RATE;
     opts - > fn_play = FILE_PCM_PLAYBACK;
     opts - > fn_cap = FILE_PCM_CAPTURE;
     opts - > fn_cntl = FILE_CONTROL;
     return &opts - > func_inst;
    }
    
  2. 为 usb_function( 我们这里是usb 声卡) 申请内存 并为相关功能函数指针赋值
    static struct usb_function * f_audio_alloc(struct usb_function_instance * fi) {
     struct f_audio * audio;
     struct f_uac1_opts * opts; /* allocate and initialize one new instance */
     audio = kzalloc(sizeof( * audio), GFP_KERNEL);
     if (!audio) return ERR_PTR(-ENOMEM);
     audio - > card.func.name = "g_audio";
     opts = container_of(fi, struct f_uac1_opts, func_inst);
     mutex_lock( & opts - > lock);
     ++opts - > refcnt;
     mutex_unlock( & opts - > lock);
     INIT_LIST_HEAD( & audio - > capture_queue);
     spin_lock_init( & audio - > capture_lock);
     audio - > card.func.bind = f_audio_bind;
     audio - > card.func.unbind = f_audio_unbind;
     audio - > card.func.get_alt = f_audio_get_alt;
     audio - > card.func.set_alt = f_audio_set_alt;
     audio - > card.func.setup = f_audio_setup;
     audio - > card.func.disable = f_audio_disable;
     audio - > card.func.free_func = f_audio_free;
     control_selector_init(audio);
     INIT_WORK( & audio - > capture_work, f_audio_capture_work);
     INIT_WORK( & audio - > close_work, f_audio_close_work);
     mutex_init( & audio - > mutex);
     return &audio - > card.func;
    }
    
  3. 设备绑定 注册设备描述符给主机
    static int f_audio_bind(struct usb_configuration * c, struct usb_function * f)
    status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, f_audio_ss_desc, NULL);
    
  4. 主机根据上报的设备相关描述符识别我们的麦克风设备, 当我们在PC端使用麦克风的时候, 主机会主动向设备的OUT端点发送 URB 请求包.
    URB 请求包

5.此时会受到并相应主机的请求
120405923911

120411769971

启动读取麦克风数据任务
120424201573

此时调用capture_work 实现麦克风数据读取并添加到capture_queue 队列。
120500305846

当 audio->in_ep 请求完成之后我们调用f_audio_capture_ep_complete(ep, req); 将数据送给PC 主机。
120513297991

120521933391

120539270906

120637128728

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

UAC麦克风驱动分析
UAC麦克风驱动框架:应用层测试代码:https://blog.csdn.net/isunbin/article/details/81503152对于 gadget uac1 驱动来说, 只需要通过ALSA 框架提供的API读写声卡设备即可。 也是就是说我们只要实现声卡的读写和配置理论上就可......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!