One challenge designers face is the need to translate their algorithms into code for use in embedded targets. The task has proven to be long and prone to error.
This article examines how the use of high-level design tools and C code generation capabilities improves the design flow by exploring different use cases and how to reduce the amount of embedded technology expertise required to program embedded targets.
Code generation: a multi-team effort
Often during the design flow, one team of engineers works to develop a simulation system using domain-specific tools like CAD or CAE packages. This simulated system is the base input – maybe even the first physical prototype where the functionality of the system is being tested – for another team in charge of developing the algorithm.
The engineers must move quickly back and forth between these two phases, simulation and prototyping, because the former establishes the starting point for the prototype and the latter adds real-world data to help validate the algorithm being developed.
This data can also be used to refine the software models to add more complexity or expose errors during the modeling stage. This ensures that the software prototype mimics more closely the system behavior and helps engineers refine the algorithm under development further. This process is sometime referred to as algorithm engineering (Figure 1, below ).
|Figure 1: Algorithm Engineering Process|
There is yet another team involved in the final stages of the design process. This team needs to convert the behavior designed in the algorithm engineering stage and port it to an embedded target. These engineers, who typically have embedded knowledge, often have to rebuild the algorithm completely from scratch.
The reason behind this is that usually the engineers who develop the algorithm are knowledgeable about the functionality and behavior of the embedded system under development and, while in the algorithm design process, this team has access to the computing power when using the CAD/CAM tools: floating-point data, unlimited processing power, and almost endless memory.
But when working with embedded targets, engineers usually do not have the luxury of these resources. The code implementation skills they need have nothing to do with domain expertise but rather with the embedded technology itself: conversion to fixed point, memory allocation, timing constraints, and many more.
Embedded Development Use Cases
As the number of embedded devices has grown exponentially in the last decade, making embedded engineers a necessity in design teams, it is impossible to have a “one size fits all” solution that describes the process of embedded C code generation for all possible use cases. Instead, engineers must work with a spectrum of situations.
On one end of the spectrum is the case where all the processes mentioned above (algorithm engineering and embedded deployment) are performed by only one designer or a small team of designers – for example, medical companies building a prototype to investigate whether new techniques are possible or engineers building new robotics systems.
The common theme in this case is that there are only a few designers and their expertise lies in application fields (medical in the above example) rather than in embedded programming and deployment.
More often than not, prototypes can be built using off-the-shelf technologies, but embedded knowledge is a requirement due to size or other specific hardware constraints. For this type of application, the optimal solution is to have a “one button” option that can take the code where the algorithm is being developed (typically high-level languages).
This option should implement the full C code generation, compilation, debugging, and deployment to the embedded target with limited or no customization by the customer. Typical hardware targets are embedded evaluation boards, where all the hardware specs have been designed. Another characteristic of this approach is that ease of use is primed over code efficiency.
The other end of the spectrum features companies with large development teams. These companies have teams and sub-teams dedicated to the different design stages of their products.
They typically produce a large number of units per year, making the main concerns time to market (to keep innovating faster than competitors) and the ability to produce a solution where the code is as optimized as possible, so companies can leverage economies of scale and reduced prices.
Because the code that represents the algorithm is typically only 20 percent of the total code, the tools that can generate C code are used on code that can be imported in already-defined embedded tool chains. This code can be used as glue between the algorithm design and embedded development stages, saving time in the design cycle but allowing the embedded teams to use highly optimized and tuned tool chains.
C Code Generation
Different high-level programs have different tools for C code generation. C has been used as a de facto language to generate code because it is considered “lingua franca” among the different embedded targets.
But it is not the only language. Even though there are code generators for other languages (like Java) and embedded targets can be programmed in other languages, C still dominates the embedded space.
The way to generate code is different for different languages, but many provide the same basic infrastructure. Once the code to generate C code is defined, a build process is specified with different options to generate the code depending on the focused target like Indian-ness and byte order.
Still Some Challenges to Overcome
Whenever there is a translation, such as the one between a high-level language and C code generation, engineers are concerned about how well the “generated” algorithm matches the one developed during the first phase of algorithm engineering. Although the algorithm is supposed to be the same, some factors, such as numerical representation or even the compiler use, prevent the results from matching exactly.
This is important for industries where the embedded target is used in critically safe final products, such as electronic control units (ECUs) in the automotive market. Engineers can choose from several solutions to meet this challenge (Figure 2, below ).
|Figure 2: C Code Generation from a graphical tool|
One main area of research is to validate the code generator so that the code it generates is automatically validated. Although this is showing promising results, the main technique used today is to define a set of vector inputs, run them through both the design and generated algorithms, and compare the results.
No matter whether the company is big or small, the product is new or an iteration on a previous design, or the level of embedded knowledge is large or limited, C code generation can help deliver the product from the algorithm engineering stage to the embedded target, saving time and decreasing costs.
Javier Gutierrez is Senior Product Manager, LabVIEW Control Design and Simulation, at National Instruments .