Code generation is a topic of intense interest for me.
If done correctly, code generation can be a tool that delivers on two of the core principles of computer science:
- One Source of the Truth/Don’t Repeat Yourself. There should be one unambiguous source of data in a system. If you try to hand synchronize your data, at some point you will get it wrong.
- Code in the most expressive language possible. Many studies have shown that a software developer will write about the same number of lines of code per day, regardless of the programming language. The more expressive the language is, the more work that gets done. This means that you want to code in a language that allows the most direct expression of the concepts of the problem domain, typically a domain specific language.
An example application of the two principles listed above is the handling of physical constants of a system. Let’s assume that we want to deal with the mass of the control system load. This value would typically show up in two places in our control system: the feedback and feedforward gains. During the development phase of the project, the mass is likely to change as the mechanical engineers proceed in their development. To avoid a long update process every time there is a mass change we don’t want to hard code the mass value into our system constants.
This is a case where code generation can be of great benefit. Our first step is to create a place to store the physical parameter value. If you can pull it directly from ME CAD, so much the better, I’ll have more to say on this in a future post. For now, let’s assume that’s not feasible. To make it simple, we’ll just drop them in a text file, with some designation of physical units attached. This file will serve as the single source of these values for all uses in the C code, addressing point one from above.
The next task is to automate the conversion of the physical parameters to each of the control gains. My tool of choice for this is a Matlab script. There are plenty of Matlab tools available to read data in from any text format, convert physical units, and scale and quantize for fixed point usage. Again, I’ll have more on these topics in future posts. This final step is to spit out bits of C code for each data use in the code. It is very simple to generate a C header with a
#define line for each constant generated. Viola, you have a code generator!
Through this simple process you have done the following to help your development process:
- You have made your development system much more robust. Storing the constants in the physical units minimizes human error when updates are made because you now get automatic updates of all the places with dependencies on that value.
- You have also increased your productivity. While you had to make an upfront investment in the code generation tools, mass changes are now handled almost effortlessly. Like any tool, upfront effort will pay off in long term productivity.
- You have documented a portion of your development process. A key thing to note is that you really haven’t expended much additional effort. You had to go through all of the same steps to go through the process one time, by recording those steps in a script, you’ve simplified the effort required the next time.
Code generation can be a powerful tool in the creation of robust, maintainable software. Modest upfront investments will pay large dividends in the long term. There are many tools available to aid in the process, in the future I’ll post about the Matlab tool stack I’ve developed over the years to aid in my code generation process.