# rk3399 USB RNIDS gagnet实战 **Repository Path**: jiang-yongxiang/rk3399_usb_rnids_gagnet ## Basic Information - **Project Name**: rk3399 USB RNIDS gagnet实战 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 8 - **Created**: 2021-12-15 - **Last Updated**: 2021-12-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rk3399 USB RNIDS/gagnet实战 任务目的:实现开发基于rk3399开发板的usb虚拟网卡功能。 任务描述:开发基于rk3399开发板的cartographer激光SLAM建图模块,需要定制价格最低、最小化的rk3399开发板,删除板上以太网卡和无线网卡,在不改变网络通讯程序的基础上,使用usb虚拟网卡进行数据传输。因此需要实现满足以上要求的最低价解决方案。 ## 1. 现有解决方案对比分析 经过调研,发现AX88179和RTL8153(USB转网口芯片)两种方法能满足任务要求。本报告中的数据来源于[AX88179](https://www.asix.com.tw/products.php?op=pItemdetail&PItemID=131;71;112)和[RTL8153官方文档](https://www.realtek.com/en/products/communications-network-ics/item/rtl8153) ### 1.1 基本参数 | 项目名 | AX88179 | RTL8153 | | ------------------------------------- | ---------------------------------------------- | ----------------- | | 传输速率 | 10/100/1000Mbps | 10/100/1000Mbps | | USB支持 | USB 3.0\2.0\1.1 | USB 3.0\2.0\1.1 | | 支持协议 | IPv4(IP/TCP/UDP/ICMP/IGMP)IPv6(TCP/UDP/ICMPv6) | IPv4/IPv6/TCP/UDP | | 电源管理(不同方式) | 支持 | 支持 | | Crossover Detection & Auto-Correction | 包含 | 包含 | | Wake-on-LAN | 支持 | 支持 | | IEEE 802.3x | 兼容 | 兼容 | | IEEE 802.3 | 兼容 | 兼容 | | IEEE 802.3u | 兼容 | 兼容 | | IEEE 802.3ab | 兼容 | | | IEEE 802.1P | Layer 2 Priority Encoding and Decoding | Layer 2 Priority Encoding | | IEEE 802.1Q | VLAN tagging and 2 VLAN ID filtering | VLAN tagging | | IEEE 802.3az | 兼容 | IEEE 802.3az-2010 | ### 1.2 电源管理 **AX88179** Advanced Power Management Features - Supports power management offload (ARP & NS) - Supports dynamic power management to reduce power dissipation during idle or light trafficUSB转网口芯片 - Supports AutoDetach power saving - Supports advanced link down power saving when Ethernet cable is unplugged **RTL8153** Intel CPPM (Converged Platform Power Management) - Supports L1 with 3ms BESL (USB 2.0) - Dynamic LTM messaging (USB 3.0) - Supports U1/U2 (USB 3.0) - Supports selective suspend 对比小结:两种USB转网口的芯片在大体的功能上没有很大的区别。相关功能从参数上来说较为一致。但部分功能如电源管理实现方式不同。由于USB转网卡芯片方案需要在开发板上集成网卡芯片,增大了开销和工作难度,因此我们选择AX88179方案。 **本小节参考文档** 1. [AX88179官方文档](https://www.asix.com.tw/products.php?op=pItemdetail&PItemID=131;71;112) 2. [RTL8153官方文档](https://www.realtek.com/en/products/communications-network-ics/item/rtl8153) ## 2. USB OTC模式 [RK3399-USB模块中的控制器和PHY](https://blog.csdn.net/kris_fei/article/details/80893535)中提到的RK3399的USB OTG配置如下 1. 接到USB2.0 PHY实现USB2.0 OTG的兼容。 2. 接到TypeC PHY实现USB3.0 OTG。 3. xHCI Host Controller实现Host功能 4. DWC3实现Device模式功能 USB3.0 OTG具有USB3.0 OTG功能,且向下兼容USB2.0 OTG功能,理论传输速率为5Gbps。USB3.0 HOST控制器为XHCI,集成于DWC3 OTG IP中,不用单独配置dts,只需要配置DWC3,并且设置DWC3的dr_mode属性为OTG,即可以enable XHCI控制器。 ``` dr_mode = “otg” ``` 或者 ``` dr_mode = “host” ``` USB3.0 OTG使用Synopsys方案,即XHCI扩展的DWC3控制器,Host功能在XHCI框架下实现,而Device功能由DWC3扩展部分实现。 配置说明见`Documentation/devicetree/bindings/usb/dwc3-rockchip.txt` Driver代码路径如下 1. drivers/usb/dwc3/* 2. drivers/usb/host/xhci* `drivers/usb/dwc3` 目录下的文件主要包括厂商引导驱动,Host Device通用DWC3控制器驱动和Device驱动,其中 文件名带厂商名字的为产商引导驱动,RK驱动文件名为dwc3-rockchip.c,core.c是DWC3控制器核心驱动,负责 加载XHCI驱动初始化XHCI控制器、加载Device驱动和初始化DWC3 Device控制器,gadget.c是DWC3 Device驱动 文件,主要实现控制器相关的Device初始化、中断处理和数据传输等功能。 ### 2.1 USB OTC在Linux下的实现方法 参考文档: 1. [OTG口在Linux的使用(H3)](http://git.linux-sunxi.cn/osi/orangepi/kai-shi-ru-keng/otgkou-zai-linux-de-shi-752828-h3.html) 2. [SEP6200平台上Linux内核的USB OTG驱动设计](https://www.ixueshu.com/document/f21b7d05519c5911237132d7bd1a8317318947a18e7f9386.html) 主要提供的实现方法如下: ![img](https://gitee.com/mr7_jacky/usb-otc-vs-vnc/raw/master/src/usb-otg.png) 最大带宽 = 5Gbps **实现方法** 参考[让Linux支持usb虚拟网卡](https://blog.csdn.net/qq_31878855/article/details/80742593) USB作为device端插入PC,在PC中会出现对用的SUB虚拟网卡,可以像普通网卡一样传递数据,socket编程。 **1. 需求** Linux下支持usb虚拟网卡,需要Linux内核支持UDC(usb 设备控制器)驱动和 Ethernet Gadget ( CDC Ethernet )驱动,cdc是usb的设备通讯类,Ethernet Gadget 驱动支持将多个以太网帧分组为一个USB传输。平台还需要支持rndis(Remote Network Driver Interface Specification),基于USB实现RNDIS实际上就是TCP/IP over USB,就是在USB设备上跑TCP/IP,让USB设备看上去像一块网卡。 **2. 步骤** 1. 首先关闭USB的host功能,打开usb gadget功能。 2. 进入到USB gadget support,打开USB Peripheral Controller,Anyka usb device Port, udc driver support(usb-otg)对应平台的UDC设备控制,让USB控制器运行在device模式。 3. 打开Ethernet Gadget 和RNDIS驱动支持。 4. 编译最后生成两个ko。udc.ko和g_ether.ko。 5. 将两个ko放入文件系统烧录到板上并加载ko,先加载udc.ko再加载g_ether.ko。 - insmod /usr/modules/udc.ko - insmod /usr/modules/g_ether.ko 6. 启动网卡 ifconfig usb0 192.168.0.1 up (IP地址随意) 7. 插入电脑 出现如下设备,该设备为usb虚拟网卡。 8. 配置IP为同一网段,互ping。 ## 3. rk3399 USB RNIDS/gagnet实战 ### 3.1 开发环境 开发板: toybrick rk3399proD 操作系统: Ubuntu 18.04 这方面的教程少之又少,在本人无数次踩坑下终于搞定。感兴趣的小伙伴可以打开[官方教程链接](http://t.rock-chips.com/wiki.php?mod=view&id=26)体验下想找教程却没有教程然后砸电脑未遂的心情。 ### 3.2 实现原理 在toybrick rk3399prod里面,Linux kernel和rootfs(根文件系统)是分开地址存放的,rootfs是在kernel之上运行的。Linux下所有的驱动和最基础的指令都存放在kernel里面,各个厂商根据自己的特性在kernel上开发自己的操作系统(例如fedora和ubuntu)。这款板子可以在不用重新编译内核的情况下更换操作系统,本文讲解如何编译驱动到kernel里面,支持多种操作系统。 我用的rootfs链接(ubuntu):[百度云网盘提取码:q9my](https://pan.baidu.com/s/1qU5noFQWEZ_M3hlIlAlcAA) ### 3.3 编译过程 首先,rk3399pro是A53+A7的芯片,需要特殊的gcc编译器,然后再编译。 ```bash git clone https://github.com/friendlyarm/prebuilts.git -b master --depth 1 cd prebuilts/gcc-x64 cat toolchain-6.4-aarch64.tar.gz* | sudo tar xz -C / ``` 然后再编辑你的.bashrc,把下面的东西加到`~/bashrc`的底部。 ```bash export PATH=/opt/FriendlyARM/toolchain/6.4-aarch64/bin:$PATH export GCC_COLORS=auto ``` 接下来,需要下载linux-kernel源码,由于官方给的源码太多坑,我把自己修改后的直接上传到gitee供国人下载,方便快捷。 ```bash git clone -b kernel-joybrick https://gitee.com/harryzhangabc/ros_bridge-and-catographer-setup.git ``` 这里介绍下如何给驱动添加USB RNIDS/gagnet网络功能。 ```bash cd /path/to/your/ros_bridge-and-catographer-setup/dir/ make menuconfig ``` 然后把下面的几个选项操作成如下方式 ``` USB Gadget Drivers USB functions configurable through configfs Ethernet Gadget (with CDC Ethernet support) [*] RNDIS support (NEW) ``` 接着在该目录下编译内核。 ```bash ./make.sh linux prod ``` 编译完成后会生成boot_linux.img文件,把这个文件烧入到3399pro对应的区域中[烧写教程](http://t.rock-chips.com/wiki.php?mod=view&id=14),只要烧这个文件,其他的都不用管。 当然你想偷懒的话可以用我编译好的:D[百度网盘提取码:pt7p](https://pan.baidu.com/s/1xrQr29kcJ-dr1g5A8dfVOg) 最后看下你编译好的文件,有几个驱动模块文件需要手动复制到3399pro里面手动加载 ``` drivers/usb/gadget/function/u_ether.ko drivers/usb/gadget/function/usb_f_ecm_subset.ko drivers/usb/gadget/function/usb_f_ecm.ko drivers/usb/gadget/function/usb_f_rndis.ko drivers/usb/gadget/legacy/g_ether.ko drivers/usb/gadget/libcomposite.ko ``` 然后在设备上,依次加载上述模块 ``` insmod libcomposite.ko insmod u_ether.ko insmod usb_f_rndis.ko insmod usb_f_ecm.ko insmod usb_f_ecm_subset.ko insmod g_ether.ko ``` 注意: 要先加载 libcomposite.ko 和 u_ether.ko,后面的模块才可以加载进去。 **IP地址设置** 用数据线连接 PC 机和设备的 OTG 接口,在 PC 机中执行 lsusb 命令可以查看到 USB 以太网设备,即说明连接成功。 ```bash firefly@Desktop:~$ lsusb Bus 002 Device 003: ID 09da:5814 A4Tech Co., Ltd. Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 005: ID 04f2:b2ea Chicony Electronics Co., Ltd Integrated Camera [ThinkPad] Bus 001 Device 004: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad] Bus 001 Device 003: ID 147e:1002 Upek Biometric Touchchip/Touchstrip Fingerprint Sensor Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 003: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub ``` **在设备中 IP 的设置** 输入执行 ifconfig -a 命令,可以查看到以下信息: ```bash root@firefly:~# ifconfig -a # eth0 是有线网卡 eth0: flags=4163 mtu 1500 inet 168.168.100.48 netmask 255.255.0.0 broadcast 168.168.255.255 inet6 fe80::1351:ae2f:442e:e436 prefixlen 64 scopeid 0x20 ether 8a:4f:c3:77:94:ac txqueuelen 1000 (Ethernet) RX packets 9759 bytes 897943 (897.9 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 236 bytes 35172 (35.1 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 42 base 0x8000 ... # usb0 是虚拟的 usb 网卡 usb0: flags=4098 mtu 1500 ether 4a:81:b1:34:d2:ad txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ``` 然后给 usb0 网卡自定义一个适当的 IP,注意要设置 usb0 的 IP 和有线网卡 eth0 的 IP 不在同一网段!! ```bash ifconfig usb0 192.168.1.101 ``` ubuntu下的IP设置如下 ```bash # 先查看 USB 虚拟网卡 firefly@Desktop:~$ ifconfig enp0s20u2i1: flags=4163 mtu 1500 inet 192.168.2.90 netmask 255.255.255.0 broadcast 192.168.2.255 inet6 fe80::871c:b87e:1327:7fd4 prefixlen 64 scopeid 0x20 ether 46:fe:6e:97:ee:a6 txqueuelen 1000 (以太网) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1 bytes 54 (54.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ... # 设置 USB 网卡的 IP 地址和设备的 usb0 的 IP 地址在同一网段 firefly@Desktop:~$ sudo ifconfig enp0s20u2i1 192.168.1.100 #设置默认网关:要设置为设备 usb0 的 ip 地址,因为后面要通过 usb0 来进行流量的转发 firefly@Desktop:~$ sudo route add default gw 192.168.1.101 ``` 设置完设备和 PC 机的 IP 后,互相是可以 ping 通的,PC 机也可以用 ssh 命令登录到设备。 配置过程中要注意以下几点: 1. 对应好上述步骤中自己设备上的各个 IP 地址,注意设备上的 USB 虚拟网卡 IP 和有线网络 IP 不在同一网段; 2. PC 机虚拟 USB 网卡的网关要设置为设备虚拟 USB 网卡的 IP 地址; 3. 设备上的虚拟网卡 IP 地址、IP 转发功能、流量转发规则等设置会在设备重启后恢复,然后大家可以自行查找资料如何开机自动设置这些配置。 ### 4. 参考链接 1. USB 以太网设置 http://wiki.t-firefly.com/zh_CN/Firefly-RK3399/ubuntu_manual.html#usb-yi-tai-wang 2. 如何烧写固件 http://t.rock-chips.com/wiki.php?mod=view&id=14 3. 编译 FriendlyCore/FriendlyDesktop/Lubuntu/EFlasher的内核源代码 http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T4/zh