安卓系统开发

EC20 驱动 移植 Gobinet 拨号

2023-04-25  本文已影响0人  Wood木木

Ubuntu Server 18.04 中 移远EC20 驱动 移植 Gobinet 拨号

某宝买了台mini 工控机,让店家给安装了 移远EC20 的4G网卡; 拿回来装ubuntu,发现没有驱动啊,店家也只有window的驱动,无奈,只给了个移远官方的文件,照着操作吧。
《Quectel_WCDMA<E_Linux_USB_Driver_User_Guide_V1.7.pdf》
《Quectel_WCDMA<E_Linux_USB_Driver_User_Guide_V2.0.pdf》
就这两份呢文件, 折腾了好几天 终于搞好了

怕有什么奇怪的问题,我都是在root 用户下操作的 ,

一、下载 linux 内核

查看内核版本 uname -r

root@thingsbox:/# uname -r
4.15.0-106-generic

查找系统可用的 内核 apt search linux-source

root@thingsbox:/# apt search linux-source
Sorting... Done
Full Text Search... Done
linux-source/bionic-updates,bionic-security,now 4.15.0.106.94 all [installed]
  Linux kernel source with Ubuntu patches
 
linux-source-4.15.0/bionic-updates,bionic-security,now 4.15.0-106.107 all [installed,automatic]
  Linux kernel source for version 4.15.0 with Ubuntu patches
 
linux-source-4.18.0/bionic-updates,bionic-security 4.18.0-25.26~18.04.1 all
  Linux kernel source for version 4.18.0 with Ubuntu patches
 
linux-source-5.0.0/bionic-updates,bionic-security 5.0.0-52.56~18.04.1 all
  Linux kernel source for version 5.0.0 with Ubuntu patches
 
linux-source-5.3.0/bionic-updates,bionic-security 5.3.0-59.53~18.04.1 all
  Linux kernel source for version 5.3.0 with Ubuntu patches

选择你和你系统相匹配的 内核版本 然后安装, 命令后面可以带上版本号

root@thingsbox:/# apt install linux-source

下载完成后, 安装的内核 一般在 /usr/src/目录下面

root@thingsbox:/usr/src# cd /usr/src/
root@thingsbox:/usr/src# ls
linux-headers-4.15.0-106  linux-headers-4.15.0-106-generic  linux-source-4.15.0  linux-source-4.15.0.tar.bz2

打开 /usr/src/linux-source-4.15.0 目录 解压内核 tar -jxvf linux-source-4.15.0.tar.bz2

root@thingsbox:/usr/src/linux-source-4.15.0# ls
debian  debian.master  linux-source-4.15.0  linux-source-4.15.0.tar.bz2
root@thingsbox:/usr/src/linux-source-4.15.0# tar -jxvf linux-source-4.15.0.tar.bz2 

最终 内核文件的位置为 /usr/src/linux-source-4.15.0/linux-source-4.15.0

root@thingsbox:/usr/src/linux-source-4.15.0/linux-source-4.15.0# pwd
/usr/src/linux-source-4.15.0/linux-source-4.15.0
root@thingsbox:/usr/src/linux-source-4.15.0/linux-source-4.15.0# ls
arch     CREDITS        dropped.txt  init     kernel       mm       scripts         tools                virt
block    crypto         firmware     ipc      lib          net      security        ubuntu
certs    Documentation  fs           Kbuild   MAINTAINERS  README   snapcraft.yaml  update-version-dkms
COPYING  drivers        include      Kconfig  Makefile     samples  sound           usr

二、USB Serial Driver USB 驱动编辑

参考 《Quectel_WCDMA<E_Linux_USB_Driver_User_Guide_V1.7.pdf》 的3.2 章节,照着一步一操作 ,很easy

If you are using UC15/UC20/EC25/EC21/EC20/EC20 R2.0/EG91/EG95/EG06/EP06/EM06/BG96 and
requiring USB serial driver, please read this section for details. Otherwise, please skip this section.
When a Quectel module is attached to the USB Serial driver, the driver will create device files in directory
“/dev”, named as below:
ttyUSB0/ttyUSB1/ttyUSB2...

如果USB 驱动安装 成功 会在 /dev 目录先看见 ttyUSB0/ttyUSB1/ttyUSB2/ ttyUSB3 这几个设备

3.2.1. Add VID and PID
In order to recognize Quectel module, you should add module VID and PID information as below:
File: [KERNEL]/drivers/usb/serial/option.c

