拨号方式

蜂窝模组拨号类型

蜂窝模组作为网卡拨号在 Linux 下一般有以下几种方式:

  • PPP:用于建立点对点链路,慢速网络效率低

  • ECM/NCM:是在USB上是要满足CDC要求的

  • MBIM:移动宽带接口模型,专门用于3G/4G/5G模块的

  • RNDIS:基于USB实现RNDIS实际上就是TCP/IP over USB

  • RMNET/QMI_WWAN/GOBINET:高通专用,使用QIM工具拨号,使用方便

USB网卡拨号类型

拨号方式LinuxIP地址拨号工具
NDIS/QMI拨号1. QMI_WWAN有版本要求
2. GOBINET驱动需要手动移植
公网IPquectel-CM
ECM拨号驱动系统自带,很老的内核都支持私网IPAT拨号+udhcp
MBIM拨号驱动是系统自带的,很老的内核都支持公网IPquectel-CM
RNDIS拨号驱动系统自带,有版本要求私网IPAT拨号+udhcp
  • 私网IP 类似4G/5G模块作为路由给网卡分配了一个 192.168.xx.xx 的局域网地址,出口依然是模块拨号成功后的外网地址,所以在 ifconfig usb0 up 后需要使用 udhcpc -i usb0 进行地址分配。

  • 公网IP 是网卡拿到的IP 地址是和4G/5G模块地址差不多的,所以需要使用quectel-CM工具进行拨号。

拨号方式对比

  • PPP使用复杂,对CPU负载大,网速上不去,不推荐使用。

  • NDIS/QMI 拨号支持 QMAP 功能,可以实现 IP聚合和 IP复用功能。支持IP聚合就可以一次URB传输多个IP包,减少CPU负载率。支持IP复用,可以实现多网卡的功能。因此推荐使用(尤其是高通模组)。

  • ECM不支持IP聚合和复用功能,决定了不适用于高速场景。

  • RNDIS协议上是支持IP聚合的,但是Linux自带驱动没有使用,所以也不适用于高速场景。

  • MBIM默认就支持IP聚合,也支持IP复用,推荐使用。

EC20 网卡移植

EC20 网卡模式(高通平台)

模块支持 RMNET(Gobinet)RNDISECMMBIM 四种网卡功能,Linux 系统默认支持这些USB 网卡功能,除了 Gobinet 驱动外,其他模式的驱动模块 Kernel中 已经存在,不需要对Linux 系统的驱动文件做任何修改。

USB 网卡模式内核驱动拨号前模式设置
RMNET (Gobinet)低版本需要移植Gobinet驱动 高版本自带 qmi_wwan.cAT+QCFG="usbnet",0
ECMcdc_etherAT+QCFG="usbnet",1
MBIMcdc_mbimAT+QCFG="usbnet",2
RNDISrndis_hostAT+QCFG="usbnet",3

可以使用 AT+QCFG="usbnet" 查询当前模式。
EC20 Gobinet 驱动见 Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.0 其中的 User Guide 有较为详细的说明,Gobinet 仅能用于高通的网卡。

内核配置修改

使用图形化配置界面配置如下选项:

make menuconfig
# 支持USBNET 功能
Device Drivers --->
        -> [*] Network device support
                -> <*> USB Network Adapters
                       -> <*> Multi-purpose USB Networking Framework
                       

# 使能USB 串口GSM、CDMA 驱动
Device Drivers --->
        -> [*] USB support
                -> <*> USB Serial Converter support
                    -> <*> USB driver for GSM and CDMA modems

 

# 内核,使能 USB的 CDC ACM模式
Device Drivers --->
        -> [*] USB support 
                -> <*> Support for Host-side USB 
                       -> <*> USB Modem (CDC ACM) support

# 支持 ppp 拨号
Device Drivers --->
        -> [*] Network device support
                -> <*> PPP (point-to-point protocol) support
                -> <*> PPP BSD-Compress compression
                -> <*> PPP Deflate compression
                -> [*] PPP filtering
                -> <*> PPP MPPE compression (encryption)
                -> [*] PPP multilink support
                -> <*> PPP over Ethernet
                -> <*> PPP support for async serial ports
                -> <*> PPP support for sync tty ports

