一、简介

  使用有线网络和无线 wifi 都会存在一些限制,因为都需要周围环境中存在路由器等设备才能连接,所以就需要一种直接使用蜂窝网络联网的方案。

  目前市面上很多4G 模块都是 MiniPCIE 接口的,很适合用于Linux 平台或者 Android 平台。不过虽然使用的接口是 MiniPCIE,内部的通信协议却大多是 USB,所以驱动的开发就转化成了 USB 驱动开发。


二、驱动开发

原理图:

image.png

图中的 U22 就是 MiniPCIE 接口,该接口连接到 FE2.1 这个 USB HUB 芯片的 DP7 和 DM7 引脚。U26 为 Nano SIM 接口,这样就可以通过手机卡进行联网测试。


实物图:

image.png

4G模块:

image.png

左边为高新兴物联的 ME3630,右边为上海移远公司的 EC20。将模块连接到开发板上,再插入 SIM 卡,就可以进行后续的驱动开发了。(模块需要连接配套的天线)


1.高新兴 ME3630 驱动开发

  ME3630 是一款 LTE Cat.4 七模全网通 4G 模块,在 LTE 模式下可以提供 50Mbps 上行速率以及 150Mbps 的下行速率,并支持回退到 3G 或 2G 网络。其特性如下:


① 一路 USB2.0 接口。

② 一路 UART 接口。

③ SIM 卡接口支持 1.8/3.0V。

④ 内置 TCP、 UDP、 FTP 和 HTTP 等协议。

⑤ 支持 RAS/ECM/NDIS。

⑥ 支持 AT 指令。


ME3630 4G 模块有多种配置,比如纯数据版本、集成 GNSS 版本、全网通版本等。本节主要使用数据通信功能,所以可以使用全网通版本,如果需要定位功能,就要使用全网通+GNSS版本。

image.png


驱动修改

首先需要在 Linux 内核中添加 ME3630 的 USB 设备信息,打开 Linux 源码的 drivers/usb/serial/option.c 文件,在 option_ids 数组中,添加 ME3630 的 PID 和 VID:


{ USB_DEVICE(0x19d2, 0x0117) }, /* ME3630*/

{ USB_DEVICE(0x19d2, 0x0199) },

{ USB_DEVICE(0x19d2, 0x1476) },

 image.png


添加 ECM 支持程序

ME3630 支持 ECM 接口,可以通过 ECM 接口轻松联网,修改 drivers/usb/serial/option.c 文件中的 option_probe 函数,添加如下内容:


/* GOSUNCN 4G modems */

printk("idVendor=%x, idProduct=%x, bInterfaceNumber =%d\r\n",

serial->dev->descriptor.idVendor,

serial->dev->descriptor.idProduct,

serial->interface->cur_altsetting->desc. bInterfaceNumber);


if (serial->dev->descriptor.idVendor == 0x19d2 &&

serial->dev->descriptor.idProduct == 0x1476 &&

serial->interface->cur_altsetting->desc. bInterfaceNumber == 3)

return -ENODEV;


if (serial->dev->descriptor.idVendor == 0x19d2 &&

serial->dev->descriptor.idProduct == 0x1476 &&

serial->interface->cur_altsetting->desc. bInterfaceNumber == 4)

return -ENODEV;


if (serial->dev->descriptor.idVendor == 0x19d2 &&

serial->dev->descriptor.idProduct == 0x1509 &&

serial->interface->cur_altsetting->desc. bInterfaceNumber == 4)

return -ENODEV;


if (serial->dev->descriptor.idVendor == 0x19d2 &&

serial->dev->descriptor.idProduct == 0x1509 &&

serial->interface->cur_altsetting->desc. bInterfaceNumber == 5)

return -ENODEV;

 

image.png


配置 Linux 内核

首先使能 USBNET 功能,在 Device Drivers 路径下,选中以下选项:

image.png

然后使能 USB 串口 GSM、CDMA 驱动:

image.png

使能 USB 的 CDC ACM 模式:

image.png


ppp拨号功能测试

ME3630 除了支持使用 ECM 接口上网,也支持通过 ppp 拨号上网。使能 Linux 内核的 ppp 功能:

image.png

接着移植 pppd 软件,这个在buildroot中进行使能:

