1

我正在尝试在我的 linux 机器上对一些 STM32 代码进行单元测试(使用 unity+ceedling),但是每次我访问任何寄存器时,代码都会失败并出现以下错误:

> Produced no final test result counts in $stdout:
Segmentation fault (core dumped)
> And exited with status: [0] (count of failed tests).
> This is often a symptom of a bad memory access in source or test code

例如,此代码将导致 PASSED 1/1(请注意,我正在测试返回 a+b 且与 STM 外围设备无关的函数)。

#include "unity.h"
#include "sum2nums.h"
#include "stm32f4xx.h"

void test_Sum(){
    TEST_ASSERT_EQUAL_UINT32(5, Sum(3, 2));
}

但是这段代码会产生上面提到的错误。

#include "unity.h"
#include "sum2nums.h"
#include "stm32f4xx.h"

void test_Sum(){
    GPIOA->MODER = 1U;
    TEST_ASSERT_EQUAL_UINT32(5, Sum(3, 2));
}

是否有可能以这种方式进行测试,或者我是否必须使用 QEMU(以及如何在不使用 Eclipse 或任何其他 IDE 的情况下这样做)?请注意,Ceedling 使用 gcc,如果我使用 arm-none-eabi 它会生成 hex 文件,我无法在我的 PC 上运行它。

4

2 回答 2

0

如果您想在 PC 上运行它,有一个简单的解决方案。您只需从 STM 库中复制stm32fxxx.h标头,然后在该文件中将所有地址替换为简单变量。例如:

volatile USART_TypeDef    usart0_base;
#define USART0_BASE       (&usart0_base) /**< USART0 base address  */

现在您更改添加了您的 CPU 特定包含的主标头,并添加一个 MOCK 或一些定义,这会将硬件寻址标头与此标头交换,您可以使用计算机 GCC 编译并在 linux 上运行(快得多) . 这样,您基本上可以模拟硬件并用简单的内存替换它。

于 2022-02-09T13:54:38.100 回答
0

如果我理解正确,这个测试框架只是试图用宿主 x86 C 编译器编译你的测试用例并直接运行它们。这将在您的测试代码不执行任何特定于硬件的操作的情况下起作用,这就是为什么您的第一个测试用例很好的原因,但是一旦您的代码尝试接触硬件,如果该硬件实际上不存在,它就会崩溃,如果您将它作为普通的 x86 Linux 进程运行,显然不是这样。

如果您需要运行访问硬件的测试用例,那么您需要运行它们:

  • 实际上在硬件上,例如通过将开发板插入您的 PC 并使用知道如何交叉编译测试的测试框架,将生成的测试用例二进制文件复制到开发板,运行它并捕获输出。

  • 或在提供硬件模型的模拟器或模拟器上。QEMU 是这里的一种可能性,假设它具有您正在使用的电路板模型并且该模型对于您正在运行的任何东西都足够好。同样,您的测试框架需要知道如何交叉编译测试以及如何在模拟器上运行它并捕获输出。

于 2021-03-24T20:10:55.707 回答