EC20 linux驱动 Gobinet 拨号

 最近新入手一块板子,里面Gobinet 和 usbserial 这些都是模块编insmod插入进去的,虽然提供了源码但是还是看不明白什么意思,于是对这块就有了兴趣,因为公司有和移远有合作,就要来了他们的Linux源码(本身也是开源的)研究了一下,发现其实很简单,主要参考医院官方的文件《Quectel_WCDMA&LTE_Linux_USB_Driver_User_Guide_V1.7.pdf》下面我就结合这个文档给大家再捋一遍。

=======================================================================


一 、USB Serial

 如果你用的是ec20**********并且需要USB串口的启动,请细度此章否则直接跳过。。。。


1.1 添加VID和PID

VID和PID其实就相当于USB硬件的识别ID系统也是通过他们来找到你的EC20设备的,修改Kernel中文件来添加,方法如下


注意:如果其他的usb设备也用到了这些资源的话就把冲突的地方删掉,比如在[KERNEL]/drivers/usb/serial/qcserial.c中和[KERNEL]/drivers/net/usb/qmi_wwan.c文件中都有对(0x05c6, 0x9215)ID的重复描述,官方文档是让删掉的,我没有删试了没事,想来应该是我的板卡上没有这些设备的原因。

1.2添加 Zero Packet Mechanism

通过USB协议的要求,你需要在bulkout传输添加加工零包的机制(直接翻译过来的照着做就可以了)。

如果你的Linuxkernel版本新于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;
 }

如果linux版本在2.6.35以下的和上述操作不一样,现在应该很少有人用了就不说了。


1.3添加Reset Resume回调

 这一块是和Linux的设备电源管理相关的,当单片机进入休眠/休眠时,一些USB主机控制器/ USB集线器将失去电源或复位。
模式,当MCU退出挂起/休眠模式时,它们不能恢复USB设备;相反,它们将操作重置恢复。您应该添加以下语句

Linux kernel 版本高于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 kernel 版本低于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.4Use GobiNet or QMI WWAN

如果用着两个驱动还需要修改File: [KERNEL]/drivers/usb/serial/option.c文件(kernel高于2.6.30):这里值得注意一下
文档中base的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&EC20 R2.0&EG91&EG95&EG06&EP06&EM06&BG96'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;
 }


我文件中的:
static int option_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
.......
#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&EC20 R2.0&EG91&EG95&EG06&EP06&EM06&BG96's interface 4 can beused as USB Network device
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)
&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
 #endif


data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->send_setup = option_send_setup;
spin_lock_init(&data->susp_lock);
data->private = (void *)id->driver_info;


return 0;
}

不知道大家用的内核是那一版,看到和描述的不一样仔细看一下就行了 上面添加的都是匹配的逻辑,下面是set的功能,一看便知
不需要看懂。我试过是可以的。

1.5 menuconfig

menuconfig如下图 设置好了保存


1.6试验

 启动时有:

 编译之后,把kernel跑起来就会发现如图:

 dev目录下已经有了ttyUSB*设备了,证明已经完成了 USB Serial的驱动。



二 、GobiNet 驱动

 当使用Gobinet驱动移远模块时,Gobinet将会创建一个网络设备(ethX)和一个QMI channel(qcqmiX),

 网络设备用于网络传输 QMI channel要用于QMI 的信息交互。


2.1将移远模块提供的源码放入到Kernel中

 linux2.6以后的版本将Gobinet驱动的源码放到/[kernel]/drivers/usb/net/中。如果是把gobinet编译到内核中,可以忽略

GoniNet源码中的Makefile,直接将源码中的.c和.h文件拷贝到上述目录中。


2.2 make menuconfig



2.3添加Makefile文件中的目标和依赖

 在【KERNEL】/drivers/net/usb/Makefile文件中添加:

obj-y += GobiNet.o

GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o


2.4试验

 将编译后的Image在板子上跑起来可以看到dev下多了一个qcqmil:


说明GobiNet驱动已经生效了。


三、拨号程序

拨号程序仍然使用移远提供的quectel-CM,这是一个4g连接管理程序,这里没什么说的,直接下载源码交叉编译之

得到可执行bin“quectel-CM”,把这个bin放到板卡上启动后上述一、二驱动没有问题的情况下直接执行该bin就可以

实现拨号:


运行:

 # quectel-CM –s ctnet &
 [01-01_00:26:45:355] Quectel_ConnectManager_SR01A01V10
 [01-01_00:26:45:356] ./quectel-CM profile = ctnet///, pincode =
 [01-01_00:26:45:357] Find qmichannel = /dev/qcqmi2
 [01-01_00:26:45:358] Find usbnet_adapter = eth2
 。。。。。
 [01-01_00:26:45:937] udhcpc (v1.20.2) started
 [01-01_00:26:45:956] Sending discover...
 [01-01_00:26:45:960] Sending select for 10.172.27.151...
 [01-01_00:26:45:964] Lease of 10.172.27.151 obtained, lease time 7200
 [01-01_00:26:45:984] deleting routers
 route: SIOCDELRT: No such process
 [01-01_00:26:46:003] adding dns 61.132.163.68
 [01-01_00:26:46:003] adding dns 202.102.213.68
 [01-01_00:26:45:560] requestGetSIMStatus SIMStatus: SIM_READY

可以ping通外网就说明拨号成功了!

本文参考文档下载链接http://download.csdn.net/download/u013008311/10240057

驱动源码下载链接http://download.csdn.net/download/u013008311/10240049













猜你喜欢

转载自blog.csdn.net/u013008311/article/details/79241243