Linux 4G 通信实验

前面我们学习了如何在Linux 中使用有线网络或者WIFI,但是使用有线网络或者WIFI 有
很多限制,因为要布线,即使是WIFI 你也得先布线,然后再接个路由器。有很多场合是不方便布线的,而我们的产品可以直接通过4G 连接到网络,本章我们就来学一下如何在I.MX6U-ALPHA 开发板中使用4G 来实现联网功能。

4G 网络连接简介

提起4G 网络连接,大家可能会觉得是个很难的东西,其实对于嵌入式Linux 而言,4G 网
络连接恰恰相反,不难!大家可以看一下其他的嵌入式Linux 或者Android 开发板,4G 模块都是MiniPCIE 接口的,包括很多4G 模块都是MiniPCIE 接口的。但是大家稍微深入研究一下就会发现,这些4G 模块虽然用了MiniPCIE 接口,但是实际上的通信接口都是USB,所以4G 模块的驱动就转换为了USB 驱动

这些4G模块厂商都提供了详细的文档讲解如何在Linux下使用4G模块,以及如何修改Linux内核加入4G模块驱动。正点原子的I.MX6U-ALPHA 开发板也有一个MiniPCIE 形式的4G 模块接口,虽然外形是MiniPCIE 的,但是内心却是USB 的。

I.MX6U-ALPHA 开发板的4G 模块原理图如图71.4.1 所示:

在这里插入图片描述

图71.4.1 中的U8就是MiniPCIE接口,MiniPCIE 接口连接到了GL850 这个HUB芯片的
DP2 和DM2,也就是GL850 的USB2 接口上。

U11 是Nano SIM 接口,I.MX6U-ALPHA 开发板使用Nano SIM 卡,这样大家就可以直接拿自己的手机卡进行测试。I.MX6U-ALPHA 开发板的4G 接口位置如图71.1.2 所示:

在这里插入图片描述

在使用之前需要将4G 模块插入到图71.1.2 所示的MiniPCIE 接口上,然后上紧两边的螺
丝,Nano SIM 卡插入到图71.1.2 中的Nano SIM 座里面,注意Nano SIM 卡的方向,
Nano SIM 卡的金属触点朝下!

理论上所有的MiniPCIE 接口的4G 模块都可以连接到正点原子的I.MX6U-ALPHA 开发板
上,因为这些4G 模块都遵循同样的接口标准,但是大家在使用的时候还是要详细的看一下4G模块的接口引脚描述。不同的4G 模块其驱动形式也不同,本章我们讲解两款4G 模块在I.MX6U-ALPHA 开发板上的使用,一个是上海移远公司的EC20,另外一个是高新兴物联的ME3630。

这两款4G 模块都有MiniPCIE 接口的,这两个4G 模块如图71.4.2 所示:

在这里插入图片描述

4G 模块工作是需要天线的,因此在选购4G 模块的时候一定要记得购买天线,否则无法进
行测试。一般MiniPCIE 接口的4G 模块留出来的天线接口为IPEX 座,因此购买天线的时候也要选择IPEX 接口的,或者使用IPEX 转SMA 线来转接。推荐大家到正电原子官方店铺购买4G模块和相应的天线。

高新兴ME3630 4G 模块实验

ME3630 4G 模块简介

ME3630 是一款LTE Cat.4 七模全网通4G 模块,在LTE 模式下可以提供50Mbps 上行速率
以及150Mbps 的下行速率,并支持回退到 3G 或 2G 网络。此模组支持分集接收、分集接收是终端产品支持双天线以提高通信质量和通信可靠性的无线连接技术。ME3630 支持多种网络协议,比如PAP、CHAP、PPP 等,拥有多种功能,比如GNSS、Remote wakeup、SMS、支持FoTA空中升级等。ME3630 4G 模块广泛应用于智能抄表、安防信息采集、工业路由器、车载通信以及监控等等M2M 领域。ME3630 4G 模组特性如下:

  • ①、一路USB2.0 接口。
  • ②、一路UART 接口。
  • ③、SIM卡接口支持1.8/3.0V。
  • ④、内置TCP、UDP、FTP 和HTTP 等协议。
  • ⑤、支持RAS/ECM/NDIS。
  • ⑥、支持AT 指令。