内核代码修改

添加 USB 设备信息

drivers/usb/serial/option.c 文件中添加 USB 设备信息,并做相应的修改如下:

/* 增加EC20 的vendor id 和产品id */ 
#define QUECTEL_VENDOR_ID    0x2c7c
#define QUECTEL_PRODUCT_EC20  0x0925
#define QUECTEL_PRODUCT_EC25  0x0125

/* option_ids数组里面增加usb 设备id信息 */
static const struct usb_device_id option_ids[] = {
    { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC20) },    /* Quectel EC20 */
    { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25) },    /* Quectel EC25/EC20 R2.0 */
    ....
};

static int option_probe(struct usb_serial *serial,
            const struct usb_device_id *id)

{

  ....
    /* EC20/EC25 驱动相关,防止被用作串口 */
    if (dev_desc->idVendor ==cpu_to_le16(QUECTEL_VENDOR_ID) &&
        iface_desc->bInterfaceNumber ==0x04)
        return -ENODEV;
    /* ************* */
    /* Store the blacklist info so we can use it during attach. */
    usb_set_serial_data(serial, (void *)blacklist);
    return 0;
}

 

static struct usb_serial_driver option_1port_device = {

  ....

  	#ifdef CONFIG_PM
    .suspend      = usb_wwan_suspend,
    .resume      = usb_wwan_resume,
  	/* 增加休眠唤醒回调 */
    .reset_resume   = usb_wwan_resume,
  	#endif
};

USB 零包处理

drivers/usb/serial/usb_wwan.c 中增加针对 EC20 USB 的零包处理代码,修改如下:

static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
          int endpoint,
          int dir, void *ctx, char *buf, int len,
          void (*callback) (struct urb *))
{

 ....
   
   /* 根据USB协议的要求,客户需要添加处理零数据包的机制 */
   if (dir == USB_DIR_OUT) {
       struct usb_device_descriptor *desc = &serial->dev->descriptor;
       if (desc->idVendor == cpu_to_le16(0x2c7c))
           urb->transfer_flags |= URB_ZERO_PACKET;
   }
   return urb;
}

内核编译测试

make imx_topeet_emmc_mfg_defconfig

make -j16

编译下载并启动后有如下log,表示已经识别出 EC20 虚拟出的 4 个usb口了。
4.1.png

4个usb口的作用如下:

ttyUSB描述
ttyUSB0DM
ttyUSB1GPS 的 NMEA 信息输出口
ttyUSB2AT指令输入口
ttyUSB3PPP 链接或AT指令输入口

GobiNet 驱动移植

由于编译成模块不太好往板子上下载,所以此处是把 GobiNet 直接编译到内核中,解压 Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.0 后,将 src 下的所有 .h 和 .c 文件拷贝到内核下的 /driver/net/usb 目录,然后再 drivers/net/usb/Makefile 中增加编译。

obj-y += GobiNet.o

GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o

完成以上所有步骤,驱动移植已经完成,编译内核并烧录后,ls /dev/qcqmi2 这个设备文件是否存在,如果存在的话就说明 Gobi 驱动工作成功。

quectel-CM 移植

quectel-CM 是移远提供的网络管理工具,使用这个工具中的相关命令进行联网等操作,类似使用 AT 命令,解压 Quectel_QConnectManager_Linux_V2.0.tar.xz.zip 后将源码拷贝到编译内核的 ubuntu 环境下进行交叉编译,目录不限,然后使用如下命令编译出 quectel-CM 工具。

make CROSS_COMPILE=arm-linux-gnueabihf-

编译完成后将 quectel-CM 软件拷贝到开发板根文件系统的** /usr/bin** 目录下给与执行权限,就可以使用如下命令来进行联网。

网卡拨号

检查USB转串口

启动 Linux 后,插入网卡(PCIE或者USB),会有如下 log 输出
4.2.png

