EPICS asyn诊断帮助

2023-10-24 22:59
文章标签 诊断 帮助 epics asyn

本文主要是介绍EPICS asyn诊断帮助,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

iocsh命令

asynReport(level,portName) 
asynInterposeFlushConfig(portName,addr,timeout)
asynInterposeEosConfig(portName,addr,processIn,processOut)
asynSetTraceMask(portName,addr,mask)
asynSetTraceIOMask(portName,addr,mask)
asynSetTraceInfoMask(portName,addr,mask)
asynSetTraceFile(portName,addr,filename)
asynSetTraceIOTruncateSize(portName,addr,size)
asynSetOption(portName,addr,key,val)
asynShowOption(portName,addr,key)
asynAutoConnect(portName,addr,yesNo)
asynSetAutoConnectTimeout(timeout)
asynWaitConnect(portName, timeout)
asynEnable(portName,addr,yesNo)
asynOctetConnect(entry,portName,addr,timeout,buffer_len,drvInfo)
asynOctetRead(entry,nread)
asynOctetWrite(entry,output)
asynOctetWriteRead(entry,output,nread)
asynOctetFlush(entry)
asynOctetSetInputEos(portName,addr,eos,drvInfo)
asynOctetGetInputEos(portName,addr,drvInfo)
asynOctetSetOutputEos(portName,addr,eos,drvInfo)
asynOctetGetOutputEos(portName,addr,drvInfo)
asynRegisterTimeStampSource(portName,functionName);
asynUnregisterTimeStampSource(portName)    

asynReport:如果指定了portName,asynReport为指定端口调用asynCommon:report,如果没有指定portName, 为所有注册的驱动程序和InterposeInterface调用asynCommon:report。

asynInterposeFlushConfig:是一个通用的interposeInterface,它为没有实现flush的底层驱动程序实现了flush。它仅发出读取请求,直到没有剩下要读的字节。timeout是用于读取请求。

asynInterposeEosConfig:是一个通用interposeInterface,它为没有实现字符串末尾处理的底层驱动程序,实现了它。

asynSetTraceMask:为指定端口和地址调用asynTrace:setTraceMask。如果portName是0长度,则全局跟踪掩码被设置。

一个掩码确定能被显示的信息类型。各种选项可是被ORed到一起。当创建一个端口时,这个掩码的默认值是:ASYN_TRACE_ERRROR。

  1. ASYN_TRACE_ERROR:报告运行时错误,例如,超时。
  2. ASYN_TRACEIO_DEVICE:设备支持报告I/O活动。
  3. ASYN_TRACEIO_FILTER:在设备支持和底层驱动之间的任何层报告它对I/O进行的任何过滤。
  4. ASYN_TRACEIO_DRIVER:底层驱动报告I/O活动。
  5. ASYN_TRACE_FLOW:报告逻辑流。设备支持应该报告所有队列请求,进入的回调以及对驱动的所有调用。在设备支持和底层驱动之间的层应该报告它们对更低层驱动的所有调用。底层驱动报告它们对其它支持的调用。
  6. ASYN_TRACE_WARNING:报告警告,即,在ASYN_TRACE_ERROR和ASYN_TRACE_FLOW之间的情况。

asynSetTraceIOMask:为指定端口和地址调用asynTrace:setTraceIOMask。如果portName是0长度,则全局跟踪掩码被设置。另一个掩码,它决定打印多少消息缓存。各种选项能够被ORed到一起。创建这个端口时,这个掩码的默认值是ASYN_TRACEIO_NODATA。

  1. ASYN_TRACEIO_NODATA:不打印来自消息缓存的任何数据。
  2. ASYN_TRACEIO_ASCII:用"%s"格式打印。
  3. ASYN_TRACEIO_ESCAPE: 调用epicsStrPrintEscaped.
  4. ASYN_TRACEIO_HEX :用%2.2x打印每个字节。

asynSetTraceInfoMask:为指定端口和地址调用asynTrace:setTraceInfoMask。如果portName是0长度,则全局跟踪掩码被设置。一个掩码确定了在每条消息开头打印数目信息。不同选项可以被ORed在一起。创建一个端口时,这个掩码的默认值是ASYN_TRACEINFO_TIME。

  1. ASYN_TRACEINFO_TIME:打印这条消息的日期和时间。
  2. ASYN_TRACEINFO_PORT:打印[port, addr, reason],此处port是端口名,addr是asyn地址,而reason是pasynUser->reason。这些是asyn中3段"地址"信息。
  3. ASYN_TRACEINFO_SOURCE:打印文件名和行号,即[__FILE__, __LINE__],此处asynPrint或asynPrintIO状态发生的位置。
  4. ASYN_TRACEINFO_THREAD:打印线程名称,线程ID和线程优先级,即[epicsThreadGetNameSelf(), epicsThreadGetIdSelf(), epicsThreadGetPrioritySelf()]。