ME3630 4G 模块有多种配置,比如纯数据版本、集成GNSS 版本、全网通版本等等,本节
教程我们主要使用到ME3630 的数据通信功能,因此推荐大家购买全网通数据版,如果想要定位功能的话就购买全网通数据+GNSS(定位)版本,至于其他的版本大家根据自己的实际需求选择即可。在正式使用ME3630 4G 模块之前,请先将其插入到开发板的MiniPCIE 座上、上紧螺、插入Nano SIM 卡、接上天线,如图71.2.1.1 所示:

在这里插入图片描述

一切准备就绪以后就可以开始驱动ME3630 4G 模块了。

ME3630 4G 模块驱动修改

教程均来源模组厂商官网提供的操作手册

1、Linux内核添加代码(USB设备信息)

我们需要先在Linux 内核中添加ME3630 的USB 设备信息,因为我们前面说了,ME3630 4G 模块用的USB 接口。打开Linux源码的drivers/usb/serial/option.c 文件,找到option_ids 数组,然后在里面添加ME3630 的PID 和VID,要添加的内容如下:

示例代码71.2.2.1 ME3630 PID 和VID 信息
1 {
    
     USB_DEVICE(0x19d2, 0x0117) }, /* ME3630*/
2 {
    
     USB_DEVICE(0x19d2, 0x0199) },
3 {
    
     USB_DEVICE(0x19d2, 0x1476) },

完成以后的option_ids 数组如图71.2.2.1 所示:

在这里插入图片描述

2、Linux内核添加代码(添加ECM支持程序)

ME3630 支持ECM 接口,可以通过ECM 接口轻松联网,如果要使用ECM 接口的话需要
修改drivers/usb/serial/option.c 文件里面的option_probe 函数。找到此函数,然后在里面输入如下内容:

示例代码71.2.2.2 option_probe 函数需要添加的内容
1 /* EM3630 */
2 if (serial->dev->descriptor.idVendor == 0x19d2 &&
3 serial->dev->descriptor.idProduct == 0x1476 &&
4 serial->interface->cur_altsetting->desc. bInterfaceNumber == 3)
5 return -ENODEV;
6
7 if (serial->dev->descriptor.idVendor == 0x19d2 &&
8 serial->dev->descriptor.idProduct == 0x1476 &&
9 serial->interface->cur_altsetting->desc. bInterfaceNumber == 4)
10 return -ENODEV;
11
12 if (serial->dev->descriptor.idVendor == 0x19d2 &&
13 serial->dev->descriptor.idProduct == 0x1509 &&
14 serial->interface->cur_altsetting->desc. bInterfaceNumber == 4)
15 return -ENODEV;
16
17 if (serial->dev->descriptor.idVendor == 0x19d2 &&
18 serial->dev->descriptor.idProduct == 0x1509 &&
19 serial->interface->cur_altsetting->desc. bInterfaceNumber == 5)
20 return -ENODEV;

添加完成以后的option_probe 函数如图71.2.2.2 所示:

在这里插入图片描述

3、配置使能Linux内核

我们需要配置Linux 内核,首先使能USBNET 功能,路径如下:

-> Device Drivers
	-> -*- Network device support
		-> USB Network Adapters
			-> -*- Multi-purpose USB Networking Framework

配置如图71.2.2.3 所示:

在这里插入图片描述

接下来我们还需要使能USB 串口GSM、CDMA 驱动,配置路径如下:

-> Device Drivers
	-> [*] USB support
		-> <*> USB Serial Converter support
			-> <*> USB driver for GSM and CDMA modems

配置如图71.2.2.4 所示

在这里插入图片描述

继续配置Linux 内核,使能USB 的CDC ACM 模式,配置路径如下:

-> Device Drivers
	-> [*] USB support
		-> <*> Support for Host-side USB
			-> <*> USB Modem (CDC ACM) support

配置如图71.2.2.5 所示:

在这里插入图片描述

4、编译Linux内核,使用新的zImage启动

关于Linux 内核的配置就到此为止,重新编译一下Linux 内核,然后使用新的zImage 启动开发板。如果ME3630 已经插上的话,系统启动以后就会输出如图71.2.2.6 所示的信息:

在这里插入图片描述

