• A133P EC200M模块调试


    Linux USB驱动框架:

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

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

    一、驱动移植

    1. // 需要修改的内核配置
    2. longan/kernel/linux-4.9/.config
    3. // 需要修改的驱动文件
    4. longan/kernel/linux-4.9/drivers/usb/serial/option.c
    5. longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c
    6. // 需要用到的驱动文件
    7. longan/kernel/linux-4.9/drivers/net/usb/cdc-acm.c
    8. longan/kernel/linux-4.9/drivers/net/usb/cdc-ether.c

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

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

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

    1. // linux-4.9/drivers/usb/serial/option.c
    2. static int option_probe(struct usb_serial *serial, const struct usb_device_id *id)
    3. {
    4.     ......    
    5. #ifdef SUPPORT_QUECTEL 
    6.     if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
    7.         __u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
    8.         struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc;
    9.         if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42) {
    10.             //ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB
    11.             return -ENODEV;
    12.         }
    13.         if ((idProduct&0xF000) == 0x0000) {
    14.             //MDM interface 4 is QMI
    15.             if (intf->bInterfaceNumber == 4 && intf->bNumEndpoints == 3 && intf->bInterfaceSubClass == 0xFF && intf->bInterfaceProtocol == 0xFF)
    16.                 return -ENODEV;
    17.         }
    18.     }
    19.     #ifdef SUPPORT_QUECTEL_AUTO_SUSPEND
    20.     //For USB Auto Suspend
    21.     if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
    22.         pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);
    23.         usb_enable_autosuspend(serial->dev);
    24.     }
    25.     #endif 
    26.     #ifdef SUPPORT_QUECTEL_REMOTE_WAKEUP
    27.     //For USB Remote Wakeup
    28.     if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
    29.         device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup
    30.     }
    31.     #endif
    32. #endif
    33.     /* Store the device flags so we can use them during attach. */
    34.     usb_set_serial_data(serial, (void *)device_flags);
    35.     return 0;
    36. }

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

    1. 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
    2. old mode 100644
    3. new mode 100755
    4. index 3dfdfc8..e56b275
    5. --- a/longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c
    6. +++ b/longan/kernel/linux-4.9/drivers/usb/serial/usb_wwan.c
    7. @@ -36,6 +36,8 @@
    8.  #include <linux/serial.h>
    9.  #include "usb-wwan.h"
    10.  
    11. +#define SUPPORT_QUECTEL 1
    12. +
    13.  /*
    14.   * Generate DTR/RTS signals on the port using the SET_CONTROL_LINE_STATE request
    15.   * in CDC ACM.
    16. @@ -504,6 +506,14 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
    17.         usb_fill_bulk_urb(urb, serial->dev,
    18.                           usb_sndbulkpipe(serial->dev, endpoint) | dir,
    19.                           buf, len, callback, ctx);
    20. +       
    21. +#ifdef SUPPORT_QUECTEL 
    22. +       if (dir == USB_DIR_OUT) {
    23. +               struct usb_device_descriptor *desc = &serial->dev->descriptor;
    24. +               if (desc->idVendor == cpu_to_le16(0x2C7C))
    25. +                       urb->transfer_flags |= URB_ZERO_PACKET;
    26. +       }
    27. +#endif
    28.  
    29.         return urb;
    30.  }


    4.增加 USB 控制器复位后恢复操作

    1. // linux-4.9/drivers/usb/serial/option.c
    2. static struct usb_serial_driver option_1port_device = {
    3.     ......
    4. #ifdef SUPPORT_QUECTEL
    5.     .reset_resume      = usb_wwan_resume,
    6. #endif
    7. };

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

    1. CONFIG_USB_SERIAL=y
    2. CONFIG_USB_SERIAL_WWAN=y
    3. CONFIG_USB_SERIAL_OPTION=y
    4. CONFIG_USB_ACM=y
    5. CONFIG_USB_NET_DRIVERS=y
    6. CONFIG_USB_USBNET=y
    7. CONFIG_USB_NET_CDCETHER=y

     6.配置内核

    1. 1):执行以下命令切换到内核目录
    2. cd <用户内核目录>
    3. 2):执行以下命令编译内核。
    4. make menuconfig
    5. 3):启用配置项。
    6.         选择<*>表示将驱动程序编译到内核映像。
    7.         选择<M>表示将驱动程序编译成模块。

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

    二、系统适配


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

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

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

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

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

    三、查看系统属性

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

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

    四、日志抓取

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

    1. adb root
    2. adb shell mkdir /data/quectel_debug_log
    3. adb shell chmod 777 /data/quectel_debug_log
    4. adb reboot

  • 相关阅读:
    超级实用网站+公众号合集
    输入输出错误重定向
    基于FPGA的RGB图像转化为灰度图实现,通过MATLAB进行辅助验证
    前端工作小结81-状态管理里面取值
    Spring系列11:@ComponentScan批量注册bean
    代码混淆与反混淆学习-第二弹
    640.Solve the Equation
    java 实现布隆过滤器(BloomFilter)
    ansible清单文件的配置方法、配置文件的配置、临时命令的用法
    Docker-compose教程(安装,使用, 快速入门)
  • 原文地址:https://blog.csdn.net/qq_53676406/article/details/132282751