Roman Samborskyi | Dreamstime.com
Code Engineer Promo2
Code Engineer Promo2
Code Engineer Promo2
Code Engineer Promo2
Code Engineer Promo2

Real-Time and Ada Programming

May 27, 2021
Check out some of the technical aspects of the Ada programming language, such as the Ravenscar profile.

This article is part of the Embedded Software series: Ada for the Embedded C Developer

Like C, Ada is a compiled language. This means that the compiler will parse the source code and emit machine code native to the target hardware. The Ada compiler we’ll be discussing in this course is the GNAT compiler. The compiler is based on the GCC technology like many available C and C++ compilers.

When the GNAT compiler is invoked on Ada code, the GNAT front end expands and translates the Ada code into an intermediate language that’s passed to GCC, where the code is optimized and translated to machine code. A C compiler based on GCC performs the same steps and uses the same intermediate GCC representation. This means that the optimizations we’re accustomed to seeing with a GCC-based C compiler also can be applied to Ada code.

The main difference between the two compilers is that the Ada compiler is expanding high-level constructs into intermediate code. After expansion, the Ada code will be very similar to the equivalent C code.

It’s possible to do a line-by-line translation of C code to Ada. This feels like a natural step for a developer familiar with C paradigms. However, there may be very little benefit to going this route. For this course, we're going to assume that the choice of Ada over C is guided by considerations linked to reliability, safety, or security.

To improve on the reliability, safety, and security of our application, Ada paradigms should be applied in replacement of those usually applied in C. Constructs such as pointers, preprocessor macros, bitwise operations, and defensive code typically get expressed in Ada in very different ways, improving the overall reliability and readability of the applications. Oftentimes, learning these new ways of coding requires effort by the developer at first, but proves more efficient once the paradigms are understood.

Concurrency and Real-Time

Concurrent and real-time programming are standard parts of the Ada language. As such, they have the same semantics, whether executing on a native target with an OS such as Linux, on a real-time operating system (RTOS) like VxWorks, or on a bare metal target with no OS or RTOS at all.

Understanding the Various Options

For resource-constrained systems, two subsets of the Ada concurrency facilities are defined, known as the Ravenscar and Jorvik profiles. Though restricted, these subsets have highly desirable properties, including efficiency, predictability, analyzability, absence of deadlock, bounded blocking, absence of priority inversion, a real-time scheduler, and a small memory footprint. On bare-metal systems, this means in effect that Ada comes with its own real-time kernel.

Enhanced portability and expressive power are the primary advantages of using the standard concurrency facilities, potentially resulting in considerable cost savings. For example, with little effort, it’s possible to migrate from Windows to Linux to a bare machine without requiring any changes to the code. Thread management and synchronization is all done by the implementation, transparently.

However, in some situations, it’s critical to be able to directly access the services provided by the platform. In this case, it’s always possible to make direct system calls from Ada code. Several targets of the GNAT compiler provide this sort of API by default—for example, win32ada for Windows and Florist for POSIX systems.

On native and RTOS-based platforms, GNAT typically provides the full concurrency facilities. In contrast, on bare-metal platforms GNAT typically provides the two standard subsets: Ravenscar and Jorvik.

Ravenscar

The Ravenscar profile, a subset of the Ada concurrency facilities, supports determinism, schedulability analysis, constrained memory utilization, and certification to the highest integrity levels. Four distinct application domains are intended:

  • Hard real-time applications requiring predictability.
  • Safety-critical systems requiring formal, stringent certification.
  • High-integrity applications requiring formal static analysis and verification.
  • Embedded applications requiring both a small memory footprint and low execution overhead.

Tasking constructs that preclude analysis, either technically or economically, are disallowed. You can use the pragma Profile (Ravenscar) to indicate that the Ravenscar restrictions must be observed in your program.

Ravenscar offers many additional restrictions. Covering those would exceed the scope of this chapter. You can find more examples using the Ravenscar profile on this blog post.

Read more from the Embedded Software Series: Ada for the Embedded C Developer

Sponsored Recommendations

Understanding Thermal Challenges in EV Charging Applications

March 28, 2024
As EVs emerge as the dominant mode of transportation, factors such as battery range and quicker charging rates will play pivotal roles in the global economy.

Board-Mount DC/DC Converters in Medical Applications

March 27, 2024
AC/DC or board-mount DC/DC converters provide power for medical devices. This article explains why isolation might be needed and which safety standards apply.

Use Rugged Multiband Antennas to Solve the Mobile Connectivity Challenge

March 27, 2024
Selecting and using antennas for mobile applications requires attention to electrical, mechanical, and environmental characteristics: TE modules can help.

Out-of-the-box Cellular and Wi-Fi connectivity with AWS IoT ExpressLink

March 27, 2024
This demo shows how to enroll LTE-M and Wi-Fi evaluation boards with AWS IoT Core, set up a Connected Health Solution as well as AWS AT commands and AWS IoT ExpressLink security...

Comments

To join the conversation, and become an exclusive member of Electronic Design, create an account today!