从图71.2.2.6 可以看出,ME3630 虚拟出了3 个USB 设备,分别为ttyUSB0~ttyUSB2。对
于支持ECM 接口的4G 模块来讲,比如ZM5330/ZM8620/ME3620/ME3630。如果模块工作在ECM 模式下,可以通过运行“ifconfig -a ”命令查看对应的网卡,网卡的名字可能为
usbX/ecmX/ethX 等,X 是具体的数字,如果存在的话就说明ECM 接口驱动加载成功。输入
“ifconfig -a”命令,会发现多了一个名为“usb0”的网卡,图71.2.2.7 所示:

在这里插入图片描述

ME3630 4G模块ppp拨号上网

1、使能Linux内核ppp功能,重新编译内核

ME3630 支持通过ppp 拨号上网,也是支持使用ECM 接口上网,我们先来学习一下如何通
过ppp 拨号上网。首先我们需要配置Linux 内核,打开Linux 内核的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

配置完成以后如图71.2.3.1 所示:

在这里插入图片描述

配置完成以后重新编译一下Linux 内核,得到新的zImage 镜像文件,然后使用新的zImage
镜像文件启动开发板。

2、移植pppd 软件

我们需要通过pppd 这个软件来实现ppp 拨号上网,这个软件需要我们移植。
在移植之前先删除掉/usr/sbin/chat 这个软件!
我们使用Busybox 制作根文件系统的时候会生成/usr/sbin/chat 这个软件,我们一会移植pppd的时候也会编译出chat 软件。因此需要将根文件系统中原来的/usr/sbin/chat 软件删除掉,否则的话我们移植的chat 软件工作将会出问题!

pppd 源码已经放到了开发板光盘中,路径为:1、例程源码->7、第三方库源码-> ppp-2.4.7.tar.gz,将ppp-2.4.7.tar.gz 拷贝到Ubuntu 下并解压,解压以后会生成一个名为ppp-2.4.7 的文件夹。进入到ppp-2.4.7 目录中,然后编译pppd 源码,命令如下:

cd ppp-2.4.7/
./configure 					//配置
make CC=arm-linux-gnueabihf-gcc //编译

如果编译失败,提示bison 和flex 这两个“not found”的话就安装这两个库,命令如下:

sudo apt-get install bison
sudo apt-get install flex

编译完成以后就会在当前目录下生成chat/chat 、pppd/pppd 、pppdump/pppdump 和
pppstats/pppstats 这四个文件,将这个四个文件拷贝到开发板根文件系统中的/usr/bin 目录下,命令如下:

sudo cp chat/chat /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
sudo cp pppd/pppd /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
sudo cp pppdump/pppdump /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
sudo cp pppstats/pppstats /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f

完成以后输入“pppd -v”查看一下pppd 的版本号,如果pppd 版本号显示正常的话就说明
pppd 移植成功,如图71.2.3.2 所示:

在这里插入图片描述

3、ppp 上网测试(配置路由表)

在使用pppd 进行拨号上网之前需要先创建4 个文件,这4 个文件必须放到同一个目录下。

在开发板根文件系统下创建/etc/gosuncn 目录,进入到刚刚创建的/etc/gosuncn 目录下,然后新建一个名为“ppp-on”的shell 脚本文件,在ppp-on 文件里面输入如下所示内容:

示例代码71.2.3.1 ppp-on 文件内容
1 #!/bin/sh
2 clear
3 OPTION_FILE="gosuncn_options"
4 DIALER_SCRIPT=$(pwd)/gosuncn_ppp_dialer
5 exec pppd file $OPTION_FILE connect "chat -v -f ${DIALER_SCRIPT}"

再新建一个名为“gosuncn_options”的文件,在文件里面输入如下所示内容:

示例代码71.2.3.2 gosuncn_options 文件内容
1 /dev/ttyUSB2
2 115200
3 crtscts
4 modem
5 persist
6 lock
7 noauth
8 noipdefault
9 debug
10 nodetach
11 user Anyname
12 password Anypassword
13 ipcp-accept-local
14 ipcp-accept-remote
15 defaultroute
16 usepeerdns
17 noccp
18 nobsdcomp
19 novj
20 dump

