STM32MP157A之U-boot移植

(一)U-boot移植步骤

1.1》导入源码

1)打开ubuntu,打开终端(ctrl+alt+T),在用户目录下建立如下目录:
linux@ubuntu:~$ mkdir fs_mp157a
linux@ubuntu:~$ cd fs_mp157a/
linux@ubuntu:~/fs_mp157a$ mkdir kernel drivers

fs_mp157a-----stm32mp157驱动开发总目录
kernel -----存放系统所需文件
drivers -----驱动模块文件

2)将系统源码en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz放入ubuntu的(~/fs_mp157a/kernel)目录下,系统源码在老师提供的资料中(E:\春\系统移植\系统移植工具\linux内核源码\)。
大家可以用samba,也可以选择其他方式,要达到的效果如下图:

3)解压系统源码
linux@ubuntu:~/fs_mp157a/kernel$ tar -xvf en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz
4)进入u-boot源码目录
linux@ubuntu:cd
cd fsmp157a/kernel/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-2020.01-r0

5)解压u-boot源码(u-boot-stm32mp-2020.01-r0.tar.gz)
linux@ubuntu:~/fs_mp157a/kernel/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-2020.01-r0
$ tar -xvf u-boot-stm32mp-2020.01-r0.tar.gz

6)进入解压完成后得到 u-boot-stm32mp-2020.01 目录
linux@ubuntu:~/fs_mp157a/kernel/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-2020.01-r0
$ cd u-boot-stm32mp-2020.01/

