Previously I discussed asymmetrical multicore and how it can used in scenarios that need real-time response times and rich user interface and/or connectivity. I used Freescale’s Vybrid as a sample of such architecture and discussed the hardware features that can make this kind of solution simpler to develop and more reliable than the “traditional” approach of connecting two separate processors using a serial link.
In this article, I will show the software components that can be used to implement a solution on this kind of architecture by presenting a demo project developed by Toradex and AntMicro. We developed a 2D plotter that provides a touchscreen user interface. The mechanical part is not very complex. It comes from a kit available on the Internet. We made some enhancements to improve drawing quality and mechanical reliability.
Controlling the plotting hardware requires a limited number of digital I/Os. On the other side, we need precise timing to get good drawing quality and need to process a good amount of data to draw complex subjects.
You can see the plotter in action in this video.
Now that you have an idea of the end-result, we can look under the hood and discover how it is implemented.
The system has two main components: a touch-screen based user interface that shows different vector-graphics images and let the user choose the one that the plotter will transfer to paper, and a real-time control system that controls the hardware during plotting. Each component runs on a dedicated core. We used the Cortex-A5 for user interface and the Cortex-M4 for real-time control.
On the Cortex-A5, we choose to run Linux and use the QT framework to implement a user-mode application. Linux is a common choice on embedded devices and provides all the features required by our system in a reasonable footprint.
The Qt framework, maintained by Digia, is also a popular choice for embedded devices. It provides a rich set of features (not limited to the user interface), a user-friendly integrated development environment (including a UI designer) and a dual open source/commercial license. Qt supports the SVG vector-graphic format and this made it easy to choose it as the format for images shown on the display. The same images are converted into G-code (a numeric control programming language). The control-system parses the G-code to perform the actual drawing operations.
On the Cortex-M4, we needed to perform simultaneous activities, getting commands and data from the UI and moving the X and Y axis at the same time. This kind of control can be implemented in a bare-metal firmware, but a real-time operating system (RTOS) can simplify the development. The RTOS manages the scheduling of the different tasks without losing real-time response times. It also allows direct access to the hardware from application code.
We choose eCos (ported by AntMicro) as the RTOS for the m4 core. It provides a scheduler and a hardware abstraction layer that made our application code simple. The two components need to communicate and we have three different kinds of communication:
• commands sent to the control system
• feedback about plotter current state
• provide G-code that would be used to control plotting
The first two kinds of communication involve small amounts of data and require fast delivery. Freescale provides a library named Multi-Core Communication (MCC) that fits quite well with these kinds of requirements. It provides an interface based on end-points that are used to exchange messages. Each application running on Linux can create its own endpoints and also send messages to endpoints managed by the M4 core. From a developer point of view, this mechanism is similar to sockets or pipes, providing an easy to use communication link.
AntMicro ported MCC to eCos, providing the same functions on the M4 core. MCC messages can be used to send small data packets, keeping them in sequence. They are not suitable to send full G-code of a complex drawing at once. For that purpose, we decided to use shared memory, allowing the M4 core to access the G-code data loaded by the Linux application.
The architecture is shown in the diagram below, highlighting the different components running on the two cores.
The Linux application loads the M4 code into memory and starts it using the mqxboot command-line tool provided by Freescale (the tool is open source and can be used as a reference to understand how the M4 can be initialized and to implement this feature directly inside application code if more strict control of the process is required). Then a “welcome” message is exchanged over MCC to ensure that both cores are up and running. When the user selects a drawing and presses the button to start drawing, the Linux application performs a sequence of operations:
• Send a “home” command to move the pen in the upper-left corner of the drawing area
• Load the G-code data in a memory area shared with the M4 (this is also done using mqxboot)
• Send a “start” command to start the plotting process
At this point the M4 core is operating independently, processing G-code data, moving axes, and sending back notifications about its progress. We provided a button that loads the A5 core at 100 percent for some time to show that this does not impact the operations of the other core since it can operate independently and access the data it needs to complete the drawing.
The source code of both applications is available on github and, looking at it, you can see that the total amount of code is quite reasonable (few hundred lines), and that the code managing the communication channel implemented via MCC is quite simple and readable.
I have to thank Stefan Agner (Toradex), Michael Gielda (AntMicro), and Peter Gielda (AntMicro), who implemented the system, for providing me with the information to write this article.
Valter Minute is Embedded Software Engineer at Toradex.