第1 行,如果是联通或移动的卡就是用ttyUSB2,如果是电信的卡就是用ttyUSB0。
第11~12 行,这两行内容和所使用的卡有关,如果是联通或者移动的卡就按照上面的写,
如果是电信的卡,要改为如下所示内容:

user card
password card

再新建一个名为“gosuncn_ppp_dialer”的文件,输入如下所示内容:

示例代码71.2.3.3 gosuncn_ppp_dialer 文件内容
1 ABORT "NO CARRIER"
2 ABORT "ERROR"
3 TIMEOUT 120
4 "" ATE
5 SAY "ATE"
6 ECHO ON
7 OK ATH
8 OK ATP
9 OK AT+CGDCONT=1,\"IP\",\"3GNET\"
10 OK ATD*99#
11 CONNECT

第9 行,后面的3GNET是网络的APN 码,这个要根据自己所使用的手机卡来确定,
通卡的APN
为3GNET,移动卡的APN为CMNET。因为我使用的是联通卡进行测试的,所有这里设置APN 为3GNET,如果使用的移动卡,那么要将APN 设置为CMNET。
如果是电信的卡,那么第9 行要改为:

OK "AT+ZCAPN=card,card"

第10 行,如果是联通或移动的卡,那么第10 行就不变。如果是电信的卡,那么第10 行
要改为:

OK ATD#777

最后新建一个名为“disconnect”的shell 脚本,输入如下所示内容:

示例代码71.2.3.4 disconnect 文件内容
1 #!/bin/sh
2 killall pppd

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

chmod 777 ppp-on disconnect

完成以后输入如下命令连接4G 网络:

./ppp-on &

在ME3630 连接4G 网络的过程中,可能会出现如图71.2.3.3 所示的错误提示:

在这里插入图片描述

从图71.2.3.3 可以看出,提示不能创建“Can’t create lock file /var/lock/LCK…ttyUSB2”,检查根文件系统是否存在/var/run 和/var/lock 这两个目录,如果没有的话就手动创建这两个文件夹,命令如下:

mkdir /var/run //创建/var/run 文件夹
mkdir /var/lock //创建/var/lock 文件夹

完成以后重新输入“./pppd-on &”命令连接4G 网络,连接成功以后会输入如图71.2.3.4
所示信息:

在这里插入图片描述

从图71.2.3.4 可以看出,在ME3630 4G 模块联网过程中,需要用到/etc/ppp/resolv.conf 文
件,但是我们当前根文件系统没有此文件,所以需要手动创建此文件。创建完成以后重启开发板!开发板重启以后进入到/etc/gosuncn 目录,然后输入如下命令完成拨号上网:

./ppp-on &

ppp 拨号成功以后就会生成一个名为“ppp0”的网卡,如图71.2.3.5 所示:

在这里插入图片描述

4G 网络测试需要关闭其他网卡,否则的话网络测试可能有问题,如下图所示:

在这里插入图片描述

这是因为默认走的有线网络,可以通过配置默认优先路由表解决:解决Linux下同时使用有线和无线/4G网络时,网络连接的优先级问题

教程的解决方法:现在是通过网络启动的系统,并且通过NFS 挂载的根文件系统,因此我们没法关闭其他的网卡,比如eth0。为了解决这个问题,我们只能将uboot、Linux kernel、.dtb 设备树和根文件系统都烧写到板子的EMMC 或NAND 上,然后直接启动EMMC 或NAND 上的系统即可,这样就不需要其他网卡工作了。烧写方法请参考我们的《第二十九章系统烧写》,这里就不详细的讲解了。系统烧写完成以后设置开发板从EMMC 或NAND 启动,因为我使用的是EMMC 核心板,因此设置从EMMC 启动,启动以后按照前面的步骤先让ME3630 4G 模块连接上网络。确保当前开发板只有一个ME3630 对应的ppp0 网卡,最后直接ping 百度官网即可,结果如图71.2.3.6 所示:

在这里插入图片描述

ME3630 4G 模块ECM 联网测试

对于支持ECM 接口的模块可以直接通过ECM 上网,比PPP方式简单,ME3630 模块支持ECM 接口,重启开发板,输入“ifconfig -a”命令可以看到有一个名为“usb0”的网卡,如图71.2.4.1 所示:

在这里插入图片描述

