OPNET核心函数

opnet学习 专栏收录该内容
20 篇文章 2 订阅
OPNET Modeler 核心函数
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-1 OPNET 中部分特殊数据类型 基本数据类型 Anvid (viewer ID) Anmid (macro ID) Andid (drawing ID) Boolean Compcode Distribution Evhandle Stathandle Ici List Anvid vid; Anmid mid; Andid did; Boolean bool; Compcode comp_status; Distribution* dist_ptr; Evhandle evh; Stathandle Stat_handle; Ici* ici_ptr; List* list_ptr; 声明示例

Objid Packet Pmohandle Log_Handle Procedure Prohandle Sbhandle

Objid objid; Packet* pkptr; Pmohandle pmh; Log_Handle config_log_hndl; Procedure proc; Prohandle proh; Sbhandle sbh;

1. Animation Entity 动画集由操作中特定动画实体的 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. Event Handle 事件句柄是惟一一种确定未决仿真事件(中断)的数据结构。该结构主要在 Intrpt 核心函 数集中使用,因此可通过它们处理预设的中断。注意,事件句柄是一种数据结构,而不是整型 或指针。因此不能把它存储在整型或指针变量中。 6. Statistic Handle 统计量句柄是一种确定动态产生的全局和局部统计量的数据结构。统计量句柄的数据类型 为 Stathandle, 获得盲文句柄的惟一方法是通过核心函数的 Stat 函数集来注册统计量。注册统计 量时将为其指定一个惟一的名称,并和时间一起存储在一个输出矢量中。局部统计量用在特定 处理器或队列中;全局统计量由仿真模型中的实体共享,每个实体分布式地作用于输出矢量。

7. ICI ICI(Interface Control Information,接口控制信息)是与仿真中断相关的结构化数据的集合 用于进程间通信机制,传输分层协议接口的控制信息。ICI 由 Ici 函数集中的杧函数操作。 8. List List 是存储在双向链表中的数据元素的集合。List 中的元素可按照从简单的 C/C++数据类 型在复杂的数据结构进行排列。List 学用于临时存储数据结构组,可包含各种不同类型的元素, 但通常并不这样使用。对 List 的大小没有限制,可在其任意位置插入或移除元素。List 由 Prg 函数集的 List 子函数集操作。 9. Object ID 对像 ID 惟一地确定了一个仿真对象。 通过使用 Objid 数据类型声明该标识符, Id、Ima、 供 Topo 和 Pk 函数集使用。 10. Packet Packet 是数据封装和传输建模中的基本仿真实体。它由 Pk 函数集中的核心函数操作。 11. Memory Object Type 某些建模需要为其动态分配内存来存储各种信息。每个相同大小数据组成的集合记为一个 池,内核为每个池分配大量的数据条目以提高标准内存分配器的效率。每个汇聚池中的内存对 象必须通过调用核心函数 op_prg_pmo_define()来创建,该函数将返回一个汇聚内存对象句柄来 标识池,用 Pmohandle 表示。创建汇聚内存对象时都为其分配了一个惟一的名称,仿真模型中 的实体可以共享汇聚内存对象。 12. Log Handle 当在仿真调试或数据分析中创建仿真日志时,日志句柄对于每个日志项非常必要。 13. Procedure 某些核心函数将 C/C++函数指针作为参数,但并不声明这些参数作为指向返回整型值的函 数的指针,而是定义了一种特殊的数据类型——Procedure。 14. Process Handle 进程句柄是惟一一种标识仿真中活动进程的数据结构,由 Pro 函数集中的核心函数使用。 需注意进程免柄是数据结构,而不是整形或指针,因而不能将它们存储在整型或指针变量中。 15. Sar Buffer Handle 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() op_ima_obj_attr_get() op_pk_fd_set() op_pk_fd_get() op_pk_nfd_set() op_pk_nfd_get() op_ini_attr_set() op_ini_attr_get() op_prg_list_insert() op_prg_mem_copy() op_prg_mem_free() Vartype Vartype* (fill-in) Vartype Vartype* (fill-in) Vartype Vartype* (fill-in) Vartype Vartype* (fill-in) Vartype* Vartype* Vartype* 变量类型参数

返回变量类型参数的部分核心函数如表 1-3 所示。 表 1-3 核心函数 op_prg_list_access() op_prg_list_remove() op_prg_mem_alloc() Vartype* Vartype* Vartype* 返回变量类型参数的核心函数 变量类型参数

表 1-4 accept() access() audit() bind() clear() clock() close() connect() exit() index() kill() link() listen() open() pipe() poll() read() select()

易冲突的函数名 send() signal() socket() stat() tell() truncate() unlink() wait()

1.3 多线程安全 无线模块允许 OPNET 采用多处理器进行收/发信机管道计算。为确保并行传输的正确性和 尽可能快速,五个管道阶段必须采用多线程安全核心函数。核心函数定义了三个多线程安全级 别,分别是 MT-safe、MT-unsafe 和 Forced serialization。 (1)MT-safe:该类核心函数已手动进行重编码以支持多线程。多个线程可安全地并行执 行该类核心函数。 (2)MT-unsafe:在该安全级别下,若在核心函数中采用并行处理,将导致性能的下降, 达不到预期的结果。使用 MT-unsafe 核心函数时,应当执行适当的代码序列化(Serialization) 。 (3)Forced serialization:对于所有已手动重编码以支持多线程的核心函数,仿真内核采 用内部互斥来执行严格的序列化。最终每个核心函数将进行手动重编码来支持多线程,它们的 状态也将由 Forced serialization 变为 MT-safe。

2. 基本核心函数 OPNET Modeler10.0 提供了 21 个核心函数集, 只有熟悉核心函数才能在建模时方便地进行 代码编写。本节按照不同的功能对常用的核心函数作了详细的介绍。 2.1 内部模型访问函数集 Ima(Internal Model Access,内部模型访问)函数集是一系列提供对仿真实体动态访问的 核心函数的集合,其中仿真实体包括仿真属性、对象属性、对象命令(Object Command)和进 程状态变量。 1. op_ima_obj_attr_get (objid,attr_name,value_ptr) 此核心函数的作用是获取给定对象的某属性值,其参数说明如表 2-1 所示。

表 2-1 op_ima_obj_attr_get()函数的参数说明 参 数 objid attr_name 类 型 Objid const char* 给定对象的对象 ID 属性名(必须是给定对象中已定义的,否则将出错) 指向存储属性值变量的指针(Vartype* 可接受字符串或指向 整型 、double 以及复合属性对象 ID 指针。当为字符串时, 字符数组必须足够大,以容纳属性值。参数指针类型必须与 给定属性的数据类型相匹配,否则将出错。如果属性类型是 value_ptr Vartype* toggle , 返 回 值 即 为 OPC_BOOLINT_ENABLED 或 OPC_BOOLINT_DISABLED;如果属性类型是 pofile,返回 值 即 为 包 含 访 问 profile 所 需 的 必 要 信 息 的 pofile specification(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()来获取。 此外,该核心函数的命令级别为 Forced serialization。 3)目的 该函数提供了一种在仿真中动态获取对象属性的机制。它可用于处理器或队列确定自身或 网络中其他对象的属性值。将该函数与 op_ima_obj_attr_set()结合,无需包、ICI 或中断递送就 可提供远程进程间的通信。 4)错误 描 述

Program Abort:分段错误(由无效值指针、指针所指内存不足或指向无效的 attr_name 地 址所引起) 。 Recoverable Error:对象无法识别属性名。 Recoverable Error:对象 ID 溢出。 Recoverable Error:对象 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-2 op_ima_obj_attr_set()函数的参数说明 参 数 objid attr_name value_ptr 1)返回值 Compcode——如果成功获取属性值,即返回 OPC_COMPCODE_SUCCESS,否则返回 OPC_COMPCODE_FAILURE。 2)详解 对于网络域对象(子网、节点和链路) 、节点域对象(模块)以及预先由网络、节点、进 程或链路编辑器定义的复合属性,都可以设置对象属性值。在对象中可以设置提升对象的值。 并不是所有的对象属性都可仿真中调用该函数来设置。比如 Simulation/Access 字段被标记 为 N/A 的属性就不能通过调用 op_ima_obj_attr_set()来设置。 此外,该核心函数的命令级别为 Forced serialization。 3)目的 该核心函数提供了一种在仿真过程中动态设置对象属性的机制,可用于处理器或队列控制 类 型 Objid const char* Vartype* 给定对象的对象 ID 属性名 指定属性需设置的新值 描 述

其他模块。与函数 op_ima_obj_attr_get()结合,无需包、ICI 或中断递送就可提供远程进程间的 通信。不过需要注意的是,远端对象值的改变并不会引起中断,只是当修改后的对象再次调用 函数 op_ima_obj_attr_get()获取其属性时才会产生影响。 4)错误 Program Abort:分段错误(由无效值指针、attr_name 地址无效或值类型错误所引起) 。 Recoverable Error:对象无法识别属性名。 Recoverable Error:对象 ID 溢出。 Recoverable Error:对象属性为只读。 Recoverable Error:属性值无效。 Recoverable Error:对象 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-3 参 数 attr_type attr_name value_ptr 1)返回值 Compcode——如果成功获取属性值,即返回 OPC_COMPCODE_SUCCESS,否则返回 OPC_COMPCODE_FAILURE。 2)详解 仿真属性与子网发属性、节点属性、模块属性以及进程属性均不同,它不在制定模块规范 int const char* Vartype* 类 型 op_ima_sim_attr_get()函数的参数说明 描 述

属性类型 (可以为 OPC_IMA_INTEGER、 OPC_IMA_DOUBLE、 OPC_IMA_TOGGLE 或 OPC_IMA_STRING) 属性名 指定存储属性值变量的指针

阶段定义,而在仿真运行期间动态定义。仿真属性是通过一些环境属性机制来进行赋值的,包 括仿真命令行、环境数据库(<HOME>/op_admin/env_db<rel>) 、shell 变量或环境文件。 该函数将触发仿真的内部环境数据库扫描可用值,如果无法在现有程序环境中为仿真属性 找到一个值,那么它将在标准输出设备上打印一个提示(可用仿真的 noprompt 环境属性来取消 用户提示) ,请求输入一个值。一旦提示出现,就将打印一个属性的默认值。 注意:默认值是调用核心函数时传递给参数的 value_ptr 值,而不使用进程模型属性列表 中的默认初始值。因此在调用该函数时,必须事先定义 value_ptr。 如果在仿真程序环境中能够找到给定属性,或当提升时值时被显示输入,那么认为函数执 行成功并返回值 OPC_COMPCODE_SUCCESS。如果内核必须要引用 value_ptr 的值,则返回 OPC_COMPCODE_FAILURE。 3)目的 该核心函数提供了一种获取在仿真运行期间设置的仿真属性的机制。将该函数与用环境属 性来分配仿真属性结合起来,不仅可以获取网络范围内的关键参数,还可获取影响进程逻辑操 作的进程级参数。 4)错误 Program Abort:分段错误(由无效值指针、指针所指内存不足或指向畸形的 attr_name 参 数引起) 。 Program Abort:内存分配失败。 Recoverable Error:属性类型不可识别。 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-4 参 数 dist_name dist_arg0 dist_arg1 1)返回值 Distribution *——指向被加载分布的指针。如果发生可恢复错误,则返回常量 OPC_NIL。 函 数 返 回 值 一 般 存 储 在 Distribution * 类 型 的 状 态 变 量 中 , 稍 后 现 传 递 给 相 关 核 心 函 数 op_dist_outcome()。 2)详解 分布是根据名称来确定的, 可以是预定义的分析分布、 采用 PDF 编辑器建立的用户自定义 PDF 模型或 EMA-specified PDF 模型。执行预定义的分布可以看作是通过一两个数值参数调用 该核心函数的参数化算法。另外两种类型的分布是后缀为“.pd.s”的表格式数据文件,调用该 函数时将其加载到内存中。需要注意的是,即使预定义的分布在 models/std/base 文件夹中有相 应的“.pd.s”文件,但这些文件都是零字节的,不包含任何分布信息,只是让分布能够显示在 OPNET 菜单中。当加载用户自定义的 PDF 时,将忽略参数 dist_arg0 和 dist_agr1。 此外,该核心函数的安全级别为 MT-safe。 3)目的 该核心函数提供作为随机数发生器的概率分布。该函数主要用于加载分布,以在处理器产 生的包之间提供随机时间间隔。任何随机分布的仿真参数都可以通过该函数来获取。实际的随 机值是通过调用函数 op_dist_outcome()来获取的。 4)错误 Program Abort:分段错误(由无效分布名指针引起) 。 Program Abort:内存分配失败。 Recoverable Error:分布名不可识别。 5)相关函数 采用 op_dist_outcome()或 op_dist_outcome_ext()获取已加载分布的随机值。 采用 op_dist_uniform()获取均匀分布的随机值。 采用 op_dist_unload()释放分布占用的内存。 类 型 const char* double double op_dist_load()函数的参数说明 描 述

