Why doesn't the loader find defined references? (Ceedling embedded testing)

52 Views Asked by At

everyone! I'd like to ask your kind support for testing my embedded software with Ceedling.

I am new to this world, so please be gentle!

I have set up a Docker container with Ceedling, offered by throwtheswitch.org. I could import every source file in the "src" directory, including vendor drivers and ARM libraries and was able to run my first test.

Here comes the hard part: I must test a function that interacts with the underlying hardware, so when I tried to test it, it failed because I was accessing illegal addresses on Windows.

I noticed that the driver's vendor has included native testing definitions for cases like this: There is a new definition for every peripheral

So I added the UNIT_TESTING_OCN define to Ceedling's project.yml file under "common_defines". On VSCode, I included the same define, and as you can see from the screenshot, original defines are dimmed out.

Nevertheless, when running "ceedling test:all", the linker loader cannot find the references: Undefined references

If I press F12 in VSCode it brings me to the new definition included in the #else preprocessor statement. So what gives?

Why can't Ceedling correctly run?

Please ask for more information, I am sure I have missed something you might need.

Thanks in advance!

2

There are 2 best solutions below

4
pmacfarlane On

The code that is compiled when UNIT_TESTING_OCN is defined just declares extern for those symbols so that the compiler will believe they exist. You're not actually defining any variables at all. Hence why linking fails.

You should define the actual variables in the test code that uses them.

e.g. I have a test_rtc.c file in one of my projects, which contains:

RTC_HandleTypeDef      hrtc;
ADC_HandleTypeDef      hadc1;

It sounds like you might want to have something like the following in your tests:

static ADC1_Type MyADC1;
ADC1_Type *ADC1 = &MyADC1;

etc.

11
Lundin On

Embedded ARM microcontrollers cannot be tested meaningfully on a hosted system PC like Windows or Linux. Various "test suite" fluffware cannot be used. Just forget about it.

Instead, embedded systems testings should be done like this:

  • Test on the actual live MCU intended for the project. Not on a PC, not in a simulator.
  • Test with the actual live hardware that the MCU requires to function meaningfully. Most of the time this means on a custom PCB.
  • There is no "isolating software from hardware". Rather you should test both of these at the same time, to test the real world application as it will eventually be delivered. Tests should be based on functionality, not on parts of the code. Ideally, tests should also be against requirements in the specification.

So for example if you are to test if the ADC is working correctly, then a sensible test could be designed as:

  • Measure the Vref voltage for the ADC with your oscilloscope. Is it within specified acceptable levels? Is it stable?
  • Arrange a test voltage from some external source and add it to an ADC input pin. Measure it to ensure it is stable and then compare it with the values read by the ADC driver. Do they match, given the specified ADC resolution?
  • Do the above test with a long series of samples. Check for fluctuations in the ADC result. What's the largest fluctuation you can catch? What's acceptable as per the specification?
  • Maybe design a software trap in case the ADC fluctuation values goes outside the valid ranges and then leave the system on for x hours.
  • In case it fails, was it because of hardware or software? Maybe the Vref or signal is picking up noise from some switching regulator? Or maybe there are rounding errors in the software?

And so on. And no, separating software tests from hardware tests and do the software tests on some PC is still nonsense. Suppose the bug was a software rounding error, then you still can't catch it on the PC, because it might use different sized integers, different FPU, different arithmetic instructions altogether.

And why on earth should you force the dev to write code portable to a PC just so that some irrelevant "test suite" can execute it? That's a nonsense requirement which just adds complexity and extra work that nobody wants to pay for.