General list discussion, and a brief design proposal


Thread Starter

Stan Brown

First let me apologize for not responding to specific mail messages, I seem to have corrupted the mail folder for this group :-(

Thanks Jiri for the tips on setting up elm, they helped a lot.

Curt, based upon your last message, it appears that you don't want to write a proposal for the design spec for the first version of this
project. OK, I will take a crack at it. This will be very brief, since it's really just to try to focus our ideas, and will need significant
fleshing out before we can start using it as a basis for writing code,

Here goes:

The (insert agreed upon name her) will be refereed to as the PLC for the rest of this document.

The PLC shall consist of a number of cooperating process. These process shall communicate with each other via shred memory segments. These shared memory segments will be discussed at greater length later in this document.

Run time tasks that will be needed, please note this does not include programming/editing/documentation functionality, even though they will be used at run time. The tasks listed below are the ones that will need
to be running, when the PLC is controlling the process/machine, and not being edited or examined by a person. Also note that not all of these
tasks must run for a given application. For example, if you don't need PID control, then you don't need to run the PID execution engine.
Also note that it is possible to run more than one of each of these. For example the I/O scanners will be hardware specific, thus if you
wanted to talk to AB RIO, and OPTO22, on the same PLC, you would need to run 2 different I/O scanners.

I/O scanner(s)

Logic engine(s)

Timer execution engine(s)

PID execution engine(s)

Counter execution engine(s)

Motion control engine(s)

Other tasks may be added as required.

Shared memory segments:

Shared memory segments will be of the following types:

I/O data table

Non I/O data table

Force Table(s) (one per I/O scanner program)

Input inversion tables (one per I/O scanner)

Interface between the tasks, and the shared memory segments will be by a standardized library. This library if called to access any segment, will create all of the segments defined in the config files, if it fails to find that they have already been created. This will avoid the need for a shared memory manager task.

The shared memory library calls will include a parameter which defines which logic engine you are, if you are a logic engine. This will be used to enforce "ownership" of real outputs. Thus only one logic engine can have control of a given real output. This cannot be changed without shutting the system down.

Some details about specific tasks

Logic engines may run any of several different programming languages (TBD). Where feasible, online editing of these will be provided. In all cases one line examination of run time status must be provided.

Data table details

Data tables shall use the AB syntax for declaring what type, file number, and element they are. Later support for user defined structs,
which must consist of aggregates of the predefined data types is planned.

Run time resizing of the data table files is a highly desirable feature.

OK guys, lay into it. raise your objections, and add your details, please

Stan Brown [email protected] 843-745-3154
Charleston SC.

LinuxPLC mailing list
[email protected]
On Mon, Jan 24, 2000 at 06:47:14AM -0500, Stan Brown wrote:
> I saw it, and your ideas also. Wht we need here is not a .h file,
> but some documentation on how the data table files are to be used.
> Want to write it up?

I've got one like that to go with my smm.h, but if Simon is going to be writing it, no point me confusing things.

Unless y'all vote that you like mine better than Simon's, I suppose :)

Jiri Baum <[email protected]>
On the Internet, nobody knows if you are a @{[@{[open(0),<0>]}-1]}-line
perl script...

LinuxPLC mailing list
[email protected]
On Tue Jan 25 06:14:50 2000 Jiri Baum wrote...
>I've got one like that to go with my smm.h, but if Simon is going to be
>writing it, no point me confusing things.

I would like to see it, please.

>Unless y'all vote that you like mine better than Simon's, I suppose :)

I'm not going to open that can of worms, right now.

Stan Brown [email protected] 843-745-3154
Charleston SC.

LinuxPLC mailing list
[email protected]
Hello List,

>Data table details

>Data tables shall use the AB syntax for declaring what type, file
>number, and element they are. Later support for user defined structs,
>which must consist of aggregates of the predefined data types is

I would like to suggest that we use IEC nomenclature for the data tables instead of the AB format. Someone posted an IEC example of data table addresses a week or two ago.

