I use Matlab/Simulink R2012b under Linux to model dynamic systems. In order to perform hardware-in-the-loop testing, I want to run my models in real-time on Linux with rt_preempt patch. Running a Simulink model in real-time can be achieved by converting the model to the C code, compiling it and running the resulting application. Simulink supports this by means of Simulink Coder. Producing a Linux application with Simulink Coder is not as straightforward as one might think, though.
About Simulink Coder
Simulink Coder can, by default, generate code for so called Generic Real-Time Target (GRT). Such code should be suitable for running on desktop platforms. If you want to run the code on a more constrained embedded system or you have additional requirements on the code (e.g. compliance with safety standards), there is Embedded Coder for you. Embedded Coder extends Simulink Coder with additional capabilities and targets. The default Embedded Coder target is called Embedded Real-Time Target (ERT).
As it turns out, neither GRT nor ERT target alone can be used to create Linux executable even if documentation says the opposite.
Available options for generating Linux applications
From the documentation it seems that there are several options available out of the box that allow to generate Linux applications from Simulink. They are:
- The use of Embedded Real-Time target (
ert.tlc) and selecting NativeThreadExample as the target operating system in Model Configuration → Code Generation → Templates.
When I tried to generate the code, I got this error:
This model specifies the ‘Target operating system’ as ‘NativeThreadsExample’ from the ‘Template’ section of the ‘Code Generation’ pane of the Configuration parameters dialog. This example target is currently supported only when the model is configured for concurrent execution.
After some searching, I figured out how to enable concurrent execution. It can be done at View → Model Explorer → right click on Configuration → Show Concurrent Execution options and then check Allow tasks to execute concurrently on target. Even though I enabled this and configure the tasks, I still got the same error.
- The second option might be using the IDE Link Target that allows to compile the generated code by Eclipse IDE. Even though I don’t like Eclipse, I tried to set it up according to the documentation. Again no success. I ended up with some strange errors suggesting that there is a problem with Eclipse (more precisely its JVM) being a 32 bit application and Matlab a 64 bit application. My guess is that this feature is tested only on Windows. Since Matlab R2012b is not distributed for 32 bit Linux, it is not possible to test this option with 32 bit Matlab. Furthermore, in release notes of R2013a it is announced that Eclipse support will be dropped in future releases.
Custom target for Linux applications
Since I failed with both above options I decided to write a custom code generation target for Linux. One option would be to use a target previously developed at our department, but it has several drawbacks:
- The generated code cannot be compiled. It seems that the interface to the generated code changed between Simulink version from 2007 (when the target was developed) and R2012b used by me.
- I don’t like that the target is meant to be used on Windows (hardcoded backslashes etc.) and additionally,
- it contains features that I do not need (CANOpen block set).
Therefore I decided to write my own target that should be as simple as possible.
After creating the target by copying the
ert.tlc file and modifying
it slightly (basically replacing
ert_linux) and selecting
NativeThreadsExample as in the step 1 above, the code was
successfully generated. You can see this target here. Such a target
has two problems:
- It does not support external mode, i.e. a mode in which Simulink can connect to the running application to provide on-line parameter tuning and real-time data plotting.
- The generated code uses POSIX timers that use signals to wake up the threads. Signals have quite big overhead and there are rumors that their delivery can suffer from priority inversion.
The only way to get Linux application with support for external mode seemed to develop a target with custom main.c file.
I developed the target that provides the main.c file (actually
ert_main.c) and supports external mode. Although the
documentation is quite extensive (several thousands pages in total),
if was really hard to figure out how to do it properly. Several times
it was necessary to study awful TLC1 source code which is, IMHO,
very badly structured. Fortunately, I could use Lukáš Hamáček’s target
as an example, which helped me a lot.
The result of my work is can be downloaded from our repository. The target has the following features:
- Support for external mode over TCP.
- Support for both single-rate and multi-rate systems.
- Simulation threads are scheduled as
- External mode communication runs in non-real-time thread.
I tested the target on several systems and everything seemed to work as expected. My only concern now is about thread safety. Given that Simulink produces the error messages about concurrent execution of threads (see above), I’m not sure whether the generated code can be safely run in multiple threads. Also the code implementing external mode server contains several semaphores but only when it is compiled for the VxWorks OS. I’ll probably check this later if we encounter any problems that might be caused by the code not being thread safe.
It is surprising how few relevant results Google gives when one asks for “simulink real-time workshop linux”. It seems that the Embedded Coder target for Linux described in this post might be useful for people waning to run their Simulink models on Linux. Although that the target may not work perfectly and in all configurations, I think it is now good enough for interested people to try. If you experience any problems with the target, let me know.
Target Language Compiler – the tool used to convert Simulink blocks to C code.