Hi Andrew,
Thank you for asking and sorry for the inconvenience.
My answer is two-fold, one being general and the other more specific. The first part is that after using EPICS for almost a year now, I am now curious about the API and hope to leverage its capabilities for future work that may arise in
my project at LLNL. I enjoy utilizing functions that are already available rather than having to duplicate work, which would lead to longer and unnecessary development time.
The second part is that I am effectively wanting to create a way of parsing record instance files, replacing the macros with the appropriate text, and storing that information in my documentation. Ideally, I would like to update that documentation
with the most recent record instances every time I run make. My goal was to use dbNextRecord, dbGetRecordName, etc. to do that, however I encountered some issues with DBBASE.
Thanks,
Andy
Hi Andy,
Are you trying to create your own program to edit or create db files? If you could explain what you want to do you might get better answers for your overall goal instead of our just pointing you to the path to another local maximum which might not get you
to where you're trying to get. We have not been updating the AppDevGuide for quite a few years now and it is now getting very out of date, although the reference sections are mostly still applicable.
To answer your specific issue, yes you need to define a record type before you can load or create an instance of it using the dbStatic API, usually by loading a DBD file. If you wanted to set the DTYP field of that ao record, you would also need to have
loaded the device() definition which provides the specific choice for the ao record type. This requirement to define before use applies to any objects that the dbStatic API can manipulate.
Unfortunately I may have misled you earlier — it is no longer easy to use recent versions of this code outside of the IOC. Earlier versions of the library had two implementations of the routines that read and write record field values, one for the IOC to
use, and one for design tools that implemented record instances as an array of strings, one for each field. The IOC implementation is the only one left in Base now, and it requires that the structure of the record type (i.e. the sizes and offsets to all of
its fields) be known before a record instance can be created.
The size & offset data is provided by the record type's implementation in a routine which is emitted into the generated *Record.h header file; for the ao record it's called aoRecordSizeOffset() and is run by the registrar routine. That means you can't write
a generic application which can manipulate any record type using the dbStatic API, your code must have been linked with object files compiled for each of the record types you want to load.
The code fragments given in the (now old and not replaced) AppDevGuide haven't been updated or tested in a very long time, and they don't provide the full picture or the current status of the code. I think they could be made to work if you ran them inside
a suitably initialized IOC, but the dbStatic API isn't the best way to manipulate DBD and DB files any more.
So, what are you trying to accomplish? The community can probably help you (there are newer ways to create DB files programmatically), but we need to see the bigger picture to give you suitable advice.
- Andrew
On 2/2/22 4:27 PM, Wang, Andrew wrote:
HI Andrew,
Thank you for your insight! Seeing dbReadDatabase being used in dbLoadRecords and dbLoadDatabase did help elucidate some of my confusion.
I tried to run the sample Expand Include code listed in page 213 and page 214, however I am presented with the following message.
Record "test" is of unknown type "ao"
Error at or before ")" in path "." file "test.db" line 1
I have a simple record called test, which is an analog output record. Do I need to register the record type “ao”?
Thanks,
Andy
Hi Andy,
On Jan 31, 2022, at 1:53 AM, Wang, Andrew via Tech-talk <tech-talk at aps.anl.gov> wrote:
I have a quick question regarding dbReadDatabase. Based upon my understanding, it seems that it is meant for loading a file containing database definitions, which I presume comes from files with a .dbd extension. However, in Chapter 14.16.1,
I noticed that one of the lines of code seems to imply that we can pass .db files into the arguments of dbReadDatabase. I was wondering if that is a typo.
No, both dbReadDatabase() can be used to read either type of file, the IOC has a single parser which handles all of the syntax described in the database definition chapter 6.2.
Additionally, I am a bit curious about how to utilize some of the functions pertaining to record instances. For instance, dbGetNRecords allows us to get the number of record instances for the record type that DBENTRY references. However,
I can’t locate a function that allows me to pass a filename to a record instance file with all the record instances within it.
The dbStaticLib API was designed for writing tools to manipulate databases as well as for internal use by the IOC, and it doesn’t encompass everything you need, look at the dbAccessDefs.h header for the dbLoadDatabase() and dbLoadRecords()
functions (AppDev chapter 6.10) for instance. Those functions both call dbReadDatabase() to do the actual parsing.
Complexity comes for free, simplicity you have to work for.
--
Complexity comes for free, Simplicity you have to work for.