通过命令查看 Linux 下新增的USB转串口设备,其中第三个串口为模块的AT 命令端口。可使用串口工具,如minicombusybox microcom,来测试AT 功能。

> ls /dev/ttyUSB*
/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3 /dev/ttyUSB4

检查网卡

模块连接到Linux USB口上,并成功加载USB 对应的网卡驱动后,将会在Host 生成一个网卡。cdc_mbim 还会生成一个cdc-wdm 字符设备用于命令交互。

通过 ifconfig -a 命令进行网卡查询,可以查看到对应的网卡模式下生成了响应的网卡节点,网卡模式和节点名称对照如下:

网卡模式AT拨号端口网卡节点名称拨号工具
RMNET (Gobinet)ttyUSB2eth2quectel-CM
ECMttyUSB2usb0AT 拨号+udhcp
MBIMttyUSB2wwan0quectel-CM
RNDISttyUSB2usb0AT 拨号+udhcp

AT 命令拨号

> microcom -s 9600 /dev/ttyUSB2

ATI
Quectel
EC20F
Revision: EC20CEHDLGR06A13M1G

OK

进入串口命令行:

# 设置拨号模式 0:RMNET, 1:ECM, 2:MBIM, 3:RNDIS
> AT+QCFG="usbnet",3

OK

# 也可以强制设置在4G模式下
> AT+QCFG=“nwscanmode”,3

OK

# 重启模块
> AT+CFUN=1,1

OK

# 如果使用RMNET、MBIM模式则不需要下面的AT,直接使用quectel-CM拨号

# 检查是否生效
> AT+QCFG="usbnet"

+QCFG: "usbnet",3
OK

# 配置PDP=1的上下文
> AT+CGDCONT=1,"IP","cmnet"

OK

# PDP=1 进行拨号,AT+CGACT=0,1 断开重连
> AT+CGACT=1,1

OK

# 测试模块外网通路
> AT+qping=1,"8.8.8.8"

OK

联网测试

RMNET、MBIM模式下拨号和网卡设置一起完成(仅适用于高通的网卡)

> ./quectel-CM -s cenet &

> ping www.baidu.com

ECM、RNDIS 模式下使用AT拨号后还需要手动设置网卡

> ifconfig usb0 up # 启动网卡

> udhcpc -i usb0  # 分配IP

> ping www.baidu.com

以下是使用 quectel-CM 拨号的 log 打印
4.3.png

连接成功后使用 ifconfig 即可查看到存在网卡 eth2 了。

quectel-CM 软件会使用到 udhcpc 来获取 IP地址,所以一定要确保当前根文件系统下存在 udhcpc,如果没有则使用 buildroot 的可视化配置工具添加 udhcpc 后重新编译根文件系统,然后烧录。

📎Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.0.zip
📎Quectel_QConnectManager_Linux_V2.0.tar.xz.zip

RG500U 网卡移植

RG500U 网卡模式(展锐平台)

模块支持RNDISECMMBIMNCM四种网卡模式,Linux 系统默认支持这些USB 网卡功能,系统内置驱动模块,不需要对Linux 系统的驱动文件做任何修改。

USB 网卡模式内核驱动拨号前模式设置
ECMcdc_etherAT+QCFG="usbnet",1
MBIMcdc_mbim(内核3.18以上)AT+QCFG="usbnet",2
RNDISrndis_hostAT+QCFG="usbnet",3
NCMcdc_ncmAT+QCFG="usbnet",5

可以使用 AT+QCFG="usbnet" 查询当前模式。

Kernel 内核修改

检查Linux 下 USB 驱动

> ls /sys/bus/usb/drivers

hub option usb usbfs usbhid usbserial usbserial_generic rndis_host cdc_ether cdc_ncm cdc_mbim

首先需要保证USB 转串口驱动存在,即option 存在;

如需移植USB NCM 驱动,请确保cdc_ncm 存在;

如需移植USB ECM 驱动,请确保cdc_ether 存在;

如需移植USB MBIM 驱动,请确保cdc_mbim 存在;

