嵌入式linux/鸿蒙开发板(IMX6ULL)开发流程(二)

文章目录

4.使用USB网卡直连配置网络

4.1 连接方式介绍

4.1.1 硬件资源列表

 百问网imx6ull pro开发板一套
 超六类RJ45网线至少1M长(默认配有)
 直连USB 有线网卡一个(目前测试多款网卡芯片 发现只有此款可以满足我们的日常使用需求)。

4.1.2 连接方式

请参考下图所示,连接独家直USB网卡USB端连接至电脑USB接口,另一端网卡接口插入配套的网线,网线另一端接入如下图所示的开发板网卡位置(只能接下图所示网卡)其它网卡网卡直连没法使用所有功能,连接成功后,请打开电脑启用开发板电源,参考下面 系统IP配置章节逐一配置IP地址来实现三者互通。

在这里插入图片描述

4.2 系统IP配置

4.2.1 windows配置

参考上图连接独家直连 USB网卡至电脑以后,会在设备管理器–>网络适配器下新增一个Realtek USB FE Family Controller 的网络设备(不同的电脑最后的几位字符可能不太一样),确认已经有此设备后可以继续执行下面步骤进行配置IP地址和网段等操作。
在这里插入图片描述

确认好 USB直连网卡名称后,参考下图打开控制面板–>网络和共享中心–>更改适配器设置 准备对独家直连 USB网卡进行IP配置。
在这里插入图片描述

进入网络适配器页面后,参考下图 鼠标左键点击选中 直连 USB网卡设备,选中设备后鼠标右键,在弹出的选项中点击属性按钮,之后在弹出新的属性对话框内 点击 Internet协议版本4(TCP/IPV4) 继续在新弹出的对话框参考下图图示 选中 使用下面的IP地址 输入 IP地址 192.168.5.10 子网掩码 255.255.255.0 默认网关 192.168.5.1 设置完成后,点击确定,会返回到以太网属性界面,继续点击 确定 表示windows下直连 USB网卡的IP已经配置完成。

在这里插入图片描述

4.2.2 常见问题

设备管理器里没有加载出来 Realtek USB FE Family Controller 网络设备
检查vmware是否默认将此设备连接到虚拟机,或提示选择连接到哪里

如果系统没有弹出上图所示窗口,请参考下图所示来查看此 usb网卡设备是否默认已经连接到了ubuntu,如果已连接 请参考下图所示 点击断开与主机的连接。

如果没有出现上述两种情况 但是usb网卡设备 在windows设备管理–>网络适配器内依旧没有新增设备,可能是由于驱动问题,请参考下述步骤检查并安装相应的设备驱动。

检查驱动是否正常安装
由于此usb网卡设备驱动是免驱设备,正常情况系统会自动装载此设备驱动,如没有自动安装驱动,请使用驱动精灵/驱动人生等工具自动安装。

4.2.3 vmware配置

确认windows 直连 USB网卡配置成功后,请参考下图配置vmware 虚拟网络编辑器,参考下图在开始菜单搜索 虚拟网络编辑器 搜索出来后点击Open 打开虚拟网络编辑器 在弹出的 虚拟网络编辑器页面,点击 更改设置 来修改网络配置设置桥接默认连接到 直连 USB网卡。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

参考下图所示 点击 桥接模式 在桥接模式下的 已桥接至下拉框 点击 会显示出很多个网卡设备,我们只需要点击选中为 直连 USB网卡名称为Realtek USB FE Family Controller 的网络设备即可,选中后,点击确定即可完成vmware配置。
在这里插入图片描述

4.2.4 ubuntu配置

执行完上述配置直连网卡作为默认的桥接设备后,开打ubuntu虚拟机,在虚拟机关机状态下,点击 编辑虚拟机设置 在弹出的虚拟机设置对话框,点击 网络适配器 设置为如下图所示的桥接默认,设置成功后点击确定,表示已经设置完成,可以 开启虚拟机。
在这里插入图片描述

配置网络适配器为桥接模式后,需要进入ubuntu手动设置默认网卡的IP地址为静态IP,参考下图所示,打开 系统 Setting。
在这里插入图片描述