If IEC is not used lets at least use Q for outputs instead of O.

Bradley G. Hite
Intertech Inc.
mailto:[email protected]
ICQ# is 38746036
Teaching Practical Skills For a Technological World

LinuxPLC mailing list
[email protected]
Providing the basic data table architecture and the data type definitions are appropriate, this is merely a matter for the compiler (source to op_code translator).

Variations on a theme can be accomadated by the compiler. There is ample precedent for this in commercially available products, e.g. some allow IEC IL instruction notation but offer an option for Siemens style notation, some allow you to switch between F and M for flags.

This can either be built into the main compiler, or pre-compilers/translators can be used (in the same way I plan to produce translators for existing PLC tools).

It may not be clear from my spec.( ) but the data table has three standard sub tables, these are I,Q and M, equating to I,O and B. Aditional tables are an extension.{ The idea is that the data table is in effect a two dimensional array each table has its own index across the width of the array, i.e I=1,O=2,M=3,...... sound familiar}

LinuxPLC mailing list
[email protected]

Jack Gallagher

This may seem like a dumb question, but why did they pick Q for output? I
feel like this is a joke that I don't get.

Jack Gallagher
3 Vision Drive
Natick, MA 01760
Phone: (508) 650-9147
Fax: (508) 650-9310
e-mail: [email protected]

LinuxPLC mailing list
[email protected]
Hi Stan,

Great but, missing the point. What is needed now is a very narrow definition of the IO memory map, the calls that all drivers must support, and how they can be sequenced. The idea being that we can then run this subsystem to verify timing issues and turn loose driver writers. Other people can then work on the language/solver/IL code side of the map. I doubt that there is sufficient concensus for the overall, but, we had ought to be able to get Linux running IO. This is the least controversial part and the one that
will answer the most questions.

Curt Wuollet

LinuxPLC mailing list
[email protected]
By I/O memory map, do you mean the shared memory segments for I/O data tables, or more generally the shared memory segments for I/O and non I/O data table, or even more generally both of these plus the layout of the force tables, and inversion tables?

AS I see it, the very first thing we need is a definition of the shred memory segments, there configuration files, and the calls that need to exist in the shared memory common access library.

You seem to be overly focused on the I/O side of things IMHO. To my mind, these shared memory areas, and the common access library for
them, are the very first thing we need to code. The reason that I believe this, is because, as I see it, these are the common ground where all the various tasks meet.

Are we in agreement on this?

If so, would you care to propose a set of prototypes for these libraries, and a shared memory layout?

If you don't want to, I can sketch this out.

Stan Brown [email protected] 843-745-3154
Charleston SC.

LinuxPLC mailing list
[email protected]
I also agree that we should take a bottoms up approach and start with a few I/O drivers. For me, a good set of I/O driver code would make
Linux far more useful.

We should also start working on a shared memory table so that we have a place to store the I/O data. Do I understand that we could use an A-B format, for now. At least we know it works. We need something to follow, so it must either be an
existing PLC format or we write our own format soon.

Any other discussions, such as I/O forcing, persistant data, real time... are premature, and should not be discussed further until we are ready. I have spent hours reading these posts, and many of them are not useful at this time,

Can we back off and refocus on the basics. Let us spend less time reading email and more time developing. Or we could do what the usenet groups
do, have a developers group and a advocacy group. This has been suggested in a previous post.

Bill Sturm

Curt Wuollet wrote:
> sufficient concensus for the overall, but, we had ought to be able to get Linux running IO. This is the least controversial part and the one that will answer the most questions.<

LinuxPLC mailing list
[email protected]
Please don't - Simon Martin narrowly beat me to the punch volunteering for this, posted a .h file and left for 1 1/2 weeks holiday, but presumably he has something planned and maybe even written.

I also have a .h file that I wrote before I realized Simon was doing it.

No point triplicating the work :)

Jiri Baum <[email protected]>
On the Internet, nobody knows if you are a @{[@{[open(0),<0>]}-1]}-line
perl script...