被加载的分布名称,通常为字符串常量 分布的附加参数#0 分布的附加参数#1

2. op_dist_outcome (dist_ptr) 此核核心函数的作用是为具有特定分布的随机变量产生一个浮点数, 其参数说明如表 7-5。 表 2-5 参 数 dist_ptr 1)返回值 double — — 具 有 特 定 分 布 随 机 变 量 的 结 果 。 如 果 发 生 可 恢 复 错 误 , 则 返 回 常 量 OPC_DBL_INVALID。 2)详解 特定分布可以是预定义的算法分布, 也可以是之前通过函数 op_dist_load()加载的数字型表 格式分布。该核心函数执行表格式分布的列表查询,并对算法分布(如指数分布)进行数字计 算。 该核心函数使用的随机数流是调用 BSD random()过程产生的, 所有分布函数集中的函数和 发生器模块都可共享此随机数流。随机数流依赖于初始的种子数(seed) ,如果仿真输入(包括 相同的随机 seed)相同,则仿真结果可重复。 此外,该核心函数的安全级别为 MT-safe。 3)目的 该核心函数提供了一种获取符合某概率分布的随机值的机制。该函数学用于计算处理器产 生的包之间的随机时间间隔。任何随机分布的仿真参数都可以通过它来获取。 4)错误 Program Abort:分段错误(由无效分布指针引起) 。 Recoverable Error:分布指针为 NIL。 5)相关函数 采用 op_dist_load()加载分布。 采用 op_dist_uniform()获取均匀分布的随机值。 采用 op_dist_unload()释放分布占用的内存。 采用 op_dist_outcome_ext()获取用户自定义的随机数发生器产生的随机数。 采用 op_intrpt_schedule_self()、op_intrpt_schedule_remote()或 op_intrpt_schedule_call()分别 产生自中断、远程中断和过程中断。 类 型 Distribution* 指向被加载分布的指针 op_dist_outcome()函数的参数说明 描 述

3. op_dist_uniform(limit) 此核心函数的作用是产生一个均匀分布的随机值,其参数说明如表 2-6 所示。

表 2-5 参 数 limit 1)返回值 类 型 double

op_dist_uniform()函数的参数说明 描 述

均匀分布的取值范围

double——产生的均匀分布的随机值,范围在[0.0,limit ]中。 2)详解 该核心函数使用的随机数流是调用 BSD random()过程产生的, 所有分布函数集中的函数和 发生器模块都可共享此随机数流。随机数流依赖于初始的种子数(seed) ,如果仿真输入(包括 相同的随机 seed)相同,则仿真结果可重复。 如果参数 limit 为负数,则返回值将是一个大于 limit 的均匀分布的负数 此外,该核心函数的安全级别为 MT-safe。 3)目的 该核心函数为普通的建模提供了一种获取均匀分布随机数的机制,例如可用于数据链路协 议计算随机超进。 4)错误 无错误捕获 5)相关函数 采用 op_dist_load()加载一个概率分布。 采用 op_dist_outcome()根据已加载的概率分布,获取一随机值。

2.3 进程函数集 进程函数集是一系列用于在一个处理器或队列模块中创建和管理多个进程的核心函数的 集合。进程是进程模型的一个实例,进程模型是在 OPNET 的进程编辑器中开发的特定类型 进 程的行为和功能规范。 1. op_pro_create (model_name, ptc_mem_ptr) 此核心函数的作用是创建一个新的进程作为特定进程模型的实例,并允许安装 parent-to-child 共享内存, 作为当前进程和创建的子进程间通信机制, 其参数说明如表 2-7 所示。 表 2-7 参 数 model_name 类 型 const char* 进程模型名称 当前进程和被创建进程共享的 parent-to-child 内存块的地址 ptc_mem_ptr Vartype* (该内存块格式是用户自定义的。通常若无内存共享,则传 递值 OPC_NIL) op_dist_load()函数的参数说明 描 述

1)返回值 Prohandle——进一步处理被创建子进程的进程句柄。 2)详解 仿真内核支持单个队列或处理器模块中任意多个不同类型进程的并存。除了根进程,其他 所有进程都通过该核心函数创建。 只有当提供的参数 process_model 引用当前仿真中已声明的进 程,该核心函数才会执行成功。在为仿真系统的任一处理器或队列模块的进程模型属性赋值, 或在通过进程编辑器将进程声明为另一进程的子进程时,均采用进程模型的隐式声明。 每个通过该核心函数创建的进程都可以利用共享内存与创建它的进程进行通信。共享内存 是用户自定义的内存块,其地址必须作为 ptc_mem_ptr 参数传递给该函数。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一个进程,其可以创建在相同模块中操作的子进程。每个子进程作为一 个进程模型实例独立存在,并维持自身的状态。 4)错误 Program Abort:核心函数需要进程上下文。 Program Abort:无法创建进程。 Program Abort:进程的描述符分配失败。 Program Abort:初始化进程失败。 Recoverable Error:进程模型未被声明。 5)相关函数 采用 op_pro_invoke()调用进程模型。 子进程采用 op_pro_parmem_access()获取 parent_to_child 共享内存。 采用 op_pro_id()确定进程的惟一整数标识符。

2. op_pro_destroy_options(pro_handle, options) 销毁动态创建的进程和该进程的所有预设事件,其参数说明如表 2-8 所示。 表 2-8 参 数 pro_handle options 1)返回值 Compcode — — 表 示 仿 真 内 核 是 否 成 功 销 毁 进 程 的 完 成 代 码 , 包 括 OPC_COMPCODE_SUCCESS 和 OPC_COMPCODE_FAILURE。 类 型 Prohandle int 被销毁进程的进程句柄 被执行的可选操作 op_pro_destroy_options ()函数的参数说明 描 述

2)详解 该函数允许进程销毁同一模块中的任意其他动态进程,因此跟进程是惟一给定模块中不能 被销毁的进程。此外,该函数还可移除被销毁进程的所有预设事件。其中,动态进程是通过核 心函数 op_pro_create()创建的,在仿真中可随时从模型中移除动态进程。 适当终止进程可释放分配给进程的动态内存,但这也可能给建模带来一定影响。进程模型 在销毁时会有一个特殊的逻辑片断,该片断是进程模型的终止块和销毁进程时仿真内核直接调 用的包含其中的代码。代码片断中可能用到状态和临时变量。 进程可以销毁自身,这时不返回任何值,除了终止块中的特定操作外,不执行任何操作。 注意:内核对释放 parent-to-child 或参数内存不负任何责任。 该核心函数可使用的 option 有: ? OPC_PRO_DESTROY_OPT_KEEP_EVENTS——核心函数移除被销毁进程的任意预 设事件。 ? OPC_PRO_DESTROY_OPT_NONE——默认操作。

此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一个进程,其可以创建在相同模块中操作的子进程。每个子进程作为一 个进程模型实例独立存在,并维持自身的状态。 4)错误 Program Abort:核心函数需要进程上下文。 Program Abort: 分段错误(由畸形进程句柄导致) 。 Recoverable Error:进程句柄无效。 Recoverable Error:进程句柄指向被销毁进程。 Recoverable Error:进程句柄指向远程进程。 Recoverable Error:进程句柄指向根进程。 Recoverable Error:进程句柄指向活动进程。 5)相关函数 采用 op_pro_create()创建新的进程并获取其句柄。 采用 op_prg_mem_free()释放通过函数 op_prg_mem_alloc()分配的内存。 采用 op_pro_invoke()调用进程模型。 采用 op_pro_parmem_access()用于子进程获取 parent_to_child 共享内存。

3. op_pro_self() 此核心函数的作用是获取当前正在执行的进程的进行句柄。

1)返回值 Prohandle——当前正在执行的进程的进程句柄。在执行与该进程相关的操作,调用其他核 心函数时可使用此句柄。 2)详解 当前执行的进程通常需要使用其自身的句柄作为进程和中断函数集中其他核心函数的参 数。例如,该句柄可作为指针来获取父进程的句柄。其他典型应用包括获取进程的惟一 ID,销 毁无用的进程本身。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数为调用该核心函数的进程提供了一个进程句柄,作为进程和中断函数集中其他 核心函数的参数。 4)错误 Program Abort:核心函数需要进程上下文。 5)相关函数 采用 op_pro_id()获取进程的惟一整数 ID。 采用 op_prg_mem_free()销毁进程。 采用 op_intrpt_port_register ()为特定流或统计中断注册一个进程。 采用 op_intrpt_type_register()为特定类型中断注册一个进程。

4. op_pro_invoke (pro_handle, argmem_ptr) 该核心函数的作用是在当前事件和当前模块的止下文中调用进程。被调用进程将被暂停直 到函数返回,其参数说明如表 2-9 所示。 表 2-9 参 数 pro_handle argmem_ptr 1)返回值 Compcode——表示调用是否成功的完成代码, 返回代码包括 OPC_COMPCODE_SUCCESS 和 OPC_COMPCODE_FAILURE。进程句柄过期或调用其他模块的进程都将引起调用失败。 2)详解 进程可调用同一模块中的其他进程。如果使用其他模块进程的进程句柄来调用该函数将引 起可恢复错误。 类 型 Prohandle Vartype* 被调用进程的进程句柄 通过函数 op_pro_argmem_access()为被调用进程提供的参数 内存块的地址 op_pro_invoke()函数的参数说明 描 述

在同一事件中,对函数 op_pro_invoke()的调用次数并没有任何限制。换句话说,调用函数 op_pro_invoke()所导致中断的进程,可接着利用该函数调用其他进程。这种一连串的进程调用 称为当前调用栈,就像 C 语言中的函数调用栈一样。仿真内核限制进程在当前调用栈中调用其 他进程。 当进行进程调用时,调用进程可建立一个内存块,供它和被调用进程共享。由于该内存可 传递被调用进程的输入和输出参数,因而作为参数内存。若调用进程需要通过函数 op_pro_argmem_access()来获取内存块地址,则地址必须作为参数传递给 op_pro_invoke();若无 此需要,则应传递常量 OPC_NIL。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 多个进程可共同处理单一队列或处理器模块上下文中发生的事件。通常对进程进行分层组 织,父进程根据不同事件的要求将事件处理任务交给合适的子进程。另外一种进程组织方式就 是根据功能行来划分任务,如可根据进程收到的中断类型调用不同的子进程。大多数组织化机 制都有一个共通处,即都需要在模块中临时传递对子进程或对等进程的执行控制权。这就需要 通过函数 op_pro_invoke()来完成,并提供需执行的进程句柄。 4)错误 Program Abort:核心函数需要进程上下文。 Program Abort: 分段错误(由畸形进程句柄导致) 。 Recoverable Error:进程句柄无效。 Recoverable Error:进程句柄指向被销毁进程。 Recoverable Error:进程句柄指向远程进程。 Recoverable Error:进程句柄指向活动进程。 5)相关函数 采用 op_pro_argmem_access()获取调用参数内存的访问权。 采用 op_pro_parent()获取父进程的进程句柄。 采用 op_pro_create()创建新的进程并获取其句柄。