static const struct usb_device_id option_ids[] = {
#if 1 //Added by Quectel
{ USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
{ USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
{ USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25/EC20 R2.0 */
{ USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
{ USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */
{ USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */
{ USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
{ USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
{ USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
#endif

If you are using EC20 and following files and statements exist in your kernel source files, please delete
them, as they will conflict with EC20's USB Drivers

如果你的芯片是 EC20 还要删除这几个冲突的东西,我也不知道是什么

[KERNEL]/drivers/usb/serial/qcserial.c
{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
[KERNEL]/drivers/net/usb/qmi_wwan.c
{QMI_GOBI_DEVICE(0x05c6, 0x9215)},  /* Acer Gobi 2000 Modem device (VP413) */

3.2.2. Add the Zero Packet Mechanism
As required by the USB protocol, you need to add the mechanism for processing zero packets during bulk
out transmission.

添加零包处理机制

File: [KERNEL]/drivers/usb/serial/usb_wwan.c
static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, 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
//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(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
urb->transfer_flags |= URB_ZERO_PACKET;
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
urb->transfer_flags |= URB_ZERO_PACKET;
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
urb->transfer_flags |= URB_ZERO_PACKET;
if (desc->idVendor == cpu_to_le16(0x2C7C))
urb->transfer_flags |= URB_ZERO_PACKET;
}
#endif
return urb;
}

3.2.3. Add Reset Resume
Some USB host controllers/USB hubs will lost power or be reset when MCU entering into suspend/sleep mode, and they cannot resume USB devices when MCU exiting from suspend/sleep mode; instead, they will operate reset-resume. You should add the following statements:

睡眠重启

File: [KERNEL]/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 //Added by Quectel
.reset_resume
= usb_wwan_resume,
#endif
#endif
};

3.2.4. Enlarge Bulk out URBs
For Linux kernel version older than 2.6.29. You need to enlarge bulk out URBs to get faster uplink speed.

老的内核版本 还要添加这个东西 ,我的内核是 4.15 所以没有操作

3.2.5. Use GobiNet or QMI WWAN
If you are using UC20/EC25/EC21/EC20/EC20 R2.0/EG91/EG95/EG06/EP06/EM06/BG96 and requiring GobiNet or QMI WWAN, you must add the following statements to prevent these modules’ interface 4 from being used as USB serial device.

如果要使用 GobiNet 拨号, 还要配置这个

File: [KERNEL]/drivers/usb/serial/option.c
static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) {
struct usb_wwan_intf_private *data;
......
#if 1 //Added by Quectel
//Quectel UC20's interface 4 can be used as USB Network device
if
(serial->dev->descriptor.idVendor
==
cpu_to_le16(0x05C6)  &&
serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)
&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
//Quectel EC20's interface 4 can be used as USB Network device
if
(serial->dev->descriptor.idVendor
==
cpu_to_le16(0x05C6)
&&
serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)
&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
//Quectel EC25&EC21&EC20 R2.0&EG91&EG95&EG06&EP06&EM06&BG96's interface 4 can be
used as USB Network device
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)
&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
#endif
/* Store device id so we can use it during attach. */
usb_set_serial_data(serial, (void *)id);
return 0;
}

3.2.6. Modify Kernel Configuration
There are several mandatory selected items in kernel configuration; you should follow the steps below to
configure the kernel:

修改内核配置,

这里要注意 我捣鼓了好久 , 就是捣鼓不对

Step 1: cd <your kernel directory>

这里 **your kernel directory ** 是内核的根目录,比如 我的内核根目录 就是'/usr/src/linux-source-4.15.0/linux-source-4.15.0'

Step 2: Set your environment variables, and import your board's defconfig The following is an example
for Raspeberrypi board

export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabi-
make bcmrpi_defconfig

关于默认的 defconfig 文件, 主要看每个平台的芯片。x86平台在[KERNEL]/arch/x86/configs。正常Arm的配置是在:[KERNEL]/arch/arm/configs

在内核 根目录下 make x86_64_defconfig

Step 3: make menuconfig
Step 4: Enable CONFIG_USB_SERIAL_OPTION

[*] Device Drivers →
          [*] USB Support →  
                  [*] USB Serial Converter support →
                             [*] USB driver for GSM and CDMA modems

按下 Y 键 选中 ,然后 选择 save 后 退出

最后在内核根目录下编译相关项目

3.2.7. Build and Load Driver as Kernel Module for PC in Linux
If you are using Linux on PC, you can follow the steps below to build the driver as Kernel module, and use
modprobe command to load the module.

Step 1:
cd <your kernel directory>

Step 2:
sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=option.o modules
sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=usb_wwan.o modules
sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=qcserial.o modules

Step 3:
sudo cp drivers/usb/serial/option.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
sudo cp drivers/usb/serial/usb_wwan.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
sudo cp drivers/usb/serial/qcserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
sudo depmod
sudo reboot

重启后 在 /dev 目录下面 看见这三个设备 就算成功了!

ttyUSB0            ttyUSB1        ttyUSB2     ttyUSB3

二、GobiNet Driver 驱动添加
参考 《Quectel_WCDMA<E_Linux_USB_Driver_User_Guide_V1.7.pdf》 的3.4 章节,照着一步一操作 ,也是很简单的

When a Quectel module is attached to GobiNet driver, the driver will create a network device and a QMI channel. The network device is named as ethX (usbX if the kernel version is 2.6.39 or older), and the QMI channel is named as /dev/qcqmiX. The network device is used for data transmission, and QMI channel is used for QMI message interaction.

如果操作成功 会在 /dev 目录下面 出现 qcqmiX 这个设备

3.4.1. Modify Driver Source Code
The GobiNet driver is provided by Quectel as a form of source file. You should copy the source files to “[KERNEL]/drivers/net/usb/” ([KERNEL]/drivers/usb/net/ if the kernel version is older than 2.6.22)

将 GobiNet 的驱动文件 放在 [KERNEL]/drivers/net/usb/ 目录下面

Step 2: Set your environment variables, and import your board’s defconfig. The following is an example for Raspeberrypi board

在 内核的根目录下面 make x86_64_defconfig

Step 3: make menuconfig

Step 4: Enable CONFIG_USB_USBNET

[*] Device Drivers →
        -*- Network device support →
                    USB Network Adapters →
                                 {*} Multi-purpose USB Networking Framework

按下 Y 键 选中 ,然后 选择 save 后 退出

Step 5: Please add the following statements to file "[KERNEL]/drivers/net/usb/Makefile"
([KERNEL]/drivers/usb/net/Makefile if the kernel version is older than 2.6.22).
obj-y += GobiNet.o
GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o

注意 : 是 Makefile 不是 makefile

然后就可以编译相关配置了

3.4.3. Build and Load Driver as Kernel Module for PC in Linux
If you are using Linux on PC, you can follow the steps below to build the driver as Kernel module, and use modprobe command to load the module.

Step 1: cd <your kernel directory>
Step 2:
sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/net/usb obj-m=GobiNet.o modules
sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=qcserial.o modules
Step 3:
sudo cp drivers/net/usb/GobiNet.ko /lib/modules/`uname -r`/kernel/drivers/net/usb
sudo cp drivers/usb/serial/qcserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
sudo depmod
sudo reboot

最终

重启后 在 /dev 目录下面 看见这这个通道 就算成功了!

三、Connect Manager 编译配置

参考 《Quectel_WCDMA<E_Linux_USB_Driver_User_Guide_V1.7.pdf》 的5.3 章节,照着一步一操作 ,也能做出来

Step 1: Compile Connect Manager.

把 quectel Connect Manager 文件 quectel-quectel 放到 一个你喜欢的地方

进入文件目录 执行 make 就会出现 可执行的二进制文件 quectel-CM 这就是 最终操作的文件

Step 2: Prepare busybox udhcpc tool.

quectel-CM will call busybox udhpc to obtain IP and NDS, and busybox udhpc will call script file
/usr/share/udhcpc/default.script to set IP/DNS/Routing table for Linux board. You can download this tool's
source code from https://busybox.net/. You should enable CONFIG_UDHCPC in busybox menuconfig and copy the script file [BUSYBOX]/examples/udhcp/simple.script to your Linux board (renamed as
/usr/share/udhcpc/default.script).

从 busybox 官网 https://busybox.net/. 下载 最新的 源码文件。

把 [BUSYBOX]/examples/udhcp/simple.script 文件移动到/usr/share/udhcpc/default.script 。如果没有目录就创建一个

因为 udhcpc 需要需要用到这个 脚本

然后 这个enable CONFIG_UDHCPC in busybox menuconfig 我也没有搞明白怎么操作,
这里编译quectel-CM命令,我直接放到开发板上,直接make就能出来了。不需要busybox

Step 3: Use quectel-CM to setup data call.

最后 执行 ./quectel-CM 就链接成功了


quectel-CM成功连接

最后可以看见网卡已经启动,并设置上了ip

还有一个就是 我执行 quectel-CM 的时候 ,

执行到 Lease of 10.172.27.151 obtained, lease time 7200 就卡住不走了;

研究了好久的udhcp 也没有搞明白。

但是 最后 ip地址和dns也写到了网卡里面,

最后 莫名其妙的成功了; 我也搞不懂。

四、添加开机自启动服务

在/lib/systemd/system 创建 quectel-ec20.service 文件

vim quectel-ec20.service

文件内容 :

[Unit]
Description=quectel ec20 4g net service
 
[Service]
Type=simple
 
ExecStart=/opt/quectel-CM/quectel-CM
ExecReload=/opt/quectel-CM/reload.sh
ExecStop=/opt/quectel-CM/stop.sh
PrivateTmp=true
 
[Install]
WantedBy=multi-user.target
Alias=quectel-ec20.service

然后 sudo systemctl daemon-reload

然后重启一下

然后就可以使用 systemctl 了

 systemctl start quectel-ec20.service

开机启动:

 systemctl enable quectel-ec20.service

最后一张图


最后一张图

后记

编译quectel-CM可以直接把源码放到宿主机器上编译。systemd的服务类型要用simple。如果用forking的话,会因为quectel-CM一直没有返回,导致服务被系统杀死的情况。

上一篇下一篇

猜你喜欢

热点阅读