⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 7.图形化编程软件平台.txt

📁 虚拟仪器软件的介绍
💻 TXT
📖 第 1 页 / 共 4 页
字号:
输入端口/输出端口可表示为 T = (N,D,V,S,IB,OB  ,E),其中:
l   N:数据端口的名称;
l   D: 数据类型;
l   V: 存放数据的变量;
l   S:状态,有三种可能的状态:连线状态(tsConnected),没有连线状态(Null),
更新状态(tsUpdated);
l   IB:  输入端口是否准备好接受数据,相对于输入端口而言;
l   OB:输出端口是否准备好发送数据,相对于输出端口而言;
l   E:以该端口为一端的连线,若S = tsNull,则E = Null;
控制流端口是一种比较特殊的输入/输出端口,它的数据类型及传递的数据本身对
程序毫无影响,我们在程序内部是做了约定的,控制流只是起到流程控制的作用。
      
在图形化平台中,元件的每个输入端口可接受一种或几种数据类型的输入。比如一
个字符串显示面板,它可接受整型数、浮点数、复数、字符串、字节、错误类型等
数据类型。为了实现这些不同类型的数据的传送,我们定义了一组类型变换函数。
当一个元件C1的输出端u与元件C2的输入端v经由边E相连,其中u和v的类型不一致
时,可以通过边E的数据类型转换函数E.F,使v得到正确的数据。边的类型转换函
数是在绘制流程图时确定的,并不是所有数据类型都是允许互相转换的。

7.2.2 图形化编程软件平台运行算法
一、主程序运行算法
在图形化编程软件平台中,有两个主要的数据结构,分别为VIList与EdgeList。
VIList表示程序中所有元件列表,EdgeList表示程序中所有连线的列表,如图7.1
所示。
图7.1数据流程序中的数据结构
一般的图形化平台的运行算法可表示如下:
设C表示一个元件,E表示一条连线,VIList表示程序中所有元件列表,EdgeList表
示程序中所有连线的列表,程序运行按VIList表中的顺序逐个环形扫描程序中的元
件(最后一个元件的下一个元件是表中的第一个元件),判断其可激活条件,若可
激活,则执行当前激活元件Curcomponent的激活函数,否则继续扫描,直到用户干
预。
1、 算法开始,根据VIList表扫描第一个元件; 
2、 对当前元件C作可激活性检查
若C.S = expired , 则 Curcomponent  = Null;
若C.S = active ,  则 Curcomponent  = C;
若C.S = idle , 则,若C.TI = φ,则Curcomponent = C; 
              若C.TI <>φ,且C.TI集合中所有输入端口状态为Null或C. Eв= 
True, 则Curcomponent = C;
             其他,则Curcomponent = Null;
3、 Curcomponent = Null, 则按VIList表顺序扫描下一个元件,并跳到 2;
4、 对激活元件的处理:
4.1 所有输入端口标识为能接受数据,即TI .IB = True;执行Curcomponent的激
活函数C.E;
4.2 若C为用户自定义的子程序或子函数,则对C中包含的所有元件重复1到5的步骤
4.3 相应的输出端口标识为可发送数据 ,即TO.IB = True ;     
5、 根据相应的连线做数据传递,必要时做类型转换,并更新元件及端口的状态:

5.1 若Td.D = Ts.D ,则Td.V = Ts.V;
5.2 否则进行类型转换,Td.V = F(Ts.V);
5.3 当前元件状态标识为C.S = expired, 并设TI .IB = False,TO.IB =  
False;
5.4 设置连线的终止元件的输入端口的状态为tsUpdated;
6、 重复步骤1 到 5,直到用户干预。
上面算法中,VIList表中元件的排列顺序是元件放入程序中的先后次序,不是元件
在程序中的实际运行顺序。这样,要得到最后的运行结果往往要扫描整个VIList表
多次,运行效率不高,也不能很好的体现数据流语言的优点。下面,本文又提出了
在程序运行之前对VIList表的排序算法。
1、 算化开始,初始化排序列表sortlist和暂时列表templist;
2、 扫描VIList表中所有元件,设C为VIList表中一元件,
    若C.TI =φ,或C.TI <>φ且C.TI集合中所有输入端口的状态为Null,则
