epicsShareFunc int epicsShareAPI eltc(int yesno) { errlogInit(0); errlogFlush(); pvtData.toConsole = yesno; return 0; }
static void testPrefixLogandCompare( const char* logmessage ) { struct timeval timeout; timeout.tv_sec = 5; /* in seconds */ timeout.tv_usec = 0; errlogPrintfNoConsole("%s", logmessage); errlogFlush(); iocLogFlush(); fdmgr_pend_event(pfdctx, &timeout); }
static void daeCASThread(void* arg) { exServer *pCAS; unsigned debugLevel = 0u; double executionTime = 0.0; double asyncDelay = 0.1; const char* pvPrefix; unsigned aliasCount = 1u; unsigned scanOn = true; unsigned syncScan = true; unsigned maxSimultAsyncIO = 1000u; isisdaeInterface* iface = static_cast<isisdaeInterface*>(arg); printf("starting cas server\n"); pvPrefix = macEnvExpand("$(MYPVPREFIX)DAE:"); try { pCAS = new exServer ( pvPrefix, aliasCount, scanOn != 0, syncScan == 0, asyncDelay, maxSimultAsyncIO, iface ); } catch ( ... ) { errlogSevPrintf (errlogMajor, "Server initialization error\n" ); errlogFlush (); return; } pCAS->setDebugLevel(debugLevel); try { while (true) { fileDescriptorManager.process(1000.0); } } catch(const std::exception& ex) { std::cerr << ex.what() << std::endl; } //pCAS->show(2u); delete pCAS; errlogFlush (); }
epicsShareFunc void * mallocMustSucceed(size_t size, const char *msg) { void * mem = NULL; if (size > 0) { while ((mem = malloc(size)) == NULL) { errlogPrintf("%s: mallocMustSucceed(%lu) - malloc failed\n", msg, (unsigned long)size); errlogPrintf("Thread %s (%p) suspending.\n", epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); errlogFlush(); epicsThreadSuspendSelf(); } } return mem; }
epicsShareFunc void cantProceed(const char *msg, ...) { va_list pvar; va_start(pvar, msg); if (msg) errlogVprintf(msg, pvar); va_end(pvar); errlogPrintf("Thread %s (%p) can't proceed, suspending.\n", epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); errlogFlush(); epicsThreadSleep(1.0); while (1) epicsThreadSuspendSelf(); }
int main(int argc,char **argv) { int argn = 1; char *sub = NULL; int subLength = 0; char **pstr; char *psep; int *len; long status = 0; static char *subSep = ","; /* Look for -Smacro=value options */ while (argc>argn && (strncmp(argv[argn], "-S", 2)==0)) { pstr = ⊂ psep = subSep; len = &subLength; if (strlen(argv[argn])==2) { dbCatString(pstr, len, argv[++argn], psep); } else { dbCatString(pstr, len, argv[argn]+2, psep); } argn++; } if (argc == argn) { status = asInitFP(stdin, sub); if(status) errlogPrintf("ascheck: Access Security File failed.\n"); } else if (argc == argn+1) { status = asInitFile(argv[argn], sub); if(status) errlogPrintf("ascheck: Access Security File failed.\n"); } else { printf("usage: ascheck [-Smac=sub ...] [<] file\n"); status = -1; } errlogFlush(); return status; }
cac::~cac () { // this blocks until the UDP thread exits so that // it will not sneak in any new clients // // lock intentionally not held here so that we dont deadlock // waiting for the UDP thread to exit while it is waiting to // get the lock. { epicsGuard < epicsMutex > cbGuard ( this->cbMutex ); epicsGuard < epicsMutex > guard ( this->mutex ); if ( this->pudpiiu ) { this->pudpiiu->shutdown ( cbGuard, guard ); // make sure no new tcp circuits are created this->cacShutdownInProgress = true; // // shutdown all tcp circuits // tsDLIter < tcpiiu > iter = this->circuitList.firstIter (); while ( iter.valid() ) { // this causes a clean shutdown to occur iter->unlinkAllChannels ( cbGuard, guard ); iter++; } } } // // wait for all tcp threads to exit // // this will block for oustanding sends to go out so dont // hold a lock while waiting // { epicsGuard < epicsMutex > guard ( this->mutex ); while ( this->iiuExistenceCount > 0 ) { epicsGuardRelease < epicsMutex > unguard ( guard ); this->iiuUninstall.wait (); } } if ( this->pudpiiu ) { delete this->pudpiiu; } freeListCleanup ( this->tcpSmallRecvBufFreeList ); freeListCleanup ( this->tcpLargeRecvBufFreeList ); delete [] this->pUserName; tsSLList < bhe > tmpBeaconList; this->beaconTable.removeAll ( tmpBeaconList ); while ( bhe * pBHE = tmpBeaconList.get() ) { pBHE->~bhe (); this->bheFreeList.release ( pBHE ); } this->timerQueue.release (); this->ipToAEngine.release (); // clean-up the list of un-notified msg objects while ( msgForMultiplyDefinedPV * msg = this->msgMultiPVList.get() ) { msg->~msgForMultiplyDefinedPV (); this->mdpvFreeList.release ( msg ); } errlogFlush (); osiSockRelease (); // its ok for channels and subscriptions to still // exist at this point. The user created them and // its his responsibility to clean them up. }
int main(int argc,char **argv) { int i; char *outFilename; char *pext; FILE *outFile; dbMenu *pdbMenu; dbRecordType *pdbRecordType; dbFldDes *pdbFldDes; char *plastSlash; int strip; char *path = NULL; char *sub = NULL; int pathLength = 0; int subLength = 0; char **pstr; char *psep; int *len; long status; static char *pathSep = OSI_PATH_LIST_SEPARATOR; static char *subSep = ","; /*Look for options*/ if(argc<2) { fprintf(stderr,"usage: dbToDoxygen -Idir -Idir file.dbd [outfile]\n"); exit(0); } while((strncmp(argv[1],"-I",2)==0)||(strncmp(argv[1],"-S",2)==0)) { if(strncmp(argv[1],"-I",2)==0) { pstr = &path; psep = pathSep; len = &pathLength; } else { pstr = ⊂ psep = subSep; len = &subLength; } if(strlen(argv[1])==2) { dbCatString(pstr,len,argv[2],psep); strip = 2; } else { dbCatString(pstr,len,argv[1]+2,psep); strip = 1; } argc -= strip; for(i=1; i<argc; i++) argv[i] = argv[i + strip]; } if(argc<2 || (strncmp(argv[1],"-",1)==0)) { fprintf(stderr,"usage: dbToRecordtypeH -Idir -Idir file.dbd [outfile]\n"); exit(0); } if(argc==2){ /*remove path so that outFile is created where program is executed*/ plastSlash = strrchr(argv[1],'/'); if(!plastSlash) plastSlash = strrchr(argv[1],'\\'); plastSlash = (plastSlash ? plastSlash+1 : argv[1]); outFilename = (char*)dbCalloc(1,strlen(plastSlash)+1); strcpy(outFilename,plastSlash); pext = strstr(outFilename,".dbd"); if(!pext) { fprintf(stderr,"Input file MUST have .dbd extension\n"); exit(-1); } strcpy(pext,".h"); }else { outFilename = (char*)dbCalloc(1,strlen(argv[2])+1); strcpy(outFilename,argv[2]); } pdbbase = dbAllocBase(); pdbbase->ignoreMissingMenus = TRUE; pdbbase->loadCdefs = TRUE; status = dbReadDatabase(&pdbbase,argv[1],path,sub); if(status) { errlogFlush(); fprintf(stderr, "dbToMenuH: Input errors, no output generated\n"); exit(1); } outFile = fopen(outFilename,"wt"); if(!outFile) { epicsPrintf("Error creating output file \"%s\"\n", outFilename); exit(1); } fprintf(outFile,"/// @file\n/// EPICS DB record definitions\n\n"); pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); while(pdbMenu) { fprintf(outFile,"/// %s EPICS DB menu\n",pdbMenu->name); fprintf(outFile,"enum %s\n{\n", pdbMenu->name); for(i=0; i<pdbMenu->nChoice; i++) { fprintf(outFile,"\t%s",pdbMenu->papChoiceName[i]); if(i < (pdbMenu->nChoice - 1)) fprintf(outFile,","); fprintf(outFile,"\t///< %s", pdbMenu->papChoiceValue[i]); fprintf(outFile,"\n"); } fprintf(outFile,"};\n\n"); pdbMenu = (dbMenu *)ellNext(&pdbMenu->node); } pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); while(pdbRecordType) { fprintf(outFile,"/// %s EPICS DB record\n",pdbRecordType->name); fprintf(outFile,"struct %s\n{\n",pdbRecordType->name); for(i=0; i<pdbRecordType->no_fields; i++) { char name[256]; int j; pdbFldDes = pdbRecordType->papFldDes[i]; for(j=0; j< (int)strlen(pdbFldDes->name); j++) name[j] = pdbFldDes->name[j]; name[strlen(pdbFldDes->name)] = 0; switch(pdbFldDes->field_type) { case DBF_STRING : fprintf(outFile, "\tchar\t\t%s[%d];\t///< %s\n", name, pdbFldDes->size, pdbFldDes->prompt); break; case DBF_CHAR : fprintf(outFile, "\tepicsInt8\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_UCHAR : fprintf(outFile, "\tepicsUInt8\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_SHORT : fprintf(outFile, "\tepicsInt16\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_USHORT : fprintf(outFile, "\tepicsUInt16\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_LONG : fprintf(outFile, "\tepicsInt32\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_ULONG : fprintf(outFile, "\tepicsUInt32\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_FLOAT : fprintf(outFile, "\tepicsFloat32\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_DOUBLE : fprintf(outFile, "\tepicsFloat64\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_MENU : pdbMenu = (dbMenu*)pdbFldDes->ftPvt; if (pdbMenu != NULL) { fprintf(outFile, "\t%s\t%s;\t///< %s\n", pdbMenu->name, name, pdbFldDes->prompt); } else { fprintf(outFile, "\tepicsEnum16\t%s;\t///< %s\n", name, pdbFldDes->prompt); } break; case DBF_ENUM : case DBF_DEVICE : fprintf(outFile, "\tepicsEnum16\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_INLINK : case DBF_OUTLINK : case DBF_FWDLINK : fprintf(outFile, "\tDBLINK\t\t%s;\t///< %s\n", name, pdbFldDes->prompt); break; case DBF_NOACCESS: break; default: fprintf(outFile,"ILLEGAL FIELD TYPE\n"); } } fprintf(outFile,"};\n"); pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node); if(pdbRecordType) fprintf(outFile,"\n"); } fclose(outFile); free((void *)outFilename); return(0); }
int main(int argc,char **argv) { dbMenu *pdbMenu; char *outFilename; char *pext; FILE *outFile; char *plastSlash; int i; int strip; char *path = NULL; char *sub = NULL; int pathLength = 0; int subLength = 0; char **pstr; char *psep; int *len; long status; static char *pathSep = OSI_PATH_LIST_SEPARATOR; static char *subSep = ","; /*Look for options*/ if(argc<2) { fprintf(stderr,"usage: dbToMenu -Idir -Idir file.dbd [outfile]\n"); exit(0); } while((strncmp(argv[1],"-I",2)==0)||(strncmp(argv[1],"-S",2)==0)) { if(strncmp(argv[1],"-I",2)==0) { pstr = &path; psep = pathSep; len = &pathLength; } else { pstr = ⊂ psep = subSep; len = &subLength; } if(strlen(argv[1])==2) { dbCatString(pstr,len,argv[2],psep); strip = 2; } else { dbCatString(pstr,len,argv[1]+2,psep); strip = 1; } argc -= strip; for(i=1; i<argc; i++) argv[i] = argv[i + strip]; } if(argc<2 || (strncmp(argv[1],"-",1)==0)) { fprintf(stderr,"usage: dbToMenu -Idir -Idir file.dbd [outfile]\n"); exit(0); } if (argc==2) { /*remove path so that outFile is created where program is executed*/ plastSlash = strrchr(argv[1],'/'); if(!plastSlash) plastSlash = strrchr(argv[1],'\\'); plastSlash = (plastSlash ? plastSlash+1 : argv[1]); outFilename = dbCalloc(1,strlen(plastSlash)+1); strcpy(outFilename,plastSlash); pext = strstr(outFilename,".dbd"); if (!pext) { fprintf(stderr,"Input file MUST have .dbd extension\n"); exit(-1); } strcpy(pext,".h"); } else { outFilename = dbCalloc(1,strlen(argv[2])+1); strcpy(outFilename,argv[2]); } pdbbase = dbAllocBase(); pdbbase->ignoreMissingMenus = TRUE; status = dbReadDatabase(&pdbbase,argv[1],path,sub); if (status) { errlogFlush(); fprintf(stderr, "dbToMenuH: Input errors, no output generated\n"); exit(1); } outFile = fopen(outFilename, "w"); if (!outFile) { epicsPrintf("Error creating output file \"%s\"\n", outFilename); exit(1); } pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); while(pdbMenu) { fprintf(outFile,"#ifndef INC%sH\n",pdbMenu->name); fprintf(outFile,"#define INC%sH\n",pdbMenu->name); fprintf(outFile,"typedef enum {\n"); for(i=0; i<pdbMenu->nChoice; i++) { fprintf(outFile,"\t%s",pdbMenu->papChoiceName[i]); if(i < (pdbMenu->nChoice - 1)) fprintf(outFile,","); fprintf(outFile,"\n"); } fprintf(outFile,"}%s;\n",pdbMenu->name); fprintf(outFile,"#endif /*INC%sH*/\n",pdbMenu->name); pdbMenu = (dbMenu *)ellNext(&pdbMenu->node); } fclose(outFile); free((void *)outFilename); return(0); }
/* * The body of the command interpreter */ static int iocshBody (const char *pathname, const char *commandLine) { FILE *fp = NULL; const char *filename = NULL; int icin, icout; char c; int quote, inword, backslash; const char *raw = NULL;; char *line = NULL; int lineno = 0; int argc; char **argv = NULL; int argvCapacity = 0; struct iocshRedirect *redirects = NULL; struct iocshRedirect *redirect = NULL; int sep; const char *prompt = NULL; const char *ifs = " \t(),\r"; iocshArgBuf *argBuf = NULL; int argBufCapacity = 0; struct iocshCommand *found; void *readlineContext = NULL; int wasOkToBlock; /* * See if command interpreter is interactive */ if (commandLine == NULL) { if ((pathname == NULL) || (strcmp (pathname, "<telnet>") == 0)) { if ((prompt = envGetConfigParamPtr(&IOCSH_PS1)) == NULL) prompt = "epics> "; } else { fp = fopen (pathname, "r"); if (fp == NULL) { fprintf(epicsGetStderr(), "Can't open %s: %s\n", pathname, strerror (errno)); return -1; } if ((filename = strrchr (pathname, '/')) == NULL) filename = pathname; else filename++; prompt = NULL; } /* * Create a command-line input context */ if ((readlineContext = epicsReadlineBegin(fp)) == NULL) { fprintf(epicsGetStderr(), "Can't allocate command-line object.\n"); if (fp) fclose(fp); return -1; } } /* * Set up redirection */ redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects); if (redirects == NULL) { fprintf(epicsGetStderr(), "Out of memory!\n"); return -1; } /* * Read commands till EOF or exit */ argc = 0; wasOkToBlock = epicsThreadIsOkToBlock(); epicsThreadSetOkToBlock(1); for (;;) { /* * Read a line */ if (commandLine) { if (raw != NULL) break; raw = commandLine; } else { if ((raw = epicsReadline(prompt, readlineContext)) == NULL) break; } lineno++; /* * Skip leading white-space */ icin = 0; while ((c = raw[icin]) && isspace(c)) { icin++; } /* * Ignore comment lines other than to echo * them if they came from a script. This * avoids macLib errors from comments. */ if (c == '#') { if ((prompt == NULL) && (commandLine == NULL)) puts(raw); continue; } /* * Expand macros */ free(line); if ((line = macEnvExpand(raw)) == NULL) continue; /* * Skip leading white-space coming from a macro */ while ((c = line[icin]) && isspace(c)) { icin++; } /* * Echo non-empty lines read from a script */ if ((prompt == NULL) && *line && (commandLine == NULL)) puts(line); /* * Ignore lines that became a comment or empty after macro expansion */ if (!c || c == '#') continue; /* * Break line into words */ icout = 0; inword = 0; argc = 0; quote = EOF; backslash = 0; redirect = NULL; for (;;) { if (argc >= argvCapacity) { char **av; argvCapacity += 50; av = (char **)realloc (argv, argvCapacity * sizeof *argv); if (av == NULL) { fprintf (epicsGetStderr(), "Out of memory!\n"); argc = -1; break; } argv = av; } c = line[icin++]; if (c == '\0') break; if ((quote == EOF) && !backslash && (strchr (ifs, c))) sep = 1; else sep = 0; if ((quote == EOF) && !backslash) { int redirectFd = 1; if (c == '\\') { backslash = 1; continue; } if (c == '<') { if (redirect != NULL) { break; } redirect = &redirects[0]; sep = 1; redirect->mode = "r"; } if ((c >= '1') && (c <= '9') && (line[icin] == '>')) { redirectFd = c - '0'; c = '>'; icin++; } if (c == '>') { if (redirect != NULL) break; if (redirectFd >= NREDIRECTS) { redirect = &redirects[1]; break; } redirect = &redirects[redirectFd]; sep = 1; if (line[icin] == '>') { icin++; redirect->mode = "a"; } else { redirect->mode = "w"; } } } if (inword) { if (c == quote) { quote = EOF; } else { if ((quote == EOF) && !backslash) { if (sep) { inword = 0; line[icout++] = '\0'; } else if ((c == '"') || (c == '\'')) { quote = c; } else { line[icout++] = c; } } else { line[icout++] = c; } } } else { if (!sep) { if (((c == '"') || (c == '\'')) && !backslash) quote = c; if (redirect != NULL) { if (redirect->name != NULL) { argc = -1; break; } redirect->name = line + icout; redirect = NULL; } else { argv[argc++] = line + icout; } if (quote == EOF) line[icout++] = c; inword = 1; } } backslash = 0; } if (redirect != NULL) { showError(filename, lineno, "Illegal redirection."); continue; } if (argc < 0) break; if (quote != EOF) { showError(filename, lineno, "Unbalanced quote."); continue; } if (backslash) { showError(filename, lineno, "Trailing backslash."); continue; } if (inword) line[icout++] = '\0'; argv[argc] = NULL; /* * Special case -- Redirected input but no command * Treat as if 'iocsh filename'. */ if ((argc == 0) && (redirects[0].name != NULL)) { const char *commandFile = redirects[0].name; redirects[0].name = NULL; if (openRedirect(filename, lineno, redirects) < 0) continue; startRedirect(filename, lineno, redirects); iocshBody(commandFile, NULL); stopRedirect(filename, lineno, redirects); continue; } /* * Special command? */ if ((argc > 0) && (strcmp(argv[0], "exit") == 0)) break; /* * Set up redirection */ if ((openRedirect(filename, lineno, redirects) == 0) && (argc > 0)) { /* * Look up command */ found = (iocshCommand *)registryFind (iocshCmdID, argv[0]); if (found) { /* * Process arguments and call function */ struct iocshFuncDef const *piocshFuncDef = found->pFuncDef; for (int iarg = 0 ; ; ) { if (iarg == piocshFuncDef->nargs) { startRedirect(filename, lineno, redirects); (*found->func)(argBuf); break; } if (iarg >= argBufCapacity) { void *np; argBufCapacity += 20; np = realloc (argBuf, argBufCapacity * sizeof *argBuf); if (np == NULL) { fprintf (epicsGetStderr(), "Out of memory!\n"); argBufCapacity -= 20; break; } argBuf = (iocshArgBuf *)np; } if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) { argBuf[iarg].aval.ac = argc-iarg; argBuf[iarg].aval.av = argv+iarg; iarg = piocshFuncDef->nargs; } else { if (!cvtArg (filename, lineno, ((iarg < argc) ? argv[iarg+1] : NULL), &argBuf[iarg], piocshFuncDef->arg[iarg])) break; iarg++; } } if ((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) { const char *newPrompt; if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL) prompt = newPrompt; } } else { showError(filename, lineno, "Command %s not found.", argv[0]); } } stopRedirect(filename, lineno, redirects); } if (fp && (fp != stdin)) fclose (fp); if (redirects != NULL) { stopRedirect(filename, lineno, redirects); free (redirects); } free(line); free (argv); free (argBuf); errlogFlush(); if (readlineContext) epicsReadlineEnd(readlineContext); epicsThreadSetOkToBlock( wasOkToBlock); return 0; }
/* * Tests the log prefix code * The prefix is only applied to log messages as they go out to the socket, * so we need to create a server listening on a port, accept connections etc. * This code is a reduced version of the code in iocLogServer. */ static void testLogPrefix(void) { struct sockaddr_in serverAddr; int status; struct timeval timeout; struct sockaddr_in actualServerAddr; osiSocklen_t actualServerAddrSize; char portstring[16]; testDiag("Testing iocLogPrefix"); timeout.tv_sec = 5; /* in seconds */ timeout.tv_usec = 0; memset((void*)prefixmsgbuffer, 0, sizeof prefixmsgbuffer); /* Clear "errlog: <n> messages were discarded" status */ errlogPrintfNoConsole("."); errlogFlush(); sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { testAbort("epicsSocketCreate failed."); } /* We listen on a an available port. */ memset((void *)&serverAddr, 0, sizeof serverAddr); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(0); status = bind (sock, (struct sockaddr *)&serverAddr, sizeof (serverAddr) ); if (status < 0) { testAbort("bind failed; all ports in use?"); } status = listen(sock, 10); if (status < 0) { testAbort("listen failed!"); } /* Determine the port that the OS chose */ actualServerAddrSize = sizeof actualServerAddr; memset((void *)&actualServerAddr, 0, sizeof serverAddr); status = getsockname(sock, (struct sockaddr *) &actualServerAddr, &actualServerAddrSize); if (status < 0) { testAbort("Can't find port number!"); } sprintf(portstring, "%d", ntohs(actualServerAddr.sin_port)); testDiag("Listening on port %s", portstring); /* Set the EPICS environment variables for logging. */ epicsEnvSet ( "EPICS_IOC_LOG_INET", "localhost" ); epicsEnvSet ( "EPICS_IOC_LOG_PORT", portstring ); pfdctx = (void *) fdmgr_init(); if (status < 0) { testAbort("fdmgr_init failed!"); } status = fdmgr_add_callback(pfdctx, sock, fdi_read, acceptNewClient, &serverAddr); if (status < 0) { testAbort("fdmgr_add_callback failed!"); } testOk1(iocLogInit() == 0); fdmgr_pend_event(pfdctx, &timeout); testPrefixLogandCompare(prefixactualmsg[0]); iocLogPrefix(prefixstring); testPrefixLogandCompare(prefixactualmsg[1]); testPrefixLogandCompare(prefixactualmsg[2]); epicsSocketDestroy(sock); }
epicsStatus mrmEvgSetupPCI ( const char* id, // Card Identifier int b, // Bus number int d, // Device number int f, // Function number bool ignoreVersion) // Ignore errors due to kernel module and firmware version checks { deviceInfoT deviceInfo; deviceInfo.bus.busType = busType_pci; deviceInfo.bus.pci.bus = b; deviceInfo.bus.pci.device = d; deviceInfo.bus.pci.function = f; deviceInfo.series = series_unknown; try { if (mrf::Object::getObject(id)) { errlogPrintf("ID %s already in use\n", id); return -1; } if(checkUIOVersion(1) > 0) { // check if kernel version is successfully read and is as expected or higher, and if it can be read at all. if(ignoreVersion){ epicsPrintf("Ignoring kernel module error.\n"); } else{ return -1; } } /* Find PCI device from devLib2 */ const epicsPCIDevice *cur = 0; if (devPCIFindBDF(mrmevgs, b, d, f, &cur, 0)) { errlogPrintf("PCI Device not found on %x:%x.%x\n", b, d, f); return -1; } epicsPrintf("Device %s %x:%x.%x\n", id, cur->bus, cur->device, cur->function); epicsPrintf("Using IRQ %u\n", cur->irq); /* MMap BAR0(plx) and BAR2(EVG)*/ volatile epicsUInt8 *BAR_plx, *BAR_evg; // base addressed for plx/evg bars if (devPCIToLocalAddr(cur, 0, (volatile void**) (void *) &BAR_plx, 0) || devPCIToLocalAddr(cur, 2, (volatile void**) (void *) &BAR_evg, 0)) { errlogPrintf("Failed to map BARs 0 and 2\n"); return -1; } if (!BAR_plx || !BAR_evg) { errlogPrintf("BARs mapped to zero? (%08lx,%08lx)\n", (unsigned long) BAR_plx, (unsigned long) BAR_evg); return -1; } //Set LE mode on PLX bridge //TODO: this limits cPCI EVG device support to LE architectures // At this point in time we do not have any BE PCI systems at hand so this is left as // unsported until we HW to test it on... epicsUInt32 plxCtrl = LE_READ32(BAR_plx,LAS0BRD); plxCtrl = plxCtrl & ~LAS0BRD_ENDIAN; LE_WRITE32(BAR_plx,LAS0BRD,plxCtrl); epicsUInt32 version = checkVersion(BAR_evg, 0x3); epicsPrintf("Firmware version: %08x\n", version); if(version == 0) { if(ignoreVersion) { epicsPrintf("Ignoring version error.\n"); } else { return -1; } } evgMrm* evg = new evgMrm(id, deviceInfo, BAR_evg, 0, cur); evg->getSeqRamMgr()->getSeqRam(0)->disable(); evg->getSeqRamMgr()->getSeqRam(1)->disable(); /*Disable the interrupts and enable them at the end of iocInit via initHooks*/ WRITE32(BAR_evg, IrqFlag, READ32(BAR_evg, IrqFlag)); WRITE32(BAR_evg, IrqEnable, 0); /* * Enable active high interrupt1 through the PLX to the PCI bus. */ // LE_WRITE16(BAR_plx, INTCSR, INTCSR_INT1_Enable| INTCSR_INT1_Polarity| INTCSR_PCI_Enable); if(ignoreVersion){ epicsPrintf("Not enabling interrupts.\n"); } else { if(devPCIEnableInterrupt(cur)) { errlogPrintf("Failed to enable interrupt\n"); return -1; } } #ifdef __linux__ evg->isrLinuxPvt = (void*) cur; #endif /*Connect Interrupt handler to isr thread*/ if(ignoreVersion){ epicsPrintf("Not connecting interrupts.\n"); } else { if (devPCIConnectInterrupt(cur, &evgMrm::isr_pci, (void*) evg, 0)) {//devConnectInterruptVME(irqVector & 0xff, &evgMrm::isr, evg)){ errlogPrintf("ERROR:Failed to connect PCI interrupt\n"); delete evg; return -1; } else { epicsPrintf("PCI interrupt connected!\n"); } } } catch (std::exception& e) { errlogPrintf("Error: %s\n", e.what()); errlogFlush(); return -1; } return 0; } //mrmEvgSetupPCI
epicsStatus mrmEvgSetupVME ( const char* id, // Card Identifier epicsInt32 slot, // VME slot epicsUInt32 vmeAddress, // Desired VME address in A24 space epicsInt32 irqLevel, // Desired interrupt level epicsInt32 irqVector, // Desired interrupt vector number bool ignoreVersion) // Ignore errors due to firmware checks { volatile epicsUInt8* regCpuAddr = 0; volatile epicsUInt8* regCpuAddr2 = 0; //function 2 of regmap (fanout/concentrator specifics) struct VMECSRID info; deviceInfoT deviceInfo; info.board = 0; info.revision = 0; info.vendor = 0; deviceInfo.bus.busType = busType_vme; deviceInfo.bus.vme.slot = slot; deviceInfo.bus.vme.address = vmeAddress; deviceInfo.bus.vme.irqLevel = irqLevel; deviceInfo.bus.vme.irqVector = irqVector; deviceInfo.series = series_unknown; int status; // a variable to hold function return statuses try { if(mrf::Object::getObject(id)){ errlogPrintf("ID %s already in use\n",id); return -1; } volatile unsigned char* csrCpuAddr; // csrCpuAddr is VME-CSR space CPU address for the board csrCpuAddr = //devCSRProbeSlot(slot); devCSRTestSlot(vmeEvgIDs,slot,&info); //FIXME: add support for EVM id if(!csrCpuAddr) { errlogPrintf("No EVG in slot %d\n",slot); return -1; } epicsPrintf("##### Setting up MRF EVG in VME Slot %d #####\n",slot); epicsPrintf("Found Vendor: %08x\nBoard: %08x\nRevision: %08x\n", info.vendor, info.board, info.revision); epicsUInt32 xxx = CSRRead32(csrCpuAddr + CSR_FN_ADER(1)); if(xxx) epicsPrintf("Warning: EVG not in power on state! (%08x)\n", xxx); /*Setting the base address of Register Map on VME Board (EVG)*/ CSRSetBase(csrCpuAddr, 1, vmeAddress, VME_AM_STD_SUP_DATA); { epicsUInt32 temp=CSRRead32((csrCpuAddr) + CSR_FN_ADER(1)); if(temp != CSRADER((epicsUInt32)vmeAddress,VME_AM_STD_SUP_DATA)) { errlogPrintf("Failed to set CSR Base address in ADER1. Check VME bus and card firmware version.\n"); return -1; } } /* Create a static string for the card description (needed by vxWorks) */ char *Description = allocSNPrintf(40, "EVG-%d '%s' slot %d", info.board & MRF_BID_SERIES_MASK, id, slot); /*Register VME address and get corresponding CPU address */ status = devRegisterAddress ( Description, // Event Generator card description atVMEA24, // A24 Address space vmeAddress, // Physical address of register space EVG_REGMAP_SIZE, // Size of card's register space (volatile void **)(void *)®CpuAddr // Local address of card's register map ); if(status) { errlogPrintf("Failed to map VME address %08x\n", vmeAddress); return -1; } epicsUInt32 version = checkVersion(regCpuAddr, 0x3); epicsPrintf("Firmware version: %08x\n", version); if(version == 0){ if(ignoreVersion) { epicsPrintf("Ignoring version error.\n"); } else { return -1; } } /* Set the base address of Register Map for function 2, if we have the right firmware version */ if(version >= EVG_FCT_MIN_FIRMWARE) { deviceInfo.series = series_300; CSRSetBase(csrCpuAddr, 2, vmeAddress+EVG_REGMAP_SIZE, VME_AM_STD_SUP_DATA); { epicsUInt32 temp=CSRRead32((csrCpuAddr) + CSR_FN_ADER(2)); if(temp != CSRADER((epicsUInt32)vmeAddress+EVG_REGMAP_SIZE,VME_AM_STD_SUP_DATA)) { epicsPrintf("Failed to set CSR Base address in ADER2 for FCT register mapping. Check VME bus and card firmware version.\n"); return -1; } } /* Create a static string for the card description (needed by vxWorks) */ char *Description = allocSNPrintf(40, "EVG-%d FOUT'%s' slot %d", info.board & MRF_BID_SERIES_MASK, id, slot); status = devRegisterAddress ( Description, // Event Generator card description atVMEA24, // A24 Address space vmeAddress+EVG_REGMAP_SIZE, // Physical address of register space EVG_REGMAP_SIZE*2, // Size of card's register space (volatile void **)(void *)®CpuAddr2 // Local address of card's register map ); if(status) { errlogPrintf("Failed to map VME address %08x for FCT mapping\n", vmeAddress); return -1; } } else { deviceInfo.series = series_230; } evgMrm* evg = new evgMrm(id, deviceInfo, regCpuAddr, regCpuAddr2, NULL); if(irqLevel > 0 && irqVector >= 0) { /*Configure the Interrupt level and vector on the EVG board*/ CSRWrite8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_LEVEL, irqLevel&0x7); CSRWrite8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_VECTOR, irqVector&0xff); epicsPrintf("IRQ Level: %d\nIRQ Vector: %d\n", CSRRead8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_LEVEL), CSRRead8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_VECTOR) ); epicsPrintf("csrCpuAddr : %p\nregCpuAddr : %p\nreCpuAddr2 : %p\n",csrCpuAddr, regCpuAddr, regCpuAddr2); /*Disable the interrupts and enable them at the end of iocInit via initHooks*/ WRITE32(regCpuAddr, IrqFlag, READ32(regCpuAddr, IrqFlag)); WRITE32(regCpuAddr, IrqEnable, 0); // VME IRQ level will be enabled later during iocInit() vme_level_mask |= 1 << ((irqLevel&0x7)-1); /*Connect Interrupt handler to vector*/ if(devConnectInterruptVME(irqVector & 0xff, &evgMrm::isr_vme, evg)){ errlogPrintf("ERROR:Failed to connect VME IRQ vector %d\n" ,irqVector&0xff); delete evg; return -1; } } } catch(std::exception& e) { errlogPrintf("Error: %s\n",e.what()); errlogFlush(); return -1; } errlogFlush(); return 0; } //mrmEvgSetupVME
int main(int argc,char **argv) { int i; char *outFilename; char *pext; FILE *outFile; dbMenu *pdbMenu; dbRecordType *pdbRecordType; dbFldDes *pdbFldDes; dbText *pdbCdef; int isdbCommonRecord = FALSE; char *plastSlash; int strip; char *path = NULL; char *sub = NULL; int pathLength = 0; int subLength = 0; char **pstr; char *psep; int *len; long status; static char *pathSep = OSI_PATH_LIST_SEPARATOR; static char *subSep = ","; /*Look for options*/ if(argc<2) { fprintf(stderr,"usage: dbToRecordtypeH -Idir -Idir file.dbd [outfile]\n"); exit(0); } while((strncmp(argv[1],"-I",2)==0)||(strncmp(argv[1],"-S",2)==0)) { if(strncmp(argv[1],"-I",2)==0) { pstr = &path; psep = pathSep; len = &pathLength; } else { pstr = ⊂ psep = subSep; len = &subLength; } if(strlen(argv[1])==2) { dbCatString(pstr,len,argv[2],psep); strip = 2; } else { dbCatString(pstr,len,argv[1]+2,psep); strip = 1; } argc -= strip; for(i=1; i<argc; i++) argv[i] = argv[i + strip]; } if(argc<2 || (strncmp(argv[1],"-",1)==0)) { fprintf(stderr,"usage: dbToRecordtypeH -Idir -Idir file.dbd [outfile]\n"); exit(0); } if(argc==2){ /*remove path so that outFile is created where program is executed*/ plastSlash = strrchr(argv[1],'/'); if(!plastSlash) plastSlash = strrchr(argv[1],'\\'); plastSlash = (plastSlash ? plastSlash+1 : argv[1]); outFilename = dbCalloc(1,strlen(plastSlash)+1); strcpy(outFilename,plastSlash); pext = strstr(outFilename,".dbd"); if(!pext) { fprintf(stderr,"Input file MUST have .dbd extension\n"); exit(-1); } strcpy(pext,".h"); if(strcmp(outFilename,"dbCommonRecord.h")==0) { strcpy(outFilename,"dbCommon.h"); isdbCommonRecord = TRUE; } }else { outFilename = dbCalloc(1,strlen(argv[2])+1); strcpy(outFilename,argv[2]); if(strstr(outFilename,"dbCommon.h")!=0) { isdbCommonRecord = TRUE; } } pdbbase = dbAllocBase(); pdbbase->ignoreMissingMenus = TRUE; pdbbase->loadCdefs = TRUE; status = dbReadDatabase(&pdbbase,argv[1],path,sub); if(status) { errlogFlush(); fprintf(stderr, "dbToMenuH: Input errors, no output generated\n"); exit(1); } outFile = fopen(outFilename,"w"); if(!outFile) { epicsPrintf("Error creating output file \"%s\"\n", outFilename); exit(1); } pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); while(pdbMenu) { fprintf(outFile,"\n#ifndef INC%sH\n",pdbMenu->name); fprintf(outFile,"#define INC%sH\n",pdbMenu->name); fprintf(outFile,"typedef enum {\n"); for(i=0; i<pdbMenu->nChoice; i++) { fprintf(outFile,"\t%s",pdbMenu->papChoiceName[i]); if(i < (pdbMenu->nChoice - 1)) fprintf(outFile,","); fprintf(outFile,"\n"); } fprintf(outFile,"}%s;\n",pdbMenu->name); fprintf(outFile,"#endif /*INC%sH*/\n",pdbMenu->name); pdbMenu = (dbMenu *)ellNext(&pdbMenu->node); } pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); while(pdbRecordType) { fprintf(outFile,"#ifndef INC%sH\n",pdbRecordType->name); fprintf(outFile,"#define INC%sH\n",pdbRecordType->name); pdbCdef = (dbText *)ellFirst(&pdbRecordType->cdefList); while (pdbCdef) { fprintf(outFile,"%s\n",pdbCdef->text); pdbCdef = (dbText *)ellNext(&pdbCdef->node); } fprintf(outFile,"typedef struct %s",pdbRecordType->name); if(!isdbCommonRecord) fprintf(outFile,"Record"); fprintf(outFile," {\n"); for(i=0; i<pdbRecordType->no_fields; i++) { char name[256]; int j; pdbFldDes = pdbRecordType->papFldDes[i]; for(j=0; j< (int)strlen(pdbFldDes->name); j++) name[j] = tolower(pdbFldDes->name[j]); name[strlen(pdbFldDes->name)] = 0; switch(pdbFldDes->field_type) { case DBF_STRING : fprintf(outFile, "\tchar\t\t%s[%d];\t/* %s */\n", name, pdbFldDes->size, pdbFldDes->prompt); break; case DBF_CHAR : fprintf(outFile, "\tepicsInt8\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_UCHAR : fprintf(outFile, "\tepicsUInt8\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_SHORT : fprintf(outFile, "\tepicsInt16\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_USHORT : fprintf(outFile, "\tepicsUInt16\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_LONG : fprintf(outFile, "\tepicsInt32\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_ULONG : fprintf(outFile, "\tepicsUInt32\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_FLOAT : fprintf(outFile, "\tepicsFloat32\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_DOUBLE : fprintf(outFile, "\tepicsFloat64\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_ENUM : case DBF_MENU : case DBF_DEVICE : fprintf(outFile, "\tepicsEnum16\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_INLINK : case DBF_OUTLINK : case DBF_FWDLINK : fprintf(outFile, "\tDBLINK\t\t%s;\t/* %s */\n", name, pdbFldDes->prompt); break; case DBF_NOACCESS: fprintf(outFile, "\t%s;\t/* %s */\n", pdbFldDes->extra, pdbFldDes->prompt); break; default: fprintf(outFile,"ILLEGAL FIELD TYPE\n"); } } fprintf(outFile,"} %s",pdbRecordType->name); if(!isdbCommonRecord) fprintf(outFile,"Record"); fprintf(outFile,";\n"); if(!isdbCommonRecord) { for(i=0; i<pdbRecordType->no_fields; i++) { pdbFldDes = pdbRecordType->papFldDes[i]; fprintf(outFile,"#define %sRecord%s\t%d\n", pdbRecordType->name,pdbFldDes->name,pdbFldDes->indRecordType); } } fprintf(outFile,"#endif /*INC%sH*/\n",pdbRecordType->name); pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node); if(pdbRecordType) fprintf(outFile,"\n"); } if(!isdbCommonRecord) { fprintf(outFile,"#ifdef GEN_SIZE_OFFSET\n"); fprintf(outFile,"#ifdef __cplusplus\n"); fprintf(outFile,"extern \"C\" {\n"); fprintf(outFile,"#endif\n"); fprintf(outFile,"#include <epicsExport.h>\n"); pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); while(pdbRecordType) { fprintf(outFile,"static int %sRecordSizeOffset(dbRecordType *pdbRecordType)\n{\n", pdbRecordType->name); fprintf(outFile," %sRecord *prec = 0;\n",pdbRecordType->name); for(i=0; i<pdbRecordType->no_fields; i++) { char name[256]; int j; pdbFldDes = pdbRecordType->papFldDes[i]; for(j=0; j< (int)strlen(pdbFldDes->name); j++) name[j] = tolower(pdbFldDes->name[j]); name[strlen(pdbFldDes->name)] = 0; fprintf(outFile, " pdbRecordType->papFldDes[%d]->size=sizeof(prec->%s);\n", i,name); fprintf(outFile," pdbRecordType->papFldDes[%d]->offset=",i); fprintf(outFile, "(short)((char *)&prec->%s - (char *)prec);\n",name); } fprintf(outFile," pdbRecordType->rec_size = sizeof(*prec);\n"); fprintf(outFile," return(0);\n"); fprintf(outFile,"}\n"); fprintf(outFile,"epicsExportRegistrar(%sRecordSizeOffset);\n", pdbRecordType->name); pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node); } fprintf(outFile,"#ifdef __cplusplus\n"); fprintf(outFile,"}\n"); fprintf(outFile,"#endif\n"); fprintf(outFile,"#endif /*GEN_SIZE_OFFSET*/\n"); } fclose(outFile); free((void *)outFilename); return(0); }