cmock with inline functions

152 Views Asked by At

I'm using CMock/Unity inside Ceedling for unit testing an embedded system:

$ ceedling version
   Ceedling:: 0.31.1
      Unity:: 2.5.4
      CMock:: 2.5.4
 CException:: 1.3.3

I have a third party driver library that contains many static inline functions in header files, with the full body of the function actually in the header file. I am having trouble getting CMock to generate mocks for these functions, I suspect because the whole body of the function is actually in the header.

If I remove the static inline, CMock generates mocks as expected:

    void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask);

works, while

    static inline void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
    {
      WRITE_REG(GPIOx->BRR, PinMask);
    }

fails with a compile warning: warning: implicit declaration of function 'LL_GPIO_ResetOutputPin_Ignore' and link error: undefined reference to `LL_GPIO_ResetOutputPin_Ignore'

Any help in getting around this?

Thanks, -Rob

2

There are 2 best solutions below

0
stevod On

It's not generating a mock because it's not a function. Link Error is occurring because if you take a look at mock_LL_GPIO.h you'll see there was no mock function generated for it.

Looking at the source

#define WRITE_REG(REG, VAL)   ((REG) = (VAL))
static inline void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
{
  WRITE_REG(GPIOx->BRR, PinMask);
}

You've sort of reached the bottom of the drivers. One way to get around this would be to write a wrapper function around it and mock that.

0
rdl_42 On

After some further digging, I found the CMock ":treat_inlines: :include" configuration, as mentioned here: https://github.com/ThrowTheSwitch/CMock/blob/master/docs/CMock_Summary.md

The basic idea is that a copy of a header with inline functions is made and put in the build/test/mocks directory, with the inline function definitions replaced by non-inline function declarations that CMock will work with. build/test/mocks is then put in the include path ahead of the location of the real header file, so the duplicate file without inline functions is used by CMock and the module under test.

The automatic file copy/modify is not working well with my Ceedling v0.31.1, but it looks like there is an imminent v0.32 release. For now I am copying the header I need, placing it in test/support, and manually changing the inline definitions to non inline declarations.

-Rob