Despite a number of other things occupying my time over the last weeks, I have been able to resolve the final blocking issues which required resolution ahead of opening public access to the IEC 61131-3 virtual machine project source code (https://bitbucket.org/rob_au/61131). One of the final concerns that I have had however has been the selection of an appropriate licence for distribution – While my natural proclivity is to opt for an Open Source Initiative (OSI) approved license such as the GNU General Public License (GPL) or the Apache License 2.0, there is a small concern that I have about the unrestricted use of this project code. This is primarily due to the industrial nature and domain within which IEC 61131-3 compatible controllers, one of the principle candidate areas where code from this project might be employed is automation and industrial control. In turn, my concern is that the unwary user might seek to employ code from this project in such a setting without taking appropriate duty or understanding of the appropriateness of the project code for the given purpose. This is not to say that this project code cannot be employed for such purposes, but believe that the state of this project code as it stands currently has not yet undergone sufficient testing, audit and/or code review.
Accordingly, I have adopted the Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) licence for the initial release of the IEC 61131-3 virtual machine project. Under this license, project users are free to:
- Share – copy and redistribute the material in any medium or format;
- Adapt – remix, transform and build upon the material.
Under the following terms:
- Attribution – You must give appropriate credit, provide a link to the license and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use;
- Non-Commercial – You may not use the material for commercial purposes.
Additional information about this licence can be found at https://creativecommons.org/licenses/by-nc/4.0/.
This license appears to strike a balance with respect to source code availability – for further development and educational purposes – while precluding commercial industrial use at this point in time. I would however encourage anybody for whom this license presents issue to contact me – I am happy to discuss the possibility of a commercial-friendly license for this project code, but want to ensure that appropriate engineering safe-guards and review are adopted such that the project code is not employed in a manner for which it is not best intended.
In my musings today, I started to give thought as to some of the mechanics associated with the implementation of a debugging interface for the IEC 61131-3 virtual machine run-time. More specifically, I have considering what form the debugger client and interface protocol might take – While one approach might be to start work on a development environment (or build upon an existing platform such as GEB Automation Integrated Development Environment [IDE], http://www.gebautomation.com), the scope of such development extends far beyond the core focus on this project. Such an extension of scope is neither desirable with respect to ensuring my own on-going interest in this project (which as already grown beyond my initial expectations of development scope) and overall project quality.
Beyond the development or debugging environment, there is also a question as to what communication protocol should be employed for debugging between the development environment and the IEC 61131-3 virtual machine run-time running on the target hardware. With a desire to ensure the interoperability of this platform, my preference would be for a published standard or protocol, however none of the existing, standard industrial protocols (with which I have experience), incorporate sufficient scope to necessarily support all operations required for debugging of IEC 61131-3 applications – such as start application, stop application, step execution, continue execution and the setting and/or clearing of breakpoints. Moreover, Google searches for “debugger protocols” returned links to protocols better suited to more capable host environments than those where I would expect the IEC 61131-3 virtual machine run-time to be executed.
Nevertheless, after having spent some time considering available options for remote debugging, an interesting idea emerged – Why not use the GNU Debugger (gdb, http://www.gnu.org/software/gdb/) for debugging applications running on the IEC 61131-3 virtual machine run-time?
Following on from the previous post where an interface to physical I/O was described, I have made some further progress on this project. Below is a short video of the implementation of this physical I/O on a Raspberry Pi single board computer with PiFace Digital I/O board (http://www.piface.org.uk/products/piface_digital/).
In this demonstration, the following Instruction List (IL) application is running that performs a bit shift of a value through output channels – This demonstration application also incorporates the calling of C-based functions in the form of the rotate-left (ROL) and logical AND mask (AND_MASK) operations.
Output0 AT %QX0: BOOL;
Output1 AT %QX1: BOOL;
Output2 AT %QX2: BOOL;
Output3 AT %QX3: BOOL;
Output4 AT %QX4: BOOL;
Output5 AT %QX5: BOOL;
Output6 AT %QX6: BOOL;
Output7 AT %QX7: BOOL;
(* Set and rotate bits through a byte variable *)
Rotate: CAL ROL( Value, INT#1 )
(* Set output lines 0 through to 7 based upon byte variable *)
(* Copy bit 0 to output 0 *)
CAL AND_MASK( Value, BYTE#1 )
(* Copy bit 1 to output 1 *)
CAL AND_MASK( Value, BYTE#2 )
(* Copy bit 2 to output 2 *)
CAL AND_MASK( Value, BYTE#4 )
(* Copy bit 3 to output 3 *)
CAL AND_MASK( Value, BYTE#8 )
(* Copy bit 4 to output 4 *)
CAL AND_MASK( Value, BYTE#16 )
(* Copy bit 5 to output 5 *)
CAL AND_MASK( Value, BYTE#32 )
(* Copy bit 6 to output 6 *)
CAL AND_MASK( Value, BYTE#64 )
(* Copy bit 7 to output 7 *)
CAL AND_MASK( Value, BYTE#128 )
Over the past month, code has been implemented to provide an interface for statically including drivers to the IEC 61131-3 virtual machine code base and in turn, to physical I/O.
Using this driver interface, the driver name and an initialisation function for the driver are registered in a static table – The initialisation function for this driver takes the prototype form:
typedef void * ( *DRIVER_INITIALISATION_POINTER )( void * );
This initialisation function is called with a contextual pointer as a sole argument which is used in calls to subsequent registration and interface functions – At the moment, there is only one such registration/interface function which permits the registration of a physical I/O interface (further details below). This initialisation function should return a pointer to a contextual data structure on success – which will subsequently passed back to functions from driver management code within the IEC 61131-3 virtual machine run-time – or NULL on error.
Well, it appears that I have reached that point in the development process for this project where I simply cannot function any longer without issue tracking. Up until this point all development has been relatively contained and straight-forward such that I have been able to address issues as a priority as I encountered them. With the branching of scope to include C-based functions and in turn, a wider set of operations in a meaningful context, issues are being encountered which, while important, are minor in nature and rightly take less precedent that other development efforts. As a result, I have enabled the issue tracker on the Bitbucket repository so that these issues and be logged (and forgotten) until a later time when they can be addressed.
It’s really amazing how much effort sometimes needs to be put in to make the smallest element of functionality work correctly. The case in point is the recent implementation of support for calling functions from within the IEC 61131-3 virtual machine. This implementation required the inclusion of new virtual machine operators (PUSH and POP) to appropriately manage the passing of parameters between the calling code and the function body. There were also considerations that had to be given to the conditional nature of calling functions – namely with respect to the difference defined in the IEC 61131-3 standard between the C and N modifiers that can be applied to the CAL (call) operator; parameter typing and return types; and how to ensure the integrity of the parameter stack between invocations.
All of this work was ultimately manifest in the following, very simple test application:
CAL Func( Count )
FUNCTION Func: INT
The result when all requisite functionality was implemented was the very simple increment of a program variable (Count), albeit by somewhat convoluted means whereby a function is called and the function result is stored in the program variable – rather than direct increment of the program variable. Nevertheless, this provided a very sure means by which function call operations could be tested and I must say that it was particularly rewarding when this test case “just worked” after implementing the final dependent code elements.
Over the last few months, I have made some excellent progress on this project – I have implemented branching and execution jumps in the compiler and run-time and am currently working on the implementation of parameter passing to function calls. This latter task in particular has been interesting in that it has led me to made some additions to the byte code employed within the IEC 61131-3 virtual machine run-time.
For some background, the byte code is the portable instruction set, shared between the compiler and virtual machine elements of this project, that dictate execution of the virtual machine run-time. The intent of using byte codes in this project, rather than compiling directly to C or machine-specific source (such as is performed by the MATIEC, https://bitbucket.org/mjsousa/matiec/) is to provide a very compact and portable instruction set for operations. Moreover, using the interpretation of byte code for directing execution of the virtual machine additionally allows for greater control to be exerted with respect to “unintended” operations that may result from the direct execution of machine assembly. For a further explanation of byte code and it’s use in portable systems, see Wikipedia (http://en.wikipedia.org/wiki/Bytecode or http://en.wikipedia.org/wiki/Java_bytecode).