Linux 使用usb3.0设备,Linux USB3.0驱动分析(九)——Gadget UAC2驱动分析

本文分析的是linux-5.4.3

一.Gadget Audio设备驱动分析

drivers/usb/gadget/legacy/audio.c

因为项目的问题,了解usb音频设备的工作原理,为啥它能让PC识别成“speak”或者“mic”,以及你能够播放录音。

主要涉及下面两个层次:

Gadget功能驱动层:  最主要的结构是struct usb_composite_driver,这个结构在这层定义,并且实现结构中的各个函数。

USB设备层:  最主要的数据结构是struct usb_composite_dev与usb_gadget_driver。前一个代表一个USB复合设备,而后一个是Gadget驱动,与UDC层交互。

这边主要是usb结构中的设备和配置相关

首先我们来看初始化流程,主要是注册audio_driver这个复合设备驱动

static struct usb_composite_driver audio_driver = {

.name = "g_audio",

.dev = &device_desc, //这是一个设备描述符

.strings = audio_strings, //一个给定语言的字符串集合,字符串描述符

.max_speed = USB_SPEED_HIGH, //设备速度

.bind = audio_bind, //注册绑定回调函数

.unbind = audio_unbind,

};

/* 设置#define module_usb_composite_driver(__usb_composite_driver) \

module_driver(__usb_composite_driver, usb_composite_probe, \

usb_composite_unregister) */

//module_usb_composite_driver是一个宏定义用usb_composite_probe注册复合驱动程序

module_usb_composite_driver(audio_driver);

我们再来看看usb_composite_probe里面具体做了什么,主要是赋值了composite_driver_template,这个是所有复合设备共有的

static const struct usb_gadget_driver composite_driver_template = {

.bind= composite_bind,

.unbind= composite_unbind,

.setup= composite_setup,

.reset= composite_disconnect,

.disconnect= composite_disconnect,

.suspend= composite_suspend,

.resume= composite_resume,

.driver= {

.owner= THIS_MODULE,

},

};

int usb_composite_probe(struct usb_composite_driver *driver) //注册复合设备

{

struct usb_gadget_driver *gadget_driver;

if (!driver || !driver->dev || !driver->bind)

return -EINVAL;

if (!driver->name)

driver->name = "composite";

driver->gadget_driver = composite_driver_template; //赋值一个usb_gadget_driver实例,应该只有一个

gadget_driver = &driver->gadget_driver;

gadget_driver->function = (char *) driver->name;

gadget_driver->driver.name = driver->name;

gadget_driver->max_speed = driver->max_speed;

return usb_gadget_probe_driver(gadget_driver); //继续调用

}

后面继续调用usb_gadget_probe_driver,进行注册。

int usb_gadget_probe_driver(struct usb_gadget_driver *driver)

{

mutex_lock(&udc_lock);

if (driver->udc_name) { //如果有udc的名字,就直接遍历比较

list_for_each_entry(udc, &udc_list, list) {

ret = strcmp(driver->udc_name, dev_name(&udc->dev));

if (!ret)

break;

}

if (ret)

ret = -ENODEV;

else if (udc->driver) //已经有匹配的driver,正在忙

ret &#

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux USB gadget驱动编写有如下几个步骤: 1. 确定USB gadget功能:首先需要确定所需实现的USB gadget功能,例如以USB设备的形式提供存储、网络、音频等服务。这样可以决定需要实现的USB gadget驱动类型和功能。 2. 编写USB驱动框架:基于Linux内核框架,编写USB gadget驱动的基本框架。这包括注册USB gadget驱动和常用的函数接口等。 3. 实现USB gadget子系统:根据所需的功能,实现USB gadget子系统的模块,如存储、网络或音频子系统等。这些子系统需要封装底层的USB通信协议和数据传输,供应用程序调用。 4. 配置USB gadget驱动:根据具体需求,在系统配置文件中进行必要的配置,以启用和配置USB gadget驱动。这包括配置端点、描述符和功能等。 5. 移植和编译:将驱动程序编译成内核模块,然后将其移植到目标设备上。对于嵌入式设备,可能需要修改硬件相关的代码,以适应硬件平台。 6. 测试和调试:编写测试用例,对USB gadget驱动进行测试和调试,确保其正常工作。这包括对设备和主机之间的数据传输进行验证,以及处理异常情况和错误处理。 总之,编写Linux USB gadget驱动需要明确所需实现的功能、基于内核框架编写驱动框架、实现USB gadget子系统、配置以及移植和编译。最后进行测试和调试,确保驱动程序的正常运行。通过以上步骤,可以实现各种USB设备功能的驱动。 ### 回答2: Linux USB gadget驱动是用于实现USB设备的功能的驱动程序。它使得Linux设备可以作为一个USB设备与其他主机进行通信。在编写Linux USB gadget驱动时,需要完成以下几个步骤。 首先,需要确定设备的功能和属性。USB设备可以有多种功能,如储存设备、键盘、鼠标等。根据设备的类型和规格,确定设备的操作和数据传输方式。 其次,在驱动程序中定义设备USB描述符。USB描述符包括设备描述符、接口描述符和端点描述符等,它们是USB协议的一部分,用于描述设备的属性和功能。 然后,在驱动程序中实现设备的相关功能。根据设备的类型和规格,编写相应的功能代码。例如,如果设备是一个键盘,就需要实现按键事件的处理逻辑;如果设备是一个储存设备,就需要实现读写数据的逻辑。 最后,编译和加载驱动程序使用Linux内核提供的工具链,将驱动程序编译为可执行文件,并将其加载到Linux内核中运行。加载驱动程序后,系统即可识别设备,并根据驱动程序中定义的功能和属性来处理设备的操作和数据传输。 总之,编写Linux USB gadget驱动需要确定设备的功能和属性、定义USB描述符、实现设备的相关功能,最后编译和加载驱动程序。通过这些步骤,我们可以在Linux系统中实现USB设备的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值