Skip to main content
 首页 » 编程设计

Android USB gadget configfs学习笔记总结

2022年07月19日59tuyile006

1.一个config_item 是通过显式用户空间mkdir操作创建的,通过rmdir销毁。属性(文件)在mkdir之后出现,可以通过read和write读取或修改属性文件。与sysfs一样,readdir查询链表上的items和/或attributes。
2.symlink可用于将items组合在一起。 与sysfs不同,表示的生命周期完全由用户空间驱动,支持这items的内核模块必须响应这一点。

3.平台A上是在init.rc文件中挂载的
mount configfs none /config

在init.recovery.BOARD.rc文件中在adb初始化好后将 setprop sys.usb.configfs 1

注意persist.sys.usb.config属性:# getprop persist.sys.usb.config mobile_link,adb

4.查看USB相关的属性:# getprop |grep usb

5.这些使用configfs作为subsystems注册其item types的模块称为客户端模块。一旦加载了client subsystem后,它将显示为/config下的子目录(或多个子目录)。

6.通过mkdir创建一个item。 该item的属性(文件)也将在这个时候出现。

7.当需要销毁某个项目时,请使用rmdir将其删除。 如果一个item存在任何其他链接,则无法销毁该项目。 可以通过unlink删除链接。

8.configfs中的每个对象都是一个config_item。 一个config_item反映了此子系统中的一个对象

9.group是共享相同属性和操作的项的集合。 Items由mkdir创建并由rmdir删除,但configfs处理它, 该group具有一组执行这些任务的操作。

10.在初始化期间,客户端模块注册子系统到configfs,子系统显示为configfs文件系统下的顶级的目录。 一个子系统也是一个config_group,可以完成config_group所能做的一切。

11.config_item的所有用户都应该通过config_item_get()来引用它,并在引用完成时通过config_item_put()删除引用。

12.config_item_type指定config_item的行为,提供操作函数。

13.动态分配的所有项items都需要提供ct_item_ops->release()方法释放。 当config_item的引用计数达到零时,将调用此方法。

14.当config_item希望某个属性在项目的configfs目录中显示为文件时,它必须定义一个configfs_attribute来描述它

15.config_item无法凭空存在,config_group上的mkdir是创建它的唯一方法。 这将触发子项目的创建。

16.正确配置该项目意味着一个组可以作为一个项目本身(也即一个config_group本身也是一个config_item)。 但是,它可以做更多:它可以创建子项或组。这是通过组的config_item_type上指定的组操作完成的。

17.当调用rmdir时,configfs将从文件系统树中删除该项(假设它没有子节点来保持它忙)。 子系统负责响应这一点。 如果子系统在其它线程中对该项目具有引用,则内存是安全的(引用计数保证的).
项目实际上可能需要一些时间才能从子系统的使用中消失。 但它已经从configfs中消失了。

18.当rmdir --> drop_item()被调用时,项目的链接已被拆除。它不再具有对其父级的引用,并且在项目层次结构中没有位置了。 如果客户端在拆除发生之前需要进行一些清理工作,则子系统可以实
现configfs_group_operations.disconnect_notify()方法。 这个方法将会在configfs将此项目从文件系统视图中移除之后,但在从其父group中删除之前调用。

19.一个子系统永远不会触及文件系统部分,但子系统可能对此层次结构感兴趣。

20.configfs构建出一个层次结构,层次结构通过config_group->cg_children和config_item->ci_parent构成树状结构。子系统可以导航cg_children列表和ci_parent指针以查看子系统创建的树。
这可能与configfs管理层次结构竞争,因此configfs使用子系统互斥锁来保护修改。 每当子系统想要导航层次结构时,它必须在子系统互斥锁的保护下这样做。
当新分配的项尚未链接到此层次结构时,将阻止子系统获取互斥锁。 同样,当丢弃的项目尚未取消链接时,它不可以获取互斥锁。 这意味着当项目在configfs中时,项目的ci_parent指针永
远不会为NULL,并且项目将仅在其父项的cg_children列表中持续相同的持续时间。 这允许子系统在保持互斥锁时信任ci_parent和cg_children。

21.configfs通过group->item 父/子关系提供一个简单的组。 但是,通常,较大的环境需要在父/子连接之外进行聚合,这是通过symlink实现的。

22.configfs提供了一种方法,可以在创建父项时在父项内自动创建一个或多个子组

23.如果ct_group_ops->make_group()存在,则其他子组可以直接在父组上创建。

24.configfs子系统通过使用configfs_add_default_group()函数将它们添加到父config_group结构来指定默认的组。每个添加的组都在configfs树中与父组一起填充。同样,它们与父母同时被删除。
没有提供额外的通知。当 ->drop_item()方法调用通知子系统父组将要被移除时,它还意味着与该父组关联的每个默认组子项。因此,默认组无法通过rmdir直接删除。 #######??########

========================

25.使用configfs需要选中CONFIGFS_FS,它又被USB_LIBCOMPOSITE select了。

