资讯动态

Cortex-M3 DesignStart Kit安装与交叉编译环境配置避坑指南

发布时间:2026/10/26 20:47:46 来源:尧图企业网站定制
简介面向嵌入式开发、FPGA原型验证与SoC入门学习者这份Arm Cortex-M3 DesignStart KitAT421-MN-80001-r0p0-00rel0提供ARM官方M3核设计套件可用于在FPGA上评估核心性能、搭建参考硬件平台并开展RTOS与实时控制实验。压缩包共611个文件、约14.64MB含274个Verilog源文件、69个头文件、55个C源码、39个Makefile及多个AXF与Keil工程文件、PDF手册和自检外设示例覆盖IP核、软件工程、参考设计与技术文档等模块。已有1070人学习下载适合需要从处理器核集成、编译调试到板级验证逐步实践的开发者参考也可作为工业控制、消费电子和汽车电子等嵌入式方案的起步素材。1. 先别双击解压Cortex-M3 DesignStart Kit 的安装门槛在版本和路径拿到AT421-MN-80001-r0p0-00rel0.tgz后很多人第一反应是解压到桌面再找 README。Cortex-M3 DesignStart Kit 这类套件不是单个安装程序压缩包里同时有 RTL、软件示例、板级工程和构建脚本解压路径一旦带空格或中文后面的 make 和脚本就会翻车。我见过最典型的翻车是编译器没装、环境变量没配直接在示例目录执行 make报错一屏接一屏最后误判成包损坏。这套环境适合要跑 Cortex-M3 CPU 最小系统、做 FPGA 原型或软件联调的开发者新手照着目录走能装通熟手重点看版本差异和工具链参数。安装前先认清文件名里的r0p0-00rel0只是发布标识不代表你宿主机上的编译器、仿真器和调试器能自动匹配后面每一层都要单独验证。2. 宿主机准备Cortex-M3 设计套件的系统依赖与目录规划Cortex-M3 DesignStart Kit 的安装不是“解压完就结束”宿主机缺依赖、目录放错、权限混乱都会在编译软件示例或构建 FPGA 工程时集中爆发。我的习惯是先确认系统基线再规划一个固定目录最后装依赖。这样做的原因是套件里的脚本经常用相对路径找 RTL、头文件和链接脚本路径一乱后面很难定位是工具链问题还是文件缺失。下面按检查、规划、装依赖、解压四步走。2.1 系统版本、磁盘和内存基线先看机器本身。Cortex-M3 的软件示例编译对内存要求不高但 RTL 仿真和 FPGA 工程构建会吃磁盘和内存如果/opt或/home空间不足解压到一半失败后续报错会很误导。我一般要求至少留出 10GB 以上空闲空间仿真工程多的时候还要更多。命令只是采集信息不改系统。# 查看架构、发行版、磁盘和内存先留一份基线 uname -m lsb_release -a 2/dev/null || cat /etc/os-release df -h /opt /home free -huname -m确认是 x86_64 还是 aarch64交叉编译工具链的包名和可用性会不同。/etc/os-release用来判断是 apt 系还是 dnf 系后面装依赖不走错包管理器。df -h重点看准备放套件的分区不要等到 tar 解压报“No space left on device”才回头清理。free -h不是硬门槛但 RTL 仿真和综合时内存不足会表现为进程被系统杀掉看起来像工具崩溃。如果宿主机是持续集成用的容器还要确认容器里有没有sudo、udev和 USB 透传没有 USB 透传时调试器配置只能做到编译验证板级验证要换到物理机。这个判断越早做越好免得装完工具链才发现调试器根本挂不进去。2.2 目录规划不要放在带空格或中文的路径我一般把套件放在/opt/designstart-kit源码包、解压目录、构建输出和本地工具分开。这样做的好处是环境变量可以写死清理构建产物时不会误删源码换版本时也只需要改一个KIT_ROOT。不要放在“桌面/新建文件夹”下面Makefile 里的空格转义经常不完整尤其是从压缩包继承下来的路径。# 建立固定目录源码包、构建输出、本地工具分开 sudo mkdir -p /opt/designstart-kit/{src,build,tools} sudo chown -R $USER:$USER /opt/designstart-kit # 把 tgz 放到 src 下先校验再解压 cp AT421-MN-80001-r0p0-00rel0.tgz /opt/designstart-kit/src/ cd /opt/designstart-kit/src sha256sum AT421-MN-80001-r0p0-00rel0.tgz tar -tzf AT421-MN-80001-r0p0-00rel0.tgz | head -n 30mkdir -p一次建好三层目录chown把属主改成当前用户避免后面make时因为目录属于 root 而写不进去。sha256sum用来确认压缩包传输完整套件包通常比较大拷贝中断后 tar 可能只解出一部分文件。tar -tzf只列目录不解压先看顶层目录名和文件结构确认压缩包没有把文件平铺到当前目录。列出来的顶层目录名就是你后面KIT_ROOT要指向的路径不要凭记忆写。如果公司或实验室有文件服务器建议把 tgz 和校验值放在只读共享里本地只保留解压目录。这样换机器时不用重新找包也能避免不同人拿到不同版本的文件。目录权限不要图省事直接chmod -R 777后面构建产物和脚本混在一起排查权限问题会更麻烦。2.3 安装交叉编译和构建依赖Cortex-M3 软件示例通常需要make、交叉编译器、C 库和基础开发头文件。apt 系和 dnf 系的包名不完全一样下面给出常见做法如果仓库里没有arm-none-eabi工具链优先看套件内是否自带工具链目录不要急着从不明来源抓二进制包。# apt 系安装构建工具和 Cortex-M3 交叉编译工具链 sudo apt update sudo apt install -y build-essential git make cmake python3 python3-pip \ libncurses-dev libssl-dev libusb-1.0-0-dev \ gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabibuild-essential提供 gcc、make 和基础头文件git、cmake、python3给套件脚本用。libncurses-dev、libssl-dev、libusb-1.0-0-dev是仿真器、调试器或构建脚本常见的动态依赖缺了不一定在编译阶段报可能在运行工具时提示libxxx.so not found。gcc-arm-none-eabi是交叉编译器主体binutils-arm-none-eabi提供objdump、size等工具libnewlib-arm-none-eabi提供嵌入式 C 库。包名在不同发行版可能变化装不上时先用包管理器搜索arm-none-eabi不要硬套。# dnf 系包名按仓库实际结果替换先搜索再安装 sudo dnf install -y development-tools git make cmake python3 \ ncurses-devel openssl-devel libusb1-devel \ arm-none-eabi-gcc-cs arm-none-eabi-binutils-cs arm-none-eabi-newlibdevelopment-tools是开发工具组包含编译和构建基础命令。ncurses-devel、openssl-devel、libusb1-devel对应 apt 系的开发包。arm-none-eabi-gcc-cs这类包名在部分仓库里存在版本可能偏旧如果套件 README 明确要求某个编译器版本以 README 为准仓库版本只用来做初步验证。装完后不要只看“安装成功”下一步要实际执行arm-none-eabi-gcc --version确认命令真的进了 PATH。2.4 解压与权限收口依赖装完后解压。这里不要用tar -xzf直接解到当前目录而是先确认顶层目录再解到/opt/designstart-kit。解压后检查顶层目录名后面所有脚本都围绕这个目录走。cd /opt/designstart-kit/src tar -xzf AT421-MN-80001-r0p0-00rel0.tgz -C /opt/designstart-kit/ # 确认解压后的顶层目录不要写死不存在的路径 find /opt/designstart-kit -maxdepth 1 -mindepth 1 -type d -print-C指定解压目标目录避免压缩包在src里散开。find -maxdepth 1 -mindepth 1只列第一层目录方便确认实际顶层目录名。假设输出是/opt/designstart-kit/AT421-MN-80001-r0p0-00rel0后面就用这个路径作为KIT_ROOT如果你的包解压后目录名不同以实际输出为准。不要为了方便把目录改名成带空格的名字脚本里的路径拼接不会感谢你。# 修正解压后可能出现的权限问题只给当前用户读写执行 KIT_ROOT/opt/designstart-kit/AT421-MN-80001-r0p0-00rel0 find $KIT_ROOT -type d -exec chmod urwx {} \; find $KIT_ROOT -type f -exec chmod urw {} \;目录给urwx是为了进入和写入构建产物普通文件只给urw不要无脑chmod x所有文件。压缩包从别的系统打包时可能丢失执行位真正需要执行的脚本后面单独补chmod x。权限收口后先找 README 和构建说明不要直接猜目录。3. 环境变量与工具链配置让 make 和脚本找得到编译器套件里的 Makefile 和脚本通常依赖CROSS_COMPILE、KIT_ROOT这类变量。环境变量没配好最常见的现象是arm-none-eabi-gcc: command not found或者 make 找到了宿主机 gcc编出来的 ELF 架构完全不对。我的做法是把变量集中写进一个env.sh每次开新 shell 先 source不把一堆 export 散落在.bashrc里。这样换版本、换目录时只改一个文件也不会污染其他项目。3.1 环境变量模板固定根目录和交叉编译前缀先写模板。CROSS_COMPILE末尾的横杠不能丢Makefile 通常把它和gcc、objcopy拼在一起少了横杠会变成arm-none-eabigcc。LC_ALLC用来避免排序和字符处理差异套件脚本里如果有sort、awk或文件匹配本地化设置可能让结果不一致。cat /opt/designstart-kit/env.sh EOF # Cortex-M3 DesignStart Kit 环境变量模板 export KIT_ROOT/opt/designstart-kit/AT421-MN-80001-r0p0-00rel0 export CROSS_COMPILEarm-none-eabi- export BUILD_DIR/opt/designstart-kit/build export PATH$KIT_ROOT/tools/bin:$PATH export LC_ALLC EOF source /opt/designstart-kit/env.shKIT_ROOT指向解压后的实际顶层目录必须和上一步find输出一致。CROSS_COMPILE是交叉工具链前缀末尾横杠是 Makefile 拼接规则的一部分。BUILD_DIR单独放在/opt/designstart-kit/build避免构建产物混进源码目录。PATH前置tools/bin是为了让套件自带工具优先于系统工具如果你不用套件自带工具这一行可以保留目录不存在也不会影响系统命令。LC_ALLC让脚本行为更稳定。source 之后只对当前 shell 生效新开终端要重新执行或者把source /opt/designstart-kit/env.sh写进自己的开发 shell 启动文件。如果套件自带编译器先找它的位置不要把系统编译器和自带编译器混着用。# 查找套件内可能自带的工具链目录 find $KIT_ROOT -maxdepth 4 -type f \( -name arm-none-eabi-gcc -o -name *-gcc \) -print-maxdepth 4限制搜索深度避免在大型 RTL 目录里扫太久。找到自带arm-none-eabi-gcc后把它的bin目录放到PATH前面再重新 source。找不到就继续用系统包管理器安装的版本但要在构建日志里记录版本后面出问题才能回溯。3.2 校验工具链、路径和构建脚本配置完不要直接 make先做三项校验编译器能不能找到、版本是否可用、路径有没有空格或非 ASCII。很多“玄学编译失败”其实是路径里藏了空格Makefile 里少了一层引号。command -v arm-none-eabi-gcc arm-none-eabi-gcc --version arm-none-eabi-gcc -print-sysroot # 检查当前目录是否存在空格或非 ASCII 字符 pwd | grep -nE [[:space:]]|[^[:ascii:]] echo 路径需要调整 || echo 路径基本可用command -v输出为空说明 PATH 没配对先解决这个再谈编译。--version看编译器版本和厂商补丁套件 README 如果指定版本这里能快速对比。-print-sysroot看默认 sysroot交叉编译器找不到头文件时这个值很关键。路径检查用grep匹配空格和非 ASCII命中就换到/opt下的纯英文路径不要试图用引号硬扛构建系统多层嵌套时很难保证每一层都转义正确。接着找构建入口。不同发布包的示例目录名可能不同不要假设一定有software目录。cd $KIT_ROOT find . -maxdepth 4 -type f \( -name Makefile -o -name *.mk \) -print | head -n 30 find . -maxdepth 3 -iname readme* -print先列 Makefile 和 README再决定进哪个目录。head -n 30只用于查看不要拿它当完整清单。README 里通常会写构建命令、支持的板卡和工具链要求如果没有 README优先找顶层 Makefile 或build脚本不要从随机示例目录开始 make。3.3 构建软件示例从最小目标开始我一般先构建一个最小示例不直接全量构建。全量构建失败时日志太长新手容易只看最后一行。先确认单个示例能出 ELF再扩大范围。# 进入示例目录前先确认路径存在下面的 software 只是常见目录名 cd $KIT_ROOT/software 2/dev/null || cd $KIT_ROOT # 先看 Makefile 支持哪些目标没有 help 就跳过 make help 2/dev/null || true # 清理后单线程构建先保证错误可读 make clean 2/dev/null || true make -j1cd $KIT_ROOT/software 2/dev/null || cd $KIT_ROOT是兜底写法有software目录就进没有就留在根目录。make help不是所有工程都支持失败就忽略。先make clean再make -j1单线程构建虽然慢但错误顺序清楚确认能过后再把-j1换成-j$(nproc)。如果 Makefile 需要指定板卡或目标按 README 加变量不要猜。构建完成后检查产物架构这一步能提前发现“用了宿主机 gcc”的问题。# 收集 ELF 并检查架构和大小 find $KIT_ROOT -type f -name *.elf -print | head -n 10 file $(find $KIT_ROOT -type f -name *.elf | head -n 1) arm-none-eabi-size $(find $KIT_ROOT -type f -name *.elf | head -n 1)file输出里应该能看到 32-bit、ARM 或 Cortex-M 相关字样如果显示 x86-64说明构建系统调用了宿主机编译器。arm-none-eabi-size看 text、data、bss 大小和链接脚本里的内存范围对比能提前发现程序超出 Flash 或 RAM。找不到 ELF 时先看 make 日志最后 50 行不要直接怀疑套件包损坏。4. 硬件与仿真侧配置FPGA 工程、调试器和串口软件示例编过只完成了一半Cortex-M3 DesignStart Kit 的价值在板级和 RTL 侧。这个阶段最容易出现两类问题一是工程文件格式和本机 FPGA 工具版本不匹配二是调试器或串口没有权限。我的顺序是先跑仿真或最小构建再接调试器最后看串口输出顺序反了一旦没输出就分不清是软件没跑起来还是链路没通。4.1 先确认仿真和 FPGA 工程入口不同发布包提供的工程格式不一样有的给 Tcl 脚本有的给完整工程目录。不要凭经验直接打开某个文件先列出来。cd $KIT_ROOT find . -maxdepth 4 -type f \( -iname *.tcl -o -iname *.v -o -iname *.vhd \ -o -iname *.xpr -o -iname *.qpf -o -iname *.qsf \) -print | head -n 50-iname忽略大小写避免漏掉.TCL这种命名。-maxdepth 4限制搜索深度防止在大型 IP 目录里翻太久。列出来的工程文件不要直接双击打开先回 README 看推荐入口有些包里的工程文件只是模板需要先跑脚本生成。没有 README 时优先找顶层build.tcl、run*.sh或sim目录不要从 RTL 文件开始猜。仿真侧常见做法是先跑一个最小 testbench确认 RTL 能编译、能出波形再接 FPGA。命令行仿真工具是否可用取决于套件支持范围不要假设开源仿真器能完整跑厂商 IP。# 查找仿真脚本先看脚本内容再执行 find . -maxdepth 4 -type f \( -name run*.sh -o -name sim*.sh -o -name *.do \) -print找到脚本后先sed -n 1,120p 脚本名看它引用了哪些工具和路径再决定是否执行。脚本里如果写死了旧版本工具路径直接跑会报找不到命令这种情况改脚本里的工具变量不要改系统 PATH 去迎合一个旧脚本。4.2 调试器权限和 udev 规则调试器插上后没权限常见表现是工具能列到设备但打不开或者时好时坏。先看 USB 设备再写 udev 规则。下面的规则是模板idVendor和idProduct必须换成lsusb里实际看到的值不要照抄。# 查看调试器 USB 信息记录 VID:PID lsusb # 模板把 xxxx 和 yyyy 替换成 lsusb 里的实际值 sudo tee /etc/udev/rules.d/99-debug-probe.rules /dev/null EOF SUBSYSTEMusb, ATTR{idVendor}xxxx, ATTR{idProduct}yyyy, MODE0666, GROUPplugdev EOF sudo udevadm control --reload-rules sudo udevadm triggerlsusb输出里的ID xxxx:yyyy就是 VID 和 PID替换模板中的占位符。MODE0666让普通用户可读写适合实验环境多人共用机器时更稳妥的做法是建plugdev组把用户加进去规则里用GROUPplugdev。udevadm control --reload-rules重新加载规则udevadm trigger对已插入设备重新应用。改完拔插一次调试器再执行调试工具不要在不拔插的情况下反复试。串口权限同样要处理。很多板子用 USB 转串口设备节点是/dev/ttyUSB0或/dev/ttyACM0。# 把当前用户加入串口组重新登录后生效 sudo usermod -aG dialout $USER # 查看串口设备 ls -l /dev/ttyUSB* /dev/ttyACM* 2/dev/nullusermod -aG是追加组不要漏掉-a否则会把用户从其他附加组里移除。加入dialout后需要重新登录或新开会话才生效。ls -l看设备节点和权限没有设备节点时先查 USB 线和驱动不要直接改程序波特率。4.3 串口参数和板级验证顺序串口参数不要凭感觉。Cortex-M3 示例常用 115200、8 数据位、无校验、1 停止位但具体以板级说明为准。先用stty固定参数再用串口工具观察输出。# 以 115200 8N1 配置串口设备名按实际替换 stty -F /dev/ttyUSB0 115200 cs8 -cstopb -parenb # 读取串口输出退出用 CtrlC cat /dev/ttyUSB0-F指定设备115200是波特率cs8是 8 数据位-cstopb是 1 停止位-parenb是无校验。这些参数必须和板卡程序一致波特率不对时收到的是乱码而不是没有输出。cat只是最简观察方式长时间抓日志可以接tee存文件但不要用会自动加时间戳和颜色的工具干扰原始输出。板级验证顺序我一般按“供电—复位—时钟—串口—调试器”走。先确认板子供电和复位灯再看晶振或时钟配置最后才接调试器。跳过前面直接连调试器工具可能能识别芯片但下载后不运行误判成软件问题。FPGA 工程构建时间长第一次不要改参数先用默认配置跑通再调整引脚和时钟。5. 避坑与排查安装后最容易翻车的五件事这套环境装坏之后报错往往不指向真正原因。下面五条是我在 Cortex-M3 DesignStart Kit 上反复见到的坑按“现象—原因—解决”记遇到时先对照不要一上来就重装系统。5.1 解压后文件权限全错make 写不进构建目录现象make一开始就报Permission denied或者构建到一半提示无法创建.o文件。原因通常有两个压缩包从别的系统打包目录属主不是当前用户或者之前用sudo make跑过一次构建产物变成 root 所有。解决时先确认当前用户和目录属主再只修必要权限。# 查看目录属主和权限 ls -ld $KIT_ROOT $KIT_ROOT/* | head # 把套件目录属主改回当前用户 sudo chown -R $USER:$USER $KIT_ROOTls -ld看目录本身的权限不要只看里面的文件。chown -R递归改属主执行前确认KIT_ROOT没有写错避免误改其他目录。改完不要立刻chmod -R 777先重新 make如果还报权限再看具体是哪个文件被锁。用sudo make是坏习惯构建产物会混入 root 属主后面普通用户清理不掉。5.2 编译器版本不匹配ELF 架构不对现象编译能过但下载或仿真时提示架构不支持或者file查看 ELF 显示 x86-64。原因通常是 Makefile 没有使用CROSS_COMPILE直接调用了宿主机gcc也可能是系统里装了多个arm-none-eabi-gccPATH 指向了旧版本。解决时先看实际调用的是哪个编译器再看版本。# 确认 make 实际使用的编译器 command -v arm-none-eabi-gcc arm-none-eabi-gcc -dumpversion # 在 make 日志里搜编译器路径 make clean /dev/null 21 || true make -j1 21 | tee /tmp/designstart-build.log grep -n gcc /tmp/designstart-build.log | head -n 20-dumpversion只输出版本号适合脚本比对。tee把完整日志存下来避免终端滚动丢信息。grep看 make 实际调用的命令如果出现/usr/bin/gcc而不是arm-none-eabi-gcc说明CROSS_COMPILE没有被 Makefile 使用需要按 README 传变量或改 Makefile 里的工具链配置。不要用软链接把gcc指向交叉编译器这会影响宿主机其他构建。5.3 路径里有空格或中文脚本找不到文件现象明明文件存在脚本报No such file or directory或者 make 提示某个头文件路径被截断。原因是路径里有空格、括号或中文字符脚本拼接时没有加引号。解决时不要试图逐个修脚本直接把套件移到纯英文无空格路径。# 检查路径是否含空格或非 ASCII 字符 pwd pwd | grep -nE [[:space:]]|[^[:ascii:]] echo 需要迁移到纯英文路径pwd先看当前路径grep匹配空格和非 ASCII。命中后把整个/opt/designstart-kit迁到新位置或者重新解压到/opt下。迁移后记得改env.sh里的KIT_ROOT并重新 source。不要用带空格的目录名做实验构建系统、仿真脚本、调试器配置文件可能分别在不同层转义修好一个还会冒出另一个。5.4 动态库缺失工具启动时报 not found现象编译器或仿真工具能执行--version但一跑构建就报libxxx.so not found或者调试工具启动直接退出。原因是安装依赖时只装了运行时包没装开发包或者套件自带工具依赖旧版本库。解决时先用ldd看缺哪个库再按发行版补包。# 检查交叉编译器和调试工具的动态依赖 ldd $(command -v arm-none-eabi-gcc) | grep not found || true ldd $(command -v arm-none-eabi-objdump) | grep not found || trueldd输出里带not found的行就是缺失库。command -v先拿到实际路径避免对不存在的命令执行ldd。补包时优先用发行版仓库不要从随机网站下载.so文件塞进/usr/lib版本不匹配会让更多工具起不来。套件自带工具如果依赖旧版库优先看套件 README 是否提供兼容库目录把该目录加进LD_LIBRARY_PATH不要全局替换系统库。5.5 FPGA 工具识别不到器件或调试器时好时坏现象FPGA 工具能打开工程但综合或下载时提示找不到器件调试器有时能识别有时断开。原因可能是工具版本和工程文件不匹配、USB 供电不足、udev 规则只对某个 PID 生效或者虚拟机没有透传 USB。解决时先看系统日志再确认工具版本。# 查看最近 USB 和内核日志 dmesg | tail -n 50 # 查看调试器是否稳定在列 lsusbdmesg看插入设备时有没有枚举失败、掉电或驱动报错lsusb确认设备还在不在。时好时坏优先换 USB 口和线不要用前置面板或延长线。FPGA 工具版本问题看工程文件格式和 README 要求不要用新版本工具强行打开旧工程后再保存容易把工程配置改坏。虚拟机环境先确认 USB 透传再谈驱动。6. 装完怎么验证跑通用一条最小工程闭环收尾验证不要只看“编译成功”要形成闭环环境变量生效、编译器正确、ELF 架构正确、调试器能识别、串口有输出。我一般用一张小表逐项打勾缺哪项就回对应章节不跳步。检查项命令通过标准环境变量echo $KIT_ROOT输出实际解压目录路径无空格交叉编译器arm-none-eabi-gcc -dumpversion有版本号不是空构建产物find $KIT_ROOT -name *.elf至少一个 ELFELF 架构file 某个.elf显示 32-bit ARM/Cortex-M 相关调试器lsusb设备稳定出现工具能连接串口cat /dev/ttyUSB0复位后有预期输出或至少不报权限错最后跑一遍最小闭环不要直接上完整工程。source /opt/designstart-kit/env.sh cd $KIT_ROOT/software 2/dev/null || cd $KIT_ROOT # 清理后单线程构建确认没有隐藏的并行错误 make clean 2/dev/null || true make -j1 # 找到 ELF检查架构和大小 ELF$(find $KIT_ROOT -type f -name *.elf | head -n 1) file $ELF arm-none-eabi-size $ELF # 看反汇编入口确认是 Cortex-M3 指令而不是宿主机代码 arm-none-eabi-objdump -d $ELF | head -n 40source让当前 shell 拿到KIT_ROOT和CROSS_COMPILEmake clean清掉旧产物make -j1保证错误顺序可读。ELF变量取第一个 ELFfile和size分别验证架构和内存占用。objdump -d看反汇编开头Cortex-M3 常见 Thumb/Thumb-2 指令出现大量 x86 指令就说明编译器用错了。验证完再换-j$(nproc)提速并保存一份构建日志。从那以后我每次拿到新的 tgz都先tar -tzf列目录、sha256sum校验、source env.sh再跑一遍这个最小闭环不会再把“解压完成”当成“安装完成”。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