Through the years I have always looked for possibilities to generate code based on Models. In the 80íes I built a generator for building PLI-80/86 programs. The model were designed in Jackson Structured programming and worked nice for the time. Through time more sophisticated software packages were brought on the market supporting current used methodologies. Even code generation was introduced. Unfortunately most modelling tools generated a software framework that generated all the function prototypes. Then you wordt start filling in the framework and as long as you did not regenerate the framework, all went well.
There is a problem however. There is no need to keep the documentation up-to-date. One could just keep modifying the code without keeping the model and corresponding documentation up to date. And since developers in general do not like documentation activities…..
Around 2010 I came across a software package that supported UML and had the possibility to add code blocks in the class diagrams. And even in a number of different programming languages. Great!!! But not yet stable enough. But the product has gone through quite a few changes and enhancements. This year (2017) I took another look at it and found it very stable with better error handling. It supported C++ which was for me a reason to see if I could use it to generate 100% code from the models and use it on embedded platforms. I succeeded allowing me to regenerate all code from the UML models. This way my documentation is corresponding with the actual embedded code.
Templates and filters.
I will not go into the details of its workings as that is reflected on the site http://www.softwareideasmodeler.net.
For code generation, 2 things are relevant for generating code. Filters and Templates. A template is a XML kind of language that describes how a file (.ino, .cpp, .h) is generated. These templates may be fully customized to ones personal style.
A filter determines which type element of a diagram is to be generated using which template(s).
Example
Let’s look at a very simple example Blink_Without_Delay. This is a simple program that lets a led blink on/off using a set switch time in milliseconds.
We have a USE case that is associated with a LED. Withing each element documentation may be added. Also an associated diagram may be connected to a single use case. In this example I named it SystemDesign which is a class diagram.
Top left is a package named Arduino. Within my templates this means I have a library named “Arduino”. The dependency <<use>> takes care of a including “Arduino.h> into my code.
Bottom left is a class with a stereotype <<arduinosketch>>. This will make sure an Arduino sketch is generated. There is one unsigned long defined timer_1 that is used for globa variable and 2 functions setup() and loop().
Top right is an enumeration class that in this example contains the user modifyable parameters.
Top bottom is the actor which in this case is the LED.
The sketch has 2 dependencies Arduino and SystemParameters. How this is translated, check the sketch code.
The generated code from this example is
sketch
[code language=”cpp”]
/**
* Project blink_without_delay
* @file blink_without_delay.ino
* @sketch name blink_without_delay
* @diagram SystemDesign
* @author Nico Verduin
* @date generated 24-5-2017 7:24:53
*
*/
#include <Arduino.h>
#include "SystemParameters.h"
//
// global variables
//
uint32_t timer_1 = 0; // Timer for flipping led
/**
* @name setup
* @returns void
* Initializes the sketch
*/
void setup()
{
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
timer_1 = millis();
}
/**
* @name loop
* @returns void
* Is continuously called from main.cpp. Thus loops forever
*/
void loop()
{
if (millis() – timer_1 &gt; TIME_DELAY){
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
timer_1 = millis();
}
}
[/code]
SystemParameters.h
[code language=”cpp”]
#ifndef SYSTEMPARAMETERS_H
#define SYSTEMPARAMETERS_H
/**
* Project blink_without_delay
* @file SystemParameters.h
* @enum SystemParameters
* @diagram SystemDesign
* @author Nico Verduin
* @date generated 24-5-2017 7:24:53
* Enumeratie van alle systeem parameters die door het programma gebruikt worden. Na deze aangepast te hebben kan er een source code hergeneratie plaatsvinden en daarna de compilatie en flash.
*/
enum SystemParameters {
LED_PIN = 13, // Fixed led on D13
TIME_DELAY = 500 // Time between LED change
};
#endif
[/code]
Usage
I have tested this sketch on both the arduino IDE and the Eclipse Arduino (Sloeber 4.0) and compile fine. Make sure the generation process creates ascii files.
More info to come….