从asyn R4-35开始,可以用以+或|连接的整数或者符号名称指定asynSetTraceMask, asynSetTraceIOMask和asynSetTraceInfoMask。空白是被允许的,但需要引号。符号名称是像在asynDriver.h中定义的宏名称,但不是区分大小写的,并且前缀ASYN_, TRACE_, TRACEIO_和TRACEINFO_是可选的。示例:

asynSetTraceMask port,0,ASYN_TRACE_ERROR 
asynSetTraceIOMask port,0,ascii+escape
asynSetTraceInfoMask port,0,1+port+TRACEINFO_SOURCE|ASYN_TRACEINFO_THREAD

asynSetTraceFile:asynSetTraceFile调用asynTrace:setTraceFile。按如下处理文件名:

  1. 未指定。一个NULL指针被传递给setTraceFile。后续消息被发送给errlog。
  2. 一个空字符串("")或"stderr":stderr被传递给setTraceFile。
  3. "stdout":stdout被传递给setTraceFile。
  4. 任何其它字符串:用选项"w"打开这个指定的文件,并且文件指针被传递给setTraceFile。

asynSetTraceIOTruncateSize:asynSetTraceIOTruncateSize调用asynTrace:setTraceIOTruncateSize。

asynSetOption:asynSetOption调用asynCommon:setOption。

asynShowOptin:asynShowOption调用asynCommon:getOption。

asynOctetXXX命令:提供了对asynOctetSyncIO方法的shell访问。entry是标识端口,地址的字符串常量。

此处:

  • filename:一个指定文件名的ascii字符串。如果null或null字符串,则输出被发送到stdout。
  • level:汇报级别。
  • portName:一个指定驱动的portName的ascii字符串。
  • addr:指定设备地址的整数。用于多设备端口,-1值标识端口自身。对于支持单设备的端口,忽略addr。
  • mask:要设置的掩码。
  • key:对应所需选项的键。
  • val:对应这个选项的值。
  • yesNo:值(0,1)表示(no, yes)。
  • entry:一个字符串,标识asynOctetConnect请求。
  • timeout:用毫秒整数指定timeout。默认是1。
  • buffer_len:对应I/O的缓存长度。默认为160。注意:传递给asynOctetWrite的输出字符串可以有转义字符。buffer_len必须足够大来处理转义字符。例如,如果\x02出现在输出字符串中,它算作4个字符。
  • drvInfo:通过接口asynDrvUser传递给驱动的字符串。
  • nread:要读取最大数目的字节。默认=buffer_len。
  • flush:(0,1)表示在读取前(不要,要)flush。默认0。
  • output:输出字符串。

命令asynOctetConnect, asynOctetDisconnect, asynOctetRead, asynOctetWrite, asynOctetWriteRead, asynOctet允许从ioc shell对设备进行I/O。示例是:

以下示例展示了使用https://blog.csdn.net/yuyuyuliang00/article/details/132668739中的asyn驱动模块创建了一个端口驱动程序来测试以上列出的部分asyn诊断命令。

以下这个驱动程序的源代码:

