一、概述
在物联网应用当中,有些应用场景需要用到USB 4G模块进行上网,实现外网数据交互。先楫目前的所有hpm6000系列芯片均带有高速480mbps USB接口,可以作为host主机连接各种4G模块。本篇文章以合宙air780e模块为例,讨论如何使用该模块进行上网。
二、原理介绍
1、RNDIS简介
RNDIS(Remote Network Driver Interface Specification)是微软公司定义的USB协议,适用于动态 即插即用 (PnP) 总线(例如 USB、1394、蓝牙和 InfiniBand)上的以太网 (802.3) 网络设备。插入4G USB模块到window系统,设备管理器上会出现rndis设备,window会适配为网络设备,以此进行上网。
远程 NDIS 通过抽象控制和数据通道在主计算机与远程 NDIS 设备之间定义与总线无关的消息协议,消息协议大致分为控制消息和数据消息,控制消息主要用于主机发送给ndis设备的相关控制,比如初始化网络连接REMOTE_NDIS_INITIALIZE_MSG;数据消息主要用于收发tcp/ip协议。如下:
启动网络连接时候,需要做一些初始化,window的文档同样也提供了初始化示例,在实现的一章会基于该示例进行初始化。
2、RNDIS的USB接口端点解析
RNDIS设备需要两个bulk endpoint EP1和EP2端口,分别用来收发RNDIS以太网帧的数据消息,另外需要一个端点0-EP0,用来进行枚举以及RNDIS控制消息传输。
3、合宙air780e模块的USB接口端点解析
在window上,插入780e模块上电后会出现以下三个端口(虚拟串口)以及一个rndis设备。虚拟串口有两个用来发送AT命令,一个用到做log口。详细信息可以参考合宙官网介绍。
在这里我们仅仅使用rndis这个设备,其他的虚拟串口并不需要,但是事实上,hpm6000使用USB作为主机时,需要枚举这些hub设备。因此需要估算下所需要的接口端点数量。一共需要9个endpoint, 以下就是合宙air680e模块的端点解析。
三、方案实现
本章节分别采取hpm_sdk和hpmicro rtthread bsp两种方式实现。均是采用cherryusb协议栈,cherryusb协议栈支持device以及host,host端支持rndis这个class,这样可以快速布局4G usb模块的开发。
1、cherryusb协议栈的USB host的基本知识和配置
本章节目前使用的是cherryusb 0.8版本,若使用其他版本,可能会有一些兼容问题出现,需要开发者自己去调试。
当USB作为HOST主机时,需要配合rtos使用。基本流程如下:
如上所示,需要注意的是“device枚举配置过程”, 需要注意配置下最大的interface和最大endpoint数量。在cherryusb中,提供了usb_config头文件配置,里面可以进行更改。
如果usb log出现 “[E/USB] Interface num overflow”,则说明有些interface Descriptor的bInterfaceNumber,也就是接口编号大于usb_config设置的CONFIG_USBHOST_MAX_INTERFACES,需要更改比之前更大的值
如果usb log出现 “[E/USB] Endpoint num overflow”,则说明有些interface Descriptor的bNumEndpoints,也就是接口使用的端口号大于usb_config设置的CONFIG_USBHOST_MAX_ENDPOINTS,需要更改比之前更大的值
2、cherryusb协议栈的USB HOST RNDIS基本知识和配置
在上述的USB流程之后,如果class driver支持rndis,那么就会进入到class_connect接口进行相关配置。
每个支持的class driver都会对应的connect接口,也就是在usbh_rndis_connect这个api,也就是上述所说的802.3初始化序列示例流程,流程如下:
RNDIS OID相关信息如下:
3、使用hpm_sdk
hpm_sdk已经集成了cherryusb协议栈,可以使用cmake进行配置构建,这里需要做的是rndis需要适配对接lwip,后续的sdk版本将会支持适配。这里做下简单介绍。
①对接rndis
cherryusb协议栈中,对rndis class进行连接成功后,开放了两个weak接口,分别是usbh_rndis_run和usbh_rndis_stop两个api。usbh_rndis_run这个api主要实现lwip网卡加载,netif的output对接rndis的发送api,新建一个软件定时器定时发送keepalive,新建一个线程接收rndis消息,进行分包解析,进而把pbuf丢入lwip的input接口进行以太网包解析。usbh_rndis_stop这个api主要实现删除相关线程管理以及注册的网卡。
②对接Lwip
网卡注册时候,也就是netif_add这个api的init注册,需要实现,也就是截图中的netif_init_cb,需要对接rndis的发送接口。以下是实现方式:
lwip接收解析上,需要单独开个接收线程,rndis端如果有接收到数据,立马进行分包解析,解析完的pbuf丢给lwip的input进行再次解析。
至此,适配完成,移植个ping ip,可以进行外网访问,效果如下:
4、使用hpmicro rtthread bsp
使用该bsp,可以在rtthread studio进行开发,cherryusb仓库已经支持了rtthread的host rndis适配。可以使用online packages进行配置使用。下面对此进行步骤说明。
①选择hpmicro的支持的Bsp board,这里选择hpm6750evkmini,选择模板工程。
② 点击RT-Thread Settings,点击添加软件包,选择cherryusb
③ 配置cherryusb,配置如下:
④网络使能 分别使能套接字抽象层、网络接口设备、lwip,其中lwip线程和以太网栈线程的大小都改为2048,其他使用默认即可
⑤修改内核的软件定时器的栈大小,默认512,改为1024
⑥ 保存以上配置,等待rtthread studi配置应用加载完成。
⑦从所在工程的packages文件夹中的cherryusb部分,在thrid_party的rtthread拷贝rndis_host文件到application文件夹,在hpm_sdk中的sample的cherryusb的根目录拷贝usb_config.h拷贝到application文件夹,并刷新工程,这时候rndis_host.c和usb_config.h就加载完毕。
⑧ 在main,c中定义一个函数,用来初始化USB引脚以及USB主机协议栈初始化,并加入以下头文件包含
⑨ 修改ld文件,加入device class driver info section
⑩ 编译烧录,可以看到现象,可以Ping 外网成功。
5、板子连接
本文使用hpm6750evkmini为例,但是不限于该板子,先楫目前发布的板子均可使用。使用air780e和hpm6750evkmini连线如下:
四、总结
本文讨论了如何使用hpmicro中支持usb的芯片以及板子连接到USB 4G模块AIR780E上网。从hpm_sdk和hpmicro rtthread bsp切入,方便用户参考连接其他4G模块。