在hi3516平台上移植4G模块(合宙CAT1:air724UG)

文章详细描述了如何在hi3516dv300SDK上移植和配置4G模块Air724UG(CAT1),包括修改源代码以识别设备VID和PID,添加reset_resume功能,增加零包机制,调整内核选项,加载驱动文件,处理网络接口和设置默认网关。此外,还解决了Linux下USB设备名称不固定的问题,通过udev规则创建固定设备名,并简述了minicom的移植。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.前言

4G模块:合宙推出的Air724UG Cat1
Linux版本:linux4.9
硬件平台:hi3516dv300 (SDK版本:rp-hi3516dv300-sdk020-20201214.tgz)

hi3516dv300的SDK源码不做任何配置或修改再编译的话,开发板是不能正确识别4G模块的。为了能让开发板正确识别4G网卡以及能够上网,则有必要对源码进行配置和修改。

2.修改源代码SDK

a.添加设备VID和PID

->进入内核目录文件 [KERNEL]/drivers/usb/serial/option.c
->在结构体 static const struct usb_device_id option_ids[]中添加如下内容:

  //+add by airm2m for Air72x
    { USB_DEVICE(0x1782, 0x4e00) },//CAT1
    // { USB_DEVICE(0x1286, 0x4e3d) },//CAT4
    //-add by airm2m for Air72x

结果如下:

static const struct usb_device_id option_ids[] = {
    //+add by airm2m for Air72x
    { USB_DEVICE(0x1782, 0x4e00) },//CAT1
    // { USB_DEVICE(0x1286, 0x4e3d) },//CAT4
    //-add by airm2m for Air72x
	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) },
	/*******省略大部分************/
	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD200, 0xff, 0xff, 0xff) },
	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_6802, 0xff, 0xff, 0xff) },
	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD300, 0xff, 0xff, 0xff) },
	{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, 0xff, 0xff, 0xff) }, /* HP lt2523 (Novatel E371) */
	{ } /* Terminating entry */
};

->在函数 option_probe中添加如下内容

//+add by airm2m for Air72x
    //CAT1
    if (dev_desc->idVendor == cpu_to_le16(0x1782) && dev_desc->idProduct == cpu_to_le16(0x4e00) && iface_desc->bInterfaceNumber <= 1)
    {
        return -ENODEV;
    }
    //CAT4
    if (dev_desc->idVendor == cpu_to_le16(0x1286) && dev_desc->idProduct == cpu_to_le16(0x4e3d) && iface_desc->bInterfaceNumber <= 1)
    {
        return -ENODEV;
    }
    //-add by airm2m for Air72x

结果如下:

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;
	struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
	const struct option_blacklist_info *blacklist;

	/* Never bind to the CD-Rom emulation interface	*/
	if (iface_desc->bInterfaceClass == 0x08)
		return -ENODEV;

	/*
	 * Don't bind reserved interfaces (like network ones) which often have
	 * the same class/subclass/protocol as the serial interfaces.  Look at
	 * the Windows driver .INF files for reserved interface numbers.
	 */
	blacklist = (void *)id->driver_info;
	if (blacklist && test_bit(iface_desc->bInterfaceNumber,
						&blacklist->reserved))
		return -ENODEV;
	/*
	 * Don't bind network interface on Samsung GT-B3730, it is handled by
	 * a separate module.
	 */
	if (dev_desc->idVendor == cpu_to_le16(SAMSUNG_VENDOR_ID) &&
	    dev_desc->idProduct == cpu_to_le16(SAMSUNG_PRODUCT_GT_B3730) &&
	    iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
		return -ENODEV;

	//+add by airm2m for Air72x
	//CAT1
	if (dev_desc->idVendor == cpu_to_le16(0x1782) && dev_desc->idProduct == cpu_to_le16(0x4e00) && iface_desc->bInterfaceNumber <= 1)
	{
		return -ENODEV;
	}
	//CAT4
	if (dev_desc->idVendor == cpu_to_le16(0x1286) && dev_desc->idProduct == cpu_to_le16(0x4e3d) && iface_desc->bInterfaceNumber <= 1)
	{
		return -ENODEV;
	}
	//-add by airm2m for Air72x

	/* Store the blacklist info so we can use it during attach. */
	usb_set_serial_data(serial, (void *)blacklist);

	return 0;
}
b.添加reset_resume