#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>#include "cantProceed.h"
#include "epicsStdio.h"
#include "epicsThread.h"
#include "iocsh.h"#include "asynDriver.h"
#include "asynOctet.h"
#include "asynInt32.h"#include <epicsExport.h>
#define BUFFERSIZE 4096static int VALUE = 0;typedef struct deviceBuffer{char	buffer[BUFFERSIZE];size_t	nchars;int	value;int	low;int	high;
}deviceBuffer;typedef struct deviceInfo{deviceBuffer	buffer;int 		connected;
}deviceInfo;typedef struct infoPvt{deviceInfo 	device;const char 	* portName;int 		connected;double 		delay;asynInterface 	common;asynInterface 	octet;asynInterface	int32;char 		eos[2];int		eoslen;void		* pasynPvt;void		* pasynInt32Pvt;
}infoPvt;static int infoDriverInit(const char * portName, double delay, int noAutoConnect, int low, int high);/* asynCommon  */
static void report(void *drvPvt, FILE * fp, int details);
static asynStatus connect(void * drvPvt, asynUser *pasynUser);
static asynStatus disconnect(void *drvPvt, asynUser * pasynUser);
static asynCommon asynC = {report, connect, disconnect};/* asynOctet */
static asynStatus infoWrite(void *drvPvt, asynUser *pasynUser,const char *data, size_t numchars, size_t *nbytesTransfered);
static asynStatus infoRead(void *drvPvt, asynUser *pasynUser,char *data, size_t maxchars, size_t *nbytesTransfered, int *eomReason);
static asynStatus infoFlush(void *drvPvt, asynUser *pasynUser);
static asynStatus setEos(void *drvPvt, asynUser *pasynUser, const char *eos, int eoslen);
static asynStatus getEos(void *drvPvt, asynUser *pasynUser, char *eos, int eossize, int *eoslen);
static asynOctet asynO;/* asynInt32*/
static asynStatus intWrite(void *drvPvt, asynUser * pasynUser, epicsInt32 value);
static asynStatus intRead(void *drvPvt, asynUser * pasynUser, epicsInt32 *value);
static asynStatus getIntBounds(void *drvPvt, asynUser * pasynUser, epicsInt32 *low, epicsInt32 *high);
static asynInt32 asynI32;static int infoDriverInit(const char * pn, double delay, int noAutoConnect, int low, int high)
{infoPvt		*pinfoPvt;char		*portName;asynStatus	status;size_t		nbytes;int		attributes;nbytes = sizeof(infoPvt) + strlen(pn) + 1;pinfoPvt = (infoPvt *)callocMustSucceed(nbytes, sizeof(char), "infoPvt");portName = (char *)(pinfoPvt + 1);strcpy(portName, pn);pinfoPvt->device.buffer.low = low;pinfoPvt->device.buffer.high = high;pinfoPvt->device.buffer.value = (low + high) / 2;pinfoPvt->portName = portName;pinfoPvt->delay = delay;pinfoPvt->common.interfaceType = asynCommonType;pinfoPvt->common.pinterface = (void *)&asynC;pinfoPvt->common.drvPvt = pinfoPvt;attributes = 0;if (delay > 0.0){attributes |= ASYN_CANBLOCK;}status = pasynManager->registerPort(portName, attributes, !noAutoConnect, 0, 0);if (status != asynSuccess){printf("infoDriverInit registerDriver failed\n");return 0;}status = pasynManager->registerInterface(portName, &pinfoPvt->common);if (status != asynSuccess){printf("infoDriverInit registerInterface failed");return 0;}asynO.write = infoWrite;asynO.read = infoRead;asynO.flush = infoFlush;asynO.setInputEos = setEos;asynO.getInputEos = getEos;pinfoPvt->octet.interfaceType = asynOctetType;pinfoPvt->octet.pinterface = (void *)&asynO;pinfoPvt->octet.drvPvt = pinfoPvt;status = pasynOctetBase->initialize(portName, &pinfoPvt->octet, 1, 1, 0);if (status == asynSuccess){status = pasynManager->registerInterruptSource(portName, &pinfoPvt->octet, &pinfoPvt->pasynPvt);}if (status != asynSuccess){printf("infoDriverInit registerInterface asynOctet failed\n");return 0;}asynI32.write = intWrite;asynI32.read  = intRead;asynI32.getBounds = getIntBounds;pinfoPvt->int32.interfaceType = asynInt32Type;pinfoPvt->int32.pinterface = (void *)&asynI32;pinfoPvt->int32.drvPvt = pinfoPvt;status =  pasynInt32Base->initialize(portName, &pinfoPvt->int32);if (status == asynSuccess){status = pasynManager->registerInterruptSource(portName, &pinfoPvt->int32, &pinfoPvt->pasynInt32Pvt);}if (status != asynSuccess){printf("infoDriverInit registerInterface asynInt32 failed\n");return 0;}return 0;
}static void report(void *drvPvt, FILE *fp, int details)
{infoPvt * pinfoPvt = (infoPvt *)drvPvt;int i,n;fprintf(fp, "infoDriver connected:%s delay = %f\n", pinfoPvt->connected ? "Yes": "NO",pinfoPvt->delay);
}static asynStatus connect(void *drvPvt, asynUser * pasynUser)
{infoPvt		*pinfoPvt = (infoPvt *)drvPvt;deviceInfo	*pdeviceInfo;int		addr;asynStatus	status;status = pasynManager->getAddr(pasynUser, &addr);if (status != asynSuccess) return status;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s infoDriver: connect addr %d\n",pinfoPvt->portName, addr);if (pinfoPvt->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR,"%s infoDriver: connect port already connected\n",pinfoPvt->portName);return asynError;}if (pinfoPvt->delay > 0.0){epicsThreadSleep(pinfoPvt->delay * 10.);}pinfoPvt->connected = 1;pinfoPvt->device.connected = 1;pasynManager->exceptionConnect(pasynUser);return asynSuccess;
}static asynStatus disconnect(void *drvPvt, asynUser *pasynUser)
{infoPvt		*pinfoPvt = (infoPvt *)drvPvt;deviceInfo 	*pdeviceInfo;int		addr;asynStatus	status;status = pasynManager->getAddr(pasynUser, &addr);if (status != asynSuccess) return status;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s infoDriver: disconnect addr %d\n",pinfoPvt->portName, addr);if (!pinfoPvt->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR,"%s infoDriver: disconnect port not connected\n",pinfoPvt->portName);return asynError;}pinfoPvt->connected = 0;pinfoPvt->device.connected = 0;pasynManager->exceptionDisconnect(pasynUser);return asynSuccess;
}static asynStatus infoWrite(void *drvPvt, asynUser *pasynUser, const char *data, size_t nchars, size_t *nbytesTransfered)
{infoPvt		*pinfoPvt = (infoPvt *)drvPvt;deviceInfo	*pdeviceInfo;deviceBuffer	*pdeviceBuffer;int		addr;asynStatus	status;//printf("infoWrite: %s\n", data);status = pasynManager->getAddr(pasynUser, &addr);if(status != asynSuccess)	return status;addr = 0;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s initDriver: write addr %d\n",pinfoPvt->portName, addr);pdeviceInfo = &pinfoPvt->device;if (!pdeviceInfo->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s infoDriver: write %d not connected\n", pinfoPvt->portName, addr);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver:write device %d not connected",pinfoPvt->portName, addr);return asynError;}if (pinfoPvt->delay > pasynUser->timeout){if (pasynUser->timeout > 0.0) epicsThreadSleep(pasynUser->timeout);asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s initDriver write timeout\n", pinfoPvt->portName);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver write timeout", pinfoPvt->portName);return asynTimeout;}pdeviceBuffer = &pdeviceInfo->buffer;if(nchars > BUFFERSIZE) nchars = BUFFERSIZE;if(nchars > 0){memcpy(pdeviceBuffer, data, nchars);}asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, nchars,"infoWrite nchars %lu\n", (unsigned long)nchars);	pdeviceBuffer->nchars = nchars;if (pinfoPvt->delay > 0.0) {epicsThreadSleep(pinfoPvt->delay);}*nbytesTransfered = nchars;return status;
}static asynStatus infoRead(void *drvPvt, asynUser *pasynUser, char *data,size_t maxchars, size_t *nbytesTransfered,int *eomReason)
{infoPvt		*pinfoPvt = (infoPvt *)drvPvt;deviceInfo	*pdeviceInfo;deviceBuffer	*pdeviceBuffer;char		*pfrom, *pto;char		thisChar;size_t		nremaining;size_t		nout = 0;int		addr;asynStatus	status;if (eomReason) *eomReason = 0;if (nbytesTransfered) *nbytesTransfered = 0;status = pasynManager->getAddr(pasynUser, &addr);addr = 0;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s infoDriver: read addr %d\n", pinfoPvt->portName, addr);pdeviceInfo = &pinfoPvt->device;if (!pdeviceInfo->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s infoDriver: read device %d not connected\n",pinfoPvt->portName, addr);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver:read device %d not connected",pinfoPvt->portName, addr);return asynError;}if (pinfoPvt->delay > pasynUser->timeout){if (pinfoPvt->delay > 0.0){epicsThreadSleep(pasynUser->timeout);}asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s infoDriver read timeout\n", pinfoPvt->portName);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver read timeout", pinfoPvt->portName);return asynTimeout;}if (pinfoPvt->delay > 0.0){epicsThreadSleep(pinfoPvt->delay);}pdeviceBuffer = &pdeviceInfo->buffer;nremaining = pdeviceBuffer->nchars;pdeviceBuffer->nchars = 0;pfrom = pdeviceBuffer->buffer;pto = data;while (nremaining >0 && nout < maxchars){thisChar = *pto++ = *pfrom++;nremaining--;nout++;if (pinfoPvt->eoslen > 0){if (thisChar == pinfoPvt->eos[0]){if (pinfoPvt->eoslen == 1){if (eomReason) * eomReason |= ASYN_EOM_EOS;break;}}if (nremaining == 0){if (eomReason) *eomReason |= ASYN_EOM_CNT;break;	}if (* pfrom == pinfoPvt->eos[1]){*pto++ = *pfrom++;nremaining--;nout++;if (eomReason){*eomReason |= ASYN_EOM_EOS;if(nremaining == 0){*eomReason |= ASYN_EOM_CNT;break;}}}}}if (nbytesTransfered) *nbytesTransfered = nout;if (eomReason){if (*nbytesTransfered >= maxchars) *eomReason |= ASYN_EOM_CNT;if (nremaining == 0) * eomReason |= ASYN_EOM_END;}pasynOctetBase->callInterruptUsers(pasynUser, pinfoPvt->pasynPvt, data,nbytesTransfered, eomReason);asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, nout,"infoRead nbytesTransfered %lu\n", (unsigned long)*nbytesTransfered);return status;
}static asynStatus infoFlush(void *drvPvt, asynUser * pasynUser)
{infoPvt *pinfoPvt = (infoPvt *)drvPvt;deviceInfo *pdeviceInfo;deviceBuffer * pdeviceBuffer;int addr;asynStatus status;status = pasynManager->getAddr(pasynUser, &addr);if (status != asynSuccess) return status;addr = 0;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s initDriver: flush addr %d\n",pinfoPvt->portName, addr);pdeviceInfo = &pinfoPvt->device;if (!pdeviceInfo->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s initDriver:flush device %d not connected\n",pinfoPvt->portName, addr);return -1;}pdeviceBuffer = &pdeviceInfo->buffer;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s infoDriver\n", pinfoPvt->portName);pdeviceBuffer->nchars = 0;return asynSuccess;
}static asynStatus setEos(void *drvPvt, asynUser * pasynUser, const char *eos, int eoslen)
{infoPvt * pinfoPvt = (infoPvt *)drvPvt;int i;if (eoslen > 2 || eoslen < 0){epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"setEos illegal eoslen %d", eoslen);return asynError;}pinfoPvt->eoslen = eoslen;for (i = 0; i < eoslen; i++){pinfoPvt->eos[i] = eos[i];}asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s setEos\n", pinfoPvt->portName);return asynSuccess;
}static asynStatus getEos(void *drvPvt, asynUser * pasynUser,char *eos, int eossize, int *eoslen)
{infoPvt * pinfoPvt = (infoPvt *)drvPvt;int i;* eoslen = pinfoPvt->eoslen;for (i = 0; i < *eoslen; i++){eos[i] = pinfoPvt->eos[i];}asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s setEos\n", pinfoPvt->portName);return asynSuccess;
}static asynStatus intWrite(void *drvPvt, asynUser * pasynUser, epicsInt32 value)
{infoPvt         *pinfoPvt = (infoPvt *)drvPvt;deviceInfo      *pdeviceInfo;deviceBuffer    *pdeviceBuffer;int             addr;asynStatus      status;//printf("infoWrite: %s\n", data);status = pasynManager->getAddr(pasynUser, &addr);if(status != asynSuccess)       return status;addr = 0;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s initDriver: intWrite addr %d\n",pinfoPvt->portName, addr);pdeviceInfo = &pinfoPvt->device;if (!pdeviceInfo->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s infoDriver: intWrite %d not connected\n", pinfoPvt->portName, addr);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver:intWrite device %d not connected",pinfoPvt->portName, addr);return asynError;}if (pinfoPvt->delay > pasynUser->timeout){if (pasynUser->timeout > 0.0) epicsThreadSleep(pasynUser->timeout);asynPrint(pasynUser, ASYN_TRACE_ERROR,"%s initDriver intWrite timeout\n", pinfoPvt->portName);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver intWrite timeout", pinfoPvt->portName);return asynTimeout;}pdeviceBuffer = &pdeviceInfo->buffer;if (value < pdeviceBuffer->low){pdeviceBuffer->value = pdeviceBuffer->low;}else if (value > pdeviceBuffer->high){pdeviceBuffer->value = pdeviceBuffer->high;}else{pdeviceBuffer->value = value;}asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, "Write to device", strlen("Write to device"),"intWrite value = %d\n", pdeviceBuffer->value);if (pinfoPvt->delay > 0.0) {epicsThreadSleep(pinfoPvt->delay);}return status;
}static asynStatus intRead(void *drvPvt, asynUser * pasynUser, epicsInt32 *value)
{infoPvt         *pinfoPvt = (infoPvt *)drvPvt;deviceInfo      *pdeviceInfo;deviceBuffer    *pdeviceBuffer;int             addr;asynStatus      status;//printf("infoRead: %s\n", data);status = pasynManager->getAddr(pasynUser, &addr);if(status != asynSuccess)       return status;addr = 0;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s initDriver: intRead addr %d\n",pinfoPvt->portName, addr);pdeviceInfo = &pinfoPvt->device;if (!pdeviceInfo->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s infoDriver: intRead %d not connected\n", pinfoPvt->portName, addr);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver:intRead device %d not connected",pinfoPvt->portName, addr);return asynError;}if (pinfoPvt->delay > pasynUser->timeout){if (pasynUser->timeout > 0.0) epicsThreadSleep(pasynUser->timeout);asynPrint(pasynUser, ASYN_TRACE_ERROR,"%s initDriver intRead timeout\n", pinfoPvt->portName);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver intRead timeout", pinfoPvt->portName);return asynTimeout;}pdeviceBuffer = &pdeviceInfo->buffer;* value = pdeviceBuffer->value;asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, "Read from device", strlen("Read from device"),"intRead value = %d\n", pdeviceBuffer->value);if (pinfoPvt->delay > 0.0) {epicsThreadSleep(pinfoPvt->delay);}return status;
}static asynStatus getIntBounds(void *drvPvt, asynUser * pasynUser, epicsInt32 *low, epicsInt32 *high)
{infoPvt         *pinfoPvt = (infoPvt *)drvPvt;deviceInfo      *pdeviceInfo;deviceBuffer    *pdeviceBuffer;int             addr;asynStatus      status;//printf("getIntBounds: %s\n", data);status = pasynManager->getAddr(pasynUser, &addr);if(status != asynSuccess)       return status;addr = 0;asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s initDriver: getIntBounds addr %d\n",pinfoPvt->portName, addr);pdeviceInfo = &pinfoPvt->device;if (!pdeviceInfo->connected){asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s infoDriver: getIntBounds %d not connected\n", pinfoPvt->portName, addr);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver:getIntBounds device %d not connected",pinfoPvt->portName, addr);return asynError;}if (pinfoPvt->delay > pasynUser->timeout){if (pasynUser->timeout > 0.0) epicsThreadSleep(pasynUser->timeout);asynPrint(pasynUser, ASYN_TRACE_ERROR,"%s initDriver getIntBounds timeout\n", pinfoPvt->portName);epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,"%s infoDriver getIntBounds timeout", pinfoPvt->portName);return asynTimeout;}pdeviceBuffer = &pdeviceInfo->buffer;* low = pdeviceBuffer->low;* high = pdeviceBuffer->high;asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, "get limits from device", strlen("get limits from device"),"getIntBounds low = %d, high = %d\n", pdeviceBuffer->low, pdeviceBuffer->high);return status;
}// static int infoDriverInit(const char * portName, double delay, int noAutoConnect, int low, int high);
static const iocshArg infoDriverInitArg0 = { "portName", iocshArgString };
static const iocshArg infoDriverInitArg1 = { "delay", iocshArgDouble };
static const iocshArg infoDriverInitArg2 = { "noautoconnect", iocshArgInt };
static const iocshArg infoDriverInitArg3 = { "low", iocshArgInt };
static const iocshArg infoDriverInitArg4 = { "high", iocshArgInt };static const iocshArg *infoDriverInitArgs[] = {&infoDriverInitArg0,&infoDriverInitArg1,&infoDriverInitArg2,&infoDriverInitArg3, &infoDriverInitArg4};static const iocshFuncDef infoDriverInitFuncDef = {"infoDriverInit", 5, infoDriverInitArgs};static void infoDriverInitCallFunc(const iocshArgBuf *args)
{infoDriverInit(args[0].sval,args[1].dval,args[2].ival,args[3].ival, args[4].ival);
}static void infoDriverRegister(void)
{static int firstTime = 1;if (firstTime) {firstTime = 0;iocshRegister(&infoDriverInitFuncDef, infoDriverInitCallFunc);}
}epicsExportRegistrar(infoDriverRegister);

将以上程序添加到应用程序的dbd文件如下:device.dbd

registrar(infoDriverRegister)

 将以上device.c和device.dbd文件添加到相同目录下Makefile中,并且添加所需的其它库文件:

...
# dbd文件
infoDriver_DBD += asyn.dbd
infoDriver_DBD += device.dbd
# 库文件
infoDriver_LIBS += asyn
# 源文件
infoDriver_SRCS += device.c...

回到这个IOC的顶层目录,执行make命令,进行编译。

进入这个点IOC程序的启动目录中,在st.cmd脚本中按定义的格式调用infoDriverInit:

#!../../bin/linux-aarch64/infoDriver#- You may have to change infoDriver to something else
#- everywhere it appears in this file< envPathscd "${TOP}"## Register all support components
dbLoadDatabase "dbd/infoDriver.dbd"
infoDriver_registerRecordDeviceDriver pdbbaseinfoDriverInit("MyPort", 0.5, 0, 0, 1000)
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=Asyn:,R=AsynRecord,PORT=MyPort,ADDR=0,OMAX=0,IMAX=0")cd "${TOP}/iocBoot/${IOC}"
iocInit

启动这个IOC程序:

root@orangepi5:/usr/local/EPICS/program/infoDriver/iocBoot/iocinfoDriver# ../../bin/linux-aarch64/infoDriver st.cmd
#!../../bin/linux-aarch64/infoDriver
< envPaths
epicsEnvSet("IOC","iocinfoDriver")
epicsEnvSet("TOP","/usr/local/EPICS/program/infoDriver")
epicsEnvSet("SUPPORT","/usr/local/EPICS/synApps/support")
epicsEnvSet("ASYN","/usr/local/EPICS/synApps/support/asyn")
epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
cd "/usr/local/EPICS/program/infoDriver"
## Register all support components
dbLoadDatabase "dbd/infoDriver.dbd"
infoDriver_registerRecordDeviceDriver pdbbase
infoDriverInit("MyPort", 0.5, 0, 0, 1000)
cd "/usr/local/EPICS/program/infoDriver/iocBoot/iocinfoDriver"
iocInit
Starting iocInit
############################################################################
## EPICS R7.0.7
## Rev. 2023-05-26T09:07+0000
## Rev. Date build date/time:
############################################################################
iocRun: All initialization complete
epics> 