LinuxPLC mailing list
[email protected]
I agree with Bill Sturm. To get going we need two things:

1) Shared memory tables
2) I/O drivers

A simple utility for manually manipulating the memory tables can be used to exercise and test the I/O drivers. Then we will have a base upon which to build logic engines, HMIs, etc.

A big nut to crack as I see it, is to structure the shared memory tables to handle the different addressing schemes used by various I/O vendors. Do we make a system which handles them all? Do we come up with our own addressing scheme which the I/O drivers "map" to?

Let's look further to how the shared memory can support symbolic addressing and jump over all these crazy rack/card/channel numbering schemes.

Ron Davis
[email protected]
Synchrony Industrial Controls
7777 Bent Mountain Rd
Roanoke, VA 24018
(540) 989-1541
(540) 989-0467 Fax

LinuxPLC mailing list
[email protected]
Dear Colleagues,

I am currently an automation consultant in the steel and aluminum industry. I was on the GE Direto-Matic 2000 Industrial Controller design
team in the late 1980s and wrote a graphical RLD editor for them. Recently I have finished a long term contract with Kaiser Aluminum where I helped develop the concepts and infrastructure to be used in the replacement of their aging MODCOMP and other legacy control systems using a linux platform.

I would like to apologize if it appears to you that I am on a mission, Well I am, kind of? I have been formulating a vision of the ultimate
automation platform for almost 20 years. If you can overlook (tolerate) my over-enthusaism, I would like to contribute to this list and share my
vision in the hope that it will be helpful. Thanks for you tolerance everyone. Well here goes my first post.


I couldn't agree more with Bill. I have been lurking on the list for about a week and keep feeling that we were getting a little ahead of
ourselves. I believe that for this project to be successful the LINUXPLC must have the following characteristics:

o Modularity
o Inter operability
o Online Programmability
o Scalablity

A modular LINUXPLC would consist of one or more modules which are loaded and executed in much the same way as normal LINUX modules are currently
loaded. Each module would contain a RLD, SFC, compiled C, I/O driver, or other definition. Communication between modules would be via a shared memory interface whose definition and management is negotiated at runtime. Modules could be added, deleted, suspended, resumed, or
modified at will during runtime.

There needs to be a common way of defining I/O, Relay Ladder code, SFC, C, and other characteristics of the control system. Ideally, an existing format for which tools, utilities, and source are already available would be selected such as ASCII or XML for example. This would allow us to split into working groups so as to get the work done instead of just talking about it. For example, one group could go off and develop an RLD editor while another group developed the execution engine, and still another group could be writing I/O drivers.

I/O drivers, execution engines, editors, and gui tools could be developed simultaneously by different groups and organizations without
regard to which should be completed first. If we don't have this ability this project will never be completed.

