Table of Contents
Digital Interface Tutorial
Definition
Example
For each digital interface there must be a definition in the rocdigs.xml:
<object name="mydigint" interface="$../rocint/rocint.xml:DigInt" use="node,trace,thread" include="$rocint/public/digint" remark="Example digital interface"> <fun name="inst" vt="this"> <param name="ini" vt="const iONode" remark="Ini node"/> <param name="trc" vt="const iOTrace" remark="Trace instance"/> </fun> <data> <var name="ini" vt="iONode"/> <var name="iid" vt="const char*"/> <var name="device" vt="const char*"/> <var name="run" vt="Boolean"/> <var name="listenerObj" vt="obj"/> <var name="listenerFun" vt="digint_listener"/> </data> </object>
The data part is implementation dependent and in this example the most commonly used are listed.
Skeleton
A skeleton will be generated by issuing the make clean
command within the Rocrail/rocdigs
directory.
This file must be copied from the generation part of the build process into the source tree:
cp Rocrail/unxgen/rocdigs/impl/mydigint.c Rocrail/rocdigs/impl
Get it in the build process
File: Rocrail/rocdigs/makefile
- Add to the all, clean and install target the new digital interface:
$(OUTDIR)$(FS)mydigint$(SHAREDSUFFIX)
- Create a rule for it:
$(OUTDIR)$(FS)mydigint$(SHAREDSUFFIX): $(TMPOUTDIR)$(FS)mydigint.o $(COMMONOBJS) $(RRLIBS) $(LNK) $(LNK_FLAGS) -o $(OUTDIR)$(FS)mydigint$(SHAREDSUFFIX) $(TMPOUTDIR)$(FS)mydigint.o $(COMMONOBJS) $(RRLIBS) $(LIBS)
Implementation
Essential
Dynamic loading
Insert underneath the _inst
function the dynamic load support:
/* Support for dynamic Loading */ iIDigInt rocGetDigInt( const iONode ini ,const iOTrace trc ) { return (iIDigInt)_inst(ini,trc); }
Trace
Insert in the _inst
function the following line to get lines in the trace files:
TraceOp.set( trc ); /* Initialize data->xxx members... */
Initialization
All initialization should be implemented in the _inst
function.
If the connecting time to the device can take a long time it is preferred to do this in a thread.
Platform independent
Use the rocs library only, for system dependent API calls to ensure implementation for all platforms.
Interface functions
The auto generated interface functions are defined in Rocrail/rocint/rocint.xml.
All functions are called by the controller.
Name | Description |
---|---|
setListener | A callback for events like sensors. |
cmd | Translate a Rocrail XM command into the protocol of the interface and send it. |
halt | Shutdown the connection. |
supportPT | Returns true in case the interface supports programming. |
version | Returns the version of this interface; If major and minor do not mach with the calling Rocrail the library is rejected. |
state | Returns the connection and power state. |
shortcut | External shortcut event. |
Free up none local objects
The cmd function for example becomes a pointer to a command node which should be freed after processing it.
This call will free up the memory but cannot not adjusted the global static instant counters:
NodeOp.base.del(nodeA);
This one does both:
nodeA->base.del(nodeA);
Add the Interface to Rocrail settings dialog
First, the new interface must be added to the digint wrapper.
This needs to be done in the wrapper.xml file which is located in the rocrail / public directory.
Look for the digint section and add the following line:
<const name="mydigint" vt="string" val="mydigint"/>
The interface must be added to rocrailinidialog.cpp in the rocview / dialogs directory.
This will add the entry to the interface list:
m_Lib->Append( wxString( wDigInt.mydigint, wxConvUTF8 ) );
Add a dialog to the interface
To allow the user to apply communication settings, a settings dialog should be added to the interface. In case no special dialog exists the default settings dialog is displayed.
The creation of dialogs is described in the Maintaining and Creating GUI Dialogs section. The dialog source should be placed in the rocview/dialogs/controllers directory. The build process scans for new dialogs automatically. Therefore, new dialogs do not need to be added to a makefile.
After the dialog is created, it needs to be added to the dialog selection handler which is located in rocrailinidialog.cpp in the rocview / dialogs directory
look for the function:
void RocrailIniDialog::OnButtonRrPropsClick( wxCommandEvent& event )
and add the folloing lines:
else if( StrOp.equals( wDigInt.mydigint, wDigInt.getlib( m_Controller ) ) ) m_CSDialog = new uMyDigIntDlg(this,m_Controller,devices);