3

I'm currently developing a controller for an industrial application which takes data inputs from various sensors and interfaces (ethernet, serial, etc.), does some minimal processing, and adjusts outputs to interfaces and mechanical systems as needed.

The device, a B&R X20 automation controller, uses a simple RTOS operating on a single-core with multi-processing, but not multi-threading support. New processes cannot be spawned during operation. Interrupts are not supported. Rather, to prioritize tasks, each process is assigned during programming a frequency for complete execution of its main loop, and the scheduler does its best to adhere to this real-time schedule, throwing exceptions upon timing violations.

To maximize concurrency between the various functions, each of which have different timing requirements, I have several small processes (e.g., an ethernet reader/ writer, a valve opener/ closer) mostly associated 1-to-1 with input/ output functions. To meet real-time i/o requirements, intensive data processing lives in separate processes prescribed to lower scheduling frequency.

Inter-process communication takes place through variables global to their respective processes, synchronized via semaphores.

The device allow programs to be written in both C and C++. When should I prefer to write with one or the other? Assume no significant difference in performance.

My thinking:

While my instinct is to prefer C++'s encapsulation, each of my processes is sufficiently simple such that using OOP would leave it housing only one object. Coding in C++ then seems to add an extra unnecessary layer of communication from the object to process-global variables that would not exist were the computation object-homeless. Additionally, because the entire process contains one object, there appears to be no encapsulation benefit, as there's nothing left to encapsulate from.

At the same time, I have some instinct that even simple programs should be programmed with OOP when possible to allow for flexibility and growth.

Have I discovered a situation where object-ification introduces unnecessary levels of structure to a simple program? Or is it preferable to adhere to OOP whenever the hardware allows?

  • 5
    "Object-ification" was never necessary to build programs, and it still isn't. There's no definitive line that you can draw where object-ification becomes preferable; it is a judgement call. And it depends on who you ask; if you ask Linus Torvalds, he'll tell you that object-ification is never desirable. – Robert Harvey Aug 7 '18 at 2:57
  • Stupid question here, but if you are only doing minimal processing why are you rolling your own control system instead of using a standard IEC 61131-3 language? – Peter M Aug 7 '18 at 23:48
  • Valid question, @PeterM. The "minimal processing" includes accepting a recipe file of unknown length from ethernet and translating that into i/o to actuators. While this could probably be done with ST, I admit to thinking of C/C++ first out of my familiarity with their built-in string handling capabilities. – Dragonsheep Aug 8 '18 at 0:51
  • 2
    I agree that it can be easy to exceed the capabilities of an IEC language, but I'd be trying as hard as possible to keep to a standard rather than reinventing a lot of wheel. Perhaps isolating the recipe code in C/C++ and keeping everything else as IEC - as while the recipe may be variable, your hardware certainly isn't. However this is an architecture discussion that I think would be better off on a PLC focussed forum such as plctalk.net or mrplc.com – Peter M Aug 8 '18 at 1:44
4

C and C++ are closely related. Their main difference is not that one is procedural and the other object-oriented. The main difference is that C++ offers a much more expressive type system (incl. support for OOP, but you are never forced to use it).

In fact, many programs do not need any kind of OOP at all. With OOP, I here specifically mean virtual methods and RTTI which imply some runtime cost. If you were writing C, you would probably use function pointers or tagged unions instead. C++ features such as the class keyword or private access are related concepts, but are useful even without any OO. Want to communicate through global variables? C++ of course lets you do that without forcing you to create any classes. A procedural design is often completely valid.

In my experience, choosing C++ is almost always the better choice, if you have the choice. You get various features such as:

  • deterministic destruction/RAII, which eliminates a common source of bugs
  • better ways to structure your code, including namespaces, private member visibility, constructors, methods/member functions, …
  • possibly a great standard library (probably not when embedded)
  • possibly exceptions (probably not in an embedded context)
  • templates, as a kind of type-safe macro
  • small things, like references or that character literals 'a' actually have type char
  • C++11: lots of quality-of-life improvements such as auto, lambdas, using, and so on.
  • near-complete compatibility with C syntax

You can literally take most C programs and compile them as C++. If you need to keep ABI compatibility you often just have to add a few extern "C" declarations. The upgrade path is very simple and gives you tons of extra features. You can decide how far you want to go: it is perfectly valid to write very C-ish C++ that just uses a few extra features.

But there are still reasons why you might want to use C instead:

  • C is a much simpler language.
  • More people know C than C++ (important if other people will have to work with your code).
  • C is more portable (irrelevant if you target a specific compiler on a specific platform).

Don't let your design guide your technology choice too far. If you want to use an object oriented design then C++ makes it easier to implement that design, but is not necessary. Conversely, C++ might still be attractive even for a procedural design. In the end this language choice is largely a matter of personal preference: whether you think your code will be simpler if you are able to create strong abstractions (C++) or if you'd rather keep the code simple, explicit, and obvious (C).

  • 2
    Another good point about C++ is its philosophy of "you only pay for what you use", so you you don't sacrifice critical embedded resources except in the areas where C++'s abstractions are worth it. – whatsisname Aug 7 '18 at 21:54
3

I have some limited experience in embedded programming, mostly with Arduino-compatibles, ESP8266, that kind of stuff, and only for fun.

I've started with the available libraries, all of which are procedural I must say, but I quickly found myself re-implementing everything in OO / C++, just to be able to plug things together more easily.

So my points are:

  • There is no such thing as a "simple program". Not if you ever want to read your code again. Even for a simple button that turns on a light, there are already multiple objects.

  • About introducing "unnecessary levels of strucutre". You don't introduce structure just for the fun of it. Ok, some people do I guess. Structure you introduce is always there to codify knowledge about the Domain. Knowledge that you document for your reader.

The structure you introduce is basically like a developer-documentation for your code, except it is understood immediately by everybody and it enforces itself.

I think you might be afraid of OO, because it enables over-engineering, sometimes even to ridiculous levels (see Java Enterprise). It does so precisely because it enables handling complexity better, so some people compensate by introducing more complexity. If you are aware of this and can resist this, you and your oo design will be fine, and it will be more readable and maintainable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.