![](https://desbravatech.com/br/wp-content/uploads/2024/07/embedded-systems-1024x585.webp)
Present in almost everywhere, Embedded Systems is a specialization field that requires a deep understanding of concepts from both hardware and software. It is necessary to recall lessons from Computer Architecture and Organization classes, as well as the concepts learned in Digital Systems courses, particularly about combinational logic circuits and the differences between compiled and interpreted programming languages.
And why is this necessary? Well, hardware is nothing more than an electronic device that operates under binary logic, performing operations such as bit shifting, memory loading, transferring sets of bytes to the Arithmetic and Logic Unit, and so on. Thus, we have an electronic machine that operates by states to execute given instructions. The way to write these instructions for the hardware is also known as machine language (binary logic). You may have heard of Assembly language. It is the closest language to binary levels, composed of operation codes (OPCODES) that, among other things, guide the hardware on its mission. Writing in binary code is impractical, and with the advances in recent decades, including the increased complexity in application integration and desire to reduce code density, Assembly language has become rarely used for writing complex systems.
In order to facilitate implementation and bring flexibility along with portability, new programming languages have emerged to abstract the lower-level languages without compromising available resources or execution speed. Thus, in the 1970s, the C language was created with the aim of building operating systems to be fast, flexible, and portable across different hardware architectures. Educationally, we have basically three classes of programming languages, as illustrated in Figure 1.
![](https://desbravatech.com/en/wp-content/uploads/2024/07/languages-class-desbravatech.jpg)
As illustrated in Figure 1, high-level languages, in their different subcategories, offer greater ease of implementation while also having a lower code density, but they are less performant in terms of execution speed.
High-Level Compiled Language C/C++
In practice, the more abstracted from the hardware a language is, the more sets of codes will need to be processed by the hardware to accomplish the same task that, for example, would require a single instruction in machine language or a few instructions in Assembly. In theory, compiled languages present better optimization, resulting in higher performance, bringing the compiled code closer to machine language for the architecture it was written for.
The intention of this post is to discuss C and C++ languages in embedded systems. Now, after a general overview of the topic, we can explore the characteristics of each.
The C language is also known as an intermediate-level language, as it combines elements of high-level languages with the functionality of machine-level languages, allowing, for example, the addition of Assembly instructions in the same code.
C++ (C plus plus or CPP) is an extension of the C language, providing greater abstraction by introducing Object-Oriented (OO) concepts. Released in 1985, C++ continues to evolve. In its C++20 version, it offers numerous features to further optimize the services behind operating systems like Linux and Windows and serves as a foundation for building other languages. JavaScript engines, such as Google’s V8 used in Google Chrome and Node.js, were implemented in C++. Python, released in 1991, has its core written in C, with some implementations also in C++. C++ has influenced many other programming languages due to its advanced features and efficiency. C++’s ability for direct memory manipulation, object-oriented programming, and high-level abstraction has inspired the development of many other languages and programming tools. For example, Java, C#, and even Rust were influenced by C++ concepts and practices. Both are among the top 10 most used languages in the world in 2023.
C/C++ for Embedded Systems
Although C and C++ share many similarities, as C++ is an extension of C, there are significant differences in their code compilation processes and how they handle resources and memory access.
C Compilation:
- Compilation Process: C code undergoes preprocessing, compilation, and linking. The preprocessor handles directives like #include and #define. Then, the compiler translates the C code into machine code. Finally, the linker combines the object code into an executable.
- Header Files: Including header files is straightforward and essential for defining interfaces between different software modules.
C++ Compilation:
- Compilation Process: Similar to C, but with additional steps due to OO features. This includes handling templates, classes, and other object-oriented functionalities.
- Templates and Instantiation: Compiling templates in C++ can generate multiple code instances, which can increase the executable size.
- Linking: C++ requires more complex linking due to its class features, inheritance, and polymorphism.
Resource Distribution and Memory Access
C:
- Manual Memory Management: In C, memory allocation and deallocation are usually done manually using functions like malloc and free.
- Low Level: C allows direct manipulation of memory and addresses, facilitating precise control over hardware resources, essential for embedded systems and high-performance applications.
- Determinism: Due to the lack of complex abstractions, memory usage in C is highly predictable, favoring environments where determinism is crucial.
C++:
- Memory Management with Abstractions: C++ introduces mechanisms like constructors and destructors, as well as smart pointers (std::unique_ptr, std::shared_ptr) to manage memory more safely and automatically.
- Object-Oriented Abstractions: Features like inheritance and polymorphism introduce abstractions that can impact resource distribution. These abstractions facilitate programming but can add memory and processing overhead.
- Templates: Although powerful, templates can increase memory usage due to the generation of multiple code instances, which does not happen in C.
Overhead, Efficiency, and Reliability
- Overhead: C++ overhead due to its abstractions (such as classes, inheritance, and templates) can result in higher memory usage and longer compilation times compared to C.
- Efficiency: C is generally more efficient in terms of memory usage and execution speed, due to its simplicity and lower abstraction.
- Safety and Reliability: C++ offers mechanisms that can increase code safety and reliability, such as RAII (Resource Acquisition Is Initialization) and smart pointers, reducing the chance of memory leaks.
Application in Embedded Systems
As we can see from the previous concepts about the languages and the characteristics of C and C++, each has its advantages and disadvantages. Their application will depend on hardware characteristics and software complexity.
Embedded with C
C is recommended for architectures limited in RAM/flash memory, single-core, where direct manipulation of peripherals is required, with maximum performance and minimal overhead, allowing the merging of Assembly code snippets. It is the ideal language when the goal is to ensure deterministic and reliable behavior in resource-limited environments. Examples include applications with microcontrollers from Renesas, Microchip, Espressif, STMicro, and Texas Instruments. Products here include IoT sensors and actuators, interface and control boards for high-level software (web frontend, mobile app, desktop) operation and communication, as well as control modules developed for aviation and automotive industries, for instance.
Embedded with C++
C++ is generally recommended for development with embedded Linux, with robust application requirements, higher complexity, and even processing involving databases. It offers a rich set of libraries with templates and OO rules to better manage software complexity. In these cases, applications with ARM32-64 bit processors, single or multi-core, megabytes/gigabytes of RAM, and ample storage space are suitable. Products here include multimedia centers, IP cameras, intercoms, network routers, and switches, among others. An example is applications to render radar images obtained via high-performance FPGA-based transponders, used in combat aircraft.
Summary and Key Ideas
In this post, we had a brief overview of programming languages and their relation to embedded systems.
Although both C and C++ are powerful and versatile languages, the choice between them should be based on the specific needs of your application. While C++ offers advanced tools that facilitate the development of complex software at the cost of higher resource usage, C provides more direct and efficient control of hardware resources, essential for applications where performance and limited resources are critical factors in the design.
To continue gaining more detailed knowledge, you can consult the following sources:
- https://www.statista.com/statistics/793628/worldwide-developer-survey-most-used-languages
- https://www.freecodecamp.org/news/the-c-programming-handbook-for-beginners/
- https://www.w3schools.com/cpp/cpp_intro.asp
- https://cplusplus.com/
- https://www.edx.org/learn/c-programming/dartmouth-college-c-programming-language-foundations?index=product&queryID=410ce020910ecd7f285d0666710f1d9a&position=3&linked_from=autocomplete&c=autocomplete
- https://www.embedded.com/
- https://www.ieee.org/
![](https://desbravatech.com/en/wp-content/uploads/2024/04/eav-2k24-avatar.jpeg)
I have worked since 2007 with software and hardware development, signal processing and electronics instrumentation. I am a hard-working and enthusiastic professional in innovation, science and integrated technologies. My aim is keep learning, evolve with challenges and always give my best on everything I do. Tai Chi enthusiast, cross-training, running and football player on the weekends. I appreciate classical music and philosophy, studying mythology, coding and teaching sw-hw tech to young enthusiasts.