Recommended IAR Compiler Settings for Embedded Projects

25 August 2015
| |
Reading time: 5 minutes

Our team recently completed a project with a client working on an industrial meter, entirely written in C and using the IAR Embedded Workbench IDE as the compiler. I wanted to share a few things that we learned to optimize in IAR, to help your projects go a little smoother.


1. Faster Terminal I/O – “buffered terminal output”

IAR allows you to have several projects in your workspace, and we set up a project to run the unit tests for each of our software modules. We used a Simulator configuration for all projects and an additional Debug configuration for downloading and executing unit tests on the processor (MSP430). We were always frustrated that printing out messages to IAR’s terminal was VERY slow while running the Debug version. Our first attempt was to pass command line arguments into the unit test fixture (Unity) to abbreviate its output to the terminal. It would still be VERY slow to print out failure strings, though. The solution was to turn on “Buffered terminal output” as you can see in the screenshot below. Project -> Options -> Linker -> Output -> Buffered terminal output. Afterwards, you should find that the terminal prints out MUCH faster and you don’t have to worry about making sure that your unit test framework’s “verbose” setting is turned off.


2. Generate code coverage metrics automatically

IAR’s CSPY can automatically generate code coverage metrics for your code modules while running Simulator configurations (but not while running tests on hardware). You simply have to include the option “–code_coverage_file <output file path>” in the PROJ_DIR/settings/PROJ_NAME.<config>.cspy.bat file.  Mine is “–code_coverage_file $PROJ_DIR$\$PROJ_FNAME$CodeCoverageFullResults.log”. Note, however, that the *.cspy.bat files are auto generated by the compiler, so we had written a script to add the string to each *.cspy.bat file. However, in the IAR V6.20 release in December 2014, they fixed the IDE so that you can simply specify the option there, without the need for a batch script to edit the *.cspy.bat files.  Project -> Options -> Debugger -> Extra Options.


After unit tests for each project/module are executed and the code coverage log files auto generated, you can run these two scripted commands to extract the top-level coverage percentages:

:: Find all module test coverage statistics and put them in a single file
findstr /C:"Module " %moduleName%CodeCoverageFullResults.log > %moduleName%CodeCoverageAllModulesOnly.log
findstr %modulesOfInterest% "%moduleName%CodeCoverageAllModulesOnly.log" >"%moduleName%CodeCoverageSummary.log"

Then, at the end of all automated unit tests, run this command to collect the code coverage results into a single summary file:

:: Collect all Unit Test Coverage metrics into a single file. Recursively search all files for Summary Logs and concatenate the results.
findstr /S /P /C:"Module " *CodeCoverageSummary.log > AllCodeCoverageResults.log

3. When archiving project files, archive *.ewd, *.ewp, *.eww files.

We should only check into a revision control system the necessary files to repeat our setup. Ideally these are also files that the IDE doesn’t unnecessarily change over time. For instance, the *.dep file changes very often and shouldn’t be committed. The *.eww file is the workspace and the *.ewp file contains the project settings. However, we didn’t discover until later that the *.ewd file was necessary to specify the Debug configurations that utilize the FET Debugger option to download to a target. If you don’t check in the *.ewd file, clean checkouts of the project will just use the Simulator to run tests.

4. Turn on several MISRA rules to help enforce coding conventions.

Our client specified that they wanted their codebase to be MISRA C compliant according to the MISRA rules they had chosen in their style guide. For the MISRA 2004 standard, these were rules 2.3, 2.4, 5.2, 5.3, 5.5, 5.6, 5.7, 6.3, 8.3, 8.7, 8.11, 9.1, 10.1, 10.2, 12.2, 12.4, 12.8, 12.9, 13.1, 14.1, 14.4, 14.5, 14.10, 15.1, 15.2, 16.8, 17.1, 17.2, 17.4, 17.6, 19.10, 19.15, 20.4, 20.5, 20.6, 20.7, 20.8, 20.9, 20.10, and 20.11. So we turned them on for the full product build but left them off in the unit test projects, since the Unity unit test framework had lots of warnings of its own. Although we put a few exceptions in which were well documented, this seemed like a good set of rules to use, and better yet the IAR compiler can automatically enforce them. Static analysis tools can later discover further issues with your code, but turning on rules in the compiler makes the feedback loop much shorter and more responsive. This will help your team avoid issues with pointer arithmetic, variable name scope shadowing, initialization, and unintended side effects.


