How can I implement a serial communication protocol in an object-oriented form?

Im works with a built-in device that connects to a PC using RS232.

I need to make software to communicate with this embedded device.

I am programming in Delphi. I have never used an object oriented approach before. But I'm trying to change that.

I canโ€™t think in an object oriented way to solve this problem.

I have this protocol:

<STX><STX><COMMAND>[<DATA><DATA>...]<CHKSUM><ETX> 

Where:

 <STX> is the Start of TeXt (0x55); <COMMAND> can be 0x01 for read, 0x02 for write, etc; <DATA> is any value; <CHKSUM> is the checksum; <ETX> is the End of TeXt (0x04). 

The software computer will send the command through the serial port, and the device will respond using the same protocol.

For instance:

 Reset command PC sends : <STX><STX><0x09><0x00><CHKSUM><ETX> Device answer: <STX><STX><0x09><0x00><CHKSUM><ETX> Get Version PC sends : <STX><STX><0x00><0x02><CHKSUM><ETX> Device answer: <STX><STX><0x00><0x00><VER_L><VER_H><CHKSUM><ETX> 

I need to send a file stream to a device.

I would like to receive suggestions and / or examples of the best way to implement this in an object-oriented manner. I would also like to do a unit test.

thanks

+4
source share
3 answers

You should look at other communication models for transmission / reception, for example HTTP. In .NET, the HTTPWebRequest object is where you collect all the pieces of information that should be sent over the wire, including the command (HTTP METHOD: GET, PUT, POST, etc.) and a stream of bytes. The HTTPWebRequest object (and the HTTP stack) internally deals with the โ€œworkflowโ€ of computing checksums of data, breaking big data into smaller packets, etc. All your code needs to do is build a request object, set a command, assign a data stream to the property of the request object, and send.

Another reason you should look for existing models of communication objects, such as .NET HTTP, is that serial communications are usually asynchronous from the perspective of your CPU. While transmitting request characters to the serial port and while waiting for a response, a lot of processor time may elapse. Use an asynchronous model for your request / response so as not to block the calling thread and potentially freeze your user interface.

To continue the .NET HTTP example, HTTPWebRequest has a GetResponse method that sends a request and blocks the calling thread until a response is received. HTTPWebRequest also has a pair of BeginGetResponse () / EndGetResponse () so you can send a request and provide a callback that will be executed when the response arrives soon.

Even if your direct design is in order with a synchronous call model with thread blocking, you should at least investigate asynchronous coding patterns and consider implementing your object as such. You can always call an asynchronous method synchronously with blocking threads, but it is much more difficult to call a synchronous method asynchronously. Invest a little time to give yourself more opportunities in the future.

+3
source

Well, I think there are as many solutions as there are programmers. Without knowing more about your system, I would probably go with this approach:

Create a base class of commands, say; TBaseCommand. Define your common interface at this level, e.g. Send (), Receive (), Run (), etc.

Only complete the code for functions common to all commands, such as send, receive, etc.

Functions that will differ during execution become virtual to define at the next level. From this, derive a new class for each command and fill in the command code, for example Run ().

Having the Run () function makes it easy to simulate your commands on the screen by overriding the Run () function.

and are your transport protocol and should be applied and deprived of your communication interface (a separate protocol class?). Your protocol class may also handle checksum errors and try to resend, etc. If this cannot be resolved, a signal error.

These were just a few things on my head with your limited description ...

+1
source

Partly difficult to answer, but from a small amount of information I have, here is how I do it:

Either you are a class that knows how to serialize itself, or you can use the visitor template to serialize. This has the advantage that you separate your data from serialization and make it easier to implement another serialization mechanism.

So, I will have a Data class, a Command class that contains a collection (select your preferred container) Data. The Command class is likely to handle the checksum calculation using a public method. I would also have a communication class to encapsulate the team and start and end the connection. Then I will have a class responsible for interacting with the serial port, which will have a send method that will reference the communication class.

From the available information, what can I think of in terms of design.

As for unit test, with a good design, you should be able to unit test almost everything. Remember to use stubs, you donโ€™t want to hit this serial port during testing, so create a fake serial communication class that writes to a string, for example, and compares the output string with the expected specification of the value.

0
source

All Articles