本文将介绍如何开发一个基于stream的EPICS IOC应用程序,其将作为一个简单的基于消息的设备(用于EPICS stream练习的设备模拟程序_yuyuyuliang00的博客-CSDN博客中最后一个python程序模拟的设备)的IOC控制程序。

1) 按如下步骤建立这个IOC程序的框架:

[blctrl@main-machine exer]$ mkdir simpleintrument
[blctrl@main-machine exer]$ cd simpleintrument/
[blctrl@main-machine simpleintrument]$ makeBaseApp.pl -t ioc streaminstrument
[blctrl@main-machine simpleintrument]$ makeBaseApp.pl -i -t ioc streaminstrument
Using target architecture linux-x86_64 (only one available)
The following applications are available:streaminstrument
What application should the IOC(s) boot?
The default uses the IOC's name, even if not listed above.
Application name?
[blctrl@main-machine simpleintrument]$ ls
configure  iocBoot  Makefile  streaminstrumentApp

2)编辑configure中RELEASE文件,添加这个IOC程序所需要支持模块的路径:

SUPPORT=/usr/local/EPICS/synApps/support
ASYN=$(SUPPORT)/asyn
STREAM=$(SUPPORT)/stream

3) 编辑simpleintrument/streaminstrumentApp/src/Makefile文件,添加这个IOC程序所需模块以及库文件:

TOP=../..include $(TOP)/configure/CONFIG
#----------------------------------------
#  ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================#=============================
# Build the IOC applicationPROD_IOC = streaminstrument
# streaminstrument.dbd will be created and installed
DBD += streaminstrument.dbd# streaminstrument.dbd will be made up from these files:
streaminstrument_DBD += base.dbd
streaminstrument_DBD += asyn.dbd
streaminstrument_DBD += drvAsynIPPort.dbd
streaminstrument_DBD += stream.dbd# Include dbd files from all support applications:
#streaminstrument_DBD += xxx.dbd# Add all the support libraries needed by this IOC
streaminstrument_LIBS += asyn
streaminstrument_LIBS += stream# streaminstrument_registerRecordDeviceDriver.cpp derives from streaminstrument.dbd
streaminstrument_SRCS += streaminstrument_registerRecordDeviceDriver.cpp# Build the main IOC entry point on workstation OSs.
streaminstrument_SRCS_DEFAULT += streaminstrumentMain.cpp
streaminstrument_SRCS_vxWorks += -nil-# Add support from base/src/vxWorks if needed
#streaminstrument_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary# Finally link to the EPICS Base libraries
streaminstrument_LIBS += $(EPICS_BASE_IOC_LIBS)#===========================include $(TOP)/configure/RULES
#----------------------------------------
#  ADD RULES AFTER THIS LINE

4)退到这个IOC程序的顶层目录,执行make命令:

[blctrl@main-machine simpleintrument]$ make
make -C ./configure install
...
make[2]: Leaving directory '/home/blctrl/exer/simpleintrument/iocBoot/iocstreaminstrument'
make[1]: Leaving directory '/home/blctrl/exer/simpleintrument/iocBoot'
[blctrl@main-machine simpleintrument]$ ls
bin  configure  dbd  iocBoot  lib  Makefile  streaminstrumentApp

5)编辑一个协议文件,记录需要使用此协议文件,与设备进行交互:

[blctrl@main-machine Db]$ cat si.proto
Terminator = CR LF;
InTerminator = CR LF;
ReplayTimeout = 10000;
ReadTimeout = 10000;# get Volts from the instrument to record
getVolt
{out "VOLTS?";in "VOLTS %f";
}# set Volts from record to instrument
setVolt
{out "VOLTS %f";@init{getVolt;}
}# get current from the instrument
getCurr
{out "CURR?";in "CURR %f";
}# instrumnet information
getIDN
{out "*IDN?";in "*IDN %#s";
}getOnOff
{out "ON?";in "ON %d";
}setOnOff
{out "ON %d";@init{getOnOff;}
}setForReadLoad
{out "LOAD?";
}read_L1
{PollPeriod = 100;in "LOAD %f %*f %*f";
}read_L2
{PollPeriod = 100;in "LOAD %*f %f %*f";
}read_L3
{PollPeriod = 100;in "LOAD %*f %*f %f";
}

6) 用VisualDCT编辑记录,并且生成运行所需的文本数据库。

导出以上记录数据库的文本:

