资讯详情

资讯详情

非实时系统架构下的硬件自动化测试方案与实践

做硬件测试的同行应该都有过这种经历项目一上来领导说要搞自动化测试你脑子里第一反应是上实时系统加专用测试机柜预算一报上去老板脸色立马就变了。其实很多时候我们的被测对象根本不需要微秒级响应一台普通工控机加上合理的软件架构就完全能撑起一套稳定可靠的硬件自动化测试系统。这篇文章我就从实际项目经验出发聊聊怎么在非实时系统架构下搭出一套能真正落地、能扛住产线长时间运行的硬件自动化测试方案。这套方案做的是什么简单说就是用跑着Windows或Linux的普通PC/工控机作为测试上位机通过串口、GPIB、USB、以太网等通用接口去控制仪器仪表和被测设备DUT完成参数采集、功能验证、结果判定和报告生成。它解决的核心问题是在硬件成本受限、交付周期紧的背景下如何用非实时的通用操作系统达到产线批量测试对稳定性、一致性、可追溯性的要求。适合谁看刚接触自动化测试的硬件工程师、测试工程师或者正在为产线测试方案选型发愁的技术管理者。1. 非实时系统架构的定位与挑战1.1 先搞清楚“非实时”到底是什么意思有些朋友一听到“非实时系统”就觉得不能用其实这是被带偏了。所谓非实时系统指的是操作系统内核不保证任务在确定时间内完成调度典型代表就是我们天天在用的Windows、普通Linux发行版。它和实时系统比如VxWorks、RT-Linux、QNX最大的区别在于实时系统能保证某个任务在硬性规定的时间窗口内被执行而非实时系统只能保证“尽量快”具体快多少取决于CPU负载、中断、驱动状态等因素。这个区别落到硬件测试上影响确实存在。比如你要用示波器抓一个上升沿的时间参数触发时机和采样时序稍有偏差测出来的数据就不准。但问题在于我们日常做的绝大多数硬件测试比如电源模块的电压精度、通信接口的报文交互、继电器开关的时序逻辑、老化过程中的温度曲线记录这些场景对时间精度的要求通常在毫秒级甚至几十毫秒级。非实时系统在正常负载下的调度抖动一般在几毫秒到几十毫秒之间完全够用。我在实际项目中做过统计一台配置普通的工控机i5处理器、8G内存在跑着测试软件同时打开日志记录、数据库写入的情况下最坏调度延迟大概在30毫秒左右。而对绝大多数被测设备的参数读取操作通信链路本身比如SCPI指令的响应、串口的发送接收耗时都在几十毫秒到几百毫秒系统调度抖动只占了很小一部分完全不会成为瓶颈。1.2 为什么值得选择非实时架构既然实时系统更“稳”为什么还要选非实时架构答案很直接成本和生态。一套入门级的实时测试系统光是专用的实时扩展卡、实时操作系统授权、配套驱动开发就够买好几台高配工控机了。而普通PC加通用仪表的组合硬件成本能低到前者的五分之一甚至更低。更重要的是软件生态的差异。非实时系统上能用的编程语言、测试框架、调试工具、报表组件非常丰富Python、C#、LabVIEW随便选招人也容易。实时系统那边开发门槛高调试手段有限遇到问题想从网上下个现成的库基本没戏。对于大多数中小规模的硬件研发和产线非实时架构是用合理的成本换取了足够用的性能属于典型的技术经济学选择。还有一个容易忽略的点硬件自动化测试的核心瓶颈很少在操作系统层面而在仪器通信协议和测试流程设计上。只要把这个认知摆正非实时系统的“劣势”就完全可控。1.3 非实时架构要面对哪些具体难题实操层面上非实时系统做硬件自动化测试最棘手的是这几个问题第一测时序抖动不可控。前面说了正常负载下抖动在几十毫秒内但如果系统里跑了别的任务、某次杀毒软件扫描、系统自动更新触发瞬时延迟可能飙到几百毫秒。对毫秒级的时序测试这就不能忍。第二硬件资源冲突。你同时挂了三台设备一台用串口一台用USB转串口还有一台通过GPIB卡通信USB总线的大流量传输可能导致其他USB设备掉线。第三数据完整性问题。系统突然蓝屏或断电正在写的测试记录可能丢失导致追溯链条断裂。第四驱动兼容性坑多。USB转串口的芯片方案五花八门有的廉价模块在高波特率下丢字节有的GPIB卡在新系统版本上找不到驱动。这些难题我在项目里都踩过后面会逐个讲对应的解法。先记住一个总原则非实时系统做测试核心思路不是去和系统争抢实时性而是通过架构设计和流程规范把对实时性的依赖降到最低把非确定性因素的影响控制在可接受范围内。2. 整体方案设计与架构拆解2.1 分层设计是方案的地基我见过很多失败的自动化测试项目共同点就是所有代码揉在一起界面直接调用仪器指令用例逻辑和驱动细节混着写测试数据硬编码在脚本里。这种写法在只有一两个测试项、设备固定时勉强能跑一旦测试项增多、设备更换维护成本直接爆炸。正确做法是分层设计。我一般把整个系统分成四层资源管理层负责所有硬件资源的抽象和调度包括仪器设备的连接、初始化、自检、关闭以及设备状态的监控。驱动适配层封装与具体设备通信的底层细节对上层提供统一的接口。比如万用表不管你是Keysight的还是Fluke的上层调用都是read_voltage()驱动层去处理不同仪器的SCPI指令差异。测试执行层负责测试用例的加载、执行、判据判定、结果收集。这一层不关心设备具体怎么通信只关心测试流程怎么编排。业务展示层负责测试流程配置、执行状态显示、数据报表生成。这一层和用户打交道做得友好与否直接影响产线工人的操作效率。分层的好处是在设备替换时只需要改驱动适配层的代码增加测试项时只需要在测试执行层加用例改动界面逻辑时不会碰到底层通信。我负责过的一条产线后来更换了万用表型号前后只用了两天时间完成适配靠的就是分层架构。2.2 关键技术选型与理由软件框架的选择上我推荐用Python作为主力开发语言。原因有三一是生态丰富pyvisa、pySerial、pymodbus这些库把底层通信封装得比较完善二是开发效率高写用例的速度比C#快不少适合测试场景多变的现实三是报表和数据分析能力强Pandas加matplotlib的组合足够应付大多数数据整理需求。如果团队里有人更熟悉C#WinForms或WPF界面开发会更顺手底层可以做个C#版本的通信类库。但这里有一个选择的关键考量硬件测试的核心资产是不断积累的测试用例和测试方法并不局限于语言生态建议以开发效率和转岗接手友好度作为优先标准只要性能达标不要过度追求底层语言。通信总线这块短距离、设备数量不多的时候优先用USB或串口距离远、抗干扰要求高时用GPIB或以太网。需要注意的是产线上不建议用蓝牙或Wi-Fi做关键数据传输干扰和延迟会让你排查问题找到怀疑人生。仪器控制方面VISAVirtual Instrument Software Architecture是绕不开的中间层。它能屏蔽不同接口USB/GPIB/串口的差异让你用同一套SCPI指令去控制不同型号的仪器。这是自动化测试的基石基本所有主流仪器厂商都提供支持。2.3 架构设计上怎么规避非实时风险在架构层面就要提前把非实时系统的“坑”兜住。我的经验是三件事第一引入消息队列。测试用例之间、界面和底层之间不要直接用全局变量传数据用消息队列或者事件总线解耦。这样底层采集的数据不会因为界面卡顿而丢失队列本身能起到缓冲作用。第二建立心跳监控机制。测试软件定时和仪器交互超过设定时间判定设备异常自动重连或者报错暂停。这个机制能有效避免设备假死导致整个测试流程挂起。第三数据持久化要异步。测试记录、日志写入不能阻塞主流程通过独立线程或进程处理防止IO抖动影响测试的连续性。这三招看着简单但在非实时系统上非常管用基本能滤掉大部分由系统不确定性引发的问题。3. 核心模块实现与实操要点3.1 设备接入与驱动适配的落地写法驱动适配层是整套系统里最基础也最容易踩坑的部分。我提供一个大致的思路对每一类设备定义一个基类声明这个类型设备的基本能力。比如万用表基类里有read_voltage_dc()、read_current_dc()、read_resistance()然后针对具体型号做实现。每个具体型号的实现里封装该设备特有的初始化流程、SCPI指令、数据解析方式。这里要特别强调初始化的重要性。很多新手直接上来就发指令发现返回值不对就怀疑自己指令写错了其实是设备没完全进入远程控制状态。正确姿势是上电后先发IDN?确认设备型号和固件版本再发RST做一次复位然后针对测试需求配置量程、积分时间、触发源。量程配置是个容易被忽略的细节。你让万用表自动量程它会先跳到最大量程再往小量程找这个过程通常要几百毫秒。如果测试项对时间敏感必须手动指定量程才能把单次读数时间控制到稳定值。3.2 测试执行引擎的设计思路测试执行引擎是整个系统的发动机它决定了一次测试“先干什么后干什么”以及“这个结果算不算通过”。我的设计里每个测试用例是一个独立的执行单元包含五个要素前置条件检查、测试动作、数据采集、判定逻辑、后置处理。前置条件检查负责判断设备状态是否就绪比如设备的NTP是否同步、继电器是否在初始态。测试动作是核心操作比如给DUT上电并发送一个配置指令。数据采集支持多种方式包括主动读取仪表的返回值或者监听DUT发出的串口数据。判定逻辑则是把采集的数据和规格书上的上下限做比较这个比较要考虑容差和单位换算。后置处理负责把仪器恢复到安全状态防止下一个用例被干扰。执行引擎内部建议用状态机来管理整个测试流程初始态、设备就绪态、执行中、暂停、异常中断、完成。每个状态下定义允许的转入动作这样即使发生异常也能知道当前卡在哪个环节便于排查。我在产线上遇到过半夜测试中途停掉的情况第二天早上过来通过状态机和日志能快速定位是哪个用例的数据采集超时解决了就很高效。3.3 测试序列流转与数据采集逻辑再来聊聊测试序列和数据采集怎么协同。测试序列是一串用例的有序集合每个用例执行完引擎根据结果决定是继续下一个用例还是跳转到异常处理分支。比如电源模块测试里先测输入浪涌再测输出电压精度浪涌没过就不需要继续测输出了直接判定不合格并做断电保护。数据采集的逻辑需要细化到位。注意这里不是简单的“发指令、收数据”而是要区分“点采”和“连续采”两种模式。点采就是时刻A读一个电压间距已知连续采则是以设定的采样间隔持续记录数据比如记录DUT上电后5秒内的电压跌落曲线。连续采对时序敏感非实时系统做连续采的时候不能依赖软件延时来保证间隔得靠设备自身的采样功能或者带时间戳的采集卡软件只负责读取。我在做电源老化监控的时候就是让电源模块每100毫秒上报一次电压值上位机每收到一条数据就盖上接收时间戳并落库。即使系统调度偶尔抖动导致接收延迟每条数据的真实上报时间还是可以从数据内容里解析出来这样曲线依然准确。这个思路叫“时间戳后补”是非实时系统做数据采集的惯用技巧。3.4 报表与日志系统的设计要点报表系统和日志系统看似简单实则最容易在后期暴露问题。我见过不少项目测试功能全通了报表却没法用因为格式不符合质量部门要求或者追溯信息不全。设计报表系统之前先问三个问题谁要看这份报告他关注什么字段报告要保留多久产线工人关心的是“这台过没过”工程师关心的是“数据趋势有没有异常”质量部门关心的可能是“这批货的测试记录能否对齐”。基于这个理解我一般设计两套报表一套是系统自动生成的结构化数据报表存到数据库里方便追溯和二次分析另一套是人读的PDF/Excel汇总展示通过率、不良项、关键参数分布给管理层快速浏览。日志系统需要分级别管理调试级记录每条指令和返回值、信息级记录测试流程节点、警告级记录异常但未中断的项、错误级记录导致中断的故障。日志要带上模块名、时间戳、线程ID这样多线程环境下也能追踪到具体来源。日志文件按天切割保留至少90天防患于未然。4. 完整实操从方案到产线运行4.1 落地前的硬件资源配置实操的第一步不是写代码而是把硬件资源规划清楚。我以一条中等规模的电源模块测试线为例标准配置大概是一台工控机作为测试主机一台程控直流电源给DUT供电一台电子负载模拟不同负载条件一台数字万用表测量输出电压电流一个串口服务器或者USB集线器统一管理通信线缆再加上一个报警灯和急停按钮。硬件接线有个原则电源线和通信线分开走线尽量避免平行长距离走线防止串扰。如果DUT有大电流开关动作建议用屏蔽双绞线做通信屏蔽层单端接地。设备地址管理也要提前规划。GPIB设备有地址冲突风险建议在工位图上画一个地址分配表USB设备建议在系统里把每个设备的序列号绑定固定端口防止开机后端口顺序变了导致映射错乱。4.2 软件部署的具体步骤部署这事看着简单实际操作起来坑不少。我的标准流程是这样的第一步装好操作系统后先做系统精简优化把自动更新、休眠、屏幕保护全部关掉因为产线机器不需要这些功能任何一个都可能中断测试或拖慢系统。第二步安装仪器厂商提供的VISA库比如Keysight IO Libraries或TekVISA装完一定要重启否则SDK可能无法正常注册。第三步用厂商工具扫描设备确认所有仪器都能被识别并分配了资源名比如USB0::0x2A8D::0x1301::MY57212345::INSTR这种格式。第四步Python环境建议用虚拟环境搭建把项目依赖锁固定在版本号里。这一步能省掉后面环境变化导致“开发环境跑得好好的到产线就不行”的麻烦。第五步配置系统的任务计划程序加入看门狗脚本定期检查测试软件进程是否存活挂了就自动重启并记录日志。产线长时间运行没有看门狗是不行的。4.3 测试用例编写的标准模板测试用例写得规不规范直接影响后续的维护。我在团队里推行过一个模板每个用例文件包含用例名称、编号、适用产品版本号、所需的设备资源列表、测试步骤序列、判据参数、异常处理策略、预设的重试次数。判据参数单独放到配置文件里方便质量人员在不改代码的情况下调整规格。比如输出电压精度上限原来是±1%后来客户要求收紧到±0.5%直接改配置文件重启就生效不用重新发版。异常处理策略要写清楚发生何种错误时重试重试几次连续失败时的降级路径是什么再明确测试失败后的自动动作比如是否切断DUT电源、是否弹出提示交给人工判定。4.4 时序控制与稳定性调优时序控制在非实时系统上是最讲究的部分。我的经验是把时序敏感度分成三个等级去处理不敏感级500ms直接软件延时控制简单可靠。中等敏感级50-500ms优先用查询设备状态寄存器的方式代替固定延时。比如你要等电源输出稳定与其sleep 200ms不如循环查询它的输出状态位这样实际时间由设备自己说了算。高敏感级50ms不在Windows应用层做控制改用设备自带的序列能力或利用采集卡的硬件触发软件只负责配置下发和数据读取。系统稳定性的调优有几个细节测试软件的主线程尽量只做流程控制和UI刷新耗时操作放到工作线程通信超时统一设置串口建议1-2秒VISA建议5-10秒避免某些无响应的设备把整个流程卡死内存管理要注意长时间运行的软件最怕内存慢慢涨建议每执行完固定数量的用例就主动回收一次资源。5. 常见问题与排查技巧实录5.1 设备偶尔连不上或掉线这是我被问得最多的问题也是最让人抓狂的问题。设备刚开机时能识别测试到一半突然报错找不到设备重试就好过一会又犯。排查思路是这样的先看是不是供电不稳导致设备重启。很多仪器对输入电压有要求产线电网波动大设备可能瞬间掉电又上电此时上位机再看之前的连接就发现已经断开了。对策是给仪器加UPS或稳压电源。其次看USB线材质量尤其是廉价USB转串口线信号质量差容易导致偶发丢包建议换带磁环的品牌线。再看是不是多个设备共用一个USB HUB带宽竞争导致枚举失败简单粗暴的解法是每个高速设备独占一个USB口。最后检查设备自身的看门狗功能有些仪器长时间不通信会自动断开远端接口需要定时发心跳指令保持会话。排查工具方面直接从堆栈日志里抓取通信异常时设备返回的完整错误码用厂商的IO工具复现效率远比猜测高。5.2 数据偶发偏差时好时坏测试结果不稳定是最难定位的问题之一因为大概率不是软件逻辑错了而是物理层面出了问题。我先检查是不是测试信号受到干扰。比如继电器切换的瞬间接触火花会产生高频噪声耦合到测量回路导致万用表读数跳变。对策是加RC吸收电路或者信号滤波测量时等继电器稳定后再触发采集。再看是不是接触电阻变化导致读数漂移。产线上测试治具老化后探针接触电阻会增大刚压下去和压久了的读数可能不一样这需要定期做治具点检。还要看是不是仪器量程设置不当。自动量程下读数在量程边界附近来回切换会导致数据跳变这时候手动固定量程往往能解决。软件侧还有一种情况多次读取的线程间没有加锁导致数据和指令错位。比如你发了“读取电压”的命令还没收到结果另一个线程又发了“切换量程”的命令设备缓冲区里残留的响应就会张冠李戴。这种问题检查代码反而难看出来加日志和时间戳就能锁定。5.3 长时间运行后性能下降产线测试最怕跑着跑着越来越慢最后卡死。这个问题百分之八十是资源泄漏。我在自己的项目里就遇到过测试软件每跑一轮就新建一个通信会话不关闭一天跑下来操作系统的句柄数暴涨最后系统崩溃。排查方法是先看任务管理器里的句柄数、GDI对象数、内存占用如果随时间单调递增而不会回落基本可以确定是泄漏。常见泄漏源头包括串口对象没释放、数据库连接没关闭、临时文件没清理、日志句柄没回收。还有一个容易被忽略的点仪器面板每次通信都会在内存里缓存位置参数长时间累计会膨胀需要定期清理。如果泄漏排查不出来一个兜底方案是定期重启测试软件比如每天夜班交接时自动重启一次产线测试不中断这种工程上的妥协是值得的。5.4 多线程导致的通信串扰测试软件追求效率往往会开多个线程分别控制不同仪器但这就带来了通信串扰的风险。典型的翻车场景是两个线程各自向同一个串口写指令结果指令交错发出去设备收到的是拼接后的乱码响应自然不对。对策很简单同一路物理通信通道无论逻辑上被多少个线程使用底层发送必须串行化通过加锁或者使用线程安全的队列来保证每次只发一条完整指令。还有硬件流控要开启防止缓冲区溢出丢数据。另外多个线程共用一个VISA资源时VISA会话级别的锁也要处理否则可能出现一边读一边被另一个线程关闭句柄的诡异问题。在非实时系统上这类“玄学”问题追根溯源大多是并发控制没做到位。6. 方案效果评估与现实边界从实际经验来看这套基于非实时系统架构的硬件自动化测试方案在绝大多数硬件测试场景下都能达到很高的稳定性和有效性。我自己带过的项目里一条12小时连续运行的产线测试工位良品判定与人工复测的一致性能维持在99%以上单个测试项的耗时波动在几十毫秒级别对产线节拍没有明显影响。尤其是可追溯性这块系统能做到每一条测试记录都有完整的时间戳、设备ID、测试程序版本号这在质量审计时非常省心。当然我也得说清楚方案的能力边界。如果被测对象涉及亚毫秒级的信号边沿、严格的总线同步时序、多通道高精度的同步采样那非实时架构的确不适合建议认真考虑实时系统或专用的硬件测试平台。方案本身不是万能的但胜在灵活、经济、可快速迭代。对大多数研发验证测试和量产产线功能测试来说这套思路完全够用而且能带来立竿见影的效率提升。我个人实际体会最深的一点的链路可靠性管理几乎是生死线。设备连接管理、心跳检测、异常重连机制、数据持久化的完整性这些做得越扎实产线运行就越省心。同时要重视看门狗和定期自检这套系统不需要人天天盯着才叫自动化。最后分享一个小技巧初期用小批量试运行两周积累设备掉线率、测试项耗时的基线数据再根据基线去优化超时参数往往能发现很多开发期间根本想象不到的问题。这套方案后续还可以扩展联网看板、数据上云做SPC分析路会越走越宽。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →