Better Heterogeneous CPU Designs

How to build and debug code for a mix of processor cores.


The trend toward heterogeneous CPU designs is growing. Case in point: The NXP i.MX7 family of devices have such a design.

In this blog, I will discuss the (simple) steps necessary to get the most out of i.MX7 using the ARM Development Studio, more commonly known as DS-5, but the information applies to most similar systems.

Compiling code depends greatly on the use case. Within DS-5, there are two proprietary compilers, ARM Compiler 5, known as armcc, and the new ARM Compiler 6, known as armclang. Both are used for bare-metal or RTOS code (the freeRTOS example below builds with armcc). If building Linux, then gcc is used. Typically this is provided as part of the vendor BSP, else any other distribution, such as that provided by Linaro, While I won’t dwell too much on the detail of building code, as this is generally closely linked to the code base itself, I link here (and here) to some related blogs from my colleagues.

For debug, we provide ready-made configurations with DS-5 for i.MX7. Launch the DS-5 Eclipse GUI, and select (from the menu bar) Run → Debug Configurations… From there, highlight DS-5 Debugger on the left column, and click on the New Launch Configuration button. Give the configuration an arbitrary name for your convenience. You can use the ‘Filter platforms’ text box to search quickly for i.MX7. From there, select whether or not you want to connect to the Cortex-M4 or Cortex-A7 with this configuration. Let’s select the Cortex-M4 first. Select your debug adapter (DSTREAM below), and then click the Browse button to locate your adapter (either on network or on USB).


You will note the DTSL (Debug and Trace Services Layer) Options ‘Edit…’ button. This links to a pop-up to configure more advanced options of your debug session. Click this, and click the green + button to create a new set up. We recommend you create various different configurations for different use cases, to enable you to track your set up easily (you can give each a meaningful name).

For this platform, if you are connecting to a board fresh out of power up, you may need to select the “Release Cortex-M4 from reset” tickbox in the Cortex-M4 tab.  Conversely, if you are connecting to a system already running code on the Cortex-M4, this should not be set, as it will affect code execution. You can also optionally enable trace and other features here. Let’s enable Cortex-M4 trace, and collect the trace into the ETF (Embedded Trace FIFO). Click OK to save.



Note the Debug Configurations pane tells you which DTSL set up you are using

Screen Shot 2016-04-25 at 7.35.29 PM

While in the Debug Configurations pane, in the Files tab, we can specify whether or not we are directly loading an image to the target (to execute from the beginning), or simply loading debug symbols to the debugger for code already running on the target. In this case, I am using the freeRTOS example provided by NXP.


If loading directly, in the Debugger tab, select Debug from entry point, or Debug from symbol. If connecting to an already running target, select Connect Only


Finally, if using an RTOS image, you can enable OS awareness from the pull down in the OS awareness tab (freeRTOS in this example.)

Screen Shot 2016-04-25 at 7.38.00 PM

Click Apply to save, or Debug to connect as configured, and we should be able to debug from there. Note if you are debugging from main (or entry point) the RTOS is not yet initialized, so nothing is visible in the OS Data pane. Run further and stop and you will see this information populated. Below is an example of the type of views you can see in the debugger. If a certain pane is not visible (some of the below are not default), use Window → Show View.

Screen Shot 2016-04-25 at 8.14.00 PM

Similarly, we can repeat the above process to create a configuration for the Cortex-A7. For this CPU, the only real difference is if you wish to enable Linux kernel awareness, you select Linux Kernel and/or Device Driver Debug, rather than Bare Metal Debug, and selecting from the OS Awareness tab. You can see more information on the Linux awareness capabilities of DS-5 here. I would also highlight the MMU view, as being particularly useful for most Cortex-A7 debug use cases. However, what I really want to focus on is the capability DS-5 has to connect to both the Cortex-A7 and the Cortex-M4 simultaneously.

Above we created two independent debug configurations, one for the Cortex-A7, one for the Cortex-M4. We can connect the debugger to both at the same time. The only caveat is that both configurations need to have the same DTSL options selected, which makes sense, as that defines how the target is being set up. If you attempt to connect with different settings, you will get an error for incompatible configuration values. Once connected, you will notice that each view has a “Linked” icon. This means that the view is related to the currently selected connection in the Debug Control pane. You can click on this to select your connection (either Cortex-A7 or Cortex-M4 in this case), and lock the view to that CPU. For common views, such as Registers, we generally recommend opening two panes (via the New Registers View menu button within the pane), and lock one to each CPU. Below is an example screenshot showing such a set up. Note the memory view is set to Linked, and shows the Cortex-A7 memory view, as that is the connection selected in the top-left Debug Control pane.

Screen Shot 2016-04-25 at 8.12.38 PM

By enabling simultaneous debug, you are better able to work out those challenging debug scenarios, where the behavior of one core affects the other. I hope this brief introduction shows you how to get started quickly and easily.