opnetmodelerfunction.docx
《opnetmodelerfunction.docx》由会员分享,可在线阅读,更多相关《opnetmodelerfunction.docx(62页珍藏版)》请在冰豆网上搜索。
opnetmodelerfunction
OPNETModeler核心函数
1.核心函数简介
1.1命名规则
OPNET中的核心函数具有非常标准的命名规则,以增强函数在C/C++代码中的可视性,避免名称与非OPNET函或变量冲突。
以下列出了一些简单的命名规则:
●名称均采用op_作为前缀,以标识其为OPNET仿真内核提供的核心函数。
●函数名的第二部分为函数集名,用小写字母表示,通常是函数所处理对象的名称缩写,如pk、ici、stat等。
●函数名的第三部分是子函数集名,对核心函数进一步进行了分类,如核心函数op_pk_nfd_set()中的nfd。
●核心函数主要用于对对象的操作。
在函数名中,对象总是出现在动作之前,比如名称中的attr_set和subq_flush就将对象(attribute和subqueue)放在动作(set和flush)之前。
1.2参数类型
大部分核心函数的参数和返回值都是标准的C/C++数据类型,如int、double、char*。
除此之外,在仿真数据结构中还通过C/C++的typedef语句定义了许多参数和返回值作为特殊的OPNET数据类型。
尽管用户通过核心函数来操作OPNET数据类型,可能对每个数据类型的基本内容都越来越熟悉,但用户并不需要关心数据类型确切的内部结构,因为OPNET仿真数据结构的内容因软件版本的不同而有所改变。
表1-1列举了部分特殊的数据类型。
表1-1OPNET中部分特殊数据类型
基本数据类型
声明示例
Anvid(viewerID)
Anvidvid;
Anmid(macroID)
Anmidmid;
Andid(drawingID)
Andiddid;
Boolean
Booleanbool;
Compcode
Compcodecomp_status;
Distribution
Distribution*dist_ptr;
Evhandle
Evhandleevh;
Stathandle
StathandleStat_handle;
Ici
Ici*ici_ptr;
List
List*list_ptr;
Objid
Objidobjid;
Packet
Packet*pkptr;
Pmohandle
Pmohandlepmh;
Log_Handle
Log_Handleconfig_log_hndl;
Procedure
Procedureproc;
Prohandle
Prohandleproh;
Sbhandle
Sbhandlesbh;
1.AnimationEntity
动画集由操作中特定动画实体的ID号表示。
之所以采用ID号来代替中的指针,是因为对于动画观察函数op_vuanim,ID号通信超过了了仿真范围。
尽管ID号只是存储在规则的C/C++整型变量中的简单整数值,但OPNET也声明了特定的数据类型来准确标记ID参数和变量。
三种基于ID号的动画实体包括浏览器(Viewer)、宏(Macro)和图画(Drawing)。
2.Boolean
核心函数通过返回布尔值来表示结果是否正确。
布尔值可与符号常量OPC_TRUE和OPC_FALSE进行比较。
3.Compcode
核心函数通过返回Compcode值来表示操作是否正确完成。
Compcode的值可与符号常量OPC_COMPCOED_SUCCESS和OPC_COMPCOED_FAILURE进行比较。
4.Distribution
Distribution是一种与概率密度函数(PDF)一致的数据结构,它描述了随机数到特定数字输出的映射。
Distribution包含一张对映射进行编码的数字表,指出完成该映射的算法。
对于基于表格的Distribution,数据从PDF编辑器的PDF模型文件中读入。
这些结构均由Dist函数集中核心函数操作。
5.EventHandle
事件句柄是惟一一种确定未决仿真事件(中断)的数据结构。
该结构主要在Intrpt核心函数集中使用,因此可通过它们处理预设的中断。
注意,事件句柄是一种数据结构,而不是整型或指针。
因此不能把它存储在整型或指针变量中。
6.StatisticHandle
统计量句柄是一种确定动态产生的全局和局部统计量的数据结构。
统计量句柄的数据类型为Stathandle,获得盲文句柄的惟一方法是通过核心函数的Stat函数集来注册统计量。
注册统计量时将为其指定一个惟一的名称,并和时间一起存储在一个输出矢量中。
局部统计量用在特定处理器或队列中;全局统计量由仿真模型中的实体共享,每个实体分布式地作用于输出矢量。
7.ICI
ICI(InterfaceControlInformation,接口控制信息)是与仿真中断相关的结构化数据的集合用于进程间通信机制,传输分层协议接口的控制信息。
ICI由Ici函数集中的杧函数操作。
8.List
List是存储在双向链表中的数据元素的集合。
List中的元素可按照从简单的C/C++数据类型在复杂的数据结构进行排列。
List学用于临时存储数据结构组,可包含各种不同类型的元素,但通常并不这样使用。
对List的大小没有限制,可在其任意位置插入或移除元素。
List由Prg函数集的List子函数集操作。
9.ObjectID
对像ID惟一地确定了一个仿真对象。
通过使用Objid数据类型声明该标识符,供Id、Ima、Topo和Pk函数集使用。
10.Packet
Packet是数据封装和传输建模中的基本仿真实体。
它由Pk函数集中的核心函数操作。
11.MemoryObjectType
某些建模需要为其动态分配内存来存储各种信息。
每个相同大小数据组成的集合记为一个池,内核为每个池分配大量的数据条目以提高标准内存分配器的效率。
每个汇聚池中的内存对象必须通过调用核心函数op_prg_pmo_define()来创建,该函数将返回一个汇聚内存对象句柄来标识池,用Pmohandle表示。
创建汇聚内存对象时都为其分配了一个惟一的名称,仿真模型中的实体可以共享汇聚内存对象。
12.LogHandle
当在仿真调试或数据分析中创建仿真日志时,日志句柄对于每个日志项非常必要。
13.Procedure
某些核心函数将C/C++函数指针作为参数,但并不声明这些参数作为指向返回整型值的函数的指针,而是定义了一种特殊的数据类型——Procedure。
14.ProcessHandle
进程句柄是惟一一种标识仿真中活动进程的数据结构,由Pro函数集中的核心函数使用。
需注意进程免柄是数据结构,而不是整形或指针,因而不能将它们存储在整型或指针变量中。
15.SarBufferHandle
Sar缓冲句柄是惟一一种标识Sar(Segmentation&Reassembly,分段与重组)缓冲区的数据结构。
Sar缓冲区缓存包序列,并可对包进行分段和重装。
Sar缓冲区由Sar函数集中的核心函数创建,该函数返回访问新缓冲区的Sar缓冲句柄。
Sar函数集函数利用Sar缓冲名柄来处理被标识的Sar缓冲区。
与其他OPNET数据结构一样,不能将Sar缓冲句柄分配到整型或指针变量中。
16.Vartype
除标准的C/C++数据类型和特殊的仿真内核数据类型外,OPNET还提供了另外一种数据类型——Vartype。
Vartype数据类型可用在变量声明或类型转换语句中,它是OPNET文档中的特殊关键词,表示函数参数可以是多种可能的数据类型之一。
类型参数的传递由C描述的调用函数确定,Vartype用于确定哪个函数参数可用来传递多种数据类型。
但需要注意的是,Vartype并不像C中的varargs那样可传递多种参数,每个Vartype参数一次只能接受一个传递值。
Vartype类型的参数,可接受int、double或指向数据结构的指针。
Vartype*是Vartype的一种变体,它可接受指向变量类型的指针。
Vartype*类型的参数可接受的值包括:
指向整型的指针、指向double的指针、指向数据结构的指针,或参数用于返回filled-in值时指向数据结构指针的指针。
每个核心函数中都描述了可被Vartype或Vartype*参数接受的类型值。
具有该类型参数的部分核心函数如表1-2所示。
表1-2带Vartype参数的核心函数
核心函数
变量类型参数
op_ima_obj_attr_set()
Vartype
op_ima_obj_attr_get()
Vartype*(fill-in)
op_pk_fd_set()
Vartype
op_pk_fd_get()
Vartype*(fill-in)
op_pk_nfd_set()
Vartype
op_pk_nfd_get()
Vartype*(fill-in)
op_ini_attr_set()
Vartype
op_ini_attr_get()
Vartype*(fill-in)
op_prg_list_insert()
Vartype*
op_prg_mem_copy()
Vartype*
op_prg_mem_free()
Vartype*
返回变量类型参数的部分核心函数如表1-3所示。
表1-3返回变量类型参数的核心函数
核心函数
变量类型参数
op_prg_list_access()
Vartype*
op_prg_list_remove()
Vartype*
op_prg_mem_alloc()
Vartype*
表1-4易冲突的函数名
accept()
index()
send()
access()
kill()
signal()
audit()
link()
socket()
bind()
listen()
stat()
clear()
open()
tell()
clock()
pipe()
truncate()
close()
poll()
unlink()
connect()
read()
wait()
exit()
select()
1.3多线程安全
无线模块允许OPNET采用多处理器进行收/发信机管道计算。
为确保并行传输的正确性和尽可能快速,五个管道阶段必须采用多线程安全核心函数。
核心函数定义了三个多线程安全级别,分别是MT-safe、MT-unsafe和Forcedserialization。
(1)MT-safe:
该类核心函数已手动进行重编码以支持多线程。
多个线程可安全地并行执行该类核心函数。
(2)MT-unsafe:
在该安全级别下,若在核心函数中采用并行处理,将导致性能的下降,达不到预期的结果。
使用MT-unsafe核心函数时,应当执行适当的代码序列化(Serialization)。
(3)Forcedserialization:
对于所有已手动重编码以支持多线程的核心函数,仿真内核采用内部互斥来执行严格的序列化。
最终每个核心函数将进行手动重编码来支持多线程,它们的状态也将由Forcedserialization变为MT-safe。
2.基本核心函数
OPNETModeler10.0提供了21个核心函数集,只有熟悉核心函数才能在建模时方便地进行代码编写。
本节按照不同的功能对常用的核心函数作了详细的介绍。
2.1内部模型访问函数集
Ima(InternalModelAccess,内部模型访问)函数集是一系列提供对仿真实体动态访问的核心函数的集合,其中仿真实体包括仿真属性、对象属性、对象命令(ObjectCommand)和进程状态变量。
1.op_ima_obj_attr_get(objid,attr_name,value_ptr)
此核心函数的作用是获取给定对象的某属性值,其参数说明如表2-1所示。
表2-1op_ima_obj_attr_get()函数的参数说明
参数
类型
描述
objid
Objid
给定对象的对象ID
attr_name
constchar*
属性名(必须是给定对象中已定义的,否则将出错)
value_ptr
Vartype*
指向存储属性值变量的指针(Vartype*可接受字符串或指向整型、double以及复合属性对象ID指针。
当为字符串时,字符数组必须足够大,以容纳属性值。
参数指针类型必须与给定属性的数据类型相匹配,否则将出错。
如果属性类型是toggle,返回值即为OPC_BOOLINT_ENABLED或OPC_BOOLINT_DISABLED;如果属性类型是pofile,返回值即为包含访问profile所需的必要信息的pofilespecification(PrgT_Profile_Spec)
1)返回值
Compcode——如果成功获取属性值,即返回OPC_COMPCODE_SUCCESS,否则返回OPC_COMPCODE_FAILURE。
如果需要获取给定对象的复合属性值,则若复合属性相等,value_ptr的值即设为复合属性中的一个对象ID,并返回OPC_COMPCODE_SUCCESS;若不相等,则返回OPC_COMPCODE_FAILURE。
注意:
在复合属性中,所谓的“相等”,是指复合属性中的所有属性都具有相同的名称、类型和值,并且复合忏悔的所有子对象也相等。
2)详解
对于网络域对象(子网、节点和链路)、节点域对象(模块)以及预先由网络、节点、进程或链路编辑器定义的复合属性,都可以获取对象属性值。
提升的属性值可以从父对象中获取。
要引用提升属性,必须为每个中间对象的属性名附加一个点分前缀。
例如,若要在节点级获取进程属性,则属性名应在包含该进程的模块名称之前。
并不是所有的对象属性都可仿真中调用该函数来获取。
比如Simulation/Access字段被标记为N/A的属性就不能通过调用op_ima_obj_attr_get()来获取。
此外,该核心函数的命令级别为Forcedserialization。
3)目的
该函数提供了一种在仿真中动态获取对象属性的机制。
它可用于处理器或队列确定自身或网络中其他对象的属性值。
将该函数与op_ima_obj_attr_set()结合,无需包、ICI或中断递送就可提供远程进程间的通信。
4)错误
ProgramAbort:
分段错误(由无效值指针、指针所指内存不足或指向无效的attr_name地址所引起)。
RecoverableError:
对象无法识别属性名。
RecoverableError:
对象ID溢出。
RecoverableError:
对象ID指向受限对象(由受护模型中的相关对象引起)。
5)相关函数
采用op_ima_obj_attr_set()、op_ima_obj_attr_set_db1()、op_ima_obj_attr_set_int32()和op_ima_obj_attr_set_str()设置对象属性值。
采用op_ima_sim_attr_get()、op_ima_sim_attr_get_db1()、op_ima_sim_attr_get_int32()和op_ima_sim_attr_get_str()获取仿真属性值。
采用op_ima_obj_svar_get()获取进程状态变量值。
采用op_ima_obj_command()向对象发出一个命令。
采用op_id_self()获取所属处理器或队列的对象ID。
采用op_id_from_name()获取对象的对象ID。
2.op_ima_obj_attr_set(objid,attr_name,value_ptr)
此核心函数的作用是设置给定对象的某属性值,其参数说明如表2-2所示。
表2-2op_ima_obj_attr_set()函数的参数说明
参数
类型
描述
objid
Objid
给定对象的对象ID
attr_name
constchar*
属性名
value_ptr
Vartype*
指定属性需设置的新值
1)返回值
Compcode——如果成功获取属性值,即返回OPC_COMPCODE_SUCCESS,否则返回OPC_COMPCODE_FAILURE。
2)详解
对于网络域对象(子网、节点和链路)、节点域对象(模块)以及预先由网络、节点、进程或链路编辑器定义的复合属性,都可以设置对象属性值。
在对象中可以设置提升对象的值。
并不是所有的对象属性都可仿真中调用该函数来设置。
比如Simulation/Access字段被标记为N/A的属性就不能通过调用op_ima_obj_attr_set()来设置。
此外,该核心函数的命令级别为Forcedserialization。
3)目的
该核心函数提供了一种在仿真过程中动态设置对象属性的机制,可用于处理器或队列控制其他模块。
与函数op_ima_obj_attr_get()结合,无需包、ICI或中断递送就可提供远程进程间的通信。
不过需要注意的是,远端对象值的改变并不会引起中断,只是当修改后的对象再次调用函数op_ima_obj_attr_get()获取其属性时才会产生影响。
4)错误
ProgramAbort:
分段错误(由无效值指针、attr_name地址无效或值类型错误所引起)。
RecoverableError:
对象无法识别属性名。
RecoverableError:
对象ID溢出。
RecoverableError:
对象属性为只读。
RecoverableError:
属性值无效。
RecoverableError:
对象ID指向受限对象。
5)相关函数
采用op_ima_obj_attr_get()、op_ima_obj_attr_get_db1()、op_ima_obj_attr_get_int32()和op_ima_obj_attr_get_str()设置对象属性值。
采用op_ima_sim_attr_get()、op_ima_sim_attr_get_db1()、op_ima_sim_attr_get_int32()和op_ima_sim_attr_get_str()获取仿真属性值。
采用op_ima_obj_svar_get()获取进程状态变量值。
采用op_ima_obj_command()向对象发出一个命令。
采用op_id_self()获取所属处理器或队列的对象ID。
采用op_id_from_name()获取对象的对象ID。
3.op_ima_sim_attr_get(attr_type,attr_name,value_ptr)
此核心函数的作用是获取仿真属性值,其说明如表2-3所示。
表2-3op_ima_sim_attr_get()函数的参数说明
参数
类型
描述
attr_type
int
属性类型(可以为OPC_IMA_INTEGER、OPC_IMA_DOUBLE、OPC_IMA_TOGGLE或OPC_IMA_STRING)
attr_name
constchar*
属性名
value_ptr
Vartype*
指定存储属性值变量的指针
1)返回值
Compcode——如果成功获取属性值,即返回OPC_COMPCODE_SUCCESS,否则返回OPC_COMPCODE_FAILURE。
2)详解
仿真属性与子网发属性、节点属性、模块属性以及进程属性均不同,它不在制定模块规范阶段定义,而在仿真运行期间动态定义。
仿真属性是通过一些环境属性机制来进行赋值的,包括仿真命令行、环境数据库(/op_admin/env_db)、shell变量或环境文件。
该函数将触发仿真的内部环境数据库扫描可用值,如果无法在现有程序环境中为仿真属性找到一个值,那么它将在标准输出设备上打印一个提示(可用仿真的noprompt环境属性来取消用户提示),请求输入一个值。
一旦提示出现,就将打印一个属性的默认值。
注意:
默认值是调用核心函数时传递给参数的value_ptr值,而不使用进程模型属性列表中的默认初始值。
因此在调用该函数时,必须事先定义value_ptr。
如果在仿真程序环境中能够找到给定属性,或当提升时值时被显示输入,那么认为函数执行成功并返回值OPC_COMPCODE_SUCCESS。
如果内核必须要引用value_ptr的值,则返回OPC_COMPCODE_FAILURE。
3)目的
该核心函数提供了一种获取在仿真运行期间设置的仿真属性的机制。
将该函数与用环境属性来分配仿真属性结合起来,不仅可以获取网络范围内的关键参数,还可获取影响进程逻辑操作的进程级参数。
4)错误
ProgramAbort:
分段错误(由无效值指针、指针所指内存不足或指向畸形的attr_name参数引起)。
ProgramAbort:
内存分配失败。
RecoverableError:
属性类型不可识别。
5)相关函数
采用op_ima_obj_attr_get()、op_ima_obj_attr_get_db1()、op_ima_obj_attr_get_int32()和op_ima_obj_attr_get_str()设置对象属性值。
采用op_ima_sim_attr_set()、op_ima_sim_attr_set_db1()、op_ima_sim_attr_set_int32()和op_ima_sim_attr_set_str()设置对象属性值。
采用op_ima_obj_svar_get()获取进程状态变量值。
采用op_ima_obj_command()向对象发出一个命令。
2.2分布函数集
Dist(Distribution)函数集是一系列根据特定概率分布产生随机值的核心函数集合。
只要具有随机行为的仿真都可以使用这些随机值中的一种或几种,如计算中断的到达时间、产生通信量目的地址或确定节点是否应被去激活等。
1.op_dist_load(dist_name,dist_arg0,dist_arg1)
此核心函数的作用是加载分布以产生随机值流,其参数说明如表2-4
表2-4op_dist_load()函数的参数说明
参数
类型
描述
dist_name
constchar*
被加载的分布名称,通常为字符串常量
dist_arg0
double
分布的附加参数#0
dist_arg1
double
分布的附加参数#1
1)返回值
Distribution*——指向被加载分布的指针。
如果发生可恢复错误,则返回常量OPC_NIL。
函数返回值一般存储在Distribution*类型的状态变量中,稍后现传递给相关核心函数op_dist_outcome()。
2)详解
分布是根据名称来确定的,可以是预定义的分析分布、采用PDF编辑器建立的用户自定义PDF模型或EMA-specifiedPDF模型。
执行预定义的分布可以看作是通过一两个数值参数调用该核心函数的参数化算法。
另外两种类型的分布是后缀为“.pd.s”的表格式数据文件,调用该函数时将其加载到内存中。
需要注意的是,即使预定义的分布在models/std/base文件夹中有相应的“.pd.s”文件,但这些文件都是零字节的,不包含任何分布信息,只是让分布能够显示在OPNET菜单中