image.png

接着编译出新的内核镜像uImage和根文件系统,就可以启动开发板进行测试。


使用pppd -v就可以查看pppd的版本号:

image.png

在使用 pppd 进行拨号上网之前,需要先创建 4 个文件,在开发板根文件系统下创建 /etc/ppp/gosuncn 目录,然后新建一个名为“ppp-on”的 shell 脚本文件:


#!/bin/sh

clear

OPTION_FILE="gosuncn_options"

DIALER_SCRIPT=$(pwd)/gosuncn_ppp_dialer

exec pppd file $OPTION_FILE connect "chat -v -f ${DIALER_SCRIPT}"

 

再新建一个名为“gosuncn_options”的文件:


/dev/ttyUSB2

115200

crtscts

modem

persist

lock

noauth

noipdefault

debug

nodetach

user Anyname

password Anypassword

ipcp-accept-local

ipcp-accept-remote

defaultroute

usepeerdns

noccp

nobsdcomp

novj

dump

 

如果是联通或移动的卡就是用 ttyUSB2。

接着新建一个名为“gosuncn_ppp_dialer”的文件:


ABORT "NO CARRIER"

ABORT "ERROR"

TIMEOUT 120

"" ATE

SAY "ATE"

ECHO ON

OK ATH

OK ATP

OK AT+CGDCONT=1,\"IP\",\"3GNET\"

OK ATD*99#

CONNECT

 

倒数第2、3行是网络 APN 码,如果是联通卡,修改为以下内容:


OK AT+CGDCONT=1,\"IP\",\"3GNET\"

OK ATD*99#

 

电信卡:


OK AT+CGDCONT=1,\"IP\",\"CTNET\"

OK ATD*99#

 

移动卡:


OK AT+CGDCONT=1,\"IP\",\"CMNET\"

OK ATD*99#

 

最后,新建一个名为“disconnect”的 shell 脚本:


#!/bin/sh

killall pppd

 

编写完成以后要给予 ppp-on 和 disconnect 这两个文件可执行权限:


chmod 777 ppp-on disconnect

 

在使用以下命令连接4G网络:


/ppp-on &

 如果连接成功,就会自动申请IP地址,并在终端打印。

注:4G 网络测试需要关闭其他网卡,否则的话网络测试可能有问题。使用网络文件系统不好操作,可以将 uboot、Linux kernel、.dtb 设备树和根文件系统都烧写到板子的EMMC 里面,然后直接启动 EMMC 上的系统。


ECM 联网测试

如果不使用 ppp 拨号上网,可以直接输入ifconfig -a命令,找到一个名为“usb0”的网卡,这个就是ME3630的设备网卡。

在开发板根文件系统的/etc/ppp/gosuncn目录下创建一个名为“ecm_on”的 shell 脚本:


#!/bin/sh

clear

OPTION_FILE="gosuncn_options"

DIALER_SCRIPT=$(pwd)/gosuncn_ecm_dialer

exec pppd file $OPTION_FILE connect "chat -v -f ${DIALER_SCRIPT}"

 

最后再创建一个名为“gosuncn_ecm_dialer” 的文件:


ABORT "NO CARRIER"

ABORT "ERROR"

TIMEOUT 120

"" ATE

SAY "ATE"

ECHO ON

OK ATH

OK ATP

OK AT+ZSWITCH=L

OK AT+ZECMCALL=1

OK AT+CGDCONT=1,"IP","3GNET"

OK ATD*99#

CONNECT

 

倒数第2、3行依旧是网络 APN 码,不同运营商的设置与上文相同。

再给予 ecm-on 这个文件可执行权限:


chmod 777 ecm-on

 

并使用以下命令连接网络:


/ecm-on &

 

打开网卡并自动获取IP地址:


ifconfig usb0 up

udhcpc -i usb0 

 

 

ME3630 4G 模块 GNSS 定位测试

注意:ME3630-C3C 的 GNSS 要用无源天线,不能使用有源天线,否则无法定位。

  有些型号的 ME3630 带有 GNSS 功能,移植完后会出现 3 个 ttyUSB 设备,分别为 ttyUSB0~ttyUSB2,其中 ttyUSB1 为 GNSS 接口。GPS 模块通常都是使用串口进行通信,ME3630 也一样,只不过是 USB 转串口。所以可以直接使用 minicom 来查看 ttyUSB1 输出的 GNSS 信息,ME3630 的 GNSS 定位使用 ttyUSB1 接口,波特率为 115200,相关设置可以参考之前的串口通信的内容,这里不再赘述。

  这里主要了解一下使用 AT 指令配置 ME3630 的步骤,ME3630 默认关闭了 GNSS 定位输出功能的,所以必须先使用 AT 指令配置:


ATI //查看固件信息

Manufacturer: GOSUNCNWELINK

Model: ME3630-W

Revision: ME3630C3CV1.0B03

IMEI: 864863045876287

OK

AT+ZGINIT //初始化 GPS

OK

AT+ZGPSEVENT=1 //使能 GPS 事件上报

OK

AT+ZGMODE=3 //设置定位模式

OK

AT+ZGPORT=0 //定位信息从 AT、 MODEM、 UART 三个口同时上报

OK

AT+ZGNMEA=31 //设置 GPS 数据为 NMEA 格式

OK

AT+ZGPSR=1 //使能 ZGPSR 数据

OK

AT+ZGRUN=2 //连续定位模式

OK

 

其中每句指令的下半部分为模块的返回值。AT 指令配置完成以后 ME3630 就会开始搜星。注:GPS 天线一定要放到室外。等 ME3630搜星结束以后就会输出 NEMA 格式的定位信息。


2.移远EC20 4G驱动开发

移远的 EC20 4G 模块采用 LTE 3GPP Rel.11 技术,支持最大下行速率 150Mbps,最大上行速率 50Mbps。相关的版本分类及选用与ME3630相同。其相关特性如下:


① 一路 USB2.0 高速接口,最高可达 480Mbps。

② 一组模拟语音接口(可选)

③ 1.8V/3.0V SIM 接口

④ 1 个 UART 接口

⑤ W_DISABLE#(飞行模式控制)

⑥ LED_WWAN#(网络状态指示)


驱动修改

需要先在 Linux 内核中添加 EC20 的 USB 设备信息,在 drivers/usb/serial/option.c 文件的 option_ids 数组中添加移远的模块 ID:


{ USB_DEVICE(0x2C7C, 0x0125) }, /* EC20 */

1

然后在 drivers/usb/serial/option.c 文件中的 option_probe 函数添加以下内容:


/* EC20 */

if (serial->dev->descriptor.idVendor == 0x05c6 &&

serial->dev->descriptor.idProduct == 0x9003 &&

serial->interface->cur_altsetting->desc. bInterfaceNumber >= 4)

return -ENODEV;


if (serial->dev->descriptor.idVendor == 0x05c6 &&

serial->dev->descriptor.idProduct == 0x9215 &&

serial->interface->cur_altsetting->desc. bInterfaceNumber >= 4)

return -ENODEV;


if (serial->dev->descriptor.idVendor == 0x2c7c &&

serial->interface->cur_altsetting->desc. bInterfaceNumber >= 4)

return -ENODEV;

 

除此之外,还要在 drivers/usb/serial/option.c 文件里的 option_1port_device 结构体变量中,加入休眠后唤醒接口:

image.png

打开 drivers/usb/serial/usb_wwan.c 文件,在usb_wwan_setup_urb函数中添加零包处理代码:


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 *))

{

struct usb_serial *serial = port->serial;

struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);

struct urb *urb;


urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */

if (!urb)

return NULL;


usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, endpoint) | dir, buf, len, callback, ctx);


if (intfdata->use_zlp && dir == USB_DIR_OUT)

urb->transfer_flags |= URB_ZERO_PACKET;


/* EC20 */

if (dir == USB_DIR_OUT) {

struct usb_device_descriptor *desc = &serial->dev->descriptor;

if (desc->idVendor == cpu_to_le16(0x05c6) && desc->iProduct == cpu_to_le16(0x9090))

urb->transfer_flags |= URB_ZERO_PACKET;

if (desc->idVendor == cpu_to_le16(0x05c6) && desc->iProduct == cpu_to_le16(0x9003))

urb->transfer_flags |= URB_ZERO_PACKET;

if (desc->idVendor == cpu_to_le16(0x05c6) && desc->iProduct == cpu_to_le16(0x9215))

urb->transfer_flags |= URB_ZERO_PACKET;

if (desc->idVendor == cpu_to_le16(0x2c7c))

urb->transfer_flags |= URB_ZERO_PACKET;

}


