硬件描述:EC20模块封装成标准的PCIe接口,和系统之家通讯主要通过usb通讯。
系统描述:此处使用的是Linux 3.0.1。
首先需要对Linux内核驱动做一定的修改,使操作系统能够支持EC20。
File: [KERNEL]/drivers/usb/serial/option.c
- #if 1 //Added by Quectel
- { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
- { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
- { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */
- { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25/EC20 R2.0 */
- { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
- #endif
As required by the USB protocol, you need to add the mechanism for processing zero packets during bulkout transmission.
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 *))
- {
- struct urb *urb;
-
- if (endpoint == -1)
- return NULL; /* endpoint not needed */
-
- urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
- if (urb == NULL) {
- dbg("%s: alloc for endpoint %d failed.", __func__, endpoint);
- return NULL;
- }
-
- /* Fill URB using supplied data. */
- usb_fill_bulk_urb(urb, serial->dev,
- usb_sndbulkpipe(serial->dev, endpoint) | dir,
- buf, len, callback, ctx);
-
- #if 1 // 2017.3.7 add by zhaoxiaodong
- if (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;
- }
- #endif
-
- return urb;
- }
Some USB host controllers/USB hubs will lost power or be reset when MCU entering into suspend/sleep
mode, and they cannot resume USB devices when MCU exiting from suspend/sleep mode; instead, they
will operate reset-resume. You should add the following statements.
For Linux Kernel Version newer than 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
- };
For Linux Kernel Version older than 3.5:
File: [KERNEL]/drivers/usb/serial/ usb-serial.c
- 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 // 2017.3.7 add by zhaoxiaodong
- .reset_resume = usb_serial_resume,
- #endif
-
- .no_dynamic_id = 1,
- .supports_autosuspend = 1,
- };
Step 1:
- cd <your kernel directory>
Step 2:Set your environment variables, and import your board’s defconfig. The following is an example
for Raspeberrypi board
- export ARCH=arm
- export CROSS_COMPILE=arm-none-linux-gnueabimake bcmrpi_defconfig
Step 3:
- make menuconfig
Step 4:Enable CONFIG_USB_SERIAL_OPTION
- [*] Device Drivers →
- [*] USB Support →
- [*] USB Serial Converter support →
- [*] USB driver for GSM and CDMA modems
Step 5:Configure Kernel to Support PPP
- [*] Device Drivers →
- [*] Network device support →
- [*] PPP (point-to-point protocol) support
- make
将编译好的内核下载到开发板。
将重新编译好的内核下载到开发板之后,待系统重新启动,肉驱动添加正确,在/dev/目录下会出现如下设备节点:
- /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3
EC20的AT端口是/dev/ttyUSB2,现在你可以使用UART端口工具如“minicom”或“busybox microcom”测试AT功能,结果如下:
- #busybox microcom /dev/ttyUSB2
- ati;+csub
- Quectel
- EC20F
- Revision: EC20CEFDR02A09M4G
-
- SubEdition: V04
-
- OK
方案一
通过几个不同的配置文件,在拨号的时候选择相应的配置文件,现将配置文件列举如下:
/etc/ppp/peers/quectel-ppp
- # /etc/ppp/peers/quectel-pppd
- # Usage:root>pppd call quectel-pppd
- #Modem path, like /dev/ttyUSB3,/dev/ttyACM0, depend on your module, default path is /dev/ttyUSB3
- /dev/ttyUSB3 115200
- #Insert the username and password for authentication, default user and password are test
- user "test" password "test"
- # The chat script, customize your APN in this file
- connect 'chat -s -v -f /etc/ppp/peers/quectel-chat-connect'
- # The close script
- disconnect 'chat -s -v -f /etc/ppp/peers/quectel-chat-disconnect'
- # Hide password in debug messages
- hide-password
- # The phone is not required to authenticate
- noauth
- # Debug info from pppd
- debug
- # If you want to use the HSDPA link as your gateway
- defaultroute
- # pppd must not propose any IP address to the peer
- noipdefault
- # No ppp compression
- novj
- novjccomp
- noccp
- ipcp-accept-local
- ipcp-accept-remote
- local
- # For sanity, keep a lock on the serial line
- lock
- modem
- dump
- nodetach
- # Hardware flow control
- nocrtscts
- remotename 3gppp
- ipparam 3gppp
- ipcp-max-failure 30
- # Ask the peer for up to 2 DNS server addresses
- usepeerdns
/etc/ppp/peers/quectel-chat-connect
- # /etc/ppp/peers/quectel-chat-connect
- ABORT "BUSY"
- ABORT "NO CARRIER"
- ABORT "NO DIALTONE"
- ABORT "ERROR"
- ABORT "NO ANSWER"
- TIMEOUT 30
- "" AT
- OK ATE0
- OK ATI;+CSUB;+CSQ;+CPIN?;+COPS?;+CGREG?;&D2
- # Insert the APN provided by your network operator, default apn is 3gnet
- OK AT+CGDCONT=1,"IP","3gnet",,0,0
- OK ATD*99#
- CONNECT
/etc/ppp/peers/quectel-chat-disconnect
- # /etc/ppp/peers/quectel-chat-disconnect
- ABORT "ERROR"
- ABORT "NO DIALTONE"
- SAY "\nSending break to the modem\n"
- "" +++
- "" +++
- "" +++
- SAY "\nGoodbay\n"
编辑好这几个文件之后,便可以通过pppd进行拨号:
- # pppd call quectel-ppp &
如果拨号成功会有以下信息打印出来:
- [root@zx64352 peers]# pppd call quectel-ppp
- 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 30 # (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)
- AT^M^M
- OK
- -- got it
-
- send (ATE0^M)
- expect (OK)
- ^M
- ATE0^M^M
- OK
- -- got it
-
- send (ATI;+CSUB;+CSQ;+CPIN?;+COPS?;+CGREG?;&D2^M)
- expect (OK)
- ^M
- ^M
- Quectel^M
- EC20F^M
- Revision: EC20CEFDR02A09M4G^M
- ^M
- SubEdition: V04^M
- ^M
- +CSQ: 14,99^M
- ^M
- +CPIN: READY^M
- ^M
- +COPS: 0^M
- ^M
- +CGREG: 0,0^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 785), status = 0x0
- Serial connection established.
- using channel 1
- Using interface ppp0
- Connect: ppp0 <--> /dev/ttyUSB3
- sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x1f2b413> <pcomp> <accomp>]
- rcvd [LCP ConfReq id=0x0 <asyncmap 0x0> <auth chap MD5> <magic 0xd11eadc2> <pcomp> <accomp>]
- sent [LCP ConfAck id=0x0 <asyncmap 0x0> <auth chap MD5> <magic 0xd11eadc2> <pcomp> <accomp>]
- rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0x1f2b413> <pcomp> <accomp>]
- rcvd [LCP DiscReq id=0x1 magic=0xd11eadc2]
- rcvd [CHAP Challenge id=0x1 <40aedf97298706e7675d614c0cea9175>, name = "UMTS_CHAP_SRVR"]
- sent [CHAP Response id=0x1 <1bf312e7aa43615e474c49c28fbbaca5>, 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=0x0]
- sent [IPCP ConfNak id=0x0 <addr 0.0.0.0>]
- rcvd [IPCP ConfNak id=0x1 <addr 10.35.149.45> <ms-dns1 218.4.4.4> <ms-dns2 218.2.2.2>]
- sent [IPCP ConfReq id=0x2 <addr 10.35.149.45> <ms-dns1 218.4.4.4> <ms-dns2 218.2.2.2>]
- rcvd [IPCP ConfReq id=0x1]
- sent [IPCP ConfAck id=0x1]
- rcvd [IPCP ConfAck id=0x2 <addr 10.35.149.45> <ms-dns1 218.4.4.4> <ms-dns2 218.2.2.2>]
- Could not determine remote IP address: defaulting to 10.64.64.64
- local IP address 10.35.149.45
- remote IP address 10.64.64.64
- primary DNS address 218.4.4.4
- secondary DNS address 218.2.2.2
此时也会在/etc/ppp/目录下生成resolv.conf文件,存放pppd拨号获取到的DNS,可以将改文件拷贝到/etc/目录下,这样便可以进行DNS解析了,至此开发板也可以通过EC20模块连接到互联网了。
方案二
方案一中的端口号、APN、用户名、密码等都是直接写在配置文件中,这样如果要更换这些内容的话要频繁修改配置文件,既消耗时间,又不太方便。所以便将几个配置文件融合到一个脚本中,并且可以通过传递参数那样修改需要修改的内容,脚本内容如下:
/etc/ppp/peers/quectel-pppd.sh
- #!/bin/sh
-
- #quectel-pppd devname apn user password
- echo "quectel-pppd options in effect:"
- QL_DEVNAME=/dev/ttyUSB3
- QL_APN=3gnet
- QL_USER=user
- QL_PASSWORD=passwd
- if [ $# -ge 1 ]; then
- QL_DEVNAME=$1
- echo "devname $QL_DEVNAME # (from command line)"
- else
- echo "devname $QL_DEVNAME # (default)"
- fi
- if [ $# -ge 2 ]; then
- QL_APN=$2
- echo "apn $QL_APN # (from command line)"
- else
- echo "apn $QL_APN # (default)"
- fi
- if [ $# -ge 3 ]; then
- QL_USER=$3
- echo "user $QL_USER # (from command line)"
- else
- echo "user $QL_USER # (default)"
- fi
- if [ $# -ge 4 ]; then
- QL_PASSWORD=$4
- echo "password $QL_PASSWORD # (from command line)"
- else
- echo "password $QL_PASSWORD # (default)"
- fi
-
- CONNECT="'chat -s -v ABORT BUSY ABORT \"NO CARRIER\" ABORT \"NO DIALTONE\" ABORT ERROR ABORT \"NO ANSWER\" TIMEOUT 30 \
- \"\" AT OK ATE0 OK ATI\;+CSUB\;+CSQ\;+CPIN?\;+COPS?\;+CGREG?\;\&D2 \
- OK AT+CGDCONT=1,\\\"IP\\\",\\\"$QL_APN\\\",,0,0 OK ATD*99# CONNECT'"
-
- pppd $QL_DEVNAME 115200 user "$QL_USER" password "$QL_PASSWORD" \
- connect "'$CONNECT'" \
- disconnect 'chat -s -v ABORT ERROR ABORT "NO DIALTONE" SAY "\nSending break to the modem\n" "" +++ "" +++ "" +++ SAY "\nGood bay\n"' \
- noauth debug defaultroute noipdefault novj novjccomp noccp ipcp-accept-local ipcp-accept-remote ipcp-max-configure 30 local lock modem dump nodetach nocrtscts usepeerdns
-
拨号
- /etc/ppp/peers/quectel-pppd.sh &
输出信息跟方案一输出一样,同样会生成/etc/ppp/resolv.conf文件。
注:在进行拨号之前一定要确保没有默认网关,如果已经设置了其他网卡的默认网关了,则4G模块没法正常上网,需要删除原来的默认网关,现以网卡eth0为例:
- route del default
- route del -host 255.255.255.255 dev eth0