这个usb0 网卡就是ECM 接口对应的网卡,我们需要使用minicom 输入一些AT 指令,所
以要先用minicom 打开ttyUSB1,ttyUSB1 就是ME3630 的AT 指令串口,波特率设置为
115200。打开以后依次输入如下指令:
①、输入AT 指令:

AT+ZSWITCH=L

然后重启开发板。如果模块已经设置为ECM 模式的话此步骤就不需要了。
②、使用AT 指令+CGDCONT 来设置数据参数。联通卡的APN 为3gnet,电信卡的APN
为ctnet,移动卡的APN 为cmnet。比如我现在用的联通卡,所以设置APN 为3gnet,命令如
下:

AT+CGDCONT=1,”IP”,”CMNET”

③、发送连接AT 命令:

AT+ZECMCALL=1

等待连接成功,连接成功以后会输出如图71.2.4.2 所示信息:

在这里插入图片描述

连接成功以后打开usb0网卡,命令如下:

ifconfig usb0 up //打开usb0 网卡

usb0 网卡打开以后输入如下命令申请IP地址

udhcpc -i usb0

IP 地址获取过程如图71.2.4.3 所示:

在这里插入图片描述

从图71.2.4.3 可以看出,usb0 网卡获取到的IP 地址为10.164.232.36,然后ping 一下百度官网,如果能ping 通就说明ME3630 的ECM 接口联网成功。

  • 4G上网模块上网时获得的IP地址是公网IP吗?
  • 不是的,每次都是电信公司动态分配的内网IP,不是固定的IP,所以也就不是公网的IP,公网IP是要付钱的;
  • 在使用上,二者没有任何区别,只是私网IP不能直接用于服务器的IP而对外提供服务。

如果提示“bad address ‘www.baidu.com’”,那么请检查一下DNS服务器地址设置是否正确,打开/etc/resolv.conf 文件,然后加入“nameserver 114.114.114.114”即可。
将DNS服务器改成114.114.114并没有直接的危险,但是需要注意以下几点:1. 114.114.114并不是唯一可用的DNS服务器,如果您的网络需要使用特定的DNS服务器,建议不要随意更改。2. 114.114.114是由中国电信提供的DNS服务器,如果您在国外,使用该DNS服务器可能会影响您的网络访问速度和稳定性。3. 如果您在使用114.114.114时遇到了网络问题,可能需要尝试使用其他DNS服务器或联系您的网络服务提供商。最后,题外扩展一下,DNS服务器是将域名解析为IP地址的关键组件,它可以帮助您更快地访问网站并提高网络安全性。

至此ME3630 4G模块的网络连接就已经全部测试完成,大家既可以在正点原子的I.MX6U-ALPHA 开发板上使用4G上网了。

ME3630 4G 模块GNSS定位测试(使用minicom工具)

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

有些型号的ME3630 带有GNSS功能,也就是GPS定位,比如正点原子售卖的ME3630-C3C 就是全网通4G+GNSS+分集。在71.2.2 小节移植ME3630 驱动的时候我们知道最终会出现3 个ttyUSB 设备,分别为ttyUSB0~ttyUSB2,其中ttyUSB1 为GNSS 接口。如果以前用过其他的GPS 模块的话应该知道,GPS 模块是串口输出的,ME3630 也一样的,只不过ME3630 是USB 转串口,ttyUSB1 就是ME3630 转出来的GNSS 串口。所以我们可以直接使用minicom 来查看ttyUSB1 输出的GNSS 信息。ME3630 的GNSS 定位使用ttyUSB1 接口,波特率为115200,因此本小节中的minicom 配置如图71.2.5.1 所示:

在这里插入图片描述

有时候使用minicom 打开串口的时候可能会提示如图71.2.5.2 的错误:

在这里插入图片描述

出现这个问题的原因就是上次没有正确关闭minicom,导致在/var/lock 目录下存在
LCK…XXX 文件(XXX 就是具体的串口设备文件名,比如ttyUSB1),如图71.2.5.3 所示:

在这里插入图片描述

图71.2.5.3 中的LCK…ttyUSB1 文件就是导致ttyUSB1 打开失败的原因,将其删除掉即可!
minicom 打开ttyUSB1 以后按照如下步骤配置ME3630

