Jetson Orin Nano - EC20 4G模组驱动移植

参照移远EC20用户指导手册移植驱动:
《Quectel_UMTS_LTE_5G_Linux_USB_Driver_用户指导_V1.0》

Linux内核版本:5.15.148

一、移植过程


jetson Orin Nano 开发板USB插拔EC20打印
USB插上EC20,生成 /dev/ttyUSB0 - /dev/ttyUSB3,功能如下:
$ lsusb #lsusb能看到 VID、PID

1、修改内核配置


Jetson Orin Nano配置文件路径:arch/arm64/configs/defconfig

1.1 配置USB转串口驱动

CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y

1.2 配置QMI_WWAN驱动


        当模块成功加载QMI_WWA驱动程序后,会创建一个网络设备和一个QMI设备节点。网络设备名称为“wwanX”,QMI设备节点名称为“/dev/cdc-wdmX”。网络设备用于数据传输,QMI设备节点用于QMI消息交互。
CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_QMI_WWAN=y
CONFIG_USB_WDM=y

修改后如下:

2、修改Kernel源码,支持EC20


2.1 修改USB转串口驱动

1)修改 drivers/usb/serial/option.c,添加VID和PID
static const struct usb_device_id option_ids[] = { 
#if 1 // 2025-04-24 Added by Quectel
    { USB_DEVICE(0x2C7C, 0x0125) }, 
#endif
    ... ...
}

2)使用USBNet驱动
drivers/usb/serial/option.c
static int option_probe(struct usb_serial *serial,
            const struct usb_device_id *id)
{
    ... ...

#if 1  // 2025-04-24 Added by Quectel  
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) { 
        __u16 idProduct = le16_to_cpu(serial->dev->descriptor.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 

    /* Store the device flags so we can use them during attach. */
    usb_set_serial_data(serial, (void *)device_flags);

    return 0;
}

3)添加零包机制
根据USB协议的要求,通过添加如下语句在bulk-out传输过程中添加处理零包的机制:
路径:drivers/usb/serial/usb_wwan.c
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 *))
{
 ... ...
    usb_fill_bulk_urb(urb, serial->dev,
              usb_sndbulkpipe(serial->dev, endpoint) | dir,
              buf, len, callback, ctx);
     
#if 1   //2025-04-24 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;
}

4)添加Reset-resume机制(休眠唤醒)
部分USB主机控制器或USB hub在MCU进入Suspend/Sleep(挂起/睡眠)模式时会发生掉电或复位,并且在MCU退出Suspend/Sleep模式后不能使模块恢复。需要通过添加以下语句来启用reset-resume机制。
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  //2025-04-24 Added by Quectel 
    .reset_resume   = usb_wwan_resume, 
#endif
#endif
};

3、添加QMI_WWAN驱动


        移远提供了QMI_WWAN驱动源文件qmi_wwan_q.c,拷贝到 drivers/net/usb/ 目录下。修改drivers/net/usb/Makefile,使其能编译 qmi_wwan_q.c
# must insert qmi_wwan_q.o before qmi_wwan.o 
obj-${CONFIG_USB_NET_QMI_WWAN} += qmi_wwan_q.o 
obj-${CONFIG_USB_NET_QMI_WWAN} += qmi_wwan.o 

二、验证EC20驱动移植结果


1、编译kernel


编译遇到问题:编译时 qmi_wwan_q.c 中报错 ,没有定义 "rmnet_nss_callbacks"
解决步骤:qmi_wwan_q.c 中搜索 "rmnet_nss_callbacks",发现与 CONFIG_QCA_NSS_DRV 配置相关,最终发现是由于 arch/arm64/configs/defconfig 中配置了 CONFIG_PINCTRL_IPQ8074 导致的
解决方法:删除 CONFIG_QCA_NSS_DRV 配置,即删除 CONFIG_PINCTRL_IPQ8074
编译OK后,刷机并启动。

2、命令测试结果


2.1 查看内核打印信息

启动后的打印:

2.2 查看 /dev/ttyUSB 0 -3 节点生成

$ ls /dev/ttyUSB*

2.3 查看 /dev/cdc-wdm0 节点生成

$ ls /dev/cdc-wdm0

2.4 查看wwan0网卡

ifconfig看不到wwan0网卡,输入命令打开网卡
$ sudo ifconfig wwan0 up

3、按照EC20文档测试


3.1 测试AT命令

$ sudo apt-get install minicom        #安装minicom工具
$ minicom -v                                   #查看版本
测试:
$ sudo busybox microcom /dev/ttyUSB2

3.2 测试QMI_WWAN驱动(4G)

quectel-CM 是移远提供的拨号工具
3.2.1 验证quectel-CM
1)编译生成测试程序
make编译结果如下
板子和电脑同时接到公司路由上(都获取同一网段的IP),UBUNTU输入命令:
$ scp ./quectel-CM nvidia@192.168.7.36:/tmp                    #用scp命令将quectel-CM拷贝到板子
$ scp defult.script nvidia@192.168.7.36:/usr/share/udhcpc/     #用scp命令将 defult.script 拷贝到板子 /usr/share/udhcpc/ 目录
$ scp defult.script nvidia@192.168.7.36:/etc/udhcpc/           #用scp命令将 defult.script 拷贝到板子 /etc/udhcpc/ 目录

注意设置 defult.script 的权限,开发板输入命令

$ sudo chmod 755 /usr/share/udhcpc/defult.script
$ sudo chmod 755 /etc/udhcpc/defult.script

断开网线,开发板输入命令:

$ sudo ./quectel-CM &     #要加sudo,否则打开文件失败

问题记录:
问题: sudo ./quectel-CM & 运行quectel-CM 会调用 udhcpc 获取 wwan0 网卡的IP地址,但是发现wwan0的IP并没有设置成功,因此无法 ping通 "www.baidu.com"
问题分析:
  • default.script脚本最前面加打印,发现调用udhcpc命令时,default.script脚本没有调用
  • 改用 dhclient wwan0 后,ip才设到wwan0,并能ping通 "www.baidu.com"。进一步确认是default.script脚本的问题
  • default.script其实就是shell脚本,命令行直接执行 ./default.script,打印"-bash: ./default.script: /bin/sh^M: bad interpreter: No such file or directory",原因是default.script文件是windos格式,需转为Linux格式
解决方法:
  • ubuntu下安装dos2unix:$ sudo apt-get install dos2unix
  • $ dos2unix default.script 将default.script转换为 UNIX/Linux格式
  • default.script 重新传入开发板测试,设置 default.script 权限为 755
将 /tmp/default.script 拷贝到 /etc/udhcpc/ 和 /usr/share/udhcpc/ 下
$ sudo chmod 755 /etc/udhcpc/default.script #修改权限
$ sudo chmod 755 /usr/share/udhcpc/default.script #修改权限

2)测试成功
$ sudo quectel-CM &
$ ifconfig wwan0
$ ping www.baidu.com

测试过程如图:


EC20移植完成,所有修改的文件:

https://download.csdn.net/download/hinewcc/90911606


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值