本例展示如何编写一个异步设备支持例程。它进程了以下操作顺序:
到此,记录已经完全被运行了。下次运行一切从头开始。注意,由于这种形式的代码更可能使用callbackRequestProcessCallbackDelayed来执行所需的processing,这是某种程度上人为设计的示例。
一般回调任务的使用请参考:CSDN讲解。
1)创建一个目录lidriver用于保存这个IOC目录结构,并且使用makeBaseApp.pl脚本创建这个IOC应用程序目录结构和启动目录:
- root@orangepi5:/usr/local/EPICS/program/liasynchronous# ls
- configure iocBoot liadrvierApp Makefile
2)进入lidriverApp/src目录,编写设备支持源文件以及对应的支持文件,并且编辑对应目录下的Makefile文件:
a) devLiA.c
- #include
- #include
- #include
- #include
- #include
-
- #include "alarm.h"
- #include "callback.h"
- #include "dbScan.h"
- #include "dbDefs.h"
- #include "dbAccess.h"
- #include "recGbl.h"
- #include "devSup.h"
- #include "longinRecord.h"
- #include "epicsExport.h"
-
-
- static void longinCallback(CALLBACK * pcallback)
- {
- dbCommon * precord;
- struct rset * prset;
-
- callbackGetUser(precord, pcallback);
- prset = (struct rset *)(precord->rset);
-
- dbScanLock(precord);
- (* prset->process)(precord);
- dbScanUnlock(precord);
- }
-
-
- static long init_record(dbCommon *pcommon);
- static long read_longin(longinRecord *prec);
-
- longindset devLiA = {
- {5, NULL, NULL, init_record, NULL},
- read_longin
- };
- epicsExportAddress(dset, devLiA);
-
- static long init_record(dbCommon *pcommon)
- {
- longinRecord *prec = (longinRecord *)pcommon;
- CALLBACK * pcallback;
-
- if (prec->inp.type != CONSTANT){
- recGblRecordError(S_db_badField, prec, "devLiA(init_record)illegal INP field");
- return S_db_badField;
- }
-
- pcallback = (CALLBACK *)(calloc(1, sizeof(CALLBACK)));
- callbackSetCallback(longinCallback, pcallback);
- callbackSetUser(prec, pcallback);
- prec->dpvt = pcallback;
-
- return 0;
- }
-
- static long readLocked(struct link *pinp, void *dummy)
- {
- longinRecord *prec = (longinRecord *) pinp->precord;
- long status = 0;
- int i;
-
- CALLBACK * pcallback = (CALLBACK *)prec->dpvt;
-
- if (prec->pact){
- i = prec->val + 1;
- if (i > prec->hihi){
- prec->val = prec->lolo;
- }
- else{
- prec->val = i;
- }
-
- prec->udf = FALSE;
- printf("Completed asynchronous processing: %s\n", prec->name);
-
- if (dbLinkIsConstant(&prec->tsel) &&
- prec->tse == epicsTimeEventDeviceTime)
- dbGetTimeStamp(pinp, &prec->time);
- return 0;
- }
-
- printf("Starting asynchronous processing: %s\n", prec->name);
- prec->pact = TRUE;
- callbackRequestDelayed(pcallback, prec->disv);
-
- return status;
- }
-
- static long read_longin(longinRecord *prec)
- {
- long status = dbLinkDoLocked(&prec->inp, readLocked, NULL);
-
- if (status == S_db_noLSET)
- status = readLocked(&prec->inp, NULL);
-
- return status;
- }
b) devLiA.dbd
device(longin, CONSTANT, devLiA, "Asynchronous")
c) 将以上两个文件名添加到相同目录下的Makefile文件中
- ...
- liadrvier_DBD += devLiA.dbd
-
- liadrvier_SRCS += devLiA.c
-
- ...
3) 在idriverApp/Db文件下,增加一个数据库实例文件longinA.db,并且编辑此路径下的Makefile文件:
a)longinA.db
- record(longin, "$(P):LiA")
- {
- field(DESC, "Asynchronous Test")
- field(DTYP, "Asynchronous")
- field(PINI, "1")
- field(DISV, "2")
- field(INP, "0")
- field(HIHI, "50")
- field(LOLO, "0")
- }
b)将上面的文件名添加到Makefile中
- ...
- DB += longinA.db
- ...
4) 回到这个IOC的顶层目录liasynchronous ,执行make进行编译。
5)进入启动目录iocBoot/iocliasynchronous,编译启动脚本st.cmd:
- #!../../bin/linux-aarch64/liadrvier
-
- #- You may have to change liadrvier to something else
- #- everywhere it appears in this file
-
- < envPaths
-
- cd "${TOP}"
-
- ## Register all support components
- dbLoadDatabase "dbd/liadrvier.dbd"
- liadrvier_registerRecordDeviceDriver pdbbase
-
- ## Load record instances
- dbLoadRecords("db/longinA.db","P=Test")
-
- cd "${TOP}/iocBoot/${IOC}"
- iocInit
6)启动这个IOC,用dbl查看加载的记录实例:
- root@orangepi5:/usr/local/EPICS/program/liasynchronous/iocBoot/iocliadrvier# ../../bin/linux-aarch64/liadrvier st.cmd
- #!../../bin/linux-aarch64/liadrvier
- ...
- ############################################################################
- ## EPICS R7.0.7
- ## Rev. 2023-05-26T09:07+0000
- ## Rev. Date build date/time:
- ############################################################################
- Starting asynchronous processing: Test:LiA
- iocRun: All initialization complete
- epics> dbl
- Test:LiA
7) 用通道访问命令测试:
- [blctrl@main-machine ~]$ caput Test:LiA 10; date ;camonitor Test:LiA
- Old : Test:LiA 1
- New : Test:LiA 10
- Thu Aug 31 00:46:41 EDT 2023
- Test:LiA 2023-08-31 00:45:31.597635 10
- Test:LiA 2023-08-31 00:46:43.158043 11
在发出通道访问写命令后,Test:LiA记录值更新为10,2秒后,发生回调,修改记录值为11。