5. Stack manipulation is tricky when using Unity unit test macros.

We were using the Unity unit test framework (written in C), the Segger embOS operating system, and the IAR compiler with all optimizations turned off. Occasionally we needed to either prove the thread safety of certain key communication pathways, or we needed to create unit tests for low-level OS functionality, which required actually running the OS within our unit tests. Unfortunately, embOS has a “Start” but no “Stop” functionality, so there’s no built-in way to cleanly exit the OS. However, IAR and TI provide the “intrinsics.h” header file which has methods for manipulating the program counter, stack pointer, and status registers. This allowed us to run unit tests within the OS and once complete we could jump back to the calling unit test body after the point where the OS had been started. However, we discovered that when “TEST_ASSERT” macros are called, the IAR compiler lazily waits until the end of the enclosing function to reset the stack pointer. So the stack pointer is actually in different place just before and just after the TEST_ASSERT call. Therefore our solution was to create a separate external buffer and save the entire stack contents before entering the OS so that it could be exactly restored afterwards. In the end, although it is tricky to implement these tests correctly, I think they significantly increase confidence in system functionality that is dependent on the OS and protect codebase maintainers from accidently introducing thread safety defects in the future.

And that’s all of the IAR compiler recommendations and gotchas from our last project. In the comments, feel free to propose other IAR compiler settings which have been useful for you and your team, and we’ll post anything else that we find useful in the future.  Next up, recommendations when using TI’s MSP430 processor.


Comments (3)


Jeff Geisler

18 April 2017 at 20:05

I am really interested in your methods using the simulator for automated unit tests. Can you say more about that? Are the unit test handwritten for the application at hand, or is it a method to execute unit tests automatically generated by a test tool, such as VectorCast?



    6 May 2017 at 21:24

    I am also very interested in using IAR’s simulator for unit testing. Could you elaborate more on that?
    Could you perhaps post an IAR example unit test configuration?

Jeremy Hannon

Jeremy Hannon

22 May 2017 at 00:41

@Jeff – yes the unit tests are handwritten in C because a developer should follow TDD so they’re developing the unit tests and production code at the same time. In my projects we’re also using CMock to generate mock implementations and sometimes using Ceedling to auto-discover, build, and execute unit tests with GCC. Unity, CMock, and Ceedling are all maintained by throwtheswitch.org and work well for codebases written in just C. CMock and Ceedling don’t handle C++ so our team assumes that with a mixed codebase we’ll use Unity/CMock/Ceedling for the C code and likely Google Test for the C++ code (which doesn’t handle C code well). Where I work now they tried VectorCast (an IDE for unit tests) but it didn’t gain traction and I think I still much prefer an entirely text-driven approach. Sure, I’ll use an IDE editor like Eclipse or IAR to text highlight and run the code, but I didn’t like how you have to go hunting for the customized test code in VectorCast.

@Chris – a unit test project in IAR is just like any project where the .ewp file (and file structure view on the left in IAR) specifies which .c files to compile in. The difference is just that each unit test project is configured for the Simulator (Project Options -> Debugger -> Setup -> Driver) and you remove most .c files from even being compiled in. Instead you just compile the .c file(s) for the unit under test and .c files for mock implementations of the modules that your UUT depends on. If you use Ceedling you can compile your code in GCC (most of the code is processor independent, right?) and you don’t even need to create unit test project files or test runner files (which call the individual tests) because Ceedling auto-discovers the tests and builds the GCC makefile for you. IIRC there are examples in the Unity download: https://github.com/ThrowTheSwitch/Unity/archive/master.zip

P.S. I no longer work at Zuhlke (great company) but am passionate about unit testing.


Sign up for our Updates

Sign up now for our updates.

This field is required
This field is required
This field is required

I'm interested in:

Select at least one category
You were signed up successfully.

Receive regular updates from our blog


Or would you like to discuss a potential project with us? Contact us »