TestStand 代码模块开发最佳实践【1】
概览
使用?TestStand?创建?测试?程序?时,?核心?测试?功能?在?单独?的?代码?模?块?中?实现。?TestStand?提供?的?适?配?器?可?调?用?使用?各种?编?程?环境?和?语言?(例如?LabVIEW、?LabVIEW NXG、?LabWindows?/?CVI?、?C#、?VB .NET、?C/?C?+?+和?ActiveX)?开发?的?代码?模?块。??本文?档?讨论?了?开发?测试?系统?代码?模?块?并从?测试?序列?中?调?用?这些?模?块?时?可能?会?用到?的?最佳?实践。?要?使用?本文?档,?您?需要?掌握?TestStand?的?基本?工作?原理,?其中?包括?创建?基本?测试?序列?的?方法。?如果?您?不?熟悉?这些?概念,?请在?使用?本文?档?之前?了解?以下?入门?资源:NI TestStand 基础学习篇
内容
- 确定?代码?模?块?开发?的?策略
- 选择?要?实现?功能?的?位置
- 实现?代码?模?块?的?最佳?实践
- 使用?代码?模?块?中的?仪器
确定?代码?模?块?开发?的?策略
开始?开发?测试?系统?之前,?请?考虑?为?测试?系统?的?以下?方面?确定?一种?通用?方法:
- 代码?模?块?的?粒度 — 定义?每?个?模?块?的?功能?范围。
- 定义?测试?代码?的?目录?结构 — 定义?明确?的?目录?结构?使?开发?人员?之间?可以?更?轻松?地?共享?代码,?且?更易?于?测试?系统?的?代码?部署。
代码?模?块?的?粒度
在?设计?测试?系统?时,?请?务必?为?代码?模?块?定义?一致?的?粒度?级别。 粒度?是?指?测试?系统?中?每?个?代码?模?块?的?功能?范围。 粒度?低?的?测试?序列?调?用?的?代码?模?块?数量?少,?每?个?代码?模?块?执行?的?功能?更多;?而?粒度?高?的?测试?序列?调?用?的?代码?模?块?数量?多,?每?个?代码?模?块?执行?的?功能?更少。
低?粒度 | 高?粒度 |
|
|
由于?二者?各有?优势,?因此?您?应该?在?这些?极端?情况?之间?取得?平衡。
利用?不同?的?粒度?级别?实现?简单?测试
为了?在?整个?测试?系统?中?保持?一致?的?粒度,?需要?为?代码?模?块?开发?创建?一?组?标准,?例如:
- 在?单独?的?代码?模?块?中?执行?硬件?初始?化?和?关闭,?让?TestStand?管理?硬件?会话?的?生命?周期。
- 为?每?个?需求?项目?创建?单?个?测试?步骤,?从而?根据?测试?需求?确定?粒度。 这种?方法?可以?更?轻松?地?确保?所有?要求?均?得到?满足。 此外,?NI Requirements Gateway?可与?TestStand?搭配?使用,?创建?测试?步骤?与?需求?文?档?之间?的?关联。 如需?更多?信息,?请?参阅《NI Requirements Gateway?与?TestStand?搭配?使用》?教程。
- 所需?的?测试?结果?结构?可?用于?帮助?确定?各个?步骤?的?范围。 由于?每?个?步骤?都会?生成?一个?结果?条目,?因此?创建?测试?步骤?到?所需?结果?条目?的?一对?一?映射?将使?组织?测试?结果?变得?更?容易,?且?对?报告?或?数据?库?记录?的?更改?最少。
定义?序列?文件?和?代码?模?块?的?目录?结构
指定?测试?步骤?中?代码?模?块?的?路径?时,?可?选择?使用?绝对?路径?或?相对?路径。?建议?不要?使用?绝对?路径,?原因?如下:
- 在?磁盘?上?移动?序列?文件?及其?依赖?项?后,?相应?路径?将?失效。
- 如果?将?序列?文件?部署?到?目标?计算?机,?除非?文件?安装?在?同一?位置,?否则?相应?路径?将?失效。
指定?相对?路径?时,?TestStand?会?使用?搜索?目录?列表?来?解析?路径。 这些?搜索?目录?通常?包含?当前?序列?文件?目录、?TestStand?特定?目录?和?系统?目录。
在?开始?开发?之前,?请?务必?为?测试?序列?和?代码?模?块?定义?文件?结构。 请?按照?以下?指南?定义?用于?存储?序列?文件?和?代码?模?块?的?策略。
- 对于?用于?单?个?序列?文件?的?代码?模?块,?请将?代码?模?块?文件?保存?在?与?序列?文件?相关?的?子?目录?中。 这?将?确保,?即使?序列?文件?在?系统?中?移动?或?复制?到?另?一个?系统?上,?它?也?能够?找到?代码?模?块。
- 对于?在?多个?相关?序列?文件?之间?共享?的?代码?模?块,?如果?相关?序列?文件?保存?在?同一?目录?中,?则?可以?使用?与?单?个?序列?文件?相同?的?方法。 考虑?创建?一个?工作?区?来?容纳?所有?相关?的?序列?文件?和?代码?模?块。
- 对于?在?多个?不?相关?的?序列?文件?之间?共享?的?代码?模?块,?请?考虑?创建?一个?特定?目录?来?容纳?所有?共享?的?代码?模?块,?并?创建?指向?此?位置?的?新?搜索?目录。 这?将?确保?系统?中的?所有?序列?文件?都可以?使用?此?搜索?目录?的?相对?路径?来?找到?相应?文件。 部署?代码?模?块?时,?可?同时?部署?位于
?\Cfg?\SearchDirectories.cfg的?搜索?目录?配置?文件。 使用?此?方法?时,?请?不要?在?目录?内?移动?代码?模?块?文件,?以免?破坏?调?用?序列?文件?时?指定?的?路径。
定义?目录?结构,?其中?代码?模?块?位于?序列?文件?的?子?目录中
使用?TestStand?部署?工具?部署?测试?代码?时,?可?为?序列?文件?和?相关?代码?模?块?选择?特定?的?目标。 如果?序列?文件?和?代码?模?块?的?目标?目录?之间?存在?相对?路径,?则?TestStand?部署?工具?会?更新?序列?文件?中的?路径?来?指向?更新?后?的?位置。 在?大?多数?情况?下,?最好?使?部署?的?目录?结构?与?开发?系统?上?的?目录?结构?相?匹配,?从而?确保?部署?与?开发?计算?机上?的?代码?尽可能?相似。
选择?要?实现?功能?的?位置
在?定义?测试?系统?的?代码?模?块?范围?时,?请?务必?定义?在?代码?模?块?和?序列?文件?中?实现?功能?的?策略。?以下?部分?可?帮助?确定?最?适合?实现?常用?功能?的?位置:
- 根据?极限?评估?测试?测量值
- 定义?激励值
- 报告?并?记录?测试?结果?和?错误
- 循环?操作
- 执行?开关?操作
- 执行?计算?和?处理?数据
评估?极限?和?测试?结果
理想?情况?下,?代码?模?块?应?包含?与?获得?测试?测量?值?直接?相关?的?功能,?并且?测试?序列?应?处理?原始?测试?结果。?这种?方法?具有?以下?优势:
- 由于?在?序列?文件?中?可?使用?属性?加?载?器?等?工具?在?单?个?中心?节点?管理?多个?步骤?的?极限,?因此?测试?极限?在?序列?文件?中?更易?于?管理。
- 序列?中?定义?的?测试?极限?将?自动?添加?到?测试?结果?中,?例如?报告?或?数据?库。
- 测试?极限?可在?不?更改?代码?模?块?的?情况?下?进行?更新,?并且?由于?只?修改?了?测试?序列,?因此?所需?的?验证?更少。
为了?简化?测量,?代码?模?块?可以?将?原始?测量?值?返回?到?序列?中?进行?处理。?例如,?如果?测试?步骤?用于?测量?待?测?设备?(UUT)?特定?引?脚上?的?电压,?则?代码?模?块?应?返回?测量?值,?而不是?直接?在?代码?模?块?中?执行?检查。 您?可以?使用?数值?边界?测试?步骤?来?处理?该?值,?从而?确定?序列?文件?中的?测试?结果。
在?测试?步骤?中?评估?极限?可?简化?代码?模?块?并?改进?结果?记录
但是,?由于?某些?测试?十分?复杂,?因此?并非?总是?能够?在?序列?文件?中?处理?原始?测试?结果。 对于?更?复杂?的?测量,?可能?需要?对?结果?数据?进行?进一步?处理。 复杂?数据?可?处理?为?单?个?字符?串?或?数值?结果,?然后?便?可以?在?TestStand?中?使用?字符?串?或?数值?比较?功能?对?其?进行?评估。 例如,?扫?频?测试?的?结果?很?复杂,?无法?直接?进行?评估,?但?可以?将?这些?数据?处理?为?代表?最小值?的?单?个?数字。 在?这种?情况?下,?代码?模?块?应?评估?处理?后?的?结果,?并?以?单独?的?参数?形式?返回?频率?数据,?以便?记录,?如?下面?的?移动?设备?测试?示例?所?示:
对于?更?复杂?的?数据,?请在?代码?模?块?中?处理?数据,?生成?数值?或?字符?串?结果,?然后?使用?参数?传?出?原始?数据,?以便?记录
如果?原始?数据?非常?大,?则?将?数据?传递?给?TestStand?的?过程?可能?会对?性能?产生?重大?影响。 在?这种?情况?下,?可?考虑?将?数据?直接?记录?到?TDMS?文件?中,?并?在?测试?报告?中?添加?指向?该?文件?的?链?接。 如此?一?来,?可在?无?需?将?数据?传递?给?TestStand?的?情况?下?从?报告?中?引用?数据。 关于?此?方法?的?更多?信息,?请?参阅《在?报告?中?添加?超?链?接 — TDMS?文件》。
如果?该?步骤?无法?使用?测试?步骤?中?可用?的?评估?类型?来?确定?测试?结果,?请?考虑?创建?具有?附加?功能?的?新?步骤?类型?来?处理?所需?的?测试?类型。 关于?创建?自?定义?步骤?类型?的?更多?信息,?请?参阅?本?系列?中的《自?定义?步骤?类型?开发?的?最佳?实践》?一文。
定义?测试?激励
对于?许多?测试?而言,?UUT?或?测试?环境?必须?处于?特定?状态?下?才能?执行?测试。 例如,?进行?温度?测量?可能?需要?使用?激励?电压,?或者?必须?将?加热?室?设置?为?指定?温度。 对于?这些?类型?的?模?块,?应?使用?参数?来?传递?输入?值,?例如?激励?电压?或?所需?温度。 与?上?一部分?所述?的?直接?在?代码?中?处理?极限?相比,?这?与?在?测试?代码?模?块?中?返回?原始?数据?具有?许多?相同?的?优势。
记录?测试?结果
TestStand?具有?使用?测试?步骤?的?结果?来?生成?报告?和?记录?数据?库?的?内?置?功能。?因此,?请?避免?直接?在?代码?模?块?内?进行?任何?类型?的?数据?记录。 相反,?请?确保?将要?记录?的?所有?数据?以?参数?形式?传?出,?并?使用?TestStand?记录?相应?数据。 一些?数据?(例如?测试?结果、?极限?和?错误?信息)?将?自动?记录。 要?记录?其他?数据,?可?使用?其他?结果?功能?来?指定?要?添加?到?报告?中的?其他?参数。
关于?将?结果?添加?到?测试?报告?中的?更多?信息,?请?参阅?TestStand?随?附?的《将?自?定义?数据?添加?到?报告》?示例。
如果?您?对?记录?有?特定?要求,?请?考虑?修改?或?创建?结果?处理?插?件。?如此?一?来,?可以?使用?内?置?的?TestStand?结果?收集?功能?收集?结果,?同时?可以?确定?结果?的?处理?方式?和?显示?方式。?如需?更多?信息,?请?参阅《TestStand?过程?模型?开发?和?自?定义?的?最佳?实践》?文?档?的“创建?插?件”部分
循环?操作
由于?实现?循环?的?每?种?方法?都有?其?自身?的?优?缺点,?因此?很?难?确定?理想?的?方法。?请?使用?以下?指南?来?帮助?确定?最?适合?您?的?应用?程序?的?策略:
在?代码?模?块?中?进行?内部?循环
- 性能?得以?提高,?尤其是?在?快速?循环?时。 由于?每次?代码?模?块?调?用?都会?产生?几?毫秒?的?开销,?因此?使用?外部?循环?进行?数百?或?数?千?次?迭代?循环?会?影响?测试?速度。
- 支持?更?复杂?的?循环?行为。
在?序列?文件?中?进行?外部?循环
- 直接?在?序列?文件?中?查看?和?修改?循环?设置,?不需要?修改?代码?模?块。
- 轻松?访问?序列?文件?中的?循环?索引。 这?对于?确定?基于?当前?迭代?而?变化?的?开关?路?由?或?其他?行为?很有?用。
- 循环?的?每次?迭代?均?单独?记录,?在?报告?或?数据?库?中?显示?每次?迭代?的?结果。
执行?开关?操作
许多?测试?系统?可?借助?开关?功能?使用?单?个?硬件?测试?多个?待?测?区。 借助?预?定义?的?路?由,?开关?功能?支持?以?编?程?方式?控制?连接?到?特定?硬件?的?待?测?设备?(UUT)?引?脚。
您?可以?通过?以下?方式?在?TestStand?代码?模?块?中?实现?开关?功能:
- 使用?步骤?的?内?置?开关?属性?(需要?NI Switch Executive)
- 使用?TestStand IVI Switch?步骤?(仅?适用?于?32?位?TestStand)
- 直接?在?代码?模?块?中?调?用?开关?驱动?程序?函数
使用?NI Switch?硬件?时,?NI Switch Executive?可?用于?快速?定义?路?由。?在?可以?访问?NI Switch Executive?的?情况?下,?使用?内?置?的?步骤?设置?来?实现?开关?功能?通常?是?最佳?方法,?此?方法?具有?以下?优势:
- 在?步骤?中?定义?开关?配置?可以?将?开关?函数?与?测试?代码?分离,?从而?提高?可?复?用?性?并?降低?代码?模?块?的?复杂?性。
- 开关?设置?中的?许多?字?段?都是?通过?表达?式?指定?的,?因此?可?利用RunState.LoopIndex属性?或?其他?变量?来?为?要?迭代?的?步骤?建立?路?由?或?路?由?组?名称?的?索引。
- 对于?并行?测试,?可在?路?由?字符?串?中?添加?测试?插?槽?索引(RunState.TestSockets.MyIndex),?对?每?个?测试?插?槽?使用?不同?的?开关?路?由。
- 连接?生命?周期?可与?步骤、?序列、?线?程?或?执行?关联?起来。
使用?NI Switch Executive?直接?在?TestStand?步骤?设置?中?指定?路?由,?包括?TestStand?表达?式?支持,?从而?使用?当前?循环?索引?或?其他?属性?来?动态?确定?路由
关于?使用?开关?步骤?属性?整合?开关?功能?的?更多?信息,?请?参见《借助?NI Switch Executive?加速?开发?并?简化?维护》?在?线?教程。
执行?计算?和?处理?数据
为了?避免?为?较?简单?的?任务?维护?代码?模?块,?可?使用?TestStand?中的?表达?式?语言?来?执行?基本?计算?和?单?维?数?组?操作。?由于?编?程?语言?提供?了?更?适合?这些?任务?且?更?强大?的?功能,?因此?应?在?代码?模?块?中?执行?更?高级?的?编?程?要求。 例如,?与?使用?表达?式?语言?相比,?使用?原生?LabVIEW?创建?数?组?函数?可?更?轻松?地?完成?多?维?数?组?的?连接。
在?某些?情况?下,?可?使用.NET?框架?随?附?的?原生?类?避免?创建?过于?复杂?的?表达?式。 例如,?System.IO.Path?类?可在?无?需?创建?代码?模?块?的?情况?下?用于?快速?执行?路径?操作。
无?需?代码?模?块?的?参与,?即可?借助.NET?步骤?来?使用.NET?框架?方法
实现?代码?模?块?的?最佳?实践
实现?代码?模?块?时,?许多?设计?决策?都会?影响?创建?的?许多?代码?模?块。 本?部分?提供?有关?以下?概念的?指南:
- 将?数据?从?TestStand?传递?到?代码?模块
- 处理?代码?模?块?中的?序列?终止
- 向?TestStand?报告?代码?模?块?错误
- 管理?代码?模?块?的?执行?速度?和?内存?使用
将?数据?从?TestStand?传递?到?代码?模块
访问?代码?模?块?中的?TestStand?数据?的?方法?有?两?种:
- 通过?代码?模?块?参数?传递?数据
- 使用?TestStand API?在?代码?模?块?内?直接?访问?数据
在?大?多数?情况?下,?与?使用?TestStand API?直接?访问?数据?相比,?使用?参数?传递?数据?是?一种?更好?的?方法,?具体?原因?如下:
- 出?错?可能性?更低 — 由于?参数?值?是在?TestStand?的?步骤?类型?设置?中?定义?的,?而不是?直接?在?代码?模?块?中?定义?的,?因此?更?容易?发现?属性?名称?或?数据?类型?中的?错误。
- 更易?于?维护 — 对?步骤?属性?的?更改?是在?TestStand?的?参数?配置?中?指定?的,?无?需?修改?代码?模?块。
- 更?容易?在?TestStand?之外?复用 — 由于?代码?模?块?不?依赖?于?TestStand API,?因此?模?块?无?需?修改?即可?在?TestStand?之外?使用
尽可能?使用?参数?将?所需?数据?传递?到?代码?模块
但是,?根据?步骤?的?状态,?当?代码?模?块?需要?动态?访问?各种?数据?时,?使用?API?直接?访问?属性?可能?很有?帮助。 在?这种?情况?下,?使用?步骤?参数?会?导致?参数?过多,?而?在?不同?情况?下,?实际?用到?的?参数?只有?一部分。
如果?要?在?代码?模?块?中?使用?TestStand API,?则?需要?向?SequenceContext?对象?(ThisContext)?传递?一个?引用?作为?参数。?SequenceContext?对象?可?访问?所有?其他?TestStand?对象,?包括?TestStand?引擎?和?当前?的?Runstate。?如果?使用?终止?监视?器?或?模?态?对话?框?VI,?则?需要?序列?上下文?引用。
使用?SequenceContext?访问?代码?模?块?中的?TestStand API,?可?用于?以?编?程?方式?访问?数据
如果?要?在?TestStand?之外?复?用?代码?模?块,?请?记住,?只有?在?从?TestStand?序列?调?用?相应?模?块?的?情况?下,?才能?使用?TestStand API?进行?操作。?模?块?通过?API?从?TestStand?获取?的?所有?数据?将?不可?用。 从?TestStand?外部?调?用?代码?模?块?时,?可先?检查?序列?上下文?引用?是否?为?空,?从而?定义?获取?测试?数据?的?备用?机制。 在?LabVIEW?中,?可以?使用Not A Number/?Path/?Refnum?函数,?它?会?返回?一个?布?尔?值,?如?图?3?所?示。
对于?在?TestStand?之外?使用?的?代码?模?块,?请?使用Not a Number/?Path/?Refnum?检查?SequenceContext?对象?引用?的?有效性
在?代码?模?块?中?处理?大型?数据集
在?许多?情况?下,?代码?模?块?会?在?测量?或?分析?过程?中?生成?大量?复杂?数据。 由于?TestStand?会?在?存储?此类?数据?时?创建?数据?副本,?因此?请?避免?将?此类?数据?存储?在?TestStand?变量?中。 这些?副本?可能?会?降低?Runtime?性能?和/?或?导致?内存?不足?错误。 使用?以下?方法?来?管理?大型?数据?集,?即可?避免?创建?不必要?的?副本:
- 在?代码?模?块?内?处理?大型?数据?集,?例如?在?获取?数据?的?同一?代码?模?块?中?分析?数据,?并且?仅?向?TestStand?返回?所需?的?结果
- 在?TestStand?和?代码?模?块?之间?传递?数据?指针。 对于?LabVIEW?代码?模?块,?请?使用数据?值?引用?(DVR)
处理?代码?模?块?中的?序列?终止
用户?按下“终止”按钮?时,?TestStand?会?停止?执行?序列?并?运行?所有“清理”步骤。?但是,?如果?执行?调?用?了?代码?模?块,?则?该?模?块?必须?完成?执行?并?将?控制?权?交回?TestStand,?然后?序列?才能?终止。?如果?代码?模?块?的?运行?时间?超过?数?秒,?或者?模?块?需要?等待?用户?输入?之类?的?条件?发生,?对于?用户?来说,?终止?命令?可能?会?被?忽略。
要?解决?此?问题,?可以?使用?终止?监视?器,?让?代码?模?块?检查?并?响应?调?用?执行?的?终止?状态。?例如,“计算?机?主?板?测试”随?附?范?例会?使用?仿真?对话?框?中的?终止?监视?器,?如下?图?所?示。 如果?测试?序列?终止,?则?检查?终止?状态?VI?会?返回?假?值,?循环?停止。
处理?错误
测试?系统?中的?错误?是非?预期?Run-?Time?行为,?会?妨碍?测试?的?执行。?代码?模?块?产生?错误?时,?请将?该?信息?传?回?测试?序列,?以此?确定?下一步?要?执行?的?操作,?例如?终止?执行、?重复?上?一次?测试?或?提示?测试?操作?员。
要?向?TestStand?提供?来自?代码?模?块?的?任何?错误?信息,?请?使用?步骤的Result.Error容器,?如下?图?所?示。 执行?每?个?步骤?之后,?TestStand?都会?自动?检查?此?属性?来?确定?是否?发生?错误。 无?需?将?错误?信息?从?TestStand?传递?到?代码?模?块。?如果?代码?模?块?向?TestStand?返回?错误,?则?执行?过程?会?引出?分支?到?测试?序列?的?另一?部分,?例如“清理”步骤?组。
您?可以?使用“测试?站?选项”的“执行”选项?卡?中的“Run-?Time?错误”设置?来?确定?TestStand?响应?步骤?错误?的?方式。 通常,?在?开发?用于?协助?调?试?的?序列?时?应?使用“显示?对话?框”选项,?因为?此?选项?可?中断?执行?并?检查?序列?的?当前?状态。 对于?已?部署?的?系统,?请?考虑?使用“运行?清理”或“忽略”选项,?而不是?要求?测试?操作?员?进行?输入。 错误?信息?将?自动?记录?到?测试?结果?中,?可?用于?查找?错误?的?原因。
将?错误?信息?传递?到?Step.Result.Error?容器,?用于?通知?TestStand?是否?发生?了?步骤?错误
管理?代码?模?块?的?性能?和?内存?使用
默认?状态?下,?在?文件?中?执行?序列?时,?TestStand?会?将?序列?文件?中的?所有?代码?模?块?加?载到?内存?中,?并?保持?加?载?状态,?直到?关闭?序列?文件?为止。 使用?这些?设置?后,?如果?在?模?块?加?载?的?同时?开始?一个?序列,?则会?出现?初始?延迟。 但是,?由于?模?块?仍在?内存?中,?因此?序列?文件?的?后?续?执行?会?更?快。
步骤?设置?窗?格?的“运行?选项”选项?卡?可?用于?配置?何时?加?载?和?卸?载?代码?模?块。?通常,?默认?的?加?载?选项?可?提供?出色?的?性能,?但是?在?某些?情况?下,?可?将?加?载?选项?设置为动态?加载,?从而?使?代码?模?块?仅?在?使用?时?才?加?载,?这?可能是?一种?更好?的?选择。 对于?不在?常用?执行?中?调?用?的?代码?模?块,?例如?仅?在?特定?测试?失败?后?才?运行?的?诊断,?应?采取?动态?加?载?方式,?因为?在?大?多数?情况?下?这些?模?块?根本?不需要?加?载。
请?注意,?在?动态?加?载?代码?模?块?时,?TestStand?只?会?在?加?载?代码?模?块?之后?才?会?报告?相应?代码?模?块?的?问题,?此时?漫长?的?执行?过程?可能?即将?结束。?但是,?可以?在?执行?之前?使用?序列?分析?仪?验证?序列?中?是否?存在?错误。 分析?仪?将?检查?静态?和?动态?加?载?的?代码?模?块。
对于?内存?密集?型?代码?模?块,?可?修改?默认?的?卸?载?选项?来?减少?总?内存?使用?量。 例如,?将?模?块?设置为步骤?执行?后?卸载或序列?执行?后?卸载。 但是,?此?更改?将?增加?执行?时间,?因为?TestStand?需要?为?每次?后?续?调?用?重新?加?载?模?块。?如有?可能,?可以?使用?64?位?版本?的?TestStand?和?具有?更多?物理?内存?的?系统,?这种?方法?更好,?在?对?内存?使用?量?有?较?高?要求?的?情况?下?仍?获得?出色?的?测试?性能。
如果?代码?模?块?维护?共享?数据,?例如?静态?变量?或?LabVIEW?功能?全局?变量,?由于?在?模?块?卸?载?时?会?丢失?全局?数据,?因此?修改?卸?载?选项?可能?会?导致?行为?改变。?更改?卸?载?选项?时,?请?确保?将?任何?必需?的?数据?传递?到?TestStand?序列?或?存储?在?更?为?永久?的?位置,?防止?数据?丢失。
关于?优?化?测试?系统?性能?的?其他?方式?的?更多?信息,?请?参阅《提高?NI TestStand?系统?性能?的?最佳?实践》。
使用?代码?模?块?中的?仪器
代码?模?块?的?常见?用途?是?与?测试?硬件?连接?以?设置?激励?并?进行?测试?测量。 与?硬件?通信?的?方法?包括:
? 使用?硬件?驱动?程序?(例如?NI-?DAQmx)?直接?与?硬件?通信。
? 使用?仪器?驱动?程序,?此?驱动?程序?可在?内部?通过?VISA?或?IVI?硬件?驱动?程序?将?命令?发送?到?仪器。
所?采用?的?通信?方式?取决?于?使用?的?硬件?类型。 对于?这?两?种?通信,?您?都?需要?在?进行?特定?驱动?程序?的?调?用?之前?打开?针对?驱动?程序?的?引用?或?会话,?并?在?交互?完成后?关闭?句柄。
选择?管理?硬件?引用?的?方法
在?大?多数?情况?下,?您?将?在?多个?测试?步骤?中?与?同一?硬件?进行?通信。?为了?避免?在?每?个?代码?模?块?中?打开?和?关闭?仪器?会话?对?性能?的?影响,?请?务必?考虑?如何?在?测试?序列?中?管理?硬件?引用。 管理?硬件?引用?的?常用?方法?有?两?种:
- 通过?从?代码?模?块?调?用?初始?化?和?关闭?函数?来?手?动?管理?硬件?引用。
- 使用?会话?管理?器?自动?管理?硬件?引用?生命?周期。
如果?使用?的是?仪器?驱动?程序,?或者?使用?VISA?或?IVI?驱动?程序?直接?与?仪器?通信,?除非?特别?需要?直接?控制?硬件?会话?生命?周期,?否则?请?使用?会话?管理?器。 如果?使用?的是?DAQmx?等?硬件?驱动?程序,?则?不能?使用?会话?管理?器,?必须?手?动?管理?引用。
使用?TestStand?变量?手?动?管理?硬件?引用
初始?化?仪器?时,?将会?话?引用?作为?输出?参数?传递?给?调?用?序列,?然后?将?引用?存储?在?变量?中。 然后,?可?将?变量?作为?输入?传递?到?需要?访问?仪器?的?各个?步骤。
包括?NI-?DAQmx?和?VISA?在内?的?许多?驱动?程序?以及?大?多数?仪器?驱动?程序?都?使用?I/?O?引用?数据?类型?来?存储?会话?引用。?在?TestStand?中?使用?LabviewIOControl?数据?类型?来?存储?这些?引用。
使用?LabVIEWIOControl?类型?的?变量?在?代码?模?块?之间?传递?硬件?引用,?例如?DAQ?任务?引用
在?TestStand?和?代码?模?块?之间?显?式?传递?仪器?句柄?时,?请将?硬件?引用?存储?在?局部?变量?中。 如果?硬件?在?多个?序列?中?使用,?请将?句柄?作为?序列?参数?传递?给?有?需求?的?每?个?序列。 避免?使用?全局?变量?存储?硬件?引用,?因为?可能?难以?确保?仪器?已?在?使用?引用?之前?完成?初始?化。
请?使用“设置”步骤?组?初始?化?硬件,?并?使用“清理”步骤?组?关闭?硬件?引用,?具体?原因?如下:
- 由于?清除?步骤?组?总是?在?执行?终止?时?运行,?因此?如果?用户?终止?序列?执行,?硬件?引用?仍?将?关闭。
- 由于?设置?和?清除?步骤?组?会?在?所?选?步骤?之前?和?之后?执行,?因此?可?交互?地?执行?使用?硬件?引用?的?步骤。
使用“设置”和“清理”组?初始?化?和?关闭?硬件?引用
使用?会话?管理?器?自动?管理?硬件?引用
对于?VISA?和?IVI?仪器?句柄,?可?使用?会话?管理?器?自动?管理?硬件?引用。?使用?会话?管理?器?具有?诸?多?优势,?包括:
- 减少?耦合 — 不必?在?软件?组?件?之间?传递?仪器?句柄?变量。?每?个?组?件?都会?指定?一个?逻辑?仪器?名称?来?获取?会话。
- 减少?编?程?语言?障碍 — 用?不同?语言?编写?的?代码?模?块?可以?使用?同一?会话,?而无?需?传递?可能?难以?在?各种?语言?之间?转换?的?句柄。
- 生命?周期?控制 — 由于?仪器?会话?是?具有?引用?计数?的?ActiveX?对象,?因此?可?将会?话?的?生命?周期?与?ActiveX?引用?变量?的?生命?周期?相关?联,?而无?需?使用?支持?ActiveX?引用?变量?的?语言?显?式?关闭?仪器。
会话?管理?器?会?在?创建?会话?后?自动?初始?化?相应?句柄,?并?在?针对?此?会话?的?最后?一个?引用?释放?后?自动?关闭?相应?句柄。?代码?模?块?和?序列?会?传递?一个?逻辑?名称?(例如“DMM1”),?用于?从?会话?管理?器?中?获取?会话?对象,?该?对象?包含?相应?的?仪器?句柄。
使用?会话?管理?器?时,?请将?会话?对象?存储?在?TestStand?对象?引用?变量?中。 由于?会话?生命?周期?与?对象?引用?变量?的?生命?周期?相关?联,?因此?无论?有?多少?序列?代码?模?块?和子?序列?访问?同一?会话,?每次?执行?时?仪器?句柄?都会?初始?化?和?关闭?一次。
在?以下?示例?中,“获取?DMM?会话”步骤?使用?逻辑?名称?获取?针对?DMM?仪器?会话?对象?的?引用。?此?步骤?将会?话?引用?存储?在?局部?变量?中,?使?会话?在?序列?执行?期间?保持?初始?化?状态。
借助?会话?管理?器,?可?使用?逻辑?名称?引用?仪器。 会话?管理?器?VI?使用?逻辑?名称?获取?DMM IO?引用
关于?如何?使用?会话?管理?器?的?更多?信息,?请?参阅
上?一个?示例?序列?从?调?用?会话?管理?器?的?LabVIEW?代码?模?块?中?获取?会话,?而不是?直接?调?用?会话?管理?器,?因为?该?示例?将?LabVIEW?适?配?器?配置?为?在?单独?的?进程?中?运行?VI。 关于?如何?使用?会话?管理?器?的?更多?信息,?请?参阅
调?用?硬件?驱动?程序库
要?与?任意?类型?的?硬件?通信,?需要?使用?驱动?程序?库,?该?库?提供?的?一系列?功能?有助?于?使用?编?程?语言?执行?各种?任务。 使用?驱动?程序?库?时,?通常?会?调?用?多个?VI?或?函数?来?执行?单?个?逻辑?操作,?例如?进行?测量?或?配置?触发?器。 创建?代码?模?块?来?实现?此?功能,?而不是?直接?在?TestStand?步骤?中?调?用?库?函数,?此?方法?具有?以下?优势:
- 避免?了?针对?各?函数?的?步骤?功能?产生?的?开销
- 提供?了?驱动?程序?调?用?和?TestStand?序列?之间?的?抽象层
- 更易?于?跨?测试?程序?共享?实现?过程
本文转载:
https://www.ni.com/content/ni/locales/zh-cn/support/documentation/supplemental/09/teststand-code-module-development-best-practices.html