In my last post, I discussed my thoughts on using code generation to aid in the development of motion control system software. In this post, I’m going to discuss issues around moving system parameter values from their original source into software.
System Parameters & First Class Design Articles
I believe that a key concept of systems engineering is the “first class design article”. In any design, there is a document that captures a system parameter in the most fundamental way. I call this document “the first class design article”. In a circuit design, this is the schematic. In a mechanical design, it’s the 3D CAD. These are the master documents from which other design documents flow: circuit layouts, mechanical 2D drawings, etc. These are also the documents from which the physical parts are eventually fabricated. In an ideal world, data would be pulled directly from the master document at build time. While I believe that it is possible to do this today, it is difficult, and I’ve never seen it done in practice.
The two biggest issues with this idealized data flow process are:
- A significant amount of effort and tool specific knowledge is needed to pull the data from all of the tools used by the various engineering disciplines. Without a willing power user for each tool, it is unlikely that getting direct access to the source data is possible.
- Many of these tools require expensive licenses. Including these in the standard build process could require a license for each software developer.
Given those hurdles, pragmatism requires at least one step of manual data transfer. This necessitates close work with engineering partners to make sure that key parameter changes make it into the database.
I store the master document parameter values in a set of text files. These files are plain text, and are checked in to the revision control system with the rest of the software source. It is important that this file is a plain text file so that the ‘diff’ utility can be used to examine and track changes. With this text based parameter database in place, the build process can modified as needed.
System Parameters & Software Build
The key to efficiently utilizing the parameter database is integration with the software make system. To do this, some form of code generation is used to convert parameter information into C source code.
The standard C software build process goes roughly like this:
- The preprocessor expands preprocessor macros and includes header files.
- The C compiler converts the expanded C source to assembly code.
- The assembler converts assembly code to machine binary.
The simplest form of code generation to integrate into this build process is to utilize the C preprocessor. The design pattern called “X-macros” can be particularly handy. I’ll cover X-macros in a future post.
For more complex code generation utilizing high level design languages, the build process must be augmented. There’s no magic here, a step is simply added before the preprocessor to run the code generation scripts. If the build system uses a standard makefile, this is easily done. From a data coherence and simplicity standpoint, it is ideal to have the full process run at each compile. If build time is an issue, intermediate files can be generated and checked in. The make system is built to handle keeping things in sync in this type of setup.
My code generators usually require Matlab, my tool of choice for mathematical data manipulation. Since Matlab licenses are not cheap, it is rare that every software engineer will have access. If Matlab cannot be included in the standard build process, there are two similar options:
- The control systems engineer creates intermediate files via code generation with Matlab. The generated intermediate C source files are then checked in to the RCS. Matlab is only required to generate the intermediate files, and everyone has access to those files.
- The control systems engineer generates the code directly in the normal source files. This keeps all of the related code together in one file.
Both of these solve the software license issue. In either case, as long as the software engineers never touch the parameter files, Matlab will not be invoked. I tend to favor the latter approach, as the final source file is unified and easier to read. In my next post, I’ll describe and share the Matlab tool I use to inject generated code directly into source files.
As a final note, on the “Matlab Tools” page of this blog you can find a Bash script which I use with makefiles to invoke Matlab for code generation.