这个应用程序可以用于测试连接管理。它用drvAsynIPPort连接一个设备并且在一个后台线程中周期地写入此设备。取决于是否连接了设备,将打印出错消息。可以通过循环上电或者断开网线连接或断开这个设备来测试这种行为。
- [blctrl@main-machine exer]$ mkdir exer41
- [blctrl@main-machine exer]$ cd exer41
- [blctrl@main-machine exer41]$ makeBaseApp.pl -t ioc testAsynDriver
- [blctrl@main-machine exer41]$ makeBaseApp.pl -i -t ioc testAsynDriver
- Using target architecture linux-x86_64 (only one available)
- The following applications are available:
- testAsynDriver
- What application should the IOC(s) boot?
- The default uses the IOC's name, even if not listed above.
- Application name?
- [blctrl@main-machine exer41]$ ls
- configure iocBoot Makefile testAsynDriverApp
- SUPPORT=/usr/local/EPICS/synApps/support
- ASYN=$(SUPPORT)/asyn
- IPAC=$(SUPPORT)/ipac
- #include
- #include
- #include
-
- #include
- #include
- #include
- #include
- #include
-
-
- #include
-
- class testConnect : public asynPortDriver {
- public:
- // 构造函数
- testConnect(const char * portName, const char * IPPortName, const char * outputString);
- void pollerTask(void);
- private:
- asynUser * pasynUserIPPort_;
- const char * outputString_;
- };
-
- static const char * driverName = "testConnect";
-
- // 定义程序轮询时间
- #define POLLER_PERIOD 1
- // 定义响应的最大长度
- #define MAX_RESPONSE_LEN 256
-
- //定义静态函数,只能被从这个文件中调用
- static void pollerTask(void * drvPvt);
-
- testConnect::testConnect(const char * portName, const char * IPPortName, const char * outputString)
- : asynPortDriver(portName,
- 1, /*maxAddr*/
- asynOctetMask, /*接口掩码*/
- 0, /*中断掩码*/
- ASYN_CANBLOCK, /*asynFlag.这个驱动程序阻塞,并且它不是多设备*/
- 1,/*自动连接*/
- 0,/*默认优先级y*/
- 0)/*默认栈大小*/
- {
- asynStatus status;
- const char * functionName = "testConnect";
- // 开辟空间,存储传入字符串
- outputString_ = epicsStrDup(outputString);
- /*
- * asynStatus (*connect)(const char *port, int addr,
- * asynUser **ppasynUser, const char *drvInfo);
- * 传入端口名称,传出一个asynUser指针
- * */
- status = pasynOctetSyncIO->connect(IPPortName, 0, &pasynUserIPPort_,NULL);
-
- if (status) //连接失败
- {
- printf("%s:%s: pasynOctetSyncIO->connect failure, status=%d\n", driverName, functionName, status);
- return;
- }
-
- /* 创建在后台运行的线程 */
- status = (asynStatus)(epicsThreadCreate("testConnectTask",
- epicsThreadPriorityMedium,
- epicsThreadGetStackSize(epicsThreadStackMedium),
- (EPICSTHREADFUNC)::pollerTask,
- this) == NULL);
-
- if (status){
- printf("%s:%s: epicsThreadCreate failed, status=%d\n", driverName, functionName, status);
- return;
- }
-
- printf("Start new Thread testConnectTask successfully!\n\n");
- }
-
- static void pollerTask(void * drvPvt)
- {
- testConnect * pPvt = (testConnect *)drvPvt;
- pPvt->pollerTask();
- }
-
- /* 轮询任务作为一个单独线程运行 */
- void testConnect::pollerTask(void)
- {
- asynStatus status;
- char response[MAX_RESPONSE_LEN] = "";
- size_t numWrite, numRead;
- int isConnected;
- int eomReason;
- static const char * functionName = "pollerTask";
-
- /* 一直循环 */
- while(1){
- // 父类的公有成员函数
- lock();
- /* 根据端口或设备是否连接,isConnect被设置0或1 */
- status = pasynManager->isConnected(pasynUserIPPort_, &isConnected);
- if (status){
- //父类的保护成员变量
- asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
- "%s:%s: error calling pasyManager->isConnected, status=%d, error=%s\n",
- driverName, functionName, status, pasynUserIPPort_->errorMessage);
-
- }
- asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
- "%s:%s: isConnected = %d\n", driverName, functionName, isConnected);
-
- /*
- * asynStatus (*writeRead)(asynUser *pasynUser, const char *write_buffer, size_t write_buffer_len,
- * char *read_buffer, size_t read_buffer_len, double timeout,size_t *nbytesOut, size_t *nbytesIn, int *eomReason);
- * */
- status = pasynOctetSyncIO->writeRead(pasynUserIPPort_, outputString_, strlen(outputString_),
- response, sizeof(response),
- 1.0, &numWrite, &numRead, &eomReason);
-
- if (status){
- asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
- "%s:%s: error calling pasynOctetSyncIO->writeRead,status=%d, error=%s\n",
- driverName, functionName, status, pasynUserIPPort_->errorMessage);
- }
- else{
- printf("From Server: %s\n", response);
- asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
- "%s:%s: numWrite=%ld, wrote:%s, numRead=%ld, response=%s\n",
- driverName, functionName, (long)numWrite,outputString_,(long)numRead, response);
- }
- unlock();
- epicsThreadSleep(POLLER_PERIOD);
- }
- }
-
- extern "C" {
- int testConnectConfigure(const char * portName, const char * IPPortName, const char * outputString)
- {
- new testConnect(portName, IPPortName, outputString);
- return(asynSuccess);
- }
-
- /* EPICS iocsh shell command */
- static const iocshArg initArg0 = {"portName", iocshArgString};
- static const iocshArg initArg1 = {"IPPortName", iocshArgString};
- static const iocshArg initArg2 = {"output string", iocshArgString};
- static const iocshArg * const initArgs[] = {&initArg0, &initArg1, &initArg2};
- static const iocshFuncDef initFuncDef = {"testConnectConfigure",3, initArgs};
-
- static void initCallFunc(const iocshArgBuf * args)
- {
- testConnectConfigure(args[0].sval,args[1].sval, args[2].sval);
- }
-
- void testConnectRegister(void)
- {
- iocshRegister(&initFuncDef, initCallFunc);
- }
-
- epicsExportRegistrar(testConnectRegister);
- }
registrar("testConnectRegister")
- TOP=../..
-
- include $(TOP)/configure/CONFIG
- #----------------------------------------
- # ADD MACRO DEFINITIONS AFTER THIS LINE
- #=============================
- LIBRARY_IOC += testAsynDriverSupport
-
- # Compile and add code to the support library
- LIB_SRCS += testConnect.cpp
- LIB_LIBS += asyn
- LIB_LIBS += $(EPICS_BASE_IOC_LIBS)
-
- #
- #=============================
- # Build the IOC application
-
- PROD_IOC = testAsynDriver
- # testAsynDriver.dbd will be created and installed
- DBD += testAsynDriver.dbd
-
- # testAsynDriver.dbd will be made up from these files:
- testAsynDriver_DBD += base.dbd
- testAsynDriver_DBD += testConnectSupport.dbd
-
- # Include dbd files from all support applications:
- testAsynDriver_DBD += asyn.dbd
- testAsynDriver_DBD += drvAsynIPPort.dbd
- testAsynDriver_DBD += testConnectSupport.dbd
-
- # Add all the support libraries needed by this IOC
- testAsynDriver_LIBS += asyn
- testAsynDriver_LIBS += testAsynDriverSupport
-
- # testAsynDriver_registerRecordDeviceDriver.cpp derives from testAsynDriver.dbd
- testAsynDriver_SRCS += testAsynDriver_registerRecordDeviceDriver.cpp
-
- # Build the main IOC entry point on workstation OSs.
- testAsynDriver_SRCS_DEFAULT += testAsynDriverMain.cpp
- testAsynDriver_SRCS_vxWorks += -nil-
-
- # Add support from base/src/vxWorks if needed
- #testAsynDriver_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
-
- # Finally link to the EPICS Base libraries
- testAsynDriver_LIBS += $(EPICS_BASE_IOC_LIBS)
-
- #===========================
-
- include $(TOP)/configure/RULES
- #----------------------------------------
- # ADD RULES AFTER THIS LINE
- #!../../bin/linux-x86_64/testAsynDriver
-
- #- You may have to change testAsynDriver to something else
- #- everywhere it appears in this file
-
- < envPaths
-
- cd "${TOP}"
-
- ## Register all support components
- dbLoadDatabase "dbd/testAsynDriver.dbd"
- testAsynDriver_registerRecordDeviceDriver pdbbase
-
- ## Load record instances
- #dbLoadRecords("db/xxx.db","user=blctrl")
- drvAsynIPPortConfigure("IPPort", "127.0.0.1:6666", 0, 0, 1);
- testConnectConfigure("PORT1", "IPPort", "Hello EPICS ")
-
- cd "${TOP}/iocBoot/${IOC}"
- iocInit
- #!/usr/bin/python3
-
- import socket
-
- serverIP = "127.0.0.1"
- serverPort = 6666
-
-
- class Tcp_Server(object):
- def __init__(self, ip, port):
- self.server_ip = ip
- self.server_port = port
-
- self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.server.bind((self.server_ip, self.server_port))
-
- self.server.listen(10)
-
- while True:
- while True:
- sock, ip_port = self.server.accept()
- if sock is not None:
- print('New Client: %s' % str(ip_port))
- break
-
- while True:
- print("start receive!")
- data = sock.recv(1024)
- print("Client: %s" % data)
- sock.send(data)
-
- if len(data) == 0:
- sock.close()
- break
-
- def server_close(self):
- self.server.close()
-
-
- def main():
- Tcp_Server(serverIP, serverPort)
-
-
- if __name__ == "__main__":
- main()
IOC应用程序终端:
- [blctrl@main-machine ioctestAsynDriver]$ ../../bin/linux-x86_64/testAsynDriver st.cmd
- #!../../bin/linux-x86_64/testAsynDriver
- < envPaths
- epicsEnvSet("IOC","ioctestAsynDriver")
- epicsEnvSet("TOP","/home/blctrl/exer/exer41")
- epicsEnvSet("SUPPORT","/usr/local/EPICS/synApps/support")
- epicsEnvSet("ASYN","/usr/local/EPICS/synApps/support/asyn")
- epicsEnvSet("IPAC","/usr/local/EPICS/synApps/support/ipac")
- epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
- cd "/home/blctrl/exer/exer41"
- ## Register all support components
- dbLoadDatabase "dbd/testAsynDriver.dbd"
- testAsynDriver_registerRecordDeviceDriver pdbbase
- ## Load record instances
- #dbLoadRecords("db/xxx.db","user=blctrl")
- drvAsynIPPortConfigure("IPPort", "127.0.0.1:6666", 0, 0, 1);
- testConnectConfigure("PORT1", "IPPort", "Hello EPICS")
- cd "/home/blctrl/exer/exer41/iocBoot/ioctestAsynDriver"
- iocInit
- Starting iocInit
- ############################################################################
- ## EPICS R7.0.3.1
- ## EPICS Base built Sep 8 2022
- ############################################################################
- From Server: Hello EPICS
- iocRun: All initialization complete
- ## Start any sequence programs
- #seq sncxxx,"user=blctrl"
- epics> From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
- From Server: Hello EPICS
服务程序的终端:
- [blctrl@main-machine python_server]$ ./server.py
- New Client: ('127.0.0.1', 50312)
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'
- start receive!
- Client: b'Hello EPICS'