做嵌入式系统集成这些年,我越来越觉得“接口互转”才是真正的刚需。前阵子接了个项目:一台基于PCIe/104 OneBank背板的老式一体化设备,需要加装一块Mini PCIe接口的工业相机采集卡。客户在网上翻了半天,要么是Mini PCIe转PCIe x1的延长线方案,要么是M.2转Mini PCIe,真正能直接怼到PCIe/104生态里的转接板几乎没有。项目工期摆在那里,我干脆自己设计了这块Mini PCIe扩展卡——一边是标准Mini PCIe插槽,另一边是PCIe/104 OneBank接口,板卡尺寸严格按PC/104规范走,插到背板上直接就能用。这篇就把从需求分析、方案选型、电路设计到驱动调试的整个过程拆开讲讲,给同在做嵌入式和工控扩展的朋友一个参考。
Mini PCIe大家都很熟了,无线网卡、4G模块、采集卡基本都是这个形态,但PCIe/104在普通消费级领域见得少,很多做软件的朋友可能都没接触过。如果你正在做工业控制、轨道交通、医疗设备或者军工项目,大概率会遇到“老背板配新模块”的尴尬。这篇文章不吹产品,就把我自己踩过的坑和验证过的设计思路完整记录下来,从信号定义到电源树,从PCB布线到Linux/Windows双系统的驱动适配,你照着这个思路走,能少走不少弯路。
1. 为什么要把Mini PCIe接到PCIe/104 OneBank上
1.1 项目背景:旧平台与新模块之间的桥
先说清楚这个项目的真实痛点。客户手上是一台基于PCIe/104规范的嵌入式整机,CPU板卡插在PCIe/104 OneBank背板上,背板本身只提供标准PCIe/104总线接口,没有多余的Mini PCIe插槽。要加的工业相机采集卡偏偏只有Mini PCIe形态,这就成了典型的“新模块、老总线”对接问题。
市面上不是没有转接方案,但问题都不小。Mini PCIe转PCIe x1的延长线,需要机箱内有足够空间,而且只是物理延长,没法接入PCIe/104背板;Mini PCIe转M.2的转接板方向不对,而且M.2和Mini PCIe的供电时序、复位逻辑都不一样。最靠谱的办法,就是自己设计一块标准的PCIe/104尺寸扩展卡,把OneBank接口的PCIe信号,通过板载走线接到标准Mini PCIe插槽上,让采集卡以标准PCIe端点设备的形式,挂到PCIe/104总线上。
这个思路的核心价值在于:PCIe/104生态里的载板和CPU板通常能工作很多年,但外设模块更新换代太快。有了这样一块“桥接扩展卡”,就可以在不动原有系统架构的前提下,把最新的Mini PCIe模块接入传统PCIe/104系统,设备的生命周期一下子延长了好几倍。
1.2 PCIe/104 OneBank标准到底讲了什么
PCIe/104是PC/104嵌入式计算机标准家族里专门定义PCI Express互连的一支,它沿用了PC/104的机械尺寸和堆叠式总线设计,但把传统ISA/PCI并行总线换成了高速串行PCIe总线。PCIe/104规范把连接器分为OneBank和TwoBank两种形态,OneBank也叫Type 1,是入门级配置,只占用一个Bank连接器。
OneBank连接器是58pin,间距0.8mm,板间堆叠高度8mm,板卡尺寸基本沿用PC/104的约90mm x 96mm。虽然引脚数量不算多,但PCIe是基于串行差分对的协议,一对发送、一对接收再加上地,就可以组成一条x1链路,所以58pin完全能承载最高x16的PCIe链路,也可以根据需要拆分成x8+x8或者x4+x4+x4+x4等不同组合。
这个设计在嵌入式领域非常实用。传统PCI/104需要一大堆并行地址线、数据线、控制线,而PCIe/104依靠串行总线的高效特性,用更少的引脚实现了更高的带宽。在设计转接板时,你不需要关心OneBank连接器的每一个引脚干什么,只需要明确几类关键信号:PCIe差分数据对、100MHz差分参考时钟、复位信号、电源引脚,以及可选的管理总线(SMBus)和唤醒信号。
1.3 扩展卡的整体方案架构
在动笔画原理图之前,我先在纸上把整个扩展卡的功能框图列了一遍。这板子的功能非常聚焦:从PCIe/104 OneBank接口取PCIe链路、电源、时钟和复位,然后通过板内走线连到标准Mini PCIe插槽,让Mini PCIe模块能够被系统正常枚举和访问。
整体架构分四块:连接器与信号调理电路、电源转换与时序控制、Mini PCIe插槽周边的辅助信号、以及可选的USB旁路通道。USB旁路是很多人容易忽略的,因为Mini PCIe插槽除了PCIe信号之外,还定义了USB 2.0信号线,很多4G模块和蓝牙/WiFi Combo卡其实是走USB通道的,如果转接板不把USB信号引出来,这些模块就用不了。
方案最终确定为“PCIe x1直通 + USB旁路 + 独立电源树”的结构,不引入PCIe Switch芯片。理由是项目只需要挂一块采集卡,x1链路足够,没必要为了扩展性把成本和复杂度拉高。如果后续客户要多卡扩展,再考虑换PCIe Switch方案,这是后话。
2. 接口信号怎么转:从52pin到OneBank的映射逻辑
2.1 吃透Mini PCIe 52pin的信号构成
Mini PCIe插槽是52pin金手指,看似很多,但真正用于PCIe数据传输的信号非常少。一对发送差分线PETp0/PETn0、一对接收差分线PERp0/PERn0,再加上一对100MHz差分参考时钟REFCLK+和REFCLK-,这就是数据通路的全部。
剩下的引脚里,电源相关占了很大比例。Mini PCIe规范要求提供3.3V和1.5V两路电源,其中3.3V主要给模块的射频前端、信号处理电路供电,1.5V则是PCIe PHY的I/O电压。很多新手画转接板时只接3.3V不接1.5V,导致模块插上去完全没有反应,这是第一个大坑。
控制信号方面,PERST#是PCIe复位信号,低电平有效,必须在所有电源稳定后至少延迟100ms释放,否则链路训练会失败。CLKREQ#是时钟请求信号,用于ASPM电源管理,如果系统需要低功耗待机,这根线必须接好。WAKE#是唤醒信号,一般用于从休眠状态恢复。还有W_DISABLE#无线禁用信号,射频模块常常用到,如果悬空,默认是射频开启,具体看模块定义。
另外还有一组SMBus信号和一组USB DP/DM信号。SMBus用于模块管理,很多模块可以不接,但如果你用的是带管理功能的4G模块,建议把它也连出来。USB信号上面说过,一定要引出到背板,否则你的“Mini PCIe扩展卡”只能支持PCIe协议的模块,适用范围窄了一半。
2.2 OneBank引脚规划与差分对映射
PCIe/104 OneBank连接器的引脚排布,是按PCIe链路分组规划的。每个lane的发送差分对、接收差分对和对应的地线会集中排布,这样设计PCB时可以大大简化走线难度。实际做板卡时,把Mini PCIe侧的一对发送差分线接到OneBank侧对应lane的接收端,把Mini PCIe侧的一对接收差分线接到OneBank侧对应lane的发送端,因为PCIe设备之间的收发是交叉的。
这个“交叉”关系是PCIe互连里最容易搞错的地方。举个例子,你是Root Complex(根复合体),连接到Endpoint(端点设备)时,RC的发送端必须连接EP的接收端,反之亦然。转接板在中间扮演的角色是“无源通道”,不改变信号方向,所以做原理图时要用网络标签仔细核对:PET从Mini PCIe插槽进来,标注Net名称为“PCIe_TX”,然后接到OneBank连接器的接收引脚上,一定不能接反。
参考时钟的处理也需要注意。PCIe的100MHz参考时钟是差分信号,通常由Root Complex提供。在PCIe/104系统里,OneBank背板会输出一路100MHz差分时钟,转接板需要把这路时钟从连接器引到Mini PCIe插槽的REFCLK引脚,中间可以加串联电阻做阻抗匹配,一般建议靠近源端放置。
2.3 直通x1还是上PCIe Switch
方案选型阶段,我在“直通x1”和“PCIe Switch扩展”之间犹豫了挺久。直通方案简单可靠,成本几十块钱,PCB面积也小,缺点是一个Mini PCIe插槽占死了一条x1链路,后续想再挂模块就得换板子。PCIe Switch方案,比如用PLX/Broadcom的PEX8605或者PEX8608,可以把一个x4或x8上行链路拆分成多个x1下行端口,一块板卡上做两到三个Mini PCIe插槽都能行。
最后我还是选了直通方案,理由有三条。第一,客户当前需求明确,就挂一块采集卡,直通板的链路延迟最低,信号完整性最好。第二,PCIe Switch芯片价格不低,带EEPROM配置、参考时钟缓冲、复位管理,整套电路下来复杂度翻好几倍,调试周期至少多两周。第三,PCIe/104背板上闲置的lane本来就不多,如果未来真需要多卡扩展,我可以重新做一块带Switch的转接板,没必要在一开始就过度设计。
这里也给你一个心得:做嵌入式硬件,永远不要为了“未来的可能性”牺牲“当前的可靠性”。能直连就别加芯片,能用离散器件解决的别上可编程逻辑。系统越简单,长期运行的故障率越低。
2.4 时钟、复位、电源这些“隐藏信号”的处理
数据信号之外,转接板设计最见功力的地方在于时钟、复位、电源这几个隐藏信号的处理。先说时钟,PCIe对参考时钟的抖动要求很高,典型的100MHz差分时钟抖动控制在几十皮秒以内,所以时钟走线必须远离大电流开关节点,尽量短,有条件的话做包地处理。
复位信号PERST#的处理我吃了不少亏。一开始我直接把背板的复位信号和Mini PCIe插槽的PERST#短接,上电后偶尔会出现系统枚举不到设备的情况。后来查资料发现,PCIe规范要求PERST#释放时间必须在电源稳定后100ms以上,而PCIe/104背板的复位时序不一定能满足这个要求,特别是在多板堆叠供电逐级上电的场景下。
解决办法是在复位信号路径上加RC延时电路,用10kΩ电阻和10uF电容组成约100ms的延时网络,再配合施密特触发器整形,确保Mini PCIe模块的复位释放晚于主板链路训练。实测下来,加了RC延时之后,设备枚举的成功率从原来的九成提升到了接近百分之百。
电源方面,Mini PCIe需要3.3V和1.5V两路电源,但OneBank背板提供的主电源可能是3.3V、5V或12V混搭。所以扩展板上必须做电源转换:如果背板提供5V或12V,就用DC-DC降到3.3V;3.3V再通过LDO降到1.5V。DC-DC方案效率高,适合电流大的3.3V主供电,LDO方案纹波小,适合1.5V这种对噪声敏感的I/O电源。
3. 原理图与Layout实操要点
3.1 原理图设计:功能区块划分与关键连接
原理图画起来其实不复杂,但区块划分要清晰。我习惯把原理图分成四个模块:PCIe/104 OneBank连接器及信号输入区、电源转换区、Mini PCIe插槽区、辅助信号配置区。每个模块用网络标签互相连接,方便后期检查。
信号输入区的关键是把OneBank连接器的每个功能引脚都标注清楚,特别是电源引脚和地引脚,要分组放置去耦电容。去耦电容的位置和数量直接影响信号质量,我一般每个电源引脚旁边放一颗0.1uF的0402电容,板卡总电源输入端再放一颗10uF和一颗100uF的钽电容做低频滤波。
Mini PCIe插槽区的关键信号就那几个:PCIe差分对、REFCLK、PERST#、CLKREQ#、WAKE#、SMBus、USB信号。对差分对网络,我在原理图里就加上了“Differential Pair”属性,这样导入PCB后能直接识别并做差分规则约束。USB信号是单端高速信号,也要注意等长和阻抗,不能因为是USB 2.0就随便拉线。
辅助信号配置区主要放一些跳线和上下拉电阻。W_DISABLE#脚做一个拨码开关,默认上拉关闭无线,需要时拨到GND开启射频,方便调试。LED信号用LED加限流电阻直接引出到板边测试点,方便看模块工作状态。这些细小的设计在量产和现场维护时非常加分。
3.2 电源树的设计与计算
电源树的设计决定了板卡能不能稳定工作。我最初设计的电源方案是:从OneBank背板取12V作为主输入,用一颗TPS62160降压到3.3V,输出电流最大1A;再用一颗低噪声LDO(TLV1117-1.5)把3.3V降到1.5V,输出电流最大800mA。
功耗计算是这么做的:查了手头几款Mini PCIe模块的规格书,WiFi模块3.3V峰值电流约300mA,4G模块的峰值电流可以达到600mA到800mA,工业相机采集卡的功耗看传感器和接口,普遍在3.3V 200mA到500mA之间。1.5V的电流主要是PCIe PHY消耗,一般在100mA到300mA。所以主3.3V电源按1A设计留了足够余量,1.5V按800mA设计,覆盖绝大多数模块。
这里还要注意上电时序。Mini PCIe规范虽然没有强制要求3.3V和1.5V的严格先后顺序,但通常建议先3.3V后1.5V,避免PHY在I/O电压未建立时收到高电平信号导致闩扣。我在这块板上用了一颗电源时序芯片,让3.3V建立后延迟10ms再使能1.5V输出,测试下来各模块兼容性都很好。
3.3 PCB Layout的差分走线与阻抗控制
到了PCB Layout阶段,核心任务就是保证PCIe高速信号的质量。PCIe Gen2的速率是5GT/s,信号上升沿很快,对走线的阻抗连续性、参考平面、串扰抑制都有要求。我的层叠方案是四层板:顶层走信号、第二层完整地、第三层电源、底层走信号。
差分对要求100Ω差分阻抗,层叠设计时我设定板厚1.6mm,顶层到参考平面的介质厚度约0.1mm,配合5mil的线宽和8mil的线距,差分阻抗基本落在95到105Ω之间,满足PCIe规范正负10%的要求。走线长度方面,Mini PCIe插槽到OneBank连接器的距离很短,我控制在3000mil以内,最大程度减少损耗。
对内等长我控制在5mil以内,这是PCIe规范比较严格的指标,差分对内部两根线的长度差会影响共模转差模噪声,导致眼图变差。对间等长可以放宽到10到15mil,因为不同lane之间允许一定的skew。时钟信号必须和高速数据线拉开距离,至少3倍线宽间距,并做包地处理,防止串扰造成参考时钟抖动。
AC耦合电容的处理也要特别注意。PCIe规范要求发送端放置AC耦合电容,典型值0.1uF。在这块转接板上,Mini PCIe插槽作为连接器,它正对着的是模块内部的发送端,但转接板本身要承担“Root Complex侧发送”的角色,所以在OneBank到Mini PCIe插槽的发送差分线上,我放了一对0.1uF的0402电容,位置靠近驱动端。这个细节如果漏了,很多模块插上去会不稳定,甚至完全无法链路训练。
3.4 机械结构:尺寸、固定孔位与模块高度
机械结构往往决定了扩展卡能不能真正装进机箱,这块板子沿用了PC/104标准的约90mm x 96mm外形,四角开标准安装孔,孔径3.2mm,便于用铜柱堆叠固定到PCIe/104背板上。安装孔的位置必须严格按照PC/104规范,因为PCIe/104背板的固定柱位置是固定的,差一点点就装不上。
Mini PCIe插槽要分全高和半高两种规格,全高模块尺寸是50.95mm x 30mm,半高模块是26.8mm x 30mm。我板子上用的是“全高卡扣式”插槽,支持两种尺寸的模块,通过卡扣固定,不需要额外的螺丝。但要注意模块厚度和高度不能和相邻板卡干涉,特别是在堆叠式机箱里,PCIe/104板间高度只有8mm,Mini PCIe模块加上插座的总高度可能超过这个值。
我实测了一下,全高Mini PCIe模块加上插槽的高度大约在5.5mm左右,距离板间8mm的净空间还有余量,但如果你的机箱里还有上层盖板或屏蔽盒,需要特别确认干涉问题。我在这块板子的左下角预留了一个2.54mm间距的调试排针,上面引出了PERST#、CLKREQ#、WAKE#和地,调试时直接用示波器探头夹上去就行,不用费劲去扎焊盘。
4. 上电联调:从BIOS到驱动的完整流程
4.1 BIOS与链路训练:先看它是否被系统认识
板卡焊接完成后的第一件事,不是装驱动,而是确认PCIe链路有没有训练成功。我用的是一台基于Intel平台的主板作为PCIe/104根复合体,接入转接板后在BIOS的PCI子系统设置里,直接能看到枚举出的设备列表。
AMI的BIOS通常可以在“Advanced -> PCI Subsystem Settings”里看到Device List,如果转接板和Mini PCIe模块被正常识别,这里会出现对应的Vendor ID和Device ID。如果这里一片空白,说明链路没训练起来,问题大概率出在复位、时钟或电源上。
Linux系统下排查更直接,用lspci -vvv就能看到设备的详细链路状态。重点关注LnkSta字段,如果显示“Speed 5GT/s, Width x1”,说明PCIe Gen2 x1链路已经协商成功。如果显示“Speed 2.5GT/s”,说明只协商到了Gen1,可能是线缆质量、走线长度或者对端模块只支持Gen1。如果显示“Down”,那链路根本没建立起来。
我在这块板上测试用的是Intel I210千兆网卡模块,第一次上电BIOS里就认出来了,LnkSta显示5GT/s x1,说明差分走线和阻抗控制没有大问题。但别高兴太早,链路训练成功只是第一步,模块能不能正常收发数据,还得进系统看。
4.2 Windows下的驱动安装:从ADB到HDB的共性问题
Windows系统下,新硬件接入后设备管理器里出现“未知设备”是家常便饭。这块转接板本身不产生驱动问题,驱动取决于你插的是什么模块。但很多朋友在Win7下装Mini PCIe的4G模块或无线模块时,会遇到“接口驱动”装不上的情况,比如设备管理器里显示“ADB Interface”或者“HDB Interface”但装不上驱动。
ADB Interface是安卓调试桥的接口,常见于4G模块或者带安卓系统的开发板;HDB是某些手机厂商的调试桥接口。这类接口驱动的安装思路是通用的:先看硬件ID,右键设备->属性->详细信息->硬件ID,记下VEN_xxxx和DEV_xxxx,然后去对应厂商官网下载匹配驱动。Win7系统因为不带自动在线更新,必须手动指定inf文件安装,而且建议先装厂商提供的USB驱动,再让系统识别ADB/HDB接口,顺序反了容易反复失败。
Intel平台还有个常见问题:设备管理器里Intel Management Engine Interface显示正常,但属性里没有“电源管理”标签页,导致无法设置节能选项。这个现象通常是ME驱动版本和ME固件不匹配,去主板官网下载对应版本的Intel ME驱动重装一遍就能解决。如果重装后还是没有,检查BIOS里ME相关选项是否被禁用。
这些都是老生常谈,但每次总会有人踩坑。我的建议是:装任何interface类驱动前,先把系统更新和芯片组驱动装全,再装厂商专用驱动,能少很多莫名其妙的兼容性问题。
4.3 Linux下的接口冲突:CH341被brltty抢占的经典场景
Linux环境下的调试工作,我遇到一个非常经典的坑。插上一块基于CH341串口芯片的Mini PCIe模块后,dmesg里直接报错:
usb 1-3: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1简单来说,Ubuntu系统预装的brltty(盲文终端支持服务)会自动占用CH341/CH340等常见USB串口芯片的设备节点,导致你的串口工具根本打不开。这个问题坑过我两次,每次换新环境都会再犯一次。
解决办法有两种。最省事的是直接卸载brltty:sudo apt remove brltty,这个服务对绝大多数普通用户来说都没有用处,卸载后USB串口芯片就能正常识别了。如果你不想卸载,也可以写udev规则,让系统在检测到CH341时不把它交给brltty,但操作比较繁琐,我建议直接卸载。
这个问题的本质是“系统服务把硬件接口抢先占用了”,和Windows下“设备管理器里interface驱动装不上”是同一个层面的问题。做嵌入式开发,Linux主机上这些问题几乎每天都能遇到,建议把常用调试工具的udev规则提前配好,能省很多时间。
4.4 性能验证:实测带宽与稳定性数据
链路识别和驱动都正常后,我做了几组性能验证,确保转接板不只是“能用”,而是“好用”。第一组测试用Intel I210千兆网卡模块,通过iperf3跑TCP吞吐,实测稳定在940Mbps到950Mbps之间,这是千兆网卡的线速水平,说明PCIe x1 Gen2链路完全没有成为瓶颈。
第二组测试用一块USB 3.0扩展卡,外接移动固态硬盘。实测连续读取速度约420MB/s,接近USB 3.0和PCIe x1 Gen2的带宽上限。PCIe x1 Gen2的理论有效带宽约500MB/s,实测能跑到420MB/s已经说明转接板的信号完整性不错。
第三组测试是长时间稳定性。我把工业相机采集卡装上去,持续采集1280x1024分辨率、30fps的图像流跑了72小时,中间没有出现丢帧、断流或设备掉线的现象。温度方面,整个板卡在密闭机箱里工作稳定,3.3V电源模块表面温度约45度,1.5V LDO约50度,都在可接受范围内。
这里给你一个明确结论:PCIe x1链路最高只能跑千兆网卡、USB 3.0扩展卡、普通采集卡这类设备。如果你要上万兆网卡或者NVMe固态硬盘,x1的带宽根本不够,必须用PCIe Switch扩展出至少x4或x8链路,或者直接从背板取更高带宽的lane。
5. 常见问题排查与避坑清单
5.1 网卡模块不识别,先查复位时序还是时钟
设备插上后系统完全不识别,这是大家最常遇到的问题。排查顺序我建议固定为:供电、时钟、复位、信号。先量Mini PCIe插槽的3.3V和1.5V是否都在,很多模块不工作就是因为1.5V没供上。
电源没问题就看REFCLK。用示波器量Mini PCIe插槽的REFCLK引脚,应该能看到一对100MHz的差分时钟,峰峰值通常在0.6V到1.2V之间。如果时钟没有,查看OneBank侧是否引出了时钟信号,或者是否在转接板上做了电源隔离导致时钟丢失。
时钟正常再看PERST#复位。上电后用示波器抓PERST#的上升沿,检查释放时间是否在电源稳定后100ms以上。我测过一些模块,复位释放太快会导致链路训练直接失败。如果复位时序不对,就调RC延时参数,把10kΩ电阻加大到20kΩ,延时翻倍。
信号层面的排查放到最后。用万用表量差分对是否导通,注意不能短路。如果原理图连接正确、Layout也做了等长,信号层面的问题一般不多。我遇到过最诡异的情况是AC耦合电容贴反了一颗,导致链路时好时坏,所以焊接后还是先做一遍视觉检查最