简介:一份基于ARM官方源码v0254的DAPLINK开发调试器完整开源方案,面向嵌入式开发者、电子爱好者和高校学生,帮助从零编译DAPLINK固件并自主设计PCB,摆脱对商业调试器的依赖。压缩包共1023个文件,约6.31MB,包含454个C源码、300个头文件、170个YAML配置、37个Python辅助脚本、14个Markdown文档,以及schdoc/pcbdoc/prjpcb等电路设计源文件和PDF/xlsx说明材料,兼顾固件构建与硬件设计。已有2666人浏览学习。资源覆盖ARM官方v0254源码获取、GCC ARM编译环境搭建、make编译与USB烧录完整流程,同时给出微控制器选型、SWD信号线布局、PCB布线及阻抗匹配等关键设计细节,适合复现一款可自定义的STM32调试工具。配套的批量构建脚本、PCB文档和裁剪说明也能为后续二次开发与教学实验提供直接参考。
1. DAPLink是什么:自己编译固件的底气从哪来
很多人手里几十块钱的调试器,拆开后发现主控就是一颗普通单片机,就能理解DAPLink项目的意义。DAPLink跑在常见ARM Cortex-M单片机上,用固件把USB和SWD协议之间的事全部包圆,官方源码提供完整功能框架,拖拽烧录、CMSIS-DAP调试协议、虚拟串口、自定义PID/VID都能在编译前改掉。
自己编译固件,最直接的好处是不受成品调试器固定行为限制。你可以把设备名改成自己的项目名,把指示灯引脚改成自己PCB上舒服的位置,把虚拟串口行为调整到适合产线。再配合自研PCB,就能做出一块尺寸、接口、电平都贴合自身项目的调试器。下文按实际流程走一遍:源码结构、编译命令、PCB模块与布线参数、排查手段。适合需要批量定制调试模块的工程师,也适合第一次接触CMSIS-DAP协议想把它真正吃透的开发者。
2. 官方源码与PCB设计:先看懂要动哪些部分
2.1 源码目录结构:board配置决定固件行为
DAPLink的源码虽然庞大,但我建议不要一上来就钻进source目录读C代码。先看顶层目录,理清楚哪部分决定固件行为。board目录存放具体板级配置,比如LED引脚、UART引脚、USB VID/PID、拖拽烧录时使用的磁盘配置。target目录按芯片类型分别保存启动文件、链接脚本和Flash算法。source目录才是协议栈和驱动代码,但对普通定制来说,大概率不需要动。
实际操作时,我会先克隆源码,然后列出board目录看看有哪些参考板:
git clone <DAPLink源码仓库地址> cd DAPLink ls boards/源码仓库地址以官方项目页发布的为准,克隆下来后可以直接看boards下的文件夹名。这些名字就是后面编译时要用到的-b参数候选值。如果你发现自己要用的是F103,而boards下有好几个F103开头的文件夹,就找最接近自己原理图的那个。比如系统板、最小系统板、官方评估板,引脚大概率都不一样,别选错。
找到参考板后,打开它的board.json,看下面几个字段是否和你的设计一致:
{ "target": "stm32f103c8", "default_interface": "stm32f103c8", "usb": { "vendor_id": 0xC251, "product_id": 0x1002 } }target是主控芯片型号,default_interface决定USB接口固件使用哪个芯片后端,usb里是PID/VID。这个文件决定最终枚举出来的设备名,也决定构建脚本会调用target目录下的哪套启动文件。如果配置错,即使编译通过,固件也跑不起来。
2.2 PCB必要模块拆解:从官方参考图里圈出来
官方仓库中每个board基本都带参考原理图,即使拿不到可编辑源文件,PDF和BOM也足够照抄。我先不急着画PCB,而是把参考图中与USB、电源、SWD、UART、复位、LED有关的零件全部圈出来,再逐个对照主控数据手册确认引脚连接。
第一个是USB物理层。USB座子的D+/D-通过22Ω左右串联电阻接到主控,靠近座子放ESD保护器件。VBUS需要分压后连到主控一个输入引脚,用来检测USB是否插入。这个检测脚决定了系统能否识别到主机,漏掉它会表现为USB枚举时好时坏。
第二个是SWD接口。DAPLink与目标板之间只需要SWCLK、SWDIO、RST三个主要信号,通常通过双排排针引出。如果你的目标板电平与DAPLink主控不一致,中间要加电平转换,或者用开漏加外部上拉的方式兼容。
第三个是虚拟串口。DAPLink的USB CDC与主控UART共用同一颗MCU,所以主控的TX/RX要交叉连接到目标板的RX/TX。PCB布局上,这两根线要避开高频开关节点,防止串口数据被干扰。
最后是电源。USB 5V输入,经LDO降到3.3V给主控供电,同时可以输出给目标板。官方参考图里通常有目标板电源选择跳线,避免调试器和目标板同时供电造成冲突。这个跳线后期调试很有用。
复位电路往往被忽略。DAPLink主控的NRST引脚需要外接10kΩ上拉和100nF电容,上电瞬间如果内部复位不彻底,USB枚举就会出现偶发性失败。LED也不能随便接,串联电阻要根据LED颜色和供电电压计算,保证灌电流在2-5mA。太亮会干扰眼睛,太小可能导致引脚过载,这些是低智商问题但最容易在后面量产时暴露。
2.3 主控芯片选型:F103C8和LPC11U35如何取舍
DAPLink能跑的主控不少,但DIY圈子里最常看到的是F103C8T6和LPC11U35。F103C8T6的优势是资料多、烧写方便,用串口ISP就能写固件,对新手特别友好。缺点是现在市场上便宜芯片很多是翻新货,长期跑USB口容易复位。
LPC11U35是官方很多参考板的首选,USB部分设计成熟,虚拟串口和HID共存时的枚举顺序更稳定,但烧写门槛稍高,通常要借助另一个调试器。选型时我会看三点:货源是否稳定,团队是否熟悉,以及RAM大小。RAM关系到拖拽烧录时的缓冲能力,如果打算做离线批量写入,尽量选RAM大一些的。
| 对比项 | F103C8T6 | LPC11U35 |
|---|---|---|
| 典型晶振 | 8MHz | 12MHz |
| RAM容量 | 20KB | 8KB |
| USB+CDC+SWD同开 | 支持 | 支持 |
| 新手烧录难度 | 低 | 中 |
| 常见问题 | 假货/翻新多 | 引脚复用复杂 |
晶振是关键变量。官方源码默认频率基于官方板设计,如果你改了晶振,target目录里的时钟配置要同步改。不然轻则USB枚举失败,重则主控跑飞。最简单的做法就是沿用官方板晶振值,PCB上已经画好就别改。
2.4 从官方参考图到自研PCB的最小改动清单
如果不想一开始就大改,我建议把官方方案作为基线,只做三步改动。第一,调整接口形态,比如把Micro USB换成Type-C,把双排排针换成单排针。第二,调整LED指示灯数量和颜色,对应修改board配置里的GPIO定义。第三,调整PCB尺寸,把不需要的测试点去掉。
这三步改动不需要碰协议栈代码,也不影响USB核心逻辑。改完后编译一次,如果枚举正常,再逐步加入你自己的功能扩展。这样能最大程度保留官方方案的稳定性,减少排错范围。
很多复刻板把官方参考图里看起来没用的滤波器电容和电阻去掉了,例如USB D+/D-线上的串联电阻,晶振负载电容,VBUS分压电阻。这些器件在功能上不是“必须有”,但少了它们,信号质量和ESD抗性会明显下降。我建议保留每一种以“防止”“保护”“滤波”开头的器件。省一个电阻可能换来一次无法解释的USB断开。
3. 自己编译固件:从克隆源码到烧录文件
3.1 搭建编译环境:工具链版本是硬门槛
DAPLink的构建脚本依赖Python和一个ARM交叉编译器。这里最容易犯的错误是装最新版GCC,结果启动文件里一堆旧汇编语法被当错误处理。我的做法是照着官方文档指定的大版本装,比如文档明确写支持某版本就装对应版本,不要盲目升到最新。
操作系统方面Windows和Linux都行,但路径里不要有中文和空格。构建脚本会调用make和python,路径太复杂容易出莫名其妙的问题。我一般放在C:\DAPLink或/home/用户名/DAPLink这类纯英文短路径下。
# Ubuntu/Debian 环境示例 sudo apt install gcc-arm-none-eabi python3 python3-pip git pip3 install --user intelhex future pyyaml arm-none-eabi-gcc --version python3 --versionintelhex用于生成hex文件,future让Python脚本兼容旧语法,pyyaml用来解析board.json。如果编译时提示找不到yaml,就是这一步没装好。装完工具链建议先编译一个官方board,不要一上来就编自己的板子。验证环境最简单的方式是挑一个官方board名编译,能产出hex说明环境没问题。
3.2 用官方构建脚本编译:命令与参数
构建脚本入口是python tools/build.py。-b参数指定board名,这个名字必须与boards目录下的文件夹名完全一致,大小写都要对。常见官方board名类似stm32f103c8_medtmp或lpc11u35_ws,具体以你克隆的源码版本为准。
# 先编译官方参考板验证环境 python tools/build.py -b stm32f103c8_medtmp编译过程会先构建bootloader,再构建interface固件,最后合并成一个hex。输出目录一般在build/stm32f103c8_medtmp/下。如果这个命令顺利结束,说明源码、工具链、依赖都正常。
这里说下-b之外的常用参数。--toolchain可以指定交叉编译器路径,不指定就默认用PATH里的arm-none-eabi-gcc。--clean会清掉上一次的中间产物,当你改了board配置后建议加上,避免旧文件没更新。--verbose打开详细日志,编译失败时看它最有用。
python tools/build.py -b stm32f103c8_medtmp --clean --verbose编译输出里会有一大段gcc命令,不用全部看懂,重点看最后有没有生成.hex和.bin文件,以及有没有以Error开头的行。有些warning可以忽略,但如果是链接阶段的错误,比如undefined symbol,就要回到board配置检查。
3.3 把自己的PCB写进构建系统:board.json与引脚映射
当官方board验证通过后,开始定制自己的PCB。先在boards目录下新建一个文件夹,名字建议短且带芯片型号,比如my_daplink_f103。里面至少要有board.json和target.mk。board.json描述设备信息和USB参数,target.mk可以复用参考板的。
{ "name": "my_daplink_f103", "target": "stm32f103c8", "interface_core": "M0", "default_interface": "stm32f103c8", "device_id": 0x3456, "usb": { "vendor_id": 0xC251, "product_id": 0x1002, "product_string": "My DAPLink" } }name是board名,编译时要保持一致。target必须和芯片型号对应,否则链接脚本和Flash算法会选错。vendor_id保持官方默认即可,product_id可以指定一个未被其他设备占用的值,product_string就是你插上电脑后看到的设备名。
device_id是调试器固件内部用的标识,和USB枚举无关,但会影响拖拽烧录时对目标板的识别。interface_core一般写M0,因为DAPLink的USB协议栈在Cortex-M0上已经足够,部分双核场景才会用到M4。
board.json只是元数据,真正决定引脚功能的是target目录内针对该芯片的IO配置。以F103为例,官方源码里会用GPIO定义把USB、UART、LED映射到具体引脚。你的PCB如果重新分配了引脚,必须在这里同步修改,而不是只改board.json。
// 以串口重映射为例 // 参考板:UART1_TX = PA2, UART1_RX = PA3 // 自己的板子:UART1_TX = PA9, UART1_RX = PA10 gpio_set_hw(GPIOA, 9, PIN_FUNC_7); gpio_set_hw(GPIOA, 10, PIN_FUNC_7);这里PIN_FUNC_7是F103的USART1_TX/RX复用编号,具体值要查数据手册的AF映射表。写错编译不会报错,但串口不会有输出。类似地,USB引脚的复用编号也要查手册,不能凭感觉搬。
3.4 编译产物里有什么:bootloader与interface的分区
DAPLink固件在Flash中通常分两个区域:bootloader和interface。bootloader负责USB拖拽烧录和升级,interface固件负责CMSIS-DAP虚拟串口等调试功能。构建脚本最后生成的hex是把两部分合并的,烧录时可以直接用。
如果你想分别烧录,脚本也会输出单独的bin文件。在配合Bootloader升级时,只更新interface区域更安全。烧录时注意不要把bootloader覆盖掉,否则后面没法用拖拽方式升级。这个分区概念在排查问题时很关键,很多“USB识别为烧录盘但无法调试”的情况,就是因为只烧了bootloader,interface固件没有写入。
改动board配置后,建议重新编译并生成完整hex。烧录前可以用arm-none-eabi-size快速看固件大小:
arm-none-eabi-size build/my_daplink_f103.hex这条命令输出代码段、数据段大小,可以快速判断固件是否完整。如果hex的Flash大小明显小于预期,可能是interface固件没合并进去。
3.5 编译常见坑先看一眼
第一次用自己板配置编译时,如果报fatal error: no such file or directory,多数是board文件夹里的文件引用路径不对。检查target.mk里写的源文件路径是否存在,比如链接脚本路径是否有拼写错误。
如果是undefined reference to SystemInit,说明startup启动文件没有被编进来,或者target配置里的启动文件路径不对。如果是指针类型不匹配的警告,可以暂时忽略,但如果是链接器脚本里的FLASH起始地址错误,则会产生无法运行的固件,表现是烧录后MCU完全没有枚举。
4. 按官方原理图设计PCB:从模块拆解到布线参数
4.1 核心电路模块与器件选型
一个典型的DAPLink PCB包含:USB座子、ESD保护、LDO稳压、主控MCU、SWD排针、UART排针、LED指示灯和配置跳线。每个模块都有明确的器件作用,不要为了省物料盲目删减。
USB部分,座子的D+/D-串联22Ω电阻,用于阻抗匹配和限流。在PCB上靠近座子放ESD器件,例如常见的低压USB保护芯片,可以防止插拔静电打坏MCU。VBUS通过两个电阻分压后连到MCU的输入引脚,用于检测USB是否在线。这个分压比例要保证MCU引脚电压不超过3.6V,否则长时间插拔可能损伤引脚。
电源部分用低压差LDO把5V降到3.3V。选型时注意最大输出电流,DAPLink要给目标板供电的话,LDO至少要能输出300mA以上。有些LDO在USB电流波动时电压跌落明显,可能导致调试过程中目标板复位。输入输出各加一个10uF电容,靠近LDO引脚放置。
SWD接口部分,推荐做成双排2.54mm排针,定义包括3.3V、SWCLK、SWDIO、GND、RST,另一个排针引出UART的TX、RX、GND。不要只用间距1.27mm的排针,除非你确定目标板接口匹配。SWCLK和SWDIO线要离D+/D-远一点,避免数字噪声耦合到USB上。
4.2 布局与布线参数:USB差分与信号完整性
画PCB时最影响成败的是USB差分线。D+/D-要按90Ω差分阻抗控制,两层板做起来不容易,但也不是没招:保持两条线等长、距离尽量近、底下不要走其他信号,线宽按板厂经验值例如0.2mm线宽加0.2mm间距。如果做不到精确阻抗,至少要让走线短而直接,避免打过孔换层。
SWD信号频率虽然不高,但布局时也要注意。SWCLK是时钟线,SWDIO是数据线,两条信号线离晶体和复位电路远一点,中间最好铺一条地线隔离。目标板连接线如果用了杜邦线,长度不要超过20cm,超过后容易在高速下载时出现CRC错误。
晶振布局是最容易翻车的地方。外部晶振要尽量靠近MCU的OSC_IN/OSC_OUT引脚,晶振下方不要铺铜,外围两个负载电容要晶振两侧对称摆放。DAPLink对USB时钟精度要求很高,如果晶振离MCU太远,寄生电容增大导致频率偏差明显,Windows可能会提示无法识别的USB设备。
下面是关键布线参数参考表:
| 网络 | 建议参数 | 说明 |
|---|---|---|
| USB D+/D- | 差分线宽0.2mm/间距0.2mm | 尽量短,等长,不换层 |
| SWCLK/SWDIO | 线宽0.3mm,地线隔离 | 远离晶振和复位电路 |
| 晶振路径 | 线宽0.2mm,下方无铜 | 负载电容靠近晶振 |
| LED/按键 | 线宽0.3mm | 不追求短,但避免绕晶振 |
| 电源主干 | 线宽至少0.5mm | LDO输入输出走粗线 |
4.3 电源去耦与地平面:一个被忽视的稳定性来源
DAPLink同时工作在三块地里:USB数字地、模拟地和目标供电地。对两层板来说,不要把地割成碎片,主控下尽量保持完整地平面。每个电源引脚旁边放一个100nF瓷片电容,位置要靠近引脚,不要用走线绕远。USB座子的外壳地通过一个1MΩ电阻和一个0.1uF电容并联到地,这是官方常见做法,能减少插拔造成的机壳静电。
LDO输入和输出各加一个10uF电容,容值不是越大越好,过大会让启动瞬间的充电电流冲击USB端口。如果焊接了测试点,尽量把SWCLK、SWDIO、UART_TX、UART_RX都引出测试点,方便飞线排错。
主控的NRST脚,DAPLink自己作为调试器时,NRST引脚带外接上拉10kΩ到3.3V,同时并联一个小电容去抖动。很多复刻板省略了这个电容,结果电脑枚举USB时主控偶尔复位,表现就是设备时有时无。这种玄学问题,最后查出来都是缺消抖电容。
4.4 从编译产物到烧录:第一次点亮调试器
PCB焊好后第一次上电,先不要插USB。用万用表测3.3V与GND是否短路,再量LDO输出是否正常。确认电源没问题后,把编译好的hex烧录到主控。对F103来说,最简单的方式是用串口ISP,BOOT0拉高,通过USART1的PA9/PA10连接USB转TTL,用官方烧录工具写入hex。注意串口ISP只能烧写全片,不能用它区分bootloader和app。
如果手头有另一个调试器,也可以用OpenOCD通过SWD烧录。这里给一个最简命令:
openocd -f interface/cmsis-dap.cfg -f target/stm32f103.cfg -c "program build/my_daplink_f103.hex verify reset exit"-f interface/cmsis-dap.cfg使用当前电脑上已有的CMSIS-DAP调试器作为烧录工具;program指令把hex写入目标芯片Flash,写完自动校验并复位运行。烧完后拔掉外接调试器,插上USB线,电脑应该枚举出一个USB设备和一个COM口。如果没有,先不要怀疑PCB,先看固件里的board配置是否和原理图一致。
4.5 PCB送厂前的检查清单
送厂打样前,我习惯按这个清单过一遍。
首先,用万用表二极管档从USB座子的D+到MCU引脚测连通性,确认没有接反。其次,检查LDO输出电容极性,贴片电容可以不看极性,但钽电容装反会冒烟。然后,检查SWD排针与目标板连接顺序,特别是VCC检测脚,很多失败故障都是这个脚悬空。再检查晶振下方是否挖空,离MCU是否够近。最后,用设计规则检查确认所有GND网络都连通,特别是USB座子外壳地有没有接消静电电阻。
如果是在立创EDA这类工具里画的,还可以在DRC里设置差分对规则,然后跑一遍连接性检查。DAPLink板子不大,但信号种类杂,跑一遍DRC能拦住绝大多数低级错误。
5. 编译与PCB调试避坑:5个让我交过学费的地方
5.1 USB枚举失败:DP/DM接反还是固件配置不对
现象:编译成功后上电,Windows设备管理器里出现“未知设备”或设备描述符请求失败。
原因有两类。一是PCB焊接问题,DP/DM线在USB座子焊盘和MCU引脚之间错位;二是固件里USB引脚配置和实际电路不一致。我见过最离谱的是USB座子画成了Mini B,但焊的是Micro B引脚定义,检测线和数据线互相错位。
解决:先查原理图,确认MCU的USBDM/USBDP对应芯片引脚号,再看焊接。用万用表蜂鸣档从USB座子的D+到MCU引脚测通断。如果没问题,把固件里的USB引脚映射改成和实际一致,或者反过来改PCB。不要同时改两边,一次只改一边,保证另一个变量恒定。
5.2 SWD连接经常失败:目标电压检测和复位时序
现象:调试器能被电脑识别,但点击下载后报“Cannot connect to target”或连接时好时坏。
常见原因不是SWCLK/SWDIO焊反,而是DAPLink需要读取目标板电压,如果目标板没有上电,SWD电平转换无法工作。很多参考图里有一个VCC感应引脚,接到目标板3.3V,如果这个引脚悬空,调试器以为目标板电压为0。
解决:给目标板上电,并确保VCC感应引脚接好。如果目标板电压是5V,而调试器主控是3.3V,需要在SWD线上加电平转换,不能直接把5V接到3.3V主控引脚。还要注意SWD慢速连接问题,OpenOCD可以降低初始时钟频率来测试连接:
openocd -f interface/cmsis-dap.cfg -f target/stm32f103.cfg -c "adapter speed 100" -c "init"adapter speed 100把SWD时钟降到100kHz,能避开许多不良接触产生的时序失败。如果低速能连而高速连不上,问题出在信号完整性而不是协议。
5.3 虚拟串口不工作:CDC描述符与枚举顺序
现象:设备能在设备管理器里识别为CMSIS-DAP调试器,但没有COM口出现。
原因可能是固件没有启用CDC接口,或者USB的配置描述符被识别成仅HID。另外,有些DAPLink版本把虚拟串口放在interface固件里,如果编译时只烧录了bootloader,串口当然不出现。
解决:检查board.json里的USB配置,确保CDC接口打开。用USB树查看设备描述符,看是否有CDC类接口。如果描述符正常但COM口不出现,检查USB_DP/DM线是不是串联电阻过大导致信号质量差。串口功能不工作不要急着改代码,先用另一个USB调试器交叉验证。
5.4 编译报错:工具链与路径的坑
现象:克隆源码后直接编译,输出一堆undefined reference to SystemCoreClock或者fatal error: no such file or directory。
原因:工具链版本过新,启动文件里的一些旧语法不再兼容;或者源码路径包含中文和空格。构建脚本还要联网下载工具资源,网络受限时也会失败。
解决:锁定官方文档指定的GCC版本,不要盲目升级。把源码移到纯英文短路径。如果用了CMake构建,注意CMake版本和Python版本匹配。还有一个容易被忽略的点,构建脚本会用Python下载依赖,国内网络如果下载失败,就手动把依赖工具装好,然后在脚本里跳过下载。
5.5 下载速度慢:缓冲区和SWD时钟设置
现象:连接正常,但每次下载几十KB的固件要花十几秒。
原因可能是SWD默认时钟被源码设得很低,或者目标板线路过长导致高频失败。DAPLink支持将SWD时钟配置到10MHz甚至更高,但前提是接线足够短,目标芯片支持。
解决:在board配置或target配置里调高SWD时钟参数,同时用短而粗的线连接SWD。如果调高后下载出错,说明信号完整性问题,需要降级并改善线材。另外,启用二进制数据的块传输也能提高速度,这些在源码里都有对应配置项。
5.6 通用的故障定位顺序
如果USB不识别,先量电源,再量晶振波形,接着看USB D+/D-到MCU引脚通断,最后才怀疑固件。如果USB识别但调试失败,先看目标板电压感应,再查SWD线序和线长。如果串口不出现,先确认固件是否烧完整,再看USB描述符。按照这个顺序排查,大多数问题能在半小时内定位。
很多问题看起来是协议导致的,最后查出来都是电源和焊接。遇到过两次新板子插上后主控发热严重,用热成像一看是LDO输入输出焊反了。所以上电前用万用表量一遍LDO输入输出对地短路,是每次都必须做的动作。
6. 进阶:让DAPLink更顺手的三个习惯
第一,每次改板前先备份board配置。源码里的boards目录是整个项目的边界,我习惯在git里建立一个独立分支,专属自己的板子。这样官方上游更新时,可以把自己的board配置merge过去,而不是每次都在代码里手工找差异。
第二,用脚本批量验证USB描述符。焊好几块板后,不可能每块都插到电脑上肉眼确认。我会写一个Python脚本,调用系统USB信息工具,批量读取设备描述符,检查VID、PID、设备字符串是否都匹配。这个习惯帮我筛掉不少焊接不良的板子,因为枚举不稳定的板子会在描述符读取超时。结合产测场景,还可以同时测试虚拟串口的自收发:把TXD和RXD短接,发送一串字符,看能否原样返回。
第三,把DAPLink和虚拟串口一起用于产线烧录。DAPLink同时提供CMSIS-DAP和CDC,等于一根USB线既下载固件又抓日志。我在产测治具里把SWDIO/SWCLK/UART三根线固定到探针上,每次测试只要插一条USB线,就能完成下载、打印、校验三个动作。这样做的成本只是一颗芯片和一块小板,比买成品调试器节省得多。
调DAPLink时,我最深的教训是:不要一开始就想着改协议层。它的价值在稳定做好USB和SWD之间的事情,定制需求绝大多数在board目录就能解决。真正扎实的做法是从官方源码照着一模一样配出来,再把能改的都改成自己的。希望这些经验帮到你,也祝你一次打样就成功。
本文还有配套的精品资源,点击获取