5. op_pro_argmem_access () 此函数的作用是获取进程调用所传递的参数内存的地址。 1)返回值 Vartype*——调用进程提供的用户自定义内存块的地址。若仿真内核直接调用进程或调用 进程不愿传递任何参数内存,则返回符号常量 OPC_NIL。 2)详解

参数磪存是一个用户自定义的内存块,其地址由进程调用其他进程时传递。内存的格式和 内容都是用户自定义的,只有其地址由仿真内核管理。仿真内核保证只有通过函数传递的内存 地址阻塞时,才能被调用进程访问,并将控制权返回给调用进程。 地于直接由仿真内核调用的进程,该核心函数将返回一个空地址 OPC_NIL。直接由内核 调用的进程和通过函数 op_pro_invoke()调用的进程应在使用该指针访问参数值之前检查返回的 地址是否为 OPC_NIL,否则将发生分段错误。 调用函数 op_pro_invoke()可使用参数内存机制,这时被调用进程并不需要接收传入的值或 向调用进程返回任何数据。在这种情况下,通常在需要参数内存的情况下,调用函数 op_pro_invoke()应传递符号常量 OPC_NIL。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种在调用进程和被调用进程间共享内存的机制。内存可在调用前建 立,以包含输入参数值。被调用进程可以检查检查该参数值,并利用它来处理事件。同样被调 用进程可修改内存,以向调用进程返回输出参数,而调用进程可在函数 op_pro_invoke()返回之 后检查内存的内容。 该核心函数提供了一种在调用进程和被调用进程间共享内存的机制。内存可在调用前建 立,以包含输入参数值。被调用进程可以检查该参数值,并利用它。 4)错误 Program Abort:核心函数需要进程上下文。 5)相关函数 采用 op_pro_invoke()调用进程模型。 采用 op_pro_modmem_access()与同一模块中的其他进程共享信息。 采用 op_pro_parmem_access()与进程及其父进程共享信息。

2.4 事件函数集 op_ev_cancel(evhandle) 函数的作用是撤销预设的事件,其参数说明如表 2-10 所示。 表 2-10 参 数 evhandle 类 型 Evhandle op_ev_seek_time()、op_ev_next()、op_intrpt_schedule_self()等函数获取 op_ev_cancel()函数的参数说明 描 述

被取消事件的事件句柄。事件句柄可以通过本函数集中的

1)返回值

Compcode——表示操作是否成功的完成代码, 包括符号常量 OPC_COMPCODE_SUCCESS 和 OPC_COMPCODE_FAILURE。 2)详解 取消事件就是将其从仿真事件列表中移除,并阻止其向目的模块发送。该函数只能用于取 消未决的事件,取消已经发送或正在执行的事件将导致错误发生。 因为仿真内核将事件信息缓存到了相应的事件句柄中,这样无需查找就可很快对事件进行 定位,所以利用该函数取消事件时不必考虑效率问题。在事件发送之前使用该函数将其取消将 比事件发送到目的地后再将其取消更加高效。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种撤销无用事件的机制。该函数常用于取消 op_intrpt_schedule_self() 函数预设的超时中断事件。如果在超时前收到 ack 包或有其他中断发生,则该函数将取消超时 事件,并重置定时器。 4)错误 Program Abort: 分段错误(由畸形进程句柄导致) 。 Recoverable Error:事件句柄指向无效或当前还未预设的事件。 Recoverable Error:无法取消当前事件。 Recoverable Error:无法取消正在进行的事件。 Recoverable Error:无法取消未定位事件。 5)相关函数 采用 op_ev_pending()确定事件是否可取消。 采用 op_intrpt_schedule_self()设置进程的自中断。 采用 op_intrpt_clear_self()撤销进程的未决中断。

2.5 仿真函数集 1. op_sim_time() 此函数的作用是获取当前仿真时间。 1)返回值 double——当前仿真时间。该双精度浮点数以秒为单位表示了当前的仿真时间,从仿真中 断(即 op_sim_time()返回零值)时刻开始计时。 2)详解 仿真时间是一个双精度浮点数,表示与当前仿真事件相关的时间值。在处理一个事件时, 仿真时间始终保持原值, 只有当在 T 时刻完成了该事件并在 T+dt 时刻开始另一个事件时, 仿真

才开始继续计时。我们将这种使用不规则模式计时的仿真方法称为事件驱动的仿真方法(区别 于规则的时间驱动的仿真方法) 。 在仿真开始执行事件之前,无线发信机模块的收信机组管道阶段调用该函数,或无线域中 初始回叫信号过程调用该函数时,该函数都将返回“-1” 。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种获取当前仿真时间的机制,可用于将来预设事件时计算绝对时间; 确定过去某事件相对于当前仿真时间的延时;在标准输出设备或其他输出文件中打印带时间标 记的诊断信息和调试语句。 4)错误 该函数无错误捕获。 5)相关函数 采用 op_intrpt_schedule()、 op_intrpt_schedule_remote()或 op_intrpt_schedule_call()预设中断。 采用 op_pk_creation_time_get()或 op_pk_stamp_time_get()从包中获取时间值与当前仿真时 间进行比较。 采用 op_q_wait_time()或 op_q_insert_time()从队列模块中的包里获取队列延时信息。

2. op_sim_end(line0,line1,line2,line3) 此核心函数的作用是终止仿真,关闭矢量输出文件并打印指定行,其参数说明如表 2-11 所示。 表 2-11 op_sim_end()函数的参数说明 参 数 line0 line1 line2 line3 1)返回值 Void——无返回值。 2)详解 该函数在时间到期前终止仿真,同时所有激活了 endsim intrpt 属性的处理器和队列的都将 收到终止仿真中断。 当 OPNET 仿真工具正在运行仿真时,尽管四个指定行在直接指向 shell 的输出中都可见, 但同时只有前三行可以显示的消息窗口中。 类 型 const char* const char* const char* const char* 消息行#0 消息行#1 消息行#2 消息行#3 描 述

此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数基于可调用该函数的进程的动态状态,提供了一种有条件仿真的机制,通常应 用在以下两类环境中: 一个异常错误环境被仿真逻辑捕获,使得以后的仿真没有必要继续进行; 仿真逻辑发现基于仿真完毕状态的统计收敛或其他度量形式的仿真停止的情况。 在任一种模式下,有效终止仿真都非常必要,因为这样仿真中被写进的矢量、标量输出文 件就可以正常这完成并关闭。 4)错误 Program Abort: 分段错误(由无效或畸形消息串引起) 。 5)相关函数 采用 op_sim_time()确定当前仿真时间。 采用 op_stat_scalar_write()写出总结仿真结果的标量统计量值。 采用 op_sim_message()在标准输出设备中打印消息但不终止仿真。

2.6 鉴定函数集 Id(Identification)函数集是获取仿真对象 ID 的核心函数的集合。对象 ID 对于核心函数非 常重要,因为大多数与对象操作相关的核心函数都需要使用对象 ID。对象 ID 是一个惟一标识 仿真中某对象的整数, 所有的仿真对象共享一个共同的对象 ID 编号空间。 例如不管是节点还是 队列,都只能有一个 ID 为 5 的对象。

op_id_self() 此函数可获取所属处理器或队列的对象 ID。 1)返回值 Objid——所属处理器或队列的对象 ID。如果核心函数由非进程上下文调用,则返回符号 常量 OPC_OBJID_INVALID。 2)详解 如果该函数由非进程上下文(如运行在处理器或队列中的进程)调用,则返回符号常量 OPC_OBJID_INVALID。通过 op_intrpt_schedule_call()接口执行的预设过程调用,将继承调用进 程的上下文。因此,如果进程预设了一个过程调用,那么过程调用将收到 op_id_self()返回的有 效值。但管道阶段并不作为进程上下文,因此将返回 OPC_OBJID_INVALID。 此外,该核心函数的安全级别为 MT-safe。 3)目的

该核心函数为进程提供了一种获取其自身对象 ID 的机制。有了自己的 ID,进程就可通过 核心函数 op_ima_obj_attr_get()访问自己的属性值。此外,还可连续调用函数 op_topo_parent() 来获取所属节点或子网的对象 ID。 op_id_self()也可用于测试当前上下文是否属于某一进程,如果不属于,则返回常量 OPC_OBJID_INVALID。 4)错误 该核心函数无错误捕获。 5)相关函数 采用 op_topo_parent()获取父对象 ID。 采用 op_topo_child()获取子对象 ID。 采用 op_ima_obj_attr_get()获取对象属性值。 采用 op_ima_obj_attr_set()设置对象属性值。

2.7 拓扑函数集 Topo(Topology)函数集是确定节点和网络模型拓扑结构的核心函数的集合。利用这类核心 函数,进程模型在被写入时可以自动配置以符合其所属环境。 1. op_topo_parent (child_objid) 此核心函数的作用是获取给定对象的父对象 ID,其参数说明如表 2-12 所示。 表 2-12 op_topo_parent()函数的参数说明 参 数 类 型 描 述

子对象 ID(对象 ID 可通过 Id 函数集里的函数 op_id_self()、 op_id_from_userid()或 op_id_from_name()获取,也可通过调用 child_objid Objid 本 函 数 集 里 的 函 数 op_topo_parent() 、 op_topo_child() 、 op_topo_assoc()和 op_topo_connect()来获取。 ) 1)返回值 Objid——父对象 ID。如果参数 child_objid 为最高级别的子网 ID,则返回符号常量 OPC_OBJID_NULL;如果发生可恢复错误,将返回符号常量 OPC_OBJID_INVALID。 2)详解 连续调用该核心函数可用于提示对象层次结构。例如在一个五级对象仿真中,可利用子队 列对象 ID,通过连续五次调用该函数来获取最高级别的子网(对象 ID=0) ,程序如下所示: subq_comp_attr_objid=op_topo_parent(subqueue_objid); queue_objid=op_topo_parent(subq_comp_attr_objid); node_objid=op_topo_parent(queue_objid);

subnet_objid=op_topo_parent(node_objid); top_subnet_objid=op_topo_parent(subnet_objid); 注意:subq_comp_attr_objid 是复合属性的嵌入类型。对于用户自定义的算命属性有: comp_attr_objid= op_topo_parent(generic_objid) path 没有父对象,因此若 child_obj_hndl 指向一个 path 对象,则该函数将返回一个无效句 柄。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种已知低层对象 ID, 需要对高层对象进行操作时, 提升对象层次结构 的机制。通常,该核心函数用于获取包含运行调用进程的处理器或队列的节点(或子网)ID。 在获取了节点或子网的对象 ID 后,就可通过 op_ima_obj_attr_get()获取它们的属性值。 4)错误 Recoverable Error:对象 ID 溢出。 Recoverable Error:对象 ID 指向受限对象。 5)相关函数 采用 op_id_self()获取所属处处理器或队列模块的对象 ID。 采用 op_topo_child()获取另一对象的子对象 ID。 采用 op_ima_obj_attr_get()获取对象属性值。 采用 op_ima_obj_attr_set()设置对象属性值。

2. op_topo_child_count (parent_objid, child_type) 此核心函数的作用是获取给定父对象中指定类型的子对象的数目,其参数说明如表 2-13 所示。 表 2-13 参 数 parent_objid child_type 1)返回值 int——给定父对象中指定类型的子对象的数目。 如果父对象不支持指定类型的子对象或父 对象 ID 无效,则将返回符号常量 OPC_OBJID_INVALID。 2)详解 仿真对象通常包含的子对象如表 2-14 所示。 表 2-14 op_topo_child_count ()函数的参数说明 类 型 Objid int 父对象 ID 相关子对象类型 op_topo_child_count ()函数的参数说明 描 述

