froglogic / Blog / FreeRTOS and code coverage on embedded systems

FreeRTOS and code coverage on embedded systems

Code coverage for embedded systems poses some questions that do not occur with desktop applications. In this post I will show the first steps on how to measure code coverage with Squish Coco on an embedded system. We will use the FreeRTOS Kernel as our example.

FreeRTOS is a popular real-time operating system for microcontrollers and small microprocessors. There exist ports for many different platforms (like Amazon FreeRTOS), and the setup of the system for code coverage may vary between them. In this post, I will use the simplest of all, the POSIX GCC simulator, which can run a FreeRTOS program in a Unix system. Even in it, some specific aspects of embedded systems show up, which need a special treatment.

General setup for compilation on a Unix system

There is an easy way to enable code coverage in a Makefile-based project and set the coverage parameters. It consists of writing a script file, here called instrumented, which executes a command with all the shell variables set that are needed for code coverage. One can then enter “make” to compile in the ordinary way, and “./instrumented make” to do the compilation with coverage enabled. (But do not forget to run a “make clean” before switching compilation modes. Or better, compile the instrumented code in a different directory.)

In its simplest form, the instrumentation script looks like this:


export PATH=/opt/SquishCoco/wrapper/bin:$PATH


It adds the Coco compiler wrappers directory to the search path, sets the COVERAGESCANNER_ARGS variable to enable code coverage, and then runs the command that it gets as parameter. If that command is make and it runs a compiler like gcc, a compiler wrapper is executed instead of gcc and it does the instrumentation. What exactly it does is determined by the value of COVERAGESCANNER_ARGS. At the moment, this variable contains only one flag, to enable code coverage. Later we will add others.

Compilation of the FreeRTOS demo application

FreeRTOS comes with a demo application, and we will compile and later instrument it.

Download the FreeRTOS Posix simulator from their website and unpack it. (Documentation for the simulator can be found here.) The Zip archive unpacks to a directory named Posix_GCC_Simulator, which is already prepared for compilation. Go to the subdirectory FreeRTOS_Posix/Debug and run make. The compilation should then create an executable, FreeRTOS_Posix. Run it; it should generate output that starts with code like this,

Pipe Open: /Local_Loopback
Running as PID: 30477
Timer Resolution for Run TimeStats is 100 ticks per second.
Serial Rx Task exiting.
Multi event task started.
Multi event task started.
Queue peek test started.
Blocking queue consumer started.
Blocking queue consumer started.
Polled queue consumer started.
Polled queue producer started.

More lines like this will follow, and the program runs indefinitely until it is stopped. Press Ctrl-C to stop the program.

You have now verified that the compilation without Coco works correctly. Next you can enable Coco instrumentation.

Command line options for Coco

Before beginning with the actual Coco compilation, run a “make clean” to to delete the results of the previous compilation. This is always a useful security measure, since it prevents mixing instrumented and uninstrumented code.

Now create a file instrumented similar to that above in the Debug directory. It needs however some additional options. Now it looks like this:


export PATH=/opt/SquishCoco/wrapper/bin:$PATH
export COVERAGESCANNER_ARGS+=' --cs-no-exit-handler-installation'
export COVERAGESCANNER_ARGS+=' --cs-exclude-file-abs-wildcard=*/FreeRTOS_Kernel/*'
export COVERAGESCANNER_ARGS+=' --cs-exclude-file-abs-wildcard=*/FileIO/*'
export COVERAGESCANNER_ARGS+=' --cs-exclude-file-abs-wildcard=*/AsyncIO/*'

The reason for the new option “–cs-no-exit-handler-installation” is that embedded programs do not finish like desktop programs. The option prevents Coco from inserting code that is run when the program exits and writes the coverage measurements to a file. With FreeRTOS, the generated code conflicts with the code that is run after Ctrl-C and causes a crash. Setting this option prevents this.

The other three options are not necessary to run the program, only to give more meaningful results. They prevent instrumentation in three directories. These directories contain the code for the FreeRTOS operating system, not the demo application. In a real project, we would be interested in the coverage of our application and not the operating system. The operating system, after all, is already tested by its own developers. Also, if we want to reach a high coverage rate, we do only care for the coverage of our code, not how much of the operating system code is executed.

Changes in the source code

With the option “–cs-no-exit-handler-installation” set, we need however to provide our own code that saves the coverage measurements. One way to do this is to use the Coco library. It consists of functions that are always accessible in an instrumented program and can be used to control some aspects of code coverage. In our case we need the function __coveragescanner_save(), which writes the coverage data to a file.

For this function we need to find a place in the code that is called sufficiently often; there we place the function call. We will use the function vErrorChecks() in the file FreeRTOS_Posix/main.c. It is called every 5 seconds and prints some statistics. With the call of __coveragescanner_save() added, it looks like this:

static void vErrorChecks( void *pvParameters )
    for( ;; )
        if( pcReceivedMessage == NULL )
			/* Check the other tasks are still running, just in case. */
			/* We unblocked due to a message becoming available.  Send the message
			for printing. */
			vDisplayMessage( pcReceivedMessage );

Here we surround the __coveragescanner_save() statement by an #ifdef#endif clause so that it is compiled only in instrumented code; the symbol __COVERAGESCANNER__ is only defined in instrumented code. This is the usual way to insert code that is only executed in instrumented code.

With this change, the demo application can now be compiled again. This time, you need to run then command “./instrumented make“, and the compilation should then produce a file that was not there before, FreeRTOS_Posix.csmes. It contains all the static data that are necessary for the interpretation and display of code coverage results.


After the compilation, run “./FreeRTOS_Posix” again and let it run for some time. At least 5 seconds of runtime are needed to make sure that vErrorChecks() is called and coverage data is written. Then press Ctrl-C. The coverage data can now be found in another new file, FreeRTOS_Posix.csexe. You can display them in the coverage browser. A possible command line is “coveragebrowser -m FreeRTOS_Posix.csmes -e FreeRTOS_Posix.csexe“, provided that coveragebrowser is in your PATH.


This is the way in which the Posix version of FreeRTOS is instrumented. It shows some of the steps that are necessary to instrument a program for a small embedded system. The Posix simulator is however atypical since it has access to the file system, which many embedded systems do not have. In such a system, one needs to write special code to transfer the coverage data to the host machine.

Leave a Reply

Your email address will not be published. Required fields are marked *

Copy link
Powered by Social Snap