EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Problems using static database routines to modify IOCs
From: [email protected]
To: "Andrew Johnson" <[email protected]>
Cc: "[email protected]" <[email protected]>, EPICS <[email protected]>
Date: Fri, 1 May 2015 17:59:05 -0500
Hello Andrew and Tim,

Ok here's what I am attempting to do.

The goal is at IOC startup after initialization to be able to compare a
set of channel values with a saved set of values, so that any differences
can be investigated.

The IOC I am tying to modify is running on a Windows 7 computer and I'm
using Visual Studio 2012 update 4.

The first step in this was to modify the Windows IOC so that it would
perform a database dump to standard output right before the ioc shell is
invoked. This was really just to get some experience modifying and working
with IOC code.

So I took the iocMain.cpp and literally copied the dbDumpRecords example
function at the end of the EPICS application developer's guide, chapter
14.16.2. After adding that function prototype and the function to the
iocMain.cpp, I am trying to call the function in main() right before the
iocsh(NULL) call.

Everything compiles ok but I am clearly not pointing to the right place
since I get garbage plus the IOC crashes. The only way it works was to
load a second instance of the database into memory which you are right is
not what I want to do.

Here is the iocMain.cpp code,



#include "epicsExit.h"
#include "epicsThread.h"
#include "iocsh.h"
#include <ctime>
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbDefs.h"
#include "dbFldTypes.h"
#include "link.h"

extern "C" {
__declspec(dllimport) void stopPLCs(void);
}

// Function proto types ************************************************

void dbDumpRecords(DBBASE *);					// code I added <---------------------

// Function definitions ************************************************

// code I added here
<--------------------------------------------------------------------------------

void dbDumpRecords(DBBASE *pdbbase)
{
	DBENTRY *pdbentry;
	long status;

	mypdbentry = dbAllocEntry(pdbbase);

	status = dbFirstRecordType(pdbentry);
	if(status) {printf("No record descriptions\n");return;}
	while(!status) {
		printf("\nRecord type: %s",dbGetRecordTypeName(pdbentry));
		status = dbFirstRecord(pdbentry);
		if(status) printf("   No Records\n");
		while(!status) {
			if (dbIsAlias(pdbentry)) {
				printf("\n  Alias: %s\n",dbGetRecordName(pdbentry));
			} else {
			printf("\n  Record: %s\n",dbGetRecordName(pdbentry));
			status = dbFirstField(pdbentry,TRUE);
				if(status) printf("    No Fields\n");
			while(!status) {
				printf("   %s:",dbGetFieldName(pdbentry));
				printf(" %s\n",dbGetString(pdbentry));	     // <-- if I comment out
dbGetString the IOC doesn't crash,
				status=dbNextField(pdbentry,TRUE);           // so the function works
to this point
				}
			}
			status = dbNextRecord(pdbentry);
		}
		status = dbNextRecordType(pdbentry);
	}

	printf("\nEnd of all Records\n");

	dbFreeEntry(pdbentry);
}
// end of function that I added
<---------------------------------------------------------------------

// Time the initialization process
clock_t begin;
clock_t end;

/** @file iocMain.cpp
	The main program for the TwinCAT IOC.
 ************************************************************************/


bool debug;

int main(int argc,char *argv[])
{
	// Start timer
	begin = clock();

	// Run initialization
	if(argc>=2) {
        iocsh(argv[1]);
        epicsThreadSleep(.2);
    }

	// Stop timer
	end = clock();
	printf("Initialization completed in %f seconds.\n",((float)(end -
begin)/CLOCKS_PER_SEC));


	// Test routine
******************************************************************

	// code I added
<---------------------------------------------------------------------------------

	printf("\nRecords dump **********************\n");

	dbDumpRecords(*iocshPpdbbase);    // Trying to call function here!

	// end of code that I added
<---------------------------------------------------------------------

	// EPICS command line
	iocsh(NULL);

	// Exit
	stopPLCs();
    epicsExit(0);

	return(0);
}

To do a value comparison I think I'll need to use the runtime access
routines in addition to some of the static routines. But at this point I'm
not sure of anything. I have been trying to understand and copy code from
the functions in dbtools.c and dbStaticLib.c but so far nothing has worked
for me.

I'm sorry to be such a problem, been staring at this for four weeks now
and am at my wits end.

Thank you in advance,

Doug Lormand