在epics命令提示环境中测试以上部分asyn诊断命令: 

epics> asynOctetConnect("myid","MyPort",0,1,20)
epics> asynOctetWrite("myid","HelloWorld")
epics> asynOctetRead("myid")
eomReason 0x4
HelloWorld
epics> asynOctetWriteRead("myid","This is a test")
eomReason 0x4
This is a test
epics> asynOctetDisconnect("myid")
epics> asynReport(1,"MyPort")
MyPort multiDevice:No canBlock:Yes autoConnect:Yesenabled:Yes connected:Yes numberConnects 1nDevices 0 nQueued 0 blocked:NoasynManagerLock:No synchronousLock:NoexceptionActive:No exceptionUsers 1 exceptionNotifys 0traceMask:0x1 traceIOMask:0x0 traceInfoMask:0x1
infoDriver connected:Yes delay = 0.500000
epics>  asynSetTraceMask("MyPort",-1, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW)
epics> asynOctetWrite("myid","HelloWorld")
2023/09/05 12:55:25.521 MyPort asynManager::queueLockPort locking port
2023/09/05 12:55:25.522 MyPort asynManager::queueLockPort taking mutex 0x55702ab790
2023/09/05 12:55:25.522 MyPort asynManager::queueLockPort queueing request
2023/09/05 12:55:25.523 MyPort addr -1 queueRequest priority 0 not lockHolder
2023/09/05 12:55:25.524 MyPort schedule queueRequest timeout in 2.000000 seconds
2023/09/05 12:55:25.525 MyPort asynManager::queueLockPort waiting for event
2023/09/05 12:55:25.526 asynManager::portThread port=MyPort callback
2023/09/05 12:55:25.526 MyPort asynManager::queueLockPortCallback signaling begin event
2023/09/05 12:55:25.526 MyPort asynManager::queueLockPortCallback waiting for mutex from queueUnlockPort
2023/09/05 12:55:25.526 MyPort asynManager::queueLockPort got event from callback
2023/09/05 12:55:25.528 MyPort initDriver: write addr 0
2023/09/05 12:55:26.028 MyPort queueUnlockPort
2023/09/05 12:55:26.030 MyPort asynManager::queueUnlockPort waiting for event
2023/09/05 12:55:26.031 MyPort queueUnlockPort unlock mutex 0x55702ab790 complete.
epics>  asynOctetRead("myid")
2023/09/05 12:56:12.292 MyPort asynManager::queueLockPort locking port
2023/09/05 12:56:12.293 MyPort asynManager::queueLockPort taking mutex 0x55702ab790
2023/09/05 12:56:12.293 MyPort asynManager::queueLockPort queueing request
2023/09/05 12:56:12.293 MyPort addr -1 queueRequest priority 0 not lockHolder
2023/09/05 12:56:12.294 MyPort schedule queueRequest timeout in 2.000000 seconds
2023/09/05 12:56:12.295 MyPort asynManager::queueLockPort waiting for event
2023/09/05 12:56:12.296 asynManager::portThread port=MyPort callback
2023/09/05 12:56:12.296 MyPort asynManager::queueLockPortCallback signaling begin event
2023/09/05 12:56:12.296 MyPort asynManager::queueLockPortCallback waiting for mutex from queueUnlockPort
2023/09/05 12:56:12.296 MyPort asynManager::queueLockPort got event from callback
2023/09/05 12:56:12.296 MyPort infoDriver: read addr 0
2023/09/05 12:56:12.797 MyPort queueUnlockPort
2023/09/05 12:56:12.797 MyPort asynManager::queueUnlockPort waiting for event
2023/09/05 12:56:12.798 MyPort queueUnlockPort unlock mutex 0x55702ab790 complete.
eomReason 0x4
HelloWorld

