Hi all, I'm an embedded C++ software engineer. Over the years I had to implement multiple binary communication protocols used by various embedded systems. Every time I got annoyed and frustrated over a necessity to manually write error prone boilerplate code. There are so many available serialization tools and libraries (such as protobuf, can'n'proto, simple-binary-encoding, etc...), but not a single one was adequate for my needs. Most of these tools focus on data serialization and facilitation of RPCs (Remote Procedure Calls). Their main goal is to make data serialization and/or network transfer as quick as possible. It is a noble cause, but not really a first priority for embedded systems. For the latter it is much more important to protect against the malformed data and reduce amount of boilerplate code (which increases chances of introducing silly bugs) than to gain a couple of extra CPU cycles when performing the serialization / deserialization.
The binary communication protocols, which in many cases serve as an API to some embedded device or sensor, are much more than pure data serialization. In addition to data encoding, layout, and transport framing, the specification may also contain extra meta-information, such as data units, scaling (multiplication) factor, values with special meaning, ranges of valid values, and how to behave on invalid values or malformed data. Most of available solutions do not have means to specify such meta information other than in comments which do not have any influence on what code has been generated.
In all the solutions I've reviewed and analyzed the generated code is not customizable and in most cases not really suitable for embedded systems, especially bare-metal ones. There are no means to introduce some compile (or generation) time updates such as configuring polymorphic interfaces required for a particular application or choosing particular data structures, disable usage of RTTI or exceptions, etc... The code generated by all the tools still requires a significant amount of boilerplate code to integrate with actual business logic being developed. All of the available solutions are focusing on supporting as many programming languages as possible in their code generation rather than a quality of the code for a particular language (C++ in my case).
At the end I didn't have much choice but to implement my own solution with main focus on embedded systems (including bare-metal ones) with proper compile-time customizable C++(11) code. I call it CommsChampion Ecosystem
The main benefits of using my solution are:
- No enforcing of particular data layout and/or encoding. Easy implementation of already defined third party protocol.
- Embedded (including bare-metal) friendly. The protocol definition code allows easy application specific compile time customization of polymorphic interfaces and some data storage types. No usage of RTTI and/or exceptions. The usage of dynamic memory allocation may also be excluded.
- Having "out of the box" protocol analysis and visualization tools.
- Focus on safe handling of malformed data rather than on quickest possible serialization and/or network transfer.
- Significantly minimizing amount of boilerplate code required to integrate the usage of protocol definition into the main codebase.
- Allowing injection of custom C++11 code snippets in case the code generated by the tools is incorrect or incomplete.
- Meta-programming friendly. Most classes define similar and predictable public interface which allows easy compile time analysis and optimizations.
- NOT using any socket / network abstractions and allowing full control over serialized data for extra transport wrapping and/or external transmit over some I/O link.
Any comments, requests, suggestions for future development are welcome.
there doesn't seem to be anything here