INTER OPERABILITY - The linux PLC will exist in a world filled with proprietary and/or legacy control systems, most of which do not
communicate with other computers. A huge benefit offered by a LINUX PLC is that it has the potential of being the means by which all of these
legacy systems are enabled to communicate.
Separate modules would provide the interfaces between the various I/O systems, PLC CPUs, or other controls system and the LINUX PLC shared
memory. Such modules could have either a GPL or proprietary license. (Don't freak at the thought that some pieces may be proprietary, I would rather have GE or AB provide a proprietary module that allows their stuff to inter operate, than to not have it at all.)

ONLINE PROGRAMMABILITY - Modules can be loaded, deleted, and replaced at runtime. Connections between modules are resolved dynamically when a
module is loaded. This provides for much of the online programmability requirements. Since connections are resolvable at runtime, it would be a simple matter to provide a tool that allowed connections to be changed "on the fly". A
module written in C could be modified and recompiled using already existing tools and then executed by replacing the running version with
the newly compiled version. The other modules in the system would continue running normally.

SCALABLITY - The LINUX PLC should be deployable on virtually any linux platform from the small (uCsimm or the very large
(unlimited number of networked linux computers). On the small/inexpensive side I believe there is a tremendous un-tapped market, who have been traditionally priced out of any kind of automation
system. These folks would welcome an affordable chance to reap the benefits of automating some of their operation. On the large side there are the traditional big crop consumers of automation systems who are looking for an upgrade path that their traditional suppliers are sometimes slow or unable to provide.

Rick Jafrate
Mitek Corp.

LinuxPLC mailing list
[email protected]

Eelco van der Wal

Hi all,

I follow this list now for some time, and I must say: it is very active indeed, and it got time I added my 2c's.

In some of the threads the discussion hits several times on the topic IEC 1131-3.
This is about my activities: running the association plcopen, being focussed to IEC 1131-3, and being referenced already several times on this list.
SFC (and Grafcet are mentioned), and explained by Johan B., as well as ST, IL, LD and FBD were mentioned.

Asnwers to open questions on this topic (as far as I could follw it)
1. Standard (watch out: not open source, but copyrighted by the IEC committee)

As already mentioned on this maillist: for IEC 1131-3 related topics, plcopen is the best resource.
I am willing to prepare and send all relevant topics to this list or make them availabe to this website. Unfortuantely, I am not able to check all the mails on this list, so please remind me if you need or expect any action from my side

alternatively, those in favor for AB, check the site (if you can enter it):

2. IEC 1131-3 Datatypes
I have put an overview at the end of this email. Not the derived datatypes, being own datatypes constructed from the standard defined types. They are very reusable.

3. Some general remarks on IEC 1131-3 (without a tutorial) IEC is more than a set of programming languages (being Ladder Daigram, Instruction List, Structured Text and Function Block Diagram). The essential addition is in the so called 'Common Elements', which includes Sequential Function Chart, SFC, as structuring tool, the datatypes and
decalaration, the Function and Function Blocks as reusable components, including data encapsulation and data-hiding, and the 'configuration', 'resources'and 'task' for the control of programs (so support for a multi tasking environment)
Please check the website for more information

Kind regards,

Eelco van der Wal
MD PLCopen
PO Box 2015, NL 5300 CA Zaltbommel, The Netherlands
Tel.: +31-418-541139 Fax: +31-418-516336
email: [email protected]

Do not forget to look at our website

DATATYPES and more....

Table 10 - Elementary data types
No. Keyword Data type Bits
1 BOOL Boolean 1
2 SINT Short integer 8
3 INT Integer 16
4 DINT Double integer 32
5 LINT Long integer 64
6 USINT Unsigned short integer 8
7 UINT Unsigned integer 16
8 UDINT Unsigned double integer 32
9 ULINT Unsigned long integer 64
10 REAL Real numbers 32
11 LREAL Long reals 64
12 TIME Duration Note 1
13 DATE Date (only) Note 1
14 TIME_OF_DAY or TOD Time of day (only) Note 1
15 DATE_AND_TIME or DT Date and time of Day Note 1
16 STRING Variable-length character string Note 1
17 BYTE Bit string of length 8 8
18 WORD Bit string of length 16 16
19 DWORD Bit string of length 32 32
20 LWORD Bit string of length 64 64

2.3.3 Derived data types Declaration
Derived (i.e., user- or manufacturer-specified) data types can be declared using the TYPE...END_TYPE textual construction shown in table 12. These derived data types can then be used, in addition to the elementary data types defined in 2.3.1, in variable declarations as defined in 2.4.3.
An enumerated data type declaration specifies that the value of any data element of that type can only take on one of the values given in the associated list of identifiers, as illustrated in table 12.
A subrange declaration specifies that the value of any data element of that type can only take on values between and including the specified upper and lower limits, as illustrated in table 12.
A STRUCT declaration specifies that data elements of that type shall contain sub-elements of specified types which can be accessed by the specified names. For instance, an element of data type ANALOG_CHANNEL_CONFIGURATION as
declared in table 12 will contain a RANGE sub-element of type ANALOG_SIGNAL_RANGE, a MIN_SCALE sub-element of type ANALOG_DATA, and a MAX_SCALE element of type ANALOG_DATA.
An ARRAY declaration specifies that a sufficient amount of data storage shall be allocated for each element of that type to store all the data which can be indexed by the specified index subrange(s). Thus, any element of type
ANALOG_16_INPUT_CONFIGURATION as shown in table 12 contains (among other elements) sufficient storage for 16 CHANNEL elements of type ANALOG_CHANNEL_CONFIGURATION. Mechanisms
for access to array elements are defined in
Table 12 - Data type declaration features
No. Feature/textual example
1 Direct derivation from elementary types, e.g.:
2 Enumerated data types, e.g.:
3 Subrange data types, e.g.:
4 Array data types, e.g.:
5 Structured data types, e.g.:
Table 13 - Default initial values
Data type(s)
Initial value
'' (the empty string)

Table 14 - Data type initial value declaration features
Feature/textual example
Initialization of directly derived types, e.g.:
Initialization of enumerated data types, e.g.:
(BIPOLAR_10V, (* -10 to +10 VDC *)
UNIPOLAR_10V, (* 0 to +10 VDC *)
UNIPOLAR_1_5V, (* + 1 to + 5 VDC *)
UNIPOLAR_0_5V, (* 0 to + 5 VDC *)
UNIPOLAR_4_20_MA, (* + 4 to +20 mADC *)
UNIPOLAR_0_20_MA (* 0 to +20 mADC *)
) := UNIPOLAR_1_5V ;
Initialization of subrange data types, e.g.:
TYPE ANALOG_DATAZ : INT (-4095..4095) := 0 ; END_TYPE
Initialization of array data types, e.g.:
ARRAY [1..16] OF ANALOG_DATA := [8(-4095), 8(4095)] ;
Initialization of structured data type elements, e.g.:
Initialization of derived structured data types, e.g.:
MAX_SCALE := 4000);

Table 15 - Location and size prefix features for directly
represented variables
No. Prefix Meaning Default data type
1 I Input location
2 Q Output location
3 M Memory location
4 X Single bit size BOOL
5 None Single bit size BOOL
6 B Byte (8 bits) size BYTE
7 W Word (16 bits) size WORD
8 D Double word (32 bits) size DWORD
9 L Long (quad) word (64 bits) size LWORD

Table 16 - Variable declaration keywords
Keyword Variable usage
VAR Internal to organization unit
VAR_INPUT Externally supplied, not modifiable within organization unit
VAR_OUTPUT Supplied by organization unit to external entities
VAR_IN_OUT Supplied by external entities
Can be modified within organization unit
NOTE - Examples of the use of these variables are given in figures 11b and 12
VAR_EXTERNAL Supplied by configuration via VAR_GLOBAL
Can be modified within organization unit
VAR_GLOBAL Global variable declaration (2.7.1)
VAR_ACCESS Access path declaration (2.7.1)
RETAIN Retentive variables (see preceding text)
CONSTANT Constant (variable cannot be modified)
AT Location assignment (
NOTE - The usage of these keywords is a feature of the program organization unit or configuration element in which they are used; see 2.5 and 2.7.

Example of VAR_RETAIN
AT %QW5 : WORD := 16#FF00 ;
At cold restart, the 8 most significant bits of the 16-bit string at output word 5 are to be initialized to 1 and the 8 least significant bits to 0

LinuxPLC mailing list
[email protected]
On Tue, Jan 25, 2000 at 07:05:08AM -0500, Stan Brown wrote:
> On Tue Jan 25 06:14:50 2000 Jiri Baum wrote...

> >I've got one like that to go with my smm.h, but if Simon is going to be
> >writing it, no point me confusing things.

> I would like to see it, please.

> >Unless y'all vote that you like mine better than Simon's, I suppose :)

> I'm not going to open that can of worms, right now.

OK, but bear in mind that Simon Martin has this part of the project. I know he's planning to do *some* things differently, and no doubt there are other differences I *don't* know about.


This is the interface used by both the I/O drivers, and the Logic Engines and other task. To avoid confusion, the two views of the interface are explained separately below. However, they use the same function calls.

Common parts

Each file must be opened with open_plc_file() before use, and it should be
closed with close_plc_file() at program termination.

Files are referred to by number. There are several pre-defined files
(input, output, coil etc) at numbers 9xx. It is strongly suggested that
these be used for the purposes indicated by their names. Alternatively,
there is a "points" file for use when only one file is desired.

The SMM makes no distinction between types of files. Each file consists of
1024 32-bit unsigned integers, which may be accessed alternately as
individual bits or whole integers.

(Note: this makes each file exactly an i386-linux page.)

(Should I allow access to it as a flat 4K of memory?)

The SMM will enforce write-exclusion: either static (one task owns a
point/subpoint for life) or dynamic (using semaphores). It also deals with
inversion and force tables.

Front-end interface

The scan-solve loop:
- a full scan is effected by calling refresh() on each file
- the solve logic can use plc_get() to read inputs and coils and
plc_set() to write outputs and coils; these work on the task's
private copy of the files.

An immediate output / coil-write is achieved by calling plc_set() as
normal, followed by refresh_point() or refresh_subpoint().

An immediate input / coil-read is achieved by calling refresh_point() or
refresh_subpoint(); the new value will be available via plc_get().

Note that these aren't really immediate: they only update the shared
memory. Support for true immediate I/O will have to be thought through

Back-end interface

Loop independently:
- update with the linuxPLC core by calling refresh() on each
relevant file
- use plc_get() to read outputs and plc_set() to write inputs;
these work on a private copy of the points.

Depending on the communications discipline, it may be useful to call
refresh() more often, or refresh_point() / refresh_subpoint() at
appropriate times.

Real-time considerations

The functions open_plc_file and close_plc_file are not real-time.

Only the refresh* and plc_get*/set* functions are intended for real-time


#ifndef __SMM_H
#define __SMM_H

typedef unsigned int u32; /* 32-bit unsigned integer */

#define PLC_FILE_SIZE 1024

#define ON 0xFF
#define OFF 0
/* note: any non-zero value is ON */


/* PRIVATE definition */
/* inline functions need the definition here, unfortunately */
typedef struct {
int magic;
/* ... */
} plc_file;

/* OPEN a file of a particular type */
plc_file*open_plc_file(int filenumber, int options);

* filenumber will usually be one of the constants below;
* (if doesn't exist, ENOENT)
* options must be zero
* on error returns NIL and sets errno (ENOENT, ENOMEM etc)

#define PLC_POINT 0x3A0
#define PLC_INPUT 0x3A1
#define PLC_OUTPUT 0x3A2
#define PLC_COIL 0x3A3
#define PLC_MISC 0x3A4
#define PLC_SPECIAL 0x3A5

/* this may change depending on how timers and counters end up */
#define PLC_TIMER 0x3B0

/* this may change depending on how timers and counters end up */
#define PLC_CNTR 0x3C0

/* CLOSE a file */
int close_plc_file(plc_file*f);

/* UPDATE the inputs/outputs/coils */
void plc_refresh(plc_file*f);
void plc_refresh_point(plc_file*f, int point);
void plc_refresh_subpoint(plc_file*f, int point, int subpoint);

/* ACCESS functions */
inline int plc_get(plc_file*f,int point, int subpoint) {
return (f->data[point]&(1<<subpoint))?ON:OFF;
inline void plc_set(plc_file*f,int point, int subpoint, int val) {
if (val)
inline u32 plc_get32(plc_file*f,int point) {return f->data[point];}
inline void plc_set32(plc_file*f,int point, u32 val) {f->data[point]=val;}

#endif /* __SMM_H */

Jiri Baum <[email protected]>
On the Internet, nobody knows if you are a @{[@{[open(0),<0>]}-1]}-line
perl script...

LinuxPLC mailing list
[email protected]