[MAT logo][Prev][Up][Next]

Interfacing other projects to the MatPLC

Interfacing the MatPLC and another project will of course always depend on the details of the other project. However, typically, it would be done by making the other project (or some part of it) a MatPLC module. In some cases, an entirely new binary would be written, which is both a MatPLC module and interacts with the other project in some way. In either case, some part of the interface will be a MatPLC module.

The minimum required for MatPLC integration is to link with the shared (or static) library, and call five functions, with seven being preferable. The functions are:

plc_init(module_name,0,0)
Initializes the library. The module_name should be a string.
pt_handle = plc_pt_by_name(pt_name)
Obtains a handle to a MatPLC point, required for the plc_get() and plc_set() functions. The pt_name should be a string, while pt_handle should be of type plc_pt_t. This function, like plc_init(), should be called before the time-critical part begins.
plc_update()
Updates the local (buffered) copy of all the MatPLC points. It should be called before reading MatPLC points or after writing them. If the module runs in a repeated "scan", this function will usually be called once at the beginning of the scan, and once at the end.
value = plc_get(pt_handle)
Reads a MatPLC point (as it was at the time of the last plc_update(), or as changed by this module), returning it as an unsigned 32-bit integer. A 32-bit float version of this function is also available.
plc_set(pt_handle, new_value)
Writes an unsigned 32-bit integer to a MatPLC point. A 32-bit float version of this function is also available. The write will not be seen by the other MatPLC modules until plc_update() is called.
The two additional functions should be used if the module runs in a repeated scan, like a traditional PLC. They enable the MatPLC to enforce execution periods, sequencing of modules, RUN/STOP modes and the like. They take no arguments.
plc_scan_beg()
Beginning of scan. This should precede the plc_update() call.
plc_scan_end()
End of scan. This should follow the plc_update() call.

Naturally, you're welcome to use any other MatPLC functions that look useful.

These functions and their use are explained in more detail in the Custom modules chapter, especially in the Native C section.

Usual usage

There are two usual ways of structuring modules: the first is the "classical scan" familiar from stepladder, while the second is a "data interface", where MatPLC and some other system exchange data.

Classical scan

Here, the behaviour resembles a stepladder scan: at the top of the loop, data is read from the inputs (and other parts of the MatPLC), then the logic is executed, and then data is written to the outputs (and other parts of the MatPLC).

This is the template for a classical-scan module:

#include <plc.h>

int main(int argc,char *argv[])
{
  plc_init("modulename",argc,argv);

  /* initialization goes here */

  while (1) {
    plc_scan_beg();
    plc_update();

    /* body of loop goes here */

    plc_update();
    plc_scan_end();
  }
}

Data interface

Here, the module does data interchange between MatPLC and something else (the "other"). In the first half of the loop, any data that's going from the other to the MatPLC is written into MatPLC points. In the second half of the loop, data is taken from MatPLC points and sent to the other. All the I/O modules work this way, exchanging data between MatPLC and the I/O.

One advantage is that the module doesn't need to keep track of which points are read-only and which are read-write in the MatPLC; in the first half, all points may be written, and in the second half all points may be read. The plc_update() discards values for which the module lacks write permission.

This is the template for a data-interface module:

#include <plc.h>

int main(int argc,char *argv[])
{
  plc_init("modulename",argc,argv);

  /* initialization goes here */

  while (1) {
    plc_scan_beg();

    /* process data going to MatPLC */

    plc_update();

    /* process data coming from MatPLC */

    plc_scan_end();
  }
}

Notes

The MatPLC library is not particularly thread-safe. If you are using multiple threads, it would be best to restrict MatPLC functions to one thread. However, it is quite OK for one thread to be using the runtime functions while another thread does a plc_pt_by_name().

[Prev][Up][Next]

$Date: 2004/12/28 05:32:10 $