[blctrl@main-machine Db]$ cat si.db
#! Generated by VisualDCT v2.8.3# Get the voltage of the instrument
record(ai, "$(INSTRUMENT):VOLTAGE_RBV") {field(DESC, "Read Voltage")field(SCAN, "Passive")field(DTYP, "stream")field(INP, "@si.proto getVolt $(PORT)")field(PREC, "2")field(LINR, "NO CONVERSION")field(EGU, "V")
}# Set Voltage for the instrument
record(ao, "$(INSTRUMENT):VOLTAGE") {field(DESC, "Set Voltage")field(SCAN, "Passive")field(PINI, "YES")field(DTYP, "stream")field(FLNK, "$(INSTRUMENT):VOLTAGE_RBV")field(OUT, "@si.proto setVolt $(PORT)")field(PREC, "2")field(LINR, "NO CONVERSION")field(EGU, "V")field(DRVH, "10")field(DRVL, "-10")
}# Get Current
record(ai, "$(INSTRUMENT):CURRENT_RBV") {field(DESC, "Get Current")field(SCAN, "Passive")field(PINI, "YES")field(DTYP, "stream")field(INP, "@si.proto getCurr $(PORT)")field(PREC, "2")field(LINR, "NO CONVERSION")field(EGU, "Amp")
}# Set the ON/OFF state
record(bo, "$(INSTRUMENT):ONOFF") {field(DESC, "Control curr output")field(SCAN, "Passive")field(PINI, "YES")field(DTYP, "stream")field(FLNK, "$(INSTRUMENT):ONOFF_RBV")field(OUT, "@si.proto setOnOff $(PORT)")field(ZNAM, "OFF")field(ONAM, "ON")field(ZSV, "NO_ALARM")field(OSV, "MINOR")
}# Get the on/off state of the instrument
record(bi, "$(INSTRUMENT):ONOFF_RBV") {field(DESC, "ON or OFF status")field(SCAN, "Passive")field(PINI, "YES")field(DTYP, "stream")field(INP, "@si.proto getOnOff $(PORT)")field(ZSV, "NO_ALARM")field(OSV, "MINOR")field(ZNAM, "OFF")field(ONAM, "ON")
}# Instrument Informantion
record(waveform, "$(INSTRUMENT):INSTRUMENT_INFO") {field(DESC, "Instrument Info")field(SCAN, "Passive")field(PINI, "YES")field(DTYP, "stream")field(INP, "@si.proto getIDN $(PORT)")field(NELM, "30")field(FTVL, "CHAR")
}record(ai, "$(INSTRUMENT):LOAD1") {field(DESC, "Read CPU Load")field(SCAN, "I/O Intr")field(PINI, "NO")field(DTYP, "stream")field(INP, "@si.proto read_L1 $(PORT)")field(PREC, "2")field(LINR, "NO CONVERSION")field(EGU, "%")field(HIHI, "90")field(HIGH, "60")field(HHSV, "MAJOR")field(LLSV, "NO_ALARM")field(HSV, "MINOR")field(LSV, "NO_ALARM")
}record(calc, "$(INSTRUMENT):POWER") {field(DESC, "Calc Power")field(SCAN, "1 second")field(CALC, "A*B")field(INPA, "$(INSTRUMENT):CURRENT_RBV PP")field(INPB, "$(INSTRUMENT):VOLTAGE_RBV")field(EGU, "W")field(PREC, "2")
}# Set For Read Load
record(stringout, "$(INSTRUMENT):SetForLoad") {field(DESC, "Set For Read Load")field(SCAN, "1 second")field(DTYP, "stream")field(FLNK, "$(INSTRUMENT):INSTRUMENT_INFO")field(OUT, "@si.proto setForReadLoad $(PORT)")
}record(ai, "$(INSTRUMENT):LOAD2") {field(DESC, "Read CPU Load")field(SCAN, "I/O Intr")field(PINI, "NO")field(DTYP, "stream")field(INP, "@si.proto read_L2 $(PORT)")field(PREC, "2")field(LINR, "NO CONVERSION")field(EGU, "%")field(HIHI, "90")field(HIGH, "60")field(HHSV, "MAJOR")field(LLSV, "NO_ALARM")field(HSV, "MINOR")field(LSV, "NO_ALARM")
}record(ai, "$(INSTRUMENT):LOAD3") {field(DESC, "Read CPU Load")field(SCAN, "I/O Intr")field(PINI, "NO")field(DTYP, "stream")field(INP, "@si.proto read_L3 $(PORT)")field(PREC, "2")field(LINR, "NO CONVERSION")field(EGU, "%")field(HIHI, "90")field(HIGH, "60")field(HHSV, "MAJOR")field(LLSV, "NO_ALARM")field(HSV, "MINOR")field(LSV, "NO_ALARM")
}

7) 将在第5步编写的协议文件si.proto和在第6步编写的记录数据库文件si.db放入以下目录streaminstrumentApp/Db,并且编写这个路径下的Makefile文件,在这个文件中添加以下内容:

DB += si.db
DB += si.proto

然后在这个路径下执行make命令。

8)切换到设备模拟程序所在的目录,执行python程序:

[blctrl@main-machine python_dir]$ ./simple_instrument.py --verbose
Serving on TCP 24742
Terminate with Ctrl-C

这个程序可以接收并且应答以下消息字符串:

  • *IDN?      :获取设备信息
  • ON 0       :关闭设备
  • ON 1       :打开设备
  • VOLTS 5.0    :设置电压,范围为-10~10V。
  • ON?        :返回关闭/开启的状态
  • VOLTS?    :返回当前电压设置
  • CURR?    :返回当前电流
  • LOAD?    :返回CPU负载(1,5,15分钟平均负载)

9) 进入iocBoot/iocstreaminstrument目录下,启动这个IOC应用程序,并用dbl查看当前IOC包含的记录:

[blctrl@main-machine simpleintrument]$ cd iocBoot/iocstreaminstrument/
[blctrl@main-machine iocstreaminstrument]$ ../../bin/linux-x86_64/streaminstrument st.cmd
#!../../bin/linux-x86_64/streaminstrument
< envPaths
epicsEnvSet("IOC","iocstreaminstrument")
epicsEnvSet("TOP","/home/blctrl/exer/simpleintrument")
epicsEnvSet("SUPPORT","/usr/local/EPICS/synApps/support")
epicsEnvSet("ASYN","/usr/local/EPICS/synApps/support/asyn")
epicsEnvSet("STREAM","/usr/local/EPICS/synApps/support/stream")
epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
cd "/home/blctrl/exer/simpleintrument"
## Register all support components
dbLoadDatabase "dbd/streaminstrument.dbd"
streaminstrument_registerRecordDeviceDriver pdbbase
drvAsynIPPortConfigure("PORT","127.0.0.1:24742")
epicsEnvSet("STREAM_PROTOCOL_PATH", "/home/blctrl/exer/simpleintrument/db")
## Load record instances
dbLoadRecords("db/si.db","INSTRUMENT=SIMPLE:INSTRUMENT,PORT=PORT")
cd "/home/blctrl/exer/simpleintrument/iocBoot/iocstreaminstrument"
iocInit
Starting iocInit
############################################################################
## EPICS R7.0.3.1
## EPICS Base built Sep  8 2022
############################################################################
iocRun: All initialization complete
## Start any sequence programs
#seq sncxxx,"user=blctrl"
epics> dbl
SIMPLE:INSTRUMENT:VOLTAGE_RBV
SIMPLE:INSTRUMENT:CURRENT_RBV
SIMPLE:INSTRUMENT:LOAD1
SIMPLE:INSTRUMENT:LOAD2
SIMPLE:INSTRUMENT:LOAD3
SIMPLE:INSTRUMENT:ONOFF
SIMPLE:INSTRUMENT:POWER
SIMPLE:INSTRUMENT:VOLTAGE
SIMPLE:INSTRUMENT:INSTRUMENT_INFO
SIMPLE:INSTRUMENT:ONOFF_RBV
SIMPLE:INSTRUMENT:SetForLoad
epics>

10) 另开一个命令行窗口,进行测试:

[blctrl@main-machine ~]$ caget -S SIMPLE:INSTRUMENT:INSTRUMENT_INFO
SIMPLE:INSTRUMENT:INSTRUMENT_INFO US-PAS Instrument, Yoyodyne I
[blctrl@main-machine ~]$ caput SIMPLE:INSTRUMENT:ONOFF 1
Old : SIMPLE:INSTRUMENT:ONOFF        OFF
New : SIMPLE:INSTRUMENT:ONOFF        ON
[blctrl@main-machine ~]$ caput SIMPLE:INSTRUMENT:VOLTAGE 5
Old : SIMPLE:INSTRUMENT:VOLTAGE      0
New : SIMPLE:INSTRUMENT:VOLTAGE      5
[blctrl@main-machine ~]$ caget SIMPLE:INSTRUMENT:CURRENT_RBV
SIMPLE:INSTRUMENT:CURRENT_RBV  0.86756
[blctrl@main-machine ~]$ caget SIMPLE:INSTRUMENT:POWER
SIMPLE:INSTRUMENT:POWER        28.873
[blctrl@main-machine ~]$ caget SIMPLE:INSTRUMENT:LOAD1
SIMPLE:INSTRUMENT:LOAD1        0.02
[blctrl@main-machine ~]$ caget SIMPLE:INSTRUMENT:LOAD2
SIMPLE:INSTRUMENT:LOAD2        0.08
[blctrl@main-machine ~]$ caget SIMPLE:INSTRUMENT:LOAD3
SIMPLE:INSTRUMENT:LOAD3        0.16