->进入内核目录文件 [KERNEL]/drivers/usb/serial/option.c
->在结构体中static struct usb_serial_driver option_1port_device添加如下内容:

  	//+add by airm2m for Air72x
	.reset_resume	   = usb_wwan_resume,
    //-add by airm2m for Air72x

结果如下:

static struct usb_serial_driver option_1port_device = {
	.driver = {
		.owner =	THIS_MODULE,
		.name =		"option1",
	},
	.description       = "GSM modem (1-port)",
	.id_table          = option_ids,
	.num_ports         = 1,
	.probe             = option_probe,
	.open              = usb_wwan_open,
	.close             = usb_wwan_close,
	.dtr_rts	   = usb_wwan_dtr_rts,
	.write             = usb_wwan_write,
	.write_room        = usb_wwan_write_room,
	.chars_in_buffer   = usb_wwan_chars_in_buffer,
	.tiocmget          = usb_wwan_tiocmget,
	.tiocmset          = usb_wwan_tiocmset,
	.ioctl             = usb_wwan_ioctl,
	.attach            = option_attach,
	.release           = option_release,
	.port_probe        = usb_wwan_port_probe,
	.port_remove	   = usb_wwan_port_remove,
	.read_int_callback = option_instat_callback,
#ifdef CONFIG_PM
	.suspend           = usb_wwan_suspend,
	.resume            = usb_wwan_resume,
  	//+add by airm2m for Air72x
	.reset_resume	   = usb_wwan_resume,
    //-add by airm2m for Air72x
#endif
};

c.增加零包机制

->进入内核目录文件 [KERNEL]/drivers/usb/serial/usb_wwan.c中
->在函数 usb_wwan_setup_urb中添加如下内容

	//+add by airm2m for Air72x
	if(dir == USB_DIR_OUT){
		struct usb_device_descriptor *desc = &serial->dev->descriptor;
		//CAT1
		if(desc->idVendor == cpu_to_le16(0x1782) && desc->idProduct == cpu_to_le16(0x4e00))
		{
			urb->transfer_flags |= URB_ZERO_PACKET;
		}
		//CAT4
		// if(desc->idVendor == cpu_to_le16(0x1286) && desc->idProduct == cpu_to_le16(0x4e3d))
		// {
		//     urb->transfer_flags |= URB_ZERO_PACKET;
		// }
	}
	//-add by airm2m for Air72x

结果如下:

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;
	struct urb *urb;

	urb = usb_alloc_urb(0, GFP_KERNEL);	/* No ISO */
	if (!urb)
		return NULL;

	usb_fill_bulk_urb(urb, serial->dev,
			  usb_sndbulkpipe(serial->dev, endpoint) | dir,
			  buf, len, callback, ctx);

	//+add by airm2m for Air72x
	if(dir == USB_DIR_OUT){
		struct usb_device_descriptor *desc = &serial->dev->descriptor;
		//CAT1
		if(desc->idVendor == cpu_to_le16(0x1782) && desc->idProduct == cpu_to_le16(0x4e00))
		{
			urb->transfer_flags |= URB_ZERO_PACKET;
		}
		//CAT4
		// if(desc->idVendor == cpu_to_le16(0x1286) && desc->idProduct == cpu_to_le16(0x4e3d))
		// {
		//     urb->transfer_flags |= URB_ZERO_PACKET;
		// }
	}
	//-add by airm2m for Air72x

	return urb;
}

3.修改内核选项

make ARCH=arm CROSS_COMPILE=arm-himix200-linux- menuconfig

