/sys/bus/usb-serial/drivers/option1/new_id'(手动添加设备 ID)_全志t113处理器移植">
赞
踩
在做这件事情前,首先得区分好虚拟机Ubuntu系统和开发板系统这两者,不然很容易造成混淆,从而会把一件简单的事情给复杂化。
1、首先在虚拟机Ubuntu系统下,这个驱动是系统自带的,但是在我们将EC20模块连接到虚拟机的时候,/dev
目录下并没有对应的ttyUSB0
,ttyUSB1
,ttyUSB2
这三个文件。这个时候,我们只要执行以下命令(一定要以root身份执行该命令)即可:
modprobe option
sh -c 'echo "2c7c 6005" > /sys/bus/usb-serial/drivers/option1/new_id' (手动添加设备ID)
在执行完上面的命令之后,再次查看/dev目录,就会发现会多出三个ttyUSB*文件
2、在我们的开发板系统里面,是没有这个驱动的,就需要我们进行移植,这样才能够去使用这个EC20模块。那么接下来所有教程,就是以开发板系统为准去进行的。(EC200T和EC200A都是一样的)
整个移植的步骤就是,修改一下内核目录里面的几个.c文件,然后进行make menuconfig进行内核定制,然后编译就行了。简单的来说就是make menuconfig就是为了让那几个被修改的.c文件生效并且使用。
在这里我以我正在使用的全志T113为例(使用Buildroot开发组件)。
在 buildroot 源码根目录下可以直接进入 output/build/
目录下找到 Linux 内核源码使用的 构建缓存文件夹 因为源码存放在 git 仓库, 所以 内核源码的 构建缓存 目录名称也是 linux+gitcommitid 组成, 如下所示, 我的内核源码目录是 linux-origin_master
你的可能是linux-d4a3… - 后一堆字符串组成
的目录名称。
打开内核目录,是如下这样子的:
为了识别模块,需要将以下模块的VID和PID信息添加到
文件 [你的内核目录]/drivers/usb/serial/option.c
将下面有’+‘号的代码加入到文件相应的位置
static const struct usb_device_id option_ids[] = {
+#if 1 //Added by Quectel
+{ USB_DEVICE(0x2C7C, 0x6026) }, /* Quectel EC200T */
+{ USB_DEVICE(0x2C7C, 0x6000) }, /* Quectel EC200T */
+#endif
添加完之后是这样的:
根据USB协议的要求,在批量输出传输期间处理零数据包的机制
需要添加到相应的文件中。
对于高于2.6.34的Linux内核版本,请将以下’+'号之间语句添加到文件中
[你的内核目录]/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(0x2C7C))
urb->transfer_flags |= URB_ZERO_PACKET;
}
#endif
+
return urb;
}
当MCU进入挂起/休眠模式时,USB主机控制器/USB集线器可能会断电或
重置,在MCU退出挂起/休眠模式后无法恢复USB设备。请添加以下语句启用重置恢复过程。
对于高于3.4的Linux内核版本,请将以下语句添加到文件中
[你的内核目录]/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
};
对于低于3.5的Linux内核版本,请将以下语句添加到文件中
[你的内核目录]/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,
};
如果需要ECM或RNDIS,请添加以下语句以防止模块的接口0
用作USB串行设备。
对于高于2.6.30的Linux内核版本,请将以下语句添加到文件中
[你的内核目录]/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
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
__u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
//Quectel EC200T's interface 0 can be used as USB Network device (ecm, rndis)
if (serial->interface->cur_altsetting->desc.bInterfaceClass != 0xFF)
return -ENODEV;
}
#endif
+
/* Store device id so we can use it during attach. */
usb_set_serial_data(serial, (void *)id);
return 0;
}
首先cd [你的内核目录],然后输入make menuconfig
:
回车之后,就会进入到一个图形化界面:
接下来我们需要去设置一点东西,进入到这个图形化界面之后,按左斜杠键,进入到搜索栏:
然后搜索USB_SERIAL回车:
找到对应的标号,然后按键盘上面的数字键,这里对应是(1),所以按1键就会这样(你们的括号里面是空的,按空格键就可以选择这一项,记住括号里面是*号,不是M):
然后继续左斜杠分别搜索和选择USB_SERIAL_OPTION、USB_USBNET、USB_NET_CDCETHER、USB_NET_RNDIS_HOST。然后通过左右键一直选择下面的Exit按钮,直到最后选择yes进行保存退出即可。
在buildroot目录下执行命令make linux-rebuild V=1
.
在单独编译完内核后,再执行命令make V=1
.
这里可以参考: 自动烧录系统脚本
在系统烧录后进入系统的时候,插上EC20模块后,/dev
目录下还是没有对应三个ttyUSB*
文件,此时,我们需要加载驱动和手动添加设备ID。
加载驱动:执行命令modprobe option
手动添加设备ID:执行命令sh -c 'echo "2c7c 6005" > /sys/bus/usb-serial/drivers/option1/new_id'
。
如果这两步没有任何问题,那么就可以看到/dev
目录下已经有了ttyUSB0
、ttyUSB1
、ttyUSB2
这三个文件。那么就说明你移植成功了。
很煎熬,编译了n次,烧录了n次
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。