usb gadget function configs

1、uvc示例

export VID=“0x1D6B”
export PID=“0x0004”
export MANUFACTURER=“Vendor”
export PRODUCT=“Camera”
export SERIALNUMBER=“123456789012”
export CamControl1=0x0A
export CamControl2=0x00
export CamControl3=0x00
export ProcControl1=0x4F
export ProcControl2=0x14
export NV21=“360p 720p 1080p 2160p”
export MJPEG=“360p 720p 1080p 2160p”
export H264=“360p 720p 1080p 2160p”
./ConfgUVC.sh
上述export所修饰的变量用户可自主适配,变量所表示的含义如下:
– VID表示厂商ID,使用时必须修改;
– PID表示产品ID,使用时必须修改;
– MANUFACTURER表示厂商名,默认发布是Vendor,使用时必须修改;
– PRODUCT表示产品名,使用时必须修改;
– SERIALNUMBER表示产品序列号,使用时请按需求修改;
– CamControl1、 CamControl2、 CamControl3表示的是UVC CT( Camera Terminal)
– ProcControl1、 ProcControl2 表示的是UVC PU( Processing Unit)单元的可控制项,
– NV21、 MJPEG和H264表示每种格式所支持的分辨率;
– ConfgUVC.sh脚本为启动uvc所进行的必要操作
脚本中部分代码
在这里插入图片描述
示例

1.1 uvc

export VID=“0x1D6B”
export PID=“0x0004”
export MANUFACTURER=“Vendor”
export PRODUCT=“Camera”
export SERIALNUMBER=“123456789012”
export CamControl1=0x0A
export CamControl2=0x00
export CamControl3=0x00
export ProcControl1=0x4F
export ProcControl2=0x14
export NV21=“360p 720p 1080p 2160p”
export MJPEG=“360p 720p 1080p 2160p”
export H264=“360p 720p 1080p 2160p”
./ConfigUVC.sh

1.2 串口

export VID=“0x1D6B”
export PID=“0x0003”
export MANUFACTURER=“Vendor”
export PRODUCT=“SerialGadget”
export SERIALNUMBER=“123456789012”
./Config_Serial.sh

1.3 网口

export VID=“0x1D6B”
export PID=“0x0002”
export MANUFACTURER=“Vendor”
export PRODUCT=“Ethernet”
export SERIALNUMBER=“123456789012”
./Config_Ether.sh

1.4 U盘

1.4.1 以SD卡作为虚拟U盘的存储介质,操作为:

export VID=“0x1D6B”
export PID=“0x0001”
export MANUFACTURER=" Vendor"
export PRODUCT=“MassStorage”
export SERIALNUMBER=“123456789012”
export MEMORY=/dev/mmcblk0pX
./Config_Storage.sh

1.4.2 以Flash作为虚拟U盘的存储介质,操作为:

export VID=“0x1D6B”
export PID=“0x0001”
export MANUFACTURER=“Vendor”
export PRODUCT=“MassStorage”
export SERIALNUMBER=“123456789012”
export MEMORY=/dev/mtdblockX
./Config_Storage.sh
这里是一部分配置文件示例

【配置下载文件链接】
通过configfs配置的Linux USB gadget

2、概述

USB Linux Gadget是一种具有UDC (USB设备控制器)的设备,可以连接到USB主机,以扩展其附加功能,如串口或大容量存储能力。

一个gadget被它的主机视为一组配置,每个配置都包含一些接口,从gadget的角度来看,这些接口被称为功能,每个功能代表一个串行连接或一个SCSI磁盘。

Linux提供了许多gadget可以使用的功能。

创建一个gadget意味着决定将有哪些配置以及每个配置将提供哪些功能。

Configfs(请参阅Configfs—用户空间驱动的内核对象配置)非常适合告诉内核上述决定。本文档是关于如何实现这一点的。它还描述了如何将configfs集成到gadget中。

要求
为了使其工作,配置文件必须可用,因此CONFIGFS_FS必须为 ‘y’ 或 ‘m’ 在.config中。在撰写本文时,USB_LIBCOMPOSITE选择CONFIGFS_FS。

