Unit testing user code that depends on FreeRTOS

[Note: this is NOT about unit testing FreeRTOS itself: that’s been well covered in other posts.]

I’m re-architecting a project that makes extensive use of FreeRTOS. For modules that don’t depend on FreeRTOS, there is (nearly) 100% unit test coverage – that’s good.

But for modules that make use of FreeRTOS, I’m trying to figure out the best testing strategy.

I could set up a minimal FreeRTOS environment for testing, but to avoid conflicts with the production FreeRTOS, I’d have to generate an entirely new project.

What strategies have people used for unit testing code that depends on FreeRTOS?

You can use some mocking framework like CMock to mock out FreeRTOS APIs. However, multi-threading (thread safety, sequencing, etc.) is hard to cover with CMock.

You can look here for an example of using CMock: https://github.com/aws/amazon-freertos/blob/master/libraries/abstractions/secure_sockets/utest/secure_sockets_utest.c


Based on other (non-FreeRTOS) work I’ve been doing, I’ve come to believe that the best testing strategy is to do unit testing on a workstation / laptop to cover the bulk of the code. The remaining hardware validation can be handled by a small dedicated app running on the target system.

Here’s how you’d do unit testing on a workstation / laptop:

  • Start with FreeRTOS Windows Port or one of the Linux / macOS equivalents.
  • Separate out all the real-time functionality, call what remains to be the “VM layer”. For example, rather than driving the RTC, the VM layer should ONLY provide a means to set the RTC count and to generate an RTC interrupt. Ditto for serial data, button pushes, etc.
  • A separate layer would link the VM layer to the actual Windows / Linux / macOS system, e.g. with a real timer / counter, serial driver, etc.

The point of separating out the vm layer is that you could now control the state of your FreeRTOS app using a unit test harness: there would no longer be any real time constraints in your testing code, and in fact, your test code could precisely manipulate virtual time and other asynchronous operations.

I’d welcome a chance to discuss this with the maintainers of the FreeRTOS simulators. This wouldn’t require much creation of new code: rather it would be a refactoring of what’s there.