A133P EC200M模块调试

Linux USB驱动框架:

        USB 是一种分层总线结构。USB 设备与主机之间的数据传输由 USB 控制器控制。Linux USB 驱动程序架构如下图所示。Linux USB 主机驱动包括三部分:USB 主机控制器驱动、USB 核心和 USB 设备驱动。

        模块加载 USB 转串口 option 驱动程序后,在/dev 目录下创建 ttyUSB0、ttyUSB1 和 ttyUSB2 等设备文件。以下章节介绍如何将 USB 转串口 option 驱动程序移植到 Linux 操作系统中。

一、驱动移植

// 需要修改的内核配置
longan/kernel/linux-4.9/.config

// 需要修改的驱动文件
longan/kernel/linux-4.9/drivers/usb/serial/option.c
longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c

// 需要用到的驱动文件
longan/kernel/linux-4.9/drivers/net/usb/cdc-acm.c
longan/kernel/linux-4.9/drivers/net/usb/cdc-ether.c

1.在 option_ids 列表内增加 EC200M-CN 的 PID\VID, 这样才能识别到该 USB 设备为串口设备,文档内可查。

// linux-4.9/drivers/usb/serial/option.c
static const struct usb_device_id option_ids[] = {
#ifdef SUPPORT_QUECTEL
    { USB_DEVICE(0x2C7C, 0x6002) }, // support EC200S/EC200M
#endif
    ......
}

2.一个 USB 设备可以有多个功能不同的接口,在 option_ids 添加该设备的 PID\VID 后,会导致该设备的所有接口都会绑定到 USB Serial Option 驱动上,导致 USBNet 驱动接口无法正常工作,因此需要在 option_probe 中根据类码、接口索引、端点数量、子类码将 USBNet 的接口排除出来。

// linux-4.9/drivers/usb/serial/option.c
static int option_probe(struct usb_serial *serial, const struct usb_device_id *id)
{
    ......    
#ifdef SUPPORT_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;
        }
    }
    #ifdef SUPPORT_QUECTEL_AUTO_SUSPEND
    //For USB Auto Suspend
    if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
        pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);
        usb_enable_autosuspend(serial->dev);
    }
    #endif 
    #ifdef SUPPORT_QUECTEL_REMOTE_WAKEUP
    //For USB Remote Wakeup
    if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
        device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup
    }
    #endif
#endif
    /* Store the device flags so we can use them during attach. */
    usb_set_serial_data(serial, (void *)device_flags);
    return 0;
}

3.根据USB协议的要求,在批量输出传输期间,通过设置 URB_ZERO_PACKET 标志来添加处理零数据包的机制。

diff --git a/longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c b/longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c
old mode 100644
new mode 100755
index 3dfdfc8..e56b275
--- a/longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c
+++ b/longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c
@@ -36,6 +36,8 @@
 #include <linux/serial.h>
 #include "usb-wwan.h"
 
+#define SUPPORT_QUECTEL 1
+
 /*
  * Generate DTR/RTS signals on the port using the SET_CONTROL_LINE_STATE request
  * in CDC ACM.
@@ -504,6 +506,14 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
        usb_fill_bulk_urb(urb, serial->dev,
                          usb_sndbulkpipe(serial->dev, endpoint) | dir,
                          buf, len, callback, ctx);
+       
+#ifdef SUPPORT_QUECTEL 
+       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.增加 USB 控制器复位后恢复操作

// linux-4.9/drivers/usb/serial/option.c
static struct usb_serial_driver option_1port_device = {
    ......
#ifdef SUPPORT_QUECTEL
    .reset_resume      = usb_wwan_resume,
#endif
};

5.在内核中启用 USB SERIAL 配置

CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_ACM=y
CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_CDCETHER=y

 6.配置内核

(1):执行以下命令切换到内核目录
    cd <用户内核目录>

(2):执行以下命令编译内核。
    make menuconfig

(3):启用配置项。
        选择<*>表示将驱动程序编译到内核映像。
        选择<M>表示将驱动程序编译成模块。

以 USB 转串口 option 驱动为例,用户可以通过以下选项启用CONFIG_USB_SERIAL_OPTION,将USB 转串口 option 驱动编译到内核镜像。

二、系统适配


主要是修改 ril 库相关的文件,实现拨号和衔接数据通路。

1.ril 库移植
涉及文件列表

android/hardware/ril/rild/radio.xml
android/hardware/ril/rild/rild.rc
android/device/softwinner/common/sepolicy/vendor/rild.te
android/vendor/aw/public/prebuild/lib/librild/radio_common.mk
android/vendor/aw/public/prebuild/lib/librild/lib/lib32/libquectel-ril.so
android/vendor/aw/public/prebuild/lib/librild/lib/lib64/libquectel-ril.so

构建文件拷贝脚本,将移远的 ril 库以及 apns-conf.xml、ql-ril.conf 文件更新到系统指定目录下

android/vendor/aw/public/prebuild/lib/librild/lib/lib32/libquectel-ril.so
android/vendor/aw/public/prebuild/lib/librild/lib/lib64/libquectel-ril.so

三、查看系统属性

mercury-demo:/ # getprop | grep ril
getprop | grep ril
[gsm.version.ril-impl]: [Quectel_Android_RIL_Driver_V3.5.0]
[init.svc.vendor.ril-daemon]: [running]
[ro.boottime.vendor.ril-daemon]: [9918673186]
[ro.radio.noril]: [false]
[vendor.rild.libargs]: [-d/dev/ttyUSB2]
[vendor.rild.libpath]: [/vendor/lib64/libquectel-ril.so]

 以上信息包括ril库的版本,ril守护进程的运行状态,还有ril库文件的路径等等,在移植相应ril库文件后EC200M模块可正常上网。

四、日志抓取

如有其他问题可进行抓取日志分析,抓取模块Log方法如下:

adb root
adb shell mkdir /data/quectel_debug_log
adb shell chmod 777 /data/quectel_debug_log
adb reboot

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春风从不入睡、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值