26.configfs中的items和groups都显示为目录。items和groups的区别是groups还可以包含其它group。group和item都可以有属性文件
greoup:
---------------------------------------
/config/usb_gadget/g1
/config/usb_gadget/g1/configs
/config/usb_gadget/g1/functions
/config/usb_gadget/g1/strings
/config/usb_gadget/g1/configs/b.1
/config/usb_gadget/g1/configs/b.1/strings

item:
---------------------------------------
/config/usb_gadget/g1/os_desc
/config/usb_gadget/g1/configs/b.1/strings/0x409
/config/usb_gadget/g1/configs/b.1/strings/0x409
/config/usb_gadget/g1/functions/eap.mobilelink
/config/usb_gadget/g1/functions/iap.mobilelink
/config/usb_gadget/g1/functions/ncm.mobilelink

27.可以删除目录,但是不可以删除属性文件!!!

28.对confifs中的属性文件进行写操作,写的内容将被保存在合适的位置。

29.用户通过configfs创建configurations和functions,然后在configurations中
创建符号链接到functions。上面的这些信息在向UDC属性文件中写入udc_name时使用,
因为此时会触发gadget driver与gadget device的绑定的操作。
drivers/usb/gadget/configfs.c中的代码会遍历所有的configurations,对于每个配置都遍历其下的functions
然后进行绑定。

======>有两个bind,1是gadget驱动bind UDC,另一个是function bind配置。

30.drivers/usb/gadget/configfs.c做了下列事情
- gadget's config_group
- gadget's default groups (configs, functions, strings)
- associating functions with configurations (symlinks)

31.usb_get_function_instance()后调用equest_module(),它会触发用户空间的modprobe加载对应的function的驱动文件。但是当gadget被disable后这些已经加载的function驱动不会自动卸载。

32. alias ls="ls --color=auto" 可以使串口终端输出带颜色

33.很经典的描述:
--------------------------------------
1.A gadget is seen by its host as a set of configurations., each of which contains a number of interfaces, which from the gadget's perspective, are known as functions,
each function representing e.g. a serial connection or a SCSI disk.

2.Creating a gadget means deciding what configurations there will be and which functions each configuration will provide.

3.Configfs lends itself nicely for the purpose of telling the kernel about the above mentioned decision.

34.cofigfs中对应函数调用时机
mkdir时调用configfs_group_operations.make_item()
rmdir时调用configfs_group_operations.drop_item()
symlink时如果ct_item_ops->allow_link()方法存在,则可以使用config_item作为链接的源调用symlink, 这些链接仅在configfs的config_items之间被允许。 #######################
unlink时在符号链接上调用unlink()时,源项为通过ct_item_ops->drop_link()方法被通知。


/config/usb_gadget/g1 # ls
UDC bDeviceSubClass bcdUSB idProduct strings
bDeviceClass bMaxPacketSize0 configs idVendor
bDeviceProtocol bcdDevice functions os_desc
/config/usb_gadget/g1 # ls configs/
b.1
/config/usb_gadget/g1 # ls configs/b.1/
MaxPower bmAttributes f1 f2 f3 f4 f5 strings
/config/usb_gadget/g1 # ls strings/
0x409
/config/usb_gadget/g1 # ls functions/ -l
total 0
drwxr-xr-x 2 shell shell 0 2016-12-31 23:50 eap.mobilelink
drwxr-xr-x 2 shell shell 0 2016-12-31 23:50 eap_carbit.mobilelink
drwxr-xr-x 2 shell shell 0 2016-12-31 23:50 eap_welink.mobilelink
drwxr-xr-x 2 root root 0 2016-12-31 23:50 ffs.adb
drwxr-xr-x 2 shell shell 0 2016-12-31 23:50 iap.mobilelink
drwxr-xr-x 2 shell shell 0 2016-12-31 23:50 ncm.mobilelink
/config/usb_gadget/g1 # ls strings/0x409/
manufacturer product serialnumber
/config/usb_gadget/g1 # ls configs/b.1/ -l
total 0
-rw-r--r-- 1 root root 4096 2016-12-31 23:50 MaxPower
-rw-r--r-- 1 root root 4096 2017-01-01 00:05 bmAttributes
lrwxrwxrwx 1 root root 0 2016-12-31 23:50 f1 -> ../../../../usb_gadget/g1/functions/iap.mobilelink
lrwxrwxrwx 1 root root 0 2016-12-31 23:50 f2 -> ../../../../usb_gadget/g1/functions/ncm.mobilelink
lrwxrwxrwx 1 root root 0 2016-12-31 23:50 f3 -> ../../../../usb_gadget/g1/functions/eap.mobilelink
lrwxrwxrwx 1 root root 0 2016-12-31 23:50 f4 -> ../../../../usb_gadget/g1/functions/eap_carbit.mobilelink
lrwxrwxrwx 1 root root 0 2016-12-31 23:50 f5 -> ../../../../usb_gadget/g1/functions/ffs.adb
drwxr-xr-x 3 root root 0 2016-12-31 23:50 strings
/config/usb_gadget/g1 # ls os_desc/
b_vendor_code qw_sign use


