Engee documentation
Notebook

Code generation for STM32 (Flashing LED on finite automata)

This demo looks at the Engee model for controlling the digital output of an STM32 microcontroller.

Introduction

The purpose of this example is to develop an Engee model for a simple digital output control programme for a STM32F446RE microcontroller using the nested states of the Engee library of Engee finite automata.
The example will also show how to add the generated files to the project and then program the controller in the PlatformIO environment for VS Code.

Model description

The example model, stm32_blink.engee, consists of two blocks, the Chart "Blink" block and the C Function "GPIO_5_OUTPUT (LED)" block.

image.png

The first block implements the control algorithm - changing the state of Out at the block output, and the second block initialises the digital control channel GPIO_5, connected to the built-in LED of the NUCLEO-F446RE debug board, and changes its state during the program operation.

State diagram

The state diagram contained in block Chart, includes the following states:

image.png

Material: "Period_and_Clock" - sets the period of FullTime pulses (in model calculation steps) to flash the inbuilt LED and increments the period counter CurrentTime.
Subsidiaries:

  • "HIGH" - at counter values CurrentTime, less than or equal to half of the pulse period, generates a high signal level at the block output.
  • "LOW" - at counter values CurrentTime, greater than half of the pulse period, generates a high level of signal at the block output.
    If the counter value is equal to the pulse period time, the counter is reset in the transition between the states "LOW" and "HIGH".

Connecting peripherals

The controller periphery - GPIO #5 involved in this example - is fully parameterised in the C Function block of the model.
First of all, it should be noted that for correct compilation in the development environment of functions and structures used in this block, it is necessary to connect a header file containing prototypes of these functions and structures stm32f4xx_hal. Further this file does not need to be used in the project for the development environment - it is usually already contained in the added libraries.
The figure below shows how to connect the header file in the block C Function.

image.png

The </> StartCode tab of the block contains the functions of configuration and initialisation of the periphery - digital input/output #5, and the </> OutputCode tab contains the function performed at each step of the model calculation - the function of setting the state of the digital output.
Additional explanations of the code given in the C Function block are given in the corresponding comments.

Modelling results

To simulate the control pulse shaping algorithm, let's load and run the model stm32_blink.engee:

In [ ]:
if "stm32_blink" in [m.name for m in engee.get_all_models()]
    m = engee.open( "stm32_blink" );
else
    m = engee.load( "$(@__DIR__)/stm32_blink.engee" );
end

data = engee.run(m);

From the obtained simulation data, plot the signal Out - the state of the built-in LED:

In [ ]:
using Plots
plotlyjs()
plot(data["Blink.Out"].time,
     data["Blink.Out"].value,
     label="Состояние светодиода", size=(900,300),
     lw=2, legend=:topright)
Out[0]:

As can be seen from the graph, at the output of the control algorithm is formed a periodic signal with a given frequency and duration of pulses.

Code generation

Let's generate code from the model to load the control algorithm into the microcontroller:

In [ ]:
engee.generate_code( "$(@__DIR__)/stm32_blink.engee",
                     "$(@__DIR__)/stm32_blink_code")
[ Info: Generated code and artifacts: /user/start/examples/codegen/stm32_blink/stm32_blink_code

The files created in the folder stm32_blink_code - header stm32_blink.h and source stm32_blink.c will be used further in the project assembly.

Project assembly

The development environment through which the project is built and loaded into the target device is VS Code with the PlatformIO add-on. When working with STM32, this example also uses the ST STM32 platform and STM32Cube framework for PlatformIO. The configuration file of the PlatformIO project platformio.ini contains the following settings:

[env:nucleo_f446re].
platform = ststm32
board = nucleo_f446re
framework = stm32cube

After creating a new project you need to add the files generated in Engee and the file with the code of the main programme main.c (added to the example folder):

image.png

After that you can proceed to build the project and load the programme.

Executing the model on STM32

Let's connect the debug board NUCLEO-F446RE to the USB port of the computer, and then in PlatformIO we can observe the connected device. To correctly identify the connection of this board requires a driver ST-Link V2.

image.png

After successful connection you can proceed to the project building: "PLATFORMIO -> PROJECT TASKS -> nucleo_f446re -> General -> Build". If there are no build errors, load the compiled code into the microcontroller: "PLATFORMIO -> PROJECT TASKS -> nucleo_f446re -> nucleo_f446re -> General -> Upload".
As a result of loading the programme on the debug board you can observe LED blinking with a frequency of 0.5 Hz.

stm32blnk.png

For demonstration in the example, a Hantec DSO digital oscilloscope was connected to the corresponding pin of the microcontroller and the oscillogram was output to the serial port of the computer using the DSO Analyzer shell. As can be seen in the figure above, the received signal has the periodicity and pulse duration specified in the model.

Conclusion

In this example we have considered the development of the Engee model for a simple control programme - a blinking LED on the STM32F446RE microcontroller as part of the NUCLEO debug board. The algorithm is implemented using the nested states of the block Chart from the Engee library of Engee automata and is suitable for code generation. The process of embedding the files generated from the model into the PlatformIO environment project for VS Code with subsequent assembly, loading and execution on the target device is considered.

Blocks used in example