仿真对象 子网 节点 队列 收信机 发信机 复合属性

所 含 子 对 象 子网、节点、链路和接头 模块、流和统计线 子队列复合属性 收信机信道复合属性对象 发信机信道复合属性对象 普通子对象、子队列、收信机信道和发信机信道

通常仿真对象并不包含以下子对象:单工和双工方式的点到点链路、总线链路、总线链路 接头、处理器和天线。 path 没有子对象,也不属于任何子网,因此如果参数 parent_object 指向一个 path 对象或参 数 child_type 等于 OPC_OBJTYPE_PATH,则该核心函数将返回零。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种确定父对象包含的子对象数目的机制。 可利用父对象 ID、 定义对象 类型的符号常量和环路索引来调用函数 op_topo_child(),以获取每个子对象的对象 ID。 4)错误 Recoverable Error:对象 ID 溢出。 Recoverable Error:对象类型不可识别。 Recoverable Error:对象 ID 指向受限对象。 5)相关函数 采用 op_topo_child()根据索引来获取子对象 ID。 采用 op_topo_object_count()确定特定类型对象的数目。 采用 op_topo_assoc_count()获取输入和输出关联的数目。

3. op_topo_child (parent_objid, child_type, child_index) 此核心函数的作用是获取具有指定类型和索引的子对象 ID,其参数说明如表 2-15 所示。 表 2-15 参 数 parent_objid child_type child_index 类 型 Objid int int 父对象 ID 子对象类型 子对象索引(子索引从零开始逐一递增,最大不超过本类 子对象的总数减一) op_topo_child ()函数的参数说明 描 述

1)返回值 Objid——子对象 ID。如果发生可恢复错误,将返回符号常量 OPC_OBJID_INVALID。 2)详解 确定子对象需要两个参数:子对象类型和子对象索引。连续调用该函数可降低对象的层次 结构。 例如在一个五级对象仿真中, 可能过连续五次调用该函数将最高级别的子网 (对象 ID=0) 转换为子队列对象 ID,程序如下所示: subnet_objid=op_topo_child(top_subnet_objid, OPC_OBJTYPE_SUBNET_FIX, 0); node_objid=op_topo_child(subnet_objid, OPC_OBJTYPE_NDFIX, 0); queue_objid=op_topo_child(node_objid,OPC_OBJTYPE_QUEUE, 0); subq_comp_attr_objid=op_topo_child(queue_objid, OPC_OBJTYPE_COMP, 0); subqueue_objid=op_topo_child(subq_comp_attr_objid, OPC_OBJTYPE_SUBQ, 0); 注意,subq_comp_attr_objid 是复合属性的嵌入类型。对于用户自定义的复合属性有: Generic_objid=op_topo_child(comp_attr_objid, OPC_OBJTYPE_GENERIC, 0); path 没有子对象,也不属于任何子网,因此若 parent_obj_hndl 指向一个 path 对象或 child_type 等于 OPC_OBJTYPE_PATH,则该核心函数将返回一个空句柄。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种已知高层对象 ID, 需要对低层对象进行操作时, 降低对象层次结构 的机制。 该函数通常用于获取已知发信机或收信机的信道 ID, 从而通过函数 op_ima_obj_attr_get() 或 op_ima_obj_attr_set()来获取信道属性值或为其赋值。该函数还可用于获取节点中的模块 ID, 但通常使用名称而不是索引值来确定子对象的函数 op_id_from_name()。该函数也可用于获取用 户自定义的复合属性和其子对象 ID。 4)错误 Recoverable Error:对象 ID 溢出。 Recoverable Error:对象类型不可识别。 Recoverable Error:对象无子对象。 Recoverable Error:对象索引溢出。 Recoverable Error:子索引超过指定类型子对象。 Recoverable Error:对象 ID 指向受限对象。 5)相关函数 采用 op_topo_child_count()确定对象的子对象数目。 采用 op_ima_obj_attr_get()获取对象属性值。 采用 op_ima_obj_attr_set()设置对象属性值。

采用 op_topo_object()获取对象 ID。 采用 op_topo_parent()获取父对象 ID。 采用 op_id_from_name()通过名称获取子对象 ID。

4. op_topo_assoc (objid, direction, objmtype, index) 此核心函数的作用是获取具有指定类型、 方向和索引的对象关联 ID, 其参数说明如表 2-16 所示。 表 2-16 参 数 objid 类 型 Objid 对象 ID 关联的方向: OPC_TOPO_ASSOC_IN:输入关联 direction int OPC_TOPO_ASSOC_OUT:输出关联 OPC_TOPO_ASSOC_THROUGH:吞吐率关联 objmtype index 1)返回值 Objid — — 输 入 / 输 出 关 联 的 对 象 ID 。 如 果 发 生 可 恢 复 错 误 , 则 返 回 符 号 常 量 OPC_OBJID_INVALID。 2)详解 所谓对象的输入/输出关联,就是直接与输入/输出端口或在节点处开始/结束的路径相连的 对象。表 2-17 列出了有效的对象和关联类型。 int int 关联的对象 meta-type 关联的数值索引(从零开始,逐一递增) op_topo_assoc ()函数的参数说明 描 述

表 2-14 对象类型 site(fixed subnet; fixed site, link, path node) link(bus;simplex; site receiver duplex; pt-pt link) 输 入

对象和关联类型 输 出 经 由

site, link, path

path

site receiver

path all attached nodes/links,

path

site (head/tail)

site(head/tail)

all demands flowing through

demand module(processor,

site(destination) module connection

site(source) module

all path used none

queue, and so on) connection(stream, module statistic wire) transmitter(pt-pt, bus, module connection radio) receiver(pt-pt, bus, link transmitter radio) tap bus transmitter bus receiver bus bus, bus transmitter

connection module none

link receiver module

none

none connection bus,bus none receiver tap none tap none none none

none tap tap

在无线建模中,移动站点和卫星站点不能与点到点链路或总线链路相连,因此只能是中由 关联和需求关联。同样,无线域也没有关联。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种已获取与输入/输出对象相关联的对象关联的对象 ID 的机制。该函 数主要用于进程需要获取钷设置邻近对象属性的情况下,如在发信机相连的处理器上运行的进 程,可能需要周期性地改变发信机信道的频率;或进程可能质询输出点到点链路的属性。 4)错误 Recoverable Error:对象 ID 溢出。 Recoverable Error:关联方向不可识别。 Recoverable Error:对象 meta-type 不可识别。 Recoverable Error:关联索引溢出。 Recoverable Error:对象类型不支持关联。 Recoverable Error:对象不支持关联方向。 Recoverable Error:关联索引超过关联类型。 Recoverable Error:对象 ID 指向受限对象。 5)相关函数 采用 op_topo_assoc_count()确定对象拥有的关联数目。 采用 op_ima_obj_attr_get()获取对象属性值。

5. op_topo_assoc_count (objid, direction, objmtype) 此核心函数的作用是获取具有特定类型和和对象的关联数目,其参数说明如表 2-18 所示。 表 2-18 参 数 objid 类 型 Objid 对象 ID 关联的方向: direction int OPC_TOPO_ASSOC_IN:输入关联 OPC_TOPO_ASSOC_OUT:输出关联 objmtype 1)返回值 Objid — — 特 定 方 向 和 类 型 的 关 联 数 目 。 若 发 生 可 恢 复 错 误 , 则 返 回 符 号 常 量 OPC_OBJID_INVALID。 2)详解 对象的输入/输出关联,是直接与输入/输出端口相连的对象,参看表 2-17。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种确定对象拥有的输入/输出关联的数目的方法。 这对于设置关联对象 的环路范围很有用。 可根据对象 ID 和环路索引调用函数 op_topo_assoc()来获取每个关联的对象 ID。 4)错误 Recoverable Error:对象 ID 溢出。 Recoverable Error:关联方向不可识别。 Recoverable Error:对象 meta-type 不可识别。 Recoverable Error:对象类型不支持关联。 Recoverable Error:引用对象不支持关联方向。 Recoverable Error:对象 ID 指向受限对象。 5)相关函数 采用 op_topo_assoc ()获取输入/输出关联的对象 ID。 采用 op_ima_obj_attr_get()获取对象属性值。 采用 op_ima_obj_attr_set()设置对象属性值。 采用 op_topo_child_count()确定子对象数目。 采用 op_topo_object_count()确定特定类型的对象数目。 int 关联的对象 meta-type op_topo_assoc_count ()函数的参数说明 描 述

2.8 接口控制信息函数集 ICI(Interface Control Information)函数集是与 ICI 仿真实实体相关的核心函数的集合。ICI 是内部进程通信所传递的数据的结构化集合。若进程在中断发生之前建立 ICI,则 ICI 就与中 断关联起来了。 主要用于分层协议的接口连接, ICI 也可用于关联复杂的自中断或点到点远程中 断的信息。 1. op_ici_create(fmt_name) 此核心函数的作用是创建一个具有预定义 ICI 格式的 ICI,其参数说明如表 2-19 所示。 表 2-19 参 数 fmt_name 1)返回值 Ici*——指向新创建的 ICI 的指针。若发生可恢复错误,则返回常量 OPC_NIL。 2)详解 新的 ICI 由仿真内核分配, 该函数返回它的指针并允许原始进程指定 ICI 属性。ICI 格式是 预先定义的固定结构,由一系列属性名称和类型按序组成。除非调用函数 op_ici_install(),否则 新创建的 ICI 不会自动影响预设中断。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数为进程模型提供了一种创建新的 ICI 与邻居进程进行通信的机制。如果进程模 型每次预设中断时都改变 ICI 的属性,并且在传递中断前又预设新的中断,那么它应为每个预 设中断创建一个新的 ICI。换句话说,如果两个进程模型采用一系列未延迟的 ICI-bearing 中断 进行通信,那么中需要在开始仿真时为单向通信创建一个 ICI(或为双向通信创建两个 ICI) 。 4)错误 Program Abort:内存分配失败(由于内存不足以满足新创建的 ICI 或其属性而引起) 。 Program Abort:核心数需要进程上下文。 Recoverable Error:ICI 格式不可识别 5)相关函数 采用 op_ici_destroy()销毁 ICI。 采用 op_ici_attr_set()为 ICI 属性赋值。 采用 op_ici_install(0 创建一个与输出中断相关联的 ICI。 采用 op_ici_format_print_set()打印给定格式 ICI 的指定结构字段。 类 型 const char* op_ici_create ()函数的参数说明 描 述

被创建 ICI 的格式名称 (该值必须为已定义的 ICI 格式名称, 否则将出错。 )

2. op_ici_destroy(iciptr) 此核心函数的作用是解除已分配的 ICI,并释放相应的内存资源,其参数说明如表 2-20 所 示。 表 2-20 参 数 类 型 op_ici_destroy ()函数的参数说明 描 述

指向给定 ICI 的指针(可以通过两个核心函数来获取 ICI 指 针:在 ICI 发送进程中,函数 op_ici_create()返回新创建 ICI iciptr Ici* 的指针:在 ICI 接收进程中,函数 op_intrpt_ici()返回与输入 中断相关的 ICI 指针) 1)返回值 Void——无返回值。 2)详解 当不再使用某个 ICI 时,就应当释放分配给它的内存资源,以用来创建新的 ICI。若在仿 真内核心释放 ICI 内存资源时出错,将导致无用的 ICI 持续占用虚拟内存。虚拟内存被完全占 用后,将无法满足创建其他新对象的需要,则仿真异常结束。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种重复利用分配给无用 ICI 的内存的机制。仿真内核可自由地按需将 内存分配给其他动态对象。调用该函数后,给定 ICI 的指针就应视为无效。 4)错误 Program Abort:分段错误(由无效 ICI 指针或畸形 ICI 数据结构引起) 。 Recoverable Error:ICI 指针为 NIL。 5)相关函数 采用 op_ici_create()创建 ICI。 采用 op_intrpt_ici()获取与输入中断相关的 ICI 指针。 采用 op_ici_attr_set()为 ICI 属性赋值。 采用 op_ici_install()创建一个与输出中断相关联的 ICI。