C -> templist; 
3、 对templist表中元件依优先级排序,元件优先级由元件功能和属性确定;
4、 把templist表中元件逐个加到sortlist表,若sortlist表中有相同的元件,就
删除前面相同的元件,同时清空templist表;
5、 按sortlist表访问下一个元件C,
若C = Null,则VIList = templist,算法结束。
若C <> Null,则依次判断元件C的各个输出端口To:
若C.To.S = tsConnected,则C.To.E.Cd -> templist;
若C为子程序或子函数,则重复步骤1到6 (其中VIList和sortlist分别为子流程内
的元件列表和排序列表),对子流程元件列表进行排序;子流程排序结束后回到上
一层流程(父流程);
6、 重复步骤2到 5。
经排序后,整个程序可以用一个有向图来表示,如图7.2所示。
VIList表中元件表示为图上的顶点,它们的排列对应着图上的序号,其中图中最上
面的顶点(即结点0)是假想的,实际不存在,只是便于有向图描述。图中的有向
边表示数据的流向,虚线1是假想的,只是便于有向图描述;虚线2和实线都是表示
对应两个顶点(图形化编程平台中的元件)之间的实际数据流向,对于它们指向的
同一个顶点,虚线2完成数据传递后并只有等到实线2完成数据传递之后该顶点才能
被激活。
因此,按图1进行类似于图的广度优先搜索遍历的次序就是图形化平台元件按数据
驱动而实际运行的先后次序,也即VIList表中元件的排列次序就是元件在程序中实
际扫描次序。
 

       
图7.2  图形化平台描述程序的有向图
二、子程序运行算法
子程序在程序设计语言中是一个重要的组成部分。应用子程序,可以实现在代码重
用,也使程序的结构显得清晰。一些VPL提出子程序抽象化(Procedural 
Abstraction)技术,在主程序中以一个图标代表子程序,子程序只在需要时才展开
显示。
在图形化平台中,称用户定义的子程序为User Object。子程序与其它元件具有相
同的属性,它内部的数据结构包含一个程序的流程图。这个程序流程图中存有子图
中的元件信息及它们之间相连的边的信息。
程序中以子程序的Name值引用子程序。
子程序是一个有输入参数和输出参数的子图(Subdiagram)。
子程序的激活条件G.Em为:当子程序的所有输入端有数据到达,子程序元件被激活
子程序的激活函数G.E设计为:对子程序包含的所有元件C?S作可激活性检查,如果
C.Em返回TRUE,则执行激活函数C.E。如此循环,直至所有元件都不可激活。

算法S (子程序激活函数):子程序元件中包含一个数据流子图,其中的元件和边分
别存储在两个列表svilist,sedgelist中。算法S扫描子图上所有元件,测试可激
活条件,并执行激活函数。
S1: 传递子程序元件的输入端数据到子图中相应元件输入端。
S2. 对子图svilist中所有元件作数据有效性检查,设C为svilist中一元件,
若C.TI  =φ,则C -> sactivelist;
若C.TI <>φ 且CA.EM = TRUE 则C->activelist;
S3. 若sactivelist =φ,则算法结束;
S4. 对sactivelist中元件依优先级排序,元件优先级由元件功能和属性确定;
S5. 对sactivelist中所有元件CA作可激活性检查及激活函数的运算:
    E1. 若CA.EM =φ,则执行CA.E;
    E2. 若CA.EM = TRUE,则执行CA.E;
E3. 若CA为用户自定义的子流程图,则对CA中包含子图中所有元件应用算法步骤
S2至S6的运算;
E4. 清除CA所有输入端的tsUpdate状态;
E5. 将CA移出sactivelist。
S6. 对sedgelist中所有边e=(Ts, Td, F, s)作数据传递和更新端子状态:
    E1: 若Ts.t = Td.t 则Td.v  Ts.v;