1、使用AT 指令配置ME3630
ME3630-C3C 默认是关闭了GNSS 定位输出功能的,必须先使用AT 指令配置,ME3630 的
详细AT 指令请参考《高新兴物联ME3630&ME3630-W 模组AT 指令手册_V3.1.pdf》的“11.GPS相关指令”小节。此文档已经放到了开发板光盘中,路径为:开发板光盘->1、例程源码->5、模块驱动源码->3、4G 模块->高新兴物联->ME3630。
AT 指令配置过程如下,其中深色是AT 指令,“OK”为ME3630 返回值:

ME3630-C3C AT 指令配置GPS
ATI //查看固件信息
Manufacturer: GOSUNCNWELINK
Model: ME3630-W
Revision: ME3630C3CV1.0B03
IMEI: 864863045876287
OK
AT+ZGINIT //初始化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 格式的定位信息,如图71.2.5.4 所示:

在这里插入图片描述

在实际的应用开发中大家直接解析NEMA 格式数据,然后得到具体的经纬度、速度、高度、
UTC 时间等信息。

移远EC20 4G 模块实验

EC20 4G 模块简介

关于EC20 4G 模块的详细资料请找卖家索要!
EC20 有多种不同的配置,比如全网通纯数据版本、语音版、带GNSS 版等等,建议大家购
买的时候至少要选择全网通数据版,因为我们使用4G 模块主要还是用于数据通信的。移远的
EC20 4G 模块采用LTE 3GPP Rel.11 技术,支持最大下行速率150Mbps,最大上行速率50Mbps。
EC20 4G 模块特性如下:

  • ①、一路USB2.0 高速接口,最高可达480Mbps。
  • ②、一组模拟语音接口(可选)。
  • ③、1.8V/3.0V SIM 接口。
  • ④、1 个UART 接口。
  • ⑤、W_DISABLE#(飞行模式控制)。
  • ⑥、LED_WWAN#(网络状态指示)。

EC20 也支持AT 指令,本教程不讲AT 指令,关于AT 指令的使用请参考EC20 的相关文
档。在正式使用EC20 4G 模块之前,请先将其插入到开发板的MiniPCIE 座上、上紧螺、插入
Nano SIM 卡、接上天线,如图71.3.1.1 所示:

在这里插入图片描述

一切准备就绪以后就可以开始驱动EC20 4G 模块了。

EC20 4G 模块驱动修改

1、内核添加代码(USB设备信息)

我们需要先在Linux 内核中添加EC20 的USB 设备信息,因为我们前面说了,EC20 4G 模
块用的USB 接口。打开Linux 源码的drivers/usb/serial/option.c 文件,首先定义EC20 的ID 宏,
内容如下:

示例代码71.3.2.1 EC20 4G 模块ID
1 /* EC20 4G */
2 #define QUECTEL_VENDOR_ID 0X2C7C
3 #define QUECTEL_PRODUCT_EC20 0X0125

完成以后如图71.3.2.1 所示:

在这里插入图片描述

继续在drivers/usb/serial/option.c 文件里面找到option_ids 数组,在此数组里面加入如下内
容:

示例代码71.3.2.2 option_ids 数组添加EC20 ID 信息
{
    
     USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC20) }, /* EC20 4G */

完成以后option_ids 数组如图71.2.2.2 所示:

在这里插入图片描述

继续在drivers/usb/serial/option.c 文件里面找到option_probe 函数,在此函数里面添加如下
内容:

示例代码71.3.2.3 option_probe 函数添加的代码
1 /* EC20 */
2 if (dev_desc->idVendor == cpu_to_le16(0x05c6) &&
3 dev_desc->idProduct == cpu_to_le16(0x9003) &&
4 iface_desc->bInterfaceNumber >= 4)
5 return -ENODEV;
6
7 if (dev_desc->idVendor == cpu_to_le16(0x05c6) &&
8 dev_desc->idProduct == cpu_to_le16(0x9215) &&
9 iface_desc->bInterfaceNumber >= 4)
10 return -ENODEV;
11
12 if (dev_desc->idVendor == cpu_to_le16(0x2c7c) &&
13 iface_desc->bInterfaceNumber >= 4)
14 return -ENODEV;