如需移植USB RNDIS 驱动,请确保rndis_host 存在;

增加USB驱动

make menuconfig 

> Device Drivers > Network device support > USB Network Adapters

4.4.png

USB 转串口驱动修改

kernel 中的 USB 转串口option 驱动的 option.c 中修改如下,其余部分见 EC20 网卡移植部分

/* 增加RG500U 的vendor id 和产品id */ 
#define QUECTEL_VENDOR_ID    0x2c7c
#define QUECTEL_PRODUCT_RG500U 0x0900 /* RG200U/RG500U/RM500U */

内核编译

修改完成后重新编译内核,并烧录 kernel 到目标板

make imx_topeet_emmc_mfg_defconfig

make -j16

网卡拨号

检查USB 转串口

启动 Linux 后,插入网卡(PCIE或者USB),会有如下 log 输出
4.2.png

通过命令查看 Linux 下新增的USB转串口设备,其中第三个串口为模块的AT 命令端口。可使用串口工具,如minicombusybox microcom来测试AT 功能。

> ls /dev/ttyUSB*

/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3 /dev/ttyUSB4

检查网卡

模块连接到Linux USB口上,并成功加载 USB 对应的网卡驱动后,将会生成一个网卡。cdc_mbi还会生成一个cdc-wdm 字符设备用于命令交互。

通过 ifconfig -a 命令进行网卡查询,可以查看到对应的网卡模式下生成了响应的网卡节点,网卡模式和节点名称对照如下:

网卡模式AT拨号端口网卡节点名称拨号工具
1 ECMttyUSB2usb0AT 拨号+udhcp
2 MBIMttyUSB2wwan0quectel-CM
3 RNDISttyUSB2usb0AT 拨号+udhcp
5 NCMttyUSB2usb0AT 拨号+udhcp

AT 命令拨号

> microcom -s 9600 /dev/ttyUSB2

ATI
Quectel
RG500U-CN
Revision: RG500UCNABR01A05M2G

OK

进入串口命令行:

# 禁用模块Ethernet网卡,仅启用蜂窝网
> AT+QCFG="ethernet",0

OK

# 设置为网卡模式
> AT+QCFG="nat",0

OK

# 设置拨号模式 1:ECM, 2:MBIM, 3:RNDIS, 5:NCM
> AT+QCFG="usbnet",5

OK

# 也可以强制设置在4G模式下
> AT+QCFG=“nwscanmode”,3

OK

 

# 重启模块
> "AT+CFUN=1,1\r\n"

OK

# 检查是否生效
> AT+QCFG="usbnet"

+QCFG: "usbnet",2

OK

# 如果使用 MBIM 模式则不需要下面的AT,直接使用quectel-CM拨号
# 配置PDP=1的上下文
> AT+QICSGP=1,1,"cmnet","","",0

OK

# PDP=1 进行拨号,自动重连
> AT+QNETDEVCTL=1,3,1 #1,0,1 断开拨号

OK

# 查询PDP=1状态
> AT+QNETDEVSTATUS=1

+QNETDEVSTATUS: 10.9.0.35,,10.9.0.35,,211.138.180.2,211.138.180.3,2409:8931:0421:0aa5:0000:0000:0000:0001,,2409:8931:0421:0aa5:0000:0000:0000:0001,,2409:8030:2000:0000:0000:0000:0000:0001,2409:8030:2000:0000:0000:0000:0000:0002

OK

具体命令参数见《Quectel_RG200U-CN&Rx500U-CN_Linux_USB驱动_用户指导_V1.2.pdf》

联网测试

# 1. 启动网卡
ifconfig usb0 up 

# 2. 分配IP
udhcpc -i usb0

# 3. 测试
ping www.baidu.com

📎Quectel_RG200U-CN&Rx500U-CN_Linux_USB驱动_用户指导_V1.2.pdf
📎Quectel_RG200U-CN&Rx500U-CN_网卡拨号应用指导_V1.1.pdf

文章作者: 路西法
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 以梦为马
imx6ull imx6ull Linux
喜欢就支持一下吧