3. op_ici_attr_get(iciptr, attr_name, value_ptr) 此核心函数的作用是获取给定 ICI 的某属性值,其参数说明如表 2-21 所示。

表 2-21

op_ici_attr_get ()函数的参数说明

参 数 iciptr attr_name value_ptr 1)返回值

类 型 Ici* const char* Vartype* 指向给定 ICI 的指针 属性名





指向变量的指针,该变量中存储了将赋给指定属性的值。

Compcode——表示是否成功获取 ICI 属性值的完整代码,如果发生可恢复错误,则返回 OPC_COMPCODE_FAILURE。 2)详解 给定的属性名必须是 ICI 引用的格式中定义过的属性。注意,函数返回的是属性的当前内 容,而不是创建 ICI 或预设相关中断时的属性内容。 进程模型是通过指针和不同的包来操作 ICI 的,并没有 ICI 所有权的概念。也就是说,几 个进程模型可能同时访问同一 ICI 数据结构,因此可能会互相干扰。当多个事件都处理同一 ICI 时,修改 ICI 将影响 ICI 在之前事件中的使用。例如,如果一个进程创建了一个 ICI,为其属性 赋值,将其安装,接着发送了一个包,并在包收到之前修改了 ICI 的一个属性,那么值将是进 程模型收到包时通过函数 op_ici_attr_get()访问 ICI 获取的值。 在声明参数 value_ptr 时必须注意, value_ptr 不仅要具有正确的数据类型, 还必须是指向可 用内存的有效指针,因此该参数通常都使用 C 语言的地址操作符“&” 。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种进程收到与 ICI 相关的中断并确定 ICI 属性值的机制。 由于一个 ICI 可被多个进程共享,因而它可用于多路通信。这里进程收到一个中断,从 ICI 中获取控制信息, 并能过在 ICI 中设置属性来返回信息。因为返回值可立即被初始进程访问,所以通常可与强制 中断结合使用。 4)错误 Program Abort:分段错误(由无效 ICI 指针、畸形 ICI 数据结构或声明出错的 value_ptr 参 数引起) Recoverable Error:属性名称在 ICI 格式中不可识别 5)相关函数 采用 op_intrpt_ici()获取与输入中断相关的 ICI 指针。 采用 op_ici_attr_exists()确定在 ICI 格式中是否存在某属性。 采用 op_ici_attr_set() 设置 ICI 属性值。 采用 op_ici_destroy()销毁无用 ICI。 采用 op_ici_print()在标准输入设备上打印 ICI 内容。

4. op_ici_attr_set(iciptr,attr_name, value) 此核心函数的作用是为给定 ICI 某属性赋值,其参数说明如表 2-22 所示。 表 2-22 参 数 iciptr attr_name value 1)返回值 Compcode——表示 ICI 属性值是否成功修改的完成代码,如果发生可恢复错误,则返回 OPC_COMPCODE_FAILURE。 2)详解 给定的属性名必须是 ICI 引用的格式中定义过的属性。通过该函数所赋的值将覆盖之前分 配的值,而任何具有该 ICI 指针的进程都可访问新的属性值。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了进程中设置 ICI 内容并与其他进程进行通信的机制。新创建的 ICI 和已 经发送到目的进程的 ICI 都可以进行属性设置。ICI 通过强制中断来执行双向通信,这样初始进 程就可立即获取结果。 4)错误 Program Abort:分段错误(由无效 ICI 指针、畸形 ICI 数据结构或声明出错的 value_ptr 参 数引起) Program Abort:核心函数需要进程上下文。 Recoverable Error:属性名称在 ICI 格式中不可识别 5)相关函数 采用 op_ici_attr_get() 获取 ICI 属性值。 采用 op_ici_create()创建 ICI。 采用 op_ici_install()建立一个与输出中断相关的 ICI。 采用 op_ici_attr_exists()确定在 ICI 格式中是否存在某属性。 类 型 Ici* const char* Vartype* 指向给定 ICI 的指针 给定属性的名称 为给定属性所赋的值 op_ici_attr_set ()函数的参数说明 描 述

5. op_ici_install(iciptr) 此核心函数的作用是建立一个 ICI,使其自动与调用进程预设的输出中断相关联,其参数 说明如表 2-23 所示。

表 2-23 参 数 iciptr 1)返回值 类 型 Ici*

op_ici_install ()函数的参数说明 描 述

指向给定 ICI 的指针

Ici*——建立的 ICI,如果为空则返回 OPC_NIL。 2)详解 任何时候,最多只能为一个进程建立一个 ICI。队列/处理器模块中的进程各自维持自己建 立的 ICI。建立 ICI 将通知仿真内核所有调用进程预设中断都应标记给定 ICI 的指针,这使得很 多预设中断不需要打标记并创建一个新的 ICI 就可自动与 ICI 关联。 在中断预设到中断传递这段时间内, 不管 ICI 发生什么变化 (包括修改 ICI 内容或销毁 ICI) , 预设中断都将始终维持与 ICI 的关联。在这种情况下,进程在收取中断时可能还将收到其他额 外信息。为了避免这种情况,通常发送进程为每个中断都创建并建立一个 ICI,而接收进程就应 当担负起销毁进程的责任。 即使处理中断并不需要与之相关的 ICI,但将 ICI 与中断保持关联也不会产生什么坏处, 因此并没有显式提供解除建立 ICI 的函数。直到需将输出中断与另一个 ICI 关联时,才需要解 除建立的当前 ICI。不过通过将常量 OPC_NIL 传递给参数 iciptr,可以用来解除 ICI 的建立,从 而阻止与输出中断的关联。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种 将预设 ICI 与输出中断相关联的机制。 每个进程都维持一个指向被 建立 ICI 的内部指针,则建立的 ICI 在非强制状态及多处理机调用中都是有效的。 4)错误 Program Abort:分段错误(由无效 ICI 指针或畸形 ICI 数据结构引起) Program Abort:核心函数需要进程上下文。 5)相关函数 采用 op_ici_create()创建 ICI。 采用 op_ici_attr_get()获取 ICI 属性值。 采用 op_ici_attr_set()设置 ICI 属性值。

2.9 中断函数集 Intrpt(Interrupt)函数集是提供具有输入中断信息的进程并可预设输出中断的核心函数的集 合。

1. op_intrpt_schedule_self (time, code) 此核心函数的作用是为调用进程预设一个中断,其参数说明如表 2-24 所示。 表 2-23 参 数 time 类 型 double op_ici_install ()函数的参数说明 描 述

预设的中断时间 (该值为绝对仿真时间, 而不是当前仿真时间的时延) 与中断关联的用户自定义数值代码(该值是一个完全由用户自定义的

code

int

整数值,可作为预设中断的标识代码。当中断调用进程时,可通过函 数 op_intrpt_code()获取该代码)

1)返回值 Evhandle——预设中断的事件句柄。该返回值可存储在一个状态变量中,以用于以后调用 函数 op_ev_cancel()时取消中断。 2)详解 调用该函数时将在仿真事件列表中加入一个代表预设自中断的新事件。一旦预设了事件, 函数将立即返回调用进程的控制权。在延时期间,调用进程可自由进行其他任何活动。如果没 有其他高优先级事件,预设的事件将会按时发生。当执行完所有的前期事件后且自中断事件位 于仿真事件列表的表头时,即将其仿真时间设为当前仿真时间并执行事件,引发调用进程的自 中断。进程可通过函数 op_intrpt_code()获取与中断相关的代码。 当自中断表示超时或其他类似事件时,有必要取消无用的自中断。如在超时前收到了 ack, 则重置计时器。该函数返回的事件句柄将存储在一个状态变量中,将来就可利用该事件句柄调 用函数 op_ev_cancel()来取消中断,程序如下所示: /*Sstate variable declaration*/ Evhandle \evh;

/*Self interrupt scheduling*/ evh=op_intrpt_schedule_self(sch_time,5);

/*Self interrupt canceling.*/ op_ev_cancel(evh); 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了预设自中断的机制,常用来限制某个进程状态的持续时间。当模拟超时 时,状态将保持在等待包的到达,而超时自中断就表示该状态的结束。当模拟延时时,状态将 保持在执行任务,而“结束任务”自中断意味着任务完成并释放资源。时间间隔结束后,进程

通常转入空闲状态或确定是否有其他未决任务需要执行。 4)错误 Program Abort:内存分配失败。 Program Abort:核心函数需要进程上下文。 Recoverable Error:预设时间小于当前时间。 Recoverable Error:预设时间是一个无效的 double 值。 5)相关函数 采用 op_intrpt_schedule_remote()预设一个远程中断。 采用 op_intrpt_force_remote()强制预设远程中断。 采用 op_intrpt_schedule_call()预设一个过程中断。 采用 op_ev_cancel()取消未决的自中断、远程中断或过程中断。 采用 op_intrpt_code()获取与中断相关的代码。

2. op_intrpt_schedule_remote (time, code, mod_objid) 此核心函数的作用是为给定处理器或队列预设一个远程中断,其参数说明如表 2-25 所示。 表 2-25 参 数 time code 类 型 double int 预设的中断时间 与中断相关的用户自定义数值代码 给定处理器或队列的对象 ID(处理器或队列 ID 可通过 Id 函 mod_objid Objid 数集中的 op_id_self()、op_topo_child()和 op_id_from_name() 函数来获取) 1)返回值 Evhandle——预设中断的事件句柄。该返回值可存储在一个状态变量中,用于以后调用函 数 op_ev_cancel()时取消中断。 2)详解 调用该函数时将在仿真事件列表中加入一个代表预设自中断的新事件。一旦预设了事件, 函数将立即返回调用进程的控制权。在延时期间,调用进程可自由进行其他任何活动。如果没 有其他高优先级事件,预设的事件将会按时发生。当执行完所有的前期事件后且自中断事件位 于仿真事件列表的表头时,即将其仿真时间设为当前仿真时间并执行事件,引发调用进程的自 中断。进程可通过函数 op_intrpt_code()获取与中断相关的代码。 该函数返回事件句柄并将其存储在一个状态变量中,当发生条件改变需要取消中断时,可 以利用该事件句柄,调用函数 op_ev_cancel()取消预设的远程中断,程序如下所示: op_intrpt_schedule_remote()函数的参数说明 描 述

/*Sstate variable declaration*/ Evhandle \evh;

/*Remote interrupt scheduling*/ evh=op_intrpt_schedule_remote(stime,22,mod_objid);

/*Remote interrupt canceling.*/ op_ev_cancel(evh); 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了无需物理包流或统计线的连接,进程可远程调用另一进程的机制,进程 可用它来警告另一进程某事件的发生。 注意:远程中断只能传递到处理器或队列,否则将引发错误。 4)错误 Program Abort:内存分配失败。 Recoverable Error:预设时间小于当前时间。 Recoverable Error:预设时间是一个无效的 double 值。 Recoverable Error:对象 ID 溢出。 Recoverable Error:对象类型错误。 5)相关函数 采用 op_intrpt_schedule_self()预设一个自中断。 采用 op_intrpt_schedule_call()预设一个过程中断。 采用 op_ev_cancel()取消未决中断。 采用 op_intrpt_code()获取与中断相关的代码。

3. op_intrpt_type () 此核心函数的作用是获取调用进程的当前中断类型。 1)返回值 int——当前中断类型。 2)详解 该函数返回的中断类型包括: ? ? OPC_INTRPT_FAIL(节点或链路失败中断) ; OPC_INTRPT_RECOVER(节点或链路失败中断) ;

? ? ? ? ? ? ? ? ? ? ?