return urb;

}

 

配置 Linux 内核

需要使能 USB NET、GSM、CDMA 驱动等,与上文的设置相同。

然后编译出内核镜像即可使用。开机后会出现 4 个tty接口 ttyUSB0~ttyUSB,其功能如下:


 image.png

EC20 ppp 拨号上网

同样需要创建 4 个文件,在开发板根文件系统下创建/etc/ppp/quectel目录,然后新建一个名为“ppp-on”的 shell 脚本文件:


#!/bin/sh

clear

OPTION_FILE="quectel_options"

DIALER_SCRIPT=$(pwd)/quectel_ppp_dialer

exec pppd file $OPTION_FILE connect "chat -v -f ${DIALER_SCRIPT}"

 

再新建一个名为“quectel_options”的文件:


/dev/ttyUSB2

115200

crtscts

modem

persist

lock

noauth

noipdefault

debug

nodetach

user Anyname

password Anypassword

ipcp-accept-local

ipcp-accept-remote

defaultroute

usepeerdns

noccp

nobsdcomp

novj

dump

 

其中ppp 拨号接口使用 ttyUSB2。

再新建一个名为“quectel_ppp_dialer”的文件:


ABORT "NO CARRIER"

ABORT "ERROR"

TIMEOUT 120

"" ATE

SAY "ATE"

ECHO ON

OK ATH

OK ATP

OK AT+CGDCONT=1,\"IP\",\"3GNET\"

OK ATD*99#

CONNECT

 

倒数第2、3行的运营商 APN 码参考上文设置。

最后新建一个名为“disconnect”的 shell 脚本:


#!/bin/sh

killall pppd

  

赋予文件可执行权限并启动网络连接:


chmod 777 ppp-on disconnect

/ppp-on &

 

移远 GobiNET 驱动移植

EC20 除了可以使用 ppp 拨号上网,也可以使用移远提供的 GobiNnet 驱动。将原子哥提供的相关文件拷贝到 Linux 内核的 /driver/net/usb 目录下:


然后打开 Linux 内核的 drivers/net/usb/Makefile 文件,在末尾添加以下内容:


obj-$(CONFIG_USB_GOBI_NET) += GobiNet.o

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

 

最后在 drivers/net/usb/Kconfig 文件中加入下所示内容,配置可视化界面:


config USB_GOBI_NET

tristate"Gobi USB Net driver for Quectel module"

help

Support Quectelmodule.

A modemmanager with support for GobiNet is recommended.

Tocompile this driver as a module, choose M here: the module will be calledGobiNet.1

 

然后在 Linux 内核的 menuconfig 中,使能添加的 Gobi 驱动:

image.png

然后编译出新的 uImage 启动开发板,启动后会出现一个 “/dev/qcqmi1” 设备文件。


quectel-CM 移植

GobiNET 移植成功以后如果要想上网,还需要用到移远提供的 quectel-CM 这个软件,这个软件是移远提供的网络管理工具。将原子哥提供的相关工具的源码拷贝到 Ubuntu 下并解压。

image.png

使用make CROSS_COMPILE=arm-none-linux-gnueabihf-命令进行交叉编译,得到一个名为“quectel-CM”软件。将编译出来的 quectel-CM 软件拷贝到开发板根文件系统的/usr/bin 目录下。


sudo cp quectel-CM ~/linux/nfs/rootfs/usr/bin/ -f

 

上网测试

quectel-CM -s 3gnet &

 

-s 指定 APN 类型,移动卡的 APN 为 cmnet,联通卡的 APN 为 3gnet,电信卡的 APN 为 cenet。 网卡会使用到 udhcpc 自动获取 IP 地址。


结束语:这里笔者没有相关的4G模块,所以仅粘贴原子哥教程的相关操作部分,具体的实验需要根据自己的设备进行验证。



————————————————

版权声明:本文为CSDN博主「Amonter」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_45682654/article/details/128550384