I had a similar problem, and solved it by using a scan task to trigger processing of the record whose operation could not work until channel access was up. (EPICS starts scan tasks after channel access.) Here's a code fragment from the table_soft.vdb database
in the synApps optics module:
initLastMotor processes once, after channel access is up, and then sets its SCAN field to "Passive"
# Strategy: We need to find out when all motors have finished executing a move
# that we started. To do this without a race condition, we set a gate PV to
# "open", write to motors, and then have the last motor written to set the gate
# PV to "closed" when it finishes. But we don't know which motor will be the
# last motor written to, because the table record can work with fewer than six
# motors, and we don't know which motors don't actually exist.
# $(P)$(Q):lastMotor figures this out at init time.
# Evidently, $(P)$(Q):lastMotor's PINI==RUNNING field isn't getting
# $(P)$(Q):closeGate.INPA initialized. This seems bulletproof.
record(scalcout, "$(P)$(Q):initLastMotor") {
#field(TPRO, "1")
field(SCAN, "10 second")
# Note that this must be a CA link so it can read a link field
field(INAA, "$(P)$(Q):closeGate.INPA CA")
field(CALC, "aa==''")
field(OOPT, "When Zero")
field(DOPT, "Use OCAL")
field(OCAL, "'Passive'")
field(OUT, "$(P)$(Q):initLastMotor.SCAN CA")
field(FLNK, "$(P)$(Q):lastMotor")
}
# Find the last motor that will be written to. (Ignore motors that
# don't actually exist.) Write that motor's .DMOV PV
record(scalcout, "$(P)$(Q):lastMotor") {
field(CALC, "(f?ff:e?ee:d?dd:c?cc:b?bb:aa)[0,' ']+' CP'")
field(INPA, "$(P)$(Q):dmov.INAV CA")
field(INPB, "$(P)$(Q):dmov.INBV CA")
field(INPC, "$(P)$(Q):dmov.INCV CA")
field(INPD, "$(P)$(Q):dmov.INDV CA")
field(INPE, "$(P)$(Q):dmov.INEV CA")
field(INPF, "$(P)$(Q):dmov.INFV CA")
field(INAA, "$(P)$(Q):dmov.INPA CA")
field(INBB, "$(P)$(Q):dmov.INPB CA")
field(INCC, "$(P)$(Q):dmov.INPC CA")
field(INDD, "$(P)$(Q):dmov.INPD CA")
field(INEE, "$(P)$(Q):dmov.INPE CA")
field(INFF, "$(P)$(Q):dmov.INPF CA")
field(PINI, "RUNNING")
field(OUT, "$(P)$(Q):closeGate.INPA CA")
}
---snip---