OPC_INTRPT_PROCEDURE(过程中断) ; OPC_INTRPT_SELF(自中断) ; OPC_INTRPT_STRM(流中断) ; OPC_INTRPT_REGULAR(常规中断) ; OPC_INTRPT_STAT(统计中断) ; OPC_INTRPT_REMOTE(远程中断) ; OPC_INTRPT_BEGSIM(仿真起始中断) ; OPC_INTRPT_ENDSIM(仿真结束中断) ; OPC_INTRPT_ACCESS(访问中断) ; OPC_INTRPT_PROCESS(进程中断) ; OPC_INTRPT_MCAST(广播中断) ;

此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种机制来确定是何原因“唤醒”调用进程。该函数是最基本的核心函 数,几乎每个进程模型都会使用它。进程模型大多都有一个或多个“分支状态” ,分支状态将该 过程返回的值存储在一个临时变量中,然后根据该返回值来选取输出转换。 4)错误 该核心函数无错误捕获。 5)相关函数 采用 op_intrpt_code()确定与当前中断相关的代码。 采用 op_intrpt_strm()确定与当前中断相关的流索引。 采用 op_intrpt_stat()确定与当前中断相关的输入统计索引。 采用 op_intrpt_ici()获取与当前中断相关的 ICI。

4. op_intrpt_strm () 此核心函数的作用是获取与调用进程当前中断相关联的流索引。 1)返回值 int——与当前中断相关联的流索引。当使用函数 op_pk_deliver…()将包传递到指定输入流 时,将显式设置该值;当使用函数 op_pk_send…()向包流中发送包或通过函数 op_strm_access() 访问包流时,将隐式设置该值。 2)详解 在与流相关联的中断后调用该函数,将只产生一个有效值。与流相关联的中断有两类:流 中断和访问中断。前者的流是指包到达的输入流,而后者的流是指与之相连的模块访问的输出

流。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 对于流中断,该函数确定了包是通过哪个输入流到达的;而对于访问中断,函数可确定所 连处理器或队列访问的是哪个输入流。 4)错误 Program Abort:核心函数需要进程上下文。 Recoverable Error:当前事件不是流中断或访问中断。 5)相关函数 采用 op_intrpt_type()确定当前中断的类型。 采用 op_intrpt_code()确定与当前中断相关的代码。 采用 op_intrpt_stat()确定与当前中断相关的输入统计索引。 采用 op_pk_send…()和 op_pk_deliver…()将包发送或传递到模块输入流中。 采用 op_strm_access()访问处理器或队列的输出流。

5. op_intrpt_ici () 该核心函数的作用是获取与当前中断相关联的 ICI。 1)返回值 Ici*——指向与当前中断相关联的 ICI 的指针。 2)详解 进程中断中携带的信息类型包括中断类型、与中断相关的标记或代码,有时还携带 ICI 信 息。获取 ICI 的指针允许接收进程撮其内容。将 ICI 的内容完全处理后,可通过 op_ici_destroy() 重复利用该 ICI。但只有当源进程为每个输出中断创建了新的 ICI,才能销毁 ICI。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数为进程提供了一种获取与当前中断相关的 ICI 指针的机制。一旦获取该指针, 便可使用函数 op_ici_attr_get()来提取 ICI 内容。 4)错误 该核心函数无错误捕获。 5)相关函数 采用 op_ici_create()创建 ICI。 采用 op_ici_install()为输出中断建立一个 ICI。 采用 op_ici_destroy()解除已处理的 ICI。

采用 op_intrpt_type()确定当前中断类型。 采用 op_ici_attr_get()获取 ICI 属性值。 采用 op_ici_attr_exists()确定 ICI 是否包含特殊属性。

6. op_intrpt_code () 此核心函数的作用是获取与调用进程当前中断相关联的数值代码。 1)返回值 int——与当前中断相关联的数值代码。 2)详解 当在具有与代码相关联的中断之后调用该函数时,将只产生有效值。支持代码的中断类型 为自中断、进程中断和远程中断。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了一种机制来确定与中断相关联的用户自定义数值代码,从而确定其目 的,主要用于存在多个相同类型、不同目的的中断的情况下。 4)错误 该核心函数无错误捕获。 5)相关函数 采用 op_intrpt_type()确定当前中断类型。 采用 op_intrpt_strm()确定与当前中断相关的流索引。 采用 op_intrpt_stat()确定与统计中断相关的输入统计索引。 采用 op_intrpt_source()确定当前中断的源对象。 采用 op_intrpt_ici()获取与当前中断相关的 ICI。

2.10 包函数集 Pk(Packet)函数集是有关处理包、主要数据建模以及封装机制的核心函数的集合。Pk 函数 集中支持的操作类型包括创建/销毁包、设置/获取包的数据内容以及获取包的特殊属性的信息。 1. op_pk_create_fmt (format_name) 此核心函数的作用是创建一个具有预定义包格式的包,其参数说明如表 2-26 所示。 表 2-26 参 数 类 型 op_pk_create_fmt()函数的参数说明 描 述

包格式名(名格式是在包格式编辑器中创建的,包格式必须放 format_name const char* 在模型目录中, 否则将发生错误。 包格式文件采用.pk.m 后缀名)

1)返回值 Packet*——指向新创建的包的指针,如果发生可恢复错误,则返回 OPC_NIL。 2)详解 新创建的包由仿真内核分配,并在调用该函数的进程模型所在的处理器或队列处加入循 环。由于采用预定义的包格式,因而新创建的包的某些字段可能采用预先指定的默认值。包的 初始大小就是所有字段大小的总和,包的 bulk 数据大小与包格式无关,初始值为零,可通过函 数 op_pk_bulk_size_set()进行修改。 包一旦被创建,将被分配一个惟一的 ID 号。包的创建时间和时间戳均设为调用该函数时 的仿真时间,而创建模块和戳模块设为运行调用该函数的进程模块。 此外,该核心函数的安全级别为 MT-safe。 3)目的 该核心函数提供了一种获取具有预定格式和默认内容的格式化亿的机制。由于字段的数据 类型不能更改也不能添加新的字段,因而格式化包是面向特定数据集通信的。采用格式化包的 好处就在于其字段可通过名称来标识,这将简化设置时的操作。但需注意的是,字段名必须与 预定的包格式中的字段名一致,否则当利用名称来确定字段时将造成性能的下降。 新创建的包被赋予特定的内容,并使用 op_pk_send…()和 op_pk_deliver…()函数将其从创 建模块转发出去,同时将新建包的指针存储到一个进程模型状态变量中,以供稍后再次传输包 时使用。 4)错误 Program Abort:内存分配失败。 Program Abort:分段错误(由错误的格式名称参数引起) 。 Recoverable Error:包格式不可识别。 Recoverable Error:设置了非法包格式字段。不可在创建设置类型结构字段。 Recoverable Error:设置了非法包格式字段。不可在创建设置类型包字段。 5)相关函数 采用 op_pk_nfd_set()设置格式化包的字段。 采用 op_pk_send…()或 op_pk_deliver…()将包发送到其他模块。 采用 op_pk_destroy()销毁无用包。

2. op_pk_copy (pkptr) 此核心函数的作用是创建指定包的复本,其参数说明如表 2-27 所示。

表 2-27 op_pk_copy()函数的参数说明

参 数 pkptr 1)返回值

类 型 Packet* 指向原包的指针





Packet*——指向复本包的指针。 2)详解 该核心函数创建一个包,并将指定包的头部复制到新创建的包中。复本包将引用原包的字 段,当原包或复本包的某个字段发生改变时,所有字段的复制必须在改变之前完成。 所有格式化包和非格式化包都可以用用该函数来进行复制,复本包将具有与原包相同的类 型。对结构字段(OPC_FIELD_TYPE_STRUCT)的复制采用与字段分配相关的函数,如函数 op_pk_fd_set()或 op_pk_nfd_set()。对包字段(OPC_FIELD_TYPE_PACKET)的复制将采取包的 递归复制。其他字段类型都作为普通数据项进行复制。 复本包被分配一个惟一的 ID。 包的创建时间设为调用该函数时的仿真时间, 创建模块设为 运行该函数的进程的模块。若该函数不是由进程或间接进程函数调用的,那么创建模块的对象 ID 将设为常量 OPC_OBJID_INVALID。包的时间戳和模块是由原包复制而来的,因此戳以复本 包字段为准,可通过显式调用 op_pk_stamp()对其进行更改。 在复制过程中,原包的路由也将被复制,但并不复制 ICI,原包和复本包均通过指针指向 同一个 ICI。 此外,该核心函数的安全级别为 MT-safe。 3)目的 该核心函数提供了一种复制包的机制,主要用于: ? ? 产生包的多个洪泛传输。 备份输出的包以供将来重传使用。

4)错误 Program Abort:分段错误(由无效包指针、畸形包或畸形结构/包字段引起) 。 Program Abort:总线错误(由对包的结构字段分配无效地址引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未许可包。 Program Abort:内存分配失败。 5)相关函数 采用 op_pk_id ()确定复本包的包 ID。 采用 op_pk_destroy()销毁原包或复本包。 采用 op_pk_create()或 op_create_fmt()创建不基于其他包的新包。

3. op_pk_destroy (pkptr) 此核心函数的作用是销毁包并释放其内存资源,其参数说明如表 2-28 所示。 表 2-28 参 数 pkptr 1)返回值 void——无返回值。 2)详解 当不再使用一个包时,就可以通过该函数将其从循环中移除,释放其内存,并同时销毁与 之相关的路由。 在销毁包时并不同时销毁与之相关的 ICI, 因为其他包或进程模型可能仍在使用 该 ICI。可以使用函数 op_ici_destroy()来单独销毁 ICI。 包被销毁后,就可重新利用其释放的内存来创建新的包。如果操作失败将导致大量无用数 据包的积聚,若这些无用数据包占用了足够的虚拟内存,且不再满足新对象的分配需求,那么 最终将导致仿真异常中断。格式化包和非格式化包均可采用该函数来进行销毁。 该函数会自动释放所有结构字段和包字段的内存。不过,如果在销毁前已使用 op_pk_nfd_get()获取包的结构字段内容, 那么就必须使用 op_prg_mem_free()释放结构字段内存。 此外,该核心函数的安全级别为 MT-safe。 3)目的 ? 该核心函数提供了一种通过销毁无用包,释放其内存,来襀内存循环利用的机制。仿 真内核可自由分配释放后的内存。一旦函数正确返回,被销毁包的指针就宣告无效。 4)错误 Program Abort:分段错误(由无效包指针、畸形包或畸形结构/包字段引起) 。 Program Abort:总线错误(由对包的结构字段分配无效地址引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未许可包。 Program Abort:包指针指向静态包。 5)相关函数 采用 op_pk_create()或 op_create_fmt()创建不基于其他包的新包。 采用 op_pk_fd_strip()或 op_pk_nfd_strip()移除包中的某个字段。 采用 op_pk_creation_time_get()确定包被销毁前的生存时间。 类 型 Packet* 指向需被销毁的包的指针 op_pk_destroy()函数的参数说明 描 述

