Serialmonitor

In few words

Serialmonitor is a communication program which allows to an end-user to control microcontroller based applications. In this way the user can configure parameters, change values and monitor realtime data. Furthermore Serialmonitor offers a library to integrate microcontroller applications into own projects. Users can write Arduino, Python, C, C++ and other applications to control and communicate applications running on a microcontroller. Serialmonitor can also be used to communicate between microcontrollers.
By default Serialmonitor uses serial interface (UART) or Bluetooth to communicate with microcontrollers. The physical interface can be easily extended by any common interface like USB, CAN, Network, WLAN, …
For a better overview selected parameters and variables can be grouped in tabs-like manner. For quick access every value can additionally be updated with help of a slider bar. Selected variables, groups, window properties, selected files and interfaces can be saved and loaded. Multiple instances of Serialmonitor can be run at the same time.

Developers can use Serialmonitor as an debugging helper. All global variables of your application can be automatically extracted out of the compiled .elf file. You can view and edit your variables during runtime over any kind of interface, e.g. over air (bluetooth), USB or network.
This application is mainly thought to run on STM32 microcontrollers but can be easily adapted to every other processor. You only have to show to the Serialmonitor how to transmit and to receive a byte over targetted interface.

Idea

The most software developers will agree that it is very useful to know the values of the program variables while the program is executed. It is also very practical to be able to change the values during runtime. For normal programs which are executed on the computer developers use debuggers. One can pause the execution to show and modify the variables.
In case of my motor controller the software is executed on the microcontroller. Moreover it is a critical realtime application. If one pause the program in best case the motor will stop spinning but probably the powerstage (and maybe the motor) will burn within a few seconds.

For such cases microcontrollers offer special debug interfaces like JTAG or SWD. Within the microcontroller there is a dedicated piece of hardware which allows to read the memory content over a JTAG (cable + adapter) interface. On the computer there is a special software which allows the developer to ask the microcontroller for desired variables or to write new values into them over JTAG or SWD. For the STM32 microcontrollers STMicroelectronics offers STM Studio. One can feed a compiled .elf file to this program. It extracts all global variables out of it and resolves them recursively down to base data types.
Example program:
typedef struct
{
    int setpoint;
    float measured_value;
}
regulator_t;

typedef struct
{
    regulator_t Iq;
    regulator_t Id;
}
control_t;

control_t control;
Recursively resolved variables:
control.Iq.setpoint.int;
control.Iq.measured_value.float;
control.Id.setpoint.int;
control.Id.measured_value.float;
Of course it can be much more complex in a real application. The structures can be of any depth.

After resolving the variables STM Studio calculates the memory addresses to know from which location it has to read or to write if the developer wants to show or edit a variable. Than it lists all the variables and connects to the microcontroller. In most cases a JTAG to USB adapter is used. This kind of tool is practically indispensable. I used (and sometimes still) for many years this program.
The drawback of STM Studio is that JTAG or SWD is not a common in-field communication interface. A non-programmer does not have a JTAG adapter. More common are USB cables, USB to Serial (UART) or Bluetooth to Serial adapters. Another point is that there is no program interface to talk to the microcontroller from other programs. One can not write a small Python or Arduino application to integrate the motorcontroller into the own project.
For these reasons I decided to write an own communication program for microcontrollers.

Serialmonitor

The program consists out the following components:

ELF Explorer

I created a python application which extracs the names of the global variables out of an compiled .elf file. Than it resolves them recursively down to the base data types and gets their memory addresses. GDB is used in the background for some operations. Even if there are not many words to say, it was one of the most complicated things.

Serial Port

A communication path for secure data transmission between microcontroller and computer (and and vice versa) had to be created. At first I decided to use the UART interface. In this way I could control the motor controller also wirelessly over bluetooth. For this two pieces of software had to be programmed: one is executed on the microcontroller and the other one on the (host) computer. For transmission error detection the communication path is secured by a checksum.

Communication Protocol

To define how the computer and the microcontroller have to talk to each other a kind of language had to be created. I paid attention to make this protocol completely independent of the physical interface, so it can be easily adapted to USB, CAN, Ethernet or whatever later. The protocol also allows a microcontroller to microcontroller communication. This allows to create a kind of master and slave system. E.g. one motor controller can be synchronized to another one. There are also two software parts here: one on the microcontroller and one on the computer.
I paid attention to implement the modules
Serial Port and
Communication Protocol as generic and hardware independent as possible. In this way they can be adapted to other microcontrollers with little effort. Actually the microcontroller software only needs to know how to transmit and to receive a byte. The rest doesn’t depend on the used microcontroller.

User Program

Finally, the user or developer must be able to control the whole thing. For this a GUI program was created.
First it lists the available communication ports. The user selects the interface.
Than the user selects his .elf file or loads a prepared configuration. The program executes
ELF Explorer to get information about the variables and lists them. The user can select the variables he wants see or to modify. It is possible to create new tabs to logically group the variables. The fully resolved variable name, the current value within the microcontroller memory, the data type and the address can be seen.
Now the communication can be started. The program asks repeatedly the microcontroller for the current values of the variables of the current tab. For this it uses
Serial Port and
Communication Protocol. Additional variables can be added during the execution.
The user can send new values to the controller.
The program checks repeatedly if the selected .elf has changed, notifies the developer and allows to update the variables and their addresses by a single mouse click.
Additionally there is a slider bar which allows to send a new value to the controller very quickly. It calculates linearly the value between the user selected minimum and maximum number and sends it to the microcontroller.
For better usability the user can save and load the current configuration. Following attributes are saved
  • Selected .elf file
  • Selected communication interface
  • Tabs (variable groups)
  • Window size and screen location
This configuration is saved in a JSON file.
The user can open any number of instances to communicate to multiple microcontrollers at the same time.
This is how the application looks like (click to zoom):

In progress

  • Port Serialmonitor to linux operating system
  • Firmware flash mode, e.g. to update the software over bluetooth, CAN, …

Keine Kommentare:

Kommentar veröffentlichen