使用asyRecord.adl进行测试:

medm -x -macro "P=Asyn:,R=AsynRecord" asynRecord.adl

出现以下窗口:

选择More...菜单的asynOctet Interface I/O:

 弹出以下窗口,在Out的ASCII文本框中输入一个字符串,这里为HelloWord,按回车,可以看到Input的ASCII文本框中显示读回的HelloWorld,并且EOM reason中显示字符串结束的原因。

选择More...菜单的Register Interface I/O,弹出以下窗口,将Interface下的菜单选中asynInt32,在Output文本框中输入一个数值68,按回车后,在Input文本框中回读到这个数值:

补充一个记录实例文件:

record(calc,"$(P)$(R)_P$(PORT)_A$(A)_calc") {field(DESC, "Counter")field(SCAN,"Passive")field(CALC, "(A<99)?(A+1):0")field(INPA,"$(P)$(R)_P$(PORT)_A$(A)_calc NPP NMS")field(FLNK,"$(P)$(R)_P$(PORT)_A$(A)_so")field(EGU, "Counts")field(HOPR, "10")field(FLNK,"$(P)$(R)_P$(PORT)_A$(A)_so")
}record(stringout,"$(P)$(R)_P$(PORT)_A$(A)_so") {field(DOL,"$(P)$(R)_P$(PORT)_A$(A)_calc NPP NMS")field(OMSL,"closed_loop")field(FLNK,"$(P)$(R)_P$(PORT)_A$(A)_si")
}record(stringin,"$(P)$(R)_P$(PORT)_A$(A)_si") {field(DTYP,"asynOctetWriteRead")field(INP,"@asyn($(PORT),$(A)) $(P)$(R)_P$(PORT)_A$(A)_so")
}

