赞
踩
开发环境
主机:ubuntu12.04
开发板内核版本:linux-2.6.35
【注】EC20支持PPP拨号,Gobi拨号和QMI拨号,笔者使用的是Gobi拨号,关于另外两种拨号请参考官方文档,后文的附件链接中已经给出了参考文档。
当模块连接到USB串行驱动时,驱动程序将在目录/dev中创建设备文件,
ttyUSB0/ttyUSB1/ttyUSB2…
接下来就是讲解如何移植USB Serial。
要想识别模块,客户应该在下面添加模块维和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
这里其实只需要{ USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */ 这一项,其他是无关紧要的,可以不放进去。option_ids[]就是一usb serial的设备pid,vid表。
【注】还有另外一种方式查看PID和VID,将EC20和微控器连接,就可以进入系统查看USB设备。
根据USB协议的要求,客户需要添加处理零数据包的机制。
For Linux Kernel Version newer than 2.6.34:
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 packet
- 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;
- }
For Linux kernel version lower than 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 packet
- 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;
- }
当MCU进入暂停/休眠模式时,一些USB主机控制器/USB集线器将失去电源或重新设置,并且在MCU退出暂停/休眠模式后,它们不能恢复USB设备。请添加以下语句以启用重新设置恢复过程。
For Linux kernel version higher 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 lower than 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,
- };
For Linux kernel version lower than 2.6.29, bulk out URBs need to be enlarged to get faster uplink speed.
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
如果客户使用ucxx/ec2x/egxx/EP06/EM06/BG96/AG35,并要求GobiNet或QMI WWAN,请添加以下语句,以防止这些模块接口4被用作USB串行设备。
For Linux Kernel Version newer than 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;
- }
For Linux kernel version lower than 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
- ……
第一步:进入内核,并进入内核配置环境
$make menuconfig
第二步:添加USB 串口 GSM 和 CDMA 驱动选项。
[*] Device Drivers → [*] USB Support → [*] USB Serial Converter support → [*] USB driver for GSM and CDMA modems
以上操作完成后就是编译内核源码了。
$ make uImage -j4
将内核烧写进入板子中,会看到以下信息表示有USB设备了。
可以在dev目录下查看设备。
第一步:进入内核,并进入内核配置环境
$make menuconfig
第二步:启用USB网络支持
[*] Device Drivers → [*]Network device support → [*]usb Network Adapters →
【注】笔者是直接编译进内核的,也可编译后成模块动态加载。
当使用Gobinet驱动移远模块时,Gobinet将会创建一个网络设备(ethX)和一个QMI channel(qcqmiX),将驱动源码放到[KERNEL]/drivers/net/usb/ (or [KERNEL]/drivers/usb/net/ if the kernel version is lower than2.6.22).。如果是把Gobinet编译到内核中,可以忽略。GoniNet源码中的Makefile,直接将源码中的.c和.h文件拷贝到上述目录中。网络设备用于网络传输 QMI channel要用于QMI 的信息交互。然后添加以下声明到file [KERNEL]/drivers/net/usb/Makefile (or [KERNEL]/drivers/usb/net/Makefile if the kernel version is lower than 2.6.22)。
- obj-y += GobiNet.o
- GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o
【注】源码在后文的附件中,请下载。
以上操作完成后就是编译内核源码了。
$ make uImage -j4
将编译后的Image在板子上跑起来可以看到启动信息有qcqmil。
另外在dev下多了一个qcqmil。
说明GobiNet驱动已经生效了。
拨号程序仍然使用移远提供的quectel-CM,这是一个4g连接管理程序,这里没什么说的,直接下载源码交叉编译后得到可执行bin“quectel-CM”,把这个bin放到板卡上启动后上述USB和Gobi没有问题的情况下直接执行该bin就可以。
【注】移动式[cmnet],电信是[ctnet]。
$ ./quectel-CM -s cmnet &
【注意】笔者使用的移动卡。
拨号成功会分配IP,接下来就是ping一下看是否可以联网。
$ping www.baidu.com
【注意】这里需要UDHCPC ,检测你的busybox是否有这个东西,如果不存在,你需要重新移植busybox,启用CONFIG_UDHCPC选项。还需要配置一个配置文件,注意检查。
可以在开发板中输入busybox中查看,笔者的文件系统有,所以就不需要配置了。
【附件】
点击进入
1.Gobinet拨号
GOBI 高通Gobi无线宽带芯片技术,只需一个模块即可支持多种移动宽带网络和众多移动运营商。高通公司称全新的芯片将基于Gobi 4G LTE无线基带、MDM9615和MDM9215。这种技术可以在FDD和TDD网络下进行LTE连接,同时支持HSPA+和EV-DO网络、2G/3G网络。这意味着用户可以在本地使用高速4G LTE网络,在其他地方使用3G网络。Gobi平台在MDM芯片组的基础上还提供了软件增强层,这样可以使用不同技术下的无线连接更简单。
2.QMI-WWAN协议拨号
QMI: Qualcom Message Interface
MSM: Mobile station mode
AP: Application Procesor
高通平台目前都是非对称多核心,最主要的是AP和Modem。
两个处理器怎么进行通信呢,我们把AP和Modem当作两个主机,问题就变得了很简单,TCP/IP协议不是一种非常成功的进程间跨主机通信方式。高通没有采用这种方式,但是借鉴了TCP/IP的框架设计。
Qualcomm MSM Interface,作用用于AP和BP侧的交互,通俗说法就是让设备终端TE(可以是手机,PDA,计算机)
对高通BP侧的AMSS系统进行操作,如调用函数,读取数据,设置其中的NV项等。
参考:http://blog.csdn.net/u012439416/article/category/7004974
3.ppp协议拨号:点对点协议
PPP(点到点协议)在拨号过程中用于MS和PC间数据交互、协商。在拨号流程的初期首先开启的就是PC和MS直接的PPP过程,在拨号成功后,还需要依靠PPP协议对IP包进行封装传输数据。
官网源码:https://ppp.samba.org
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。