This page describes the common interface that all ecmc plugins use.
That interface has two parts:
This distinction is important: plugin loading is standardized, but the actual runtime names, functions, records, and configuration keys are usually plugin-specific.
The normal startup entry point is:
${SCRIPTEXEC} ${ecmccfg_DIR}loadPlugin.cmd, \
"PLUGIN_ID=0,FILE=/path/to/libecmc_plugin_xxx.so,CONFIG='KEY=VALUE;KEY2=VALUE2;',REPORT=1"
Main arguments:
PLUGIN_ID: numeric plugin object idFILE: shared library to loadCONFIG: plugin-specific configuration stringREPORT: if 1, call Cfg.ReportPlugin(...) after loadThe underlying command-parser calls are:
Cfg.LoadPlugin(<id>,<file>)
Cfg.LoadPlugin(<id>,<file>,<config>)
Cfg.ReportPlugin(<id>)
The safety plugin is a special case and is loaded with:
Cfg.LoadSafetyPlugin(<file>,<config>)
CONFIG is passed directly to the plugin constructor.
Important points:
KEY=VALUE;... style stringExamples:
CONFIG='DBG_PRINT=1;'
CONFIG='SOURCE=ec0.s11.mm.analogInputArray01;ELEMENTS=1024;'
CONFIG='IF=can0;DBG_PRINT=0;'
After plugins are loaded, the IOC exposes common summary information:
$(IOC):MCU-Cfg-PLG-Cnt for the plugin count$(IOC):MCU-Cfg-PLG-FrstObjId for the first plugin object idThese PVs are mainly used by overview panels and configuration summaries.
The runtime interface is not identical across plugins, but most plugins expose one or more of these surfaces:
Some plugins expose runtime values through the normal ecmc asyn port.
Those values can then be mapped to EPICS records with the generic wrapper scripts:
addAsynVarAnalog.cmdaddAsynVarBinary.cmdExample:
${SCRIPTEXEC} ${ecmccfg_DIR}addAsynVarAnalog.cmd \
"NAME=Plugin-Adv-Counter,ASYN_NAME=plugin.adv.counter,PREC=0"
Here:
DEV:NAME, where DEV defaults to IOCPORT is the normal ecmc asyn port unless overriddenASYN_NAME is the plugin-defined runtime variable nameplugin.adv.counter namespace is defined by that specific pluginSome plugins ship their own record templates instead of relying only on generic analog/binary templates.
Example:
dbLoadRecords(ecmcPluginFFT.template,"P=$(IOC):,INDEX=0,NELM=4096")
This is common when a plugin has a richer object model, such as FFT spectra, trigger control, or waveform readback.
Some plugins also register extra PLC functions and constants.
Examples from plugin test material:
adv_plugin_func_1(...)
adv_plugin_func_2(...)
adv_CONST_1
rpi_digitalWrite(...)
rpi_digitalRead(...)
rpi_OUTPUT
These names become available in PLC code after the plugin has been loaded.
Use this when plugin functionality should be driven directly from PLC logic.
Some plugin packages provide their own helper scripts, for example DAQ or safety setup scripts.
In those cases, the common pattern is:
loadPlugin.cmdCfg.LoadPlugin(...)Cfg.ReportPlugin(...)PLUGIN_IDCONFIG keysplugin.adv.counterloadPlugin.cmd.REPORT=1 while commissioning so the plugin reports its object/config details.ecmcGeneric*.db records.addAsynVarAnalog.cmd / addAsynVarBinary.cmd.