5

我在做什么:

我正在使用 cmocka 为大型嵌入式项目运行单元测试。嵌入式项目使用arm-gcc-compiler. gcc单元测试使用嵌入式代码和 cmocka 库的正常使用片段进行编译。

通常 cmocka 建议使用-Wl,--wrap=functionName标志来模拟(替换)一些不需要的子功能。这工作得很好。

问题:

好吧,在我的嵌入式代码中有一个头文件 ( foo.h),其中包含一些函数(声明为内联)。其中一个函数包含 . 的一些汇编代码arm-gcc-compiler,当然gcc.

愚蠢的是,wrap-flag 似乎不适用于放置在头文件中的函数。

问题:

如何在头文件中模拟这个函数?

我如何尝试解决问题:

我想过插入一些#idef宏来排除提到的汇编器部分。但这无法做到,因为该文件属于许可库,并且我不允许更改其内容。

我可以将我的待测函数提取到一个附加文件中,这样foo.h就不需要再包含它了。但这会混淆嵌入式源代码结构。

问题的确切线

确切的代码放在 freeRtos 的portmacro.h中的第 233 行:

portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI;

    __asm volatile
    (
        "   mov %0, %1                                              \n" \
        "   msr basepri, %0                                         \n" \
        "   isb                                                     \n" \
        "   dsb                                                     \n" \
        :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
    );
}

其中 asportFORCE_INLINE定义为:

#define portFORCE_INLINE inline __attribute__(( always_inline))
4

2 回答 2

2

愚蠢的是,包装标志似乎不适用于放置在头文件中的函数。

这不是 的错wrap,该函数已被编译器内联,因此链接器无能为力。

如何在头文件中模拟这个函数?

一种选择是sed在将有问题的代码传递给 gcc 之前自动修补它。例如改变

portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
  uint32_t ulNewBASEPRI;
  ...
}

portFORCE_INLINE static void vPortRaiseBASEPRI_2( void )
{
  uint32_t ulNewBASEPRI;
  ...
}

从你的例子到

portFORCE_INLINE static void vPortRaiseBASEPRI( void );

portFORCE_INLINE static void vPortRaiseBASEPRI_2( void );

cat tmp.c | sed '/inline\|INLINE/,/^}$/{ s/^\(.*\(inline\|INLINE\).*\)/\1;/; /inline\|INLINE/!d }'

正则表达式非常草率,它依赖于标头中的所有定义都将具有INLINE标记的事实,但在您的情况下可能就足够了。

您可以将上述命令嵌入到您的 Makefile 中以在临时文件夹中生成自定义标头,然后使用-Ipath/to/temp/folder标志覆盖默认标头。

于 2017-02-07T11:13:14.407 回答
0

我没有使用 cmocka,所以我不确定框架内是否已经有管理它的方法。

但是,cmock使用一种方法,将标头复制到测试构建的包含层次结构中更高的位置(并且仅测试构建,该位置甚至不包含在发布构建中)。

然后可以编辑此标头的副本,使函数声明简单地变为port void vPortRaiseBASEPRI( void );. 然后,当生成模拟时,会为此(以及同一标头中的其他函数声明)生成模拟,就像在任何其他情况下一样。因为正在生成 hte 模拟,所以函数没有匹配的源代码定义(即.c文件)并不重要。

请参阅https://dmitryfrank.com/articles/unit_testing_embedded_c_applications上的“处理编译器特定的东西”部分

还有我的类似问题以及我如何在这里解决它:Unit test C with compiler specific keywords

于 2017-02-07T13:01:17.793 回答