Enable CONFIG_USB_SERIAL_OPTION
[]Device Drivers →
  [
] USB Support →
    [] USB Serial Converter support →
      [
] USB driver for GSM and CDMA modems
在这里插入图片描述
[] Device Drivers →
  [
] Network device support →
    [*] PPP (point-to-point protocol) support
在这里插入图片描述
make 之后

make ARCH=arm CROSS_COMPILE=arm-himix200-linux- uImage -j32

结果如下:
在这里插入图片描述

4.加载驱动文件

将以下内核驱动文件拷贝到根文件系统中

[kernel]/drivers/net/usb/usbnet.ko
[kernel]/drivers/net/usb/cdc_ether.ko
[kernel]/drivers/net/usb/rndis_host.ko

加载到内核

insmod usbnet.ko
insmod cdc_ether.ko
insmod rndis_host.ko

结果如下:
在这里插入图片描述

5.查看是否出现新的模块网卡ethx

ifconfig -a

结果如下:
在这里插入图片描述

6.启动网卡模块网卡ethx

ifconfig eth1 up

7.添加模块网卡的默认网关

Ifconfig -a出现了新的模块网卡之后,这个时候模块网卡无法ping通外网,必须把本地网卡网线拔掉才能使用模块网卡ping通外网

解決方法:需要设置一次ethx的默认网关

1.查看系统当前路由表:

ip route show  
#或者
route

2.设置一次ethx的默认网关:
route add default gw xxx.xxx.xxx.xxx ethx
例子:

route add default gw 192.168.5.1 eth1

结果如下:
在这里插入图片描述

问题

a.linux下多个usb设备不固定名称

输入命令:
ls /sys/class/tty/ttyUSB* -l // 查看usb设备信息

在这里插入图片描述

其中的1-1:1.2/1-1:1.3/1-1:1.4为固定的串口编号。

或者输入命令
udevadm info --attribute-walk --name=/dev/ttyUSB0
udevadm info --attribute-walk --name=/dev/ttyUSB1
udevadm info --attribute-walk --name=/dev/ttyUSB2

udevadm info --attribute-walk --name=/dev/ttyUSB0 |grep KERNELS #通过对比信息中的不同,可以提取出区别与各个串口的KERNELS值,
udevadm info --attribute-walk --name=/dev/ttyUSB1 |grep KERNELS #通过对比信息中的不同,可以提取出区别与各个串口的KERNELS值,
udevadm info --attribute-walk --name=/dev/ttyUSB2 |grep KERNELS #通过对比信息中的不同,可以提取出区别与各个串口的KERNELS值,

在这里插入图片描述

添加在/etc/udev/rules.d/xxxxx.rules 文件

创建一个10-local.rules 文件(root权限下建立,命名可以自定义),并添加以下内容:

KERNELS=="1-1:1.4", KERNEL=="ttyUSB*", MODE:="0777", SYMLINK+="4G_uart"
#KERNELS是工控机usb插口编号、
#KERNEL是内核设备名称
#OWNER, GROUP, MODE是设备设定权限
#SYMLINK+是为 /dev/下的设备文件产生符号链接。由于 udev 只能为某个设备产生一个设备文件,所以为了不覆盖系统默认的 udev 规则所产生的文件,推荐使用符号链接。

保存退出。重新插拔设备(或重启)就会在/dev目录下生成固定的设备名(本实例为:4G_uart)。
也可以重启服务:

#分别在终端输入以下命令,要保持一定的时间间隔:
sudo service udev reload
sudo  service udev restart

备注:

1.固定好之后usb设备插入的usb端口不能再改变。

2.操作中如果提示权限问题,用root用户操作即可。

3.若ttyUSB设备过多找不到自己要固定的串口设备,可以对要固定的设备进行拔插,通过比较插拔前后ls /sys/class/tty/ttyUSB* -l命令输出结果来找到所需要固定的串口号。

4.此方法也适用其他usb设备的固定,例如usb摄像头。。

b.minicom移植

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值