用法
(描述configfs提供的第一个功能的原始帖子可以在这里看到:http://www.spinics.net/lists/linux-usb/msg76388.html)

$ modprobe libcomposite
$ mount none $CONFIGFS_HOME -t configfs
其中CONFIGFS_HOME是configfs的挂载点。

  1. 创建gadget
    对于每个要创建的gadget,必须创建相应的目录:

$ mkdir $CONFIGFS_HOME/usb_gadget/
例如:

$ mkdir $CONFIGFS_HOME/usb_gadget/g1
$ cd $CONFIGFS_HOME/usb_gadget/g1
每个gadget需要指定其vendor id 和product id :

$ echo > idVendor
$ echo > idProduct
gadget还需要它的序列号、制造商和产品字符串。为了有一个地方存储它们,必须为每种语言创建一个字符串子目录,例如:

$ mkdir strings/0x409
然后可以指定字符串:

$ echo > strings/0x409/serialnumber
$ echo > strings/0x409/manufacturer
$ echo > strings/0x409/product
2. 创建配置
每个 gadget 将由许多配置组成,必须创建相应的目录:

$ mkdir configs/.
可以是文件系统中合法的任意字符串,而是配置的编号,例如:

$ mkdir configs/c.1
每个配置也需要它的字符串,所以必须为每种语言创建一个子目录,例如:

$ mkdir configs/c.1/strings/0x409
然后可以指定配置字符串:

$ echo > configs/c.1/strings/0x409/configuration
也可以为配置设置一些属性,例如:

$ echo 120 > configs/c.1/MaxPower
3. 创建功能
gadget将提供一些功能,对于每个功能,必须创建相应的目录:

$ mkdir functions/.
其中对应于一个允许的功能名称,是文件系统中允许的任意字符串,例如:

$ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module()
每个函数都提供其特定的属性集,具有只读或读写访问权限。如适用,需要酌情写入。更多信息请参考Documentation/ABI/testing/configfs-usb-gadget。

  1. 关联功能及其配置
    此时,许多gadget被创建出来,每个gadget都有一些指定的配置和一些可用的功能。剩下的就是指定哪个功能在哪个配置中可用(同一个功能可以在多个配置中使用)。这是通过创建符号链接来实现的:

$ ln -s functions/. configs/.
例如:

$ ln -s functions/ncm.usb0 configs/c.1
5. 启用gadget
以上所有步骤的目的是组成gadget的配置和功能。

示例目录结构可能看起来像这样:

复制代码
.
./strings
./strings/0x409
./strings/0x409/serialnumber
./strings/0x409/product
./strings/0x409/manufacturer
./configs
./configs/c.1
./configs/c.1/ncm.usb0 -> …/…/…/…/usb_gadget/g1/functions/ncm.usb0
./configs/c.1/strings
./configs/c.1/strings/0x409
./configs/c.1/strings/0x409/configuration
./configs/c.1/bmAttributes
./configs/c.1/MaxPower
./functions
./functions/ncm.usb0
./functions/ncm.usb0/ifname
./functions/ncm.usb0/qmult
./functions/ncm.usb0/host_addr
./functions/ncm.usb0/dev_addr
./UDC
./bcdUSB
./bcdDevice
./idProduct
./idVendor
./bMaxPacketSize0
./bDeviceProtocol
./bDeviceSubClass
./bDeviceClass
复制代码
这样的gadget必须最终启用,以便USB主机能够枚举它。

为了启用gadget,它必须绑定到UDC (USB设备控制器):

$ echo > UDC
其中是在/sys/class/udc/*,例如:

$ echo s3c-hsotg > UDC
6. 禁用gadget
$ echo “” > UDC
7. 清理
从配置中删除功能:

$ rm configs/./
.指定配置,是指向从配置中删除的功能的符号链接,例如:

$ rm configs/c.1/ncm.usb0
删除配置中的字符串目录:

$ rmdir configs/./strings/
例如:

$ rmdir configs/c.1/strings/0x409
并删除配置:

$ rmdir configs/.
例如:

rmdir configs/c.1
删除功能(功能模块不会被卸载):

$ rmdir functions/.
例如:

$ rmdir functions/ncm.usb0
删除gadget中的字符串目录:

$ rmdir strings/
例如:

$ rmdir strings/0x409
最后移除gadget:

$ cd …
$ rmdir
例如:

$ rmdir g1
实施设计
下面介绍configfs的工作原理。在configfs中有项目和组,它们都表示为目录。项和组之间的区别在于,组可以包含其他组。下图中只显示了一个项目。项和组都可以具有属性,这些属性表示为文件。用户可以创建和删除目录,但不能删除文件,文件可以是只读的或读写的,这取决于它们所代表的内容。

configfs的文件系统部分操作config_items/groups和configfs_attributes,它们是通用的,对所有配置的元素具有相同的类型。但是,它们被嵌入到特定于使用的更大的结构中。下面的图片中有一个“cs”,它包含一个config_item和一个“sa”,它包含一个configfs_attribute。

文件系统视图是这样的:

./
./cs (directory)
|
±-sa (file)
|
.
.
.

每当用户读取/写入“sa”文件时,都会调用一个函数,该函数接受一个struct config_item和一个struct configfs_attribute。在上述函数中,使用众所周知的container_of技术检索“cs”和“sa”,并调用适当的sa函数(show或store)并传递“cs”和字符缓冲区。“show”用于显示文件的内容(将数据从cs复制到缓冲区),而“store”用于修改文件的内容(将数据从缓冲区复制到cs),但这取决于两个函数的实现者来决定它们的操作。

typedef struct configured_structure cs;
typedef struct specific_attribute sa;
在这里插入图片描述

文件名由配置项/组设计器决定,而目录通常可以随意命名。一个组可以有许多自动创建的默认子组。

有关configfs的更多信息,请参见Documentation/filesystems/configfs.rst

上面描述的概念转化为USB gadget如下:

  1. 一个小工具有它的配置组,它有一些属性(idVendor, idProduct等)和默认子组(configs, functions, strings)。写入属性将导致信息存储在适当的位置。在配置、函数和字符串子组中,用户可以创建它们的子组来表示给定语言中的配置、函数和字符串组。

  2. 用户创建配置和函数,在配置中创建到函数的符号链接。当将gadget的UDC属性写入时使用此信息,这意味着将gadget绑定到UDC。驱动程序/usb/gadget/configfs.c中的代码遍历所有配置,并且在每个配置中遍历所有函数并绑定它们。这样整个gadget就被绑定了。

  3. 文件驱动程序/usb/gadget/configfs.c包含以下代码:

gadget’s config_group
gadget’s default groups (configs, functions, strings)
associating functions with configurations (symlinks)
4. 个USB函数自然都有自己想要配置的视图,所以特定函数的config_groups定义在函数实现文件drivers/ USB /gadget/f_*.c中。

  1. 函数的代码是以它所使用的方式编写的。

Usb_get_function_instance(),它反过来调用request_module。因此,只要modprobe工作正常,特定函数的模块就会自动加载。请注意,相反的情况是不正确的: 在 gadget 被禁用和卸载后,模块仍然是加载的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值