I'm trying to do a unit test by using the library "check.h" on a register containing a hexadecimal number to check if the return value is correct. The registers are for programming an STM32F030F4 ARM Cortex M0 microcontroller. However when running my test, I have a segmentation fault.
Here is the function I want to test :
#define GPIOA_BASE 0x48000000
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
#define LED1 (*(volatile uint32_t *)(0))
#define OFF 0UL
uint32_t LED1_off (void) {
GPIOA_ODR |= (OFF << LED1);
return GPIOA_ODR ;
}
And here is my test :
START_TEST (test_LED1_off) {
ck_assert_int_eq(0x48000014, LED1_off());
}
END_TEST
For information, the ck_assert_int_eq function works with a uint32_t, I have another test that works with a return value of this type.
Even though the return value is not necessarily equal to what I want to test, I get a segmentation fault when I run my tests. Here is the error :
Running suite(s): FunctionsTests 66%: Checks: 3, Failures: 0, Errors: 1 tests/tests.c:31:E:Core:test_LED1_off:0: (after this point) Received signal 11 (Segmentation fault)
By removing the following line: "GPIOA_ODR |= (OFF << LED1);" and by setting the return value to "1", I no longer have a segmentation fault. I have the impression that when I run my tests, my computer understands that I am trying to access its own memory.
Is what I'm trying possible ? If so how ? If not, what kind of tests can I try ? I've been struggling with this for several hours. Thanks.
By removing the following line: "GPIOA_ODR |= (OFF << LED1);" and by setting the return value to "1", I no longer have a segmentation fault. I have the impression that when I run my tests, my computer understands that I am trying to access its own memory.
On your PC you try to modify the memory at the address GPIOA_BASE + 0x14
(more precisely you dereference pointer assigned with GPIOA_BASE + 0x14
converted to pointer). It is definitely not memory which belongs to you and invoke segfault.
The whole test of the STM32 registers on the PC makes no sense at all.
Also:
OFF << LED1
dereferences NULL pointer which UB|
will not reset the bitIf you want to run it on the PC you need a real object to be referenced by the pointer
#if defined(__x86_64__) || defined(_M_X64)
static uint32_t GPIOA_ODR;
#else
#define GPIOA_BASE 0x48000000
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
#endif
#define LED1 0
#define OFF 1UL
uint32_t LED1_off (void) {
GPIOA_ODR &= ~(OFF << LED1);
return GPIOA_ODR ;
}