EPICS简单实例2 -- subroutine记录(sub)介绍与使用
这个subroutine记录用于调用一个C初始化程序和一个重复出现的扫描程序。没有设备支持对应这个记录。
参数字段
在以下描述记录专用字段,按功能分组。
扫描参数
subroutine记录有用于指定这个记录在什么情况下将被运行的标准字段。
读取字段
subroutine记录有12格输入记录(INPA-INPL),每个输入链接有一个对应的值字段(A-L)。这些字段用于此记录调用获取和存储能够被传递给这个subroutine的值。
输入链接可以时通道访问或数据库链接或常数。当常数时,用这个常数值初始化对应这个链接的相应值字段,并且在运行时通过dbPuts可以更改这个字段的值。否则,当运行这个记录时从输入链接为(A-F)获取值。
subroutine连接
这些字段用于连接到C子程序。在SNAM字段中应该输入这个子程序的名称。
操作显示参数
这些参数用于向操作显示有意思数据。它们以文本地或图形地显示这个subroutine的值或其它参数。EGU是最长16个字符的字符串,它描述这个subroutine记录使用的任何单位。通过get_units记录支持程序获取它。
HOPR和LOPR字段是用于VAL, A-L, LA-LL, HIHI, LOLO, LOW和HIGH字段的上下显示限制。get_graphic_double和get_control_double记录支持程序都获取这些字段。
PREC字段决定了用什么浮点精度显示VAL。当调用get_precision记录支持时,使用它。
警报参数
对于subroutine记录的可能警报情况是SCAN,READ,limit警报以及如果subroutine返回一个负值能被触发的警报。SCAN和READ警报是被记录或设备支持程序调用。限制的警报是由用户使用数值在HIHI,LOLO,HIGH和LOW字段中配置的。它们应用于VAL字段。对于这些字段中每一个字段,有一个相应的严重性字段,其可以是NO_ALARM, MINOR或MAJOR。
BRSV字段是在这个routine返回一个负值时用户能够设置警报严重性的地方。
警报的字段类列出了与所有记录类型都共有的警报关联。
用于监视的参数
这些参数用于决定何时发出放置于VAL字段上的监视。当VAL不同于在ALST和MLST运行时字段中的值时,调用合适的监视,即是:当VAL的值变化超过了在这些字段中指定的死区时。ADEL和MEDL字段指定在调用值变化监视前这个变化必须超过的最小差值。如果这些字段有一个0值,每次值变化,将触发一个监视;如果它们有一个-1值,每次记录运行,触发监视。ADEL字段被存档监视使用,MDEL字段用于所有其它类型的监视。
运行时参数
这些参数被运行时代码使用,用于运行这个subroutine记录。不能使用数据库配置工具配置它们。它们代表这个记录的当前状态。它们中很多被记录processing程序或监视使用。
VAL字段应该被subroutine设置。SADR保存这个subroutine地址并且由这个记录processing程序设置。
余下字段LALM,ALST,MLST和LA-LL用于实现监视。例如,当LA不等于A,调用对应那个字段的值变化监视。
记录支持
记录支持程序
1) init_record
long (*init_record)(struct dbCommon *precord, int pass)
对于每个常数输入链接,用这个常数值初始化相应的值字段。对于为类型PV_LINK的每个输入链接,创建一个通道访问。如果定义了一个初始化subroutine,找到并且调用它。进行处理的subroutine被找到并且其地址存储在SADR中。
2) process
long (*init_record)(struct dbCommon *precord, int pass)
见以下"记录运行""
3) get_units
long (*get_units)(struct dbAddr *paddr, char *units)
4) get_precsion
long (*get_precision)(const struct dbAddr *paddr, long *precision)
当VAL时被引用的字段时,获取PREC。否则,调用recGblGetPrec()。
5) get_graphic_double
long (*get_graphic_double)(struct dbAddr *paddr, struct dbr_grDouble *p)
为一个字段设置上显示和下显示限制。如果字段是VAL,A-L,LA-LL,HIHI,HIGH,LOW或LOLO,这些限制被设置成HOPR和LOPR,另外如果字段有定义的上和下限制,将使用它们,否则将使用对应这个字段类型的上和下最大值。
6) get_control_double
为一个字段设置上显示和下控制限制。如果字段是VAL,A-L,LA-LL,HIHI,HIGH,LOW或LOLO,这些限制被设置成HOPR和LOPR,另外如果字段有定义的上和下限制,将使用它们,否则将使用对应这个字段类型的上和下最大值。
long (*get_control_double)(struct dbAddr *paddr, struct dbr_ctrlDouble *p)
7) get_alarm_double
long (*get_alarm_double)(struct dbAddr *paddr, struct dbr_alDouble *p)
设置以下值:
upper_alarm_limit = HIHI
upper_warning_limit = HIGH
lower_warning_limit = LOW
lower_alarm_limit = LOLO
记录运行
程序Process实现以下算法:
1) 如果PACT为FALSE,则获取所有参数。
2) 调用这个subroutine并且检查返回值。
- 调用subroutine
- 设置PACT为TRUE
- 如果返回值是1,返回
3) 检查警报。这个routine检查新的VAL是否引起警报状态和严重性变化。如果发生了,设置NSEV,NSTA和LALM。它也遵守警报回滞因子(HYST)。因而,在警报状态和验证性被降低前,这个值必须变化超过HYST。
4) 检查是否应该调用监视
- 如果警报状态或严重性发生变化,调用警报监视
- 如果ADEL和MDEL条件满足了,调用存档和值变化监视
- 如果A-L的值变化了,调用对应A-L的监视
- 重置NSEV和NSTA回0
5) 如果需要,扫描forward链接。设置PACT为FALSE并且返回。
示例同步subroutine
这是一个在每次调用process时仅对VAL加1的示例subroutine。
在blctrl用户家目录中的exer目录下创建一个子目录exer2,并且使用makeBaseApp.pl产生一个应用程序目录和一个IOC启动目录:
[blctrl@main-machine ~]$ mkdir exer/exer2
[blctrl@main-machine ~]$ cd exer/exer2
[blctrl@main-machine exer2]$ /usr/local/EPICS/base/bin/linux-x86_64/makeBaseApp.pl -t ioc exer2
[blctrl@main-machine exer2]$ /usr/local/EPICS/base/bin/linux-x86_64/makeBaseApp.pl -i -t ioc exer2
Using target architecture linux-x86_64 (only one available)
The following applications are available:exer2
What application should the IOC(s) boot?
The default uses the IOC's name, even if not listed above.
Application name?
[blctrl@main-machine exer2]$ ls
configure exer2App iocBoot Makefile
进入exer2App/src路径下,编写两个文件 subRecordExample.c和subRecordExample.dbd,其内容如下:
subRecordExample.c:
#include <stdio.h>
#include <dbDefs.h>
#include <registryFunction.h>
#include <subRecord.h>
#include <epicsExport.h>int mySubDebug = 0;static long mySubInit(struct subRecord *precord)
{if (mySubDebug){printf("Record %s called mySubInit(%p)\n", precord->name, (void *)precord);}printf("subInit was called\n");return 0;
}static long mySubProcess(struct subRecord * precord)
{if(mySubDebug){printf("Record %s called mySubProcess(%p)\n", precord->name,(void *)precord);}precord->val++;return 0;
}epicsExportAddress(int, mySubDebug);
epicsRegisterFunction(mySubInit);
epicsRegisterFunction(mySubProcess);
subRecordExample.dbd:
variable(mySubDebug)
function(mySubInit)
function(mySubProcess)
为在与以上两个文件相同路径下的Makefile文件添加以下两行:
TOP=../..include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================#=============================
# Build the IOC applicationPROD_IOC = exer2
# exer2.dbd will be created and installed
DBD += exer2.dbd# exer2.dbd will be made up from these files:
exer2_DBD += base.dbd# Include dbd files from all support applications:
#exer2_DBD += xxx.dbd
exer2_DBD += subRecordExample.dbd # 添加行1exer2_SRCS += subRecordExample.c # 添加行2# Add all the support libraries needed by this IOC
#exer2_LIBS += xxx# exer2_registerRecordDeviceDriver.cpp derives from exer2.dbd
exer2_SRCS += exer2_registerRecordDeviceDriver.cpp# Build the main IOC entry point on workstation OSs.
exer2_SRCS_DEFAULT += exer2Main.cpp
exer2_SRCS_vxWorks += -nil-# Add support from base/src/vxWorks if needed
#exer2_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary# Finally link to the EPICS Base libraries
exer2_LIBS += $(EPICS_BASE_IOC_LIBS)#===========================include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
进入到路径exer2/exer2App/Db路径下,添加以下一个文件dbSubExample.db,内容如下:
record(sub,"$(user):subExample")
{field(INAM,"mySubInit")field(SNAM,"mySubProcess")
}
并且在与上面文件相同路径下的Makefile中添加如下一行:
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE#----------------------------------------------------
# Create and install (or just install) into <top>/db
# databases, templates, substitutions like this
#DB += xxx.db
DB += dbSubExample.db # 添加这一行
#----------------------------------------------------
# If <anyname>.db template is not named <anyname>*.template add
# <anyname>_template = <templatename>include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
然后切换到这个程序的顶层路径,执行make:
[blctrl@telecom exer2]$ make
make -C ./configure install
make[1]: Entering directory `/home/blctrl/exer/exer2/configure'
perl -CSD /usr/local/EPICS/base/bin/linux-x86_64/makeMakefile.pl O.linux-x86_64 ../..
...
make[2]: Leaving directory `/home/blctrl/exer/exer2/iocBoot/iocexer2'
make[1]: Leaving directory `/home/blctrl/exer/exer2/iocBoot'
接着切换到iocBoot/iocexer2路径下,编辑st.cmd文件:
#!../../bin/linux-x86_64/exer2#- You may have to change exer2 to something else
#- everywhere it appears in this file< envPathscd "${TOP}"## Register all support components
dbLoadDatabase "dbd/exer2.dbd"
exer2_registerRecordDeviceDriver pdbbase## Load record instances
#dbLoadRecords("db/xxx.db","user=blctrl")
dbLoadRecords("db/dbSubExample.db","user=TEST") # 添加这一行,加载记录cd "${TOP}/iocBoot/${IOC}"
iocInit
用以下命令启动这个IOC程序:
[blctrl@telecom iocexer2]$ ../../bin/linux-x86_64/exer2 st.cmd
#!../../bin/linux-x86_64/exer2
< envPaths
epicsEnvSet("IOC","iocexer2")
epicsEnvSet("TOP","/home/blctrl/exer/exer2")
epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
cd "/home/blctrl/exer/exer2"
## Register all support components
dbLoadDatabase "dbd/exer2.dbd"
exer2_registerRecordDeviceDriver pdbbase
## Load record instances
#dbLoadRecords("db/xxx.db","user=blctrl")
dbLoadRecords("db/dbSubExample.db","user=TEST")
cd "/home/blctrl/exer/exer2/iocBoot/iocexer2"
iocInit
Starting iocInit
############################################################################
## EPICS R7.0.3.1
## EPICS Base built Aug 28 2022
############################################################################
subInit was called
iocRun: All initialization complete
## Start any sequence programs
#seq sncxxx,"user=blctrl"
epics>
测试这个IOC下是否加载了指定的记录:
epics> dbl
TEST:subExample
再开一个命令行终端,测试这个加载的记录:
[root@telecom ~]# caget TEST:subExample
TEST:subExample 0
[root@telecom ~]# cainfo TEST:subExample
TEST:subExampleState: connectedHost: localhost:5064Access: read, writeNative data type: DBF_DOUBLERequest type: DBR_DOUBLEElement count: 1
[root@telecom ~]# caput TEST:subExample.PROC 1
Old : TEST:subExample.PROC 0
New : TEST:subExample.PROC 1
[root@telecom ~]# caget TEST:subExample
TEST:subExample 1
EPICS简单实例2 -- subroutine记录(sub)介绍与使用相关推荐
- mysql 实例复制_MYSQL教程MySQL 复制详解及简单实例
<MysqL教程MysqL 复制详解及简单实例>要点: 本文介绍了MysqL教程MysqL 复制详解及简单实例,希望对您有用.如果有疑问,可以联系我们. MysqL 复制详解及简单实例 主 ...
- (三)AJAX基本介绍和简单实例03
(三)AJAX基本介绍和简单实例03-----Ajax与数据库的动态应用 前台显示界面: 选择所有客户之后: 选择其中一个客户---杜森: Demo03.html代码 <html> < ...
- Log4j2日志记录框架的使用教程与简单实例
1.Log4j2的使用教程 1.1 简介 Log4j的1.x版本虽然已经被广泛使用于很多应用程序中,但由于出现内存泄漏等bug,代码难以维护,以及需要使用老版本的jdk等劣势,在2015年8月已经玩完 ...
- ActiveMQ简单介绍+简单实例
本文出自:http://www.open-open.com/lib/view/open1388994166156.html 1. JMS基本概念 JMS(Java Message Servi ...
- Hibernate搭建开发环境+简单实例(二)
2019独角兽企业重金招聘Python工程师标准>>> Hibernate是非常典型的持久层框架,持久化的思想是非常值得我们学习和研究的.这篇博文,我们主要以实例的形式学习Hiber ...
- 程序设计-在校整理-06 最常公共子序列与子串+2048小游戏+KNN简单实例
[在校整理-06 最常公共子序列与子串+2048小游戏+KNN简单实例](注:仅供参考学习使用) 一.课题内容和要求 1.问题描述 1.1最长公共子序列与子串 1.2 2048小游戏 1.3 K-NN ...
- pytorch生成对抗网络GAN的基础教学简单实例(附代码数据集)
1.简介 这篇文章主要是介绍了使用pytorch框架构建生成对抗网络GAN来生成虚假图像的原理与简单实例代码.数据集使用的是开源人脸图像数据集img_align_celeba,共1.34G.生成器与判 ...
- Antlr4入门(安装、配置、简单实例)
Antlr4入门(安装.配置.简单实例) 2020.5.28 仅本人初次使用Antlr4的经历分享 目前所知有3种使用Antlr4的方式: 通过命令行使用: 在Eclipse中安装Antlr4插件:( ...
- WPF MvvmLight简单实例(1) 页面导航
原文:WPF MvvmLight简单实例(1) 页面导航 实现了那些功能,先看看截图: 操作描述: 在程序运行后,点击"Load"按钮,页面会加载PageOne,点击PageOne ...
最新文章
- sql server 2008建域时提示admin密码不符合要求解决方法
- Stuts的Web.xml 详解
- oracle数据库exp命令导入导出dmp文件演示,oracle数据库备份还原功能
- 2.数据中心网络演进
- python交互式shell_交互式 shell 玩转 Python
- 【VB.NET】VB.NET字符串数组排序
- mysql 集中join的区别
- java常用方法名_Java语言常见名称有哪些
- CentOS下安装JDK6u30
- CSDN VIP 常见问题解答
- 《JavaScript权威指南第7版》第4章 表达式和运算符
- matlabRC电路实验仿真
- office文档管理服务器编辑,office在线编辑方案
- ActiveMQ笔记(一)
- Git使用小技巧【git reset和git revert, 你真的知道怎么用吗, 详细图解】
- 洛谷 P1192 台阶问题
- IO模型(阻塞,非阻塞,多路复用......)
- 如何消除USB共享网络导致的Windows系统中自动增加的网络设备序列号?
- buuctf [WUSTCTF2020]dp_leaking_1s_very_d@angerous
- Python之xlrd读Excel文件问题解决 (python xlrd unsupported format, or corrupt file.)
热门文章
- web端微信二维码自定义样式
- python自动化测试面试题None is ==详解
- js赋值改变后,原数据也发生改变
- 雷神领域(并查集真是个好东西)并查集+流氓dp
- 微信小程序+SpringBoot+mybatis+MySQL实现简单的登录
- Windows平台精选软件工具列表-Windows绝赞应用
- 女生从猫猫身上学到的.........||精品||
- 模拟计算 |“五重解读”带你玩转CO2RR描述符-科学指南针
- 大数据必学Java基础(三十一):IDEA模板的使用
- 撸猫游戏千千万,他们凭什么被推荐?