(注意:老师接下来的操作都在此目录下:u-boot-stm32mp-2020.01/)
7)将 ST 官方补丁文件打到 u-boot 源码中,在命令行输入以下指令:
for p in ls -1 ../*.patch; do patch -p1 < $p; done

1.2》建立自己板子的平台

1)导入交叉编译器,执行以下两条指令:(如果没有安装交叉编译器,先参考交叉编译器安装手册,本文档第四部分)
source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
$CC --version

2)在官方默认的配置文件夹中,添加自己板子的配置文件(将st的基础板的配置文件拷贝出来,改个名字,变成我们自己的,再在这个文件中添加和基础配置不同内容)
cp configs/stm32mp15_basic_defconfig configs/stm32mp15_fsmp1a_basic_defconfig
3)添加自己板子的设备树文件
cp arch/arm/dts/stm32mp15xx-dkx.dtsi arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
cp arch/arm/dts/stm32mp157a-dk1.dts arch/arm/dts/stm32mp157a-fsmp1a.dts
cp arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi arch/arm/dts/stm32mp157a-fsmp1a-u-boot.dtsi
4)修改设备树文件,打开arch/arm/dts/stm32mp157a-fsmp1a.dts
code arch/arm/dts/stm32mp157a-fsmp1a.dts

将#include “stm32mp15xx-dkx.dtsi” 修改为 #include “stm32mp15xx-fsmp1x.dtsi”

5)修改设备树的编译文件 arch/arm/dts/Makefile
code arch/arm/dts/Makefile
在 stm32mp157a-dk1.dtb \ 下添加 stm32mp157a-fsmp1a.dtb \ (如果没有添加,将不会生成设备树执行文件)

6)使用新的u-boot配置文件来编译u-boot
make stm32mp15_fsmp1a_basic_defconfig

7)后续咱们可以使用图形化的界面来配置u-boot。当然现在没有功能添加可以不配置。(如果下面指令执行不了,你肯定一边是ubuntu,一边是步骤,把ubuntu放大,就可以执行了。还有一种情况就是分辨率不够,调整ubuntu的分辨率。)
make menuconfig

8)编译u-boot源码--------后续只要改动了源码和设备树,都必须重新便宜烧录,指令都是下面这个
make DEVICE_TREE=stm32mp157a-fsmp1a all

9)编译完成后会得到如下文件:ls指令查看一下

1.3》TF卡分区和固件烧录

1)要对 TF 卡进行烧录,需要先将 TF 接入到 ubuntu 系统中。(读卡器+SD,插入电脑USB)

2)查看分区情况,输入指令
ls /dev/sd*

3)如果和上图一样只有一个分区 /dev/sdb1,首先删除原有分区,执行下面指令:
sudo parted -s /dev/sdb mklabel msdos

输入linux密码,回车。
4)如果显示如下内容,则表示设备已经被挂载,需要卸载掉设备再删除分区。

umount /dev/sdb1(用mount可以查看哪个设备挂载,就卸载哪个,不一定是sdb1)

5)卸载完成后重新执行删除分区命令
sudo parted -s /dev/sdb mklabel msdos

6)对 tf 进行重新分区,执行以下指令:
sudo sgdisk --resize-table=128 -a 1 -n 1:34:545 -c 1:fsbl1 -n 2:546:1057 -c 2:fsbl2 -n 3:1058:5153 -c 3:ssbl -n 4:5154:136225 -c 4:bootfs -n 5:136226 -c 5:rootfs -A 4:set:2 -p /dev/sdb -g

7)再次查看分区
ls /dev/sd*

8)分区已完成,执行如下指令烧写 u-boot:(将刚刚编译生成的u-boot-spl.stm32和u-boot.img,放入SD卡)
sudo dd if=u-boot-spl.stm32 of=/dev/sdb1 conv=fdatasync
sudo dd if=u-boot-spl.stm32 of=/dev/sdb2 conv=fdatasync
sudo dd if=u-boot.img of=/dev/sdb3 conv=fdatasync
9)启动开发板。
首先插入刚刚烧录好的SD卡到开发板。

将板子调到SD卡启动

然后安装Xshell软件,参考安装Xshell手册。
连接调试工具,下面这个工具,一端连接在开发板,一端接在自己的电脑,接上去后灯闪烁,后常亮。

在电脑上,打开设备管理器,查看端口。

打开Xshell,点击新建:

10)将电源线接入开发板。

错误提示电源初始化错误,需重新调整电源相关配置,由于官方参考板 DK1 采用电源管理芯片做电源管理,而 FS-MP1A 采用分离电路作为电源管理,需要将文件中原有电源管理芯片相关内容去掉,增加上固定电源相关内容。

1.4》调整设备树电源配置

1)去掉原有电源管理内容----DK1 参考板电源管理芯片挂在 I2C4 上,而 FS-MP1A 并未使用 I2C4 总线,所以直接将I2C4 相关容完全删除即可。
修改 arch/arm/dts/stm32mp15xx-fsmp1x.dtsi 文件,执行以下指令:
code arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
将文件中 i2c4 节点相关内容整体删除,删除内容如下:(不要删除多了,也不要少了,要不多不少)
&i2c4 {
pinctrl-names = “default”, “sleep”;
pinctrl-0 = <&i2c4_pins_a>;
pinctrl-1 = <&i2c4_pins_sleep_a>;
i2c-scl-rising-time-ns = <185>;
i2c-scl-falling-time-ns = <20>;
clock-frequency = <400000>;
status = “disabled”;
/内容太长此处省略/
watchdog {
compatible = “st,stpmic1-wdt”;
status = “disabled”;
};
};
};
2)修改 arch/arm/dts/stm32mp15xx-fsmp1x.dtsi 文件:
code arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
删除如下内容:
&cpu0{
cpu-supply = <&vddcore>;
};
&cpu1{
cpu-supply = <&vddcore>;
};

3)修改 arch/arm/dts/stm32mp157a-fsmp1a-u-boot.dtsi 文件:
code arch/arm/dts/stm32mp157a-fsmp1a-u-boot.dtsi
删除如下内容:
&pmic {
u-boot,dm-pre-reloc;
};
4)由于官方参考板 DK1 I2C4 总线上有个 USB type C 的控制器,上文删除 I2C4 节点的同时将 type C 控制器的描述删除,所以需要将引用 type C 控制器的内容删掉。修改 arch/arm/dts/stm32mp15xx-fsmp1x.dtsi 文件:
code arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
删除红色部分内容:(红色部分,别全删除了啊)
&usbotg_hs {
phys = <&usbphyc_port1 0>;
phy-names = “usb2-phy”;
usb-role-switch;
status = “okay”;
port {
usbotg_hs_ep: endpoint {
remote-endpoint = <&con_usbotg_hs_ep>;
};
};
};
5)添加固定电源配置,修改 arch/arm/dts/stm32mp15xx-fsmp1x.dtsi 文件
code arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
固定电源配置通常添加在根节点下,在根节点末尾位置添加如下内容(红色字体为需要添加的内容):
vin: vin {
compatible = “regulator-fixed”;
regulator-name = “vin”;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
v3v3: regulator-3p3v {
compatible = “regulator-fixed”;
regulator-name = “v3v3”;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
v1v8_audio: regulator-v1v8-audio {
compatible = “regulator-fixed”;
regulator-name = “v1v8_audio”;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
v3v3_hdmi: regulator-v3v3-hdmi {
compatible = “regulator-fixed”;
regulator-name = “v3v3_hdmi”;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
v1v2_hdmi: regulator-v1v2-hdmi {
compatible = “regulator-fixed”;
regulator-name = “v1v2_hdmi”;
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
};
vdd: regulator-vdd {
compatible = “regulator-fixed”;
regulator-name = “vdd”;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
vdd_usb: regulator-vdd-usb {
compatible = “regulator-fixed”;
regulator-name = “vdd_usb”;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
6)配置u-boot,取消电源管理
执行make menuconfig
Device Drivers —>
Power —>
[ ] Enable support for STMicroelectronics STPMIC1 PMIC (*号取消,按空格就取消了)
退出,保存。
7)更新配置文件-----只要执行过make menuconfig更改了u-boot的配置,必须重新执行以下指令:
cp .config configs/stm32mp15_fsmp1a_basic_defconfig
8)重新编译源码
make DEVICE_TREE=stm32mp157a-fsmp1a all
9)重新编译源码后,需要重新烧录SD卡,将SD卡接入ubuntu后,重新执行以下三条指令:
sudo dd if=u-boot-spl.stm32 of=/dev/sdb1 conv=fdatasync
sudo dd if=u-boot-spl.stm32 of=/dev/sdb2 conv=fdatasync
sudo dd if=u-boot.img of=/dev/sdb3 conv=fdatasync
10)烧录完成,重新将SD卡插入开发板,打开Xshell,上电。

提示显示 TF 卡未被检测到。系统检测 TF 卡拔插是通过 CD 脚的状态确认,通过原理图可知,TF 卡对应 MMC1 的
CD 脚是与 STM32MP1 的 PH3 连接。对照设备树中MMC1的描述,发现设备树种原有CD脚的配置与FS-MP1A板子不一致,
需调整为 PH3。

1.5》TF 卡支持和去掉 ADC 功能

官方参考板DK1通过ADC检测开机电流,如果供电电流不足3A则启动失败,FS-MP1A 没有设计这个功能,所以需要去掉这部分功能,否则就会报上图中显示的错误,由于 u-boot 期间 ADC 主要功能是检测开机电流,这里直接去掉 ADC 功能即可。
1)修改 arch/arm/dts/stm32mp15xx-fsmp1x.dtsi 文件,调整 MMC1 中 CD 引脚的配置:
code arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
修改红色字体内容:
&sdmmc1 {
pinctrl-names = “default”, “opendrain”, “sleep”;
pinctrl-0 = <&sdmmc1_b4_pins_a>;
pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
disable-wp;
st,neg-edge;
bus-width = <4>;
vmmc-supply = <&v3v3>;
status = “okay”;
};
修改为
&sdmmc1 {
pinctrl-names = “default”, “opendrain”, “sleep”;
pinctrl-0 = <&sdmmc1_b4_pins_a>;
pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
cd-gpios = <&gpioh 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
disable-wp;
st,neg-edge;
bus-width = <4>;
vmmc-supply = <&v3v3>;
status = “okay”;
};
2)配置 uboot 去掉 ADC 功能:按空格键去掉[ ]的星号
执行make menuconfig
Command line interface —>
Device access commands —>
[ ] adc - Access Analog to Digital Converters info and data
Device Drivers —>
[ ] Enable ADC drivers using Driver Model
3)更新配置文件-----只要执行过make menuconfig更改了u-boot的配置,必须重新执行以下指令:
cp .config configs/stm32mp15_fsmp1a_basic_defconfig
4)重新编译源码
make DEVICE_TREE=stm32mp157a-fsmp1a all
5)重新编译源码后,需要重新烧录SD卡,将SD卡接入ubuntu后,重新执行以下三条指令:
sudo dd if=u-boot-spl.stm32 of=/dev/sdb1 conv=fdatasync
sudo dd if=u-boot-spl.stm32 of=/dev/sdb2 conv=fdatasync
sudo dd if=u-boot.img of=/dev/sdb3 conv=fdatasync
6)烧录完成,重新将SD卡插入开发板,打开Xshell,上电。

1.6》关闭ltdc和配置网络

1)由于在 u-boot 阶段我们不使用显示设备,因此需要将 ltdc 相关配置关闭。 现在你不关没有影响,影响后面的驱动课程学习。
2)修改 arch/arm/dts/stm32mp15xx-fsmp1x.dtsi 文件,修改红色部分内容:
code arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
&ltdc {
pinctrl-names = “default”, “sleep”;
pinctrl-0 = <&ltdc_pins_a>;
pinctrl-1 = <&ltdc_pins_sleep_a>;
status = “okay”;
port {
#address-cells = <1>;
#size-cells = <0>;
ltdc_ep0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&sii9022_in>;
};
};
};
修改为
&ltdc {
pinctrl-names = “default”, “sleep”;
pinctrl-0 = <&ltdc_pins_a>;
pinctrl-1 = <&ltdc_pins_sleep_a>;
status = “disabled”;
port {
#address-cells = <1>;
#size-cells = <0>;
ltdc_ep0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&sii9022_in>;
};
};
};
3)重新编译源码
make DEVICE_TREE=stm32mp157a-fsmp1a all
4)重新编译源码后,需要重新烧录SD卡,将SD卡接入ubuntu后,重新执行以下三条指令:
sudo dd if=u-boot-spl.stm32 of=/dev/sdb1 conv=fdatasync
sudo dd if=u-boot-spl.stm32 of=/dev/sdb2 conv=fdatasync
sudo dd if=u-boot.img of=/dev/sdb3 conv=fdatasync
5)烧录完成,重新将SD卡插入开发板,打开Xshell,上电。这个现象现在不明显。

6)配置网络
进入uboot界面:

U-boot 启动后通过命令设置一个 MAC 地址,这是在Xshell中哟:
env set -f ethaddr 00:80:E1:42:60:17
env save

重启开发板,将网线插入开发板中可以进行网络测试。
使用 dhcp 命令获取 ip 地址:(自动获取IP)
STM32MP> dhcp

获取的IP是192.168.1.3
我们可以测试一下,用开发板的IP去ping一下Ubuntu,也可以ping一下外网(但是不要用ubuntu来ping板子)

1.7》eMMC移植

参考原理图可知 eMMC 使用的是 SDMMC2 总线,当前所使用的设备树文件中没有 SDMMC2 的支持,所以需要增加相关内容才能正常驱动 eMMC。

1)增加 SDMMC2 节点信息
修改 arch/arm/dts/stm32mp15xx-fsmp1x.dtsi 增加 SDMMC2 的信息 ,在原有 sdmmc1 节点下增加 sdmmc2 的内容
code arch/arm/dts/stm32mp15xx-fsmp1x.dtsi
&sdmmc2 {
pinctrl-names = “default”, “opendrain”, “sleep”;
pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;
pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
non-removable;
no-sd;
no-sdio;
st,neg-edge;
bus-width = <8>;
vmmc-supply = <&v3v3>;
vqmmc-supply = <&vdd>;
mmc-ddr-3_3v;
status = “okay”;
};
2)修改 arch/arm/dts/stm32mp157a-fsmp1a-u-boot.dtsi 文件,调整启动通道。
code arch/arm/dts/stm32mp157a-fsmp1a-u-boot.dtsi
修改如下内容:
aliases {
i2c3 = &i2c4;
mmc0 = &sdmmc1;
usb0 = &usbotg_hs;
};
修改为(红色字体为增加内容):
aliases {
i2c3 = &i2c4;
mmc0 = &sdmmc1;
mmc1 = &sdmmc2;
usb0 = &usbotg_hs;
};
在 sdmmc1 节点后 sdmmc2 的内容(红色字体部分为添加内容):
&sdmmc1 {
u-boot,dm-spl;
};
&sdmmc2 {
u-boot,dm-spl;
};
3)重新编译
make DEVICE_TREE=stm32mp157a-fsmp1a all
4)重新编译源码后,需要重新烧录SD卡,将SD卡接入ubuntu后,重新执行以下三条指令:
sudo dd if=u-boot-spl.stm32 of=/dev/sdb1 conv=fdatasync
sudo dd if=u-boot-spl.stm32 of=/dev/sdb2 conv=fdatasync
sudo dd if=u-boot.img of=/dev/sdb3 conv=fdatasync
5)测试
重新编译烧写后启动信息对比前文多一个 MMC:(那么我们这个uboot也支持emmc了)

1.8》生成 Trusted 镜像

前面我们做的相关配置都是基于 basic 的配置,而实际 FS-MP1A 使用的 uboot 是基于
Trusted 配置的镜像,后边的《Trusted Firmware-A 移植》章节会使用到 Trusted 镜像。
1)建立基础的 Trusted 配置文件
cp configs/stm32mp15_trusted_defconfig configs/stm32mp15_fsmp1a_trusted_defconfig
make stm32mp15_fsmp1a_trusted_defconfig
2)去掉 PMIC 的配置选项,按空格将方括号内*号去掉:
make menuconfig
Device Drivers —>
Power —>
[ ] Enable support for STMicroelectronics STPMIC1 PMIC
Command line interface —>
Device access commands —>
[ ] adc - Access Analog to Digital Converters info and data
Device Drivers —>
[ ] Enable ADC drivers using Driver Model
3)修改配置文件
cp .config configs/stm32mp15_fsmp1a_trusted_defconfig
4)修改上层目录下的 Makefile.sdk 编译脚本在 UBOOT_CONFIGS 配置项中添加红色内容“stm32mp15_fsmp1a_trusted_defconfig,trusted,u-boot.stm32”在 DEVICE_TREE 配置项中添 加“stm32mp157a-fsmp1a” 。执行以下指令:
code …/Makefile.sdk
UBOOT_CONFIGS ?= stm32mp15_fsmp1a_trusted_defconfig,trusted,u-boot.stm32 stm32mp15_trusted_defconfig,trusted,u-boot.stm32 stm32mp15_trusted_defconfig,optee,u-boot.stm32 stm32mp15_basic_defconfig,basic,uboot.img
DEVICE_TREE ?= stm32mp157a-fsmp1a stm32mp157a-dk1 stm32mp157d-dk1 stm32mp157c-dk2 stm32mp157f-dk2 stm32mp157c-ed1 stm32mp157f-ed1 stm32mp157a-ev1 stm32mp157c-ev1 stm32mp157d-ev1 stm32mp157f-ev1
5)编译 trusted 镜像
make distclean
make -f $PWD/…/Makefile.sdk all UBOOT_CONFIGS=stm32mp15_fsmp1a_trusted_defconfig,trusted,u-boot.stm32

6)编译完成后生成的镜像文件在上级目录下的 build-trusted 文件夹中有一个“u-boot stm32mp157a-fsmp1a-trusted.stm32”
查看是否生成:
ls …/build-trusted/

u-boot-stm32mp157a-fsmp1a-trusted.stm32 即为我们后续会使用的镜像文件。

(二)安装linux交叉编译工具

1)将交叉编译工具en.SDK-x86_64-stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24.tar.xz放入ubuntu目录下,系统源码在老师提供的资料中(E:\春\系统移植\系统移植工具\交叉编译工具)。
大家可以用samba,也可以选择其他方式,要达到的效果如下图:

2)解压交叉编译工具------我的交叉编译工具是在~/shared下。
linux@ubuntu:~/shared$ tar -xvf en.SDK-x86_64-stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24.tar.xz

3)进入解压后的交叉编译器的执行目录:
linux@ubuntu:/home/linux/shared/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sdk

4)执行交叉编译器的应用程序,交叉编译器会默认安装在(/opt)中。
linux@ubuntu:~/shared/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sdk$ ./st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1-openstlinux-5.4-dunfell-mp1-20-06-24.sh

直接按回车。

输入Y,按回车。

输入你的linux登陆密码。回车,这里输入密码可能没显示,输入密码本来就没显示,输入了按回车就行。
5)等待安装完成。

6)导入交叉编译器-----注意:每次重启ubuntu和打开新的终端,都需要重新导入,导入指令如下:
source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

7)测试交叉编译器是否可用:
linux@ubuntu:~/shared/stm32mp1-openstlinux-5.4-dunfell-mp1-20-/sdk$ $CC --version

(三)安装Xshell调试软件。

5.1)打开Xshell软件安装包。老师给的资料----E:\春\系统移植\系统移植工具\Xshell中文破解\xshell_v7.0.0.0093_downyi.com

5.2)双击Xshell-7.0.0093p.exe,下一步

5.2)我接受,下一步

5.3)选择安装路径,下一步

5.3)安装。安装完成后点击,完成。(如果提示已经过期,必须安装最新版,你就按着提示一步一步往下就行。个人是可以试用免费版不要购买许可证的。)

猜你喜欢

转载自blog.csdn.net/qq_52531759/article/details/131832038