一、4G模块概述
1、调试的模块型号是广和通的 NL668-EAU-00-M.2。
2、使用的接口是 M.2 Key-B。实际只用到了M2里的USB接口。
-
调试过程
以QMI_WWAN号方式进行说明,其他拨号方式也试过。最后以QMI_WWAN方式调通了,拨号成功了。
其他拨号方式因为现有文档资料工具移植平台导致失败,比如GobiNet拨号提供AT$QCRMCALL=1,1现驱动已不支持,提供的AT通信文档也没有该指令且使用其他拨号方式提供拨号AT指令也不支持,ECM拨号方式走到了获取IP地址哪一步,但是使用udhcpc -i usb0获取的ip为本公司内网的ip,初步怀疑是是该拨号方式与hisi平台udhcpc指令兼容性的问题,最后又重新选择的qmi拨号方式。
一开始就是用的qmi拨号方式,主要是该拨号方式驱动集成简单只需要修改内核配置及其文件即可,且设置APN获取ip等通过工具即可不需要外部输入AT指令,但是可能是hisi平台系统的差异性,该厂商提供的拨号程序始终获取不到ip,最后找了个新的开源的拨号程序quectel-cm成功获取到ip且ping通网络。
1、USB串口驱动集成
1)修改内核配置
修改内核支持option驱动。
在 Device Drivers > USB support > USB Serial Converter support 下选中 USB driver for GSM and CDMA modems。
修改 USBnet 驱动支持,因此需要配置 Linux 内核,配置 方法如下:
Device Drivers->Network device support->USB Network Adapters
选中如下组件:
Multi-purpose USB Networking Framework
2)修改option.c文件
文件路径:drivers/usb/serial/option.c 。
在源码中找到option_ids数组,在数组中添加NL668产品的VID(0x1508)和PID(0x1001);
static const struct usb_device_id option_ids[] = {
... ...
{ USB_DEVICE(0x1508, 0x1001),
.driver_info = RSVD(4)},
文件中已经添加了改VID,只需过来rm net端口即可。
3)修改qmi_wwan文件
文件路径:drivers/net/usb/qmi_wwan.c。
在源码中找到usb_device_id数组,在数组中添加NL668产品的VID(0x1508)和PID(0x1001);
static const struct usb_device_id products[] = {
... ...
{QMI_FIXED_INTF(0x1508, 0x1001, 4)},
... ...
在该文件添加RAW IP支持
添加qmi_wwan_tx_fixup函数接口
struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb,gfp_t flags)
{
if (dev->udev->descriptor.idVendor !=cpu_to_le16(0x1508))
return skb;
// Skip Ethernet header from message
If (skb_pull(skb, ETH_HLEN)) {
return skb;
}
else {
dev_err(&dev->intf->dev, "Packet Dropped");
}
// Filter the packet out, release it
dev_kfree_skb_any(skb);
return NULL;
}
找到qmi_wwan_bind函数 在err: retuen status;前添加if语句
static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
{
... ...
if (dev->udev->descriptor.idVendor == cpu_to_le16(0x1508))
{
dev_info(&intf->dev, "Fibocom nl668 work on RawIP mode\n");
dev->net->flags |= IFF_NOARP;
usb_control_msg(
interface_to_usbdev(intf),
usb_sndctrlpipe(interface_to_usbdev(intf), 0),
0x22,//USB_CDC_REQ_SET_CONTROL_LINE_STATE
0x21,//USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
1, //active CDCDTR
intf->cur_altsetting->desc.bInterfaceNumber,
NULL, 0, 100);
}
err:
return status;
}
找到 qmi_wwan_info结构体在末尾添加.tx_fixup = qmi_wwan_tx_fixup,
static const struct driver_info qmi_wwan_info = {
... ...
.tx_fixup = qmi_wwan_tx_fixup,
};
2、内核环境确认
修改内核源码根目录.config 文 件 ,.config 中修改 CONFIG_USB_NET_QMI_WWAN=y 、
CONFIG_USB_SERIAL_OPTION=y
选中后保存配置,重新编译内核。
3、USB 串口驱动加载确认
使用lsusb 和 ls /dev/ttyUSB*命令,查看是否加载成功。如果lsusb没有相关设备出来,先确认内核是否修改成功在确认硬件问题。
ls /dev/ttyUSB* 正常可以看到4个设备。
/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3
4、USBMODE确认
QMI_WWAN模式需要特定的模式支持。用AT指令先查询模式,一般为17
用 AT+GTUSBMODE? 指令查询模式,显示如下,即不用修改。
echo -e "AT+GTUSBMODE?\r\n" > /dev/ttyUSB2 ; cat /dev/ttyUSB2
+GTUSBMODE: 17
OK
如果返回值不为17、22或25时,表示模块未进入 RMNET,需要发 AT+GTUSBMODE=x(x 为 17 、 22 或 25)成功后,并重启模块,使模块切换到 RMNET 模式。
模式切换完毕后使用ifconfig命令查看网卡信息,如果出现wwan0表示wwan0驱动加载成功,如果该网卡信息没有出现则确认qmi_wwan.c文件中修改是否有缺漏,.config配置中是否添加CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_USBNET=y,CONFIG_USB_NET_CDCETHER=y, CONFIG_USB_USBNET=y
4、QMI_WWAN 拨号程序编译
该模块文档提供的拨号程序与问题始终不能通过udhcpc获取到ip可能是平台兼容性没有做好,所以在网上找了个开源的拨号程序quectel-CM(quectel-cm-main),交叉编译后移植到板机上输入一下命令即可:
Example 1: ./quectel-CM
Example 2: ./quectel-CM -s 3gnet
例2第三位参数为sim卡的apn,运行成功如下图所示成功获取ip:
注:APN要对应运营商,运营商不同则需要不同APN
最后还需给wwan0网卡分配默认路由;即可成功ping通百度等外网,如果发现延迟过高先查看是否是LTE模式若不是则发送
echo -e "at+gtact=10,3\x0D\x0A" > /dev/ttyUSB1 ; cat /dev/ttyUSB1
返回
at+gtact=10,3
OK
则重新使用拨号程序获取ip。