What is the minimal FreeRTOS environment to execute unit-tests?

I want to unit-test my code components by executing them on PC with the FreeRTOS port on Windows. Some component uses a Queue. I get segmentation fault when I access to xQueueReceive(). I have created no FreeRTOS object other than a Queue. By debugging, I remark a null pointer: pxCurrentTCB.
I suppose I have to create at least one task… and maybe something else. Could somebody describe me the minimal environment to have to make my tests?
Thanks in advance!

Did you call vTaskStartScheduler?

1 Like

Hi Damien -

to me it looks like you have made a spot landing on the limits of usefulness of unit testing right on your first jump! Congrats! :slight_smile:

Queues are IPC mechanisms, and fairly heavily used ones in FreeRTOS, too. Thus, the very idea of a unit test is misproven in this example: A unit test assumes that the code to be tested is a static, fully deterministic function between the input parametrs and the result.

In RTOS rhis rarely holds true as any use of IPC implies side effects on other threads of execution as well as dependencies of other threads. Also, concurrency allow for many different outcomes of a function call with the same input parameters. There is nothing deterministic about that. Thus, as a corollary, only those functions in an RTOS context are meaningfully unit testable that do not have side effects nor rely on external operation parameters such as data passed in from other threads via IPC.

1 Like

I agree with @RAc,

An integration test will be better suited here.
In that case, you can create a queue and call vTaskStartScheduler as Gaurav pointed out. And then use the queue to transfer data from one task to another. Of course there are many cases that you might want to test - one example being “Is the receiver woken up when data is added to an empty queue”.

Hope this helps,

Sorry for the delay: I was on holiday :wink:
To aggarg: No, I do not call vTaskStartScheduler for the moment in my test code.
To RAc and kanherea: I am aware of the context of an RTOS and I want a good unit-test coverage of my software components before doing integration tests. I am at the beginning of the unit-tests using FreeRTOS and I’d like to understand, discover and define the minimal environment to execute them in a proper way.
I remarked the following thing. When xQueueReceive is called with a non zero ticks_to_wait, xTaskCheckForTimeOut is called to check this timeout. And this function use the pointer to the current task, which is null in my case. I will post later what I’ll learn to solve this issue.
Thanks for your answers!

Thanks for the update, Damien! I am very curious to see how you “solve” the issue. Again, in a unit test context, you would need to treat every different outcome of the control flow - timeouting wait, fail wait, success wait with every possible (valid and invalid) contents of the queue return - as additional inputs to your function - with the additional complication that those “inputs” typically come into play possibly long after the true function inputs have been processed. It is easy to see how this can become extremly complex.

Looking forward to your results!

As I promised, I am back, after a long time, sorry, to explain what solution I took for my tests.
I actually agree with @RAc and @kanherea: a unit-test has to be independent of an unpredictable environment like an RTOS. And furthermore it is not easily compatible with a unit-test framework, like doctest I use.

Ideally I would like to realise two approaches:

  • True unit-tests of my code using mocked interface functions of FreeRTOS. But this does not exist in C.
  • A simulation even partial of my application on Windows using the FreeRTOS port for that OS.

My code is currently still in C. I intend to convert it in C++. The solution I took is making a copy of the implementation files of FreeRTOS I use, like queue.c, and rewriting a simplified, sometimes even empty, version of the called functions. That way, my unit-test code still uses the original header files (queue.h) but is compiled with a “mocked” version. I’m partly satisfied with this solution because the mock implementation is fix and cannot dynamically change along the unit-tests, like with FakeIt.

Concerning the simulation, I intend to implement it once the application I rewrite is decoupled from its numerous dependencies…

Thanks for your replies and explanations. I’ve had the occasion to precise my goals!