The micro-controller units need to effectively communicate with other systems. These systems can be the PC, smartphones, or any random smart embedded system. And for that, they need specific communication protocols.  In case to communicate with others and to provide an anticipated output, each communicating entity must abide by the protocols to exchange the information.

The term protocol here encapsulates all the rules, semantics, syntaxes, and synchronization among the communicating systems. They can be implemented by either hardware or software or even with a combination of both.

In general, there are two communication protocols – Intersystem Protocol and Intra-system Protocol.

The intersystem protocol establishes communication between two communicating devices like PC and Developmental boards viz. USB, UART, USART. The intra-system protocols establish communication among different units of the circuit board viz. I2C, SPI, CAN etc.

While designing the communication protocol, things are not as easy as discussed above. When one has full control over finalizing the communication protocol between two ends without any restriction to apply only what is in hands- then the situation gets much more complex.

With this article, Team InSemi throws light on the basic aspects that one needs to keep in mind in bringing up the most apt communication protocols for a specific embedded system, quickly!

Development Phase

The conventional approach is to set a frame structure first. The frame consists of a header with a fixed number of bytes and a variable-size payload. Let’s check the header first –

Header

The header contains the data fields that are common to all the frames. These frames are then exchanged between the communications. The size of the frame defines the payload. The data in the header, to save space, is usually encoded in fields that are not in the multiple of bytes. If space saving is not a constraint then everything can be in byte-multiples and this will eliminate the complexities in handling the bit-fields. It is always prudential to get the header small so that it fits into the 32-bit or 64-bit variable. This way it would be easier to shift bits from one variable to another to encode & decode the values.

If the header is encoded in the Big Endian then the data is naturally read in both the logic analyser and Hex Dump. This encoding also assists in aligning the fields to a 4-bit boundary. One must also consider leaving some free bits in the header for future usage.

Payload

One must try to avoid bit fields in the payloads. Here, everything must be in the byte multiple and the Big Endian should also be considered for easy debugging. If the 32-bit values are more in the payload then one should consider adding some padding there. This will help those values to end up in a 32-bit aligned position. If they are not aligned then the developers must pack & unpack them byte by byte. Such an alignment will make the code faster & simpler.

The aligned approach must be attained in a structured manner and an interface must be made. Ad-hoc in-place casts should be avoided.

Limits

Depending on the particularity of a specific application one can also put limits on the protocol values. So even after having a 14-bit size field, one can define that the maximum frame size in this application is 256 bytes. This makes memory management an easier task, especially in the resource crunch MCUs.

Code Management

It is always prudential to create and retain a special file containing the specifications regarding the fields in your protocol. Unless the payload data is differently formatted for other specs, this file should contain information regarding both the header and payload.

Also, as no one likes or wants to repeatedly implement the bit shifting and masking around so it would be better to get some functions or macros to work together in the developed specifications.

Therefore, the file thus created should be made common for all and should be available with all the places that are using or will use this new protocol.

Also, make sure to have a single place in the software that handles the protocol. A centralized unit imparts several benefits. Encoding and decoding protocol header, easy error detection & recovery, and facilitation of a place to log and dump the exchanged data- are a few major ones!

Error Detection

In the design process, developers are sure to witness various errors in vivid forms. If one develops the possibility of data loss, link disconnections, and duplication of data, then one is sure to be wary of designs. Even if something is being implemented on the protocol with the guarantee of data integrity then there is a possibility of link disconnections.

Bugs can also be there in the main code!

If your system interprets a clear error message in case of anything is wrong then will be highly beneficial. This thing must be kept in mind while designing the main system.

A cyclic redundancy check is the most common way to check data integrity. Both the wrong and missing data are protected with this approach. And in case of data being discarded the best solution lies in expecting a response for anything one sends.

Timeouts are also important as they allow the participating system in the communication link to resynchronize. To tackle the timeout situation a timeout window is inserted in both the transmitter and receiver sides. From the transmitter side, the timeout is activated after the transmission is complete and it is defined in advance how long the system must wait before trying again. From the receiver’s end, it is activated when the reception starts and it defines how long the receiver should wait for the existing frame to complete before dropping it.

Start Codes

Adding a fixed value as the first byte of every frame makes development quite easier. This eliminates the possibility of random data appearing on the receiving end at the early stages. This also eases the visual inspection of Hex dumps of frames. Oscilloscopes and logic analysers are also easily triggered by this pattern. This greatly helps in a better live view of the data exchange in case debugging is required.

            With these tips and tricks, one can easily develop the communication protocol for their embedded systems. We would love to hear from you about what you loved most. Additions and constructive criticism will be warmly welcomed!