35.configfs使用步骤:
===============================================

1.挂载configfs
$ mount none /config -t configfs

2.创建一个gadget
$ mkdir /config/usb_gadget/g1
$ cd /config/usb_gadget/g1
[@/config/usb_gadget/g1]$ echo <VID> > idVendor
[@/config/usb_gadget/g1]$ echo <PID> > idProduct
[@/config/usb_gadget/g1]$ mkdir strings/0x409
[@/config/usb_gadget/g1]$ echo <serial number> > strings/0x409/serialnumber
[@/config/usb_gadget/g1]$ echo <manufacturer> > strings/0x409/manufacturer
[@/config/usb_gadget/g1]$ echo <product> > strings/0x409/product

3.创建configs
[@/config/usb_gadget/g1]$ mkdir configs/<name>.<number>   #<name>表示gadget设备名,可以是任意字符串,<number>是configure ID,eg: mkdir configs/c.1 #1号配置
[@/config/usb_gadget/g1]$ echo 120 > configs/c.1/MaxPower #可以配置1号配置的内部的一些参数

4.创建functions
[@/config/usb_gadget/g1]$ mkdir functions/<name>.<instance name> #和配置的目录是在同一级目录下,eg:mkdir functions/iap.mobilelink name为iap, instance name为mobilelink ===>TODO: 这两个name有什么区别??
注意:<instance name> 是文件系统允许的任意字符串,mkdir创建config_item

5.将function和configs进行关联
[@/config/usb_gadget/g1]$ ln -s functions/<name>.<instance name> configs/<name>.<number>/fx   #Android中创建符号链接使用的不是ln

注意:一个function可以被多个configuration使用,Android中使用的是symlink创建的软链接

参考配置如下:
symlink /config/usb_gadget/g1/functions/iap.mobilelink /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ncm.mobilelink /config/usb_gadget/g1/configs/b.1/f2
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f3
write /config/usb_gadget/g1/UDC ${sys.usb.controller}

显示为:
/config # busybox ls --color /config/usb_gadget/g1/configs/b.1/ -l <
total 0
-rw-r--r-- 1 0 0 4096 Dec 31 15:50 MaxPower
-rw-r--r-- 1 0 0 4096 Dec 31 16:07 bmAttributes
lrwxrwxrwx 1 0 0 0 Dec 31 15:50 f1 -> ../../../../usb_gadget/g1/functions/iap.mobilelink
lrwxrwxrwx 1 0 0 0 Dec 31 15:50 f2 -> ../../../../usb_gadget/g1/functions/ncm.mobilelink
lrwxrwxrwx 1 0 0 0 Dec 31 15:50 f3 -> ../../../../usb_gadget/g1/functions/eap.mobilelink
lrwxrwxrwx 1 0 0 0 Dec 31 15:50 f4 -> ../../../../usb_gadget/g1/functions/eap_carbit.mobilelink
lrwxrwxrwx 1 0 0 0 Dec 31 15:50 f5 -> ../../../../usb_gadget/g1/functions/ffs.adb
drwxr-xr-x 3 0 0 0 Dec 31 15:50 strings
/config #

7.使能gadget
[@/config/usb_gadget/g1]$ echo <udc name> > UDC
如果gadget设备没有被使能,那么USB host就不能枚举它。通过绑定UDC才能使能gadget. udc name可以查找位置:/sys/class/udc

8.失能gadget
[@/config/usb_gadget/g1]$ echo "" > UDC

9.清理操作
a.将functions从configurations里面移除
[@/config/usb_gadget/g1]$ rm configs/<config name>.<number>/<function>
eg :
[@/config/usb_gadget/g1]$ rm /config/usb_gadget/g1/configs/b.1/f4 # 删除的是软链接

b.删除configurations下的strings目录
Remove strings directories in configurations
eg:
[@/config/usb_gadget/g1]$ rmdir configs/c.1/strings/0x409 # A平台上这个没有做

c.删除configurations
[@/config/usb_gadget/g1]$ rmdir configs/<config name>.<number>
eg:
rmdir configs/c.1

d.移除functions
[@/config/usb_gadget/g1]$ rmdir functions/<name>.<instance name>
eg:
$ rmdir functions/eap.mobilelink
注意:尽管functions是被移除了,但是加载的模块还是没有被卸载的。

e.删除gadget下的strings目录
[@/config/usb_gadget/g1]$ rmdir strings/<lang>
eg:
$ rmdir strings/0x409

f.最后删除gadget目录
[@/config/usb_gadget/g1]$ cd ..
[@/config/usb_gadget]$ rmdir <gadget name>
eg:
$ rmdir g1


本文参考链接:https://www.cnblogs.com/hellokitty2/p/10458143.html