引言
由于最近装毕的新家所在的小区未能及时通宽带,于是家中各类无线设备如何上网就成了首要要解决的问题。
在将手机网络经USB数据线和本地局域网共享给华为AP6050DN无线接入点一文中,已将华为AP6050DN无线接入点调通了,本文将记录使用基于幸狐(Luckfox)Pico这一可运行Linux操作系统的MPU来实现4G LTE上网,并将外网流量经USB网卡和网线转发给华为AP6050DN无线接入点,以实现全家各类网络设备的上网需求。
硬件准备
项 | 数量 | 购买地址 | 必要性 | 备注 |
---|---|---|---|---|
幸狐Luckfox Pico开发板 | 1 | 【幸狐科技企业店】https://item.taobao.com/item.htm?id=787699332431 | 必需 | 有条件的可以买带以太网口的幸狐Luckfox Pico Plus开发板。 |
PL2303HX USB2.0转TTL 4线串口数据线 | 1 | 【深圳市育松创达电子有限公司 电子元件 模块 电子元器件】https://item.taobao.com/item.htm?id=534848868496 | 必需 | 1. 用于Linux开发板与Windows PC的串口通信。以避免使用ADB、以太网口与Windows PC通信,占用宝贵的Type-C接口和以太网口。 2. CH340/CH340G芯片的USB2.0转TTL 4线串口数据线也可。 |
RTL8153B USB3.0转千兆以太网USB网络适配器 | 1 | 【凌天电子】https://item.taobao.com/item.htm?id=826458380979 | 必需 | 由于移远EC20-CE的最大下行速度仅为150Mbps(约18.75MB/s),又限于生活中复杂的网络状况,其根本无法跑到理论速度,因此买百兆的、SPI接口的W5100S以太网模块也够了。 但这里为了快速调通,减少制造障碍,于是直接购买了USB接口的网络模块。 |
移远EC20-CE 4G模块 | 1 | 【松胜科技】https://item.taobao.com/item.htm?id=719166266616 | 必需 | 实现4G上网的核心设备。 |
MiniPCIe转USB2.0转接板 | 1 | 【物联网模组智能科技】https://item.taobao.com/item.htm?id=698856614415 | 必需 | 用于经USB接口简单、快速地接入4G模块。 |
MiniPCIe转USB2.0转接板 配套的USB2.0转4针线 |
1 | 【物联网模组智能科技】https://item.taobao.com/item.htm?id=699660033716 | 必需 | 用于开发板与4G模块的连接。 |
物联网专用的流量卡 | 1 | – | 必需 | 用于拨号上网。 |
带5V独立供电的USB3.0 Hub | 1 | – | 必需 | 1. 4G模块启动电流大、USB网络适配器运行功耗高,必须采用带5V独立供电的USB集线器。 2. 只要可以独立供电即可,与受电接口无关。 > MicroUSB、Type-C、DC等接口均可。 |
20针/24针ATX台式机电源 | 1 | – | 可选 | 使用手机充电器为开发板或USB集线器供电有被烧毁的风险。建议使用台式机20针/24针电源+ATX台式机电源取电板的方案作为电源来为其供电。 |
ATX台式机电源取电板 | 1 | 【电子模组设计】https://item.taobao.com/item.htm?id=676931626329 | 可选 |
软件准备
正常运行Windows操作系统的PC一台,并要求已在系统内部署以下组件:
已安装虚拟机软件。
此处以Oracle VirtualBox为例。
注意事项:
确保虚拟机挂载的磁盘空间足够大,SDK的存储目录建议设置为50GB的动态磁盘存储空间,否则难以容纳编译期间所产生的大量文件。
已在虚拟机软件中安装22.04.X版本的Ubuntu Server操作系统。
硬件连接
下载并配置Linux开发板的SDK
打开Oracle VirtualBox应用程序并启动Ubuntu Server 22.04.X虚拟机实例。
键入并执行 sudo su 命令,以切换到管理员账户下。
键入并执行以下命令,以安装编译SDK所必须的组件:
apt-get update && apt install git ssh make gcc gcc-multilib g++-multilib module-assistant expect g++ gawk texinfo libssl-dev bison flex fakeroot cmake unzip gperf autoconf device-tree-compiler libncurses5-dev pkg-config bc python-is-python3 passwd openssl openssh-server openssh-client vim file cpio rsync curl
在任意目录下键入并执行以下命令,以从远端代码仓库拉取最新的SDK源码:
git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git
修改与Linux开发板相关的配置
使用 cd 命令切换到SDK源码的根目录下。
视具体所用的Linux开发板型号,键入并执行以下命令,以个性化定制主板配置文件(BoardConfig):
vi project/cfg/BoardConfig_IPC/BoardConfig-XXX-Buildroot-RV110X_Luckfox_Pico_X-IPC.mk
注意事项:
此步骤可选,编辑它的目的是为了减小给摄像头分配的系统内存,以优化系统。
为什么Luckfox Pico开发板的内核配置文件是luckfox_rv1106_linux_defconfig文件?
因为这项配置是在对应Linux开发板的主板配置文件(BoardConfig)中配置的。
根据幸狐官方文档能够已知Luckfox Pico开发板的主板配置文件(BoardConfig)是位于以下目录:
project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
示例命令如下:
vi project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
打开主板配置文件(BoardConfig)后,按如下修改,然后保存退出:
修改 export RK_BOOTARGS_CMA_SIZE=“66M” 为 export RK_BOOTARGS_CMA_SIZE=“1M”。
末尾新行新增 LF_SUBMODULES_BY=gitee。
修改与移远EC20-CE模块相关的配置
使用 cd 命令切换到SDK源码的根目录下。
键入并执行以下命令,以打开option.c源代码文件,来自定义USB相关配置:
vi sysdrv/source/kernel/drivers/usb/serial/option.c
键入 ? 命令并搜索option_ids[]变量,找到其定义处的代码:
此变量主要定义了USB设备VID和PID信息,以便Linux操作系统识别。
因为使用的是移远的EC20-CE模块,此文件继续往下查看,就能发现已默认集成了移远EC20-CE的VID和PID数据。
但是移远的EC20模块分别有05c6:9215``2c7c:0125
两种不同的VID和VID,为了确保已在上述配置数组中添加了所购买的移远EC20模块的VID和PID,则要先将模块经USB接口连入Windows PC上,并在设备管理器对应设备中的“详情”选项卡查看其VID和PID信息。
此时继续返回option_ids[]配置数组代码,键入 ? 命令搜索QUECTEL_PRODUCT_EC25,结果如下:
这两个宏定义正好与先前option_ids[]配置数组中的如下配置相对应:
上述配置说明option_ids[]配置数组中已添加了我购买的、VID为2c7c的、PID为0125的EC20-CE模块了,无需再添加了。
对于其他不能被直接识别的品牌型号的4G模块也需要做类似的添加。
根据幸狐官方技术人员在论坛回复的一则问题贴可知,SDK是默认支持芯讯通厂商的SIM7600G模块的。再看到option_ids[]数组代码处的开头,是已被幸狐手动添加到了其中的。所以对于其他不能被直接识别的品牌型号的4G模块也需要做类似的添加。
继续在此文件中,键入 ? 命令并搜索option_probe函数,找到其函数实现处的代码:
在Added by Simcom注释的代码块后另起一行,插入以下代码然后保存退出,以使用USBNet驱动程序,并防止因走USB协议的EC20-CE模块与USB转串口的option驱动程序绑定而造成模块工作异常的问题:
#if 1 /* 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
若要适配其他品牌型号的4G模块,也需要做类似的添加。但因模块参数各异,具体添加何代码,则需要参考模块的开发手册等文档。
最终如下:
继续在此文件中,键入 ? 命令并搜索option_1port_device变量,找到其定义处的代码:
在 .resume = usb_wwan_resume, 代码后另起一行,插入以下代码然后保存退出,以添加避免因上位机休眠/唤醒状态的切换而导致USB设备无法从中恢复的的Reset-resume机制:
#if 1 /* Added by Simcom and Quectel */
.reset_resume = usb_wwan_resume,
#endif
最终如下:
继续在此文件中,键入 ? 命令并搜索N_IN_URB宏定义,找到其定义处的代码:
在IN_BUFLEN宏定义后另起一行,插入以下代码然后保存退出,以增加批量输出URB的数量和容量:
#define N_OUT_URB 4 //Increase the quantity of the bulk out URBs to 4.
#define OUT_BUFLEN 4096 //Increase the capacity of the bulk out URBs to 4096.
最终如下:
键入并执行以下命令,以打开usb_wwan.c源代码文件,来向USB网卡添加零包机制:
vi sysdrv/source/kernel/drivers/usb/serial/usb_wwan.c
键入 ? 命令并搜索usb_wwan_setup_urb函数,找到其函数实现处的代码:
在Added by Simcom for Zero Packet注释的代码块后另起一行,插入以下代码然后保存退出,以添加USB协议所需的零包机制:
#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(0x2C7C)) {
urb->transfer_flags |= URB_ZERO_PACKET;
}
}
#endif
最终如下:
使用 cd 命令切换到SDK源码的根目录下。
将附件中“移远EC20” -> “适用于Linux和Android操作系统的移远GobiNet驱动源码 v1.3.0”目录内的所有文件,以及“其他文件”目录中qmi_wwan_q.c和cdc_ncm.c两个源代码文件,均复制到SDK源码的sysdrv/source/kernel/drivers/net/usb目录下。
最终如下:
此操作用于向Linux开发板的嵌入式操作系统中增加GobiNet驱动。
此操作用于向Linux开发板的嵌入式操作系统中增加QMI_WWAN驱动。
使用 cd 命令切换到SDK源码的根目录下。
键入并执行以下命令,以打开USB的构建文件:
vi sysdrv/source/kernel/drivers/net/usb/Makefile
在文件末尾另起一行,插入以下代码,以将GobiNet驱动编译进Linux内核中:
# Quectel
obj-y += GobiNet.o
GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o
继续,在 obj-${CONFIG_USB_NET_QMI_WWAN} += qmi_wwan.o 代码行之前另起一行,插入以下代码,以合并QMI_WWAN驱动的行为。然后保存并退出。
# must insert qmi_wwan_q.o before qmi_wwan.o
obj-${CONFIG_USB_NET_QMI_WWAN} += qmi_wwan_q.o
使用 cd 命令切换到SDK源码的根目录下。
SDK关于内核配置的图形化界面中是缺失直接设置GobiNet的相关选项的,直接修改配置文件不仅复杂繁琐,而且易出错。于是在修改内核配置前,有必要将这项加入到内核配置的图形化界面中。
键入以下命令,以修改SDK内核配置图形化界面的显示配置文件:
vi sysdrv/source/kernel/drivers/net/usb/Kconfig
在文件末尾另起一行,插入以下代码,然后保存退出。以将设置GobiNet的相关选项加入到图形化界面中:
config USB_GOBI_NET
tristate"Gobi USB Net driver for Quectel module"
help
Support Quectelmodule.
A modemmanager with support for GobiNet is recommended.
Tocompile this driver as a module, choose M here: the module will be calledGobiNet.
最终如下:
继续修改与Linux开发板相关的配置
SDK是通过执行其根目录下build.sh脚本的方式图形化配置Linux内核参数的,所以在配置前,要先进行以下操作,以初步构建。
使用 cd 命令切换到SDK源码的根目录下,键入并执行以下命令,以根据指定的Linux开发板型号使用对应的主板配置文件(BoardConfig)初步构建:
./build.sh lunch
注意事项:
在命令执行期间,会提示Linux开发板具体型号和规格的序号选择,视实际情况输入并回车即可。
示例如下:
键入并执行以下命令,以在图形化配置界面中修改内核配置:
./build.sh kernelconfig
依次按下Y键逐个选中以下项来使能对应的功能,然后保存退出:
注意事项:
黑色加粗部分的项,按Y键选中以使能。
列出的项,已选中的保持默认选中状态即可,否则要按Y键选中。
由于SDK中的内核配置图形化程度不完全,还有关于一些4G模块的配置未能直接在图形化配置界面中使能,需要编辑对应Linux开发板型号的内核配置文件依次检查是否有漏掉的项。
使用 cd 命令切换到SDK源码的根目录下。
视具体所用的Linux开发板型号,键入并执行以下命令,以在文本编辑器中修改内核配置:
vi sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_defconfig
※ 为什么Luckfox Pico开发板的内核配置文件是luckfox_rv1106_linux_defconfig文件?
因为这项配置是在对应Linux开发板的主板配置文件(BoardConfig)中配置的。
根据幸狐官方文档能够已知Luckfox Pico开发板的主板配置文件(BoardConfig)是位于以下目录:
project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
查看此文件的内容,其中的RK_KERNEL_DEFCONFIG项,指明了其所用的内核配置文件,即为sysdrv/source/kernel/arch/arm/configs目录下的luckfox_rv1106_linux_defconfig配置文件。
按照以下所列出的键值对配置项,依次检查内核配置文件中是否有漏项,已有则跳过,没有则不全,然后保存退出:
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_WWAN=y=y
CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_NET_QMI_WWAN=y
CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_NET_RNDIS_HOST=y
CONFIG_USB_NET_CDC_NCM=y
CONFIG_USB_NET_CDC_MBIM=y
CONFIG_USB_WDM=y
CONFIG_USB_ACM=y
SDK采用了Buildroot工具+图形化界面配置的方式来管理和构建软件包,在新增软件包后会通过网络进行下载,然后编译至操作系统中。
为了避免编译SDK期间的组件下载失败问题,采用幸狐官方提供的离线版本的软件包,将其解压后覆盖到Buildroot的本地工作缓存目录下。
但在编译SDK前,Buildroot的本地缓存目录是不存在的,故需要先执行以下操作,让其生成对应目录。
使用 cd 命令切换到SDK源码的根目录下。
键入并执行以下命令,以通过编译而生成Buildroot的本地工作目录:
./build.sh buildrootconfig
注意事项:
Buildroot的本地工作目录位于SDK根目录下的sysdrv/source目录中。
Buildroot的本地工作目录中的组件下载缓存目录位于SDK根目录下的sysdrv/source/buildroot/buildroot-2023.02.6/dl目录中。
命令执行前的目录示例如下:
命令执行后的目录示例如下:
使用 cd 命令切换到SDK源码的根目录下,再切换到以下目录:
cd sysdrv/source/buildroot/buildroot-2023.02.6
将附件中“幸狐Linux开发板” -> “Buildroot的离线软件包”目录下的压缩包,上传到虚拟机内SDK源码的以上目录下并解压。
最终如下:
使用 cd 命令切换到SDK源码的根目录下。
键入并执行以下命令,以在图形化配置界面中配置软件包:
./build.sh buildrootconfig
依次在图形化界面中输入“/”符号依次搜索以下所列出的软件包并按Y键使能,然后保存退出:
iftop
iptables
minicom
neofetch
nginx
注意事项:
在保存退出后,注意观察日志输出中是否有报错。若有,要重新执行上述命令,再次进入图形化配置界面,并重新搜索对应软件包是否被成功使能了。
编译Linux开发板的SDK
使用 cd 命令切换到SDK源码的根目录下。
键入并执行以下命令,以全量编译SDK:
./build.sh
编译成功后,会在SDK根目录下的output/image目录下生成系统镜像文件。
烧录系统镜像
将除update.img外的所有系统镜像拷贝到Windows PC本机的任意位置,并使用幸狐官方提供的SocToolKit工具,将其烧写进任意TF卡中。
交叉编译拨号程序
移远官方提供了能快速部署和测试的Connect Manager拨号程序的源代码。若想要在目标开发板上运行,则需要目标开发板SDK所用的gcc编译器参与交叉编译才能实现。
将附件中“移远EC20” -> “适用于Linux和Android操作系统的移远Connect Manager拨号程序源码”目录下的所有文件上传到虚拟机内的任意空目录中。
最终如下:
使用 cd 命令切换到移远Connect Manager拨号程序源码的根目录下。
视实际情况,键入并执行以下命令,以交叉编译源码:
make CROSS_COMPILE=[Linux开发板SDK所用gcc编译器的根目录]
示例命令如下:
make CROSS_COMPILE=/mnt/data/luckfox-pico-main/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf
※ 为什么Luckfox Pico开发板的交叉编译器存储位置是在以上位置?
因为这项配置是在对应Linux开发板的主板配置文件(BoardConfig)中配置的。
根据幸狐官方文档能够已知Luckfox Pico开发板的主板配置文件(BoardConfig)是位于以下目录:
project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
查看此文件的内容,其中的RK_TOOLCHAIN_CROSS项,指明了其所用的交叉编译器的目录位于tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf目录中。
编译成功后,在当前目录下会生成一个名为quectel-CM的、二进制的、可执行的Linux应用程序。将其复制到Windows PC以在后续过程中使用。
Linux开发板上电开机
串口登录Linux开发板
参见:参考资料 – 官方文档。
将拨号程序上传到Linux开发板
将在交叉编译拨号程序步骤中编译好的、名为quectel-CM的、二进制的、可执行的Linux应用程序复制到Linux开发板的/usr/bin目录下,并为其赋予u+x权限。
配置Linux开发板
基础配置
在Linux开发板的任意位置键入并执行以下命令,以在图形化配置界面中配置Linux开发板:
luckfox-config
依次导航并设置USB的工作模式为host,退出菜单后键入并执行reboot命令,以重启Linux开发板来应用设置:
配置与调测移远EC20-CE模块
在Linux开发板上电的情况下,插拔4G模块,并观察lsusb -t命令的日志输出。能够发现在设备插拔前后,USB 4G设备是被成功检测到的:
观察dmesg命令的日志输出,同样也能发现:
键入并执行以下命令,确认USB串口设备是否被操作系统正常检测到:
ls /dev/ttyUSB*
输出结果示例如下:
表明EC20-CE模块的4个串口均被操作系统正常识别了。
键入并执行以下命令,进入minicom串口终端,以配置移远EC20-CE模块:
minicom -D /dev/ttyUSB2
继续,在终端中键入并执行以下AT命令,以切换移远EC-20模块的网卡接口类型为RmNet:
AT+QCFG="usbnet",0
成功显示OK后,按下Ctrl+A组合键和x键并在弹出的退出确认窗口中选择Yes,以退出minicom串口终端。
键入并执行reboot命令,以重启Linux开发板。
重启后,键入并执行以下命令,查看是否存在一个名为/dev/cdc-wdmX的设备资源文件:
ls /dev/cdc*
输出结果示例如下:
观察dmesg命令的日志输出,同样也能发现:
表明QMI_WWAN驱动开启成功,可以进行拨号操作了。
配置与调测拨号上网
在Linux开发板的任意位置键入并执行以下命令,以在后台拨号:
quectel-CM &
拨号结果示例如下:
此时也可以成功ping通外网IP和域名了。
配置与调测以太网卡
键入并执行以下命令,查看当前操作系统已识别并加载的网卡信息:
ip add
输出结果示例如下:
其中,eth0网卡即为以太网卡。
键入并执行以下命令,以将以太网卡的IP设为与华为AP6050DN无线接入点在同一网段:
ifconfig [ip add命令显示的以太网卡的网卡名] [目标IP地址]
示例命令如下:
ifconfig eth0 192.168.137.1
因为在华为AP6050DN无线接入点中配置的静态IP地址为192.168.137.2、网关为192.168.137.1,所以需要将Linux开发板流量出口网卡的IP修改为与无线接入点同一网段,且要为网关的IP,这样才能将移远EC20-CE模块的移动数据流量通过后续NAT转发的方式给到无线接入点。
配置与调测NAT转发
键入并执行以下命令,查看当前操作系统的规则:
iptables -t nat -L -n -v
输出结果示例如下:
注意事项:
正常情况下应如上图所示,没有任何规则。
每次重启后,规则都会丢失,需要重新配置。
键入并执行以下命令,以开启IPv4网络下的网络转发:
sysctl net.ipv4.ip_forward=1
键入并执行以下命令,以将wwan0网卡的流量转发给eth0网卡:
iptables -t nat -A POSTROUTING -o wwan0 -j MASQUERADE
再次键入并执行以下命令,查看当前操作系统的规则:
iptables -t nat -L -n -v
输出结果示例如下:
可以看到多出一个wwan0网卡的转发规则。
此时无线接入点也能够正常访问外网了。
参考资料
官方文档
【幸狐官方文档】Luckfox Pico – Luckfox Pico RV1103 – Luckfox Pico Plus Mini – SDK 环境部署(X86_64平台)。
【幸狐官方论坛】luckfox ultra w 4G网卡 移远EC200。
Quectel_UMTS_LTE_5G_Linux_USB_Driver_用户指导_V1.1.pdf。
网站论坛
核心板移植移远4G模块EC20过程记录1-Gobinet。
适配移远RG200U-5G模块。
4G模块 EC20 R2.0 USB Serial/GobiNet/QMI WWAN 驱动移植过程。
V3S挖坑EC20。
移植iptables至嵌入式设备。
linux下4g模块共享网络给内网。
Linux-将usb 4G网卡的网络共享给多个有线网卡。
ec20正常创建ecm网络后无法连接外网。
linux下EC20 4G模块驱动移植。
移远RM500U-CN模块直连嵌入式ubuntu实现拨号上网。
驱动程序开发:基于EC20 4G模块自动拨号联网的两种方式(GobiNet工具拨号和PPP工具拨号)。
移远5G模块移植。
minicom的使用,发送AT指令。
修改移远提供的GobiNet、quectel-CM源码,使其支持有方N720 4G模块。
EC600N-CN 的Linux驱动。
4G模块生成wwan0网卡,可以连接4g信号,不能自动生成默认网关,不能访问外网。
暂无评论内容