打开Setting后,在左侧找到 Network 选择栏,点击显示详细内容,之后点击 设置 图标,在弹出的设置界面内,点击 IPV4 切换到 IPV4 设置页面,之后继续点击 Manual 表示自己设置IP地址,在Addresses下的输入框分别填入如下所示的内容,其中 Address写入192.168.5.11 Netmask 写入 255.225.225.0 Gateway 写入 192.168.5.1,填写完成后点击 Apply 应用此设置,之后会弹出一个对话框提示输入 root用户的密码,请参考下图所示。
在这里插入图片描述

在弹出的授权请求对话框 里面输入 root用户的密码 (如果未设置root用户密码 请在ubuntu终端下使用 sudo passwd root命令来设置root用户密码),输入密码后点击 Authenticate 授权,到这里就表示IP地址已经设置成功,之后我们可以在ubuntu终端下输入 ifconfig 命令来查看IP地址是否设置正确。
在这里插入图片描述

4.2.5 开发板设置IP地址

每次开机手动设置IP地址
开发板终端下执行 ifconfig eth0 192.168.5.9 即可设置eth0网卡IP地址为192.168.5.9,设置成功后可以使用 ifconfig命令来查看已设置的IP地址,参考如下命令。
在这里插入图片描述

设置IP为固定静态IP(开机不变) 设置eth0为静态IP地址, 开发板/etc/network/目录下对interfaces文件进行修改 。

[root@100ask:~]# vi /etc/network/interfaces

修改并为如下内容,执行 :wq 保存并退出,执行/etc/init.d/S40network restart 重启网络服务。

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
 address 192.168.5.9
 netmask 255.255.255.0
 gateway 192.168.5.1

在这里插入图片描述

重启后使用ifconfig查看IP地址是否已经自动配置。
在这里插入图片描述

4.3 三者互ping验证

设置完上述IP地址后,知道了 windows ip 192.168.5.10 ubuntu ip 192.168.5.11 开发板ip 192.168.5.9 接下来验证三者是否可以互相网络通信。

4.3.1 windows ping ubuntu

在windows下使用命令提示符,输入 ping 192.168.5.11去 ping ubuntu IP地址,看是否可以接收到数据,同样的 ubuntu下在终端里输入 ping 192.168.5.10 来查看是否有数据返回,正常情况如下图所示,如果你在测试时发现只能单向Ping 通请检查windows防火墙是否全部关闭。
在这里插入图片描述

4.3.2 开发板ping windows 和 ubuntu

如下所示在开发板手动设置 ip地址为192.168.5.9 之后使用ping命令来验证是否可以ping通 ubuntu和windows主机,其中ping windows使用ping 192.168.5.10命令 ping ubuntu使用ping 192.168.5.11命令 看是否有返回值,正确情况如下图所示。
在这里插入图片描述

4.3.3 windows 和 ubuntu ping 开发板

如下图所示为windwos和ubuntu去ping 开发板IP,在windows下使用 命令提示符,执行 ping 192.168.5.9 去ping开发板,来确认是否可以和开发板网络通信,在ubuntu使用终端,执行ping 192.168.5.9去ping开发板来确认是否可以和开发板网络通信。

在这里插入图片描述

4.4 开发板使用网络服务

4.4.1 文件系统内使用nfs挂载ubuntu目录

确认windows ubuntu 开发板三者可以互相ping通以后,ubuntu下已经配置好了nfs目录及环境,可以在开发板上执行以下命令来挂载ubuntu的nfs目录到开发板/mnt目录下,挂载成功后使用df -h命令查看所有挂载。

