【EPICS学习记录】注册函数并使用IOC shell进行调用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

根据大佬的教程自己进行了操作,本文对大佬的教程中涉及到的一些代码内容进行了补充说明
参考教程:EPICS简单实例1 – 向IOCSH注册自己的函数


一、创建一个IOC

创建一个IOC程序,将其命名为exer1(建立exer1文件夹,并在该目录下执行makeBaseApp.pl -t 操作)
具体的IOC的创建过程可以参考教程:【EPICS学习记录】根据官方教程创建一个IOC应用
创建完成后文件夹内容显示如下:

yifeng@yifeng:~$ cd EPICS/practice/exer1/
yifeng@yifeng:~/EPICS/practice/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:
exer1Add.c  exer1Add.dbd  exer1Hello.c  exer1Hello.dbd  exer1Main.cpp  Makefile

./iocBoot:
iocexer1  Makefile

./iocBoot/iocexer1:
Makefile  st.cmd

二、创建函数文件

cd进入exer1App/src目录下,使用touch命令创建如下四个文件:

yifeng@yifeng:~/EPICS/practice/exer1/exer1App/src$ touch exer1Hello.c exer1Hello.dbd exer1Add.c exer1Add.dbd
yifeng@yifeng:~/EPICS/practice/exer1/exer1App/src$ ls
exer1Add.c  exer1Add.dbd  exer1Hello.c  exer1Hello.dbd  exer1Main.cpp  Makefile

分别对四个文件的内容进行编辑:

  • 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)

关于注册函数的说明:

  1. IOC shell

IOC Shell是EPICS中的一个交互式命令行工具,用于控制和调试IOC。它提供了一些内置的命令来操作设备和记录,例如查看和修改记录的值、启动和停止设备等。除了内置的命令,用户还可以通过使用iocshRegister()函数注册自定义的命令函数,以扩展IOC Shell的功能。

  1. iocshRegister()函数

iocshRegister()函数是用于注册IOC(Input/Output Controller)命令解释器(IOC Shell)命令的函数。它的作用是将自定义的命令函数与IOC Shell关联起来,使得在IOC Shell中可以使用这些自定义命令。
iocshRegister()函数通常在IOC中的驱动程序文件中使用,通过在IOC初始化函数中调用该函数将自定义的命令函数注册到IOC Shell中。具体的用法是将命令函数的地址和命令名称作为参数传递给iocshRegister()函数,例如:

static const iocshArg myCmdArg0 = { "arg0", iocshArgInt };
static const iocshArg myCmdArg1 = { "arg1", iocshArgString };
static const iocshArg * const myCmdArgs[] = { &myCmdArg0, &myCmdArg1 };
static const iocshFuncDef myCmdDef = { "myCmd", 2, myCmdArgs };

static void myCmdFunc(const iocshArgBuf *args)
{
    // 命令函数实现
}

void myInitFunc()
{
    iocshRegister(&myCmdDef, myCmdFunc);
}

上述代码中,myCmdFunc()是自定义的命令函数,使用iomemArgBuf结构传递参数。通过iocshFuncDef和iocshArg定义命令函数的参数信息。然后,将函数定义结构和命令函数地址作为参数传递给iocshRegister()函数来注册自定义命令。

注册后,可以在IOC Shell中使用myCmd命令调用自定义的命令函数,并传递相应的参数。例如,在IOC Shell中执行以下命令:

myCmd 10 "Hello"

这将调用myCmdFunc()函数,并将参数10和"Hello"传递给该函数进行处理。

总之,iocshRegister()函数的作用是将自定义的命令函数与IOC Shell关联起来,使得在IOC Shell中可以使用这些自定义命令。它通过在IOC的初始化函数中注册命令函数来实现命令的扩展和定制。

  1. epicsExportRegistrar()函数

epicsExportRegistrar()函数是用于注册IOC(Input/Output Controller)初始化函数的函数。它的作用是将初始化函数与IOC注册表关联起来,使得在IOC启动时能够自动调用初始化函数。

在EPICS中,初始化函数负责注册IOC中的各种设备和记录,并进行必要的配置和初始化。而epicsExportRegistrar()函数的作用就是告诉IOC注册表在IOC启动时应该调用哪个初始化函数。

epicsExportRegistrar()函数通常在IOC的驱动程序文件中使用,通过在初始化函数定义之前调用该函数,将初始化函数和IOC的启动过程连接起来。具体的用法是将初始化函数作为参数传递给epicsExportRegistrar()函数,例如:

void myInitFunc()
{
    // 初始化代码
}
epicsExportRegistrar(myInitFunc);

上述代码中,myInitFunc()是自定义的初始化函数,通过调用epicsExportRegistrar()函数将其注册到IOC的初始化过程中。这样,在IOC启动时,IOC注册表会调用该初始化函数来执行相应的操作,以实现设备和记录的初始化和配置。

三、编译运行测试

编译前还需先设置Makefile文件调用上述文件
打开/exer1App/src目录下的Makefile文件并添加如下内容:

# Include dbd files from all support applications:
#exer1_DBD += xxx.dbd
 
exer1_DBD += exer1Hello.dbd  
exer1_DBD += exer1Add.dbd    
 
exer1_SRCS += exer1Hello.c   
exer1_SRCS += exer1Add.c     

回到exer1目录下,执行make编译
然后cd进入/iocBoot/iocexer1目录下,终端输入如下命令行修改st.cmd文件的权限,然后运行文件

chmod +x st.cmd
./st.cmd

接下来就可以在IOC shell中对函数进行调用

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

总结

本文全部是按照大佬的教程进行操作的,主要是添加了对两个注册函数的说明解释

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值