EPICS简单实例1 -- 向IOCSH注册自己的函数

本实例的目的是练习向IOCSH shell注册自己的函数:

1) 使用当前用户在其家目录中新建一个exer目录并且其下新建一个exer1目录,并切换到exer1目录下,并在此目录下用makeBaseApp.pl以base下的ioc为模板新建一个应用程序目录和ioc启动目录。

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

2) 查看当前的目录结构:

[blctrl@main-machine exer1]$ ls
configure  exer1App  iocBoot  Makefile
[blctrl@main-machine exer1]$ ls -R
.:
configure  exer1App  iocBoot  Makefile

./configure:
CONFIG  CONFIG_SITE  Makefile  RELEASE  RULES  RULES_DIRS  RULES.ioc  RULES_TOP

./exer1App:
Db  Makefile  src

./exer1App/Db:
Makefile

./exer1App/src:
exer1Main.cpp  Makefile

./iocBoot:
iocexer1  Makefile

./iocBoot/iocexer1:
Makefile  st.cmd

3) 进入到 exer1App/src/路径下,编辑四个文件exer1Hello.c和exer1Hello.dbd文件以及exer1Add.c和exer1Add.dbd文件,内容如下:

exer1Hello.c:

/* 展示如何向iocsh注册一条新命令的示例 */
# include <stdio.h>
# include <epicsExport.h>
# include <iocsh.h>

/*  iocsh将能够直接调用这条命令。*/
void hello(const char * name)
{
        if (name)
        {
                printf("Hello %s, from my fisrt exer1\n", name);
        }
        else{
                printf("Hello from my exer1\n");
        }
}

/* iocsh所需的信息  */
/*
    定义这个参数的名称以及类型
*/
static const iocshArg helloArg0 = {"name", iocshArgString};
/* 定义参数数组,数组元素为iocshArg结构体的指针 */
static const iocshArg * helloArgs[] = {&helloArg0};
/*  这个函数的名称,这个函数需要的参数数目,以及其参数数组 */
static const iocshFuncDef helloFuncDef = {"hello", 1, helloArgs};

/* 由iocsh调用的包装器,选择hello需要的参数类型 */
static void helloCallFunc(const iocshArgBuf * args)
{
        hello(args[0].sval);
}

/* 在启动时运行,注册程序 */
static void helloRegister(void)
{
        //注册时,传给iocshRegister一个函数定义结构体iocshFuncDef的地址
        //以及一个调用包装器
        iocshRegister(&helloFuncDef, helloCallFunc);
}
/* 导出注册程序 */
epicsExportRegistrar(helloRegister);

exer1Hello.dbd:

registrar(helloRegister)

exer1Add.c:

# include <stdio.h>
# include <epicsExport.h>
# include <iocsh.h>

void add(int a, int b, const char * name, double time)
{
        printf("a:%d\n",a);
        printf("b:%d\n",b);
        printf("%d + %d = %d\n", a, b , a+b);

        if (name)
        {
                printf("Hello %s, from my fisrt exer1Add\n", name);
        }
        else{
                printf("Hello from my exer1Add\n");
        }
        printf("time: %3.2f\n", time);
}

static const iocshArg addArg0 = {"a", iocshArgInt};
static const iocshArg addArg1 = {"b", iocshArgInt};
static const iocshArg addArg2 = {"name", iocshArgString};
static const iocshArg addArg3 = {"time", iocshArgDouble};
static const iocshArg * addArgs[] = {&addArg0, &addArg1,&addArg2,&addArg3};
static const iocshFuncDef addFuncDef = {"add", 4, addArgs};

static void addCallFunc(const iocshArgBuf * args)
{
        add(args[0].ival, args[1].ival,args[2].sval,args[3].dval);
}

static void addRegister(void)
{
        iocshRegister(&addFuncDef, addCallFunc);
}

epicsExportRegistrar(addRegister);

 exer1Add.dbd:

registrar(addRegister)

4) 编辑相同目录下的Makefile文件,并且添加标注的几行:

TOP=../..

include $(TOP)/configure/CONFIG
#----------------------------------------
#  ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================

#=============================
# Build the IOC application

PROD_IOC = exer1
# exer1.dbd will be created and installed
DBD += exer1.dbd

# exer1.dbd will be made up from these files:
exer1_DBD += base.dbd

# Include dbd files from all support applications:
#exer1_DBD += xxx.dbd

exer1_DBD += exer1Hello.dbd  # 添加行1
exer1_DBD += exer1Add.dbd    # 添加行2

exer1_SRCS += exer1Hello.c   # 添加行3
exer1_SRCS += exer1Add.c     # 添加行4


# Add all the support libraries needed by this IOC
#exer1_LIBS += xxx

# exer1_registerRecordDeviceDriver.cpp derives from exer1.dbd
exer1_SRCS += exer1_registerRecordDeviceDriver.cpp

# Build the main IOC entry point on workstation OSs.
exer1_SRCS_DEFAULT += exer1Main.cpp
exer1_SRCS_vxWorks += -nil-

# Add support from base/src/vxWorks if needed
#exer1_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary

# Finally link to the EPICS Base libraries
exer1_LIBS += $(EPICS_BASE_IOC_LIBS)

#===========================

include $(TOP)/configure/RULES
#----------------------------------------
#  ADD RULES AFTER THIS LINE

5) 退回到这个IOC的顶层目录,即exer1目录,执行make

[blctrl@main-machine src]$ cd ../..
[blctrl@main-machine exer1]$ ls
configure  exer1App  iocBoot  Makefile
[blctrl@main-machine exer1]$ make
make -C ./configure install
make[1]: Entering directory '/home/blctrl/exer/exer1/configure'
...
make[2]: Leaving directory '/home/blctrl/exer/exer1/iocBoot/iocexer1'
make[1]: Leaving directory '/home/blctrl/exer/exer1/iocBoot'

6) 运行这个IOC,方法如下,进入到iocBoot/iocexer1目录下,执行以下命令:

[blctrl@main-machine exer1]$ cd iocBoot/iocexer1/
[blctrl@main-machine iocexer1]$ ls
envPaths  Makefile  st.cmd
[blctrl@main-machine iocexer1]$ ../../bin/linux-x86_64/exer1 st.cmd
#!../../bin/linux-x86_64/exer1
< envPaths
epicsEnvSet("IOC","iocexer1")
epicsEnvSet("TOP","/home/blctrl/exer/exer1")
epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
cd "/home/blctrl/exer/exer1"
## Register all support components
dbLoadDatabase "dbd/exer1.dbd"
exer1_registerRecordDeviceDriver pdbbase
## Load record instances
#dbLoadRecords("db/xxx.db","user=blctrl")
cd "/home/blctrl/exer/exer1/iocBoot/iocexer1"
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>

7)验证iocsh中是否有hello命令,并且执行这个命令:

epics> help hello
hello name
epics> hello
Hello from my exer1
epics> hello(EPICS)
Hello EPICS, from my fisrt exer1
epics> hello EPICS
Hello EPICS, from my fisrt exer1
epics> help add
add a b name time
epics> add(1,2,blctrl, 5.0)
a:1
b:2
1 + 2 = 3
Hello blctrl, from my fisrt exer1Add
time: 5.00
epics> add 1 2 blctrl 5.0
a:1
b:2
1 + 2 = 3
Hello blctrl, from my fisrt exer1Add
time: 5.00

 结论:通过以上练习,我们学会了如何向EPICS iocsh shell注册自己的函数以及在这个shell中运行所注册的函数。

猜你喜欢

转载自blog.csdn.net/yuyuyuliang00/article/details/126932221