Tutorial: GNU gcov Coverage with the NXP i.MX RT1064

This tutorial shows how to use and collect coverage data using the GNU gcov tool. As board and hardaware I’m using the NXP i.MX RT1064 EVK:

MIMXRT1064-EVK running ThreadX
MIMXRT1064-EVK

While this tutorial uses this specific board, things are pretty generic and should be applicable for any other board or MCU.

Outline

Collecting coverage or test coverage data is very useful and tells which part of the code has been executed and how many time. This is especially useful to show how much of the code has been tested (or not). For details how this works using the gcov GNU utility and for other boards, see the links to my articles in the ‘Links’ section at the end of this tutorial, especially Tutorial: GNU Coverage with MCUXpresso IDE.

The project created and used is available on GitHub.

collected coverage information

SDK

I’m using the SDK 2.10.0 from https://mcuxpresso.nxp.com with the version 11.4.1 of the eclipse-based MCUXpresso IDE.

Used NXP MCUXpresso SDK for i.MX RT1064

Project

I recommend to start using gcov with a small project. Use the menu File > New Project and then create a new project or import the Hello World project:

Hello World Project

Next, make sure the project builds successfully and can be debugged.

I’m using the J-Link debug connection as this one supports fully the semihosting file I/O which is required for gcov data collection.

Coverage Stubs

Add the coverage stubs folder and files to the project (you can copy it from my project on GitHub). Make sure the folder is not excluded from the build:

added gcov stubs

Library

Make sure that the newlib library is used with semihosting:

newlib with semihosting

Coverage Initialization

The library needs to be initialized properly, which requires the symbol __init_array_start to be present. For this create (or copy) the file main_text.ldt into a folder named linkscripts.

Initializing Stubs

From the main file, call the gcov stubs like this:

Initializing gcov stubs

Semihosting File I/O

gcov uses file I/O through semihosting to write the data to the host. Check that your debug connection is able to sucessfully open and create a file on the host. For this there is a check routine present in the stub library:

File I/O check

Heap and Stack

File I/O uses lots of heap and stack space. Be sure that you allocate enough space: the more the better, at least trying out things. You still can reduce it later.

Heap and Stack size

My usual approach is to give it as much as possible (e.g. >8k for stack, >8k for heap) and then check with the ‘Heap and stack usage’ view in the IDE:

Heap and Stack usage

How much is needed depends on the library used too, but because file I/O needs large set of data, the more is better. Newlib nano should use less RAM than newlib.

Linker Option

Instruct the linker to link with the gcov library using the -fprofile-arcs option:

-fprofile-arcs linker option

Instrumenting to collect Coverage Information

To collect coverage, individual files/folders need to use the following (file/project!) specific option:

-fprofile-arcs -ftest-coverage

In return if you build the project, there shall be a file with extension .gcno created:

Writing Coverage

To write the coverage information to the host, call gcov_write() at the end:

Writing coverage information

Collecting Coverage

Now execute the file with the debugger and write the data. This shall create files with the .gcda extension:

Then terminate the debug session.

If you should get an error like this:

libgcov profiling error:....gcda:overwriting an existing profile data with a different timestamp

it means that there is existing profiler information data with a different time stamp and previously generated. Make sure to delete any old or existing data (delete for example the ‘debug’ folder).

💡 in case of problems, I recommend to make a clean-clean with deleting the ‘debug’ folder.

Show Coverage

To show the collected information, double-click on the generated data and press OK in the dialog:

Open Coverage Information

This opens the ‘gcov’ view with the details. Double-clicking on an entry opens the corresponding source file which shows the coverage information with green/red color.

Coverage with Source Information

Summary

Congratulations, you successfully instrumented and collected coverage information :-).

Collecting GNU coverage with gcov is rather straightforward with the MCUXpresso IDE, as all the necessary plugins are included. All what I have to do is to add the necessary high-level steps, add a linker symbol plus add the necessary compiler and linker options.

I hope you find this tutorial useful. Please check the links below for more details and further information, or check my project(s) on GitHub.

Happy covering 🙂

Links

4 thoughts on “Tutorial: GNU gcov Coverage with the NXP i.MX RT1064

      • Is there a rule of thumb for values to start with?

        I’m curious because I always find myself using up all the available resources. Not necessarily because of my largess, just because I want to select the minimum device for the application and SRAM, in embedded devices, is always a resource you’d like more of,

        Like

        • With using semihosting file I/O, I would start with about 2 kByte of RAM for the stack. For using gcov, the amoung of heap depends on the number of instrumented modules (or better: arcs). It starts with something around 4KByte for a single module instrumented, and only the ‘sky’ is the limit.

          Liked by 1 person

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.