以上实例文件运行过程为:当calc记录运行时,其从自己的VAL读取一个值,如果这个数值小于99就VAL增加1,否则VAL变为0,在运行结束前,通过FLNK使stringout记录运行,stringout从calc记录的VAL字段读取一个值,将其转换成字符串表示形式,存入到自己的VAL字段,并且在运行结束前,通过FLNK使得stringin记录运行,当stringin运行时,通过接口asynOctetWriteRead设备支持,将从stringout读取的字符串写入到端口驱动程序中,然后从端口驱动中回读字符串,写入到自己的VAL字段中。 

 将以下记录加载命令,添加到st.cmd启动脚本文件的iocInit前:

dbLoadRecords("db/test.db", "P=Test:,R=Client,PORT=MyPort,A=0")

 重启这个IOC,用dbl命令查看加载的记录:

epics>dbl
Asyn:AsynRecord
Test:Client_PMyPort_A0_calc
Test:Client_PMyPort_A0_si
Test:Client_PMyPort_A0_so

 用CSS进行以上记录运行的显示:

asynRegisterTimeStampSource:为指定端口调用pasynManager->registerTimeStampSource。时间戳源函数必须在这个程序的dbd文件中被定义为"函数"。

asynReisgerTimeStampSource:为指定端口调用pasynManager->unregisterTimeStampSource。这恢复成asynManager中默认的时间戳源函数。