11) 用CSS设计一个图形化用户操作界面:

一个基于stream的EPICS IOC应用程序相关推荐

  1. 一个基于codeigniter的淘宝客程序源码,适合学习参考,京东拼多多淘宝联盟api

    一个基于codeigniter的淘宝客程序源码,直接调用淘宝联盟api,效果图如下: 该源码需要的环境是php5.6,适合初学者开发学习之用. 下载资源地址分享, https://download.c ...

  2. JAVA小程序:一个基于MVC框架的贪吃蛇程序

    学习JAVA也有一段时间了,之前看了翁恺老师的视频,跟着做了一个细胞自动机,粗浅地了解了一点MVC框架的知识,感觉获益匪浅.但是细胞自动机毕竟是跟着视频完成的,有很大程度上都是参考了视频里的代码,没有 ...

  3. Java使用IntelliJ IDEA创建一个基于Swing的GUI图形化程序,打包发布为jar

    1.创建GUI窗体 首先,直接新建一个默认的空的Java模块即可,随便取个名字 之后再src目录下右键,新建,创建一个Swing的GUI窗体,随便取个名字 给主窗体改个名字 到java代码中生成一个窗 ...

  4. java在线问答系统_求一个基于JAVA的在线答疑系统程序

    /** * 计算 * * @author 3306 2017年5月9日 * @see * @since 1.0 */public class NumPicker { public static voi ...

  5. 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)

    最近看了关于XMPP的框架,以文本聊天为例,需要发送的消息为: <message type="chat" from="kang@server.com" t ...

  6. 基于VTK与Qt的体绘制程序

    基于VTK与Qt的体绘制程序 分类: VTK Qt Volume Rendering C&C++ 2013-06-10 09:17 3434人阅读 评论(13) 收藏 举报 目录(?)[+] ...

  7. [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)

    最近看了关于XMPP的框架,以文本聊天为例,需要发送的消息为: [html] view plaincopy <message type="chat" from="k ...

  8. 树莓派开发笔记(九):基于CSI口的摄像头拍照程序(同样适用USB摄像头)

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  9. 树莓派android摄像头驱动开发,树莓派开发笔记(九):基于CSI口的摄像头拍照程序(同样适用USB摄像头)...

    前话 前面开发完GPIO口的功能,还剩下2个接口,一个是摄像头,一个是显示屏.本篇我们开发一个基于CSI接口的摄像头拍照程序. Demo:摄像头CSI的拍照程序 树莓派摄像头 笔者买的不是USB网络摄 ...

最新文章

  1. Form_通过FND_FNDFLUPL标准功能上传CSV控件(案例)
  2. python 整合excel_Python将多个excel文件合并为一个文件
  3. I/O模型之一:Unix的五种I/O模型
  4. go语言初体验(流程控制、range遍历、函数、结构体、面向对象)
  5. 【419天】跃迁之路——程序员高效学习方法论探索系列(实验阶段176-2018.03.31)...
  6. bzoj 1901: Zju2112 Dynamic Rankings
  7. [No000017F]如何监控注册表的修改
  8. 全志r11_全志R328 Demo开发板;全志R333开发板/核心板;全志R11开发板/核心板;全志R16开发板/方案设计...
  9. break lab c语言,C语言实验lab10.doc
  10. Docker用法整理
  11. 是真“开发者”,就来一“测”到底!
  12. axure html显示效果,Axure RP基础篇: 实现循环显示效果的两种方法
  13. axure侧弹层遮罩_Axure教程 带遮罩层的弹出框(9)
  14. 解决java poi海量数据导出内存溢出问题
  15. 咦?Storyboard在WPF变换中怎么不能用了?
  16. 旋转数组的最小数字(牛客网C++代码)
  17. 中国第一,全球领先的「浪潮」:用智慧计算征服的计算力天下
  18. 量化视角下的基金定投策略
  19. 腾讯回应“暴力裁员”
  20. 暑期实习-京东广告架构组三面面经

热门文章

  1. 月薪10000起步,移民新加坡,快速之路
  2. 在UE4.27下打包VR程序并部署到PICO 3
  3. 基于原始套接字(raw socket)的网络抓包工具
  4. vue中报错 fns.apply is not a function
  5. citrix服务器虚拟化视频,citrix服务器虚拟化(citrix应用虚拟化)
  6. 一家初创公司如何将企业绩效管理带入新高度
  7. C++ 中的DWORD
  8. ce修改器过检测_GG修改器使用教程
  9. 误差放大器中的参数,误差放大器
  10. 加密的m3u8视频下载支持本地m3u8