Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
CherryUSB
USB_RNDIS网卡
USB
基于CherryUSB Host适配RNDIS网卡笔记
发布于 2022-03-13 00:01:47 浏览:9878
订阅该版
[tocm] ## 前言 原项目中需要用到RNDIS,移植了一版,效果不是很好,项目最后没用上😭 现在计划重新基于CherryUSB来适配,记录一些调试笔记。 ## 计划 因有一些USB基础,因此打算以突击的方式来推进。 ## 开发环境 ### 开发板 干活前先做准备工作,了解到目前CherryUSB HOST驱动适配相对较好的是STM32,刚好有个429开发板,因此就打算以这个板子来进行开发。 示例工程可以开箱即用,同时可以SWD仿真调试,应该能给后期调试带来方便。 ### 网卡 RNDIS网卡选用的Air724UG,先插好4G SIM卡,接在电脑上确认能正常识别为RNDIS并能上网。建议抄下设备所有相关的信息,以方便后面调试时对比。 ``` UNISOC Communications Inc. LUAT USB Device 0 Modem USB\VID_1782&PID_4E00&MI_02\6&2BFA9591&0&0002 USB\VID_1782&PID_4E00&REV_0000&MI_02 USB\VID_1782&PID_4E00&MI_02 USB\Class_ff&SubClass_00&Prot_00 USB\Class_ff&SubClass_00 USB\Class_ff LUAT USB Device 1 AT USB\VID_1782&PID_4E00&MI_03\6&2BFA9591&0&0003 USB\VID_1782&PID_4E00&REV_0000&MI_03 USB\VID_1782&PID_4E00&MI_03 USB\Class_ff&SubClass_00&Prot_00 USB\Class_ff&SubClass_00 USB\Class_ff LUAT USB Device 2 AP Diag USB\VID_1782&PID_4E00&MI_04\6&2BFA9591&0&0004 USB\VID_1782&PID_4E00&REV_0000&MI_04 USB\VID_1782&PID_4E00&MI_04 USB\Class_ff&SubClass_00&Prot_00 USB\Class_ff&SubClass_00 USB\Class_ff 基于远程 NDIS 的 Internet 共享设备 USB\VID_1782&PID_4E00&MI_00\6&2BFA9591&0&0000 USB\VID_1782&PID_4E00&REV_0000&MI_00 USB\VID_1782&PID_4E00&MI_00 USB\Class_e0&SubClass_01&Prot_03 USB\Class_e0&SubClass_01 USB\Class_e0 USB Composite Device USB\VID_1782&PID_4E00\5&C6BC3AE&0&1 USB\VID_1782&PID_4E00&REV_0000 USB\VID_1782&PID_4E00 USB\DevClass_00&SubClass_00&Prot_00 USB\DevClass_00&SubClass_00 USB\DevClass_00 USB\COMPOSITE ``` ![枚举1.png](https://oss-club.rt-thread.org/uploads/20220314/48484b4e29b34507a9e24fe6ce94751f.png.webp) ### USB抓包分析仪 还在路上,现在居家办公,看起来一时半会快递不会送了😪 --- ## 调试过程 ### 抓包 没有硬件抓包,就先来软件抓个包吧,Wireshark就可以,好用得很。 买了[这位老兄的RNDIS插件](https://blog.csdn.net/bacon315/article/details/113076499),就能解析RNDIS协议了。 ![QQ截图20220314124059.png](https://oss-club.rt-thread.org/uploads/20220314/a502ba9e170abaed91b708df63eb5989.png) ### 上板枚举 把我的4G网卡插到开发板上,提示 ``` [I/USB] Hub 1, Port 1 connected, low speed [E/USB] Failed to get device descriptor,errorcode:-16 [I/USB] Hub 1,Port:1 disconnected ...不停重复 ``` 分析感觉不对,至少也得是`full speed`才对,`low speed`后面也无法切成高速。 大佬建议先插好网卡,再启动软件这边来枚举。 之前是自动启动USB的,现在改为命令启动,插好网卡后2秒后,再手动启动USB。 ```c [I/USB] Hub 1, Port 1 connected, full speed [I/USB] Enumeration success, start loading class driver [E/USB] do not support Class:0xe0,Subclass:0x01,Protocl:0x03 [E/USB] do not support Class:0x0a,Subclass:0x00,Protocl:0x00 [E/USB] do not support Class:0xff,Subclass:0x00,Protocl:0x00 [E/USB] do not support Class:0xff,Subclass:0x00,Protocl:0x00 [E/USB] do not support Class:0xff,Subclass:0x00,Protocl:0x00 [I/USB] Hub 1,Port:1 disconnected ``` 看起来都正常了,至少枚举过程是完成了。 项目中用的话,估计要从供电和开机过程中来找问题,不然怕起不来。 ### class驱动 根据现有calss驱动,照葫芦画瓢。 `class\wireless\usbh_rndis.c` ```c // Class:0xe0,Subclass:0x01,Protocl:0x03: 只有1个用于中断通知的endpoint const struct usbh_class_driver rndis_class_driver = { .driver_name = "rndis", .connect = usbh_rndis_connect, .disconnect = usbh_rndis_disconnect }; ``` `core/usbh_core.c` ```c { .class = USB_DEVICE_CLASS_WIRELESS, // 0xe0 .subclass = 0x01, // RNDIS .protocol = 0x03, .vid = 0x00, .pid = 0x00, .class_driver = &rndis_class_driver }, ``` 发现`Class:0xe0,Subclass:0x01,Protocl:0x03`里面只有一个`int endpoint`。 真正传输数据是在`Class:0x0a,Subclass:0x00,Protocl:0x00`这个是`CDC_DATA`, 里面有`bulkin`和`bulkout`。 于是我机智的注册了2个class用于快速测试。🐷🐷🐷🐷🐷🐷 依样学样,在`connect`中`alloc`好`class driver`和`bulk endpoint`后。 就是试着`usbh_ep_bulk_transfer(class->bulkout`发了一个`DHCP Discover`数据包出去。 然后`usbh_ep_bulk_async_transfer(bulkin`的`callback`里面就收到一个一样长的数据包。 我凭经验感觉这就是`DHCP Offer`,直呼太行了,这就通了。 ### 疯狂调试并对接相关API 有了基本通信能力后,开始整理代码,对接驱动。然后发现这收到的数据包和我发出去的完全一样。。 这不可能是DHCP Offer,看源和目标MAC地址就知道这不对,因为没有硬件分析仪,这里就假定这是设备发出的包。 于是脑补成这是网卡里面可能有类似交换机的机制,因为DHCP Discover是个广播包。 虽然这挺奇怪的,会有回环风险,但host这边并不会转发,所以回环不了。 等把驱动接口对得差不多了,通过软件dump发现所有网卡发出的数据包,根本就没有我想要的, 基本都是我自己发出去的,有时连回弹也没有。 分析下来,应该是有些初始化和设置没有做。 于是逐步对接一些接口 #### rndis_init 发送`RNDIS_MSG_INIT`,用于初始化 #### rndis_query_oid 发送`RNDIS_MSG_QUERY`,查询设备的一些属性,调试下来感觉主要是MAC地址,其它参数在跑通阶段可以不用太关心。 不过`RNDIS_OID_GEN_MEDIA_CONNECT_STATUS`要关注下,这是反应网线连接状态。 4G网卡并没有网线,因此主要反应SIM卡和网络服务的状态。 #### rndis_msg_set 发送`RNDIS_MSG_SET`,设置设备的一些属性,主要是包过滤器。 #### rndis_keepalive 发送`RNDIS_MSG_KEEPALIVE`保活,用于在没有数据包时让USB一直有通信。 发`RNDIS_MSG_KEEPALIVE`时,有时会收到`RNDIS_MSG_INDICATE`。 此时应该再收1次`RNDIS_MSG_KEEPALIVE_C`。 开始不通时,以为这里是 关键,一直要等到`INDICATE`才行,后面换了一个android手机来测试。 发现手机根本就不发`INDICATE`,通过抓包发现PC在没有`INDICATE`时就已经在通信了, 看来只需要`RNDIS_OID_GEN_MEDIA_CONNECT_STATUS`显示连接上就能收发数据了。 然而此时host上面的rndis网卡依然无法收到数据,甚至连有没有发出去都开始怀疑了, 调试一度陷入困境,好在只是抽空研究一下,并非主要工作。 ### 发现线索 在多次高度中,发现有时 callback中收到的数据,并不一定是我发出的。 有好几次都显示收到一串数据 ``` 00000000: 0D 0A 53 4D 53 20 52 45 41 44 59 0D 0A ..SMS READY.. ``` 看数据内容,绝对不是我发出的,且不可能是脏数据,那么至少说明这是网卡发出的。 另外看前面都有 `\r\n`,看起来是个文本交互。 看RNDIS的数据报头,都是二进制的结构体`struct rndis_data_hdr` 也不可能是这个文本啊,很是奇怪。 直到向大佬请教此问题时,说这个像是AT数据。 AT AT AT !!! 突然想起,这个网卡不就是有3个AT用的串口嘛?那应该是那边的数据,但我并没有读那几个intf啊。 像是错位了。。。 突然想到前面注册class时进行了非常规操作🐷,然后抄过来的cdc代码中是用的`[intf + 1]`, 用于`intf[0]`里面绑定`intf[1]`。 而我是**自作聪明**的写了2个`class driver`,那此第2个就不能用`[intf + 1]`。 不然往后挪1个,不正好是AT串口嘛。😂 把这改回,果然收到了网卡发出的数据。👍👍👍 至此,数据收发都通了,接下来就愉快写重构代码,整理驱动,优化性能并压测稳定性了!! 这种1个`Control interface`再加1个`Data interface`基本是标配,这块之前不了解,所以掉坑了!多沉下心来阅读理解规范就能少些弯路!
10
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
aozima
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
文章
28
回答
4481
被采纳
381
关注TA
发私信
相关文章
1
请教USB Host
2
STM32F4调试USB 读卡器(Slave)提示格式化
3
急求 STM32F4 USB Device MSC+SD 的相关问题
4
USB 框架问题
5
USB键盘
6
LPC17xx 如何添加USB HOST设备
7
RT-Thread目前支持USB HOST了吗?
8
USB HOST的支持问题
9
RTT 2.0.1 USB存储设备问题,枚举到USBREQ_GET_MAX_LUN后复位
10
USB库已经很久没更新了
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
812
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部