[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt

在这里插入图片描述

4.4.2 开发板使用mobaxterm ssh登录开发板

确认windows ubuntu 开发板三者可以互相ping通以后,可以使用moabaxteram SSH会话远程登录开发板,操作步骤请参考下图所示。

在这里插入图片描述

4.5 其它可选配置

4.5.1 配置Ubuntu连接网络

在某些情况下 学员可能需要保证ubuntu windows 和开发板之间可以网络通信用来传输文件或者调试,又想让ubuntu可以连接网络进行安装某些在线的软件包,此时我们需要在ubuntu上再新增一个网卡设备并设置为NAT方式用于共享主机Internet网络进行上网。
首先在虚拟机关机状态下,点击 编辑虚拟机设置 在虚拟机设置里新增一个网络适配器。

进入虚拟机设置后,点击 添加–> 网络适配器–>下一步 ,之后再点击完成,即可。
在这里插入图片描述在这里插入图片描述

添加完成 网络适配器后,会在虚拟机设置里面 出现一个 网络适配器2设备,之后我们需要设置网络连接方式 为 NAT模式 设置成功后,点击确定即可返回虚拟机启动页面,此时启动虚拟机即可。
在这里插入图片描述

启动虚拟机并进入虚拟机后,可以在终端下执行ifconfig命令查看当前网卡信息,会发现多出来一个网卡设备,其中一个是我们之前配置直连网卡桥接所用的网卡,另一个ens38(你的可能不是这个名称)已经自动配置了NAT网段的IP(如没有自动设置NAT网卡IP则在ubuntu终端下执行 sudo dhclient 来自动获取IP),之后我们可以来使用ping 来验证是否可以上网和之前的直连网卡直连是否依旧可用,使用ping qq.com 来验证是否可以连接internet网络,使用ping 192.168.5.10来验证原直连网卡直连是否有效。

在这里插入图片描述

4.5.2 常见问题1 虚拟机可以上网但是无法ping通windows和开发板

请在开始菜单 打开 虚拟网络编辑器,参考是否和下图设置一致,由于192.168.2.0/24网段已经被用于直连网卡直连所用,所以NAT模式下不能为 192.168.5.0/24网段。
在这里插入图片描述

4.5.3 配置开发板连接网路

我们的开发板一般有两个网口,其中一个被我们用来和直连 usb网卡进行连接作为调试使用,但是另一个网络可以用来进行设置上网,如果需要另一个网口上网,我们可以把网线一段接至开发板 另一端接至可以上网的路由器,之后在开发版文件系统内执行 udhcpc -i eth1 等待获取IP成功即可。

4.5.4 uboot下设置IP挂载NFS网络文件系统启动系统

问: 为什么要在开发板uboot下设置IP挂载NFS网络文件系统启动系统?
答: 在某些场景下,需要多次调试内核,存储驱动或文件系统等某个比较复杂的问题,每次通过手动拷贝重启的方式太过于繁琐缓慢,所以就通过网络方式下载到内存直接运行,文件系统也存在于ubuntu端,可以快速的去调试或定位问题。
在确认windows ubuntu 开发板三者可以互相ping通并配置好 uboot 挂载所需的nfs 根文件系统 TFTP下载所需的内核和设备树后,可以使用如下命令进行下载启动并自动挂载nfs文件系统,其中 /home/book/nfs_rootfs 为ubuntu下开发板所需的文件系统所在目录,100ask_imx6ull-14x14.dtb 为设备树文件,zImage为内核镜像文件。

setenv serverip 192.168.5.11
setenv ipaddr 192.168.5.9
setenv gatewayip 192.168.5.1
tftpboot 0x83000000 100ask_imx6ull-14x14.dtb; 
tftpboot 0x80800000 zImage; 
setenv bootargs root=/dev/nfs nfsroot=192.168.5.11:/home/book/nfs_rootfs,vers=3 rw 			t		tip=192.168.5.9:192.168.5.11:192.168.5.1:255.255.255.0:ask:eth0:off:192.168.5.1; 
bootz 0x80800000 - 0x83000000 

执行上述命令后开发板会自动获取内核和设备树文件到开发板内存内,并配置文件系统参数,启动内核并自动挂载NFS文件系统。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

如果您在文件系统启动过程中一直卡死在udhcpc获取IP处,请参考下图删除ubuntu nfs imx6ull根文件系统内 /etc/init.d目录下的 S4开头的文件,(注意是解压到nfs目录的imx6ull根文件系统,不是ubuntu的根文件系统)。

运行内核并挂载nfs文件系统成功后,可以在开发板串口终端下执行 cat /pro/mounts 来查看根目录所在位置。

4.6 使用路由器配置网络(待更新)

5.烧写整个系统或更新部分系统

百问网开发了一款烧写软件:100ask_imx6ull_flashing_tool,它的界面如下:
在这里插入图片描述

使用这软件,只需要一条USB线连接电脑和开发板USB OTG口,只需要点击一个按钮就可以实现某项烧写功能。
100ask_imx6ull_flashing_tool是一个GUI前端,它调用NXP官方的烧写工具uuu:Universal Update Utility(又名mfgtools 3.0)。
市面上的imx6ull开发板多是使用mfgtools 2.0来烧写,效率不高,脚本复杂;uuu有所改进,但是烧写效率还是不高。
我们做了很多改进,烧写更方便、效率更高。使用mfgtools烧写500M的映象文件到EMMC,耗时5分钟;而使用100ask_imx6ull_flashing_tool只需要1分钟。

本章会首先介绍100ask_imx6ull_flashing_tool的使用,后面也会介绍常规的烧写方法。

5.1 100ASK_IMX6ULL启动开关

MINI EMMC版
百问网 IMX6ULL EMMC版支持USB、EMMC、SD/TF卡三种启动方式。使用后2种启动方式之前,需要先在EMMC或SD/TF卡上烧写系统。
板子背后画有一个表格,表示这3种方式如何设置。表格如下:
在这里插入图片描述
这3种启动方式的设置示意图如下:
在这里插入图片描述

其中的USB启动模式主要用来烧写系统。
注意:设置为USB启动时,不能先插上SD/TF卡。
要在USB启动模式下烧写SD/TF卡时,需要先上电再插卡,先上电再插卡,先上电再插卡,。

5.2 在Windows使用USB烧写工具

NXP公司给IMX6ULL提供了烧写工具:mfgtools。注意nxp烧写工具不支持烧写imx6ull mini emmc版和imx6ull mini nand版,它的使用界面如下:
在这里插入图片描述

操作很简单,一键烧写整个映象文件。
但是,缺点也很多:
a. 不能单独烧写bootloader、内核、设备树
或者说,可以实现这些功能,但是需要你去修改xml配置文件,对初学者不友善,对老手也显得麻烦。
b. 烧写速度慢
烧写500M的系统,耗时5分钟(我们的工具可以在1分钟内烧完)。

基于上述缺点,我们开发了新的烧写工具100ask imx6ull flashing tool,并且完全开源。它有如下特点:
a. 可以烧写整个系统,也可以分开烧写bootloader、内核、设备树
b. 可以上传用户文件到开发板系统中任意目录里
c. 烧写速度是原厂工具的5倍
d. 支持所有厂家的开发板烧写,注意:不只是支持100ASK_IMX6ULL,还支持其他厂家的IMX6ULL开发板。

从网盘下载工具后,在“01_Tools(工具)/100ask_imx6ull烧写工具”目录下双击运行“100ask_imx6ull_flashing_tool.exe”。
它有“基础版”、“专业版”两个页面。

在这里插入图片描述

“基础版”是专为100ASK_IMX6ULL设计的,点击一下即可完成某项烧写。
“专业版”功能更强大,特别是它可以上传文件到某个分区、某个目录。有些厂家的开发板,zImage和设备树是在第1个分区里的,而100ASK_IMX6ULL的zImage和设备树是在第2个分区里,所以这些厂家的开发板就无法使用基础版来烧写,需要使用专业版,指定分区、指定分区格式、指定路径,然后再上传文件。
注意:开发板必须设置为USB模式,如果要用SD/TF卡,必须先上电再插卡;
不能先插卡再上电,不能先插卡再上电,不能先插卡再上电!

5.2.1 烧写工具目录详解

在100ASK_IMX6ULL的配套资料中,有文件:“01_Tools (工具)/100ask_imx6ull烧写工具.tar.bz2”,把它解压后可得如下目录:
在这里插入图片描述

要留意的是files目录下的文件,各文件的作用在上图中列出来了,文件名不能改变,要更新某文件时需要覆盖旧文件。
这个烧写工具不断更新,现在是V3.0版本,增加了Nand Flash的烧写功能。上述截图中files目录下内容更丰富了,请见下表。
如果要更新某个文件,把新文件放进去覆盖同名文件即可。
在这里插入图片描述

5.2.2 连接USB OTG线

接线、设置USB启动的方式如下:
注意:USB串口线可接可不接,接上只是为了观察烧写过程。
注意:设置为USB启动时,先不要接TF卡
在这里插入图片描述

5.2.3 安装IMX6ULL的USB驱动程序

通过USB下载或是烧写程序时,需要把开发板的OTG口用USB线连接到电脑。一般都会自动安装驱动,烧写软件的绿灯不亮时,则很有可能是驱动程序没有安装好,这时再来看本节文档。

5.2.3.1 VMWARE可能会截取USB设备导致烧写失败

如果你运行了VMWARE,它会截取USB设备,可能会有如下提示:
在这里插入图片描述
要选择“连接到主机”,勾选“记住我的选择,以后不再询问”。
也许你不慎点错了“连接到虚拟机”,那也没关系,在VMWARE的菜单中把“Freescale SE Blank 6ULL”或“Netchip USB download gadget”断开连接,如下图所示:

在这里插入图片描述

5.2.3.2 USB驱动没有自动安装

通过USB下载或是烧写程序时,需要把开发板的OTG口用USB线连接到电脑。IMX6ULL开发板会通过这一个OTG口,模拟出2个USB设备(先后模拟,不是同时):“Freescale SE Blank 6ULL”、“USB download gadget”。一般会自动安装好驱动程序,如果驱动程序没安装好,你可以去下载“zadig”来安装驱动。
安装第1个驱动:只要开发板设为USB启动(不要插SD/TF卡)并上电,电脑就会识别出“Freescale SE Blank 6ULL”设备,一般都会自动给它安装驱动程序。
如果没有自动安装好驱动程序(“设备已连接”绿灯没亮),要使用zadig安装libusb-win32驱动。
先去请点击-官网下载zadig并运行,然后参考下图安装驱动程序:
在这里插入图片描述

安装第2个驱动:当烧写工具的“设备已连接”绿灯亮起,就可以在“专业版”点击“运行”按钮,这时电脑会识别出“USB download gadget”设备,一般都会自动给它安装驱动程序,如下图:

在这里插入图片描述

如果没有自动安装好驱动程序(“固件已运行”绿灯没亮),先去https://zadig.akeo.ie/下载zadig并运行,然后参考下图安装驱动程序:

在这里插入图片描述

如果一切正常,烧写工具的2个绿灯都会亮,如下:
在这里插入图片描述

这就表示所有驱动都安装好了,可以重启开发板,使用后面2节的方法来烧写。

5.2.4 基础版烧写方法

要更新某个文件,就把它复制到烧写工具的files目录,比如zImage、100ask_imx6ull-14x14.dtb。
举例:要更新内核,先把新的zImage覆盖files目录下的zImage,然后接线,上电,选择设备,点击“更新内核”即可。
板子复位或重新上电后,在APP里操作即可,一个图就可以列清楚所有步骤:
在这里插入图片描述

当开发板设为USB模式,上图的烧写工具中“设备已连接”的绿灯亮起,就可以通过按钮一键烧写了,各按钮作用如下:

在这里插入图片描述

5.2.5 专业版烧写方法

专业版的强大在于烧写文件时可以选择任意文件,上传文件时可以指定分区、分区格式、目标路径。用法也很简单,一图足以说明:
在这里插入图片描述
有些开发板厂家把内核zImage、设备树放在第1个分区里,它通常是FAT分区。那么可以使用专业版来更新内核、更新设备树。
比如:
在这里插入图片描述

几乎所有的开发板的第2个分区都是EXT4格式,我们可以上传文件到它的任意目录下,比如:
在这里插入图片描述

5.3 老方法:使用win32diskimage通过读卡器烧写SD/TF卡

安装映象烧写工具win32diskimager后,插卡到电脑上,直接烧写即可。

  1. 安装软件
    在“网盘的配套的资料\01_Tools (开发工具含ubuntu镜像等)\ 【Windows】SD卡IMG系统镜像烧写工具”中解压得到win32diskimager-1.0.0-install.exe软件,以后运行它时要“以管理员身份运行”。
  2. 把SD/TF卡接入读卡器,读卡器插到电脑上
  3. 烧写映像文件
    “以管理员身份运行”win32diskimager,如下图选择SD卡、选择映像文件sdcard.img,然后点击“写入”,操作步骤如下图所示:
    在这里插入图片描述

上图中各序号含义为:

  1. 选择SD卡
  2. 选择映象文件,比如sdcard_20200211.img
  3. 点击“写入”
  4. 确定要写入。

烧写成功后,弹出对话框“写入成功”,如下图:
在这里插入图片描述

此时点击OK,拔下SD卡,将启动开关拨到SD卡处,上电启动开发板。

6.安装软件及虚拟机上开发示例

6.1 安装Windows软件

有如下软件:
软件名 说明
vmware 虚拟机软件,安装时需要用到管理员权限,详细的安装过程见后文
Source insight 阅读、编写源码的工具,即装即用;推荐初学者使用
Visual Studio Code 阅读、编写源码的工具,需要进行很多配置;不推荐初学者使用
MobaXterm 串口工具、远程登录工具
Filezilla 文件传输工具,在Windows和Ubuntu之间传输文件
Notepad++ 文本编辑工具,比记事本好用

注意:Visual Studio Code的配置比较麻烦,建议初学者使用Source insight来阅读、编写源码。

6.2 安装Ubuntu软件

确保Ubuntu能上网之后,使用下面命令一键配置/初始化开发环境(其实就是安装tftp,nfs,vim等软件,此脚本只支持Ubuntu-16.04 /Ubuntu-18.04)。
注意:为了方便大家复制,这些命令写成了多行,你要把它们复制到记事本,合并成一行,注意空格:

book@100ask: ~ $ wget --no-check-certificate -O Configuring_ubuntu.sh
https://weidongshan.coding.net/p/DevelopmentEnvConf/d/DevelopmentEnvConf/git/raw/master/Configuring_ubuntu.sh && 
sudo chmod +x Configuring_ubuntu.sh && 
sudo ./Configuring_ubuntu.sh

上述命令是下载脚本,给它添加可执行权限,运行它。
按提示输入book密码123456和选择对应的系统,如下图所示:
在这里插入图片描述在这里插入图片描述

注意:如果Ubuntu无法上网,请参考前面《网络问题》进行设置。
如果执行该命令出现如下错误:
在这里插入图片描述

可以先执行“sudo apt-get update”,再重新执行前面的命令。

6.3 使用MobaXterm远程登录Ubuntu

安装、运行MobaXterm,如下建立Session:
在这里插入图片描述

按上图操作后,在MobaXterm左侧就可以看到这项,双击它就可以登录Ubuntu,然后就可以执行各种Linux命令了:
在这里插入图片描述

注意: IP地址一定要是ubuntu桥接模式的网卡IP地址。

6.4 使用FileZilla在Windows和Ubuntu之间传文件

使用MobaXterm及可以ssh登录又可以传输文件,不过Mobaxterm在传输文件时使用效率上没有 FileZilla高,所以我们推荐Windows和Ubuntu互相传输文件用FileZilla。
双击打开FileZilla后,按下图操作:
在这里插入图片描述

如下图为示例其中 Ubuntu桥接网卡IP地址是192.168.5.11 用户名book 密码123456 访问端口22 。
在这里插入图片描述

在Filezilla中,左边是Windows文件,右边是Ubuntu的文件,如下图:

在这里插入图片描述

注意:如果不是使用NAT,则需要输入Ubuntu的IP。

6.4 编程示例:Ubuntu上的Hello程序

本节演示如何在Windows编写程序、上传到Ubuntu,在Ubuntu中编译、执行。只涉及一个简单的Hello程序,使用命令行编译,不涉及Makefile等知识,这些知识在后面的应用基础中讲解。

6.4.1 用Source Insight编写hello.c

启动Source Insight,点击“File”->“New”,新建文件:
在这里插入图片描述

接下来编写代码,保存文件,如下图所示:
在这里插入图片描述

hello.c的源码如下:

#include <stdio.h>

int main(int argc, char **argv)
{
    
    
	printf("hello, world!\n");
	return 0;
}

6.4.2 使用FileZilla上传源码

如下图操作:
在这里插入图片描述

6.4.3 使用MobaXterm远程登录Ubuntu

你当然可以直接在Ubuntu桌面启动终端,但是日常工作中使用MobaXterm会更方便。请参考前面《5.3 使用MobaXterm远程登录Ubuntu》。

6.4.4 编译、运行程序

如下图操作,对于gcc命令的用法在后面讲到应用开发基础时再细讲,这里只是体验一下:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45840087/article/details/121647860