这篇关于EPICS asyn诊断帮助的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/278346

相关文章

JVM 常见异常及内存诊断

栈内存溢出 栈内存大小设置:-Xss size 默认除了window以外的所有操作系统默认情况大小为 1MB,window 的默认大小依赖于虚拟机内存。 栈帧过多导致栈内存溢出 下述示例代码,由于递归深度没有限制且没有设置出口,每次方法的调用都会产生一个栈帧导致了创建的栈帧过多,而导致内存溢出(StackOverflowError)。 示例代码: 运行结果: 栈帧过大导致栈内存

PDF 软件如何帮助您编辑、转换和保护文件。

如何找到最好的 PDF 编辑器。 无论您是在为您的企业寻找更高效的 PDF 解决方案,还是尝试组织和编辑主文档,PDF 编辑器都可以在一个地方提供您需要的所有工具。市面上有很多 PDF 编辑器 — 在决定哪个最适合您时,请考虑这些因素。 1. 确定您的 PDF 文档软件需求。 不同的 PDF 文档软件程序可以具有不同的功能,因此在决定哪个是最适合您的 PDF 软件之前,请花点时间评估您的

电子电气架构---私有总线通信和诊断规则

电子电气架构—私有总线通信和诊断规则 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节能减排。 无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事.而不是让内心的烦躁、

机器人可能会在月球上提供帮助

登月是我们这个时代最具标志性的事件之一,这可能还算轻描淡写了:这是我们迄今为止在物理上探索得最远的一次。我听过一些当时的老广播,它们可以让你想象出这次航行的重要性。 现在,研究人员表示,我们可能很快就能重返月球,甚至可能很快就会有人类任务前往火星。 火星。艺术家:NASA 这次会有什么不同呢? 有一点是确定的:机器人将大力协助—— 非常多。 在麻省理工学院,我们的一些团队正在开发突破性的

DoIP-ISO 13400-1 道路车辆-基于互联网协议的诊断通信(DoIP)-第 1 部分:一般信息和用例定义 (1/2)

如下内容基于2011版本的 ISO 13400开展,内容较多,拆分为2篇,此篇为 1/2。 前言 ISO(国际标准化组织)是一个全球范围内的国际标准机构联合体(ISO 成员机构)。国际标准的制备工作通常通过 ISO 技术委员会进行。每个相关成员机构都有权在已建立的技术委员会中代表其利益。与 ISO 保持联系的国际组织、政府和非政府组织也参与这项工作。ISO 与国际电工委员会(IEC)在所有电气

PMP–一、二、三模–分类–14.敏捷–技巧–帮助团队交付价值的执行实践迭代和增量如何帮助交付工作产品

文章目录 技巧一模14.敏捷--实践--帮助团队交付价值的执行实践--持续集成--在不同层面测试、验收测试驱动开发 (ATDD) 、测试驱动开发和行为驱动开发、刺探 。90、 [单选] 敏捷项目的第一次迭代即将开始。发起人召集团队、Scrum主管、产品负责人和其他项目干系人参加启动会议。发起人强调需要在项目尽可能早的时候以最小的成本识别和应对项目风险。与会者实现发起人要求的最佳方式是什么?

「账号诊断」上线,「违规检测」全新改版!企业运营效率再提升!

云略自推出至今,始终致力于搜集用户的使用反馈,并据此不断新增及优化各项功能,持续产品迭代。 从矩阵号管理延伸的私聊/评论回复功能,到文案生成进阶的智能混剪,云略通过产品功能的不断升级优化,助力品牌的内容创作与用户经营。 近期,我们新增「账号诊断」功能,并对「违规检测」全面改版,让企业运营者可以更加轻松地掌握账号健康状况,及时发现并解决潜在问题,从而提升整体运营效率。 具体功能

猫猫学iOS(四十七)之网易彩票帮助界面UIWebView的运用

猫猫分享,必须精品 原创文章,欢迎转载。转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 效果: 制作过程 首先是帮助按钮那个地方的点击。 这里是用点击跳转的用的是 NJSettingArrowItem,前面的设置的,从字典通过模型转过来的。 // 分享NJSettingArrowItem

Windows下面查看Python帮助

在Windows中,查看Python帮助的命令如下: python -m pydoc the_command 示例: 出现More之后,用空格可以继续显示下一屏。要退出当前命令,键入q即可。

Linux下面查看python帮助文档

因为python网站被墙,所以在线查看帮助比较困难。好在Linux自身通常都已经带了python的联机帮助,对应的命令是pydoc。 使用方法: flying-bird@flyingbird:~/examples/python/print_file_type$ pydoc --helppydoc - the Python documentation toolpydoc <name>