添加完成以后的option_probe 函数如图71.3.2.3 所示:

在这里插入图片描述

继续在drivers/usb/serial/option.c 文件里面找到option_1port_device 结构体变量,在里面加
入休眠后唤醒接口,如图71.3.2.4 所示:

在这里插入图片描述

打开drivers/usb/serial/usb_wwan.c 文件,在usb_wwan_setup_urb 函数中添加零包处理代码,完成后的usb_wwan_setup_urb 函数如下所示:

示例代码71.3.2.4 修改后的usb_wwan_setup_urb 函数
1 static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
2 int endpoint,
3 int dir, void *ctx, char *buf, int len,
4 void (*callback) (struct urb *))
5 {
    
    
6 struct usb_serial *serial = port->serial;
7 struct urb *urb;
8
9 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
10 if (!urb)
11 return NULL;
12
13 usb_fill_bulk_urb(urb, serial->dev,
14 usb_sndbulkpipe(serial->dev, endpoint) | dir,
15 buf, len, callback, ctx);
16
17 /* EC20 */
18 if (dir == USB_DIR_OUT) {
    
    
19 struct usb_device_descriptor *desc =
&serial->dev->descriptor;
20 if (desc->idVendor == cpu_to_le16(0x05c6) &&
21 desc->iProduct == cpu_to_le16(0x9090))
22 urb->transfer_flags |= URB_ZERO_PACKET;
23
24 if (desc->idVendor == cpu_to_le16(0x05c6) &&
25 desc->iProduct == cpu_to_le16(0x9003))
26 urb->transfer_flags |= URB_ZERO_PACKET;
27
28 if (desc->idVendor == cpu_to_le16(0x05c6) &&
29 desc->iProduct == cpu_to_le16(0x9215))
30 urb->transfer_flags |= URB_ZERO_PACKET;
31
32 if (desc->idVendor == cpu_to_le16(0x2c7c))
33 urb->transfer_flags |= URB_ZERO_PACKET;
34 }
35
36 return urb;
37 }

第18~34 行就是要添加到usb_wwan_setup_urb 函数里面的零包处理代码。至此,Linux 内
核需要修改的地方就完了。编译一下Linux 内核,检查一下代码修改有没有问题,如果修改正确的话就是没有任何问题的。

2、配置编译Linux 内核

我们需要配置Linux 内核,使能USB NET、GSM、CDMA 驱动等,配置方法和我们在71.2.2
小节讲解的ME3630 4G 模块的配置方法一样,大家参考71.2.2 小节即可。配置完成以后编译一下Linux 内核,然后使用新的zImage 启动开发板。如果EC20 已经插上的话,系统启动以后就会输出如图71.3.2.5 所示的信息:

在这里插入图片描述

从图71.3.2.5 可以看出,多了ttyUSB0~ttyUSB3,这4 个tty 接口就是EC20 虚拟出来的,
可以查看一下/dev/ttyUSB0~ttyUSB3 是否存在,结果如图71.3.2.6 所示:

在这里插入图片描述

图71.3.2.6 中的这4 路ttyUSB 的含义见表71.3.2.1:

在这里插入图片描述

我们用到最多的就是ttyUSB1 和ttyUSB2,如果你购买的EC20 模块带有GPS 功能,那么
就可以通过ttyUSB1 接口读取GPS 数据。如果你想使用EC20 的AT 指令功能,那么就使用
ttyUSB2 接口即可。

3、添加移远官方的GobiNet 驱动

移远为EC20 提供了GobiNet 驱动,驱动源码我们已经放到了开发板光盘中,路径为:1、
例程源码->5 、模块驱动源码->3 、4G 模块-> 移远EC20\EC20_R2.1_Mini_PCIe-C->05 Driver->Linux->GobiNet-> Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.0.zip 。
将Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.0/src 下的所有.c 和.h 文件都拷贝到Linux 内核中的/driver/net/usb 目录下,也就是图71.3.2.7 中所示的文件:

在这里插入图片描述

拷贝完成以后打开Linux 内核的drivers/net/usb/Makefile 文件,在此文件末尾加入如下内容:

示例代码71.3.2.5 修改后的drivers/net/usb/Makefile 文件
1 obj-$(CONFIG_USB_GOBI_NET) += GobiNet.o
2 GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o

