11usbh_net
22===============
33
4- 本节主要介绍 USB 网卡的使用,USB 网卡推荐采用 AIR780(RNDIS),EC20(ECM/RNDIS), 手机(RNDIS),RTL8152 USB 网卡,AX88772 USB 网卡。
4+ 本节主要介绍 USB 网卡的使用,当前已经支持和测试以下 USB 网卡:
55
6- USB 网卡传输层面已经对接好了 LWIP 的收发接口,因此,用户只需要包含 ** platform/XXX/usbh_lwip.c ** 并根据需要开启对应的网卡类的宏即可。
6+ - 4G 网卡:EC20(ECM/RNDIS)、手机(RNDIS)、SIMCOM7600(RNDIS)、ML307R(RNDIS)、AIR780(RNDIS)
77
8- - 当前支持以下网卡类:
8+ .. caution :: 请注意,部分 4G 网卡默认不带自动拨号功能,请更换固件或者使用 AT 配置成自动拨号,否则无法获取 IP。
9+
10+ - USB 以太网卡:ASIX AX88772,REALTEK RTL8152
11+ - USB WIFI 网卡: 博流 BL616(RNDIS/ECM)
12+
13+ USB 网卡相关的宏和文件
14+ ------------------------
15+
16+ 网卡相关的宏如下,主要用于根据不同的网络组件注册网卡驱动:
917
1018.. code-block :: C
1119
@@ -14,34 +22,24 @@ USB 网卡传输层面已经对接好了 LWIP 的收发接口,因此,用户
1422 // #define CONFIG_USBHOST_PLATFORM_CDC_NCM
1523 // #define CONFIG_USBHOST_PLATFORM_ASIX
1624 // #define CONFIG_USBHOST_PLATFORM_RTL8152
17- // #define CONFIG_USBHOST_PLATFORM_BL616
1825
19- - 包含了对接 LWIP 的输入输出接口,举例如下
26+ .. note :: 如果使用了 Kconfig 系统,上述宏自定生成,其他平台请手动定义。
2027
21- .. code-block :: C
28+ USB 网卡传输层面已经对接好了相关网络组件,列举如下:
2229
23- static err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p)
24- {
25- int ret;
26- (void)netif;
30+ - 自定义 OS + LWIP 请使用 ** platform/lwip/usbh_lwip.c **,需要自行包含该文件,并使能上述相关的宏。并在初始化 USB 之前调用 ` tcpip_init(NULL, NULL) `
31+ - RT-THREAD + LWIP 请使用 ** platform/rtthread/usbh_lwip.c **,在 Kconfig 中使能对应的网卡驱动后自动勾选该文件,勾选 rt-thread lwip以后自动调用 ` tcpip_init(NULL, NULL) `
32+ - ESP-IDF + LWIP 请使用 ** platform/freertos/usbh_net.c **,在 Kconfig 中使能对应的网卡驱动后自动勾选该文件,并且在初始化 USB 之前调用 ` esp_netif_init() ` + ` esp_event_loop_create_default() `
33+ - NUTTX + NUTTX 网络组件 请使用 ** platform/nuttx/usbh_net.c **,在 Kconfig 中使能对应的网卡驱动后自动勾选该文件,勾选网络组件以后自动调用
2734
28- usbh_lwip_eth_output_common(p, usbh_cdc_ecm_get_eth_txbuf());
29- ret = usbh_cdc_ecm_eth_output(p->tot_len);
30- if (ret < 0) {
31- return ERR_BUF;
32- } else {
33- return ERR_OK;
34- }
35- }
35+ .. note :: 如果是自行添加代码,别忘了添加 USB 网卡驱动相关的源文件,例如 **class/usbh_cdc_ecm.c**。所以我们推荐搭配对应平台使用哦,省去自己添加文件的麻烦
3636
37- void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen)
38- {
39- usbh_lwip_eth_input_common(&g_cdc_ecm_netif, buf, buflen);
40- }
37+ USB 网卡对接过程
38+ -------------------
4139
40+ 下面举例对接 LWIP 的对接过程。
4241
43- - 网卡类枚举完成后,注册 netif,并且创建网卡接收线程(因此使用 RTTHREAD 时不需要使用 RTT 的接收线程模块)。
44- - 必须开启 DHCP client 服务,用于从 USB 网卡获取 IP 地址。
42+ - 在 USB 网卡枚举完成以后,会 **自动 ** 调用 `usbh_xxx_run ` 函数,此时注册 netif 驱动,并且开启 DHCP 客户端和获取 IP 的定时器。
4543
4644.. code-block :: C
4745
@@ -75,17 +73,61 @@ USB 网卡传输层面已经对接好了 LWIP 的收发接口,因此,用户
7573 #endif
7674 }
7775
78- - 获取到 IP 以后,就与 USB 没有关系了,直接使用 LWIP 的接口即可。
76+ - `usbh_lwip_eth_output_common ` 用于将发送 pbuf 组装成 USB 网卡数据包
77+ - `usbh_lwip_eth_input_common ` 用于将 USB 网卡数据组装成 pbuf
78+ - 实际网卡发送和接收处理
7979
80- - 需要注意以下参数
80+ .. code-block :: C
8181
82- LWIP_TCPIP_CORE_LOCKING_INPUT 用于不使用 lwip 内置的 tcpip 线程,而使用 USB 自己的处理线程。
82+ static err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p)
83+ {
84+ int ret;
85+ (void)netif;
8386
84- LWIP_TCPIP_CORE_LOCKING 在现在 lwip 版本中默认是打开的,也推荐必须打开。
87+ usbh_lwip_eth_output_common(p, usbh_cdc_ecm_get_eth_txbuf());
88+ ret = usbh_cdc_ecm_eth_output(p->tot_len);
89+ if (ret < 0) {
90+ return ERR_BUF;
91+ } else {
92+ return ERR_OK;
93+ }
94+ }
8595
86- PBUF_POOL_BUFSIZE 推荐大于1600,搭配 LWIP_TCPIP_CORE_LOCKING_INPUT 使用,因为我们提供了使用 zero mempy 的方式,使用静态 pbuf,而不是把数据 copy 到 pbuf 中。
96+ void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen)
97+ {
98+ usbh_lwip_eth_input_common(&g_cdc_ecm_netif, buf, buflen);
99+ }
87100
88- TCPIP_THREAD_STACKSIZE 推荐大于 1K,防止栈溢出。
101+ - USB 网卡 拔出以后会 **自动 ** 调用 `usbh_xxx_stop ` 函数,此时需要停止 DHCP 客户端,删除定时器,并且移除 netif。
102+
103+ .. code-block :: C
104+
105+ void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
106+ {
107+ struct netif *netif = &g_cdc_ecm_netif;
108+ (void)cdc_ecm_class;
109+
110+ #if LWIP_DHCP
111+ dhcp_stop(netif);
112+ dhcp_cleanup(netif);
113+ usb_osal_timer_delete(dhcp_handle);
114+ #endif
115+ netif_set_down(netif);
116+ netif_remove(netif);
117+ }
118+
119+ - 因为 USB 网卡内部已经对接了LWIP,因此用户可以直接使用 LWIP 的 API,无需关心 USB 的实现。
120+
121+ USB 网卡 LWIP 配置宏相关注意事项
122+ ------------------------------------
123+
124+ **LWIP_TCPIP_CORE_LOCKING_INPUT ** 用于不使用 lwip 内置的 tcpip 线程,而使用 USB 自己的接收处理线程。
125+
126+ **LWIP_TCPIP_CORE_LOCKING ** 在现在 lwip 版本中默认是打开的,也推荐必须打开。
127+
128+ **PBUF_POOL_BUFSIZE ** 推荐大于1600,搭配 LWIP_TCPIP_CORE_LOCKING_INPUT 使用,因为我们提供了使用 zero mempy 的方式,使用静态 pbuf,而不是把数据 copy 到 pbuf 中。
129+
130+ **TCPIP_THREAD_STACKSIZE ** 推荐大于 1K,防止栈溢出。
89131
90132.. code-block :: C
91133
@@ -105,4 +147,10 @@ TCPIP_THREAD_STACKSIZE 推荐大于 1K,防止栈溢出。
105147 #error TCPIP_THREAD_STACKSIZE must be >= 1024
106148 #endif
107149
108- - 具体移植文章可以参考开发者的一些笔记 https://club.rt-thread.org/ask/article/5cf3e9e0b2d95800.html
150+
151+ 总结
152+ --------------
153+
154+ .. note :: 通过以上内容,我们可以看到 CherryUSB 对 USB 网卡的支持是非常完善的,用户只需要使能对应的宏或者勾选,就可以实现 USB 网卡的自动识别和驱动注册,无需手动初始化网卡相关配置,用户只需关注应用层,极大地方便了用户的使用。
155+
156+ 具体移植文章可以参考开发者的一些笔记 https://club.rt-thread.org/ask/article/5cf3e9e0b2d95800.html
0 commit comments