From: Wimberger D. <die...@td...> - 2001-11-05 15:54:22
|
Hi Kelvin, > [Proctor, Kelvin] =20 > This is becoming vitally important for the RTU transport, there is >no way it could work without looking for whole frames. I was working on >that over the weekend and I'm having real trouble coming up with system for >doing this under the javax.comm API. Most implementations that are floating >around on the net (under any language) are Master devices and simply write a >frame, pause and then read until there is no more to read. This works fine >for the master only cause but I would like something that conforms to the >spec a little better and is more suitable for use in either a master or a >slave. The implementations that really do stick to the spec (such as PLC's) >have access to the UART in more primitive and powerful way usually. I'll >find some way to solve this but it might take some more work yet. Well I have a design that works out with the javax.comm API ;) The idea I had was to use a Pipe for "pumping" the incoming data through on the respective registered event: public void serialEvent(SerialPortEvent e) { // Determine type of event. switch (e.getEventType()) { //pump data through the pipe case SerialPortEvent.DATA_AVAILABLE: try { while (m_SerialIn.available()>0) { try { int b=3Dm_SerialIn.read(); //DEBUG: m_Pipe.write(m_SerialIn.read()); m_Pipe.write(b); //DEBUG: System.out.println("Piped byte "+b+"=3D"+(char)b); } catch (IOException ex) { System.err.println(ex); return; } } } catch (Exception ex) { //handle } break; } }//serialEvent Just to get the idea.... I have also provided the infrastructure like for TCP, i.e. there is now a ModbusSerialListener, and a SerialConnection, and a ModbusSerialTransaction. =20 =20 > I have also done a LRC, it would be good to have some results to test > against..it is much simpler then the version you created, and it gives > the same results but anyway, maybe there is some official way to test > this. >=20 > [Proctor, Kelvin] =20 > I'll be fascinated to see this, the version I came up with was >pretty small already. With a function like this (and more importantly for >the CRC for RTU) getting a fast implementation is the most important issue, >even at he expense of 10 vs 5 lines of code. I have not had a serious think >out run time of my algorithm yet, I just hacked up something that worked. I made a trial and error approach, and I realized that Java naturally does the job: private final int getLRC(byte[] data,int tailskip) { byte lrc=3D0; for (int i =3D 0; i < data.length-tailskip; i++) { lrc+=3Ddata[i]; } return (int)-lrc; }//getLRC The tailskip is just to skip the LRC byte that is part of the byte[] data (because that one represents the complete frame without FRAME_START and FRAME_END). You see it is a one line algorithm, however, there is one thing I am not exactly sure about and that is the=20 minus in the return. This way the result is exactly the same as coming from your algorithm. =20 >> [Wimberger, Dieter] >> Another point I did not have the time to figure out are the >> specifications for the serial communication. As each cycle is a >> Transaction (Request by Master, Response by addressed Client) there must >> be some mechanism that repeats frames if there is no answer from any >> client (timeout??) or to notify the master that a frame is corrupt etc.=20 >> Any clue about this so far? >>=20 > [Proctor, Kelvin] =20 > You are correct here. The spec is a little vague about how all of >this should be handled. My original code does not handle any of this at all >really, only working out if a packet was sent correctly or not and returning >true or false. The method you have used in creating a Connection class is a >good solution to this. You can set it up to know how many times to retry, >set the timeouts etc.. and it can reference the transport. It adds another >layer but I think it is justified. Well this is a bit what I did, as I already mentioned above. It looks pretty much the same as for TCP now, it is just that a few of those mechanisms are not hooked up yet (i.e. the exception handling etc.). However, there must be a schema for reactions, as this is supposed to be an industrial field bus. I will plunge into a research session, when I find some time. We have resources here probably, as some guys are teaching data transmission and industrial field bus lectures :) >=20 > [Proctor, Kelvin] =20 > This was always likely to be that hardest part of the design. My >design was written with the TINI in mind and written to be able to act as a >master or a slave. You code was written with the master only in mind and >designed to be run from a PC or similar. These two setups have very >different requirements. Hmm yes. Well one thing is that it runs on TINI, and I am testing this, however, to be optimized to run there and to run there are two different things. I'll say with a bit of work we get results that will be fine for us. > Until we work out where we want to go with this I'll keep plugging >away with my transport code under my old architecture (as it's more basic >and hence a little simpler to integrate into). I'll have another go at the >serial stuff tonight and see where it gets me.=20 Well that I agree, still it is nice to see that most of the infrastructure as I put it up seems to work out also for the serial transport flavors :) I will try to put up the package as soon as possible, so that you can take a look at things, and judge were you want to go. I guess with the RTU it is going to be another challenge, because I wonder how to=20 measure 3.5 character times etc. Without a Mechanism to ensure that a message was received or not, there is not much chance to get this going nicely from Java (with this high level view of the system...) > I'm interested in what you would intend to use the ObjectPool for? >I have usually seen this term used in the context of web servers where a set >of threads is created and then reset after a connection assigned to them >dies, as opposed to creating a new thread each time. If this is the case >I'm note sure it would really help this all that much. In my experience of >control type application this is not as much of a problem. In the case of a >web server you will have a lot of very short sessions open and closed all >the time, each dealing with only a single request. In the case of ModbusTCP >this is unlikely as most application will open a single connect and keep it >open send possibly millions of requests across a single connection. > If I have your definition of an ObjectPool wrong let me know. What you are describing is a so called thread pool. I have implemented this for the TCPSlave, as it is perfectly suited for multithreaded handling of Request-Response problems :) Runs also nicely on Tini..... An ObjectPool is to recycle instances at runtime. This would prevent the code from constantly creating new instances and garbage collecting unreferenced old ones. This is not the best practice for all cases, as the trade off on present up to date computers with an up-to date JVM is low compared to the additional cost on creating and garbage collecting. At least this is what "Effective Java" author Joshua Bloch believes. However, we are dealing with an embedded system, and probably the trade off balance is better for the pool implementation. This would clutter the code a little bit more, and needs care when Recycling (to assert that the object is like newly created), but maybe it is worth a try..... Best regards, Dieter =20 |