最后在drivers/net/usb/Kconfig 文件中加入下所示内容:

示例代码71.3.2.6 drivers/net/usb/Kconfig 要添加的内容
1 config USB_GOBI_NET
2 tristate"Gobi USB Net driver for Quectel module"
3 help
4 Support Quectelmodule.
5
6 A modemmanager with support for GobiNet is recommended.
7 Tocompile this driver as a module, choose M here: the module will be calledGobiNet.1

上述内容在drivers/net/usb/Kconfig 文件中的位置如图71.3.2.8 所示:

在这里插入图片描述

完成以后打开Linux 内核配置界面,使能前面添加的Gobi 驱动,配置路径如下:

-> Device Drivers
	-> [*] Network device support
		-> -*- USB Network Adapters
			-> <*> Gobi USB Net driver for Quectel module

配置如图71.3.2.9 所示:

在这里插入图片描述

配置完成以后就重新编译一下Linux 内核,然后使用新的zImage 启动开发板。启动以后检
查一下“/dev/qcqmi2”这个文件是否存在,如果存在的话就说明Gobi 驱动工作成功。至此,
EC20 的驱动就已经修改完成了,接下来就是使用EC20 来实现联网。

quectel-CM 移植

要使用EC20,我们需要用到移远提供的quectel-CM 这个软件,这个软件是移远提供的网
络管理工具,软件源码已经放到了开发板光盘中,路径为:1、例程源码->5、模块驱动源码->3、4G 模块-> 移远EC20->EC20_R2.1_Mini_PCIe-C->05 Driver->Linux->GobiNet->WCDMA&LTE_QConnectManager_Linux&Android_V1.1.34.zip 。将
WCDMA&LTE_QConnectManager_Linux&Android_V1.1.34.zip 这个压缩包进行解压,得到
quectel-CM 这个文件夹,然后将quectel-CM 文件夹拷贝到Ubuntu 中。拷贝完成以后进入到
Ubuntu 中的quectel-CM 文件夹,使用如下命令进行交叉编译:

make CROSS_COMPILE=arm-linux-gnueabihf-

编译完成以后得到一个名为“quectel-CM”软件,如图71.3.3.1 所示:

在这里插入图片描述

将图71.3.3.1 中编译出来的quectel-CM 软件拷贝到开发板根文件系统的/usr/bin 目录下,命
令如下:

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

拷贝完成以后就可以使用quectel-CM 软件来实现EC20 联网测试了。

EC20上网测试

在开发板上输入如下命令完成EC20 的4G 网络连接:

quectel-CM -s cenet &

注意,quectel-CM 软件会使用到udhcpc 来获取IP 地址,所以一定要确保当前根文件系统下存在udhcpc。当4G 网络连接成功以后就会获取到IP 地址,如图71.3.4.1 所示:

在这里插入图片描述

从图71.3.4.1 可以看出,EC20 对应的网卡名字为“eth2”,输入“ifconfig eth2”即可查看
eth2 网卡的详细信息,如图71.3.4.2 所示:

在这里插入图片描述

4G 网络测试需要关闭其他网卡,否则的话网络测试可能有问题,但是我们现在是通过网络
启动的系统,并且通过NFS 挂载的根文件系统,因此我们没法关闭其他的网卡,比如eth0。为了解决这个问题,我们只能将uboot、Linux kernel、.dtb 设备树和根文件系统都烧写到板子的EMMC 或NAND 上,然后直接启动EMMC 或NAND 上的系统即可,这样就不需要其他网卡工作了。烧写方法请参考我们的《第二十九章系统烧写》,这里就不详细的讲解了。系统烧写完成以后设置开发板从EMMC 或NAND 启动,因为我使用的是EMMC 核心板,因此设置从EMMC 启动,启动以后按照前面的步骤先让EC20 连接上网络。确保当前开发板只有一个EC20对应的eth2 网卡,然后直接直接ping 百度官网即可,结果如图71.3.4.3 所示:

在这里插入图片描述

如果ping 百度官网没有问题,那么就表示EC20 4G 模块在我们的I.MX6U-ALPHA 开发板
上工作正常。

猜你喜欢

转载自blog.csdn.net/zhuguanlin121/article/details/129867773