cancel
Showing results for 
Search instead for 
Did you mean: 

How to add unit tests (google test) to test my software for the STM32? I am unable to find/setup a 32bit toolchain.

cr.1
Associate

I just started an STM32 project and am new to STM32CubeIDE, I want to add a build configuration that will run my unit tests.

I'm using google test, and following this guide I got it working with cygwin64 (so not 32 bit).

But cygwin32 is deprecated, so how can I unit test my logic for the STM32, on my 64x Windows system?

Hope anyone can tell me their approach, and how to get it to work. Thanks.

9 REPLIES 9
Javier1
Principal

which stm32 are you using?

its pretty commn around here, for people comming from high abstraction level OS/web developing frameworks to try and fail to code in object oriented for OSless stm32 (they end up painfully wrapping C based HAL in cpp classes).

I bookmark your question, because i want to know the usefullness of unit test in embedded firmware without a mcu simulator , i want to hear everyone else's saying about it

we dont need to firmware by ourselves, lets talk
Pavel A.
Evangelist III
cr.1
Associate

@Javier Muñoz​ I'm using the STM32F446RE, but that shouldn't be relevant to the setup of 32 bit unit testing.

My two cents about the usefulness of testing without mcu simulator: I use it to test the 'higher level' functions of my firmware. That way I am confident those functions are solid. this also helps to implement a good HAL.

@Pavel A.​ Interesting read, but It does not answer my problem:

I don't know how I can setup 32 bit unit tests, integrated in STM32CubeIDE/Eclipse.

I don't want to use docker (imo overkill for this), I prefer cygwin, but cygwin32 is no longer maintained, so what is a recommended way to do this in STM32CubeIDE?

>>but that shouldn't be relevant to the setup of 32 bit unit testing

Well... you could fit linux in some stm32, that unit testing would be very different.

>> I use it to test the 'higher level' functions of my firmware. That way I am confident those functions are solid. this also helps to implement a good HAL.

Understood

we dont need to firmware by ourselves, lets talk
Michael K
Senior III

Is your question asking how to set up the unit testing as a build configuration of an STM32 project? If so, I created a step by step guide to integrating GoogleTest directly into your STM32 projects.

Or is your question asking about how to set up a 32 bit compiler instead of a 64 bit compiler - perhaps because you want to unit test with the same bit-width as your 32 bit STM32? If so, ask yourself why this matters - what if you were developing for a 16 bit, or 8 bit target like the STM8? You wouldn't (and couldn't) compile your tests with a 16 or 8 bit compiler just to match the target. Especially you are testing "higher level" functions, the bit-width of the development PC shouldn't matter. Anywhere that, for example, an int must be guaranteed to be 32 bits wide should use the int_32t type anyway.

Unit tests are one of a number of testing stages that are recommended during embedded development. Other tests for architecture-specific bugs can be done separately. For example, in James Grenning's book Test Driven Development for Embedded C he describes a situation where the function strstr() passed unit tests on the PC but failed on the target, because the target's standard library had a bug in that function's implementation!

Hi Michael,I tried using your method but am stuck at the moment when it comes to using files/including them from my main STM project to the test files. So I have been able to set up the test and common folder in my stm project's project explorer along with setting up a donor project.I now look forward to writing test cases in the test folder however for that I would need to include files from other folders in my stm project so that I could test the functions inside them.How do I integrate my main stm project for testing ?

@Michael K​ Yes, the compiler on the build machine does matter. Even if you use standard fixed width types (e.g. `uint32_t`) in your embedded code, when you compile this with 64-bit tools for unit testing on your build machine the pointer types will be a different size. So, any casting between pointer and integer types in your code will spew out a bunch of warnings/errors when compiling for an x64 machine.

JFieb
Associate II

@cr.1​ You can get a 32-bit version of gcc from MinGW-64. The toolchain bundles have `i386` in the name instead of `x86_64`

If you use the tutorial posted by @Michael K​ above (using MinGW-64 inside MSYS2), you can use `pacman` to get the right compiler:

> `pacman -S mingw-w64-i386-toolchain`

Getting the right Windows gcc binaries cleared up most of my issues. However, I did have trouble finding `strlcpy()` (and `strlcat()`) which are not included in the Windows libraries. [The ARM gcc libraries have these built-in]. In the end I just mocked them along with the other unit-test mocks required.

@JFieb You are correct that the pointer sizes are different between architectures. In fact, I ran into that very issue when I moved a project's test environment from 32-bit MinGW to 64-bit. To solve this, anywhere I was casting an integer to a pointer I converted the integer from uint32_t into uintptr_t, which automatically adjusts the integer size to match the target architecture's pointer size.