当前位置:   article > 正文

USB-4G/LTE移植 -第4节 USB-4G移植(移远EC20开发-GOBI拨号)_ec800m不支持gobinet拨号

ec800m不支持gobinet拨号

开发环境
主机:ubuntu12.04
开发板内核版本:linux-2.6.35
【注】EC20支持PPP拨号,Gobi拨号和QMI拨号,笔者使用的是Gobi拨号,关于另外两种拨号请参考官方文档,后文的附件链接中已经给出了参考文档。

3.1 USB SERIAL驱动

当模块连接到USB串行驱动时,驱动程序将在目录/dev中创建设备文件,
ttyUSB0/ttyUSB1/ttyUSB2…
接下来就是讲解如何移植USB Serial。

3.1.1增加PID&VID

要想识别模块,客户应该在下面添加模块维和PID信息
File: [KERNEL]/drivers/usb/serial/option.c

  1. static const struct usb_device_id option_ids[] = {
  2. #if 1 //Added by Quectel
  3. { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
  4. { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
  5. { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */
  6. { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
  7. { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */
  8. { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */
  9. { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
  10. { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
  11. { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
  12. { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */
  13. #endif

这里其实只需要{ USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */ 这一项,其他是无关紧要的,可以不放进去。option_ids[]就是一usb serial的设备pid,vid表。
【注】还有另外一种方式查看PID和VID,将EC20和微控器连接,就可以进入系统查看USB设备。

3.1.2添加零包处理

根据USB协议的要求,客户需要添加处理零数据包的机制。
For Linux Kernel Version newer than 2.6.34:
File: [KERNEL]/drivers/usb/serial/usb_wwan.c

  1. static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint,
  2. int dir, void *ctx, char *buf, int len,void (*callback) (struct urb *))
  3. {
  4. ……
  5. usb_fill_bulk_urb(urb, serial->dev,
  6. usb_sndbulkpipe(serial->dev, endpoint) | dir,
  7. buf, len, callback, ctx);
  8. #if 1 //Added by Quectel for zero packet
  9. if (dir == USB_DIR_OUT) {
  10. struct usb_device_descriptor *desc = &serial->dev->descriptor;
  11. if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
  12. urb->transfer_flags |= URB_ZERO_PACKET;
  13. if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
  14. urb->transfer_flags |= URB_ZERO_PACKET;
  15. if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
  16. urb->transfer_flags |= URB_ZERO_PACKET;
  17. if (desc->idVendor == cpu_to_le16(0x2C7C))
  18. urb->transfer_flags |= URB_ZERO_PACKET;
  19. }
  20. #endif
  21. return urb;
  22. }


For Linux kernel version lower than 2.6.35:
File: [KERNEL]/drivers/usb/serial/option.c

  1. /* Helper functions used by option_setup_urbs */
  2. static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
  3. int dir, void *ctx, char *buf, int len,
  4. void (*callback)(struct urb *))
  5. {
  6. ……
  7. usb_fill_bulk_urb(urb, serial->dev,
  8. usb_sndbulkpipe(serial->dev, endpoint) | dir,
  9. buf, len, callback, ctx);
  10. #if 1 //Added by Quectel for zero packet
  11. if (dir == USB_DIR_OUT) {
  12. struct usb_device_descriptor *desc = &serial->dev->descriptor;
  13. if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
  14. urb->transfer_flags |= URB_ZERO_PACKET;
  15. if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
  16. urb->transfer_flags |= URB_ZERO_PACKET;
  17. if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
  18. urb->transfer_flags |= URB_ZERO_PACKET;
  19. if (desc->idVendor == cpu_to_le16(0x2C7C))
  20. urb->transfer_flags |= URB_ZERO_PACKET;
  21. #endif
  22. return urb;
  23. }

3.1.3增加休眠后唤醒接口

当MCU进入暂停/休眠模式时,一些USB主机控制器/USB集线器将失去电源或重新设置,并且在MCU退出暂停/休眠模式后,它们不能恢复USB设备。请添加以下语句以启用重新设置恢复过程。
For Linux kernel version higher than 3.4:
File: [KERNEL]/drivers/usb/serial/option.c

  1. static struct usb_serial_driver option_1port_device = {
  2. ……
  3. #ifdef CONFIG_PM
  4. .suspend = usb_wwan_suspend,
  5. .resume = usb_wwan_resume,
  6. #if 1 //Added by Quectel
  7. .reset_resume = usb_wwan_resume,
  8. #endif
  9. #endif
  10. };

For Linux kernel version lower than 3.5:
File: [KERNEL]/drivers/usb/serial/usb-serial.c

  1. /* Driver structure we register with the USB core */
  2. static struct usb_driver usb_serial_driver = {
  3. .name = "usbserial",
  4. .probe = usb_serial_probe,
  5. .disconnect = usb_serial_disconnect,
  6. .suspend = usb_serial_suspend,
  7. .resume = usb_serial_resume,
  8. #if 1 //Added by Quectel
  9. .reset_resume = usb_serial_resume,
  10. #endif
  11. .no_dynamic_id = 1,
  12. .supports_autosuspend = 1,
  13. };

3.1.4 ENLARGE BULK OUT URBS

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

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

3.1.5使用 GOBINET OR QMI WWAN

如果客户使用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

  1. static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) {
  2. struct usb_wwan_intf_private *data;
  3. ……
  4. #if 1 //Added by Quectel
  5. //Quectel UC20's interface 4 can be used as USB network device
  6. if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
  7. serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)
  8. && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
  9. return -ENODEV;
  10. //Quectel EC20's interface 4 can be used as USB network device
  11. if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
  12. serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)
  13. && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
  14. return -ENODEV;
  15. //Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as USB network device
  16. if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)
  17. && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
  18. return -ENODEV;
  19. #endif
  20. /* Store device id so we can use it during attach. */
  21. usb_set_serial_data(serial, (void *)id);
  22. return 0;
  23. }


For Linux kernel version lower than 2.6.31:
File: [KERNEL]/drivers/usb/serial/option.c

  1. static int option_startup(struct usb_serial *serial)
  2. {
  3. ……
  4. dbg("%s", __func__);
  5. #if 1 //Added by Quectel
  6. //Quectel UC20's interface 4 can be used as USB network device
  7. if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
  8. serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)
  9. && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
  10. return -ENODEV;
  11. //Quectel EC20's interface 4 can be used as USB network device
  12. if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
  13. serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)
  14. && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
  15. return -ENODEV;
  16. //Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as
  17. USB network device
  18. if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)
  19. && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
  20. return -ENODEV;
  21. #endif
  22. ……

3.1.6修改内核配置

第一步:进入内核,并进入内核配置环境
$make menuconfig
第二步:添加USB 串口 GSM 和 CDMA 驱动选项。

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

3.1.7编译

以上操作完成后就是编译内核源码了。
$ make uImage -j4
将内核烧写进入板子中,会看到以下信息表示有USB设备了。

可以在dev目录下查看设备。

 

 

3.2 GOBINET移植

3.2.1修改内核配置

第一步:进入内核,并进入内核配置环境

$make menuconfig

第二步:启用USB网络支持

[*] Device Drivers →
    [*]Network device support →
            [*]usb Network Adapters →
 


【注】笔者是直接编译进内核的,也可编译后成模块动态加载。

 

3.2.2添加驱动代码

当使用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)。

  1. obj-y += GobiNet.o
  2. GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o

【注】源码在后文的附件中,请下载。

3.2.3编译

以上操作完成后就是编译内核源码了。
$ make uImage -j4

3.2.4测试

将编译后的Image在板子上跑起来可以看到启动信息有qcqmil。

另外在dev下多了一个qcqmil。

说明GobiNet驱动已经生效了。

 

3.3拨号上网

拨号程序仍然使用移远提供的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中查看,笔者的文件系统有,所以就不需要配置了。

【附件】
点击进入

GOBINET/QMI-WWAN/PPP拨号区别

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/211387
推荐阅读
  

闽ICP备14008679号