> Hi Doug,
>
>> The system is a Windows 7 computer! Unfortunately I need this to work in
>> Windows because the software we use the IOC for is only Windows based.
>> Thank you for pointing this out since I hadn't considered it could be a
>> Windows compatibility issue. The ultimate goal is to use database access
>> to compare values at boot up with a set of stored 'good' values. I think
>> this will require the runtime database access routines which I've had
>> some
>> success with so far. So in the end I'm hoping this might be a non issue.
>
> Doing this on Windows should not be a problem. To clarify, you're
> wanting to compare these values *before* the IOC runs iocInit()?
>
>>>> I have been able to get the example code to work within the IOC I'm
>>>> trying
>>>> to modify, but in a round about way. It is some type of pointer
>>>> problem
>>>> but I'm not sure what's wrong.
>>>>
>>>> So the code works if I add the following,
>>>>
>>>> void dbDumpRecords(DBBASE *pdbbase)
>>>> {
>>>>          DBENTRY *pdbentry;
>>>>      long status;
>>>>
>>>>      status =
>>>> dbReadDatabase(&pdbbase,"C:\\SlowControls\\EPICS\\Utilities\\Bin\\tCat.dbd",NULL,NULL);
>>>>      if(!status) {printf("Database file loaded.\n");}
>>>>      else {printf("Database load file failed.\n");}
>>>>
>>>>      status =
>>>> dbReadDatabase(&pdbbase,"C:\\SlowControls\\EPICS\\Utilities\\Bin\\test.db",NULL,NULL);
>>>>      if(!status) {printf("Records file loaded.\n\n");}
>>>>      else {printf("Records load file failed.\n\n");}
>>>>
>>>>          pdbentry = dbAllocEntry(pdbbase);
>>>> .......rest of dump routine
>>>>
>>>> So the dump routine runs perfectly if I include dbReadDatabase
>>>> routines
>>>> for both the database.dbd and records.db files.
>
> What that is doing is loading a second instance of the database
> definition into memory, which is not what you want to do.
>
>>>> What I don't understand is why I need to Read the databases into the
>>>> function separately from the IOCs initialization. I thought I could
>>>> access the runtime database in memory through pdbbase.
>
> You should be able to, so the fact that you're having problems tells me
> that the pdbbase pointer that your code is using is not the same one
> that the IOC is using. The dbStatic library is designed to allow
> multiple databases to be loaded into memory at once, but the IOC can
> only run one, which is declared in the header dbAccessDefs.h (also
> included by dbAccess.h).
>
>>>>>> The code solution compiles without any issues but when I try to run
>>>>>> the
>>>> IOC it causes the following
>>>>>> Unhandled exception at 0x5C6F1C6E (dbStaticHost.dll) in tcIoc.exe:
>>>> 0xC0000005: Access violation reading location 0x00000031.
>
> That might have been that you were accessing iocshPpdbbase or pdbbase
> before it was initialized. I'd need to see your iocMain.c to be sure,
> but in general you should be running this kind of code from the startup
> script using a command that your code registers with iocsh, or from an
> initHook. That way it can be run at the right time, which would be after
> the dbLoadDatabase() and dbLoadRecords() commands but before iocInit()
> starts up the database operations.
>
>
> Lets try starting from the beginning again: You're wanting to "compare
> values at boot up with a set of stored 'good' values". As Tim said there
> are some fields (mostly array fields) for which you can only do that
> from an initHook as part of the IOC startup, but for most fields you can
> do it earlier, as long as the database definition and record instances
> have been loaded first.
>
> How & when are you running your code?
>
> - Andrew
>
> --
> Light thinks it travels faster than anything but it is wrong.
> No matter how fast light travels, it finds the darkness has
> always got there first, and is waiting for it.
>     -- Terry Pratchett, Reaper Man
>



Replies:
RE: Problems using static database routines to modify IOCs Mooney, Tim M.
RE: Problems using static database routines to modify IOCs freddie.akeroyd
References:
Re: Problems using static database routines to modify IOCs Dirk Zimoch
Re: Problems using static database routines to modify IOCs marc . lormand
RE: Problems using static database routines to modify IOCs Mooney, Tim M.
Re: Problems using static database routines to modify IOCs Andrew Johnson

Navigate by Date:
Prev: Re: Problems using static database routines to modify IOCs Andrew Johnson
Next: RE: Problems using static database routines to modify IOCs Mooney, Tim M.
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Problems using static database routines to modify IOCs Andrew Johnson
Next: RE: Problems using static database routines to modify IOCs Mooney, Tim M.
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 16 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·