On 12/01/2017 10:40 AM, Mark Rivers wrote:
>> I don't want to encourage this usage which is why I've never
> documented it myself,
> Can you explain what you mean by "this usage"? You mean relying
> on the fact that dbGetLink establishes monitor on CA links for
> both input and output?
I mean expecting any DBF_OUTLINK field to be able to get data or any
DBF_INLINK field to be able to put data (the latter is more common in
subroutine records which pre-dated the introduction of the aSub record
type). The precise mechanism by which the data gets transferred through
a link ("establishes a monitor...") is a detail of the particular link
type. The dbGetLink() routine is now generic and just calls a method
provided by the link type. The particular link type used is controlled
by the database designer's value for that field.
Calls to dbGetLink(), dbPutLink() or almost any of the other routines
now declared in dbLink.h (previously in dbAccess.h, which now includes
that header) may return an error if the link field's value can't be
resolved into a specific link type, or if the link type doesn't
implement that particular method.
For example the calc link type that was added to Base-3.16.1 quite
reasonably doesn't implement the method called by dbPutLink(), so a
database designer can cause any output soft device support to get an
error from its call to dbPutLink() just by putting a calc link on an OUT
field. I haven't looked to see what will happen...
> The problem is that the Developer's Guide is currently just silent on
> the topic, but it is important.
> It currently says the following:
> - At IOC initialization, dbCa issues channel access search requests
> for each channel access link.
> - For each input link it establishes a channel access monitor, using
> the channel’s native field type and element count. It also monitors
> the alarm status. Whenever the monitor callback gets invoked the new
> data is stored in a buffer belonging to dbCa. When iocCore or the
> record support module asks for data from the link, the contents
> of the buffer are converted to the requested type.
> - For each output link, a buffer is allocated the first time
> iocCore/record support issues a put after the channel access
> connection has been made. This buffer is allocated large enough to
> store the channel’s native field type and element count. Each time
> iocCore/record support issues a put, the data is converted and
> placed in the buffer and a request is made to dbCa to issue a new
> This provides no information how dbGetLink will work on output links,
> leading to the question I posted. Why not say that it also
> establishes monitors on output links?
Ok, looking at the code in dbCa.c any DBF_INLINK will get its monitor
created automatically when the channel connects. A DBF_OUTLINK that
calls dbGetLink() will only set up the monitor the first time it does
that call after the channel has connected. In both cases though the
record will go into LINK/INVALID alarm when dbGetLink() is called until
the first monitor value has been received.
Thus the above descriptions are essentially correct but incomplete.
Internally the dbCa code doesn't actually handle DBF_INLINK and
DBF_OUTLINK fields diferently, other than that automatic subscription
> This question was prompted by the recent thread on the EPID record
> (http://www.aps.anl.gov/epics/tech-talk/2017/msg01863.php). I was
> wondering whether the "bump" that was being seen could be caused by
> dbGetLink not working for the output link if it was CA. It sounds
> from your description like that should not be a problem, as long as
> it was not the first time that dbGetLink was called for that link.
> But if I had known how it works I would have done a dbGetLink at
> iocInit to be sure it did not fail the first time.
You can't guarantee that the link is connected (or that you have read
access to it, or that the value received from it can be represented as a
double, or ...), so your code that calls dbGetLink() always needs to
look at the return status it gets back anyway.
I don't think calling dbGetLink() from the rset::init_record() routine
will work anyway, the link has to be connected for the monitoring to be
set up, and the dbCa subsystem doesn't get fully started until after the
second phase of record initialization anyway. Sorry!
These complexities all contribute to why I haven't spent time trying to
document the behaviour more precisely (I didn't write the code or the
wording in the AppDevGuide) and why I don't want to encourage people to
write code that does gets through output links or puts through input links.
Arguing for surveillance because you have nothing to hide is no
different than making the claim, "I don't care about freedom of
speech because I have nothing to say." -- Edward Snowdon
- dbGetLink question Mark Rivers
- Re: dbGetLink question Andrew Johnson
- RE: dbGetLink question Mark Rivers
- Navigate by Date:
RE: Andor shamrock not detected Mark Rivers
Re: Andor shamrock not detected Hinko Kocevar
- Navigate by Thread:
RE: dbGetLink question Mark Rivers
Andor shamrock not detected Hinko Kocevar