一、USB Serial Driver 安装

当设备连接4G模块后,查看 /dev 下是否有以下设备文件:

ttyUSB0/ttyUSB1/ttyUSB2…

如果没有,则需要按照下列步骤集成USB串行驱动程序(以下操作均需要在内核根目录下进行,因此在操作前要安装对应版本的内核源码):

1.1 添加 VID 和 PID

为了识别模块,客户应该添加模块VID和PID信息,如下所示:

File: [KERNEL]/drivers/usb/serial/option.c

static const struct usb_device_id option_ids[] = {
#if 1 //Added by Quectel{ USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */ { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */ { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */{ USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */ { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */
{ USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */
{ USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
{ USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
{ USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
{ USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */
#endif

对于EC20模块,如果内核源文件中存在以下文件和语句,请删除它们,因为它们会与EC20的USB驱动程序冲突。

File: [KERNEL]/drivers/usb/serial/qcserial.c

{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

File: [KERNEL]/drivers/net/usb/qmi_wwan.c

{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

1.2 添加零分组机制

根据USB协议的要求,客户需要在大量传输过程中添加用于处理零数据包的机制。
对于高于2.6.34的Linux内核版本:

File: [KERNEL]/drivers/usb/serial/usb_wwan.c

static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, int dir, void *ctx, char *buf, int len,void (*callback) (struct urb *)) { ……usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, endpoint) | dir, buf, len, callback, ctx); #if 1 //Added by Quectel for zero packetif (dir == USB_DIR_OUT) { struct usb_device_descriptor *desc = &serial->dev->descriptor; if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090)) urb->transfer_flags |= URB_ZERO_PACKET; if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003)) urb->transfer_flags |= URB_ZERO_PACKET; if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215)) urb->transfer_flags |= URB_ZERO_PACKET; if (desc->idVendor == cpu_to_le16(0x2C7C)) urb->transfer_flags |= URB_ZERO_PACKET; } #endifreturn urb; }

对于Linux内核版本低于2.6.35:

File: [KERNEL]/drivers/usb/serial/option.c

/* Helper functions used by option_setup_urbs */ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,int dir, void *ctx, char *buf, int len, void (*callback)(struct urb *)) { ……usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, endpoint) | dir, buf, len, callback, ctx); #if 1 //Added by Quectel for zero packetif (dir == USB_DIR_OUT) { struct usb_device_descriptor *desc = &serial->dev->descriptor; if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090)) urb->transfer_flags |= URB_ZERO_PACKET; if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003)) urb->transfer_flags |= URB_ZERO_PACKET; if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215)) urb->transfer_flags |= URB_ZERO_PACKET; if (desc->idVendor == cpu_to_le16(0x2C7C)) urb->transfer_flags |= URB_ZERO_PACKET; #endifreturn urb; }

1.3 添加重置恢复

一些USB主机控制器/USB集线器将在MCU进入暂停/睡眠模式时损失或重置,并且在MCU从暂停/睡眠模式下退出后,它们无法恢复USB设备。请添加以下语句以启用重置恢复过程。

对于Linux内核版本高于3.4:

File: [KERNEL]/drivers/usb/serial/option.c

static struct usb_serial_driver option_1port_device = { ……#ifdef CONFIG_PM .suspend = usb_wwan_suspend, .resume = usb_wwan_resume, #if 1 //Added by Quectel.reset_resume = usb_wwan_resume, #endif #endif
};

对于Linux内核版本低于3.5:

File: [KERNEL]/drivers/usb/serial/ usb-serial.c

/* Driver structure we register with the USB core */ static struct usb_driver usb_serial_driver = { .name = "usbserial", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .suspend = usb_serial_suspend, .resume = usb_serial_resume, #if 1 //Added by Quectel.reset_resume = usb_serial_resume, #endif.no_dynamic_id = 1, .supports_autosuspend = 1, };

1.4 放大散装网址

对于低于2.6.29的Linux内核版本,大量URB需要放大以获得更快的上行链路速度。

File: [KERNEL]/drivers/usb/serial/option.c

#define N_IN_URB 4
#define N_OUT_URB 4 //Quectel 1
#define IN_BUFLEN 4096
#define OUT_BUFLEN 4096 //Quectel 128

1.5 使用 GobiNet 或 QMI WWAN

如果要求使用Gobinet或QMI WWAN,请添加以下语句以防止这些模块的接口4作为USB串行设备。

对于Linux内核版本高于2.6.30:

File: [KERNEL]/drivers/usb/serial/option.c

static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; ……#if 1 //Added by Quectel//Quectel UC20's interface 4 can be used as USB network device if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&serial->dev->descriptor.idProduct == cpu_to_le16(0x9003) && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) return -ENODEV; //Quectel EC20's interface 4 can be used as USB network device if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215) && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) return -ENODEV; //Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as USB network device if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C) && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) return -ENODEV; #endif/* Store device id so we can use it during attach. */ usb_set_serial_data(serial, (void *)id); return 0; }

对于Linux内核版本低于2.6.31:

File: [KERNEL]/drivers/usb/serial/option.c

static int option_startup(struct usb_serial *serial) { ……dbg("%s", __func__); #if 1 //Added by Quectel//Quectel UC20's interface 4 can be used as USB network device if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003) && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) return -ENODEV; //Quectel EC20's interface 4 can be used as USB network device if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215) && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) return -ENODEV; //Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as USB network device if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C) && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) return -ENODEV; #endif ……}

1.6 修改内核配置

内核配置中有几个强制性选定项目,请按照以下步骤配置内核:

步骤1:进入到内核根目录。

cd < your kernel directory >

步骤2:设置环境变量和导入板的defconfig。以下是RaspeBerry Pi板的示例。

export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabi-
make bcmrpi_defconfig

对于X86架构的系统,我的默认的defconfig文件为x86_64_defconfig,只需要在内核根目录下 make x86_64_defconfig

步骤3:编译内核。

make menuconfig

步骤4:启用CONFIG_USB_SERIAL_OPTION

[*] Device Drivers →[*] USB Support →  [*] USB Serial Converter support →[*] USB driver for GSM and CDMA modems

1.7 作为内核模块构建并加载驱动程序

请按照以下步骤将驱动程序作为内核模块构建。

步骤1:进入到内核根目录。

cd < your kernel directory >

步骤2:构建驱动程序。

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=option.o modules
sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=usb_wwan.o modules
sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=qcserial.o modules

步骤3:加载驱动程序并重新启动。

sudo cp drivers/usb/serial/option.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
sudo cp drivers/usb/serial/usb_wwan.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
sudo cp drivers/usb/serial/qcserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
sudo depmod
sudo reboot

二、配置内核以支持PPP

首先检测 /dev 下面是否有 ppp 设备,没有的话请按照以下步骤配置内核以支持PPP。

步骤1:进入到内核根目录。

cd < your kernel directory >

步骤2:设置环境变量和导入板的defconfig。下面显示了一个例子。

export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabi-
make bcmrpi_defconfig

对于X86架构的系统,我的默认的defconfig文件为x86_64_defconfig,只需要在内核根目录下 make x86_64_defconfig

步骤3:编译内核。

make menuconfig

步骤4:启用CONFIG_PPP_ASYNC CONFIG_PPP_SYNC_TTY CONFIG_PPP_DEFLATE

[*] Device Drivers → [*] Network device support → [*] PPP (point-to-point protocol) support

内核启动后在 /dev 下生成 ppp 设备节点

三、测试PPP拨号上网

下载ppp服务:https://ppp.samba.org/download.html

解压:tar -xzvf ppp-2.4.4.tar.gz
cd ppp-2.4.4
./configure
make && make install

实现ppp拨号上网:

查看是否有名为/etc/ppp/ip-up的ppp脚本文件,用于设置DNS(域名系统)。如果没有这样的文件,请使用 Quectel 提供的linux-ppp-scripts\ip-up
关于 linux-ppp-scripts_V1.2.zip 请自行到网上下载。

解压:unzip linux-ppp-scripts_V1.2.zip

linux-ppp-scripts 里面的 quectel-pppquectel-chat-connectquectel-chat-disconnect 三个脚本复制到 /etc/ppp/peers 目录下
根据不同的模块,客户可能需要进行一些更改。有关更多信息,请参阅 linux-ppp-scripts\readme

然后通过以下命令开始设置PPP呼叫:

pppd call quectel-ppp &

拨号过程如下所示(EC20的示例):

# pppd options in effect:
debug # (from /etc/ppp/peers/quectel-ppp)
nodetach # (from /etc/ppp/peers/quectel-ppp)
dump # (from /etc/ppp/peers/quectel-ppp)
noauth # (from /etc/ppp/peers/quectel-ppp)
user test # (from /etc/ppp/peers/quectel-ppp)
password ?????? # (from /etc/ppp/peers/quectel-ppp)
remotename 3gppp # (from /etc/ppp/peers/quectel-ppp)
/dev/ttyUSB3 # (from /etc/ppp/peers/quectel-ppp)
115200 # (from /etc/ppp/peers/quectel-ppp)
lock # (from /etc/ppp/peers/quectel-ppp)
connect chat -s -v -f /etc/ppp/peers/quectel-chat-connect # (from
/etc/ppp/peers/quectel-ppp)
disconnect chat -s -v -f /etc/ppp/peers/quectel-chat-disconnect # (from
/etc/ppp/peers/quectel-ppp)
nocrtscts # (from /etc/ppp/peers/quectel-ppp)
modem # (from /etc/ppp/peers/quectel-ppp)
hide-password # (from /etc/ppp/peers/quectel-ppp)
novj # (from /etc/ppp/peers/quectel-ppp)
novjccomp # (from /etc/ppp/peers/quectel-ppp)
ipcp-accept-local # (from /etc/ppp/peers/quectel-ppp)
ipcp-accept-remote # (from /etc/ppp/peers/quectel-ppp)
ipparam 3gppp # (from /etc/ppp/peers/quectel-ppp)
noipdefault # (from /etc/ppp/peers/quectel-ppp)
ipcp-max-failure 10 # (from /etc/ppp/peers/quectel-ppp)
defaultroute # (from /etc/ppp/peers/quectel-ppp)
usepeerdns # (from /etc/ppp/peers/quectel-ppp)
noccp # (from /etc/ppp/peers/quectel-ppp)
abort on (BUSY)
abort on (NO CARRIER)
abort on (NO DIALTONE)
abort on (ERROR)
abort on (NO ANSWER)
timeout set to 30 seconds
send (AT^M)
expect (OK)
^M
OK
-- got it
send (ATE0^M)
expect (OK)
^M
^M
OK
-- got it
send (ATI;+CSUB;+CSQ;+CPIN?;+COPS?;+CGREG?;&D2^M)
expect (OK)
^M
^M
Quectel^M
EC20^M
Revision: EC20CQAR02A03E2G_BETA0914^M
^M
SubEdition: V01^M
^M
+CSQ: 23,99^M
^M
+CPIN: READY^M
^M
+COPS: 0,0,"CHN-CT",7^M
^M
+CGREG: 2,1,"FFFE","6916934",7^M
^M
OK
-- got it
send (AT+CGDCONT=1,"IP","3gnet",,0,0^M)
expect (OK)
^M
^M
OK
-- got it
send (ATD*99#^M)
expect (CONNECT)
^M
^M
CONNECT
-- got it
Script chat -s -v -f /etc/ppp/peers/quectel-chat-connect finished (pid 3017), status = 0x0
Serial connection established.
using channel 3
Using interface ppp0
Connect: ppp0 <--> /dev/ttyUSB3
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xf2b7d6ee> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x4 <asyncmap 0x0> <auth chap MD5> <magic 0x45c0e381> <pcomp>
<accomp>]
sent [LCP ConfAck id=0x4 <asyncmap 0x0> <auth chap MD5> <magic 0x45c0e381> <pcomp>
<accomp>]
rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0xf2b7d6ee> <pcomp> <accomp>]
rcvd [LCP DiscReq id=0x5 magic=0x45c0e381]
rcvd [CHAP Challenge id=0x1 <f8d54e0fa294c100101805a512176ff1>, name =
"UMTS_CHAP_SRVR"]
sent [CHAP Response id=0x1 <e8ad86182138523599fb54a172da7154>, name = "test"]
rcvd [CHAP Success id=0x1 ""]
CHAP authentication succeeded
CHAP authentication succeeded
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [IPCP ConfReq id=0x4]
sent [IPCP ConfNak id=0x4 <addr 0.0.0.0>]
rcvd [IPCP ConfNak id=0x1 <addr 100.65.245.137> <ms-dns1 61.132.163.68> <ms-dns2
202.102.213.68>]
sent [IPCP ConfReq id=0x2 <addr 100.65.245.137> <ms-dns1 61.132.163.68> <ms-dns2
202.102.213.68>]
rcvd [IPCP ConfReq id=0x5]
sent [IPCP ConfAck id=0x5]
rcvd [IPCP ConfAck id=0x2 <addr 100.65.245.137> <ms-dns1 61.132.163.68> <ms-dns2
202.102.213.68>]
Could not determine remote IP address: defaulting to 10.64.64.64
local IP address 100.65.245.137
remote IP address 10.64.64.64
primary DNS address 61.132.163.68
secondary DNS address 202.102.213.68
Script /etc/ppp/ip-up started (pid 3020)
Script /etc/ppp/ip-up finished (pid 3020), status = 0x0

现在PPP呼叫设置成功。通过以下方式查看:

ifconfig ppp0
ppp0  Link encap:Point-to-Point Protocol inet addr:100.65.245.137 P-t-P:10.64.64.64 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:15 errors:0 dropped:0 overruns:0 frame:0 TX packets:19 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:1057 (1.0 KiB) TX bytes:1228 (1.1 KiB)
cat /etc/resolv.conf
nameserver 61.132.163.68
nameserver 202.102.213.68
route -n
Kernel IP routing table
Destination     Gateway     Genmask         Flags    Metric     Ref     Use     Iface
10.64.64.64     0.0.0.0     255.255.255.255 UH       0          0       0       ppp0
0.0.0.0         0.0.0.0     0.0.0.0         U        0          0       0       ppp0
ping www.baidu.com
PING www.a.shifen.com (115.239.211.112) 56(84) bytes of data.
64 bytes from 115.239.211.112: icmp_seq=1 ttl=54 time=46.4 ms

关闭PPP呼叫:

pkill -f pppd

参考文献:

《Quectel_WCDMA&LTE_Linux_USB_Driver_User_Guide_V1.8.pdf》

适配4G模块 EC20 使用ppp拨号上网相关推荐

  1. 在ARM-linux上实现4G模块simcom7100c 的PPP拨号上网

    转http://blog.sina.com.cn/s/blog_7880d3350102wb92.html 在ARM平台上实现4G模块的PPP拨号上网,参考网上的资料和自己的理解,从一无所知到开发完成 ...

  2. 第三节 树莓派EC20之PPP拨号上网

    EC20 ppp拨号上网步骤 1. 准备工作 2.安装软件 3.上网测试 树莓派内核现在已集成了EC20的驱动,不需要再去进行驱动移植,虽然没有MiniPcie的接口,但用usb转minipcie也是 ...

  3. linux系统华为4G模块移植及pppd拨号上网开发总结

    一.开发环境简介 开发系统: Ubuntu 14.04 内核版本:linux 3.10 4G模块:ME909-821和ME909-120 模块接口:pcle SIM卡:联通 二.内核驱动配置 需向li ...

  4. 实现4G模块EC20在树莓派系统下的PPP拨号上网

    目录 PPP协议 PPP通信建立 PPP认证方式 ppp协议栈 pppd数据传输 Pppd 控制协议数据流程 Linux中的PPP实现 安装PPP 方法一:源码安装 方法二: 直接安装 PPP拨号上网 ...

  5. 移植移远4G模块EC20过程记录2-QMI+PPP拨号上网

    目录 1.背景 2.移植QMI_WWAN驱动 2.1 准备源码 2.2 修改源码 2.3 make 2.4 安装 2.5 编译cdc_wdm 2.6 再次安装 2.7 验证QMI驱动 3.ppp拨号 ...

  6. linux怎么使用4g模块的网络,在ARM-linux上实现4G模块PPP拨号上网(示例代码)

    在ARM平台上实现4G模块的PPP拨号上网,参考网上的资料和自己的理解,从一无所知到开发完成花了一周多.最后看到ARM板ping通www.baidu.com时甚是高兴,现将此过程整理如下.当然,除此之 ...

  7. linux 串口4g ppp,在ARM-linux上实现4G模块PPP拨号上网

    原标题:在ARM-linux上实现4G模块PPP拨号上网 在ARM平台上实现 的 ,参考网上的资料和自己的理解,从一无所知到开发完成花了一周多.最后看到ARM板ping通www.baidu.com时甚 ...

  8. 树莓派搭载EC200U 4G模块(USB网卡上网和PPP拨号上网)

    文章目录 一.EC200U模块4G模块介绍 二.USB转串口驱动设置 (1)打开树莓派的串口 (2)lsusb是否有EC200U模块 (3)添加 VID 和 PID 信息 三.USB网卡驱动上网 四. ...

  9. 树莓派中SIM7600G-H 4G DONGLE模块使用记录(一)PPP拨号上网/4G上网

    项目场景: 如何使用SIM7600系列的4G通信模块进行PPP网上拨号以实现4G通信,在讲解前,未搭建好树莓派远程连接桌面的读者可以先转向树莓派4B环境搭建+电脑远程连接+打开文件管理闪退(上). 模 ...

  10. 怎么在Linux内核模块加打印,在ARM-linux上实现4G模块PPP拨号上网

    在ARM平台上实现4G模块的PPP拨号上网,参考网上的资料和自己的理解,从一无所知到开发完成花了一周多.最后看到ARM板ping通www.baidu.com时甚是高兴,现将此过程整理如下.当然,除此之 ...

最新文章

  1. php cache缓存 购物车,Yii2使用Redis缓存购物车等数据
  2. golang并发和并行
  3. 1核1g服务器开多少虚拟主机,1核1g服务器开多少虚拟主机
  4. 「实战篇」开源项目docker化运维部署-后端java部署(七)
  5. java如何读取下拉列表的值_java - 如何在Selenium 2中选择/获取下拉选项
  6. oracle 数字处理函数,Oracle函数-单行函数-数字、日期、日期处理函数
  7. 实践 + 理论 | API 接口安全性设计
  8. animation-fill-mode的一些思考
  9. DataGridView拖动换行
  10. paip.python错误解决6
  11. 在IDEA中编辑struts国际化properties文件
  12. C/C++连连看C++游戏项目教程
  13. PRIMARY KEY与identity(1,1)的比较
  14. 如何做好性能压测(一) | 压测环境的设计和搭建
  15. 中文数字与阿拉伯数字转换(Python)
  16. 三维模型obj文件解析
  17. 移动电源给路由器供电
  18. Tensorflow中实现leakyRelu操作(高效)
  19. Android Killer的安装和配置 -安卓逆向的必备神器
  20. 7T, 9T and Track

热门文章

  1. 数据分析EXCEL常用统计函数
  2. c语言 标准正态分布表,标准正态分布表
  3. python 姓名转拼音
  4. 中文汉化AE插件-图层边界自动填充生长动画插件
  5. Java生成随机数的方法
  6. vs2013连接access2016
  7. Linux虚拟机网络配置
  8. 如何设置win7计算机不更新,win7系统不要自动更新的设置步骤(图文)
  9. 检测计算机无线网卡驱动,win10怎么修复无线网卡驱动 无线网卡驱动修复方法
  10. 微警务:网上公安服务一键开启