E2: 否则转换类型赋值:Td.v  F(Ts.v);
E3: 设置输入端状态Td.s  tsUpdate;
S7. 重复S2至S6的扫描,直至sactivelist = F。
从上述算法中可以看出,子程序的激活函数算法S与前面所述主程序的运行算法R类
似,不同之处在于结束条件。在子程序中,当子图中没有元件可以激活时算法结束
,将控制交还给主程序。而主程序会持续扫描直至用户干预。
三、流程控制算法
数据流语言定义了一种程序运行的模式,在其中程序的运行流程依赖于数据是否有
效到达,这被称作数据驱动式(Data-Driven)的运行方式。为了在数据流程序中实
现文本形式的程序设计语言中所具有的流程分支功能,我们扩展了数据流语言的运
行模式,并设计了流程元件完成这一功能。
以IF/THEN/ELSE二分支元件为例,分支元件由一个条件表达式,二个输出端口
THEN和ELSE,零个或多个输入端口组成。其中输入端口为条件表达式提供变量值。

当条件表达式运算结果为TRUE,在输出端口THEN置数据1,输出端口ELSE置数据0,
如果条件表达式运算为FALSE,则输出端口THEN置数0,输出端口ELSE置数据1。
步骤如下:
E1: 计算表达式G.Expr,其中的变量值由输入端口G.TI取得
E2: 若G.Expr = TRUE,则G.To(THEN) = 1; G.To(ELSE) = 0;
E3: 若G.Expr = FALSE,则G.To(THEN) = 0; G.To(ELSE) = 1;
E4: 算法结束,返回。
条件表达式的输出通常连至其它元件的流程控制端口Tc。
元件的可激活条件定义为:
E1: 若Tc中数据大于0且所有输入端数据有效到达,则返回TRUE;
E2: 否则返回FALSE。
以上只介绍了图形化平台中几个重要算法,其它如边的折线显示算法、边的删除算
法、图形化源文件的保存与恢复算法可详细参见耿晨歌论文。

7.2.3 图形化编程软件平台的结构
在前二节介绍了图形化编程软件平台的技术关键与理论基础,本节开始将对具体的
图形化编程软件平台进行阐述。
图形化编程软件平台的开发,从难度上与工作量上是过去的专用应用程序的开发无
法相比拟的,目前在国外上只有HP公司的VEE和NI公司的LabVIEW两个成熟的图形化
编程软件平台产品,此两家公司无不以此作为技术垄断的武器。为了打破这种技术
垄断,实现自动测试系统关键技术的自主化,浙江大学数字技术及仪器研究所在国
家“九五”重点科技攻关项目的资助下,研制开发了一个全中文界面的、自主版权
的图形化编程软件平台,并命名为VPP(Visual Programming Platform),适用操
作系统为WIN9X/WINNT/WIN2000,开发环境为Delphi3.0,目前版本为1.0。本章将
以VPP作为基本平台,进行详细分解介绍。
整个图形化编程软件平台VPP的模块结构以及和外部模块的关系如图7.3所示,包括
核心模块、仪器接口模块、图形化编程元件库三大部分,其中函数扩展库接口与虚
拟仪器接口在实现上是共享一个模块的。下面分别介绍三大部分的结构组成:
图7.3 图形化编程软件平台VPP的结构框图
一、核心模块:
该模块是整个VPP软件的核心,负责用户界面的生成,图形化元件的动态生成、属
性编辑、调用运行,系统数据的维护等重要工作。
核心模块包括编辑模块、运行模块和调试模块。三个模块之间的相互关系由图7.4
所示。当执行运行或调试操作时,控制权从编辑模块分别交给运行模块和调试模块
。编辑模块中利用图形化元件进行编程时,在内存中建立两张列表VIList和
EdgeList。VIList是个环形数据链,列出源程序编辑窗口中所有元件,这些元件的
激活情况由运行模块或调试模块在执行时动态改变。EdgeList则列出源程序编辑窗
口中所有元件以及这些元件引脚的连接情况,该列表信息用来决定数据的传递赋值
和元件的激活条件(在本章中,控件与元件的概念是一样的)。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -