rk3568-EC200A_4G模块联网调试

本文讲述了如何移植4G模块到rk3568开发板并实现上网功能

先将开发板上电,输入命令lsusb,看有没有出现,如果出现了Bus 001 Device 003: ID 2c7c:6005 ,则设备树大概率是没问题的。如果没有,则表明4G模块没有被识别到。本文仅针对驱动进行讲解,不涉及设备树方面。

1 USB转串口驱动

1.1 添加VID和PID

为了识别模块,需将模块的 VID 和 PID 信息添加到kernel/drivers/usb/serial/option.c 文件中,该4G模块使用的是移远的EC200A-CN,我们可以查询到其 VID为0x2c7c 和 PID为0x6005。

static const struct usb_device_id option_ids[] = {
	{ USB_DEVICE(0x1286, 0x4e3c) },
#if 1 //此处为添加的代码,到endif结束。
	{ USB_DEVICE(0x2C7C, 0x6005) }, 
	{ .match_flags = USB_DEVICE_ID_MATCH_VENDOR, .idVendor = 0x2C7C },
#endif

1.2 使用USBNet驱动

在1.1添加VID和PID中,配置会使模块的所有 USB 接口均绑定 USB 转串口 option 驱动程序,导致 USBNet 驱动程序接口无法工作。我们需要添加以下语句以防止 USBNet 驱动程序接口绑定 USB 转串口 option 驱动程序。

static int option_probe(struct usb_serial *serial,
			const struct usb_device_id *id)
{
	struct usb_interface_descriptor *iface_desc =
				&serial->interface->cur_altsetting->desc;
	unsigned long device_flags = id->driver_info;

#if 1 //此处为添加的代码,到endif结束。 
 	if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) { 
 		__u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
		//printk("aaaaaaaaaaaaaaaaaaddfasdf");
		//print("Detected device with Product ID: 0x%04X\n", idProduct) ;
 		struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc; 
 
 		if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42) { 
 			//ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB 
 			return -ENODEV; 
 		} 
 
 		if ((idProduct&0xF000) == 0x0000) { 
 			//MDM interface 4 is QMI 
 			if (intf->bInterfaceNumber == 4 && intf->bNumEndpoints == 3 && intf->bInterfaceSubClass == 0xFF && intf->bInterfaceProtocol == 0xFF) 
				return -ENODEV; 
 		} 
 	} 
#endif
/* Never bind to the CD-Rom emulation interface	*/
	if (iface_desc->bInterfaceClass == USB_CLASS_MASS_STORAGE)
		return -ENODEV;

1.3 修改内核配置

我们需要检查kernel的“.config”文件,查看是否启用以下配置项:

CONFIG_USB_SERIAL;
CONFIG_USB_SERIAL_WWAN;
CONFIG_USB_SERIAL_OPTION;

如果没有启用,则需要进行添加配置项,使用命令“make menuconfig ARCH=arm64”进行配置。

1.4 添加零包机制

根据 USB 协议的要求,通过在kernel/drivers/usb/serial/usb_wwan.c文件中添加如下语句在 bulk-out 传输过程中添加处理零包的机制。

static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
				      int endpoint,
				      int dir, void *ctx, char *buf, int len,
				      void (*callback) (struct urb *))
{
	struct usb_serial *serial = port->serial;
……
	usb_fill_bulk_urb(urb, serial->dev,
			  usb_sndbulkpipe(serial->dev, endpoint) | dir,
			  buf, len, callback, ctx);
#if 1 //此处为添加的代码,到endif结束。
 	if (dir == USB_DIR_OUT) { 
 		//struct usb_device_descriptor *desc = &serial->dev->descriptor; 
 
 		if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) 
 			urb->transfer_flags |= URB_ZERO_PACKET; 
 	}	 
#endif

	if (intfdata->use_zlp && dir == USB_DIR_OUT)
		urb->transfer_flags |= URB_ZERO_PACKET;

1.5 添加Reset-resume机制

部分 USB 主机控制器或 USB hub 在 MCU 进入 Suspend/Sleep(挂起/睡眠)模式时会发生掉电或复位,并且在 MCU 退出Suspend/Sleep模式后不能使模块恢复。需要通过在kernel/drivers/usb/serial/option.c文件中添加以下语句来启用reset-resume机制。

static struct usb_serial_driver option_1port_device = {
……
#ifdef CONFIG_PM
	.suspend           = usb_wwan_suspend,
	.resume            = usb_wwan_resume,
#if 1 //此处为添加的代码,到endif结束。
	.reset_resume = usb_wwan_resume, 
#endif
#endif
};

2 USB转串口结果验证

先看模块是否成功连接开发板。成功连接开发板的日志信息如下图所示。
在这里插入图片描述
使用命令busybox microcom /dev/ttyUSB1 -s 115200 回车,输入AT命令进行验证4G模块和SIM卡是否都能被检测到。
输入AT返回ok,则表示AT命令可用。

AT

输入AT+CPIN?,返回READY,表示检测到SIM卡。

AT+CPIN?

其余AT命令可以参照移远给出的AT命令手册。

3 联网

该4G模块是可以通过ECM驱动的方式进行上网的。
需要开启以下配置项。

CONFIG_USB_NET_DRIVERS 
CONFIG_USB_USBNET 
CONFIG_USB_NET_CDCETHER

ECM驱动上网前需要进行网卡绑定。步骤如下:
在控制台输入命令

busybox microcom /dev/ttyUSB1 -s 115200

输入命令进行测试。

at+qnetdevctl=?

输入命令进行联网

at+qnetdevctl=1,1,1

结果如下所示

在这里插入图片描述

本文参考了移远给出的用户手册以及AT命令。如有侵权,请联系作者进行删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值