
Guide to Implementing Communication Protocols in C++ for Embedded Systems - ingve
https://arobenko.gitbooks.io/comms-protocols-cpp/content/
======
berti
> Many developers implement this logic using simple switch statement. However,
> after about 7 - 10 cases such dispatch mechanism becomes quite inefficient,
> and its inefficiency grows with number of new messages being introduced.

It's actually pretty cheap on ARM (2 cycles [1]), if the message IDs are
consecutive, due to TBB/TBH [2], and GCC will use it when appropriate. Not
sure if x86 has an equivalent.

[1]
[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc....](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/CHDDIGAC.html)
[2]
[http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/BA...](http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/BABJHIGF.html)

~~~
vardump
Switch is efficient on pretty much any platform I can think of (well, except
some 8-bit uC compilers...).

That statement about switch inefficiency is simply not true, except for sparse
case values.

But since one can generally choose those values (and they're often a running
enum anyways), it's really a non-issue.

For sparse case, it's better to use a hash table. Perhaps a build phase to
generate a perfect hash
([https://en.wikipedia.org/wiki/Perfect_hash_function](https://en.wikipedia.org/wiki/Perfect_hash_function))
to map each possible input value to continuous range of integer values.

~~~
brandmeyer
> except for sparse case values

Even for sparse case values the compiler will emit a binary search once the
list of labels is long enough.

~~~
convolvatron
i’m pretty sure i’ve heard of compilers generating a perfect hash (since the
key space is known) also

~~~
vardump
This has been my expectation as well, but haven't seen this in real life.

I guess the main issue is that the compiler will need to also ensure no value
outside the expected set can match a case statement either (no match and
default cases), which kinda negates the benefit.

Maybe there are cases this is generated, anyone seen compiler generating
those?

I wonder whether it is possible to generate reversible (almost) perfect
"hashes"?

I mean a hash where every unique input value is guaranteed to map to a unique
output value. Because this kind of hash could be used to handle no-
match/default case safely.

------
bsenftner
Just use Restbed and you have as much of Apache's abilities as you want. I've
been using Restbed for a few years now, for a communications application that
scales from enterprise to embeds inside devices, and Restbed handles it all.
[https://github.com/corvusoft/restbed](https://github.com/corvusoft/restbed)

~~~
gmueckl
Sorry, but this misses the point completely. The guide is about implementing
communication on platforms that can be so tiny that using embedded OSes like
FreeRTOS becomes tight and the RAM might not be sufficient to store a single
TCP/IP packet. A full blown HTTP stack is a luxury that is way beyond these
platforms. Besides, how do you do implement HTTP over I2C or SPI?

------
codehero
I tried really hard to find a main() function browsing the demo source code,
but I could not. I also find it interesting that code boilerplating is called
out as a problem, but I run into code like this:

    
    
      #include "Protocol.h"
    
      #include "comms/comms.h"
    
      namespace cc = comms_champion;
    
      namespace demo
      {
    
      namespace cc_plugin
      {
    
      Protocol::~Protocol() noexcept = default;
    
      const QString& Protocol::nameImpl() const
      {
          static const QString& Str("Demo");
          return Str;
      }
    
      }  // namespace cc_plugin
    
      }  // namespace demo

~~~
keithnz
I'm trying to remain open minded to it, I found a few protocols :-

[https://github.com/arobenko/comms_all_protocols](https://github.com/arobenko/comms_all_protocols)

the ublox example seems a reasonably complex protocol of messages.

However, I'm not really sold on the framework to do it this way.

------
0110011
Eh, just write a state machine.

------
vardump
Embedded dev here.

Using C/C++ for embedded systems external communications feels like building a
house out of matches.

Sure, there's tooling to help fire proofing things a bit, like static analysis
and so on. You see, it's important to spray some fire retardant on the match
house.

But wouldn't it be so much nicer to have a construction material other than
matches for this purpose...

~~~
ranit
So, which language or tool would you recommend?

~~~
vardump
Rust looks quite promising.

Currently limited microcontroller architecture support is one of the biggest
issues with it.

Rust based RTOS would also be helpful for medium size devices. Of course small
devices are fine on bare metal.

~~~
iainmerrick
If you don't use Rust yet, what do you use right now?

I would have guessed C or C++. Maybe they're not great for the purpose but
they're also just about the only game in town, no?

~~~
vardump
Mostly C.

While C++ is easier to write, for very low level code, it is harder to
maintain when you need to understand _all_ of the side effects to maintain
code safety.

C++ compiler support is also sometimes not available. (And of course it's very
like there'll be no Rust compiler available either in this case.)

------
dokem
I was working on a similar problem recently and ended up dropping all the
fancy OOP footwork for a handful of static functions.