4. op_pk_get (instrm_index) 该核心函数的作用是获取到达输入包流的包的指针,并将其从流中移除,其参数说明如表 2-29 所示。 表 2-29 op_pk_copy()函数的参数说明 参 数 instrm_index int 1)返回值 Packet*——指向从输入流包流的指针。如果流中无包,则返回 OPC_NIL。可首先通过函 数 op_strm_empty()来确定流中是否包含包。 2)详解 该核心函数获取包的方式有两种,一种是获取在包流中发送的包,另一种 是获取由远程 模块传送的包,两种获取方式没有任何区别。 安静地发送或传递到输入流(采用函数 op_send_quiet()或 op_deliver_quiet())中的包不会 引起相关模块的中断。如果多个安静包属于同一个输入流,则它们将按到达顺序进行排队,使 用函数 op_pk_get()只获取输入流队列中到达的第一个包,通过连续调用该函数就可从流中获取 剩余的包(可调用函数 op_strm_pksize()来获取输入流队列中包的数目) 。 由于该核心函数需要进程上下文,因而只有进程模型或进程模型直接或间接调用的函数才 能调用该函数。所有非格式化或格式化包均可通过该核心函数获取。 当调用该函数时,若输入流索引超过已存在输入流的最大索引,那么仿真内核将试图分配 新的输入流,这样就可通过包传递机制的无限多个输入流中获取包。 此外,该核心函数的安全级别为 MT-safe。 3)目的 该核心函数提供了从所属模块获取包的机制。由于该核心函数是进程获取并非自己创建或 声明的包的惟一方法,因此大量的进程模型都会采用该函数。 4)错误 Program Abort:核心函数需要进程上下文。 Program Abort: 内存分配失败。 Recoverable Error:输入流索引溢出。 5)相关函数 采用 op_pk_nfd_send()通过输出流 采用 op_pk_nfd_deliver()将包传递到未连模块的输入流中。 采用 op_pk_send()或 op_pk_deliver()以延时、强制、安静到达方式传递包。 采用 op_strm_empty()或 op_strm_pksize()确定输入流中是否包含包。 类 型 描 所属模块输入包流的索引。 述

5. op_pk_send (pkptr, outstrm_index) 此核心函数的作用是将包发送到输入包流中,基于当前仿真时间安排包到达某个目的模块 的时间,并释放调用进程对包的所有权,其参数说明如表 2-30 所示。 表 2-30 参 数 pkptr 类 型 Packet* 指向被发送包的指针 所属模块输出包流的索引值 op_pk_send()函数的参数说明 描 述

outstrm_index int 1)返回值 void——无返回值。 2)详解

该核心函数函数确定了包到达目的模块的时间。到达时间是相对于当前仿真时间而设定 的,相应事件随之加入到仿真事件列表中。事件发生在仿真时间结束之前,但并不在执行当前 仿真时间已经安排的其他事件之前执行。在执行事件之前,将通过一个流中断来调用目的模块。 如果目的模块是一个处理器或队列,相关进程可通过函数 op_intrpt_type()来确定中断是否由输 入流引起,如果是,则可通过函数 op_pk_get()获取该包。 一旦包传给该函数,包的所有权即从调用进程转到目的模块,之前进程将不能再继续调用 包。 由于该核心函数需要进程上下文,因而只有进程模型或进程模型直接或间接调用的函数才 能调用该函数。所有非格式化或格式化包均可采用该函数。 此外,该核心函数的安全级别 Forced serialization。 3)目的 该核心函数提供了在节点内的通过包流相连的模块间传递包的机制。该函数是仿真中进行 包传递的最基本函数。此类核心函数提供了延时、强制、安静到达目的模块等功能。在不依赖 模块间物理连接的情况下可通过函数 op_pk_deliver()来传递包。 函数 op_pk_sent()允许包传递到其他在处理器或队列中运行的进程或发信机模块中。 4)错误 Program Abort:分段错误(由无效包指针或畸形包引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未知包。 Program Abort:包指针指向静态包。 Program Abort:在对象或流中传递包失败。

Program Abort:核心函数需要进程上下文。 Recoverable Error:输出流索引溢出。 Recoverable Error:输出流索引未被占用。 5)相关函数 采用 op_pk_send_delayed()发送延时到达的包。 采用 op_pk_send_forced()发送包并立即在目的点进行处理。 采用 op_pk_send_quiet()发送包但不在目的模块处引起中断。 采用 op_pk_send_deliver…()将包传递到模块但并不采用包流。 采用 op_pk_get()获取包的指针。

6. op_pk_send_delayed (pkptr, outstrm_index, delay) 此核心函数的作用是将包发送到输出包流中,确定附加一段延时后包到达目的模块的时 间,并释放调用进程对包的所有权,其参数说明如表 2-31 所示。 表 2-31 参 数 pkptr 类 型 Packet* 指向被发送包的指针 所属模块输出包流的索引值 op_pk_send()函数的参数说明 描 述

outstrm_index int 1)返回值 void——无返回值。 2)详解

该核心函数函数确定了包到达目的模块的时间。到达时间为当前仿真时间加上一段特定的 延时,同时相应事件加入到仿真事件队列中。一旦预设了事件,该函数立即将控制权返回给调 用进程。如果没有其他高优先级的事件,那么预设事件将在指定的延时后如期执行。在延时期 内,调用进程可脱离延时包,执行任何其他事件。因此该函数可用来模拟与包传输相关的时延。 当执行该事件时,目的模块将会收到流中断,表示可通过函灵符 op_pk_get()获取该包。 一旦包传到该函数,调用进程就不再拥有包的所有权。任何由传递包指针的核心函数调用 的发送进程将引起包的所有权错误。该核心函数需要进程上下文,可支持格式化包和非格式化 包。 此外,该核心函数的安全级别 Forced serialization。 3)目的 该核心函数提供了通过包流相连的模块间传递包的机制。该函数是 op_pk_send()的衍生函 数, 对于模拟由调用进程引起的处理延时或传输延时很有用。op_pk_send()的其他衍生函数提供 了强制、安静到达目的模块等功能。在不依赖模块间物理连接的情况下可通过函数

op_pk_deliver()来传递包。 函数 op_pk_send_delayed()允许包传递到其他处理器或队列中运行的进程或发信机模块中。 4)错误 Program Abort:分段错误(由无效包指针或畸形包引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未知包。 Program Abort:包指针指向静态包。 Program Abort:在对象或流中传递包失败。 Program Abort:核心函数需要进程上下文。 Recoverable Error:输出流索引溢出。 Recoverable Error:输出流索引未被占用。 Recoverable Error:延时值溢出。 5)相关函数 采用 op_pk_send ()发送无延时的包。 采用 op_pk_send_forced()发送包并立即在目的点进行处理。 采用 op_pk_send_quiet()发送包但不在目的模块处引起中断。 采用 op_pk_send_deliver…()将包传递到模块但并不采用包流。 采用 op_pk_get()获取包的指针。

7. op_pk_nfd_set (pkptr, fd_name, value) 此核心函数的作用是为给定包的某一字段赋值, 该字段由其名称确定, 所赋的值只能是 Int、 Double 或包字段,其参数说明如表 2-32 所示。 表 2-32 参 数 pkptr fd_name value 1)返回值 Compcode — — 确 认 赋 值 操 作 是 否 成 功 的 完 成 代 码 。 如 果 发 生 可 恢 复 错 误 , 则 返 回 OPC_COMPCODE_FAILURE。 2)详解 函数参数 value 的声明采用 Vartype,它可接受 int、double 或包指针。核心函数会根据包的 类 型 Packet* const char* Vartype 指向给定包的指针 字段名 所赋的值 op_pk_()函数的参数说明 描 述

内部结构来确定传递给确定传递给参数的是何种类型的字段,从而改变它的字段分配方法。如 果给定字段之前未被赋值,则新字段的大小仍由包格式决定,并相应增加包总的大小。 对于 int、double 和包指针类型,需要指定字段的值。在该函数将包封装到字段中后,调用 进程就丧失了对被封装包的所有权,只有用函数 op_pk_fd_get()(如果为格式化包,采用函数 op_pk_nfd_get())对其进行解封装后,才可重新使用被封装包。 包类型字段采用特殊的方法来动态确定其大小。在用包格式编辑器在包格式中定义了这种 类型字段后,字段大小值就记入某数据表中。如果字段值设为“inherited” ,则字段大小就为被 封装包的大小,从而准确模拟了包的总大小。如果某字段大小在表中值小于等于 0,将不考虑 任何被封装包的大小,从而支持模拟数据压缩。 此外,该核心函数的安全级别 MT-safe。 3)目的 该核心函数提供了对包中字段赋值的机制。该函数只能对格式化包的字段赋值,否则将出 错。对于格式化包,只需指定字段的值,而字段的类型和大小可从包格式中自动获取。 4)错误 Program Abort:分段错误(由无效包指针或 fd_name 参数引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未知包。 Recoverable Error:包中无此字段。 5)相关函数 采用该核心函数的衍生函数来给包的 information 或 structure 字段赋值。 采用 op_pk_fd_set()根据数字索引为字段赋值。 采用 op_pk_nfd_get()获取包中某字段的值。 采用 op_pk_nfd_strip()删除某字段,并相应减小包的总大小。

8. op_pk_nfd_get (pkptr, fd_name, value_ptr) 此核心函数的作用是获取给定包中某字段值,将字段类型状态改为“unset” ,根据名称来 确定字段,其参数说明如表 2-33 所示。 表 2-32 参 数 pkptr fd_name value_ptr 类 型 Packet* const char* Vartype 指向给定包的指针 字段名 指向存放指定字段地址的指针 op_pk_nfd_get()函数的参数说明 描 述

1)返回值 Compcode — — 确 认 操 作 是 否 成 功 的 代 码 。 如 果 发 生 错 误 , 则 返 回 OPC_COMPCODE_FAILURE。 2)详解 该核心函数参数支持五种字段类型:int、double、packet、information 和 structure。对于 简单的字段类型,如 int 和 double,直接将它们的值赋给参数,并不受该函数影响。 对于 packet 和 structure 字段类型,同样将它们的值赋给参数。然而,当访问这些值时,就 将其从包中删除,其状态更改为“unset” ,且不可通过函数 op_pk_nfd_get()来进行访问,同时包 的总大小也随之减小。这种机制更严格了对被封装字段内容的所有权控制。 访问未定义的的 information 字段是非法的,为了避免产生错误,应将字符串“unspecified” 复制到被传递值的指针中。 此外,该核心函数的安全级别 MT-safe。 3)目的 该核心函数提供了获取包字段值的机制,常用于将包作为用于进程间通信的数据容器。通 常在包到达处理器或队列输入流时调用该函数,且必须对该包进行处理、存储并需要一个应答 信息。 4)错误 Program Abort:分段错误(由无效包指针或 fd_name 参数引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未知包。 5)相关函数 采用 op_pk_fd_set()为包字段赋值。 采用 op_pk_nfd_get_db1()通过数字索引获取包中 double 类型字段值。 采用 op_pk_nfd_get_int32()通过数字索引获取包中 32 位整型字段值。 采用 op_pk_nfd_get_int64()通过数字索引获取包中 64 位整型字段值。 采用 op_pk_nfd_get_objid()通过数字索引获取包中对象 ID 字段值。 采用 op_pk_nfd_get_pkid()通过数字索引获取包中包 ID 字段值。 采用 op_pk_nfd_get_pkt()通过数字索引获取包中包字段值。 采用 op_pk_nfd_get_ptr()通过数字索引获取包中指针字段值。 采用 op_pk_fd_get()通过数字索引获取格式化包或非格式化包中某字段值。 采用 op_pk_nfd_type()确定包字段的类型。 采用 op_pk_nfd_size()确定包字段的大小。

采用 op_pk_nfd_is_set()确定包字段是否已设置。

9. op_pk_creation_time_get (pkptr) 此核心函数的作用是获取包创建时的仿真时间,其参数说明如表 2-34 所示。 表 2-34 参 数 pkptr 1)返回值 double——给定包创建时的仿真时间。 2)详解 新包通常通过以下三种方法进入循环: ? ? ? 由函数 op_pk_create()或 op_pk_create_fmt()显式创建; 通过函数 op_pk_copy()复制已存在的包; 通过核心函数自动复制在总线或无线链路上向多个目的地传输的包。 类 型 Packet* 指向相关包的指针 op_pk_creation_time_get()函数的参数说明 描 述

通过上述前两种方法创建的包将被赋予新的创建模块 ID 和创建时间。若外部进程的上下 文调用第二种方法,此时的创建模块 ID 将设为常量 OPC_OBJID_INVALID。通过第三种方法 复制的包将被赋予最初传送的包的创建信息。 对包的许多操作大多都不会影响包的创建信息。正如前面提到的,在总线和无线链路上传 输将创建多个包的复本,但但复本都将保留初始的创建信息。通过函数 op_pk_copy()生成的复 本包将产生新的创建信息。 此外,该核心函数可用于格式化包和非格式化包,其安全级别 MT-safe。 3)目的 该核心函数提供了确定包创建时的仿真时间的机制,主要用于计算端到端传输和处理延 时。与函数 op_pk_creation_mod_get()结合,op_pk_create_time_get()函数可用于比较不同源位置 的端到端延时。 4)错误 Program Abort:分段错误(由无效包指针或 fd_name 参数引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未知包。 5)相关函数 采用 op_pk_creation_mod_get()获取包创建处的模块 ID。 采用 op_pk_stamp()标记包的当前模块和仿真时间。

采用 op_pk_stamp_mod_get()和 op_pk_stamp_time_get()通过包戳获取模块 ID 和仿真时间。

10. op_pk_total_size_get (pkptr) 此核心函数的作用是获取包的总大小,其参数说明如表 2-35 所示。 表 2-35 参 数 pkptr 1)返回值 OpT_Packet_Size——给定包的总大小(bit 位数) 。 2)详解 包的总大小为数据和各个附加字段大小的总和。修改数据大小、设置/复位包字段、修改包 字段大小都可影响包总的大小。 此外,该核心函数可用于格式化包和非格式化包,其安全级别 MT-safe。 3)目的 该核心函数提供了一种确定包总的大小的机制,主要用于统计量收集、资源分配、根据大 小对包进行分类。 4)错误 Program Abort:分段错误(由无效包指针或 fd_name 参数引起) 。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向未知包。 5)相关函数 采用 op_pk_total_size_set()分配包的总大小。 采用 op_pk_bulk_size_set()设置包的 bulk 数据大小。 采用 op_pk_bulk_size_get()获取包的 bulk 数据大小。 采用 op_pk_fd_size()修改非格式包中的字段大小。 采用 op_pk_fd_strip()或 op_pk_nfd_strip()删除某字段从而减小包总的大小。 类 型 Packet* 指向相关包的指针 op_pk_total_size_get()函数的参数说明 描 述

2.11 子队列函数集 Subq(Subqueue)函数集是与队列模块中与单一的队列资源处理相关的核心函数的集合。

1. op_subq_pk_insert (subq_index, pkptr, pos_index) 此核心函数的作用是将包插入到给定子队列的指定位置,其参数说明如表 2-36 所示。

表 2-36 参 数 subq_index pkptr pos_index 1)返回值 类 型 int Packet* int

op_subq_pk_insert()函数的参数说明 描 述

给定子队列的索引(子队列索引从 0 开始,依次加 1 递增,无上限) 指向给定包的指针 子队列中包应插入的位置索引

int——表明插入是否成功的插入代码。 该返回代码值包括以下符号常量: OPC_QINS_OK、 OPC_QINS_FAIL、OPC_QINS_PK_ERROR、OPC_QINS_SEL_ERROR。 2)详解 如果位置索引小于零或不是系统支持的符号常量(OPC_QPOS_PRID、OPC_QPOS_HEAD 或 OPC_QPOS_TAIL) ,那么该函数将把包插入到子队列的队列头。同样,如果位置索引大于等 于子队列中包的总数,那么该函数将把包插入到子队列的队列尾。 又若位置索引为 OPC_QPOS_PRID,函数将根据包的优先级对其进行插入。优先级越高的 包越靠近队列头,没有指定优先级(OPC_PRiO_NOT_SET)的包将被插入到最后。如果子队列 中存在一个或多个具有相同优先级的包,则新包将立即被插入到它们后面。 注意: 当采用 OPC_QPOS_PRID 插入包时,必须首先使用函数 op_subq_sort()对子队列进行 优先级排序。 子队列初始化为空,可通过函数 op_subq_pk_insert()将包插入到子队列中,通过函数 op_subq_pk_remove()、op_subq_flush()或 op_q_flush()将包从子队列中移除。由于子队列容量有 限,插入包操作可能失败,帮此时进程将对包进行灵活处理(如销毁、回送到源等) ,包状态不 会受到影响。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数提供了惟一一种将包插入到子队列中的方法。位置索引参数可以灵活地确定给 定包插入的位置,既可以是具体的数值,也可以是包的优先级。 4)错误 Program Abort:核心函数需要队列上下文。 Program Abort:包指针为空。 Program Abort:包指针指向已销毁包。 Program Abort:包指针指向静态包。 Program Abort:分段错误(由畸形包引起) 。 Recoverable Error:子队列选择标记不可识别(此时返回 OPC_QINS_SEL_ERROR) 。 Recoverable Error:包已插入到子队列中(引时返回 OPC_QINS_PK_ERROR) 。

注意:如果由于队列或子队列的容量不够而引起的包插入失败,将返回常量 OPC_QINS_FAIL,但这不属于错误。 5)相关函数 采用 op_subq_pk_access()获取包在子队列中的指针,但关不将包从子队列中移除。 采用 op_subq_pk_remove()将包从子队列中移除,并获取其指针。 采用 op_subq_pk_swap()交换两个包在子队列中的位置。 采用 op_subq_flush()移除子队列中所有的包。

2. op_subq_pk_remove (subq_index, subq_index) 此核心函数的作用是获取包在子队列中的位置指针,并将其从子队列中移除,其参数说明 如表 2-37 所示。 表 2-37 参 数 subq_index subq_index 1)返回值 Packet*——从给定子队列中移除的包的指针,如果发生可恢复错误,则返回 OPC_NIL。 2)详解 只能在队列模块中运行的进程上下文中调用该核心函数(或由队列进程调用的函数调用) , 如果处理器或管道阶段运行的进程调用该函数,那么将发行错误。 如果位置索引为负值,或大于等于队列中包的数目,那么将产生可恢复错误并返回常量 OPC_NIL。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 提供了惟一一种将包非破坏性地从子队列中移除的机制。 通过其他函数, op_subq_flush() 如 和 op_q_flush()也可将包从子队列中移除。位置索引参数可灵活地确定哪个包将被移除,它可以 是一个具体的数值, 也可以由包的优先级确定,此进高优先级的包无论在哪个位置都将被移除。 4)错误 Program Abort:核心函数需要上下文。 Recoverable Error:子队列选择标记不可识别。 Recoverable Error:位置索引超出子队列范围。 5)相关函数 类 型 int int 相关子队列的索引 子队列中需移除的包所在位置的索引(队列头的位置索引为 0,依 次加 1 递增,直到队列尾) op_subq_pk_remove()函数的参数说明 描 述

采用 op_subq_pk_access()获取包在子队列中的指针,但关不将包从子队列中移除。 采用 op_subq_pk_insert()将包插入到子队列中。 采用 op_subq_pk_swap()交换两个包在子队列中的位置。 采用 op_subq_flush()移除子队列中所有的包。

2.12 统计量函数集 Stat(Statistic)函数集中所包含的核心函数将用户自定义的自动计算的统计量写入仿真中 创建的数据文件。输出文件共有两类:矢量输出文件和标量输出文件。 1. op_stat_reg (group_dot_stat_name, stat_index, type ) 此核心函数的作用是返回进程模型中节点或模块统计量(局部或全局)的句柄,其参数说 明如表 2-38 所示。 表 2-38 参 数 类 型 op_stat_reg()函数的参数说明 描 述

group_dot_stat_name const char* stat_index int

统计量的所在组和名称,用“. ”隔开 统计量的数字索引,若为一维统计量, 则为 OPC_STAT_INDEX_NONE OPC_STAT_GLOBAL(全局统计量)

type 1)返回值

int OPC_STAT_LOCAL(局部统计量)

Stathandle——统计量句柄,可在函数 op_stat_write()和 op_stat_write_t()调用时使用。 2)详解 该函数与 op_stat_obj_reg()类似,但本函数只能用在进程模块上下文中,且既可注册局部 统计量,又可注册全书统计量。 仿真内核集中管理全书统计量和局部统计量, 为每个统计量都保存了所属组、 名称、 索引、 类型和输出矢量。当使用函数 op_stat _reg()注册统计量时,可为其指定前面四项。如果能做到 名称同步,则可允许多个进程访问相同的统计量。所有进程都可集结同一全局统计量,而同一 模块的进程才可集结同一局部统计量。 多维统计量提供了一个输出统计量库,Stathandle 根据索引指向库中的元素。一维统计量 全用符号常量 OPC_STAT_INDEX_NONE 作为索引值。 使用全书统计量时, 模型中的所有进程共享一个输出矢量, 并记录它们测量的端到端延时。 而使用局部统计量时,每个进程只记录自己的输出矢量。 注册统计量时将会在现有统计量中搜索名称和所属组。为提高效率,一个统计量只能注册 一次,然后缓存统计量句柄以便使用。

此外,该核心函数的安全级别为 Forced serialization。 3)目的 统计量注册提供了一种多个进程共享输出矢量的机制。进程只需要调整统计量名称就可通 过注册来访问统计量,这可以比较容易地避免独立模型间的冲突。函数 op_stat_write()和 op_stat_write_t()可以根据该函数返回的统计量句柄,并将值写到统计量中。 4)错误 Program Abort:分段错误(由无效或畸形 stat_name 参数引起) 。 Recoverable Error:无法注册统计量(由未声明统计量引起) 。 Recoverable Error:因内存限制而无法注册统计量。 Program Abort:核心函数需要进程上下文。 Recoverable Error:统计量索引溢出。 5)相关函数 采用 op_stat_obj_reg()访问任意链路、路径、模块或子模块对象统计量。 采用 op_stat_write()将值写到输出统计量中,并标记当前仿真时间。 采用 op_stat_write_t()将值写到输出统计量中,并标记指定的仿真时间。 采用 op_stat_scalar_write() 将值写到与其他仿真中记录的标量合并的标题统计量中。

2. op_stat_write (stat_handle, value) 此核心函数的作用是将(时间,值)对写到指定统计量中,将写入的值通过参数传递给该 函数,时间为当前仿真时间,其参数说明如表 2-39 所示。 表 2-39 op_stat_write()函数的参数说明 参 数 stat_handle value 1)返回值 void——无返回值。 2)详解 该核心函数为给定统计量的输出矢量附加一个新的(时间,值)对。统计量只能是采用函 数 op_stat_reg()注册的统计量。句柄使用不当将导致可恢复仿真错误。 仿真模型中的不同进程如果使用相同的统计量句柄,那么就可通过该函数将值写到同一个 输出矢量中。 在同一仿真时间对函数 op_stat_write()的多次调用将按序记录,而不是互相覆盖。 为了在输出矢量文件中产生数据,统计量必须使用探针编辑器中定义的探针对象探测,或 类 型 Stathandle double 指定统计量的统计量句柄 指定统计量将写入的值 描 述

在项目编辑器中通过选择统计量操作将其选中。探针文件的名称由仿真的探针属性确定。需要 设置仿真的 record_gstats 属性来记录所有的全书统计量。 如果捕获模式是“divides by time” ,且在特定时间段内统计量有效,则必须采用函数 op_stat_write()在时间段结束时向统计量写入零值,以报告系统该时间段已结束。 此外,该核心函数的安全级别为 Forced serialization。 3)目的 该核心函数将值写入输出矢量中,并标记当前仿真时间。 如果 Stathandle 指向一个与统计线相连的局部统计量,且该统计线处于解状态,那么将为 统计线的目的模块预设一个中断。 4)错误 Program Abort:分段错误(由无效统计量句柄引起) 。 Recoverable Error:使用未注册的统计量句柄。 5)相关函数 采用 op_stat_local_read()读取输入统计量的当前值。 采用 op_stat_write_t()将值写到输出统计量中,并标记指定的仿真时间。 采用 op_stat_scalar_write() 将值写到与其他仿真中记录的标量合并的标题统计量中。 采用 op_stat_obj_reg()访问任意链路、路径、模块或子模块对象统计量。 采用 op_stat_reg()获取统计量句柄。
  • 0
    点赞
  • 0
    评论
  • 5
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值