在这里准备了一个型号为NPort 5650-8-DT的Moxa串口服务器,用于一根交叉DB9双母头线缆连接设备上端口2和端口3,使之可以相互通信。
串口服务器配置如下:
a) 按如下步骤,先建立这个IOC程序的程序框架:
- [blctrl@main-machine exer40]$ makeBaseApp.pl -t ioc asynRecordTest
- [blctrl@main-machine exer40]$ makeBaseApp.pl -i -t ioc asynRecordTest
- Using target architecture linux-x86_64 (only one available)
- The following applications are available:
- asynRecordTest
- What application should the IOC(s) boot?
- The default uses the IOC's name, even if not listed above.
- Application name?
- [blctrl@main-machine exer40]$ ls
- asynRecordTestApp configure iocBoot Makefile
b) 编辑configure/RELEASE文件,添加指向asyn以及ipac模块的环境变量ASYN和IPAC:
- SUPPORT=/usr/local/EPICS/synApps/support
-
- IPAC=$(SUPPORT)/ipac
- ASYN=$(SUPPORT)/asyn
c) 编辑asynRecordTestApp/Db/Makefile文件,添加如下一行用于指向asynRecord.db文件
DB += $(ASYN)/db/asynRecord.db
d) 编辑asynRecordTestApp/src/Makefile文件,添加以下行,使得这个IOC程序能够找到asyn的动态链接库
- # Include dbd files from all support applications:
- asynRecordTest_DBD += asyn.dbd
- asynRecordTest_DBD += drvAsynSerialPort.dbd
- asynRecordTest_DBD += drvAsynIPPort.dbd
- #
- # Add all the support libraries needed by this IOC
- asynRecordTest_LIBS += asyn
e) 返回这个IOC程序的顶层目录,执行make命令进行编译。
f) 进入IOC启动目录,编辑st.cmd启动文件:
- [blctrl@main-machine exer40]$ cd iocBoot/iocasynRecordTest/
- [blctrl@main-machine iocasynRecordTest]$ pwd
- /home/blctrl/exer/exer40/iocBoot/iocasynRecordTest
- [blctrl@main-machine iocasynRecordTest]$ cat st.cmd
- #!../../bin/linux-x86_64/asynRecordTest
-
- #- You may have to change asynRecordTest to something else
- #- everywhere it appears in this file
-
- < envPaths
-
- cd "${TOP}"
-
- ## Register all support components
- dbLoadDatabase "dbd/asynRecordTest.dbd"
- asynRecordTest_registerRecordDeviceDriver pdbbase
- drvAsynIPPortConfigure("IP1","192.168.3.50:4002",0,0,1)
- drvAsynIPPortConfigure("IP2","192.168.3.50:4003",0,0,1)
-
- ## Load 2 record instances
- dbLoadRecords("db/asynRecord.db","P=Test:,R=IPPORT1,PORT=IP1,ADDR=0,IMAX=0,OMAX=0")
- dbLoadRecords("db/asynRecord.db","P=Test:,R=IPPORT2,PORT=IP2,ADDR=0,IMAX=0,OMAX=0")
-
- cd "${TOP}/iocBoot/${IOC}"
- iocInit
g) 启动这个IOC程序,并且查看启动后装置的记录实例:
- [blctrl@main-machine iocasynRecordTest]$ ../../bin/linux-x86_64/asynRecordTest st.cmd
- #!../../bin/linux-x86_64/asynRecordTest
- < envPaths
- epicsEnvSet("IOC","iocasynRecordTest")
- epicsEnvSet("TOP","/home/blctrl/exer/exer40")
- epicsEnvSet("SUPPORT","/usr/local/EPICS/synApps/support")
- epicsEnvSet("IPAC","/usr/local/EPICS/synApps/support/ipac")
- epicsEnvSet("ASYN","/usr/local/EPICS/synApps/support/asyn")
- epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
- cd "/home/blctrl/exer/exer40"
- ## Register all support components
- dbLoadDatabase "dbd/asynRecordTest.dbd"
- asynRecordTest_registerRecordDeviceDriver pdbbase
- drvAsynIPPortConfigure("IP1","192.168.3.50:4002",0,0,1)
- drvAsynIPPortConfigure("IP2","192.168.3.50:4003",0,0,1)
- ## Load record instances
- #dbLoadRecords("db/asynRecord.db","P=Test:,R=SPORT")
- dbLoadRecords("db/asynRecord.db","P=Test:,R=IPPORT1,PORT=IP1,ADDR=0,IMAX=0,OMAX=0")
- dbLoadRecords("db/asynRecord.db","P=Test:,R=IPPORT2,PORT=IP2,ADDR=0,IMAX=0,OMAX=0")
- cd "/home/blctrl/exer/exer40/iocBoot/iocasynRecordTest"
- 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
- Test:IPPORT1
- Test:IPPORT2
- epics>
a) 如下所述用medm分别连接上述两个asynRecord记录:
- [blctrl@main-machine adls]$ medm -x -macro "P=Test:,R=IPPORT1,PORT=IP1" asynRecord.adl &
- [blctrl@main-machine adls]$ medm -x -macro "P=Test:,R=IPPORT2,PORT=IP2" asynRecord.adl &
连接后成功后,显示了两个窗口
b) 以下是一个Python脚本,演示了asyn记录的用法。它用ASCII和二进制格式传输数据。
这是Python程序,它演示了EPICS asyn记录的用法。这个程序使用2个asyn记录。对应这两个记录的端口连接了所提供的串口服务器的两个TCP端口。
- [blctrl@main-machine exer40]$ cat write_read.py
- import epics
- import time
-
- rec1="Test:IPPORT1"
- rec2="Test:IPPORT2"
-
- # 记录1 ASCII输出,二进制输入
- t=epics.caput(rec1+'.OFMT', 'ASCII')
- t=epics.caput(rec1+'.OEOS','\r')
- t=epics.caput(rec1+'.IFMT', 'Binary')
- t=epics.caput(rec1+'.IEOS', '')
- # 清除记录1的输入垃圾
- junk=epics.caget(rec1+'.BINP')
-
- # 记录2 ASCII输入,二进制输出
- t=epics.caput(rec2+'.OFMT', 'Binary')
- t=epics.caput(rec2+'.OEOS', '')
- t=epics.caput(rec2+'.IFMT','ASCII')
- t=epics.caput(rec2+'.IEOS','\r')
-
- # 记录2,处于读取模式
- t=epics.caput(rec2+'.TMOD', 'Read')
- # 清除读取值
- junk=epics.caget(rec2+'.AINP')
-
- message="Hello EPICS"
- t=epics.caput(rec1+".TMOD", "Write")
- epics.caput(rec1+".AOUT", message)
-
- print("Record1 send Record2:", message)
- time.sleep(0.1)
- epics.caput(rec2+".PROC",1)
- recv=epics.caget(rec2+".AINP")
- print("Record2 received:",recv)
-
- # 预计30个字节
- size=30
- # 记录1处于读取模式
- t=epics.caput(rec1+".TMOD", "Read")
- t=epics.caput(rec1+".NRRD", size)
-
- junk=epics.caget(rec1+".BINP")
- # 记录2处于写模式
- send_data=[]
- for i in range(size):
- send_data.append(i)
-
- print("Record2 sends Record1:", send_data)
-
- t=epics.caput(rec2+".TMOD","Write")
- t=epics.caput(rec2+".NOWT",size)
- t=epics.caput(rec2+".BOUT",send_data)
-
- time.sleep(0.1)
- t=epics.caput(rec1+".PROC",1)
- time.sleep(0.1)
- arr=epics.caget(rec1+".BINP")
- print("Record1 received",arr)
运行以上python脚本,测试结果:
- [blctrl@main-machine exer40]$ python3 write_read.py
- Record1 send Record2: Hello EPICS
- Record2 received: Hello EPICS
- Record2 sends Record1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
- Record1 received [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
- 24 25 26 27 28 29]