自学内容网 自学内容网

EPICS asyn库

EPICS ASYN是一种设备支持库,属于EPICS(实验物理和工业控制系统)框架的模块之一。EPICS是一个用于控制和监控实验设备的分布式软件平台,广泛应用于加速器,实验物理设备等领域。ASYN模块的全称是异驱动支持(Asynchronous Driver Support),主要用于处理异步设备通信。

ASYN模拟的主要功能:

1、异步通信:它提供了支持异步和同步设备通信的接口。异步设备通信是串行通信,网络通信等类型的设备,它们的响应时间较慢或不能立即提供数据。

2、驱动层支持:ASYN提供一个统一的驱动框架,开发者可以基于这个框架开发设备的通信驱动,无论设备是通过串口,TCP/IP,GPIB,MODBUS等方式通信。

3、灵活的接口:ASYN支持多种协议和接口(如串口,GPIB,Ethernet等),并提供了读写数据,设备控制等操作的API。

4、支持设备参数管理:它为设备的参数(如波特率,数据格式等)提供了配置和管理的机制,便于设备驱动的开发和调试。

5、可扩展性:通过ASYN框架,开发者可以将不同类型的设备轻松集成到EPICS系统中,无需重复开发底层通信逻辑。

总结来说,EPICS ASYN是要给用于异步设备通信的驱动支持模块,极大地简化了设备和控制系统之间地集成工作,尤其是在需要处理不同通信协议和接口地场景下。

使用EPICS ASYN编写程序,主要用于控制异步设备或通信接口地设备。下面以一个基于EPICS ASYN的程序。

1、系统环境准备

确定操作系统上已经安装了EPICS base和ASYN模块。如果没有安装从EPICS官方网站下载并安装。

2、创建一个新的IOC应用程序

在编写ASYN驱动程序之前,首先创建一个新的IOC(输入/输出控制器)应用程序。

打开一个bash shell,进入你放置EPICS IOC应用程序的路劲并且为这个IOC创建一个文件夹:

root@orangepi5plus:/usr/local/EPICS/program# pwd
/usr/local/EPICS/program
root@orangepi5plus:/usr/local/EPICS/program# mkdir asyn-example
root@orangepi5plus:/usr/local/EPICS/program# cd asyn-example/
root@orangepi5plus:/usr/local/EPICS/program/asyn-example#

3、使用EPICS的makeBaseApp.pl工具创建新的IOC应用程序的基础框架:

root@orangepi5plus:/usr/local/EPICS/program/asyn-example# makeBaseApp.pl -t ioc asynExample1
root@orangepi5plus:/usr/local/EPICS/program/asyn-example# makeBaseApp.pl -i -t ioc asynExample1
Using target architecture linux-aarch64 (only one available)
The following applications are available:
    asynExample1
What application should the IOC(s) boot?
The default uses the IOC's name, even if not listed above.
Application name?
root@orangepi5plus:/usr/local/EPICS/program/asyn-example# ls
asynExample1App  configure  iocBoot  Makefile

3、配置Makefile和configure/RELEASE

确保ASYN模块能够正确编译和链接到你的应用程序中,你需要编辑asyn-example/configure/RELEASE文件,添加ASYN模块的路径:

...
SUPPORT=/usr/local/EPICS/synApps/support    # 添加此行
ASYN=$(SUPPORT)/asyn                        # 添加此行

...

EPICS_BASE = /usr/local/EPICS/base

...
-include $(TOP)/../RELEASE.local
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
-include $(TOP)/configure/RELEASE.local

4、编写asyn驱动代码,在asyn-example/asynExample1App目录中找到src目录,并在其中床新的驱动文件,例如:TestAsynDriver.cpp:

#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>

#include <cantProceed.h>
#include <epicsStdio.h>
#include <epicsMutex.h>
#include <epicsEvent.h>
#include <epicsThread.h>
#include <iocsh.h>

#include <asynPortDriver.h>
#include <epicsExport.h>

class TestAsynDriver:public asynPortDriver{
public:
        TestAsynDriver(const char * portName);
        virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
        virtual asynStatus readInt32(asynUser *pasynUser,  epicsInt32 *value);

private:
        int counter_;
};

