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


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

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

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

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

    1. [blctrl@main-machine exer1]$ ls
    2. configure exer1App iocBoot Makefile
    3. [blctrl@main-machine exer1]$ ls -R
    4. .:
    5. configure exer1App iocBoot Makefile
    6. ./configure:
    7. CONFIG CONFIG_SITE Makefile RELEASE RULES RULES_DIRS RULES.ioc RULES_TOP
    8. ./exer1App:
    9. Db Makefile src
    10. ./exer1App/Db:
    11. Makefile
    12. ./exer1App/src:
    13. exer1Main.cpp Makefile
    14. ./iocBoot:
    15. iocexer1 Makefile
    16. ./iocBoot/iocexer1:
    17. Makefile st.cmd

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

    exer1Hello.c:

    1. /* 展示如何向iocsh注册一条新命令的示例 */
    2. # include
    3. # include
    4. # include
    5. /* iocsh将能够直接调用这条命令。*/
    6. void hello(const char * name)
    7. {
    8. if (name)
    9. {
    10. printf("Hello %s, from my fisrt exer1\n", name);
    11. }
    12. else{
    13. printf("Hello from my exer1\n");
    14. }
    15. }
    16. /* iocsh所需的信息 */
    17. /*
    18. 定义这个参数的名称以及类型
    19. */
    20. static const iocshArg helloArg0 = {"name", iocshArgString};
    21. /* 定义参数数组,数组元素为iocshArg结构体的指针 */
    22. static const iocshArg * helloArgs[] = {&helloArg0};
    23. /* 这个函数的名称,这个函数需要的参数数目,以及其参数数组 */
    24. static const iocshFuncDef helloFuncDef = {"hello", 1, helloArgs};
    25. /* 由iocsh调用的包装器,选择hello需要的参数类型 */
    26. static void helloCallFunc(const iocshArgBuf * args)
    27. {
    28. hello(args[0].sval);
    29. }
    30. /* 在启动时运行,注册程序 */
    31. static void helloRegister(void)
    32. {
    33. //注册时,传给iocshRegister一个函数定义结构体iocshFuncDef的地址
    34. //以及一个调用包装器
    35. iocshRegister(&helloFuncDef, helloCallFunc);
    36. }
    37. /* 导出注册程序 */
    38. epicsExportRegistrar(helloRegister);

    exer1Hello.dbd:

    registrar(helloRegister)

    exer1Add.c:

    1. # include
    2. # include
    3. # include
    4. void add(int a, int b, const char * name, double time)
    5. {
    6. printf("a:%d\n",a);
    7. printf("b:%d\n",b);
    8. printf("%d + %d = %d\n", a, b , a+b);
    9. if (name)
    10. {
    11. printf("Hello %s, from my fisrt exer1Add\n", name);
    12. }
    13. else{
    14. printf("Hello from my exer1Add\n");
    15. }
    16. printf("time: %3.2f\n", time);
    17. }
    18. static const iocshArg addArg0 = {"a", iocshArgInt};
    19. static const iocshArg addArg1 = {"b", iocshArgInt};
    20. static const iocshArg addArg2 = {"name", iocshArgString};
    21. static const iocshArg addArg3 = {"time", iocshArgDouble};
    22. static const iocshArg * addArgs[] = {&addArg0, &addArg1,&addArg2,&addArg3};
    23. static const iocshFuncDef addFuncDef = {"add", 4, addArgs};
    24. static void addCallFunc(const iocshArgBuf * args)
    25. {
    26. add(args[0].ival, args[1].ival,args[2].sval,args[3].dval);
    27. }
    28. static void addRegister(void)
    29. {
    30. iocshRegister(&addFuncDef, addCallFunc);
    31. }
    32. epicsExportRegistrar(addRegister);

     exer1Add.dbd:

    registrar(addRegister)

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

    1. TOP=../..
    2. include $(TOP)/configure/CONFIG
    3. #----------------------------------------
    4. # ADD MACRO DEFINITIONS AFTER THIS LINE
    5. #=============================
    6. #=============================
    7. # Build the IOC application
    8. PROD_IOC = exer1
    9. # exer1.dbd will be created and installed
    10. DBD += exer1.dbd
    11. # exer1.dbd will be made up from these files:
    12. exer1_DBD += base.dbd
    13. # Include dbd files from all support applications:
    14. #exer1_DBD += xxx.dbd
    15. exer1_DBD += exer1Hello.dbd # 添加行1
    16. exer1_DBD += exer1Add.dbd # 添加行2
    17. exer1_SRCS += exer1Hello.c # 添加行3
    18. exer1_SRCS += exer1Add.c # 添加行4
    19. # Add all the support libraries needed by this IOC
    20. #exer1_LIBS += xxx
    21. # exer1_registerRecordDeviceDriver.cpp derives from exer1.dbd
    22. exer1_SRCS += exer1_registerRecordDeviceDriver.cpp
    23. # Build the main IOC entry point on workstation OSs.
    24. exer1_SRCS_DEFAULT += exer1Main.cpp
    25. exer1_SRCS_vxWorks += -nil-
    26. # Add support from base/src/vxWorks if needed
    27. #exer1_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
    28. # Finally link to the EPICS Base libraries
    29. exer1_LIBS += $(EPICS_BASE_IOC_LIBS)
    30. #===========================
    31. include $(TOP)/configure/RULES
    32. #----------------------------------------
    33. # ADD RULES AFTER THIS LINE

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

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

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

    1. [blctrl@main-machine exer1]$ cd iocBoot/iocexer1/
    2. [blctrl@main-machine iocexer1]$ ls
    3. envPaths Makefile st.cmd
    4. [blctrl@main-machine iocexer1]$ ../../bin/linux-x86_64/exer1 st.cmd
    5. #!../../bin/linux-x86_64/exer1
    6. < envPaths
    7. epicsEnvSet("IOC","iocexer1")
    8. epicsEnvSet("TOP","/home/blctrl/exer/exer1")
    9. epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
    10. cd "/home/blctrl/exer/exer1"
    11. ## Register all support components
    12. dbLoadDatabase "dbd/exer1.dbd"
    13. exer1_registerRecordDeviceDriver pdbbase
    14. ## Load record instances
    15. #dbLoadRecords("db/xxx.db","user=blctrl")
    16. cd "/home/blctrl/exer/exer1/iocBoot/iocexer1"
    17. iocInit
    18. Starting iocInit
    19. ############################################################################
    20. ## EPICS R7.0.3.1
    21. ## EPICS Base built Sep 8 2022
    22. ############################################################################
    23. iocRun: All initialization complete
    24. ## Start any sequence programs
    25. #seq sncxxx,"user=blctrl"
    26. epics>

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

    1. epics> help hello
    2. hello name
    3. epics> hello
    4. Hello from my exer1
    5. epics> hello(EPICS)
    6. Hello EPICS, from my fisrt exer1
    7. epics> hello EPICS
    8. Hello EPICS, from my fisrt exer1
    9. epics> help add
    10. add a b name time
    11. epics> add(1,2,blctrl, 5.0)
    12. a:1
    13. b:2
    14. 1 + 2 = 3
    15. Hello blctrl, from my fisrt exer1Add
    16. time: 5.00
    17. epics> add 1 2 blctrl 5.0
    18. a:1
    19. b:2
    20. 1 + 2 = 3
    21. Hello blctrl, from my fisrt exer1Add
    22. time: 5.00

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

  • 相关阅读:
    【每周一测】Java阶段三第三周学习
    编译原理实验--实验三 预测分析法判断算术表达式的正确性--Python实现
    100万级连接,石墨文档WebSocket网关如何架构?
    pytorch数学运算
    最大流与最小费用最大流简略版)
    创建项目与认识DevEco Studio界面
    《机器学习----简单的分类器》第二章、朴素贝叶斯,项目:使用特征值给语句打标签
    Jenkins 之 Pipeline 学习总结
    2核4G服务器支持多少用户同时在线访问?卡不卡?
    安装MinGW win安装gcc
  • 原文地址:https://blog.csdn.net/yuyuyuliang00/article/details/126932221