You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(35) |
Nov
(5) |
Dec
(1) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Dieter W. <wi...@oe...> - 2001-10-18 11:02:52
|
Hi Kelvin, I have subscribed to the list, and I will send my mails to the list from now on. It is good that we have a similar picture of the "process image" term, and I fully agree that the threading mechanics should be hidden behind interface(s). I even think that for specific cases it will be necessary to specially implement this to suit the actual requirements. Regarding to the sources I would like to mention that I did not update the package that I dropped on my web site. I have driven things further, and I will put up the new version as soon as I am done with some basic testing and my clean up (I want to ensure I remove unecessary comments, and add documentation were I left it out). I'll notify you when I am done, and the new package can be picked up :) During the last half day and night I was running a slave burn-in test, two simulatenous Requesters running a million requests each in the fastest sequence possible. It is still running, but that it is still running already prooves the stability of the implementation :) Regards, Dieter |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:56:25
|
Dieter, I have setup a jmodbus-devel list for the project. Knowing how bad my own memory can be I through it might be a really good idea if we pushed most of our mail through a list so that is logged in it's entirety so we can look back at the decision process we have gone through in the future etc... if required. I have forwarded most of e-mail discussion we have had so far to the list so it will be archived as well. (I have numbered the e-mails, put I may have 1 or 2 out of other, oh well) With regard to your message once again see my comments below. Cheers, Kelvin > -----Original Message----- > From: Dieter Wimberger [SMTP:wi...@oe...] > Sent: Tuesday, October 16, 2001 18:41 > To: Proctor, Kelvin > Subject: The quest continues > > Hi Kelvin, > > Hope you had a nice weekend, and don't let yourself be stressed too much > throughout the week ;) > > >One other thing I have to do is more the build environment of the project > >from make to Ant, especially if we intend to use Junit as the two > integrate > >nicely I'm told. I have never bothered to get Ant running before but I'm > >sure it won't be too much work. > > This is fairly easy, as I include ant into the package. The one you > downloaded came with a build.sh and a build.bat, both scripts that > directly call ant by invoking the JVM with right arguments. The necessary > JAR libraries are also in the package, that's ant.jar, jaxp.jar and > crimson.jar > > Thus you are able to build with > > build <ant target> (Windows) > build.sh ant <ant target> (Unix/Linux) > > directly from the commandline. I have recently switched my Development > Environment after testing a few different ones, and most of them have > support for directly using ant as build tool. > Targets are defined in build.xml, the file that came with my package is a > rather standard variant of it, not using too much of ant's more > complicated features: > compile (compiles the classes) > jar (makes a jar file) > dist (a tar.gz distribution, no "external" tools needed for this!) > zipdist (a zip distribution) > clean-dist > clean-classes > clean-all > > The behaviour of the build can be influenced easily by setting properties > (init target, command line or properties file). > I have now added also targets for TINI, so that together with the > libraries and files necessary for the task, one can directly create the > installable for TINI: > tini-compile (against the tiniclasses.jar) > tini-file (packaging the installable using TINIConvertor) > > Thanks for the hint with the -m, I will try it out and come up with a > solution where the main class can be set via a property (that can be > overidden on the commandline for example). > > I have also added a preliminary target for invoking junit tests: > test (invokes the junit testbed using the text runner) > > > >With regard to locking and concurrency issues in the register/coil banks > I > >also re-read the language spec relating to synchronized. None of the > >methods need to be public but all critical section of code need to be > >contained with a > > >synchronized(this) { > > // Critical code > >} > > >This will block on the lock for the object owning the method. Why I was > >taught about using the synchronized modifier for function prototypes and > not > >told of it's use in this context I'm not sure. This is quite an elegant > >IMHO. > > Well the elegancy of synchronized is just the start of the story. The book > and the web page I have pointed out to you do demonstrate the problems > with this modifier (or block) and discuss various concurrency > mechanisms/patterns. All source code is public domain..... > [Proctor, Kelvin] I have downloaded the code and will start to have a look. First I would propose that we use the relatively simple synchronized method and we can look further into this once we have the API defined. I would anticipate that all locking and mutexes etc.. could be done internally to the classes and would not effect the interface. > >Not a problem. I was out for this weekend and have a fairly busy > >week but I have allocated all of next weekend for the task. So anything > you > >can code up before the end of the week would be great as I can see where > you > >have started to take things. I think with a decent effort this weekend I > >should be able to get a lot of this stuff working. > > I completely agree with you. I will see about getting things out until the > end of the week, allthough I am fairly busy too. However, I see a chance > to prove some concepts, so there is double use for a running > implementation. > > >I should check, what do you define the 'process image' to be. I > >want to avoid misinterpreting the term, as this could lead to great > >confusion. > I agree with you in this point too. It is important that we "talk the same > language". > What we have is > 1. A backend > Which can be a device with sensors or I/O's or another bus system (like > the collector mechanism you described) > 2.A frontend > Which gives access to the device/sensor/IO data from outside. This is the > Modbus/TCP Slave implementation (for our case and the collector example). > > Usually it is the case that the backend is hard realtime, and the frontend > not necessarily. > These hard realtime environments do everything in terms of cycles, and > thus there must be some mediator to the frontend part. This is often a > shared memory area, which people here call "Process image". This term is > also likely to be found in books on industrial bus systems. > [Proctor, Kelvin] Thanks for that. I did have the same definition of the term as you. > > Now if we are talking only in terms of data acquisition (like with your > thermo iButtons), the issue is not as complicated, however, if you want to > seize acquisition and control (writing to outputs or registers) then you > have a big issue with concurrency, going far beyond "synchronized" :) > There is a need to define priorities (for reading and writing) and to take > care about things like priority inversion, deadlocking etc. > > Coming back to the process image, then what I am talking about is an OO > abstraction that reflects the "shared memory area". This would be like the > CoilBanks and the RegisterBanks.... > > I hope that this helps to tune in on things :) > > Then to the Modbus rundown. I'll got the Modbus Specs in the mean time, > and I will see about finding time to study what you send me (thanks) and > the Specs itself. I hope that I can be of help regarding to a solution > after that. > > Regards, > Dieter > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:41:50
|
> Subject: The quest continues > > Hi Kelvin, > > Hope you had a nice weekend, and don't let yourself be stressed too much > throughout the week ;) > > >One other thing I have to do is more the build environment of the project > >from make to Ant, especially if we intend to use Junit as the two > integrate > >nicely I'm told. I have never bothered to get Ant running before but I'm > >sure it won't be too much work. > > This is fairly easy, as I include ant into the package. The one you > downloaded came with a build.sh and a build.bat, both scripts that > directly call ant by invoking the JVM with right arguments. The necessary > JAR libraries are also in the package, that's ant.jar, jaxp.jar and > crimson.jar > > Thus you are able to build with > > build <ant target> (Windows) > build.sh ant <ant target> (Unix/Linux) > > directly from the commandline. I have recently switched my Development > Environment after testing a few different ones, and most of them have > support for directly using ant as build tool. > Targets are defined in build.xml, the file that came with my package is a > rather standard variant of it, not using too much of ant's more > complicated features: > compile (compiles the classes) > jar (makes a jar file) > dist (a tar.gz distribution, no "external" tools needed for this!) > zipdist (a zip distribution) > clean-dist > clean-classes > clean-all > > The behaviour of the build can be influenced easily by setting properties > (init target, command line or properties file). > I have now added also targets for TINI, so that together with the > libraries and files necessary for the task, one can directly create the > installable for TINI: > tini-compile (against the tiniclasses.jar) > tini-file (packaging the installable using TINIConvertor) > > Thanks for the hint with the -m, I will try it out and come up with a > solution where the main class can be set via a property (that can be > overidden on the commandline for example). > > I have also added a preliminary target for invoking junit tests: > test (invokes the junit testbed using the text runner) > > > >With regard to locking and concurrency issues in the register/coil banks > I > >also re-read the language spec relating to synchronized. None of the > >methods need to be public but all critical section of code need to be > >contained with a > > >synchronized(this) { > > // Critical code > >} > > >This will block on the lock for the object owning the method. Why I was > >taught about using the synchronized modifier for function prototypes and > not > >told of it's use in this context I'm not sure. This is quite an elegant > >IMHO. > > Well the elegancy of synchronized is just the start of the story. The book > and the web page I have pointed out to you do demonstrate the problems > with this modifier (or block) and discuss various concurrency > mechanisms/patterns. All source code is public domain..... > > >Not a problem. I was out for this weekend and have a fairly busy > >week but I have allocated all of next weekend for the task. So anything > you > >can code up before the end of the week would be great as I can see where > you > >have started to take things. I think with a decent effort this weekend I > >should be able to get a lot of this stuff working. > > I completely agree with you. I will see about getting things out until the > end of the week, allthough I am fairly busy too. However, I see a chance > to prove some concepts, so there is double use for a running > implementation. > > >I should check, what do you define the 'process image' to be. I > >want to avoid misinterpreting the term, as this could lead to great > >confusion. > I agree with you in this point too. It is important that we "talk the same > language". > What we have is > 1. A backend > Which can be a device with sensors or I/O's or another bus system (like > the collector mechanism you described) > 2.A frontend > Which gives access to the device/sensor/IO data from outside. This is the > Modbus/TCP Slave implementation (for our case and the collector example). > > Usually it is the case that the backend is hard realtime, and the frontend > not necessarily. > These hard realtime environments do everything in terms of cycles, and > thus there must be some mediator to the frontend part. This is often a > shared memory area, which people here call "Process image". This term is > also likely to be found in books on industrial bus systems. > > Now if we are talking only in terms of data acquisition (like with your > thermo iButtons), the issue is not as complicated, however, if you want to > seize acquisition and control (writing to outputs or registers) then you > have a big issue with concurrency, going far beyond "synchronized" :) > There is a need to define priorities (for reading and writing) and to take > care about things like priority inversion, deadlocking etc. > > Coming back to the process image, then what I am talking about is an OO > abstraction that reflects the "shared memory area". This would be like the > CoilBanks and the RegisterBanks.... > > I hope that this helps to tune in on things :) > > Then to the Modbus rundown. I'll got the Modbus Specs in the mean time, > and I will see about finding time to study what you send me (thanks) and > the Specs itself. I hope that I can be of help regarding to a solution > after that. > > Regards, > Dieter > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:38:53
|
> Subject: RE: More about the implementation > > Dieter, > > See my comments in the included reply below. > > If we can thrash out an architecture that we are both happy with over the > next week or so I will have a good shot at getting it implemented in a > basic way next weekend. > > Have a good weekend as I'm about to go home for the weekend. > > Cheers, > > Kelvin > > -----Original Message----- > From: Dieter Wimberger [SMTP:wi...@oe...] > Sent: Friday, October 12, 2001 12:29 > To: Proctor, Kelvin > Subject: More about the implementation > > Kelvin, > > It does not matter, I also just wrote down fast handed thoughts :) > I'll keep on with this, comming up with some more things directly related > to your last email: > > 1. > Following the specification, the slave implementation should be able > to support multiple concurrent clients. Due to the fact that the Java > platform > is well equipped for multithreading, I would suggest to go for > multithreaded > implementation. > > [Proctor, Kelvin] > > I agree. My ModbusTCPSlave class requires a socket in it's constructor, > and the examples I have created use a ServerSocket to spawn sockets and > create a new thread per connection. I have proved this works by having > two Citect Servers connected to a single TINI reading temperature values > and trending them. > > A good place to learn from are HTTP Server designs, which have the same > underlying request-response > principle. Best would be a thread pool, however, maybe this is too much > for TINI... > A possibility is to take a look at and learn from the sources of the > TiniHTTPServer > (with is in fact also a servlet engine). > > 2. > Regarding the registers and coil banks I would suggest to learn from PLC > and bus coupler concepts. > Considering 1. we are talking about a multi-master system, where the slave > exposes concurrent access to (a) backend device(s). It will require a very > well thought out design to insure consistency under all circumstances. > Probably I am too conservative, but I'd say it needs a stable and a little > bit more sophisticated mechanism then plain event/listener to ensure > sequential access. > > The best resource I know for concurrent programming in Java is > http://gee.cs.oswego.edu/dl/cpj/index.html > which represents the online supplement to > Concurrent Programming in Java: Design Principles and Patterns by Doug Lea > (ISBN 0-201-31009-0). Second edition published by Addison-Wesley, November > 1999. > > [Proctor, Kelvin] > > I only intended the event/listener interface as an interface that the > 'device' could use to prevent it having to poll the registers to see when > the master has set things. One of the most important items I had on my > to-do list was to make the Register/Coil banks more robust. The methods I > was going to use to assure sequential access was to make both read and > write function go through a single internal access function that is > synchronised. I think this should be sufficient, do you agree? > > The book you have pointed me to looks like a good resource, I will have to > check it out. > > 3. > I think that it should be possible to come up with a mechanism that reads > a ModbusRequest and constructs a ModBusResponse by interpreting what is > requested (via get methods of the particular > request) and setting up the response via set methods of the related > response message. > > The ModbusRequest could be staffed with > > a. a readData(DataInputStream in) method which is able to read > respectively interpret the bytes > which resemble the request message. > > b. a factory method in the ModbusRequest class, which can be called by the > handler, passing in an input stream (likely buffered). This method > should be able to determine the specific type of request message, > construct the specialized instance, and call it's readData(DataInputStream > in) method. > > c. A response factory method that returns the specialized ModbusResponse > instance, with header data and data set. > > With this setup, the functionality of reading/writing from/to the "device" > could be either embedded into the existing specialized ModbusRequest > classes, or into an even more specialized set of "SlaveModbusRequest" > classes that extend the existing ones. > > The sequence for the slave (i.e. server) would be as follows: > A Handler class (representing a thread or runable) reads the incoming > message into a buffered input stream and constructs the ModbusRequest > object by using the factory method mentioned above in (b). > Then it retrieves the response by the response factory mentioned above in > (c) and writes it to the specific transport (adding up special information > in case it is necessary, like the CRC for non TCP flavors). > > Maybe it is possible to enhance the performance by integrating some kind > of object recycling (reducing the amount of dynamically allocated memory), > and prediction algorithms to speed up reply times (which should bring > significant speed ups due to the polling nature of the protocol, with one > and the same read request being repeated often/continously). > > [Proctor, Kelvin] > I don't know how practical it is (or if your code already does this) but > I'm thinking of a system where you have a base ModbusRequest class, that > is extended by all the different request classes for the different > functions. You could have the code read in the request, call a > getFunction() methods and switch on the result and then cast it to the > particular request type. I'm note sure if this could be done directly but > humour me for a moment, I'm thinking of something like..... > > private ModbusRequest request; > > ....... > > transport.readRequest(request); > > switch (request.getFunction()) { > > case READ_MULTIPLE_REGISTERS: > request = (ReadMultipleRegistersRequest) request; > // code that can now do things that are specific to this being a > Read Multiple Registers request > break; > case WRITE_MULTIPLE_REGISTERS: > request = (WriteMultipleRegistersRequest) request; > // code that can now do things that are specific to this being a > Write Multiple Registers request > break; > } > > ........ > > I don't know if you can 'impart' knowledge onto an object in this way, it > just seemed a cool idea to me. > > The above might be crazy and when I get a chance to have a better look at > your code I'll probably be able to make more informed comments but I > figure now is the time to throw crazy ideas around and see what we come up > with.. > > The other way should simply be to create a new object based o the result > of getFunction(). > > 4. > I know that there are probably issues with the resources, but I think that > the dynamic allocation > should not be such an issue. Again the TINI Http Server could serve as an > example what can be done. > However, as I did not test the library I wrote on TINI so far, I am on > thin ice with whatever comment I come up :) > > [Proctor, Kelvin] > I agree. For this sort of exercise there is probably a way to produce an > implementation that does not consume *any* memory, but this is likely to > be ugly. For anything like this where reliability is a must then > minimising object creation is good but only to the extent allowable within > a clean and robust implementation. > > 5. > I agree that a test possibility is good to have. Probably it would be also > good to introduce some unit testing to ensure quality and functionality of > the code. > It depends a lot on the aims of the project as a whole. Introducing this > to the automation industry implies that some efforts have to be spend on > reliability :) > > [Proctor, Kelvin] > I couldn't agree more. I would like to see part of the distribution > include a full test suite with shell scripts or whatever to start the > servers and run the full suite of tests for all function codes. We are > lucky with this sort of application to be able to easily write such a test > suite, many projects would not be able to do such a test. > > Quite something to digest :) .....don't hesitate to ask if I was not clear > enough and further explanation is necessary or to criticize and oppose any > of the above ideas. > > Regards, > Dieter > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:38:40
|
> Subject: RE: About the Implementation > > Dieter, > > I did not articulate myself well in my e-mail to you yesterday afternoon > as I was only in the middle of coming up with the model I have now had > time to think about over night. > > As you point out the Modbus protocol is a pull (or polled) protocol and I > have not intention of setting up bi-directional channels etc.... to change > that in any way. > > My thoughts for how the slave implementations should occur are as follows. > > - The slave class runs as an independent thread that continually blocks > waiting for requests, processes them and sends responses. It does this in > an asynchronous manner not tied in any way to the behaviour of the > 'device' it is acting as an interface to. > - The slave class will reference a set of register/coil banks and this > will be the interaction it has with the 'device' it is acting as an > interface to. > - The 'device' will have two options for interfacing to the register/coil > banks. It can just read and write to the registers directly at it's own > leisure (ideal for it changing the values of input registers etc...) or it > can use a event/listener interface allowing multiple triggers and > different types of triggers. > > The even/listener interface would be particular useful for the output > registers/coils. The 'device' might put a listener on a particular coil > for a change of state event so that it will be called when the master > changes the value of the coil, and it can take appropriate action, without > the need to it to continually poll the coil. I think this would be a nice > OO way of doing things. > > With regards to the master the sort of setup you have in place is ideal. > There are no situation I can imagine where the master would need to run as > an independent thread. It should simply be an object that can be used by > the calling application to read requests and receive replies. > > With regard to implementation of functions I'm trying to think of a nice > command interface to allow the master and slave code to exist in the same > class file. This might be a silly idea but it sounded good to me in terms > of code maintenance. As I trying to do something silly here? What are > your thoughts? > > <NEW_IDEA> > Looking more closely at the definition of protected in java, it states > that classes in the same package have access to it as well. > > Possibly your request and reply classes could all be rolled into a single > class with a structure something like.... > > package net.sourceforge.jmodbus; > > class ReadMultipleRegisters extends ModbusCommand { > > public void setReference(int reference) > public void setWordCount(int wordCount) > > public boolean sendRequest() { > // Code that tests if all required data has been provided > // then assembles a request > // then sends the request > // then waits for a reply > // then decodes the reply > // returns a boolean to indicate if the command succeeded > } > > public void getRegisters(int[] registers) > > protected processRequest(ModbusMessage request, ModbusMessage reply) > { > // slave processing code here > } > > } > > This way the processRequest function is available to the slave class but > is not a public interface. > > </NEW_IDEA> > > The other thing I have done with my implementation so far is code it in > such a way that no memory is dynamically allocated while it is running. > This is also part of the fact that it was originally written to run on the > TINI. It also bades well for performance and stability. So if you see > weird things in my code, this would be the reason for it. > > An example of this is the ModbusMessage instances in the slave and master > code. Two objects are defined and then are reused for each request and > response cycle. > > Once we can work through a structure that provides all the facilities that > we require I don't think the porting of the code should be too difficult. > The other advantage that I have found with the project is that with both > master and slave functionality it allows me to easily create test programs > that fire up two threads that talk to themselves. > > Cheers, > > Kelvin > > -----Original Message----- > From: Dieter Wimberger [SMTP:wi...@oe...] > Sent: Wednesday, October 10, 2001 20:33 > To: Proctor, Kelvin > Subject: About the Implementation > > Hi Kelvin, > > I understand that the polling is an issue, however, my implementation > targeted a "dumb" remote I/O device which would only act as Modbus/TCP > slave. > It is even trimmed to react like a standard industrial bus implementation, > with a watchdog timeout which causes the device to shut down all I/O's in > case there is no further message from the master device. > We discussed this polling mechanism with the term "pull principle" on a > data flow level. > > I also understand the need for the opposite "push principle", which would > be far more effective for many cases. This would be best with kind of a > Subscribe/Unsubscribe mechanism, where a party that wants to receive data > from a specific source subscribes for getting it. > > Now to implement push and pull, you would need both a master & a slave > modbus implementation on both sides, and a specific mechanism that allows > the subscription and unsubscription (probably SEMI can be abused for > that). > In most cases I studied, the thing described above will only happen if two > more intelligent devices are talking with each other, thus meaning that it > is probably not necessary to stick with the Modbus, but to derive the best > of Modbus and common TCP, and make up a simpler and robust protocol that > supports a subscription/unsubscription mechanism. I had some ideas about > this, but people here decided that this would go too far :) > > Now to add slave functionality to the classes could be done fairly easy. I > guess it is not much of a problem to extend with the mechanism that reads > the message from the request, and builds up a response. > What it needs is a readFrom() in the Request, and to make the mutator > methods for the response public, to be able to set them for writing the > response. > It will also need some intelligent mechanism to get the data requested > from your Register/Coil bank implementations (which definately have to be > thread safe, and you could go for this by introducing a cycle and keeping > two copies of it, which are swapped at each cycle, much the way a PLC does > it) and put it into the response. Probably we will end up with a > MasterTransaction and a SlaveTransaction, where the second embeds the just > described mechanism. > > Regarding the DataInput/Output streams, well I think it should be done the > same way always, because two Java platforms have to be able to exchange > data over this streams. I have tested this on Windows and QNX (4 & > Realtime Platform), I also have a Mac, so we can check if it runs also on > a Motorolla platform. > I'd rather would say it does, and this way safes me a lot of code, which > is probably already in burned into a EEPROM (or somethings similar) and > optimized (on embedded systems). > > I hope that was not too confusing now :) I'll suggest we keep the > discussion, and see what we can come up with. > > Regards, > Dieter > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:37:51
|
> Subject: More about the implementation > > Kelvin, > > It does not matter, I also just wrote down fast handed thoughts :) > I'll keep on with this, comming up with some more things directly related > to your last email: > > 1. > Following the specification, the slave implementation should be able > to support multiple concurrent clients. Due to the fact that the Java > platform > is well equipped for multithreading, I would suggest to go for > multithreaded > implementation. > > A good place to learn from are HTTP Server designs, which have the same > underlying request-response > principle. Best would be a thread pool, however, maybe this is too much > for TINI... > A possibility is to take a look at and learn from the sources of the > TiniHTTPServer > (with is in fact also a servlet engine). > > 2. > Regarding the registers and coil banks I would suggest to learn from PLC > and bus coupler concepts. > Considering 1. we are talking about a multi-master system, where the slave > exposes concurrent access to (a) backend device(s). It will require a very > well thought out design to insure consistency under all circumstances. > Probably I am too conservative, but I'd say it needs a stable and a little > bit more sophisticated mechanism then plain event/listener to ensure > sequential access. > > The best resource I know for concurrent programming in Java is > http://gee.cs.oswego.edu/dl/cpj/index.html > which represents the online supplement to > Concurrent Programming in Java: Design Principles and Patterns by Doug Lea > (ISBN 0-201-31009-0). Second edition published by Addison-Wesley, November > 1999. > > 3. > I think that it should be possible to come up with a mechanism that reads > a ModbusRequest and constructs a ModBusResponse by interpreting what is > requested (via get methods of the particular > request) and setting up the response via set methods of the related > response message. > > The ModbusRequest could be staffed with > > a. a readData(DataInputStream in) method which is able to read > respectively interpret the bytes > which resemble the request message. > > b. a factory method in the ModbusRequest class, which can be called by the > handler, passing in an input stream (likely buffered). This method > should be able to determine the specific type of request message, > construct the specialized instance, and call it's readData(DataInputStream > in) method. > > c. A response factory method that returns the specialized ModbusResponse > instance, with header data and data set. > > With this setup, the functionality of reading/writing from/to the "device" > could be either embedded into the existing specialized ModbusRequest > classes, or into an even more specialized set of "SlaveModbusRequest" > classes that extend the existing ones. > > The sequence for the slave (i.e. server) would be as follows: > A Handler class (representing a thread or runable) reads the incoming > message into a buffered input stream and constructs the ModbusRequest > object by using the factory method mentioned above in (b). > Then it retrieves the response by the response factory mentioned above in > (c) and writes it to the specific transport (adding up special information > in case it is necessary, like the CRC for non TCP flavors). > > Maybe it is possible to enhance the performance by integrating some kind > of object recycling (reducing the amount of dynamically allocated memory), > and prediction algorithms to speed up reply times (which should bring > significant speed ups due to the polling nature of the protocol, with one > and the same read request being repeated often/continously). > > 4. > I know that there are probably issues with the resources, but I think that > the dynamic allocation > should not be such an issue. Again the TINI Http Server could serve as an > example what can be done. > However, as I did not test the library I wrote on TINI so far, I am on > thin ice with whatever comment I come up :) > > 5. > I agree that a test possibility is good to have. Probably it would be also > good to introduce some unit testing to ensure quality and functionality of > the code. > It depends a lot on the aims of the project as a whole. Introducing this > to the automation industry implies that some efforts have to be spend on > reliability :) > > > Quite something to digest :) .....don't hesitate to ask if I was not clear > enough and further explanation is necessary or to criticize and oppose any > of the above ideas. > > Regards, > Dieter > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:37:40
|
> Subject: About the Implementation > > Hi Kelvin, > > I understand that the polling is an issue, however, my implementation > targeted a "dumb" remote I/O device which would only act as Modbus/TCP > slave. > It is even trimmed to react like a standard industrial bus implementation, > with a watchdog timeout which causes the device to shut down all I/O's in > case there is no further message from the master device. > We discussed this polling mechanism with the term "pull principle" on a > data flow level. > > I also understand the need for the opposite "push principle", which would > be far more effective for many cases. This would be best with kind of a > Subscribe/Unsubscribe mechanism, where a party that wants to receive data > from a specific source subscribes for getting it. > > Now to implement push and pull, you would need both a master & a slave > modbus implementation on both sides, and a specific mechanism that allows > the subscription and unsubscription (probably SEMI can be abused for > that). > In most cases I studied, the thing described above will only happen if two > more intelligent devices are talking with each other, thus meaning that it > is probably not necessary to stick with the Modbus, but to derive the best > of Modbus and common TCP, and make up a simpler and robust protocol that > supports a subscription/unsubscription mechanism. I had some ideas about > this, but people here decided that this would go too far :) > > Now to add slave functionality to the classes could be done fairly easy. I > guess it is not much of a problem to extend with the mechanism that reads > the message from the request, and builds up a response. > What it needs is a readFrom() in the Request, and to make the mutator > methods for the response public, to be able to set them for writing the > response. > It will also need some intelligent mechanism to get the data requested > from your Register/Coil bank implementations (which definately have to be > thread safe, and you could go for this by introducing a cycle and keeping > two copies of it, which are swapped at each cycle, much the way a PLC does > it) and put it into the response. Probably we will end up with a > MasterTransaction and a SlaveTransaction, where the second embeds the just > described mechanism. > > Regarding the DataInput/Output streams, well I think it should be done the > same way always, because two Java platforms have to be able to exchange > data over this streams. I have tested this on Windows and QNX (4 & > Realtime Platform), I also have a Mac, so we can check if it runs also on > a Motorolla platform. > I'd rather would say it does, and this way safes me a lot of code, which > is probably already in burned into a EEPROM (or somethings similar) and > optimized (on embedded systems). > > I hope that was not too confusing now :) I'll suggest we keep the > discussion, and see what we can come up with. > > Regards, > Dieter > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:34:32
|
> Subject: RE: More on jModbus > > Dieter, > > Once again see my comments below. > > One other thing I have to do is more the build environment of the project > from make to Ant, especially if we intend to use Junit as the two > integrate nicely I'm told. I have never bothered to get Ant running > before but I'm sure it won't be too much work. > > With regard to locking and concurrency issues in the register/coil banks I > also re-read the language spec relating to synchronized. None of the > methods need to be public but all critical section of code need to be > contained with a > > synchronized(this) { > // Critical code > } > > This will block on the lock for the object owning the method. Why I was > taught about using the synchronized modifier for function prototypes and > not told of it's use in this context I'm not sure. This is quite an > elegant IMHO. > > Cheers, > > Kelvin > > -----Original Message----- > From: Dieter Wimberger [SMTP:di...@wi...] > Sent: Tuesday, October 16, 2001 4:29 > To: Kel...@al... > Subject: More on jModbus > > Hi Kelvin, > > I have some more suggestions and good news for you (at least I hope they > are good :) > > Things I have done lately: > 1. Undusted our TINI board, installed 1.02c firmware (latest) and got it > up and running again without much troubles. > > 2. Added TINI compile and packaging targets to the ant build file, to > compile against the TINI API and to convert the results to an installable. > What I could not figure out so far is if I can pass in the executeable as > a commandline argument, because the TINIConvertor is always taking the > first class with a main method that it finds. > If this is not possible (as it occurs to me) I will see about making the > packaging more flexible through using targets and properties (when > building). > I put everything necessary into the working directory, including the > tini.jar, tiniclasses.jar and the 1.02c firmware file (tini.db), thus the > build process is very straightforward :) > > [Proctor, Kelvin] > There is a flag in TINI convertor that lets you specify which classes main > method you want to use. I have just checked, it is the -m flag. > > I also tried running my lib against the Modbus Slave we have, and it seems > to work fine, not too much of a problem :) > > 3. I added the junit library to the libs directory. This is a very common > and "famous" unit testing framework, that can easily be integrated into > the build process (through ant). > All Java :) I have been successfully running this tools on Linux (intel > and ppc), Windows, MacOSX etc. > Probably you might want to take a look at the junit site > (http://junit.org), and the articles you can find there, which represent > tutorials and good ground information to get started with junit (including > the combine in with ant). > > If you can embrace this, I could come up with a basic testbed.... > > [Proctor, Kelvin] > While I have not used juint before I have read about it before and I'm > keen to get used to using a decent testing framework. I'll have more of a > look into this in the next few days. > > 4. I also made a shot on the architecture, after our discussions and your > last mail I was convinced that my idea would work out somehow. As it is > not possible to "impart knowledge" on an object other then through > aggregation, I have tried to prove my concept with the factory method. In > some way this is close to the alternative way you suggested ("simply > create a new object based on getFunction). > This creational pattern is a common and adequate way to hide specialized > implementations... > > Furthermore I implemented a basic server infrastructure (I did quite a lot > of work on this in the past), and came up with a Listener, plus a > ThreadPool implementation that is stable (lend some code from good old > Doug) and compact enough to serve it's purpose very well on TINI :) > By extending my existing objects the way I described in my mail, I > achieved good results pretty fast. I am amazed how easy that rolled > out.... would you be willing to take a look at it once I cleaned up the > code? > I hope I am not overunning you...... > > [Proctor, Kelvin] > Not a problem. I was out for this weekend and have a fairly busy week but > I have allocated all of next weekend for the task. So anything you can > code up before the end of the week would be great as I can see where you > have started to take things. I think with a decent effort this weekend I > should be able to get a lot of this stuff working. > > I migrated all to net.sourceforge.jmodbus.* and I am looking forward to > find an example implementation regarding the "process image". After some > discussions with my academical thesis advisor, I have decided to take a > deeper look on the issues and place interfaces meanwhile :) Those enhance > reusability and code interdependency very much. > I think I have to update the docs too.... > > [Proctor, Kelvin] > I should check, what do you define the 'process image' to be. I want to > avoid misinterpreting the term, as this could lead to great confusion. > > The thing I am also concerned about (despite the concurrency issues > BusCoupler<->ProcessImage<->Device) are the different Modbus flavors. I > have to take a more in depth look at your sources, to me it seemed that > you just put dummy implementations into the other transports. Is this > correct? > Do you have further information about the RTU and ASCII flavors? Would'nt > it be good to check out which constraints come from those? The only > specifical thing I know about is package CRC, this should not be such an > issue :) > > [Proctor, Kelvin] > As a basic rundown. > 1. All flavours of Modbus have a common section that includes a unit > address (1 byte) and then the normal message section (function + data of > some sort etc...) > 2. Modbus/TCP has a transaction ID field in it's header, so for the > purpose of modelling all modbus flavours will be considered to have a > transaction ID and some (ASCII and RTU) don't use it. > 3. The frame separators and checks are different. ASCII uses a ':' to > start a frame and a CR LF to end it. RTU uses a >3.5 character time break > as a frame separator. TCP has a fixed length frame header with frame > length field that requires you to keep track of the frame locations. > ASCII uses a LRC as a check, TRU uses a CRC and TCP relies on the CRC > check in the TCP layer for checking. > > The ModbusMessage class does need to be revised. I think it should store > the message internally as a byte array. It should provide get and set > methods for the transaction ID and the unit ID. (more about the unit ID in > the future, as there is a common use of building a ModbusTCP slave that > acts as a gateway / concentrator to a network of ModbusASCII/RTU connected > to it, and it raises some interesting issues with how the class interfaces > should be written). It should provide get methods to allow access to > Input and Output streams (ByteArray streams, to be used by the function > part of the code) and the internal byte array and length of the used > portion of the byte array (to be used by the transports). This would wrap > what is currently a *very* ugly class into an acceptable OO wrapper. > > The only transport I have finished is the TCP transport. You are correct > in assuming that the others have null implementations. I have worked out > how I want to write them but have not had time to code them yet. > > If we are changing the way a few things behave then I think we should > leave it that the send and receive frame commands transfer byte arrays > around the place, particularly due to the packaging that the transport > have to perform, but I don't think the rest of the classes should be using > them, we would be better encompassing them in ByteArray(I/O) streams. > This way your method of using the DataInput/Output streams can be used for > reading and writing values, which I like. > > Guess that is it for now, more to digest for you :) > > Regards, > Dieter > > > > > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:33:50
|
> Subject: More on jModbus > > Hi Kelvin, > > I have some more suggestions and good news for you (at least I hope they > are good :) > > Things I have done lately: > 1. Undusted our TINI board, installed 1.02c firmware (latest) and got it > up and running again without much troubles. > > 2. Added TINI compile and packaging targets to the ant build file, to > compile against the TINI API and to convert the results to an installable. > What I could not figure out so far is if I can pass in the executeable as > a commandline argument, because the TINIConvertor is always taking the > first class with a main method that it finds. > If this is not possible (as it occurs to me) I will see about making the > packaging more flexible through using targets and properties (when > building). > I put everything necessary into the working directory, including the > tini.jar, tiniclasses.jar and the 1.02c firmware file (tini.db), thus the > build process is very straightforward :) > > I also tried running my lib against the Modbus Slave we have, and it seems > to work fine, not too much of a problem :) > > 3. I added the junit library to the libs directory. This is a very common > and "famous" unit testing framework, that can easily be integrated into > the build process (through ant). > All Java :) I have been successfully running this tools on Linux (intel > and ppc), Windows, MacOSX etc. > Probably you might want to take a look at the junit site > (http://junit.org), and the articles you can find there, which represent > tutorials and good ground information to get started with junit (including > the combine in with ant). > > If you can embrace this, I could come up with a basic testbed.... > > 4. I also made a shot on the architecture, after our discussions and your > last mail I was convinced that my idea would work out somehow. As it is > not possible to "impart knowledge" on an object other then through > aggregation, I have tried to prove my concept with the factory method. In > some way this is close to the alternative way you suggested ("simply > create a new object based on getFunction). > This creational pattern is a common and adequate way to hide specialized > implementations... > > Furthermore I implemented a basic server infrastructure (I did quite a lot > of work on this in the past), and came up with a Listener, plus a > ThreadPool implementation that is stable (lend some code from good old > Doug) and compact enough to serve it's purpose very well on TINI :) > By extending my existing objects the way I described in my mail, I > achieved good results pretty fast. I am amazed how easy that rolled > out.... would you be willing to take a look at it once I cleaned up the > code? > I hope I am not overunning you...... > > I migrated all to net.sourceforge.jmodbus.* and I am looking forward to > find an example implementation regarding the "process image". After some > discussions with my academical thesis advisor, I have decided to take a > deeper look on the issues and place interfaces meanwhile :) Those enhance > reusability and code interdependency very much. > I think I have to update the docs too.... > > The thing I am also concerned about (despite the concurrency issues > BusCoupler<->ProcessImage<->Device) are the different Modbus flavors. I > have to take a more in depth look at your sources, to me it seemed that > you just put dummy implementations into the other transports. Is this > correct? > Do you have further information about the RTU and ASCII flavors? Would'nt > it be good to check out which constraints come from those? The only > specifical thing I know about is package CRC, this should not be such an > issue :) > > > Guess that is it for now, more to digest for you :) > > Regards, > Dieter > > > > > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:33:33
|
> Subject: RE: jModbus project, Link for my package > > Dieter, > > I have added you to the developer list for the jModbus project. > > While at work I have had a bit of a look at the code you have sent me. It > looks really good. The more I think about the way you have done some > things the more I like them. I'm still tossing up a few of the ways > things would be handled in moving to master and slave in the same codebase > but the feel is very good. > > The other issue with master/slave functionality is the two different ways > in which this would want to be used. Master code is almost always going > to be used in a polled manner, as your interface works. Slave code is > often going to want to run as a separate thread that services requests > about a set of registers/coils most of the time. I'm wondering if there > would be much need for a system where the slave sends events/message > etc... to another device to indicate that something has changed, as > opposed to having the rest of your application continually poll the > registers/coils for changes etc... Another topic for more thought. > > Possibly this is something I should build into the > ModbusRegisterBank/ModbusCoilBank classes. I could provide an interface > where you could setup triggers so that events would be fired when certain > registers or coils changed etc... > > I will get a chance in a week and a half to try and merge in the code and > see how it looks. Some of my code was written with the TINI in mind a bit > too much and I think I should go for a slightly higher level interface, as > you have done, and forget the small speed decrease. > > I also noticed that you used the Data(Input/Output)Stream classes for > reading and writing registers. While I know it does use big-edian > encoding, is there anyway that actually states that the class must do > that? In the API docs it just says 'in a machine independent way'. I'm > wondering if this is guaranteed to be identical across all API > implementations? > > Anyway thanks for the code and I look forward to getting a change to play > with it shortly. If this merges nicely and I get the other transports > fixed then release 0.2.0 should be a fairly comprehensive release. > > Cheers, > > Kelvin > > -----Original Message----- > From: Dieter Wimberger [SMTP:wi...@oe...] > Sent: Wednesday, October 10, 2001 6:29 > To: Proctor, Kelvin > Subject: Re: jModbus project, Link for my package > > Hi Kelvin, > > You should be able to download the complete package from > http://g5311m.unileoben.ac.at/~wimpi/modbus.zip > > It should be 968k , the MD5 is > d53f49e6f069940f9dd80c9d5e639ea9 > > The size is because everything is included (build tool and scripts, > sources, documentation). > > Let me know if it worked, and what you think. > > Regards, > Dieter Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:32:21
|
> Subject: Re: jModbus project, Link for my package > > Hi Kelvin, > > You should be able to download the complete package from > http://g5311m.unileoben.ac.at/~wimpi/modbus.zip > > It should be 968k , the MD5 is > d53f49e6f069940f9dd80c9d5e639ea9 > > The size is because everything is included (build tool and scripts, > sources, documentation). > > Let me know if it worked, and what you think. > > Regards, > Dieter Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:31:52
|
> Subject: Re: jModbus Project > > Hi Kelvin, > > I will put together my package and send you a link for downloading as a > start. > I think this allows you to get a better picture and an idea if the thing > is useful at all :) > I guess I manage that until tonight. > > Regarding the position of myself, well I am writing a master thesis which > is mentored by a company. This means I have both an advisor in the > academia, and one in the company. > The Modbus/TCP implementation is no major part of the thesis at all, so it > does not matter much, and if the two parties are satisfied with the link, > than I am fine with it. > > My username at SF is wimpi, you can also visit the other projects I have > running there :) > > The country is Austria, yes, the Institute is Institute for Automation, > University of Leoben (http://automation.unileoben.ac.at), and the company > is TDE Thonhauser Data Engineering (http://www.tde.at). > > Regards, > Dieter > Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:31:34
|
> Subject: RE: jModbus Project > > Dieter, > > I would see no problem on the main page stating that a large body of the > code was released by yourself and you company and providing a link to your > web site. In all the source files that are merged across from your code > base they should also contain your original copyright notices or at least > a notice stating the code was based on your release appended after the > project license notice. > > With open source related issue I can understand the position of your > company. This is the sort of reason that I was careful to use a BSD style > license rather than the GPL as it is a little more friendly to commercial > interests that would like to use the code base. > > I'm assuming you have a sourceforge account, if so what is your username > so I can add you to the developers list so you can start changing things. > > > I would like to integrate your command structure into the code as the > first thing. The code will need to be modified / duplicated to work for > master and slave classes, a possibly way of doing this is to have the base > abstract class have some sort of master() and slave() functions. This way > the code for the master and slave implementation of any command would have > to be in one file, which would be good from a code maintenance > perspective. > > My classes representing a ModbusMessage and the Register/Coil banks are > also very rough at this stage. They need to be made much more OO, rugged > and thread safe. > > I have also stuffed up my use of bit shift operators in places and will be > modifying things to look identical to the code in the > Data(Input/Output)Stream classes that ship with the standard Sun JDK. > > I must also ask which country the .at top level domain is for, I'm > assuming Austria but I had trouble confirming that. > > Cheers, > > Kelvin > > -----Original Message----- > From: Dieter Wimberger [SMTP:wi...@oe...] > Sent: Tuesday, October 09, 2001 5:01 > To: Proctor, Kelvin > Subject: RE: jmodbus Project > > Hi Kelvin, > > I have taken a look at your design, and I am aware of the differences. > I suggested the merger, because I think that a synergy effect could be > achieved anyway :) > > I am willing to make it open source, and I am quite involved in the idea > of open source (I'll run about four projects myself, and have contributed > to others...). > I have also read the pointed out papers plus a lot of others which discuss > possible business models around open source. However, I think I have to > accept that for some business models it (the idea) does not apply, simply > due to the company culture, strategy, market (!) and their right to think > different :) > > What I think that the institute and the company expect if this goes open > source, is to be named as supporters with a link to their site (which is > fair I guess, and does no harm). > > I have been running my implementation against a Beckhoff BK9000 Ethernet > Buskoppler with several attached modules. This is standard off-the-shelf > industrial remote I/O hardware. > There are plans for using it against a Schneider PLC, but I will not > necessarily be directly involved into this. We also have a TINI board > available and I could see about getting somebody to work with it. > > Please let me know what you think about the links issue, and how you would > like to proceed. > I would suggest to add my package up as another module to your project, > and merge the best of both code bases into another module. Probably you > also just want me to send you the package so that you can see sources > first. > > Comments are welcome and if you have more questions just go ahead, I'll > try to answer them. > > Regards, > Dieter Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:28:59
|
> Subject: RE: jmodbus Project > > Hi Kelvin, > > I have taken a look at your design, and I am aware of the differences. > I suggested the merger, because I think that a synergy effect could be > achieved anyway :) > > I am willing to make it open source, and I am quite involved in the idea > of open source (I'll run about four projects myself, and have contributed > to others...). > I have also read the pointed out papers plus a lot of others which discuss > possible business models around open source. However, I think I have to > accept that for some business models it (the idea) does not apply, simply > due to the company culture, strategy, market (!) and their right to think > different :) > > What I think that the institute and the company expect if this goes open > source, is to be named as supporters with a link to their site (which is > fair I guess, and does no harm). > > I have been running my implementation against a Beckhoff BK9000 Ethernet > Buskoppler with several attached modules. This is standard off-the-shelf > industrial remote I/O hardware. > There are plans for using it against a Schneider PLC, but I will not > necessarily be directly involved into this. We also have a TINI board > available and I could see about getting somebody to work with it. > > Please let me know what you think about the links issue, and how you would > like to proceed. > I would suggest to add my package up as another module to your project, > and merge the best of both code bases into another module. Probably you > also just want me to send you the package so that you can see sources > first. > > Comments are welcome and if you have more questions just go ahead, I'll > try to answer them. > > Regards, > Dieter Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:26:43
|
> Dieter, > > Thank-you for sending the link to your site, it is interesting to see how > you have gone about many things. I like the way you have gone about > setting out all the commands in a proper OO structure. > > My design parameters were somewhat different and I will explain some of > them. > * Code base to be able to act as either master or slave (Master > implementations are common, slave implementations are rare on the whole - > which is why I needed to write one) > * Code to be able to which between different flavours of Modbus easily > * Code to be shared between slaves/masters and transports as much as > possible. > > Based on the above I have chose the architecture that I have. I think > this accomplishes my goals in a fairly elegant way. The implementation of > functions to date is very primitive and this is an area I am intending to > work on. I like the method you have adopted and would intend to implement > something similar. The architecture must also be capable of being > extended to enable SEMI Object Messaging over Modbus/TCP and the like. > > If you are able to make you code open source I would be very interested in > merging the two code bases together matching your command implementation > structure with my master/slave and transport structure. > > I'm also interested to know what devices you were talking to that > necessitated the code that you have written. I needed to allow a Citect > SCADA system to talk to a network of TINIs with cheap temperature sensors > attached for environmental and motor state monitoring. > > If you are looking for information to convince people to take code to open > source can I recommend you read some of the writing of Eric Raymond. They > can be found at http://www.tuxedo.org/~esr/writings/ and there are three > main papers in the series entitled The Cathedral and the Bazaar, > Homesteading the Noosphere and The Magic Cauldron. They are quite long > but if you are interested in open source they make a great read. > > > Regards, > > Kelvin > > > -----Original Message----- > From: Dieter Wimberger <wi...@oe...> > Sent: Saturday, 6 October 2001 17:50 > To: ke...@us... > Subject: jmodbus Project > > Hi there, > > I have done a Modbus TCP implementation in Java as part of my master > thesis. > The institute and company I am working for were not quite convinced to > make this implementation open source, and I did not have much arguments in > favor until I stumbled over your project. > Now I have convinced people to let me try to join forces with you. > I would like to ask you to check out: > http://g5311m.unileoben.ac.at/~wimpi/modbusdocs > You should be able to find a documentation which I assembled to be > prepared for the case that I could convince people to go open source; UML > class diagrams and the API docs are included. > > I know that I have taken a completely different approach, but maybe you > are interested anyway. In case you are, just drop me a mail and we see how > we proceed. > > Regards, > Dieter > > PS: I did not try to run this on TINI, but we have a 1 MB version around > to run tests... Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 23:25:59
|
Hi there, I have done a Modbus TCP implementation in Java as part of my master thesis. The institute and company I am working for were not quite convinced to make this implementation open source, and I did not have much arguments in favor until I stumbled over your project. Now I have convinced people to let me try to join forces with you. I would like to ask you to check out: http://g5311m.unileoben.ac.at/~wimpi/modbusdocs You should be able to find a documentation which I assembled to be prepared for the case that I could convince people to go open source; UML class diagrams and the API docs are included. I know that I have taken a completely different approach, but maybe you are interested anyway. In case you are, just drop me a mail and we see how we proceed. Regards, Dieter PS: I did not try to run this on TINI, but we have a 1 MB version around to run tests... Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |
From: Proctor, K. <Kel...@al...> - 2001-10-17 22:28:32
|
Welcome to the jModbus project's developers list. Kelvin Proctor Project Administrator Alcoa World Alumina Australia is a trading name of Alcoa of Australia Limited, ACN 004 879 298 |