TestAsynDriver::TestAsynDriver(const char * portName)
        :asynPortDriver(portName, 1,
                                        asynInt32Mask | asynDrvUserMask,
                                        asynInt32Mask,
                                        0,1,0,0)
{
        createParam("COUNTER", asynParamInt32, &counter_);
        setIntegerParam(counter_, 0);
}

asynStatus TestAsynDriver::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
        int function = pasynUser->reason;

        if (function == counter_){
                printf("write %d \n", value);
                setIntegerParam(counter_, value);
                callParamCallbacks();

                return asynSuccess;
        }

        return asynPortDriver::writeInt32(pasynUser, value);
}

asynStatus TestAsynDriver::readInt32(asynUser *pasynUser, epicsInt32 *value)
{
        int function = pasynUser->reason;

        if (function == counter_)
        {
                getIntegerParam(counter_, value);
                printf("read %d\n", value);
                return asynSuccess;
        }

        return asynPortDriver::readInt32(pasynUser, value);
}

extern "C" {
int TestAsynDriverConfigure(const char *portName)
{
    new TestAsynDriver(portName);
    return(asynSuccess);
}


/* EPICS iocsh shell commands */

static const iocshArg initArg0 = { "portName",iocshArgString};
static const iocshArg * const initArgs[] = {&initArg0};
static const iocshFuncDef initFuncDef = {"TestAsynDriverConfigure",1,initArgs};
static void initCallFunc(const iocshArgBuf *args)
{
    TestAsynDriverConfigure(args[0].sval);
}

void TestAsynDriverRegister(void)
{
    iocshRegister(&initFuncDef,initCallFunc);
}

epicsExportRegistrar(TestAsynDriverRegister);
}

在此目录下添加一个数据库定义文件TestAsynDriverSupport.dbd:

registrar("TestAsynDriverRegister")

在此目录下Makefile文件中,添加以下内容:

asynExample1_DBD += TestAsynDriverSupport.dbd
asynExample1_DBD += asyn.dbd

asynExample1_LIBS += asyn
asynExample1_SRCS += TestAsynDriver.cpp

5、添加记录类型支持,在在asyn-example/asynExample1App目录中找到Db目录,添加一个数据库实例文件counter.db:

record(longin, "$(P)$(R)COUNTER_RBV") {
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),0,1)COUNTER")
    field(SCAN, "I/O Intr")
}

record(longout, "$(P)$(R)COUNTER") {
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),0,1)COUNTER")
}

将这个文件名,添加到相同目录中Makefile文件中:

DB += counter.db

6、切换到这个IOC的顶层目录asyn-example中,执行make,进行编译。

7、进入启动目录asyn-example/iocBoot/iocasynExample1中,编辑启动脚本st.cmd:

#!../../bin/linux-aarch64/asynExample1

#- You may have to change asynExample1 to something else
#- everywhere it appears in this file

< envPaths

cd "${TOP}"

## Register all support components
dbLoadDatabase "dbd/asynExample1.dbd"
asynExample1_registerRecordDeviceDriver pdbbase
TestAsynDriverConfigure("TEST")                              # 添加此行

## Load record instances
dbLoadRecords("db/counter.db","P=TEST:,R=CH1:,PORT=TEST")    # 添加此行

cd "${TOP}/iocBoot/${IOC}"
iocInit

8、启动这个IOC应用程序:

root@orangepi5plus:/usr/local/EPICS/program/asyn-example/iocBoot/iocasynExample1# ../../bin/linux-aarch64/asynExample1 st.cmd

9、用通道访问进行测试测试:

(base) [blctrl@localhost db]$  caput TEST:CH1:COUNTER 5
Old : TEST:CH1:COUNTER               0
New : TEST:CH1:COUNTER               5
(base) [blctrl@localhost db]$ caget TEST:CH1:COUNTER_RBV
TEST:CH1:COUNTER_RBV           5
(base) [blctrl@localhost db]$  caput TEST:CH1:COUNTER 100
Old : TEST:CH1:COUNTER               5
New : TEST:CH1:COUNTER               100
(base) [blctrl@localhost db]$ caget TEST:CH1:COUNTER_RBV
TEST:CH1:COUNTER_RBV           100

原文地址:https://blog.csdn.net/yuyuyuliang00/article/details/142686018

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!