Linux USB ECM Gadget 驱动介绍
1 USB ECM介绍
USB ECM,属于USB-IF定义的CDC(Communication Device Class)下的一个子类:Ethernet Networking Control Model,用于Host和Device之间交换以太网帧。下图是从USB ECM规范中截取:
2 关键描述符解析
用USB tool抓取ECM设备的描述符,部分关键描述符如下。
首先是IAD描述符。
IAD Descriptor : Interface AssociationDescriptor,接口关联描述符,将多个接口组合在一起。
bDescriptorType : 0x0B 表示描述符类型是IAD描述符。
bInterfaceCount : 0x02表示组合的接口数目是2个。
bFunctionClass : 0x02表示CDC class。
bFunctionSubClass : 0x06表示ECM subclass.
接下来是接口0的描述符,接口0用作ECM的control接口。
Interface Descriptor : 接口描述符
bInterfaceNumber : 0x00 标识该接口为接口0
bAlternateSetting : 0x00 如果同一个接口有多个描述符设置,那该值就用来区分是哪个
bNumEndpoints : 0x01表示该接口使用1个端点
bInterfaceClass : 0x02 表示CDC class
bInterfaceSubClass : 0x06 表示ECM subclass
bInterfaceProtocol : 0x00 表示使用标准协议
以下三个CDC Interface Descriptor属于functional descriptor,functional descriptor用来描述class-specific的信息,从属于某个标准接口描述符下。
HeaderFunctional Descriptor,CDC class-specific的描述符必须以这个描述符作为开头。
UnionFunctional Descriptor,包含控制接口信息。
EthernetNetworking Functional Descriptor,包含网卡的信息,比如MAC地址、统计能力等。其中MAC地址是通过字符串index来间接表示的,位于该描述符第4个字节,这里是06,表示String Descriptor 6中存放了MAC地址。
接口0的端点描述符,使用IN-2端点,端点方向为IN(Device->Host),中断传输方式。
接下来是接口1的描述符,大部分字段的意义和接口0的描述符类似,因此不再重复解释。接口1用作ECM的data接口。
接口1用做ECM的data接口。分配了两个端点。
接口1的端点描述符,使用了IN-1端点,传输类型为Bulk。
接口1的另一个端点描述符,使用了OUT-1端点,传输类型为Bulk。
接下来是字串描述符,这里只截取了字串6,也就是存放MAC地址的字串。
3 数据通路
Device ->Host:
在ECM Gadget驱动中,USB角色是device,在本地注册一个以太网卡设备,网络协议栈发送数据到该网卡,该网卡驱动会将数据以USB传输的方式发送到主机。Host端有ECM Host驱动,也会在Host端注册一个以太网卡,收到USB传输过来的数据后,网卡会将数据上报给Host端的网络协议栈。
Host -> Devcie:
Host端网络协议栈把数据发给ECM Host驱动,ECM Host驱动以USB传输的方式将数据发送给Device,Device端网卡收到数据后,上报给Device端网络协议栈。
4 驱动流程
源码位置在:
drivers\usb\gadget\function\f_ecm.c
drivers\usb\gadget\function\u_ether.c
4.1 驱动的注册
注册function到USB gadget驱动框架中。
1 |
|
4.2 USB function的实现
-
ecm_alloc_inst函数主要是调用gether_setup_default创建一个net设备。
1 |
|
-
ecm_alloc函数主要做两件事:
一是从net设备中获取该网卡host mac地址并记录下来,后续bind时会添加到描述符中。
1 2 |
|
二是按USB function driver框架注册各回调函数。
1 2 3 4 5 6 7 8 9 |
|
-
ecm_bind函数主要完成USB bind的过程:
一是将net设备和gadget关联,并注册net设备。
1 2 3 4 5 6 7 8 9 |
|
二是处理字符串描述符。
1 2 3 4 5 6 7 8 9 10 |
|
三是分配interface,并将interface信息更新到描述符中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
四是分配端点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
五是分配描述符。
1 2 |
|
4.3 网卡部分的实现
-
网卡设备操作函数集
1 2 3 4 5 6 7 |
|
-
分配网卡设备
1 2 3 4 |
|
-
注册网卡设备
1 |
|
-
数据的收发
1 2 3 4 5 |
|
以上就是对Linux USB ECM Gadget驱动的介绍,谢谢阅读。
文章会在公众号“大鱼嵌入式”同步发布,欢迎关注,一起交流。