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
- # include
- # include
-
- /* 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
- # include
- # include
-
- 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中运行所注册的函数。